mapshaper 0.6.63 → 0.6.65
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 +457 -355
- package/package.json +1 -1
- package/www/mapshaper-gui.js +119 -7
- package/www/mapshaper.js +457 -355
- package/www/page.css +9 -0
package/package.json
CHANGED
package/www/mapshaper-gui.js
CHANGED
|
@@ -2578,6 +2578,25 @@
|
|
|
2578
2578
|
internal.snapVerticesToPoint(ids, lyr.invertPoint(p[0], p[1]), lyr.source.dataset.arcs, true);
|
|
2579
2579
|
}
|
|
2580
2580
|
|
|
2581
|
+
function setRectangleCoords(lyr, ids, coords) {
|
|
2582
|
+
ids.forEach(function(id, i) {
|
|
2583
|
+
var p = coords[i];
|
|
2584
|
+
internal.snapVerticesToPoint([id], p, lyr.source.dataset.arcs, true);
|
|
2585
|
+
if (isProjectedLayer(lyr)) {
|
|
2586
|
+
internal.snapVerticesToPoint([id], lyr.projectPoint(p[0], p[1]), lyr.arcs, true);
|
|
2587
|
+
}
|
|
2588
|
+
});
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
// lyr: display layer
|
|
2592
|
+
// export function updateRectangleCoords(lyr, ids, coords) {
|
|
2593
|
+
// if (!isProjectedLayer(lyr)) return;
|
|
2594
|
+
// ids.forEach(function(id, i) {
|
|
2595
|
+
// var p = coords[i];
|
|
2596
|
+
// internal.snapVerticesToPoint([id], lyr.invertPoint(p[0], p[1]), lyr.source.dataset.arcs, true);
|
|
2597
|
+
// });
|
|
2598
|
+
// }
|
|
2599
|
+
|
|
2581
2600
|
function isProjectedLayer(lyr) {
|
|
2582
2601
|
// TODO: could do some validation on the layer's contents
|
|
2583
2602
|
return !!(lyr.source && lyr.invertPoint);
|
|
@@ -4852,6 +4871,7 @@
|
|
|
4852
4871
|
var menus = {
|
|
4853
4872
|
standard: ['info', 'selection', 'data', 'box'],
|
|
4854
4873
|
polygons: ['info', 'selection', 'data', 'box', 'vertices'],
|
|
4874
|
+
rectangles: ['info', 'selection', 'data', 'box', 'rectangles', 'vertices'],
|
|
4855
4875
|
lines: ['info', 'selection', 'data', 'box', 'vertices'],
|
|
4856
4876
|
table: ['info', 'selection', 'data'],
|
|
4857
4877
|
labels: ['info', 'selection', 'data', 'box', 'labels', 'location'],
|
|
@@ -4875,6 +4895,7 @@
|
|
|
4875
4895
|
vertices: 'edit vertices',
|
|
4876
4896
|
selection: 'select features',
|
|
4877
4897
|
'add-points': 'add points',
|
|
4898
|
+
rectangles: 'drag-to-resize',
|
|
4878
4899
|
off: 'turn off'
|
|
4879
4900
|
};
|
|
4880
4901
|
var btn, menu;
|
|
@@ -4929,11 +4950,11 @@
|
|
|
4929
4950
|
};
|
|
4930
4951
|
|
|
4931
4952
|
this.modeUsesSelection = function(mode) {
|
|
4932
|
-
return ['info', 'selection', 'data', 'labels', 'location', 'vertices'].includes(mode);
|
|
4953
|
+
return ['info', 'selection', 'data', 'labels', 'location', 'vertices', 'rectangles'].includes(mode);
|
|
4933
4954
|
};
|
|
4934
4955
|
|
|
4935
4956
|
this.modeUsesPopup = function(mode) {
|
|
4936
|
-
return ['info', 'selection', 'data', 'box', 'labels', 'location'].includes(mode);
|
|
4957
|
+
return ['info', 'selection', 'data', 'box', 'labels', 'location', 'rectangles'].includes(mode);
|
|
4937
4958
|
};
|
|
4938
4959
|
|
|
4939
4960
|
this.getMode = getInteractionMode;
|
|
@@ -4975,7 +4996,8 @@
|
|
|
4975
4996
|
return menus.lines;
|
|
4976
4997
|
}
|
|
4977
4998
|
if (internal.layerHasPaths(o.layer) && o.layer.geometry_type == 'polygon') {
|
|
4978
|
-
return
|
|
4999
|
+
return internal.layerOnlyHasRectangles(o.layer, o.dataset.arcs) ?
|
|
5000
|
+
menus.rectangles : menus.polygons;
|
|
4979
5001
|
}
|
|
4980
5002
|
return menus.standard;
|
|
4981
5003
|
}
|
|
@@ -7029,7 +7051,8 @@
|
|
|
7029
7051
|
|
|
7030
7052
|
function clickable() {
|
|
7031
7053
|
// click used to pin popup and select features
|
|
7032
|
-
return interactionMode == 'data' || interactionMode == 'info' ||
|
|
7054
|
+
return interactionMode == 'data' || interactionMode == 'info' ||
|
|
7055
|
+
interactionMode == 'selection' || interactionMode == 'rectangles';
|
|
7033
7056
|
}
|
|
7034
7057
|
|
|
7035
7058
|
self.getHitId = function() {return storedData.id;};
|
|
@@ -7787,6 +7810,10 @@
|
|
|
7787
7810
|
_on = false,
|
|
7788
7811
|
handles;
|
|
7789
7812
|
|
|
7813
|
+
if (opts.classname) {
|
|
7814
|
+
el.addClass(opts.classname);
|
|
7815
|
+
}
|
|
7816
|
+
|
|
7790
7817
|
el.hide();
|
|
7791
7818
|
|
|
7792
7819
|
gui.on('map_rendered', function() {
|
|
@@ -7857,6 +7884,11 @@
|
|
|
7857
7884
|
});
|
|
7858
7885
|
}
|
|
7859
7886
|
|
|
7887
|
+
box.setDataCoords = function(bbox) {
|
|
7888
|
+
boxCoords = bbox;
|
|
7889
|
+
redraw();
|
|
7890
|
+
};
|
|
7891
|
+
|
|
7860
7892
|
box.getDataCoords = function() {
|
|
7861
7893
|
if (!boxCoords) return null;
|
|
7862
7894
|
var dataBox = getBBoxCoords(gui.map.getActiveLayer(), boxCoords);
|
|
@@ -7883,8 +7915,8 @@
|
|
|
7883
7915
|
props = {
|
|
7884
7916
|
top: Math.min(y1, y2),
|
|
7885
7917
|
left: Math.min(x1, x2),
|
|
7886
|
-
width: Math.max(w - stroke
|
|
7887
|
-
height: Math.max(h - stroke
|
|
7918
|
+
width: Math.max(w - stroke / 2, 1),
|
|
7919
|
+
height: Math.max(h - stroke / 2, 1)
|
|
7888
7920
|
};
|
|
7889
7921
|
el.css(props);
|
|
7890
7922
|
el.show();
|
|
@@ -9322,7 +9354,10 @@
|
|
|
9322
9354
|
var inSelection = o.ids.indexOf(o.id) > -1;
|
|
9323
9355
|
var geomType = lyr.geometry_type;
|
|
9324
9356
|
var style;
|
|
9325
|
-
if (isPinned) {
|
|
9357
|
+
if (isPinned && o.mode == 'rectangles') {
|
|
9358
|
+
// kludge for rectangle editing mode
|
|
9359
|
+
style = selectionStyles[geomType];
|
|
9360
|
+
} else if (isPinned) {
|
|
9326
9361
|
// a feature is pinned
|
|
9327
9362
|
style = pinnedStyles[geomType];
|
|
9328
9363
|
} else if (inSelection) {
|
|
@@ -10682,6 +10717,82 @@
|
|
|
10682
10717
|
return self;
|
|
10683
10718
|
}
|
|
10684
10719
|
|
|
10720
|
+
function RectangleControl(gui, hit) {
|
|
10721
|
+
var box = new HighlightBox(gui, {persistent: true, handles: true, classname: 'rectangles'});
|
|
10722
|
+
var _on = false;
|
|
10723
|
+
var dragInfo;
|
|
10724
|
+
|
|
10725
|
+
gui.addMode('rectangle_tool', turnOn, turnOff);
|
|
10726
|
+
|
|
10727
|
+
gui.on('interaction_mode_change', function(e) {
|
|
10728
|
+
if (e.mode === 'rectangles') {
|
|
10729
|
+
gui.enterMode('rectangle_tool');
|
|
10730
|
+
} else if (gui.getMode() == 'rectangle_tool') {
|
|
10731
|
+
gui.clearMode();
|
|
10732
|
+
}
|
|
10733
|
+
});
|
|
10734
|
+
|
|
10735
|
+
hit.on('change', function(e) {
|
|
10736
|
+
if (!_on) return;
|
|
10737
|
+
// TODO: handle multiple hits (see gui-inspection-control2)
|
|
10738
|
+
var id = e.id;
|
|
10739
|
+
if (e.id > -1 && e.pinned) {
|
|
10740
|
+
var target = hit.getHitTarget();
|
|
10741
|
+
var path = target.layer.shapes[e.id][0];
|
|
10742
|
+
var bbox = target.arcs.getSimpleShapeBounds(path).toArray();
|
|
10743
|
+
box.setDataCoords(bbox);
|
|
10744
|
+
dragInfo = {
|
|
10745
|
+
id: e.id,
|
|
10746
|
+
target: target,
|
|
10747
|
+
ids: [],
|
|
10748
|
+
points: []
|
|
10749
|
+
};
|
|
10750
|
+
var iter = target.arcs.getShapeIter(path);
|
|
10751
|
+
while (iter.hasNext()) {
|
|
10752
|
+
dragInfo.points.push([iter.x, iter.y]);
|
|
10753
|
+
dragInfo.ids.push(iter._arc.i);
|
|
10754
|
+
}
|
|
10755
|
+
gui.container.findChild('.map-layers').classed('dragging', true);
|
|
10756
|
+
|
|
10757
|
+
} else if (dragInfo) {
|
|
10758
|
+
// TODO: handle this event: add undo/redo states
|
|
10759
|
+
gui.dispatchEvent('rectangle_dragend', dragInfo);
|
|
10760
|
+
gui.container.findChild('.map-layers').classed('dragging', false);
|
|
10761
|
+
reset();
|
|
10762
|
+
} else {
|
|
10763
|
+
box.hide();
|
|
10764
|
+
}
|
|
10765
|
+
|
|
10766
|
+
});
|
|
10767
|
+
|
|
10768
|
+
box.on('handle_drag', function(e) {
|
|
10769
|
+
if (!_on || !dragInfo) return;
|
|
10770
|
+
var coords = internal.bboxToCoords(box.getDataCoords());
|
|
10771
|
+
setRectangleCoords(dragInfo.target, dragInfo.ids, coords);
|
|
10772
|
+
gui.dispatchEvent('map-needs-refresh');
|
|
10773
|
+
});
|
|
10774
|
+
|
|
10775
|
+
function turnOn() {
|
|
10776
|
+
box.turnOn();
|
|
10777
|
+
_on = true;
|
|
10778
|
+
}
|
|
10779
|
+
|
|
10780
|
+
function turnOff() {
|
|
10781
|
+
box.turnOff();
|
|
10782
|
+
if (gui.interaction.getMode() == 'rectangles') {
|
|
10783
|
+
// mode change was not initiated by interactive menu -- turn off interactivity
|
|
10784
|
+
gui.interaction.turnOff();
|
|
10785
|
+
}
|
|
10786
|
+
_on = false;
|
|
10787
|
+
reset();
|
|
10788
|
+
}
|
|
10789
|
+
|
|
10790
|
+
function reset() {
|
|
10791
|
+
box.hide();
|
|
10792
|
+
dragInfo = null;
|
|
10793
|
+
}
|
|
10794
|
+
}
|
|
10795
|
+
|
|
10685
10796
|
// Create low-detail versions of large arc collections for faster rendering
|
|
10686
10797
|
// at zoomed-out scales.
|
|
10687
10798
|
function enhanceArcCollectionForDisplay(unfilteredArcs) {
|
|
@@ -11372,6 +11483,7 @@
|
|
|
11372
11483
|
new InspectionControl2(gui, _hit);
|
|
11373
11484
|
new SelectionTool(gui, _ext, _hit),
|
|
11374
11485
|
new BoxTool(gui, _ext, _nav),
|
|
11486
|
+
new RectangleControl(gui, _hit),
|
|
11375
11487
|
initInteractiveEditing(gui, _ext, _hit);
|
|
11376
11488
|
// initDrawing(gui, _ext, _mouse, _hit);
|
|
11377
11489
|
_hit.on('change', updateOverlayLayer);
|