Skip to content

Commit 6149bde

Browse files
authored
Merge pull request #107 from mapbox/further_cleanup_improvements
Further cleanup improvements
2 parents 8768a97 + d3773a5 commit 6149bde

9 files changed

+170
-46
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ example/*.dbf
44
example/*.shp
55
example/*.shx
66
yarn.lock
7+
package-lock.json
8+
yarn.lock

README.md

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
[![Build Status](https://secure.travis-ci.org/mapbox/shp-write.svg?branch=master)](http://travis-ci.org/mapbox/shp-write)
2-
31
# shp-write
42

3+
# ANNOUNCEMENT!
4+
5+
The npm package location (and subsequently unpkg url) for this repo has changed!
6+
7+
tl;dr: `shp-write` -> `@mapbox/shp-write`
8+
9+
510
Writes shapefile in pure javascript. Uses [dbf](https://github.com/tmcw/dbf)
611
for the data component, and [jsZIP](http://stuk.github.io/jszip/) to generate
712
ZIP file downloads in-browser.
@@ -77,7 +82,7 @@ const options = {
7782
types: {
7883
point: "mypoints",
7984
polygon: "mypolygons",
80-
line: "mylines",
85+
polyline: "mylines",
8186
},
8287
};
8388

@@ -112,6 +117,15 @@ const zipData = shpwrite.zip(
112117
);
113118
```
114119

120+
## Custom .prj file
121+
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:
122+
123+
```js
124+
var options = {
125+
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]]'
126+
}
127+
```
128+
115129
## API
116130
### `write(data, geometrytype, geometries, callback)`
117131

dist/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ declare module "@mapbox/shp-write" {
1818
export interface DownloadOptions {
1919
folder?: string;
2020
filename?: string;
21+
prj?: string;
2122
types?: {
2223
point?: string;
2324
polygon?: string;

index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<script src='bundle.js'></script>
1+
<script src='shpwrite.js'></script>

indexTest.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
require('./src/download')({
2+
'type': 'FeatureCollection',
3+
'features': [{
4+
'type': 'Feature',
5+
'properties': {},
6+
'geometry': {
7+
'type': 'Polygon',
8+
'coordinates': [
9+
[
10+
[
11+
24.936046600341797,
12+
60.175245406790246
13+
],
14+
[
15+
24.920597076416016,
16+
60.15577400466598
17+
],
18+
[
19+
24.953556060791016,
20+
60.1570553725571
21+
],
22+
[
23+
24.936046600341797,
24+
60.175245406790246
25+
]
26+
],
27+
[
28+
[
29+
24.93523120880127,
30+
60.169247224327165
31+
],
32+
[
33+
24.945573806762695,
34+
60.15874243076889
35+
],
36+
[
37+
24.928064346313477,
38+
60.15825127085746
39+
],
40+
[
41+
24.93523120880127,
42+
60.169247224327165
43+
]
44+
]
45+
]
46+
}
47+
},
48+
{
49+
'type': 'Feature',
50+
'properties': {},
51+
'geometry': {
52+
'type': 'LineString',
53+
'coordinates': [
54+
[
55+
24.920940399169922,
56+
60.17977000114811
57+
],
58+
[
59+
24.953556060791016,
60+
60.17486121440947
61+
]
62+
]
63+
}
64+
},
65+
{
66+
'type': 'Feature',
67+
'properties': {},
68+
'geometry': {
69+
'type': 'Point',
70+
'coordinates': [
71+
24.925403594970703,
72+
60.171830205844614
73+
]
74+
}
75+
}
76+
]
77+
}, {
78+
file: 'my_zip_filename', // if empty, filename will be download.zip
79+
folder: 'my_internal_shapes_folder', // leave empty to put in root
80+
outputType: 'blob',
81+
compression: 'DEFLATE',
82+
types: {
83+
point: 'points',
84+
polygon: 'polygons',
85+
polyline: 'lines'
86+
}
87+
});

package.json

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"name": "@mapbox/shp-write",
3-
"version": "0.4.2",
3+
"version": "0.4.3",
44
"description": "write shapefiles from pure javascript",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
77
"scripts": {
88
"test": "mocha -R spec",
99
"prepublish": "npm run make",
10-
"make": "browserify -s shpwrite ./ > shpwrite.js"
10+
"make": "browserify -s shpwrite ./ > shpwrite.js",
11+
"make-test": "browserify indexTest.js > shpwrite.js"
1112
},
1213
"repository": {
1314
"type": "git",
@@ -31,14 +32,14 @@
3132
},
3233
"dependencies": {
3334
"dbf": "0.2.0",
34-
"jszip": "3.6.0",
35-
"file-saver": "2.0.5"
35+
"file-saver": "2.0.5",
36+
"jszip": "^3.10.1"
3637
},
3738
"devDependencies": {
38-
"browserify": "^13.0.0",
39+
"browserify": "^17.0.0",
3940
"cz-conventional-changelog": "^1.2.0",
4041
"expect.js": "~0.3.1",
41-
"mocha": "~2.4.5"
42+
"mocha": "^10.2.0"
4243
},
4344
"config": {
4445
"commitizen": {

src/geojson.js

+33-12
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,53 @@ module.exports.multiline = justType("MultiLineString", "POLYLINE");
44
module.exports.polygon = justType("Polygon", "POLYGON");
55
module.exports.multipolygon = justType("MultiPolygon", "POLYGON");
66

7-
function justType(type, TYPE) {
7+
/**
8+
* Generate a function that returns an object with the geometries, properties, and type of the given GeoJSON type
9+
* @param {string} type the GeoJSON type
10+
* @param {string} TYPE the Shapefile type
11+
* @returns {(gj: { features: Feature[] }) => { geometries: number[] | number[][] | number[][][] | number[][][][], properties: {Object.<string, string>}, type: string }}
12+
*/
13+
function justType(gjType, shpType) {
814
return function (gj) {
9-
var oftype = gj.features.filter(isType(type));
15+
var oftype = gj.features.filter(isType(gjType));
1016
return {
11-
geometries: oftype.map(justCoords),
17+
geometries: shpType === 'POLYLINE' ? [oftype.map(justCoords)] : oftype.map(justCoords),
1218
properties: oftype.map(justProps),
13-
type: TYPE,
19+
type: shpType,
1420
};
1521
};
1622
}
1723

