Skip to content

Commit

Permalink
Deno lint fixes, Polygon implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
abrman committed Nov 26, 2024
1 parent 89773dc commit 7d26bf2
Show file tree
Hide file tree
Showing 29 changed files with 4,374 additions and 35 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-phones-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"shp-kit": minor
---

Implemented Polygon write and read
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
dist
dist
.DS_Store
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ The following table outlines the current support for different types of shapefil
| -------------- | ---- | ----- |
| Point |||
| PolyLine |||
| Polygon | | |
| Polygon | | |
| MultiPoint |||
| PointZ |||
| PolyLineZ |||
| PolygonZ | | |
| PolygonZ | | |
| MultiPointZ |||
| PointM |||
| ⚠ PolyLineM |||
| ⚠ PolygonM | | |
| ⚠ PolygonM | | |
| ⚠ MultiPointM |||
| MultiPatch |||

Expand Down
3,038 changes: 3,038 additions & 0 deletions deno.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"vitest": "^0.34.6"
},
"dependencies": {
"@turf/helpers": "^7.1.0",
"@turf/turf": "^7.1.0",
"buffer": "^6.0.3",
"jszip": "^3.10.1",
"proj4": "^2.10.0"
Expand Down
112 changes: 112 additions & 0 deletions src/private/readers/Polygon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Feature } from "geojson";
import { ShapefileTypesString } from "../helpers/shapefileTypes";
import { Options } from "../../public/shpRead";

const getOptionalViewFloat64 = (view: DataView, target: number, lastValidByte: number, little: boolean) => {
if (target > view.byteLength - 1 || target > lastValidByte) return 0;
return view.getFloat64(target, little);
};

const Polygon = (
shpView: DataView,
o: Options,
currByteIndex: number,
recordLength: number,
shpType: ShapefileTypesString,
properties: {
[key: string]: any;
}
) => {
const recordEndByte = currByteIndex + recordLength;
//significant header information
const partsLength = shpView.getInt32(currByteIndex + 36, true);
const pointsLength = shpView.getInt32(currByteIndex + 40, true);
currByteIndex += 44;
const partsSeparators = [...Array(partsLength)].map((_, i) => shpView.getInt32(currByteIndex + 4 * i, true));
partsSeparators.push(pointsLength);

currByteIndex += 4 * partsLength;

let points = [...Array(pointsLength)].map((_, i) => {
return [shpView.getFloat64(currByteIndex + 16 * i, true), shpView.getFloat64(currByteIndex + 16 * i + 8, true)];
});

currByteIndex += 16 * pointsLength;

let mValues: number[] | null = null;
let zValues: number[] | null = null;
if (shpType === "PolygonM") {
currByteIndex += 32; // min-max
mValues = [...Array(pointsLength)].map((_, i) => {
return shpView.getFloat64(currByteIndex + 8 * i, true);
});
}
if (shpType === "PolygonZ") {
currByteIndex += 16; // min-max
zValues = [...Array(pointsLength)].map((_, i) => {
return getOptionalViewFloat64(shpView, currByteIndex + 8 * i, recordEndByte, true);
});
currByteIndex += pointsLength * 8 + 16;
mValues = [...Array(pointsLength)].map((_, i) => {
return getOptionalViewFloat64(shpView, currByteIndex + 8 * i, recordEndByte, true);
});

if (!o.elevationPropertyKey) {
points = points.map((pt, i) => [pt[0] as number, pt[1] as number, (zValues as number[])[i] as number]);
}
}

const coordinates = partsSeparators.reduce(
(list, v, i, a) =>
i === 0 ? list : [...list, [...Array(v - (a[i - 1] as number))].map((_, j) => points[(a[i - 1] as number) + j])],
[] as any[]
);

const output = {
type: "Feature",
geometry: {
type: "Polygon",
coordinates,
},
properties: {
...properties,
...(o.elevationPropertyKey && zValues
? {
[o.elevationPropertyKey]:
zValues && [...new Set(zValues)].length === 1
? zValues[0]
: partsSeparators.reduce(
(list, v, i, a) =>
i === 0
? list
: [
...list,
[...Array(v - (a[i - 1] as number))].map((_, j) => zValues[(a[i - 1] as number) + j]),

Check failure on line 84 in src/private/readers/Polygon.ts

View workflow job for this annotation

GitHub Actions / build

'zValues' is possibly 'null'.
],
[] as any[]
),
}
: {}),
...(o.measurePropertyKey && mValues
? {
[o.measurePropertyKey]:
mValues && [...new Set(mValues)].length === 1
? mValues[0]
: partsSeparators.reduce(
(list, v, i, a) =>
i === 0
? list
: [
...list,
[...Array(v - (a[i - 1] as number))].map((_, j) => mValues[(a[i - 1] as number) + j]),

Check failure on line 101 in src/private/readers/Polygon.ts

View workflow job for this annotation

GitHub Actions / build

'mValues' is possibly 'null'.
],
[] as any[]
),
}
: {}),
},
} as Feature;
return output as Feature;
};

export default Polygon;
7 changes: 4 additions & 3 deletions src/private/readers/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import PolyLineReader from "./PolyLine";
import PolygonReader from "./Polygon";
import PointReader from "./Point";

const readers = {
// 0 : "Null Shape",
1: PointReader, // "Point",
3: PolyLineReader, // "PolyLine",
// 5: "Polygon",
5: PolygonReader, // "Polygon",
// 8: "MultiPoint",
11: PointReader, // "PointZ",
13: PolyLineReader, // "PolyLineZ",
// 15: "PolygonZ",
15: PolygonReader, //"PolygonZ",
// 18: "MultiPointZ",
21: PointReader, // "PointM",
23: PolyLineReader, // "PolyLineM",
// 25: "PolygonM",
25: PolygonReader, // "PolygonM",
// 28: "MultiPointM",
// 31 : "MultiPatch",
} as const;
Expand Down
Loading

0 comments on commit 7d26bf2

Please sign in to comment.