mapshaper 0.6.0 → 0.6.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/README.md +3 -3
- package/mapshaper.js +242 -202
- package/package.json +7 -4
- package/www/mapshaper-gui.js +61 -51
- package/www/mapshaper.js +242 -202
- package/www/page.css +1 -1
- package/www/assets/iosevka-light.woff +0 -0
- package/www/assets/iosevka-regular.woff +0 -0
- package/www/assets/iosevka-regular.woff2 +0 -0
- package/www/assets/iosevka-slab-light.woff +0 -0
- package/www/assets/iosevka-slab-light.woff2 +0 -0
- package/www/nacis/Makefile +0 -22
- package/www/nacis/Makefile.txt +0 -22
- package/www/nacis/images/close.png +0 -0
- package/www/nacis/images/eye.png +0 -0
- package/www/nacis/images/eye2.png +0 -0
- package/www/nacis/index.html +0 -262
- package/www/nacis/manifest.js +0 -27
- package/www/nacis/map.svg +0 -12308
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"cartography",
|
|
10
10
|
"simplification",
|
|
11
11
|
"topology",
|
|
12
|
-
|
|
12
|
+
"csv",
|
|
13
13
|
"gis"
|
|
14
14
|
],
|
|
15
15
|
"author": "Matthew Bloch <masiyou@gmail.com>",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"scripts": {
|
|
26
26
|
"test": "mocha test",
|
|
27
27
|
"build": "rollup --config",
|
|
28
|
-
|
|
28
|
+
"lint": "eslint --ext mjs src/",
|
|
29
|
+
"prepublishOnly": "npm lint; npm test; ./pre-publish",
|
|
29
30
|
"postpublish": "./release_web_ui; ./release_github_version",
|
|
30
31
|
"browserify": "browserify -r sync-request -r mproj -r buffer -r iconv-lite -r fs -r flatbush -r rw -r path -r kdbush -r @tmcw/togeojson -o www/modules.js",
|
|
31
32
|
"dev": "rollup --config --watch"
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
"/bin/**",
|
|
36
37
|
"/www/**",
|
|
37
38
|
"!/www/basemap.js",
|
|
38
|
-
"!/www/nacis
|
|
39
|
+
"!/www/nacis/**",
|
|
39
40
|
"/mapshaper.js",
|
|
40
41
|
"!.DS_Store"
|
|
41
42
|
],
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
"@rollup/plugin-node-resolve": "^13.3.0",
|
|
62
63
|
"browserify": "^17.0.0",
|
|
63
64
|
"csv-spectrum": "^1.0.0",
|
|
65
|
+
"eslint": "^8.16.0",
|
|
64
66
|
"mocha": "^10.0.0",
|
|
65
67
|
"rollup": "^2.73.0",
|
|
66
68
|
"shell-quote": "^1.6.1",
|
|
@@ -71,6 +73,7 @@
|
|
|
71
73
|
"node-option": [
|
|
72
74
|
"experimental-specifier-resolution=node"
|
|
73
75
|
],
|
|
76
|
+
"check-leaks": true,
|
|
74
77
|
"parallel": true,
|
|
75
78
|
"jobs": 4
|
|
76
79
|
},
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
get findValueByPct () { return findValueByPct; },
|
|
79
79
|
get findValueByRank () { return findValueByRank; },
|
|
80
80
|
get findMedian () { return findMedian; },
|
|
81
|
+
get findQuantile () { return findQuantile; },
|
|
81
82
|
get mean () { return mean; },
|
|
82
83
|
get format () { return format; },
|
|
83
84
|
get formatter () { return formatter; },
|
|
@@ -1682,7 +1683,6 @@
|
|
|
1682
1683
|
}
|
|
1683
1684
|
|
|
1684
1685
|
function Slider(ref, opts) {
|
|
1685
|
-
var _el = El(ref);
|
|
1686
1686
|
var _self = this;
|
|
1687
1687
|
var defaults = {
|
|
1688
1688
|
space: 7
|
|
@@ -1713,7 +1713,7 @@
|
|
|
1713
1713
|
_handle = El(ref);
|
|
1714
1714
|
draggable(_handle)
|
|
1715
1715
|
.on('drag', function(e) {
|
|
1716
|
-
setHandlePos(startX + e.dx
|
|
1716
|
+
setHandlePos(startX + e.dx);
|
|
1717
1717
|
})
|
|
1718
1718
|
.on('dragstart', function(e) {
|
|
1719
1719
|
startX = position();
|
|
@@ -1739,7 +1739,7 @@
|
|
|
1739
1739
|
return _pct;
|
|
1740
1740
|
};
|
|
1741
1741
|
|
|
1742
|
-
function setHandlePos(x
|
|
1742
|
+
function setHandlePos(x) {
|
|
1743
1743
|
x = utils$1.clamp(x, 0, size());
|
|
1744
1744
|
var pct = x / size();
|
|
1745
1745
|
if (pct != _pct) {
|
|
@@ -3122,7 +3122,7 @@
|
|
|
3122
3122
|
|
|
3123
3123
|
function cleanLayerName(raw) {
|
|
3124
3124
|
return raw.replace(/[\n\t/\\]/g, '')
|
|
3125
|
-
.replace(/^[
|
|
3125
|
+
.replace(/^[.\s]+/, '').replace(/[.\s]+$/, '');
|
|
3126
3126
|
}
|
|
3127
3127
|
|
|
3128
3128
|
function updateLayerStackOrder(layers) {
|
|
@@ -3856,8 +3856,6 @@
|
|
|
3856
3856
|
}
|
|
3857
3857
|
}
|
|
3858
3858
|
|
|
3859
|
-
var snapVerticesToPoint = internal.snapVerticesToPoint;
|
|
3860
|
-
var cloneShape = internal.cloneShape;
|
|
3861
3859
|
var copyRecord = internal.copyRecord;
|
|
3862
3860
|
|
|
3863
3861
|
function Undo(gui) {
|
|
@@ -4741,7 +4739,7 @@
|
|
|
4741
4739
|
'/': '/'
|
|
4742
4740
|
};
|
|
4743
4741
|
function htmlEscape(s) {
|
|
4744
|
-
return String(s).replace(/[&<>"'
|
|
4742
|
+
return String(s).replace(/[&<>"'/]/g, function(s) {
|
|
4745
4743
|
return entityMap[s];
|
|
4746
4744
|
});
|
|
4747
4745
|
}
|
|
@@ -5315,18 +5313,24 @@
|
|
|
5315
5313
|
return arr[k];
|
|
5316
5314
|
}
|
|
5317
5315
|
|
|
5318
|
-
//
|
|
5319
|
-
//
|
|
5320
5316
|
function findMedian(arr) {
|
|
5321
|
-
|
|
5322
|
-
rank = Math.floor(n / 2) + 1,
|
|
5323
|
-
median = findValueByRank(arr, rank);
|
|
5324
|
-
if ((n & 1) == 0) {
|
|
5325
|
-
median = (median + findValueByRank(arr, rank - 1)) / 2;
|
|
5326
|
-
}
|
|
5327
|
-
return median;
|
|
5317
|
+
return findQuantile(arr, 0.5);
|
|
5328
5318
|
}
|
|
5329
5319
|
|
|
5320
|
+
function findQuantile(arr, k) {
|
|
5321
|
+
var n = arr.length,
|
|
5322
|
+
i1 = Math.floor((n - 1) * k),
|
|
5323
|
+
i2 = Math.ceil((n - 1) * k);
|
|
5324
|
+
if (i1 < 0 || i2 >= n) return NaN;
|
|
5325
|
+
var v1 = findValueByRank(arr, i1 + 1);
|
|
5326
|
+
if (i1 == i2) return v1;
|
|
5327
|
+
var v2 = findValueByRank(arr, i2 + 1);
|
|
5328
|
+
// use linear interpolation
|
|
5329
|
+
var w1 = i2 / (n - 1) - k;
|
|
5330
|
+
var w2 = k - i1 / (n - 1);
|
|
5331
|
+
var v = (v1 * w1 + v2 * w2) * (n - 1);
|
|
5332
|
+
return v;
|
|
5333
|
+
}
|
|
5330
5334
|
|
|
5331
5335
|
function mean(arr) {
|
|
5332
5336
|
var count = 0,
|
|
@@ -5384,8 +5388,8 @@
|
|
|
5384
5388
|
var type = matches[4];
|
|
5385
5389
|
var isString = type == 's',
|
|
5386
5390
|
isHex = type == 'x' || type == 'X',
|
|
5387
|
-
isInt = type == 'd' || type == 'i',
|
|
5388
|
-
isFloat = type == 'f',
|
|
5391
|
+
// isInt = type == 'd' || type == 'i',
|
|
5392
|
+
// isFloat = type == 'f',
|
|
5389
5393
|
isNumber = !isString;
|
|
5390
5394
|
|
|
5391
5395
|
var sign = "",
|
|
@@ -5444,7 +5448,7 @@
|
|
|
5444
5448
|
|
|
5445
5449
|
// Get a function for interpolating formatted values into a string.
|
|
5446
5450
|
function formatter(fmt) {
|
|
5447
|
-
var codeRxp = /%([
|
|
5451
|
+
var codeRxp = /%([',+0]*)([1-9]?)((?:\.[1-9])?)([sdifxX%])/g;
|
|
5448
5452
|
var literals = [],
|
|
5449
5453
|
formatCodes = [],
|
|
5450
5454
|
startIdx = 0,
|
|
@@ -5844,27 +5848,21 @@
|
|
|
5844
5848
|
|
|
5845
5849
|
function pointTest(x, y) {
|
|
5846
5850
|
var bullseyeDist = 2, // hit all points w/in 2 px
|
|
5847
|
-
tinyDist = 0.5,
|
|
5848
|
-
toPx = ext.getTransform().mx,
|
|
5849
|
-
hits = [],
|
|
5850
5851
|
hitThreshold = 25,
|
|
5851
|
-
|
|
5852
|
+
toPx = ext.getTransform().mx,
|
|
5853
|
+
hits = [];
|
|
5852
5854
|
|
|
5855
|
+
// inlining forEachPoint() does not not appreciably speed this up
|
|
5853
5856
|
internal.forEachPoint(displayLayer.layer.shapes, function(p, id) {
|
|
5854
5857
|
var dist = geom.distance2D(x, y, p[0], p[1]) * toPx;
|
|
5855
5858
|
if (dist > hitThreshold) return;
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
hits = [id];
|
|
5860
|
-
hitThreshold = Math.max(bullseyeDist, dist + tinyDist);
|
|
5861
|
-
newThreshold = dist < bullseyeDist ? -1 : dist - tinyDist;
|
|
5862
|
-
} else {
|
|
5863
|
-
// add to hits if inside bullseye or is same dist as previous hit
|
|
5864
|
-
hits.push(id);
|
|
5859
|
+
if (dist < hitThreshold && hitThreshold > bullseyeDist) {
|
|
5860
|
+
hits = [];
|
|
5861
|
+
hitThreshold = Math.max(bullseyeDist, dist);
|
|
5865
5862
|
}
|
|
5863
|
+
hits.push(id);
|
|
5866
5864
|
});
|
|
5867
|
-
// TODO: add info on what part of a shape gets hit
|
|
5865
|
+
// TODO: add info on what part of a shape gets hit?
|
|
5868
5866
|
return {
|
|
5869
5867
|
ids: utils$1.uniq(hits) // multipoint features can register multiple hits
|
|
5870
5868
|
};
|
|
@@ -8273,20 +8271,25 @@
|
|
|
8273
8271
|
_frame;
|
|
8274
8272
|
|
|
8275
8273
|
_position.on('resize', function(e) {
|
|
8276
|
-
if (
|
|
8274
|
+
if (ready()) {
|
|
8277
8275
|
onChange({resize: true});
|
|
8278
8276
|
}
|
|
8279
8277
|
});
|
|
8280
8278
|
|
|
8279
|
+
function ready() { return !!_contentBounds; }
|
|
8280
|
+
|
|
8281
8281
|
this.reset = function() {
|
|
8282
|
+
if (!ready()) return;
|
|
8282
8283
|
recenter(_contentBounds.centerX(), _contentBounds.centerY(), 1, {reset: true});
|
|
8283
8284
|
};
|
|
8284
8285
|
|
|
8285
8286
|
this.home = function() {
|
|
8287
|
+
if (!ready()) return;
|
|
8286
8288
|
recenter(_contentBounds.centerX(), _contentBounds.centerY(), 1);
|
|
8287
8289
|
};
|
|
8288
8290
|
|
|
8289
8291
|
this.pan = function(xpix, ypix) {
|
|
8292
|
+
if (!ready()) return;
|
|
8290
8293
|
var t = this.getTransform();
|
|
8291
8294
|
recenter(_cx - xpix / t.mx, _cy - ypix / t.my);
|
|
8292
8295
|
};
|
|
@@ -8294,6 +8297,7 @@
|
|
|
8294
8297
|
// Zoom to @w (width of the map viewport in coordinates)
|
|
8295
8298
|
// @xpct, @ypct: optional focus, [0-1]...
|
|
8296
8299
|
this.zoomToExtent = function(w, xpct, ypct) {
|
|
8300
|
+
if (!ready()) return;
|
|
8297
8301
|
if (arguments.length < 3) {
|
|
8298
8302
|
xpct = 0.5;
|
|
8299
8303
|
ypct = 0.5;
|
|
@@ -8313,6 +8317,7 @@
|
|
|
8313
8317
|
};
|
|
8314
8318
|
|
|
8315
8319
|
this.zoomByPct = function(pct, xpct, ypct) {
|
|
8320
|
+
if (!ready()) return;
|
|
8316
8321
|
this.zoomToExtent(this.getBounds().width() / pct, xpct, ypct);
|
|
8317
8322
|
};
|
|
8318
8323
|
|
|
@@ -8754,7 +8759,7 @@
|
|
|
8754
8759
|
bx = t.bx,
|
|
8755
8760
|
by = t.by;
|
|
8756
8761
|
if (size === 0) return;
|
|
8757
|
-
if (size <=
|
|
8762
|
+
if (size <= 6 && !styler) {
|
|
8758
8763
|
// optimized drawing of many small same-colored dots
|
|
8759
8764
|
_self.drawSquareDotsFaster(shapes, color, size, t);
|
|
8760
8765
|
return;
|
|
@@ -8811,14 +8816,12 @@
|
|
|
8811
8816
|
// pixels: Uint32Array of pixel colors
|
|
8812
8817
|
// w, h: Size of canvas
|
|
8813
8818
|
function drawSquareFaster(x, y, rgba, size, pixels, w, h) {
|
|
8814
|
-
var xmin = (x - size * 0.5) | 0;
|
|
8815
|
-
var ymin = (y - size * 0.5) | 0;
|
|
8816
|
-
var xmax = xmin + size - 1;
|
|
8817
|
-
var ymax = ymin + size - 1;
|
|
8818
|
-
var
|
|
8819
|
-
|
|
8820
|
-
if (c < 0 || c >= w) continue;
|
|
8821
|
-
for (r = ymin; r <= ymax && r >= 0 && r < h; r++) {
|
|
8819
|
+
var xmin = x < 0 ? 0 : (x - size * 0.5) | 0;
|
|
8820
|
+
var ymin = y < 0 ? 0 : (y - size * 0.5) | 0;
|
|
8821
|
+
var xmax = x >= w-1 ? w-1 : xmin + size - 1;
|
|
8822
|
+
var ymax = y >= h-1 ? h-1 : ymin + size - 1;
|
|
8823
|
+
for (var r = ymin; r <= ymax; r++) {
|
|
8824
|
+
for (var c = xmin; c <= xmax; c++) {
|
|
8822
8825
|
pixels[r * w + c] = rgba;
|
|
8823
8826
|
}
|
|
8824
8827
|
}
|
|
@@ -8905,24 +8908,25 @@
|
|
|
8905
8908
|
return s;
|
|
8906
8909
|
}
|
|
8907
8910
|
|
|
8908
|
-
|
|
8909
8911
|
function getDotScale(ext) {
|
|
8910
8912
|
var smallSide = Math.min(ext.width(), ext.height());
|
|
8913
|
+
var mapScale = ext.scale();
|
|
8911
8914
|
// reduce size on smaller screens
|
|
8912
8915
|
var j = smallSide < 200 && 0.5 || smallSide < 400 && 0.75 || 1;
|
|
8916
|
+
// grow dots as map zooms in
|
|
8913
8917
|
var k = 1;
|
|
8914
|
-
var mapScale = ext.scale();
|
|
8915
8918
|
if (mapScale < 0.5) {
|
|
8916
8919
|
k = Math.pow(mapScale + 0.5, 0.35);
|
|
8917
|
-
}
|
|
8918
|
-
if (mapScale > 1) {
|
|
8920
|
+
} else if (mapScale > 1) {
|
|
8919
8921
|
// scale faster at first, so small dots in large datasets
|
|
8920
8922
|
// become easily visible and clickable after zooming in a bit
|
|
8921
8923
|
k *= Math.pow(Math.min(mapScale, 10), 0.3);
|
|
8922
8924
|
k *= Math.pow(mapScale, 0.1);
|
|
8923
8925
|
}
|
|
8924
|
-
|
|
8925
|
-
|
|
8926
|
+
// grow pixels more slowly on retina displays (to reduce number of pixels to
|
|
8927
|
+
// draw for large point datasets when slightly zoomed in)
|
|
8928
|
+
var l = Math.pow(GUI.getPixelRatio(), 0.8);
|
|
8929
|
+
return j * k * l;
|
|
8926
8930
|
}
|
|
8927
8931
|
|
|
8928
8932
|
function getScaledTransform(ext) {
|
|
@@ -9495,7 +9499,7 @@
|
|
|
9495
9499
|
|
|
9496
9500
|
// Only generate low-detail arcs for larger datasets
|
|
9497
9501
|
if (size > 5e5) {
|
|
9498
|
-
if (
|
|
9502
|
+
if (unfilteredArcs.getVertexData().zz) {
|
|
9499
9503
|
// Use precalculated simplification data for vertex filtering, if available
|
|
9500
9504
|
filteredArcs = initFilteredArcs(unfilteredArcs);
|
|
9501
9505
|
filteredSegLen = internal.getAvgSegment(filteredArcs);
|
|
@@ -9861,7 +9865,13 @@
|
|
|
9861
9865
|
var warning;
|
|
9862
9866
|
|
|
9863
9867
|
if (!dataCRS || !displayCRS || !crsIsUsable(displayCRS) || !crsIsUsable(dataCRS)) {
|
|
9864
|
-
warning = '
|
|
9868
|
+
warning = 'This data is incompatible with the basemaps.';
|
|
9869
|
+
if (!internal.layerHasGeometry(activeLyr.layer)) {
|
|
9870
|
+
warning += ' Reason: layer is missing geographic data';
|
|
9871
|
+
} else if (!dataCRS) {
|
|
9872
|
+
warning += ' Reason: unknown projection.';
|
|
9873
|
+
}
|
|
9874
|
+
|
|
9865
9875
|
basemapWarning.html(warning).show();
|
|
9866
9876
|
basemapNote.hide();
|
|
9867
9877
|
} else {
|