mapshaper 0.6.87 → 0.6.89
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/mapshaper.js +28 -22
- package/package.json +2 -2
- package/www/index.html +2 -2
- package/www/mapshaper-gui.js +108 -67
- package/www/mapshaper.js +28 -22
- package/www/page.css +15 -4
package/mapshaper.js
CHANGED
|
@@ -5004,11 +5004,12 @@
|
|
|
5004
5004
|
}
|
|
5005
5005
|
|
|
5006
5006
|
function toLngLat(xy, P) {
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5007
|
+
return projectPoint(xy, P, parseCrsString('wgs84'));
|
|
5008
|
+
}
|
|
5009
|
+
|
|
5010
|
+
function projectPoint(xy, crsFrom, crsTo) {
|
|
5011
|
+
if (crsAreEqual(crsFrom, crsTo)) return xy.concat();
|
|
5012
|
+
var proj = getProjTransform2(crsFrom, crsTo);
|
|
5012
5013
|
return proj(xy[0], xy[1]);
|
|
5013
5014
|
}
|
|
5014
5015
|
|
|
@@ -5242,6 +5243,7 @@
|
|
|
5242
5243
|
getProjTransform: getProjTransform,
|
|
5243
5244
|
getProjTransform2: getProjTransform2,
|
|
5244
5245
|
toLngLat: toLngLat,
|
|
5246
|
+
projectPoint: projectPoint,
|
|
5245
5247
|
getProjInfo: getProjInfo,
|
|
5246
5248
|
crsToProj4: crsToProj4,
|
|
5247
5249
|
crsToPrj: crsToPrj,
|
|
@@ -5582,6 +5584,7 @@
|
|
|
5582
5584
|
var arcOffs = _ii[i];
|
|
5583
5585
|
var j = i * 4;
|
|
5584
5586
|
var b = calcArcBounds(_xx, _yy, arcOffs, arcLen);
|
|
5587
|
+
// NOTE: if arcLen is 0, bounds coords are undefined, coerced to NaN in _bb.
|
|
5585
5588
|
_bb[j++] = b[0];
|
|
5586
5589
|
_bb[j++] = b[1];
|
|
5587
5590
|
_bb[j++] = b[2];
|
|
@@ -5994,12 +5997,14 @@
|
|
|
5994
5997
|
this.arcIntersectsBBox = function(i, b1) {
|
|
5995
5998
|
var b2 = _bb,
|
|
5996
5999
|
j = i * 4;
|
|
6000
|
+
// returns false if _bb bounds are NaN
|
|
5997
6001
|
return b2[j] <= b1[2] && b2[j+2] >= b1[0] && b2[j+3] >= b1[1] && b2[j+1] <= b1[3];
|
|
5998
6002
|
};
|
|
5999
6003
|
|
|
6000
6004
|
this.arcIsContained = function(i, b1) {
|
|
6001
6005
|
var b2 = _bb,
|
|
6002
6006
|
j = i * 4;
|
|
6007
|
+
// returns false if _bb bounds are NaN
|
|
6003
6008
|
return b2[j] >= b1[0] && b2[j+2] <= b1[2] && b2[j+1] >= b1[1] && b2[j+3] <= b1[3];
|
|
6004
6009
|
};
|
|
6005
6010
|
|
|
@@ -6036,22 +6041,21 @@
|
|
|
6036
6041
|
return bounds;
|
|
6037
6042
|
};
|
|
6038
6043
|
|
|
6039
|
-
this.
|
|
6044
|
+
this.getSimpleShapeBbox = function(arcIds, arr) {
|
|
6040
6045
|
var bbox = arr || [],
|
|
6041
6046
|
bb = _bb,
|
|
6042
|
-
|
|
6043
|
-
bbox[0] =
|
|
6044
|
-
bbox[
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
if (bb[
|
|
6050
|
-
if (bb[++
|
|
6051
|
-
if (bb[++
|
|
6052
|
-
if (bb[++id] > bbox[3]) bbox[3] = bb[id];
|
|
6047
|
+
arcId, offs;
|
|
6048
|
+
bbox[0] = bbox[1] = Infinity;
|
|
6049
|
+
bbox[2] = bbox[3] = -Infinity;
|
|
6050
|
+
for (var i=0, n=arcIds.length; i<n; i++) {
|
|
6051
|
+
arcId = absArcId(arcIds[i]);
|
|
6052
|
+
offs = arcId * 4;
|
|
6053
|
+
if (bb[offs] < bbox[0]) bbox[0] = bb[offs];
|
|
6054
|
+
if (bb[++offs] < bbox[1]) bbox[1] = bb[offs];
|
|
6055
|
+
if (bb[++offs] > bbox[2]) bbox[2] = bb[offs];
|
|
6056
|
+
if (bb[++offs] > bbox[3]) bbox[3] = bb[offs];
|
|
6053
6057
|
}
|
|
6054
|
-
return bbox;
|
|
6058
|
+
return bbox[0] == Infinity ? [] : bbox;
|
|
6055
6059
|
};
|
|
6056
6060
|
|
|
6057
6061
|
// TODO: move this and similar methods out of ArcCollection
|
|
@@ -6068,7 +6072,9 @@
|
|
|
6068
6072
|
this.mergeArcBounds = function(arcId, bounds) {
|
|
6069
6073
|
if (arcId < 0) arcId = ~arcId;
|
|
6070
6074
|
var offs = arcId * 4;
|
|
6071
|
-
|
|
6075
|
+
if (_nn[arcId] > 0) {
|
|
6076
|
+
bounds.mergeBounds(_bb[offs], _bb[offs+1], _bb[offs+2], _bb[offs+3]);
|
|
6077
|
+
}
|
|
6072
6078
|
};
|
|
6073
6079
|
}
|
|
6074
6080
|
|
|
@@ -17254,7 +17260,7 @@
|
|
|
17254
17260
|
}
|
|
17255
17261
|
|
|
17256
17262
|
function procShapeRing(path) {
|
|
17257
|
-
currRingBbox = arcs.
|
|
17263
|
+
currRingBbox = arcs.getSimpleShapeBbox(path);
|
|
17258
17264
|
ringIndex.setIds(path);
|
|
17259
17265
|
procArcIds(path);
|
|
17260
17266
|
ringIndex.clear();
|
|
@@ -38149,7 +38155,7 @@ ${svg}
|
|
|
38149
38155
|
|
|
38150
38156
|
// Assumes that ring boundaries to not cross
|
|
38151
38157
|
function ringHasHoles(ring, rings, arcs) {
|
|
38152
|
-
var bbox = arcs.
|
|
38158
|
+
var bbox = arcs.getSimpleShapeBbox(ring);
|
|
38153
38159
|
var sibling, p;
|
|
38154
38160
|
for (var i=0, n=rings.length; i<n; i++) {
|
|
38155
38161
|
sibling = rings[i];
|
|
@@ -45578,7 +45584,7 @@ ${svg}
|
|
|
45578
45584
|
});
|
|
45579
45585
|
}
|
|
45580
45586
|
|
|
45581
|
-
var version = "0.6.
|
|
45587
|
+
var version = "0.6.89";
|
|
45582
45588
|
|
|
45583
45589
|
// Parse command line args into commands and run them
|
|
45584
45590
|
// 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.6.
|
|
3
|
+
"version": "0.6.89",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"iconv-lite": "^0.6.3",
|
|
57
57
|
"idb-keyval": "^6.2.0",
|
|
58
58
|
"kdbush": "^3.0.0",
|
|
59
|
-
"mproj": "0.0.
|
|
59
|
+
"mproj": "0.0.39",
|
|
60
60
|
"msgpackr": "^1.10.1",
|
|
61
61
|
"opn": "^5.3.0",
|
|
62
62
|
"rw": "~1.3.3",
|
package/www/index.html
CHANGED
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
<div class="erase-btn btn sidebar-btn">Erase</div>
|
|
124
124
|
<div class="rect-btn btn sidebar-btn">Rectangle</div>
|
|
125
125
|
<div class="frame-btn btn sidebar-btn">Frame</div>
|
|
126
|
-
<div class="info-btn btn sidebar-btn">
|
|
126
|
+
<div class="info-btn btn sidebar-btn">Bounds</div>
|
|
127
127
|
<div class="box-coords selectable"></div>
|
|
128
128
|
<div class="cancel-btn btn sidebar-btn">Cancel</div>
|
|
129
129
|
</div>
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
<div class="filter-btn btn sidebar-btn">Keep</div>
|
|
136
136
|
<div class="duplicate-btn btn sidebar-btn">Duplicate</div>
|
|
137
137
|
<div class="split-btn btn sidebar-btn">Split</div>
|
|
138
|
-
<div class="coords-btn btn sidebar-btn toggle-btn">
|
|
138
|
+
<div class="coords-btn btn sidebar-btn toggle-btn">Bounds</div>
|
|
139
139
|
<div class="box-coords selectable"></div>
|
|
140
140
|
<div class="data-btn btn sidebar-btn toggle-btn">Edit data</div>
|
|
141
141
|
<div class="cancel-btn btn sidebar-btn">Clear</div>
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -3500,15 +3500,6 @@
|
|
|
3500
3500
|
}
|
|
3501
3501
|
}
|
|
3502
3502
|
|
|
3503
|
-
function deleteFeature(lyr, fid) {
|
|
3504
|
-
var records = lyr.data?.getRecords();
|
|
3505
|
-
if (records) records.splice(fid, 1);
|
|
3506
|
-
lyr.shapes.splice(fid, 1);
|
|
3507
|
-
if (isProjectedLayer(lyr) && lyr.shapes != lyr.gui.displayLayer.shapes) {
|
|
3508
|
-
lyr.gui.displayLayer.shapes.splice(fid, 1);
|
|
3509
|
-
}
|
|
3510
|
-
}
|
|
3511
|
-
|
|
3512
3503
|
// p: one point in source data coords
|
|
3513
3504
|
function appendNewPoint(lyr, p) {
|
|
3514
3505
|
lyr.shapes.push([p]);
|
|
@@ -3521,15 +3512,20 @@
|
|
|
3521
3512
|
}
|
|
3522
3513
|
}
|
|
3523
3514
|
|
|
3524
|
-
function
|
|
3525
|
-
|
|
3515
|
+
function deleteFeature(lyr, fid) {
|
|
3516
|
+
var records = lyr.data?.getRecords();
|
|
3517
|
+
if (records) records.splice(fid, 1);
|
|
3518
|
+
lyr.shapes.splice(fid, 1);
|
|
3519
|
+
if (isProjectedLayer(lyr) && lyr.geometry_type == 'point') {
|
|
3520
|
+
lyr.gui.displayLayer.shapes.splice(fid, 1); // point layer
|
|
3521
|
+
}
|
|
3526
3522
|
}
|
|
3527
3523
|
|
|
3528
|
-
function
|
|
3524
|
+
function insertFeature(lyr, fid, shp, d) {
|
|
3529
3525
|
var records = lyr.data?.getRecords();
|
|
3530
3526
|
if (records) records.splice(fid, 0, d);
|
|
3531
3527
|
lyr.shapes.splice(fid, 0, shp);
|
|
3532
|
-
if (isProjectedLayer(lyr)) {
|
|
3528
|
+
if (isProjectedLayer(lyr) && lyr.geometry_type == 'point') {
|
|
3533
3529
|
var shp2 = projectPointCoords(shp, lyr.gui.projectPoint);
|
|
3534
3530
|
lyr.gui.displayLayer.shapes.splice(fid, 0, shp2);
|
|
3535
3531
|
}
|
|
@@ -4255,6 +4251,10 @@
|
|
|
4255
4251
|
setDisplayProjection(gui, cmd);
|
|
4256
4252
|
} else {
|
|
4257
4253
|
line.hide(); // hide cursor while command is being run
|
|
4254
|
+
// quit certain edit modes
|
|
4255
|
+
if (!gui.interaction.modeWorksWithConsole(gui.interaction.getMode())) {
|
|
4256
|
+
gui.interaction.turnOff();
|
|
4257
|
+
}
|
|
4258
4258
|
runMapshaperCommands(cmd, function(err, flags) {
|
|
4259
4259
|
if (flags) {
|
|
4260
4260
|
gui.clearMode();
|
|
@@ -5606,12 +5606,12 @@
|
|
|
5606
5606
|
addHistoryState(undo, redo);
|
|
5607
5607
|
});
|
|
5608
5608
|
|
|
5609
|
-
gui.on('
|
|
5609
|
+
gui.on('feature_delete', function(e) {
|
|
5610
5610
|
var redo = function() {
|
|
5611
|
-
|
|
5611
|
+
deleteFeature(e.data.target, e.fid);
|
|
5612
5612
|
};
|
|
5613
5613
|
var undo = function() {
|
|
5614
|
-
|
|
5614
|
+
insertFeature(e.data.target, e.fid, e.coords, e.d);
|
|
5615
5615
|
};
|
|
5616
5616
|
addHistoryState(undo, redo);
|
|
5617
5617
|
});
|
|
@@ -5833,7 +5833,7 @@
|
|
|
5833
5833
|
|
|
5834
5834
|
document.addEventListener('keydown', function(e) {
|
|
5835
5835
|
if (!GUI.isActiveInstance(gui) || e.repeat && e.keyCode == 32) return;
|
|
5836
|
-
updateControlKeys(e, '
|
|
5836
|
+
updateControlKeys(e, 'keydown');
|
|
5837
5837
|
self.dispatchEvent('keydown', getEventData(e));
|
|
5838
5838
|
});
|
|
5839
5839
|
|
|
@@ -5966,6 +5966,10 @@
|
|
|
5966
5966
|
setMode('off');
|
|
5967
5967
|
};
|
|
5968
5968
|
|
|
5969
|
+
this.modeWorksWithConsole = function(mode) {
|
|
5970
|
+
return ['off', 'info'];
|
|
5971
|
+
};
|
|
5972
|
+
|
|
5969
5973
|
this.modeUsesHitDetection = function(mode) {
|
|
5970
5974
|
return ['info', 'selection', 'data', 'labels', 'edit_points', 'vertices', 'rectangles', 'edit_lines', 'edit_polygons'].includes(mode);
|
|
5971
5975
|
};
|
|
@@ -7904,7 +7908,7 @@
|
|
|
7904
7908
|
return;
|
|
7905
7909
|
}
|
|
7906
7910
|
for (var i = 0, n = shp && shp.length; i < n; i++) {
|
|
7907
|
-
arcs.
|
|
7911
|
+
arcs.getSimpleShapeBbox(shp[i], bbox);
|
|
7908
7912
|
if (x + dist < bbox[0] || x - dist > bbox[2] ||
|
|
7909
7913
|
y + dist < bbox[1] || y - dist > bbox[3]) {
|
|
7910
7914
|
continue; // bbox non-intersection
|
|
@@ -8497,8 +8501,8 @@
|
|
|
8497
8501
|
};
|
|
8498
8502
|
if (evt) {
|
|
8499
8503
|
// data coordinates
|
|
8500
|
-
eventData.
|
|
8501
|
-
eventData.
|
|
8504
|
+
eventData.projected_coordinates = gui.map.pixelCoordsToProjectedCoords(evt.x, evt.y);
|
|
8505
|
+
eventData.lonlat_coordinates = gui.map.pixelCoordsToLngLatCoords(evt.x, evt.y);
|
|
8502
8506
|
eventData.originalEvent = evt;
|
|
8503
8507
|
eventData.overMap = isOverMap(evt);
|
|
8504
8508
|
}
|
|
@@ -10243,8 +10247,8 @@
|
|
|
10243
10247
|
function removePoint(target, id) {
|
|
10244
10248
|
var d = target.data ? target.data.getRecords()[id] : null;
|
|
10245
10249
|
var coords = target.shapes[id];
|
|
10246
|
-
|
|
10247
|
-
gui.dispatchEvent('
|
|
10250
|
+
deleteFeature(target, id);
|
|
10251
|
+
gui.dispatchEvent('feature_delete', {coords, d, target, fid: id});
|
|
10248
10252
|
gui.dispatchEvent('map-needs-refresh');
|
|
10249
10253
|
hit.setHitId(-1);
|
|
10250
10254
|
}
|
|
@@ -10316,7 +10320,7 @@
|
|
|
10316
10320
|
|
|
10317
10321
|
function initLineEditing(gui, ext, hit) {
|
|
10318
10322
|
var hoverVertexInfo;
|
|
10319
|
-
var
|
|
10323
|
+
var prevVertexAddedEvent;
|
|
10320
10324
|
var prevHoverEvent;
|
|
10321
10325
|
var initialArcCount = -1;
|
|
10322
10326
|
var initialShapeCount = -1;
|
|
@@ -10487,12 +10491,12 @@
|
|
|
10487
10491
|
hit.clearDrawingId();
|
|
10488
10492
|
drawingId = -1;
|
|
10489
10493
|
hoverVertexInfo = null;
|
|
10490
|
-
|
|
10494
|
+
prevVertexAddedEvent = prevHoverEvent = null;
|
|
10491
10495
|
updateCursor();
|
|
10492
10496
|
}
|
|
10493
10497
|
|
|
10494
10498
|
gui.keyboard.on('keydown', function(e) {
|
|
10495
|
-
if (
|
|
10499
|
+
if (pathDrawing() && e.keyName == 'space') {
|
|
10496
10500
|
e.stopPropagation(); // prevent console from opening if shift-panning
|
|
10497
10501
|
}
|
|
10498
10502
|
}, null, 1);
|
|
@@ -10506,6 +10510,7 @@
|
|
|
10506
10510
|
deleteActiveVertex(e, vInfo);
|
|
10507
10511
|
};
|
|
10508
10512
|
}
|
|
10513
|
+
|
|
10509
10514
|
// don't allow copying of open paths as geojson in polygon mode
|
|
10510
10515
|
gui.contextMenu.open(e, target);
|
|
10511
10516
|
});
|
|
@@ -10544,6 +10549,7 @@
|
|
|
10544
10549
|
hoverVertexInfo = findPathStartInfo(e);
|
|
10545
10550
|
var xy = [e.x, e.y], xy2;
|
|
10546
10551
|
var p = pixToDataCoords(e.x, e.y);
|
|
10552
|
+
var addedToPath = true;
|
|
10547
10553
|
if (!pathDrawing()) {
|
|
10548
10554
|
pencilPoints = [xy];
|
|
10549
10555
|
startNewPath(p);
|
|
@@ -10557,7 +10563,7 @@
|
|
|
10557
10563
|
appendVertex$1(hit.getHitTarget(), p);
|
|
10558
10564
|
extendCurrentPath(p);
|
|
10559
10565
|
pencilPoints = null; // stop drawing
|
|
10560
|
-
} else if (pencilPoints.length >= 2 && pointExceedsTolerance(xy, pencilPoints, 1.
|
|
10566
|
+
} else if (pencilPoints.length >= 2 && pointExceedsTolerance(xy, pencilPoints, 1.2)) {
|
|
10561
10567
|
xy2 = pencilPoints.pop();
|
|
10562
10568
|
p = pixToDataCoords(xy2[0], xy2[1]);
|
|
10563
10569
|
extendCurrentPath(p);
|
|
@@ -10569,6 +10575,11 @@
|
|
|
10569
10575
|
// skip this point, update the hover line
|
|
10570
10576
|
pencilPoints.push(xy);
|
|
10571
10577
|
updatePathEndpoint(p);
|
|
10578
|
+
addedToPath = false;
|
|
10579
|
+
}
|
|
10580
|
+
if (addedToPath) {
|
|
10581
|
+
//
|
|
10582
|
+
prevVertexAddedEvent = e;
|
|
10572
10583
|
}
|
|
10573
10584
|
}, null, 3); // higher priority than hit control
|
|
10574
10585
|
|
|
@@ -10625,7 +10636,7 @@
|
|
|
10625
10636
|
return;
|
|
10626
10637
|
}
|
|
10627
10638
|
if (gui.keyboard.shiftIsPressed()) {
|
|
10628
|
-
alignPointerPosition(e,
|
|
10639
|
+
alignPointerPosition(e, prevVertexAddedEvent);
|
|
10629
10640
|
}
|
|
10630
10641
|
updatePathEndpoint(pixToDataCoords(e.x, e.y));
|
|
10631
10642
|
}
|
|
@@ -10658,12 +10669,12 @@
|
|
|
10658
10669
|
} else {
|
|
10659
10670
|
startNewPath(p);
|
|
10660
10671
|
}
|
|
10661
|
-
|
|
10672
|
+
prevVertexAddedEvent = e;
|
|
10662
10673
|
});
|
|
10663
10674
|
|
|
10664
10675
|
// esc or enter key finishes a path
|
|
10665
10676
|
gui.keyboard.on('keydown', function(e) {
|
|
10666
|
-
if (
|
|
10677
|
+
if (pathDrawing() && (e.keyName == 'esc' || e.keyName == 'enter')) {
|
|
10667
10678
|
e.stopPropagation();
|
|
10668
10679
|
finishCurrentPath();
|
|
10669
10680
|
e.originalEvent.preventDefault(); // block console "enter"
|
|
@@ -10672,10 +10683,10 @@
|
|
|
10672
10683
|
|
|
10673
10684
|
// detect second 'click' event of a double-click action
|
|
10674
10685
|
function detectDoubleClick(evt) {
|
|
10675
|
-
if (!
|
|
10676
|
-
var elapsed = evt.time -
|
|
10677
|
-
var dx = Math.abs(evt.x -
|
|
10678
|
-
var dy = Math.abs(evt.y -
|
|
10686
|
+
if (!prevVertexAddedEvent) return false;
|
|
10687
|
+
var elapsed = evt.time - prevVertexAddedEvent.time;
|
|
10688
|
+
var dx = Math.abs(evt.x - prevVertexAddedEvent.x);
|
|
10689
|
+
var dy = Math.abs(evt.y - prevVertexAddedEvent.y);
|
|
10679
10690
|
var dbl = elapsed < 500 && dx <= 2 && dy <= 2;
|
|
10680
10691
|
return dbl;
|
|
10681
10692
|
}
|
|
@@ -12394,21 +12405,24 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12394
12405
|
target.layer.pinned = !!pinned;
|
|
12395
12406
|
};
|
|
12396
12407
|
|
|
12397
|
-
this.
|
|
12398
|
-
var
|
|
12399
|
-
if (!
|
|
12400
|
-
|
|
12408
|
+
this.pixelCoordsToLngLatCoords = function(x, y) {
|
|
12409
|
+
var crsFrom = this.getDisplayCRS();
|
|
12410
|
+
if (!crsFrom) return null; // e.g. table view
|
|
12411
|
+
var p1 = internal.toLngLat(_ext.translatePixelCoords(x, y), crsFrom);
|
|
12412
|
+
var p2 = internal.toLngLat(_ext.translatePixelCoords(x+1, y+1), crsFrom);
|
|
12413
|
+
return p1 && p2 && p1[1] <= 90 && p1[1] >= -90 ?
|
|
12414
|
+
formatCoordsForDisplay(p1, p2) : null;
|
|
12401
12415
|
};
|
|
12402
12416
|
|
|
12403
|
-
this.
|
|
12404
|
-
|
|
12405
|
-
var
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
p1 = internal.toLngLat(p1, crs) || p1;
|
|
12409
|
-
p2 = internal.toLngLat(p2, crs) || p2;
|
|
12417
|
+
this.pixelCoordsToProjectedCoords = function(x, y) {
|
|
12418
|
+
if (!_activeLyr) return null;
|
|
12419
|
+
var info = getDatasetCrsInfo(_activeLyr.gui.source.dataset);
|
|
12420
|
+
if (info && internal.isLatLngCRS(info.crs)) {
|
|
12421
|
+
return null; // latlon dataset
|
|
12410
12422
|
}
|
|
12411
|
-
|
|
12423
|
+
var p1 = translateDisplayPoint(_activeLyr, _ext.translatePixelCoords(x, y));
|
|
12424
|
+
var p2 = translateDisplayPoint(_activeLyr, _ext.translatePixelCoords(x+1, y+1));
|
|
12425
|
+
return p1 && p2 ? formatCoordsForDisplay(p1, p2) : null;
|
|
12412
12426
|
};
|
|
12413
12427
|
|
|
12414
12428
|
// this.getCenterLngLat = function() {
|
|
@@ -12885,21 +12899,64 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12885
12899
|
}
|
|
12886
12900
|
|
|
12887
12901
|
function addMenuItem(label, func) {
|
|
12902
|
+
var prefix = '• ';
|
|
12903
|
+
|
|
12888
12904
|
El('div')
|
|
12889
12905
|
.appendTo(menu)
|
|
12890
12906
|
.addClass('contextmenu-item')
|
|
12891
|
-
.html(label)
|
|
12907
|
+
.html(prefix + label)
|
|
12892
12908
|
.on('click', func)
|
|
12893
12909
|
.show();
|
|
12894
12910
|
}
|
|
12895
12911
|
|
|
12912
|
+
function addMenuLabel(label) {
|
|
12913
|
+
El('div')
|
|
12914
|
+
.appendTo(menu)
|
|
12915
|
+
.addClass('contextmenu-label')
|
|
12916
|
+
.html(label);
|
|
12917
|
+
}
|
|
12918
|
+
|
|
12896
12919
|
this.open = function(e, lyr) {
|
|
12920
|
+
var copyable = e.ids?.length;
|
|
12897
12921
|
if (lyr && !lyr.gui.geographic) return; // no popup for tabular data
|
|
12922
|
+
menu.empty();
|
|
12923
|
+
|
|
12924
|
+
// menu contents
|
|
12925
|
+
//
|
|
12926
|
+
if (e.deleteVertex || e.deletePoint || copyable || e.deleteFeature) {
|
|
12927
|
+
|
|
12928
|
+
addMenuLabel('selection');
|
|
12929
|
+
if (e.deleteVertex) {
|
|
12930
|
+
addMenuItem('delete vertex', e.deleteVertex);
|
|
12931
|
+
}
|
|
12932
|
+
if (e.deletePoint) {
|
|
12933
|
+
addMenuItem('delete point', e.deletePoint);
|
|
12934
|
+
}
|
|
12935
|
+
if (e.ids?.length) {
|
|
12936
|
+
addMenuItem('copy as GeoJSON', copyGeoJSON);
|
|
12937
|
+
}
|
|
12938
|
+
if (e.deleteFeature) {
|
|
12939
|
+
addMenuItem(getDeleteLabel(), e.deleteFeature);
|
|
12940
|
+
}
|
|
12941
|
+
}
|
|
12942
|
+
|
|
12943
|
+
if (e.lonlat_coordinates) {
|
|
12944
|
+
addMenuLabel('longitude, latitude');
|
|
12945
|
+
addCoords(e.lonlat_coordinates);
|
|
12946
|
+
}
|
|
12947
|
+
if (e.projected_coordinates) {
|
|
12948
|
+
addMenuLabel('easting, northing');
|
|
12949
|
+
addCoords(e.projected_coordinates);
|
|
12950
|
+
}
|
|
12951
|
+
|
|
12952
|
+
if (menu.node().childNodes.length === 0) {
|
|
12953
|
+
return;
|
|
12954
|
+
}
|
|
12955
|
+
|
|
12898
12956
|
_open = true;
|
|
12899
12957
|
_openCount++;
|
|
12900
12958
|
var rspace = body.clientWidth - e.pageX;
|
|
12901
12959
|
var xoffs = 10;
|
|
12902
|
-
menu.empty().show();
|
|
12903
12960
|
if (rspace > 150) {
|
|
12904
12961
|
menu.css('left', e.pageX + xoffs + 'px');
|
|
12905
12962
|
menu.css('right', null);
|
|
@@ -12908,32 +12965,16 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12908
12965
|
menu.css('left', null);
|
|
12909
12966
|
}
|
|
12910
12967
|
menu.css('top', (e.pageY - 15) + 'px');
|
|
12911
|
-
|
|
12912
|
-
// menu contents
|
|
12913
|
-
//
|
|
12914
|
-
if (e.display_coordinates) {
|
|
12915
|
-
addCoords(e.display_coordinates);
|
|
12916
|
-
}
|
|
12917
|
-
if (e.deleteVertex) {
|
|
12918
|
-
addMenuItem('Delete vertex', e.deleteVertex);
|
|
12919
|
-
}
|
|
12920
|
-
if (e.deletePoint) {
|
|
12921
|
-
addMenuItem('Delete point', e.deletePoint);
|
|
12922
|
-
}
|
|
12923
|
-
if (e.ids?.length) {
|
|
12924
|
-
addMenuItem('Copy as GeoJSON', copyGeoJSON);
|
|
12925
|
-
}
|
|
12926
|
-
if (e.deleteFeature) {
|
|
12927
|
-
addMenuItem(getDeleteLabel(), e.deleteFeature);
|
|
12928
|
-
}
|
|
12968
|
+
menu.show();
|
|
12929
12969
|
|
|
12930
12970
|
function getDeleteLabel() {
|
|
12931
|
-
return '
|
|
12971
|
+
return 'delete ' + (lyr.geometry_type == 'point' ? 'point' : 'shape');
|
|
12932
12972
|
}
|
|
12933
12973
|
|
|
12934
12974
|
function addCoords(p) {
|
|
12935
12975
|
var coordStr = p[0] + ',' + p[1];
|
|
12936
|
-
var displayStr = '• ' + coordStr.replace(/-/g, '–').replace(',', ', ');
|
|
12976
|
+
// var displayStr = '• ' + coordStr.replace(/-/g, '–').replace(',', ', ');
|
|
12977
|
+
var displayStr = coordStr.replace(/-/g, '–').replace(',', ', ');
|
|
12937
12978
|
addMenuItem(displayStr, function() {
|
|
12938
12979
|
saveFileContentToClipboard(coordStr);
|
|
12939
12980
|
});
|
package/www/mapshaper.js
CHANGED
|
@@ -5004,11 +5004,12 @@
|
|
|
5004
5004
|
}
|
|
5005
5005
|
|
|
5006
5006
|
function toLngLat(xy, P) {
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5007
|
+
return projectPoint(xy, P, parseCrsString('wgs84'));
|
|
5008
|
+
}
|
|
5009
|
+
|
|
5010
|
+
function projectPoint(xy, crsFrom, crsTo) {
|
|
5011
|
+
if (crsAreEqual(crsFrom, crsTo)) return xy.concat();
|
|
5012
|
+
var proj = getProjTransform2(crsFrom, crsTo);
|
|
5012
5013
|
return proj(xy[0], xy[1]);
|
|
5013
5014
|
}
|
|
5014
5015
|
|
|
@@ -5242,6 +5243,7 @@
|
|
|
5242
5243
|
getProjTransform: getProjTransform,
|
|
5243
5244
|
getProjTransform2: getProjTransform2,
|
|
5244
5245
|
toLngLat: toLngLat,
|
|
5246
|
+
projectPoint: projectPoint,
|
|
5245
5247
|
getProjInfo: getProjInfo,
|
|
5246
5248
|
crsToProj4: crsToProj4,
|
|
5247
5249
|
crsToPrj: crsToPrj,
|
|
@@ -5582,6 +5584,7 @@
|
|
|
5582
5584
|
var arcOffs = _ii[i];
|
|
5583
5585
|
var j = i * 4;
|
|
5584
5586
|
var b = calcArcBounds(_xx, _yy, arcOffs, arcLen);
|
|
5587
|
+
// NOTE: if arcLen is 0, bounds coords are undefined, coerced to NaN in _bb.
|
|
5585
5588
|
_bb[j++] = b[0];
|
|
5586
5589
|
_bb[j++] = b[1];
|
|
5587
5590
|
_bb[j++] = b[2];
|
|
@@ -5994,12 +5997,14 @@
|
|
|
5994
5997
|
this.arcIntersectsBBox = function(i, b1) {
|
|
5995
5998
|
var b2 = _bb,
|
|
5996
5999
|
j = i * 4;
|
|
6000
|
+
// returns false if _bb bounds are NaN
|
|
5997
6001
|
return b2[j] <= b1[2] && b2[j+2] >= b1[0] && b2[j+3] >= b1[1] && b2[j+1] <= b1[3];
|
|
5998
6002
|
};
|
|
5999
6003
|
|
|
6000
6004
|
this.arcIsContained = function(i, b1) {
|
|
6001
6005
|
var b2 = _bb,
|
|
6002
6006
|
j = i * 4;
|
|
6007
|
+
// returns false if _bb bounds are NaN
|
|
6003
6008
|
return b2[j] >= b1[0] && b2[j+2] <= b1[2] && b2[j+1] >= b1[1] && b2[j+3] <= b1[3];
|
|
6004
6009
|
};
|
|
6005
6010
|
|
|
@@ -6036,22 +6041,21 @@
|
|
|
6036
6041
|
return bounds;
|
|
6037
6042
|
};
|
|
6038
6043
|
|
|
6039
|
-
this.
|
|
6044
|
+
this.getSimpleShapeBbox = function(arcIds, arr) {
|
|
6040
6045
|
var bbox = arr || [],
|
|
6041
6046
|
bb = _bb,
|
|
6042
|
-
|
|
6043
|
-
bbox[0] =
|
|
6044
|
-
bbox[
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
if (bb[
|
|
6050
|
-
if (bb[++
|
|
6051
|
-
if (bb[++
|
|
6052
|
-
if (bb[++id] > bbox[3]) bbox[3] = bb[id];
|
|
6047
|
+
arcId, offs;
|
|
6048
|
+
bbox[0] = bbox[1] = Infinity;
|
|
6049
|
+
bbox[2] = bbox[3] = -Infinity;
|
|
6050
|
+
for (var i=0, n=arcIds.length; i<n; i++) {
|
|
6051
|
+
arcId = absArcId(arcIds[i]);
|
|
6052
|
+
offs = arcId * 4;
|
|
6053
|
+
if (bb[offs] < bbox[0]) bbox[0] = bb[offs];
|
|
6054
|
+
if (bb[++offs] < bbox[1]) bbox[1] = bb[offs];
|
|
6055
|
+
if (bb[++offs] > bbox[2]) bbox[2] = bb[offs];
|
|
6056
|
+
if (bb[++offs] > bbox[3]) bbox[3] = bb[offs];
|
|
6053
6057
|
}
|
|
6054
|
-
return bbox;
|
|
6058
|
+
return bbox[0] == Infinity ? [] : bbox;
|
|
6055
6059
|
};
|
|
6056
6060
|
|
|
6057
6061
|
// TODO: move this and similar methods out of ArcCollection
|
|
@@ -6068,7 +6072,9 @@
|
|
|
6068
6072
|
this.mergeArcBounds = function(arcId, bounds) {
|
|
6069
6073
|
if (arcId < 0) arcId = ~arcId;
|
|
6070
6074
|
var offs = arcId * 4;
|
|
6071
|
-
|
|
6075
|
+
if (_nn[arcId] > 0) {
|
|
6076
|
+
bounds.mergeBounds(_bb[offs], _bb[offs+1], _bb[offs+2], _bb[offs+3]);
|
|
6077
|
+
}
|
|
6072
6078
|
};
|
|
6073
6079
|
}
|
|
6074
6080
|
|
|
@@ -17254,7 +17260,7 @@
|
|
|
17254
17260
|
}
|
|
17255
17261
|
|
|
17256
17262
|
function procShapeRing(path) {
|
|
17257
|
-
currRingBbox = arcs.
|
|
17263
|
+
currRingBbox = arcs.getSimpleShapeBbox(path);
|
|
17258
17264
|
ringIndex.setIds(path);
|
|
17259
17265
|
procArcIds(path);
|
|
17260
17266
|
ringIndex.clear();
|
|
@@ -38149,7 +38155,7 @@ ${svg}
|
|
|
38149
38155
|
|
|
38150
38156
|
// Assumes that ring boundaries to not cross
|
|
38151
38157
|
function ringHasHoles(ring, rings, arcs) {
|
|
38152
|
-
var bbox = arcs.
|
|
38158
|
+
var bbox = arcs.getSimpleShapeBbox(ring);
|
|
38153
38159
|
var sibling, p;
|
|
38154
38160
|
for (var i=0, n=rings.length; i<n; i++) {
|
|
38155
38161
|
sibling = rings[i];
|
|
@@ -45578,7 +45584,7 @@ ${svg}
|
|
|
45578
45584
|
});
|
|
45579
45585
|
}
|
|
45580
45586
|
|
|
45581
|
-
var version = "0.6.
|
|
45587
|
+
var version = "0.6.89";
|
|
45582
45588
|
|
|
45583
45589
|
// Parse command line args into commands and run them
|
|
45584
45590
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
package/www/page.css
CHANGED
|
@@ -1206,8 +1206,9 @@ div.basemap-style-btn.active {
|
|
|
1206
1206
|
}
|
|
1207
1207
|
|
|
1208
1208
|
.basemap-overlay-btn img {
|
|
1209
|
-
margin-left: -
|
|
1210
|
-
|
|
1209
|
+
margin-left: -31px;
|
|
1210
|
+
margin-top: -5px;
|
|
1211
|
+
width: 90px;
|
|
1211
1212
|
}
|
|
1212
1213
|
|
|
1213
1214
|
.mapbox-improve-map {
|
|
@@ -1379,9 +1380,19 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
1379
1380
|
.contextmenu-item {
|
|
1380
1381
|
background-color: #fff;
|
|
1381
1382
|
white-space: nowrap;
|
|
1382
|
-
padding:
|
|
1383
|
-
line-height: 11px;
|
|
1383
|
+
padding: 3px 10px 4px 10px;
|
|
1384
1384
|
cursor: pointer;
|
|
1385
|
+
font-size: 13px;
|
|
1386
|
+
line-height: 13px;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
.contextmenu-label {
|
|
1390
|
+
color: #999;
|
|
1391
|
+
white-space: nowrap;
|
|
1392
|
+
padding: 4px 10px 1px 10px;
|
|
1393
|
+
font-size: 12px;
|
|
1394
|
+
line-height: 12px;
|
|
1395
|
+
margin-top: -2px;
|
|
1385
1396
|
}
|
|
1386
1397
|
|
|
1387
1398
|
.nav-menu-item:hover,
|