18-
function justCoords(t) {
19-
return t.geometry.coordinates;
24+
/**
25+
*
26+
* @param {Feature} feature The feature to get the coordinates from
27+
* @returns {number[] | number[][] | number[][][] | number[][][][]}
28+
*/
29+
function justCoords(feature) {
30+
return feature.geometry.coordinates;
2031
}
2132

22-
function justProps(t) {
23-
return t.properties;
33+
/**
34+
*
35+
* @param {Feature} feature The feature to get the properties from
36+
* @returns {Object.<string, string>}
37+
*/
38+
function justProps(feature) {
39+
return feature.properties;
2440
}
2541

26-
function isType(t) {
27-
if (Array.isArray(t))
42+
/**
43+
* Generate a function that filters features based on their geometry.type
44+
* @param {string | string[]} type the GeoJSON type to filter with
45+
* @returns {(f: Feature) => boolean} a function that returns true if the feature's type is in {@link type}
46+
*/
47+
function isType(type) {
48+
if (Array.isArray(type))
2849
return function (f) {
29-
return t.includes(f.geometry.type);
50+
return type.includes(f.geometry.type);
3051
};
3152
else
3253
return function (f) {
33-
return f.geometry.type === t;
54+
return f.geometry.type === type;
3455
};
3556
}

src/write.js

+15-20
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,30 @@
1-
var types = require('./types'),
2-
dbf = require('dbf'),
3-
prj = require('./prj'),
4-
ext = require('./extent'),
5-
getFields = require('./fields'),
6-
assert = require('assert'),
7-
pointWriter = require('./points'),
8-
polyWriter = require('./poly');
1+
var types = require('./types');
2+
var dbf = require('dbf');
3+
var prj = require('./prj');
4+
var pointWriter = require('./points');
5+
var polyWriter = require('./poly');
96

107
var writers = {
118
1: pointWriter,
129
5: polyWriter,
1310
3: polyWriter
1411
};
1512

16-
var recordHeaderLength = 8;
17-
1813
module.exports = write;
1914

2015
// Low-level writing interface
2116
function write(rows, geometry_type, geometries, callback) {
2217

23-
var TYPE = types.geometries[geometry_type],
24-
writer = writers[TYPE],
25-
parts = writer.parts(geometries, TYPE),
26-
shpLength = 100 + (parts - geometries.length) * 4 + writer.shpLength(geometries),
27-
shxLength = 100 + writer.shxLength(geometries),
28-
shpBuffer = new ArrayBuffer(shpLength),
29-
shpView = new DataView(shpBuffer),
30-
shxBuffer = new ArrayBuffer(shxLength),
31-
shxView = new DataView(shxBuffer),
32-
extent = writer.extent(geometries);
18+
var TYPE = types.geometries[geometry_type];
19+
var writer = writers[TYPE];
20+
var parts = writer.parts(geometries, TYPE);
21+
var shpLength = 100 + (parts - geometries.length) * 4 + writer.shpLength(geometries);
22+
var shxLength = 100 + writer.shxLength(geometries);
23+
var shpBuffer = new ArrayBuffer(shpLength);
24+
var shpView = new DataView(shpBuffer);
25+
var shxBuffer = new ArrayBuffer(shxLength);
26+
var shxView = new DataView(shxBuffer);
27+
var extent = writer.extent(geometries);
3328

3429
writeHeader(shpView, TYPE);
3530
writeHeader(shxView, TYPE);

src/zip.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
var write = require("./write"),
2-
geojson = require("./geojson"),
3-
prj = require("./prj"),
4-
JSZip = require("jszip");
1+
var write = require("./write");
2+
var geojson = require("./geojson");
3+
var defaultPrj = require('./prj');
4+
var JSZip = require("jszip");
5+
56

67
module.exports = function (
78
gj,
@@ -14,6 +15,8 @@ module.exports = function (
1415
zipTarget = zip.folder(options.folder);
1516
}
1617

18+
var prj = (options && options.prj) ? options.prj : defaultPrj;
19+
1720
[
1821
geojson.point(gj),
1922
geojson.line(gj),

0 commit comments

Comments
 (0)