mapshaper 0.7.2 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/bin/mapshaper-gui +31 -7
- package/mapshaper.js +45 -42
- package/package.json +8 -7
- package/www/geopackage.js +10 -10
- package/www/index.html +32 -4
- package/www/mapshaper-gui.js +529 -83
- package/www/mapshaper.js +45 -42
- package/www/modules.js +5 -5
- package/www/page.css +157 -0
- package/www/docs/_assets/cmd-search.js +0 -213
- package/www/docs/_assets/docs.css +0 -722
- package/www/docs/_assets/docs.js +0 -75
- package/www/docs/_assets/highlight.css +0 -10
- package/www/docs/essentials/command-line.html +0 -127
- package/www/docs/essentials/command-line.html.md +0 -112
- package/www/docs/essentials/web-app.html +0 -138
- package/www/docs/essentials/web-app.html.md +0 -106
- package/www/docs/examples/basics.html +0 -275
- package/www/docs/examples/basics.html.md +0 -370
- package/www/docs/examples/data/Makefile +0 -31
- package/www/docs/examples/data/globe.msx +0 -0
- package/www/docs/examples/data/globe.svg +0 -616
- package/www/docs/examples/data/globe.txt +0 -21
- package/www/docs/examples/data/globe.zip +0 -0
- package/www/docs/examples/data/ne_50m_admin_0_countries.geojson +0 -1
- package/www/docs/examples/data/ne_50m_admin_1_states_provinces_lakes.geojson +0 -1
- package/www/docs/examples/data/us-states.msx +0 -0
- package/www/docs/examples/data/us-states.svg +0 -56
- package/www/docs/examples/data/us-states.txt +0 -6
- package/www/docs/examples/data/us-states.zip +0 -0
- package/www/docs/examples/globe.html +0 -108
- package/www/docs/examples/globe.html.md +0 -64
- package/www/docs/examples/us-states.html +0 -88
- package/www/docs/examples/us-states.html.md +0 -44
- package/www/docs/formats/csv.html +0 -127
- package/www/docs/formats/csv.html.md +0 -97
- package/www/docs/formats/dbf.html +0 -87
- package/www/docs/formats/dbf.html.md +0 -39
- package/www/docs/formats/flatgeobuf.html +0 -85
- package/www/docs/formats/flatgeobuf.html.md +0 -41
- package/www/docs/formats/geojson.html +0 -107
- package/www/docs/formats/geojson.html.md +0 -65
- package/www/docs/formats/geopackage.html +0 -87
- package/www/docs/formats/geopackage.html.md +0 -42
- package/www/docs/formats/json.html +0 -83
- package/www/docs/formats/json.html.md +0 -35
- package/www/docs/formats/kml.html +0 -82
- package/www/docs/formats/kml.html.md +0 -39
- package/www/docs/formats/overview.html +0 -191
- package/www/docs/formats/overview.html.md +0 -34
- package/www/docs/formats/shapefile.html +0 -123
- package/www/docs/formats/shapefile.html.md +0 -84
- package/www/docs/formats/snapshot.html +0 -87
- package/www/docs/formats/snapshot.html.md +0 -39
- package/www/docs/formats/svg.html +0 -99
- package/www/docs/formats/svg.html.md +0 -51
- package/www/docs/formats/topojson.html +0 -102
- package/www/docs/formats/topojson.html.md +0 -54
- package/www/docs/gallery/index.html +0 -80
- package/www/docs/gallery/index.html.md +0 -29
- package/www/docs/guides/combining-layers.html +0 -109
- package/www/docs/guides/combining-layers.html.md +0 -89
- package/www/docs/guides/expressions.html +0 -600
- package/www/docs/guides/expressions.html.md +0 -376
- package/www/docs/guides/programmatic.html +0 -117
- package/www/docs/guides/programmatic.html.md +0 -91
- package/www/docs/guides/projections.html +0 -158
- package/www/docs/guides/projections.html.md +0 -118
- package/www/docs/guides/simplification.html +0 -110
- package/www/docs/guides/simplification.html.md +0 -96
- package/www/docs/guides/topology.html +0 -90
- package/www/docs/guides/topology.html.md +0 -63
- package/www/docs/images/cal-counties.png +0 -0
- package/www/docs/images/simplification-detail.png +0 -0
- package/www/docs/images/simplification-dp.png +0 -0
- package/www/docs/images/simplification-mod2.png +0 -0
- package/www/docs/images/tiger-counties.png +0 -0
- package/www/docs/index.html +0 -101
- package/www/docs/index.html.md +0 -59
- package/www/docs/reference.html +0 -1302
- package/www/docs/reference.html.md +0 -1817
- package/www/docs/whats-new.html +0 -77
- package/www/docs/whats-new.html.md +0 -59
- package/www/llms-full.txt +0 -4053
- package/www/llms.txt +0 -55
package/LICENSE
CHANGED
package/bin/mapshaper-gui
CHANGED
|
@@ -16,6 +16,7 @@ var defaultPort = 5555,
|
|
|
16
16
|
.option('-t, --target <name>', 'name of layer to select initially')
|
|
17
17
|
.addOption(new commander.Option('-b, --blurb <text>',
|
|
18
18
|
'replace the default blurb on the import screen').hideHelp())
|
|
19
|
+
.argument('[file...]', 'data files to load')
|
|
19
20
|
.helpOption('-h, --help', 'show this help message')
|
|
20
21
|
.version(require('../package.json').version)
|
|
21
22
|
.parse(process.argv),
|
|
@@ -25,7 +26,6 @@ var defaultPort = 5555,
|
|
|
25
26
|
url = require("url"),
|
|
26
27
|
fs = require("fs"),
|
|
27
28
|
Cookies = require("cookies"),
|
|
28
|
-
opn = require("opn"),
|
|
29
29
|
webRoot = path.join(__dirname, "../www"),
|
|
30
30
|
port = parseInt(opts.port, 10) || defaultPort,
|
|
31
31
|
dataFiles = expandShapefiles(program.args),
|
|
@@ -66,10 +66,24 @@ function startServer(port) {
|
|
|
66
66
|
// block attempts to load files outside webroot
|
|
67
67
|
serve404(response);
|
|
68
68
|
} else if (uri == '/close') {
|
|
69
|
-
//
|
|
69
|
+
// End process when page closes, unless page is immediately refreshed.
|
|
70
|
+
// The grace window (1500ms) gives the refreshed page time to send
|
|
71
|
+
// /cancel-close. A short window is not safe here: with sendBeacon,
|
|
72
|
+
// /close frequently arrives at the server *after* the new page's
|
|
73
|
+
// resource fetches have already been served, so we can't rely on
|
|
74
|
+
// those fetches to reset the timer for us.
|
|
70
75
|
timeout = setTimeout(function() {
|
|
71
76
|
process.exit(0);
|
|
72
|
-
},
|
|
77
|
+
}, 1500);
|
|
78
|
+
response.writeHead(204); // no content
|
|
79
|
+
response.end();
|
|
80
|
+
} else if (uri == '/cancel-close') {
|
|
81
|
+
// The page-load-time refresh detection in src/gui/gui.mjs sends this
|
|
82
|
+
// when sessionStorage indicates the new page is a refresh of the
|
|
83
|
+
// previous tab incarnation. clearTimeout above already cancelled any
|
|
84
|
+
// pending exit; we just need to acknowledge the request.
|
|
85
|
+
response.writeHead(204);
|
|
86
|
+
response.end();
|
|
73
87
|
} else if (uri == "/manifest.js") {
|
|
74
88
|
if (!sessionId && opts.directSave) {
|
|
75
89
|
// create a session id for authenticating requests to save files
|
|
@@ -86,14 +100,24 @@ function startServer(port) {
|
|
|
86
100
|
} else if (uri.indexOf('/save') === 0) {
|
|
87
101
|
saveContent(request, response);
|
|
88
102
|
} else {
|
|
89
|
-
// serve a file from the web root
|
|
90
|
-
|
|
91
|
-
|
|
103
|
+
// serve a file from the web root. Translate directory paths (any URI
|
|
104
|
+
// ending in '/') to their index.html so that links like '/docs/' work
|
|
105
|
+
// the way they do behind a normal static-file host (mapshaper.org).
|
|
106
|
+
if (uri.endsWith('/')) {
|
|
107
|
+
uri += 'index.html';
|
|
92
108
|
}
|
|
93
109
|
serveFile(getAssetFilePath(uri), response);
|
|
94
110
|
}
|
|
95
111
|
}).listen(port, 'localhost', function() {
|
|
96
|
-
|
|
112
|
+
// `open` is ESM-only since v9, so import it dynamically from this CJS bin
|
|
113
|
+
// script. Failure to launch a browser is non-fatal: the user can still
|
|
114
|
+
// visit the URL printed (or implied) by the running server.
|
|
115
|
+
import('open').then(function(mod) {
|
|
116
|
+
return mod.default("http://localhost:" + port);
|
|
117
|
+
}).catch(function(err) {
|
|
118
|
+
console.error("Could not open browser automatically; visit http://localhost:" + port + " manually.");
|
|
119
|
+
console.error(err && err.message || err);
|
|
120
|
+
});
|
|
97
121
|
});
|
|
98
122
|
}
|
|
99
123
|
|
package/mapshaper.js
CHANGED
|
@@ -12416,8 +12416,8 @@
|
|
|
12416
12416
|
return obj;
|
|
12417
12417
|
};
|
|
12418
12418
|
|
|
12419
|
-
async function writeFiles(exports, opts) {
|
|
12420
|
-
return _writeFiles(exports, opts);
|
|
12419
|
+
async function writeFiles(exports$1, opts) {
|
|
12420
|
+
return _writeFiles(exports$1, opts);
|
|
12421
12421
|
}
|
|
12422
12422
|
|
|
12423
12423
|
// Used by GUI to replace the CLI version of writeFiles()
|
|
@@ -12426,24 +12426,24 @@
|
|
|
12426
12426
|
_writeFiles = func;
|
|
12427
12427
|
}
|
|
12428
12428
|
|
|
12429
|
-
var _writeFiles = function(exports, opts) {
|
|
12430
|
-
if (exports.length > 0 === false) {
|
|
12429
|
+
var _writeFiles = function(exports$1, opts) {
|
|
12430
|
+
if (exports$1.length > 0 === false) {
|
|
12431
12431
|
message("No files to save");
|
|
12432
12432
|
} else if (opts.dry_run) ; else if (opts.stdout) {
|
|
12433
12433
|
// Using async writeFile() function -- synchronous output to stdout can
|
|
12434
12434
|
// trigger EAGAIN error, e.g. when piped to less.
|
|
12435
|
-
require$1('rw').writeFile('/dev/stdout', exports[0].content, function() {});
|
|
12435
|
+
require$1('rw').writeFile('/dev/stdout', exports$1[0].content, function() {});
|
|
12436
12436
|
} else {
|
|
12437
12437
|
if (opts.zip) {
|
|
12438
|
-
exports = [{
|
|
12438
|
+
exports$1 = [{
|
|
12439
12439
|
// TODO: add output subdirectory, if relevant
|
|
12440
12440
|
filename: opts.zipfile || 'output.zip',
|
|
12441
|
-
content: zipSync(exports)
|
|
12441
|
+
content: zipSync(exports$1)
|
|
12442
12442
|
}];
|
|
12443
12443
|
}
|
|
12444
|
-
var paths = getOutputPaths(utils.pluck(exports, 'filename'), opts);
|
|
12444
|
+
var paths = getOutputPaths(utils.pluck(exports$1, 'filename'), opts);
|
|
12445
12445
|
var inputFiles = getStashedVar('input_files');
|
|
12446
|
-
exports.forEach(function(obj, i) {
|
|
12446
|
+
exports$1.forEach(function(obj, i) {
|
|
12447
12447
|
var path = paths[i];
|
|
12448
12448
|
if (obj.content instanceof ArrayBuffer) {
|
|
12449
12449
|
// replacing content so ArrayBuffers can be gc'd
|
|
@@ -14993,10 +14993,10 @@
|
|
|
14993
14993
|
return d;
|
|
14994
14994
|
}
|
|
14995
14995
|
|
|
14996
|
-
var cache
|
|
14996
|
+
var cache = {};
|
|
14997
14997
|
|
|
14998
14998
|
function getParseRxp(fmt) {
|
|
14999
|
-
if (fmt in cache
|
|
14999
|
+
if (fmt in cache) return cache[fmt];
|
|
15000
15000
|
var rxp = fmt;
|
|
15001
15001
|
rxp = rxp.replace('[-]', '(?<prefix>-)?'); // optional -
|
|
15002
15002
|
rxp = rxp.replace(/\[[NSEW, +-]{2,}\]/, '(?<prefix>$&)');
|
|
@@ -15020,11 +15020,11 @@
|
|
|
15020
15020
|
rxp = '^' + rxp + '$';
|
|
15021
15021
|
try {
|
|
15022
15022
|
// TODO: make sure all DMS codes have been matched
|
|
15023
|
-
cache
|
|
15023
|
+
cache[fmt] = new RegExp(rxp);
|
|
15024
15024
|
} catch(e) {
|
|
15025
15025
|
stop$1('Invalid DMS format string:', fmt);
|
|
15026
15026
|
}
|
|
15027
|
-
return cache
|
|
15027
|
+
return cache[fmt];
|
|
15028
15028
|
}
|
|
15029
15029
|
|
|
15030
15030
|
function formatNumber(val, integers, decimals) {
|
|
@@ -21150,15 +21150,6 @@
|
|
|
21150
21150
|
getSphereEffectParams: getSphereEffectParams
|
|
21151
21151
|
});
|
|
21152
21152
|
|
|
21153
|
-
var cache = {};
|
|
21154
|
-
function fetchFileSync(url) {
|
|
21155
|
-
if (url in cache) return cache[url];
|
|
21156
|
-
var res = require$1('sync-request')('GET', url, {timeout: 2000});
|
|
21157
|
-
var content = res.getBody().toString();
|
|
21158
|
-
cache[url] = content;
|
|
21159
|
-
return content;
|
|
21160
|
-
}
|
|
21161
|
-
|
|
21162
21153
|
// convert object properties to definitions for images and hatch fills
|
|
21163
21154
|
function convertPropertiesToDefinitions(obj, defs) {
|
|
21164
21155
|
procNode(obj);
|
|
@@ -21183,6 +21174,13 @@
|
|
|
21183
21174
|
function convertSvgImage(obj, defs) {
|
|
21184
21175
|
// Same-origin policy prevents embedding images in the web UI
|
|
21185
21176
|
var href = obj.properties.href;
|
|
21177
|
+
// Remote URLs were previously fetched at export time so the SVG could be
|
|
21178
|
+
// embedded inline. That capability has been removed (it required a
|
|
21179
|
+
// synchronous-HTTP dependency built on a child-process hack); download
|
|
21180
|
+
// the asset first and reference it by local path instead.
|
|
21181
|
+
if (href.indexOf('http') === 0) {
|
|
21182
|
+
stop$1('Remote SVG asset references are not supported. Download the file first and reference it by a local path:', href);
|
|
21183
|
+
}
|
|
21186
21184
|
// look for a previously added definition to use
|
|
21187
21185
|
// (assumes that images that share the same href can also use the same defn)
|
|
21188
21186
|
var item = utils.find(defs, function(item) {return item.href == href;});
|
|
@@ -21200,12 +21198,12 @@
|
|
|
21200
21198
|
}
|
|
21201
21199
|
}
|
|
21202
21200
|
|
|
21203
|
-
// Returns the content of an SVG file from a local path
|
|
21204
|
-
// Returns '' if unable to get the content
|
|
21201
|
+
// Returns the content of an SVG file from a local path.
|
|
21202
|
+
// Returns '' if unable to get the content; the caller leaves the original
|
|
21203
|
+
// <image> tag in the output so the SVG renderer can attempt to load it.
|
|
21205
21204
|
function serializeSvgImage(href, id) {
|
|
21206
21205
|
var svg = '';
|
|
21207
21206
|
try {
|
|
21208
|
-
// try to download the SVG content and use that
|
|
21209
21207
|
svg = convertSvgToDefn(getSvgContent(href), id) + '\n';
|
|
21210
21208
|
svg = '<!-- ' + href + '-->\n' + svg; // add href as a comment, to aid in debugging
|
|
21211
21209
|
} catch(e) {
|
|
@@ -21216,20 +21214,12 @@
|
|
|
21216
21214
|
return svg;
|
|
21217
21215
|
}
|
|
21218
21216
|
|
|
21219
|
-
// href: A
|
|
21220
|
-
// TODO: download SVG files asynchronously
|
|
21221
|
-
// (currently, files are downloaded synchronously, which is obviously undesirable)
|
|
21222
|
-
//
|
|
21217
|
+
// href: A local path
|
|
21223
21218
|
function getSvgContent(href) {
|
|
21224
|
-
|
|
21225
|
-
|
|
21226
|
-
content = fetchFileSync(href);
|
|
21227
|
-
} else if (require$1('fs').existsSync(href)) {
|
|
21228
|
-
content = require$1('fs').readFileSync(href, 'utf8');
|
|
21229
|
-
} else {
|
|
21230
|
-
stop$1("Invalid SVG location:", href);
|
|
21219
|
+
if (require$1('fs').existsSync(href)) {
|
|
21220
|
+
return require$1('fs').readFileSync(href, 'utf8');
|
|
21231
21221
|
}
|
|
21232
|
-
|
|
21222
|
+
stop$1("Invalid SVG location:", href);
|
|
21233
21223
|
}
|
|
21234
21224
|
|
|
21235
21225
|
function convertSvgToDefn(svg, id) {
|
|
@@ -21372,12 +21362,27 @@ ${svg}
|
|
|
21372
21362
|
var geojson = exportDatasetAsGeoJSON(d, opts);
|
|
21373
21363
|
var features = geojson.features || geojson.geometries || (geojson.type ? [geojson] : []);
|
|
21374
21364
|
var children = importGeoJSONFeatures(features, opts);
|
|
21365
|
+
// Drop empty placeholder <g/> elements (features whose geometry was null in the
|
|
21366
|
+
// source data, collapsed during simplification, or otherwise produced no
|
|
21367
|
+
// visible output). Keep the layer's records in lockstep so that data-*
|
|
21368
|
+
// attributes added via -o svg-data= remain correctly aligned.
|
|
21369
|
+
var records = lyr.data ? lyr.data.getRecords() : null;
|
|
21370
|
+
var keptRecords = records ? [] : null;
|
|
21371
|
+
children = children.filter(function(child, i) {
|
|
21372
|
+
if (isEmptyPlaceholder(child)) return false;
|
|
21373
|
+
if (keptRecords) keptRecords.push(records[i]);
|
|
21374
|
+
return true;
|
|
21375
|
+
});
|
|
21375
21376
|
if (opts.svg_data && lyr.data) {
|
|
21376
|
-
addDataAttributesToSVG(children, lyr.data, opts.svg_data);
|
|
21377
|
+
addDataAttributesToSVG(children, keptRecords, lyr.data.getFields(), opts.svg_data);
|
|
21377
21378
|
}
|
|
21378
21379
|
return children;
|
|
21379
21380
|
}
|
|
21380
21381
|
|
|
21382
|
+
function isEmptyPlaceholder(o) {
|
|
21383
|
+
return o.tag == 'g' && (!o.children || o.children.length === 0);
|
|
21384
|
+
}
|
|
21385
|
+
|
|
21381
21386
|
function validateSvgDataFields(layers, fieldsArg) {
|
|
21382
21387
|
var missingFields = fieldsArg.reduce(function(memo, field) {
|
|
21383
21388
|
if (!fieldExists(layers, field)) {
|
|
@@ -21397,15 +21402,13 @@ ${svg}
|
|
|
21397
21402
|
}
|
|
21398
21403
|
}
|
|
21399
21404
|
|
|
21400
|
-
function addDataAttributesToSVG(children,
|
|
21401
|
-
var allFields = table.getFields();
|
|
21405
|
+
function addDataAttributesToSVG(children, records, allFields, fieldsArg) {
|
|
21402
21406
|
var dataFields = fieldsArg.indexOf('*') > -1 ? allFields.concat() : fieldsArg;
|
|
21403
21407
|
var missingFields = utils.difference(dataFields, allFields);
|
|
21404
21408
|
if (missingFields.length > 0) {
|
|
21405
21409
|
dataFields = utils.difference(dataFields, missingFields);
|
|
21406
21410
|
// stop("Missing data field(s):", missingFields.join(', '));
|
|
21407
21411
|
}
|
|
21408
|
-
var records = table.getRecords();
|
|
21409
21412
|
var data = exportDataAttributesForSVG(records, dataFields);
|
|
21410
21413
|
if (children.length != data.length) {
|
|
21411
21414
|
error("Mismatch between number of SVG symbols and data attributes");
|
|
@@ -52127,7 +52130,7 @@ ${svg}
|
|
|
52127
52130
|
});
|
|
52128
52131
|
}
|
|
52129
52132
|
|
|
52130
|
-
var version = "0.7.
|
|
52133
|
+
var version = "0.7.4";
|
|
52131
52134
|
|
|
52132
52135
|
// Parse command line args into commands and run them
|
|
52133
52136
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"url": "git+https://github.com/mbloch/mapshaper.git"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=
|
|
23
|
+
"node": ">=20.11.0"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"test": "mocha test",
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
"/www/**",
|
|
39
39
|
"!/www/nacis/**",
|
|
40
40
|
"/mapshaper.js",
|
|
41
|
-
"!.DS_Store"
|
|
41
|
+
"!.DS_Store",
|
|
42
|
+
"!/www/docs/**",
|
|
43
|
+
"!/www/llms*"
|
|
42
44
|
],
|
|
43
45
|
"dependencies": {
|
|
44
46
|
"@ngageoint/geopackage": "^4.2.6",
|
|
@@ -47,7 +49,7 @@
|
|
|
47
49
|
"@xmldom/xmldom": "^0.8.6",
|
|
48
50
|
"adm-zip": "^0.5.9",
|
|
49
51
|
"big.js": "^7.0.1",
|
|
50
|
-
"commander": "
|
|
52
|
+
"commander": "^14.0.3",
|
|
51
53
|
"cookies": "^0.8.0",
|
|
52
54
|
"d3-color": "3.1.0",
|
|
53
55
|
"d3-interpolate": "^3.0.1",
|
|
@@ -63,9 +65,8 @@
|
|
|
63
65
|
"kdbush": "^3.0.0",
|
|
64
66
|
"mproj": "0.0.40",
|
|
65
67
|
"msgpackr": "^1.10.1",
|
|
66
|
-
"
|
|
68
|
+
"open": "^11.0.0",
|
|
67
69
|
"rw": "~1.3.3",
|
|
68
|
-
"sync-request": "6.1.0",
|
|
69
70
|
"tinyqueue": "^2.0.3"
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
@@ -76,7 +77,7 @@
|
|
|
76
77
|
"eslint": "^8.16.0",
|
|
77
78
|
"highlight.js": "^11.11.1",
|
|
78
79
|
"marked": "^18.0.2",
|
|
79
|
-
"mocha": "^
|
|
80
|
+
"mocha": "^11.7.5",
|
|
80
81
|
"rollup": "^4.44.1",
|
|
81
82
|
"rollup-plugin-polyfill-node": "^0.13.0",
|
|
82
83
|
"shell-quote": "^1.7.4",
|