diff --git a/.gitignore b/.gitignore
index f0eb7ff..b4896a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ example/*.dbf
example/*.shp
example/*.shx
yarn.lock
+package-lock.json
+yarn.lock
diff --git a/README.md b/README.md
index 365a358..400fa6f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,12 @@
-[![Build Status](https://secure.travis-ci.org/mapbox/shp-write.svg?branch=master)](http://travis-ci.org/mapbox/shp-write)
-
# shp-write
+# ANNOUNCEMENT!
+
+The npm package location (and subsequently unpkg url) for this repo has changed!
+
+tl;dr: `shp-write` -> `@mapbox/shp-write`
+
+
Writes shapefile in pure javascript. Uses [dbf](https://github.com/tmcw/dbf)
for the data component, and [jsZIP](http://stuk.github.io/jszip/) to generate
ZIP file downloads in-browser.
@@ -77,7 +82,7 @@ const options = {
types: {
point: "mypoints",
polygon: "mypolygons",
- line: "mylines",
+ polyline: "mylines",
},
};
@@ -112,6 +117,15 @@ const zipData = shpwrite.zip(
);
```
+## Custom .prj file
+To pass a custom [WKT string](http://www.opengeospatial.org/standards/wkt-crs) in the .prj file to define a different projection the prj option can be used:
+
+```js
+var options = {
+ prj: 'PROJCS["Amersfoort / RD New",GEOGCS["Amersfoort",DATUM["D_Amersfoort",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Stereographic_North_Pole"],PARAMETER["standard_parallel_1",52.15616055555555],PARAMETER["central_meridian",5.38763888888889],PARAMETER["scale_factor",0.9999079],PARAMETER["false_easting",155000],PARAMETER["false_northing",463000],UNIT["Meter",1]]'
+}
+```
+
## API
### `write(data, geometrytype, geometries, callback)`
diff --git a/dist/index.d.ts b/dist/index.d.ts
index 5f2852d..8db94eb 100644
--- a/dist/index.d.ts
+++ b/dist/index.d.ts
@@ -18,6 +18,7 @@ declare module "@mapbox/shp-write" {
export interface DownloadOptions {
folder?: string;
filename?: string;
+ prj?: string;
types?: {
point?: string;
polygon?: string;
diff --git a/index.html b/index.html
index f856a0a..46db318 100644
--- a/index.html
+++ b/index.html
@@ -1 +1 @@
-
+
diff --git a/indexTest.js b/indexTest.js
new file mode 100644
index 0000000..3a8438e
--- /dev/null
+++ b/indexTest.js
@@ -0,0 +1,87 @@
+require('./src/download')({
+ 'type': 'FeatureCollection',
+ 'features': [{
+ 'type': 'Feature',
+ 'properties': {},
+ 'geometry': {
+ 'type': 'Polygon',
+ 'coordinates': [
+ [
+ [
+ 24.936046600341797,
+ 60.175245406790246
+ ],
+ [
+ 24.920597076416016,
+ 60.15577400466598
+ ],
+ [
+ 24.953556060791016,
+ 60.1570553725571
+ ],
+ [
+ 24.936046600341797,
+ 60.175245406790246
+ ]
+ ],
+ [
+ [
+ 24.93523120880127,
+ 60.169247224327165
+ ],
+ [
+ 24.945573806762695,
+ 60.15874243076889
+ ],
+ [
+ 24.928064346313477,
+ 60.15825127085746
+ ],
+ [
+ 24.93523120880127,
+ 60.169247224327165
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'properties': {},
+ 'geometry': {
+ 'type': 'LineString',
+ 'coordinates': [
+ [
+ 24.920940399169922,
+ 60.17977000114811
+ ],
+ [
+ 24.953556060791016,
+ 60.17486121440947
+ ]
+ ]
+ }
+ },
+ {
+ 'type': 'Feature',
+ 'properties': {},
+ 'geometry': {
+ 'type': 'Point',
+ 'coordinates': [
+ 24.925403594970703,
+ 60.171830205844614
+ ]
+ }
+ }
+ ]
+}, {
+ file: 'my_zip_filename', // if empty, filename will be download.zip
+ folder: 'my_internal_shapes_folder', // leave empty to put in root
+ outputType: 'blob',
+ compression: 'DEFLATE',
+ types: {
+ point: 'points',
+ polygon: 'polygons',
+ polyline: 'lines'
+ }
+});
\ No newline at end of file
diff --git a/package.json b/package.json
index a767d3c..d8876c8 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,14 @@
{
"name": "@mapbox/shp-write",
- "version": "0.4.2",
+ "version": "0.4.3",
"description": "write shapefiles from pure javascript",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"test": "mocha -R spec",
"prepublish": "npm run make",
- "make": "browserify -s shpwrite ./ > shpwrite.js"
+ "make": "browserify -s shpwrite ./ > shpwrite.js",
+ "make-test": "browserify indexTest.js > shpwrite.js"
},
"repository": {
"type": "git",
@@ -31,14 +32,14 @@
},
"dependencies": {
"dbf": "0.2.0",
- "jszip": "3.6.0",
- "file-saver": "2.0.5"
+ "file-saver": "2.0.5",
+ "jszip": "^3.10.1"
},
"devDependencies": {
- "browserify": "^13.0.0",
+ "browserify": "^17.0.0",
"cz-conventional-changelog": "^1.2.0",
"expect.js": "~0.3.1",
- "mocha": "~2.4.5"
+ "mocha": "^10.2.0"
},
"config": {
"commitizen": {
diff --git a/src/geojson.js b/src/geojson.js
index 77eed44..be8f28c 100644
--- a/src/geojson.js
+++ b/src/geojson.js
@@ -4,32 +4,53 @@ module.exports.multiline = justType("MultiLineString", "POLYLINE");
module.exports.polygon = justType("Polygon", "POLYGON");
module.exports.multipolygon = justType("MultiPolygon", "POLYGON");
-function justType(type, TYPE) {
+/**
+ * Generate a function that returns an object with the geometries, properties, and type of the given GeoJSON type
+ * @param {string} type the GeoJSON type
+ * @param {string} TYPE the Shapefile type
+ * @returns {(gj: { features: Feature[] }) => { geometries: number[] | number[][] | number[][][] | number[][][][], properties: {Object.}, type: string }}
+ */
+function justType(gjType, shpType) {
return function (gj) {
- var oftype = gj.features.filter(isType(type));
+ var oftype = gj.features.filter(isType(gjType));
return {
- geometries: oftype.map(justCoords),
+ geometries: shpType === 'POLYLINE' ? [oftype.map(justCoords)] : oftype.map(justCoords),
properties: oftype.map(justProps),
- type: TYPE,
+ type: shpType,
};
};
}
-function justCoords(t) {
- return t.geometry.coordinates;
+/**
+ *
+ * @param {Feature} feature The feature to get the coordinates from
+ * @returns {number[] | number[][] | number[][][] | number[][][][]}
+ */
+function justCoords(feature) {
+ return feature.geometry.coordinates;
}
-function justProps(t) {
- return t.properties;
+/**
+ *
+ * @param {Feature} feature The feature to get the properties from
+ * @returns {Object.}
+ */
+function justProps(feature) {
+ return feature.properties;
}
-function isType(t) {
- if (Array.isArray(t))
+/**
+ * Generate a function that filters features based on their geometry.type
+ * @param {string | string[]} type the GeoJSON type to filter with
+ * @returns {(f: Feature) => boolean} a function that returns true if the feature's type is in {@link type}
+ */
+function isType(type) {
+ if (Array.isArray(type))
return function (f) {
- return t.includes(f.geometry.type);
+ return type.includes(f.geometry.type);
};
else
return function (f) {
- return f.geometry.type === t;
+ return f.geometry.type === type;
};
}
diff --git a/src/write.js b/src/write.js
index 0f0cbbe..42d9ff9 100644
--- a/src/write.js
+++ b/src/write.js
@@ -1,11 +1,8 @@
-var types = require('./types'),
- dbf = require('dbf'),
- prj = require('./prj'),
- ext = require('./extent'),
- getFields = require('./fields'),
- assert = require('assert'),
- pointWriter = require('./points'),
- polyWriter = require('./poly');
+var types = require('./types');
+var dbf = require('dbf');
+var prj = require('./prj');
+var pointWriter = require('./points');
+var polyWriter = require('./poly');
var writers = {
1: pointWriter,
@@ -13,23 +10,21 @@ var writers = {
3: polyWriter
};
-var recordHeaderLength = 8;
-
module.exports = write;
// Low-level writing interface
function write(rows, geometry_type, geometries, callback) {
- var TYPE = types.geometries[geometry_type],
- writer = writers[TYPE],
- parts = writer.parts(geometries, TYPE),
- shpLength = 100 + (parts - geometries.length) * 4 + writer.shpLength(geometries),
- shxLength = 100 + writer.shxLength(geometries),
- shpBuffer = new ArrayBuffer(shpLength),
- shpView = new DataView(shpBuffer),
- shxBuffer = new ArrayBuffer(shxLength),
- shxView = new DataView(shxBuffer),
- extent = writer.extent(geometries);
+ var TYPE = types.geometries[geometry_type];
+ var writer = writers[TYPE];
+ var parts = writer.parts(geometries, TYPE);
+ var shpLength = 100 + (parts - geometries.length) * 4 + writer.shpLength(geometries);
+ var shxLength = 100 + writer.shxLength(geometries);
+ var shpBuffer = new ArrayBuffer(shpLength);
+ var shpView = new DataView(shpBuffer);
+ var shxBuffer = new ArrayBuffer(shxLength);
+ var shxView = new DataView(shxBuffer);
+ var extent = writer.extent(geometries);
writeHeader(shpView, TYPE);
writeHeader(shxView, TYPE);
diff --git a/src/zip.js b/src/zip.js
index 43daf20..b2b02e1 100644
--- a/src/zip.js
+++ b/src/zip.js
@@ -1,7 +1,8 @@
-var write = require("./write"),
- geojson = require("./geojson"),
- prj = require("./prj"),
- JSZip = require("jszip");
+var write = require("./write");
+var geojson = require("./geojson");
+var defaultPrj = require('./prj');
+var JSZip = require("jszip");
+
module.exports = function (
gj,
@@ -14,6 +15,8 @@ module.exports = function (
zipTarget = zip.folder(options.folder);
}
+ var prj = (options && options.prj) ? options.prj : defaultPrj;
+
[
geojson.point(gj),
geojson.line(gj),