Skip to content

Commit

Permalink
Merge pull request #7 from vojtatom/dev
Browse files Browse the repository at this point in the history
Added triangulation
  • Loading branch information
vojtatom authored May 10, 2023
2 parents f11d62d + 077f4e3 commit 51ba46d
Show file tree
Hide file tree
Showing 25 changed files with 1,184 additions and 17 deletions.
18 changes: 18 additions & 0 deletions LICENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,21 @@ shp.ts uses the following third-party code:
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
### [mapbox earcut](https://github.com/mapbox/earcut)

> ISC License
>
> Copyright (c) 2016, Mapbox
>
> Permission to use, copy, modify, and/or distribute this software for any purpose
> with or without fee is hereby granted, provided that the above copyright notice
> and this permission notice appear in all copies.
>
> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
> REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
> INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
> OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
> TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
> THIS SOFTWARE.
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
# SHP.ts 🗺️

<sup>⚠️☕️ Careful, still hot, very early stages of development, consume with caution</sup>

TypeScript package for loading Esri Shapefiles.
TypeScript package for loading Esri Shapefiles, primary developed for for WebGL applications

- ✅ returns a geojson-like representation
- ✅ supports all shape types (including MultiPatch) per [Esri Shapefile specification](https://www.esri.com/content/dam/esrisites/sitecore-archive/Files/Pdfs/library/whitepapers/pdfs/shapefile.pdf)
- ✅ supports X, Y, Z, and M coordinates
- ✅ uses vitest 🧪 for testing
- ✅ includes mapbox's earcut triangulation

## Install from [npm](https://www.npmjs.com/package/shpts)

```
npm install shpts
```

| Branch | |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Release | [![SHPts CI Release](https://github.com/vojtatom/shpts/actions/workflows/ci.yaml/badge.svg?branch=release)](https://github.com/vojtatom/shpts/actions/workflows/ci.yaml) |
| Dev | [![SHPts CI Dev](https://github.com/vojtatom/shpts/actions/workflows/ci.yaml/badge.svg?branch=dev)](https://github.com/vojtatom/shpts/actions/workflows/ci.yaml) |

## Usage

```typescript
Expand Down Expand Up @@ -64,6 +68,23 @@ const properties = reader.readRecord(index);
console.log(properties);
```

triangulate a polygon (expects a set of rings, where the first one is the outer ring and the rest are holes):

```typescript
import { triangulate, Ring } from 'shpts';

const input: Ring[] = [
[
[0, 0],
[1, 0],
[1, 1],
[0, 1],
],
];
const output = triangulate(input, CoordType.XY);
//Float32Array([1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1])
```

## Credits

- insipred by https://github.com/oyvindi/ts-shapefile (MIT Licence), uses all of its test data, partially uses its code
Expand Down
12 changes: 10 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "shpts",
"private": false,
"version": "1.0.4",
"version": "1.0.5",
"type": "module",
"repository": {
"type": "git",
Expand Down Expand Up @@ -43,5 +43,8 @@
"vite": "^4.1.0",
"vite-plugin-dts": "^2.0.0-beta.3",
"vitest": "^0.30.1"
},
"dependencies": {
"gl-matrix": "^3.4.3"
}
}
6 changes: 4 additions & 2 deletions shpts/geometry/multipatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ export class MultiPatchRecord extends BaseRingedRecord {
let offsetFirst = 1;
let offsetSecond = 2;
for (let i = 0; i < coords.length - 2; i++) {
polygons.push([[coords[i], coords[i + offsetFirst], coords[i + offsetSecond]]]);
polygons.push([
[coords[i], coords[i + offsetFirst], coords[i + offsetSecond], coords[i]],
]);
offsetFirst = offsetFirst === 1 ? 2 : 1;
offsetSecond = offsetSecond === 1 ? 2 : 1;
}
Expand All @@ -103,7 +105,7 @@ export class MultiPatchRecord extends BaseRingedRecord {
private static triangleFanToPolygon(coords: Coord[]) {
const polygons = [];
for (let i = 1; i < coords.length - 1; i++) {
polygons.push([[coords[0], coords[i], coords[i + 1]]]);
polygons.push([[coords[0], coords[i], coords[i + 1], coords[0]]]);
}
return polygons;
}
Expand Down
4 changes: 3 additions & 1 deletion shpts/reader/featureReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ export class FeatureReader {
let attrs = [];
if (this.dbfReader != null) attrs = this.dbfReader.readRecord(index);

if (geom == null) return null;

return new Feature(geom, attrs, this.dbfReader?.fields);
}

public readFeatureCollection() {
const collection = new FeatureCollection();
for (let i = 0; i < this.featureCount; i++) {
const feature = this.readFeature(i);
collection.features.push(feature);
if (feature != null) collection.features.push(feature);
}
return collection;
}
Expand Down
8 changes: 8 additions & 0 deletions shpts/reader/shpReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ export class ShapeReader {
}

readGeom(geomIndex: number) {
try {
return this.readGeometryData(geomIndex);
} catch (e: any) {
return null;
}
}

private readGeometryData(geomIndex: number) {
const offset = this.getShpIndex(geomIndex);
this.shpStream.seek(offset);
const recHead = this.readGeomHeader();
Expand Down
2 changes: 2 additions & 0 deletions shpts/shpts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { MultiPatchRecord } from './geometry/multipatch';
import { DbfRecord } from './table/record';
import { DbfFieldDescr, DbfFieldType } from './types/dbfTypes';
import { Coord, CoordType } from './types/coordinate';
import { triangulate } from './utils/triangulation';

export {
DbfReader,
Expand All @@ -25,6 +26,7 @@ export {
MultiPointRecord,
MultiPatchRecord,
CoordType,
triangulate,
};

export type { DbfFieldType, DbfFieldDescr, Coord };
4 changes: 2 additions & 2 deletions shpts/types/coordinate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ export type PointCoord = Coord;
export type MultiPointCoord = Coord[];
export type PolyLineCoord = Coord[][];
export type Ring = Coord[];
export type PolygonCoord = Coord[][][];
export type MultiPatchCoord = Coord[][][];
export type PolygonCoord = Ring[][];
export type MultiPatchCoord = Ring[][];
Loading

0 comments on commit 51ba46d

Please sign in to comment.