Skip to content

Commit

Permalink
Merge pull request #22 from modelcreate/binaryReader
Browse files Browse the repository at this point in the history
Binary reader
  • Loading branch information
lbutler authored Jan 26, 2020
2 parents ba4c8ad + 7e7caae commit 6d965ea
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 3 deletions.
2 changes: 1 addition & 1 deletion packages/epanet-engine/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@model-create/epanet-engine",
"version": "0.2.0",
"version": "0.3.0",
"description": "",
"main": "dist/index.js",
"module": "dist/index.es6.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/epanet-js/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.2.0",
"version": "0.3.0",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand All @@ -20,7 +20,7 @@
"doc": "tsdx build && yarn api-extractor run --local --verbose && mv ./temp/epanet-js.api.json ./input/ && yarn api-documenter markdown"
},
"dependencies": {
"@model-create/epanet-engine": "0.2.0"
"@model-create/epanet-engine": "0.3.0"
},
"peerDependencies": {},
"husky": {
Expand Down
185 changes: 185 additions & 0 deletions packages/epanet-js/src/OutputReader/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
enum NodeResultTypes {
Demand,
Head,
Pressure,
WaterQuality,
}

enum LinkResultTypes {
Flow,
Velcoity,
Headloss,
AvgWaterQuality,
Status,
Setting,
ReactionRate,
Friction,
}

export interface LinkResults {
flow: number[];
velcoity: number[];
headloss: number[];
avgWaterQuality: number[];
status: number[];
setting: number[];
reactionRate: number[];
friction: number[];
}

export interface NodeResults {
demand: number[];
head: number[];
pressure: number[];
waterQuality: number[];
}

export interface EpanetProlog {
nodeCount: number;
resAndTankCount: number;
linkCount: number;
pumpCount: number;
valveCount: number;
reportingPeriods: number;
}

export interface EpanetResults {
prolog: EpanetProlog;
results: {
nodes: NodeResults[];
links: LinkResults[];
};
}

export function readBinary(results: Uint8Array): EpanetResults {
const view1 = new DataView(results.buffer);
const prolog: EpanetProlog = {
nodeCount: view1.getInt32(8, true),
resAndTankCount: view1.getInt32(12, true),
linkCount: view1.getInt32(16, true),
pumpCount: view1.getInt32(20, true),
valveCount: view1.getInt32(24, true),
reportingPeriods: view1.getInt32(results.byteLength - 12, true),
};

const offsetResults =
884 +
36 * prolog.nodeCount +
52 * prolog.linkCount +
8 * prolog.resAndTankCount +
28 * prolog.pumpCount +
4;

const nodes: NodeResults[] = [...Array(prolog.nodeCount)].map((_, i) => {
return getNodeResults(prolog, offsetResults, i, view1);
});
const links: LinkResults[] = [...Array(prolog.linkCount)].map((_, i) => {
return getLinkResults(prolog, offsetResults, i, view1);
});

const data: EpanetResults = {
prolog,
results: {
nodes,
links,
},
};
return data;
}

const getNodeResults = (
prolog: EpanetProlog,
offsetResults: number,
nodeIndex: number,
dataView: DataView
): NodeResults => {
const nodeResults = {
demand: [],
head: [],
pressure: [],
waterQuality: [],
};

const result: NodeResults = [
'demand',
'head',
'pressure',
'waterQuality',
].reduce((map, obj, i) => {
return {
...map,
[obj]: getResultByteOffSet(
prolog,
offsetResults,
true,
nodeIndex,
i
).map(x => dataView.getFloat32(x, true)),
};
}, nodeResults);

return result;
};

const getLinkResults = (
prolog: EpanetProlog,
offsetResults: number,
linkIndex: number,
dataView: DataView
): LinkResults => {
const linkResults = {
flow: [],
velcoity: [],
headloss: [],
avgWaterQuality: [],
status: [],
setting: [],
reactionRate: [],
friction: [],
};

const result: LinkResults = [
'flow',
'velcoity',
'headloss',
'avgWaterQuality',
'status',
'setting',
'reactionRate',
'friction',
].reduce((map, obj, i) => {
return {
...map,
[obj]: getResultByteOffSet(
prolog,
offsetResults,
false,
linkIndex,
i
).map(x => dataView.getFloat32(x, true)),
};
}, linkResults);

return result;
};

const getResultByteOffSet = (
prolog: EpanetProlog,
offsetResults: number,
isNode: boolean,
objIndex: number,
resultType: NodeResultTypes | LinkResultTypes
): number[] => {
const linkResultOffset = isNode ? 0 : 16 * prolog.nodeCount;
const typeCount = isNode ? prolog.nodeCount : prolog.linkCount;
const resultSize = 16 * prolog.nodeCount + 32 * prolog.linkCount;
const answer = [...Array(prolog.reportingPeriods)].map(
(_, i) =>
offsetResults +
resultSize * i +
linkResultOffset +
4 * objIndex +
4 * resultType * typeCount
);
return answer;
};
1 change: 1 addition & 0 deletions packages/epanet-js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as Workspace } from './Workspace/Workspace';
export { default as Project } from './Project/Project';
export * from './enum/index';
export * from './OutputReader/index';

0 comments on commit 6d965ea

Please sign in to comment.