mapshaper 0.6.101 → 0.6.103
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/mapshaper.js +449 -285
- package/package.json +4 -5
- package/www/index.html +1 -1
- package/www/mapshaper-gui.js +304 -127
- package/www/mapshaper.js +449 -285
- package/www/modules.js +26899 -24043
- package/www/page.css +4 -0
package/www/mapshaper-gui.js
CHANGED
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
get formatIntlNumber () { return formatIntlNumber; },
|
|
68
68
|
get formatNumberForDisplay () { return formatNumberForDisplay; },
|
|
69
69
|
get shuffle () { return shuffle; },
|
|
70
|
+
get pickOne () { return pickOne; },
|
|
70
71
|
get sortOn () { return sortOn; },
|
|
71
72
|
get genericSort () { return genericSort; },
|
|
72
73
|
get getSortedIds () { return getSortedIds; },
|
|
@@ -1156,21 +1157,18 @@
|
|
|
1156
1157
|
|
|
1157
1158
|
|
|
1158
1159
|
function adjustPointSymbolSizes(layers, overlayLyr, ext) {
|
|
1159
|
-
var bbox = ext.getBounds().scale(1.
|
|
1160
|
-
var
|
|
1161
|
-
|
|
1162
|
-
};
|
|
1163
|
-
var topTier = 50000;
|
|
1160
|
+
var bbox = ext.getBounds().scale(1.3).toArray(); // add buffer
|
|
1161
|
+
// var topTier = 50000; // can be a bottleneck
|
|
1162
|
+
var topTier = 10000; // short-circuit counting here
|
|
1164
1163
|
var count = 0;
|
|
1165
1164
|
layers = layers.filter(function(lyr) {
|
|
1166
1165
|
return lyr.geometry_type == 'point' && lyr.gui.style.dotSize > 0;
|
|
1167
1166
|
});
|
|
1168
1167
|
layers.forEach(function(lyr) {
|
|
1169
|
-
|
|
1170
|
-
count += countPoints(lyr.gui.displayLayer.shapes, topTier, testInBounds);
|
|
1168
|
+
count += countPoints(lyr.gui.displayLayer.shapes, topTier, bbox);
|
|
1171
1169
|
});
|
|
1172
1170
|
count = Math.min(topTier, count) || 1;
|
|
1173
|
-
var k = Math.pow(
|
|
1171
|
+
var k = Math.pow(5 - utils$1.clamp(Math.log10(count), 1, 4), 1.25);
|
|
1174
1172
|
|
|
1175
1173
|
// zoom adjustments
|
|
1176
1174
|
var mapScale = ext.scale();
|
|
@@ -1178,10 +1176,11 @@
|
|
|
1178
1176
|
k *= Math.pow(mapScale + 0.5, 0.35);
|
|
1179
1177
|
} else if (mapScale > 1) {
|
|
1180
1178
|
// scale faster at first
|
|
1181
|
-
k *= Math.pow(Math.min(mapScale, 4), 0.
|
|
1182
|
-
k *= Math.pow(mapScale, 0.
|
|
1179
|
+
k *= Math.pow(Math.min(mapScale, 4), 0.25);
|
|
1180
|
+
k *= Math.pow(mapScale, 0.02);
|
|
1183
1181
|
}
|
|
1184
1182
|
|
|
1183
|
+
|
|
1185
1184
|
// scale down when map is small
|
|
1186
1185
|
var smallSide = Math.min(ext.width(), ext.height());
|
|
1187
1186
|
k *= utils$1.clamp(smallSide / 500, 0.5, 1);
|
|
@@ -1194,13 +1193,17 @@
|
|
|
1194
1193
|
}
|
|
1195
1194
|
}
|
|
1196
1195
|
|
|
1197
|
-
function countPoints(shapes, max,
|
|
1196
|
+
function countPoints(shapes, max, bbox) {
|
|
1198
1197
|
var count = 0;
|
|
1199
|
-
var
|
|
1200
|
-
|
|
1198
|
+
var shp, p;
|
|
1199
|
+
// short-circuit point counting above top threshold
|
|
1200
|
+
for (var i=0, n=shapes.length; i<n && count<max; i++) {
|
|
1201
1201
|
shp = shapes[i];
|
|
1202
|
-
for (j=0, m=(shp ? shp.length : 0); j<m; j++) {
|
|
1203
|
-
|
|
1202
|
+
for (var j=0, m=(shp ? shp.length : 0); j<m; j++) {
|
|
1203
|
+
p = shp[j];
|
|
1204
|
+
if (p[0] > bbox[0] && p[0] < bbox[2] && p[1] > bbox[1] && p[1] < bbox[3]) {
|
|
1205
|
+
count ++;
|
|
1206
|
+
}
|
|
1204
1207
|
}
|
|
1205
1208
|
}
|
|
1206
1209
|
return count;
|
|
@@ -1367,6 +1370,15 @@
|
|
|
1367
1370
|
});
|
|
1368
1371
|
}
|
|
1369
1372
|
|
|
1373
|
+
// save file to selected folder if supported, else to downloads
|
|
1374
|
+
function saveBlobToLocalFile2(filename, blob) {
|
|
1375
|
+
if (window.showSaveFilePicker) {
|
|
1376
|
+
saveBlobToSelectedFile(filename, blob);
|
|
1377
|
+
} else {
|
|
1378
|
+
saveBlobToDownloadsFolder(filename, blob);
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1370
1382
|
async function saveBlobToLocalFile(filename, blob, done) {
|
|
1371
1383
|
var chooseDir = GUI.getSavedValue('choose-save-dir');
|
|
1372
1384
|
done = done || function() {};
|
|
@@ -1454,6 +1466,7 @@
|
|
|
1454
1466
|
|
|
1455
1467
|
function saveBlobToDownloadsFolder(filename, blob, done) {
|
|
1456
1468
|
var anchor, blobUrl;
|
|
1469
|
+
done = done || function() {};
|
|
1457
1470
|
try {
|
|
1458
1471
|
blobUrl = URL.createObjectURL(blob);
|
|
1459
1472
|
} catch(e) {
|
|
@@ -1475,7 +1488,23 @@
|
|
|
1475
1488
|
}, 400);
|
|
1476
1489
|
}
|
|
1477
1490
|
|
|
1478
|
-
|
|
1491
|
+
// Several dependencies are loaded via require()
|
|
1492
|
+
var f;
|
|
1493
|
+
if (typeof require == 'function') {
|
|
1494
|
+
// Node.js context: native require() function
|
|
1495
|
+
f = require;
|
|
1496
|
+
} else if (typeof window == 'object' && window.modules) {
|
|
1497
|
+
// running in web GUI
|
|
1498
|
+
f = function(name) {
|
|
1499
|
+
return window.modules[name];
|
|
1500
|
+
};
|
|
1501
|
+
} else {
|
|
1502
|
+
// stub to avoid runtime error in a handful of tests
|
|
1503
|
+
f = function() {};
|
|
1504
|
+
}
|
|
1505
|
+
var require$1 = f;
|
|
1506
|
+
|
|
1507
|
+
var idb = require$1('idb-keyval');
|
|
1479
1508
|
// https://github.com/jakearchibald/idb
|
|
1480
1509
|
// https://github.com/jakearchibald/idb-keyval
|
|
1481
1510
|
var sessionId = getUniqId('session');
|
|
@@ -1563,10 +1592,9 @@
|
|
|
1563
1592
|
var obj = await idb.get(item.id);
|
|
1564
1593
|
await internal.compressSnapshotForExport(obj);
|
|
1565
1594
|
var buf = internal.pack(obj);
|
|
1566
|
-
// choose output filename and directory every time
|
|
1567
|
-
// saveBlobToLocalFile('mapshaper_snapshot.msx', new Blob([buf]));
|
|
1568
1595
|
var fileName = `snapshot-${String(item.number).padStart(2, '0')}.msx`;
|
|
1569
|
-
|
|
1596
|
+
// choose output filename and directory every time, if supported
|
|
1597
|
+
saveBlobToLocalFile2(fileName, new Blob([buf]));
|
|
1570
1598
|
}).text('export');
|
|
1571
1599
|
El('span').addClass('save-menu-btn').appendTo(line).on('click', async function(e) {
|
|
1572
1600
|
await removeSnapshotById(item.id);
|
|
@@ -1606,6 +1634,7 @@
|
|
|
1606
1634
|
|
|
1607
1635
|
async function saveSnapshot(gui) {
|
|
1608
1636
|
var obj = await captureSnapshot(gui);
|
|
1637
|
+
|
|
1609
1638
|
if (!obj) return;
|
|
1610
1639
|
// storing an unpacked object is usually a bit faster (~20%)
|
|
1611
1640
|
// note: we don't know the size of unpacked snapshot objects
|
|
@@ -1693,9 +1722,7 @@
|
|
|
1693
1722
|
// in file size in a typical polygon or polyline file, but longer processing time
|
|
1694
1723
|
var opts = {compact: false, active_layer: lyr};
|
|
1695
1724
|
var datasets = gui.model.getDatasets();
|
|
1696
|
-
// console.time('msx');
|
|
1697
1725
|
var obj = await internal.exportDatasetsToPack(datasets, opts);
|
|
1698
|
-
// console.timeEnd('msx')
|
|
1699
1726
|
obj.gui = getGuiState(gui);
|
|
1700
1727
|
return obj;
|
|
1701
1728
|
}
|
|
@@ -2672,7 +2699,7 @@
|
|
|
2672
2699
|
// load Proj.4 CRS definition files dynamically
|
|
2673
2700
|
//
|
|
2674
2701
|
async function loadProjLibs(opts) {
|
|
2675
|
-
var mproj = require('mproj');
|
|
2702
|
+
var mproj = require$1('mproj');
|
|
2676
2703
|
var libs = internal.findProjLibs([opts.init || '', opts.match || '', opts.crs || ''].join(' '));
|
|
2677
2704
|
libs = libs.filter(function(name) {return !mproj.internal.mproj_search_libcache(name);}); // skip loaded libs
|
|
2678
2705
|
for (var libName of libs) {
|
|
@@ -2836,8 +2863,8 @@
|
|
|
2836
2863
|
return getDefaultStyle(lyr, intersectionStyle);
|
|
2837
2864
|
}
|
|
2838
2865
|
|
|
2839
|
-
//
|
|
2840
|
-
// (styled
|
|
2866
|
+
// Display style for unselected layers with visibility turned on
|
|
2867
|
+
// (may be fully styled or outlined)
|
|
2841
2868
|
function getReferenceLayerStyle(lyr, opts) {
|
|
2842
2869
|
var style;
|
|
2843
2870
|
if (layerHasCanvasDisplayStyle(lyr) && !opts.outlineMode) {
|
|
@@ -2919,6 +2946,7 @@
|
|
|
2919
2946
|
style.styler = getOverlayPointStyler(getCanvasDisplayStyle(baseLyr).styler, styler);
|
|
2920
2947
|
}
|
|
2921
2948
|
style.type = 'styled';
|
|
2949
|
+
|
|
2922
2950
|
}
|
|
2923
2951
|
return ids.length > 0 ? style : null;
|
|
2924
2952
|
}
|
|
@@ -3022,6 +3050,7 @@
|
|
|
3022
3050
|
// array of field names of relevant svg display properties
|
|
3023
3051
|
fields = getCanvasStyleFields(lyr).filter(function(f) {return f in styleIndex;}),
|
|
3024
3052
|
records = lyr.data.getRecords();
|
|
3053
|
+
|
|
3025
3054
|
var styler = function(style, i) {
|
|
3026
3055
|
var rec = records[i];
|
|
3027
3056
|
var fname, val;
|
|
@@ -3045,14 +3074,20 @@
|
|
|
3045
3074
|
style.fillColor = 'black';
|
|
3046
3075
|
}
|
|
3047
3076
|
};
|
|
3048
|
-
|
|
3077
|
+
var style = {styler: styler, type: 'styled'};
|
|
3078
|
+
// use squares if radius is missing... (TODO: check behavior with labels, etc)
|
|
3079
|
+
if (lyr.geometry_type == 'point' && fields.includes('r') === false) {
|
|
3080
|
+
style.dotSize = 1;
|
|
3081
|
+
}
|
|
3082
|
+
return style;
|
|
3049
3083
|
}
|
|
3050
3084
|
|
|
3051
|
-
// check if layer should be displayed with
|
|
3085
|
+
// check if layer should be displayed with a full style
|
|
3052
3086
|
function layerHasCanvasDisplayStyle(lyr) {
|
|
3053
3087
|
var fields = getCanvasStyleFields(lyr);
|
|
3054
3088
|
if (lyr.geometry_type == 'point') {
|
|
3055
|
-
return fields.indexOf('r') > -1; // require 'r' field for point symbols
|
|
3089
|
+
// return fields.indexOf('r') > -1; // require 'r' field for point symbols
|
|
3090
|
+
return fields.includes('fill') || fields.includes('r'); // support colored squares
|
|
3056
3091
|
}
|
|
3057
3092
|
return utils$1.difference(fields, ['opacity', 'class']).length > 0;
|
|
3058
3093
|
}
|
|
@@ -6090,6 +6125,9 @@
|
|
|
6090
6125
|
|
|
6091
6126
|
utils$1.inherit(ModeSwitcher, EventDispatcher);
|
|
6092
6127
|
|
|
6128
|
+
// export var ESC = 27;
|
|
6129
|
+
var SPACE = 32;
|
|
6130
|
+
|
|
6093
6131
|
function KeyboardEvents(gui) {
|
|
6094
6132
|
var self = this;
|
|
6095
6133
|
var shiftDown = false;
|
|
@@ -6103,7 +6141,7 @@
|
|
|
6103
6141
|
ctrlDown = e.ctrlKey;
|
|
6104
6142
|
metaDown = e.metaKey;
|
|
6105
6143
|
altDown = e.altKey;
|
|
6106
|
-
if (e.keyCode ==
|
|
6144
|
+
if (e.keyCode == SPACE) {
|
|
6107
6145
|
spaceDown = evtName == 'keydown';
|
|
6108
6146
|
}
|
|
6109
6147
|
}
|
|
@@ -6113,13 +6151,13 @@
|
|
|
6113
6151
|
}
|
|
6114
6152
|
|
|
6115
6153
|
document.addEventListener('keyup', function(e) {
|
|
6116
|
-
if (!GUI.isActiveInstance(gui) || e.repeat && e.keyCode ==
|
|
6154
|
+
if (!GUI.isActiveInstance(gui) || e.repeat && e.keyCode == SPACE) return;
|
|
6117
6155
|
updateControlKeys(e, 'keyup');
|
|
6118
6156
|
self.dispatchEvent('keyup', getEventData(e));
|
|
6119
6157
|
});
|
|
6120
6158
|
|
|
6121
6159
|
document.addEventListener('keydown', function(e) {
|
|
6122
|
-
if (!GUI.isActiveInstance(gui) || e.repeat && e.keyCode ==
|
|
6160
|
+
if (!GUI.isActiveInstance(gui) || e.repeat && e.keyCode == SPACE) return;
|
|
6123
6161
|
updateControlKeys(e, 'keydown');
|
|
6124
6162
|
self.dispatchEvent('keydown', getEventData(e));
|
|
6125
6163
|
});
|
|
@@ -6444,7 +6482,7 @@
|
|
|
6444
6482
|
if (flags.select) {
|
|
6445
6483
|
self.dispatchEvent('select', active);
|
|
6446
6484
|
}
|
|
6447
|
-
self.dispatchEvent('update',
|
|
6485
|
+
self.dispatchEvent('update', {flags: flags});
|
|
6448
6486
|
};
|
|
6449
6487
|
|
|
6450
6488
|
self.selectLayer = function(lyr, dataset) {
|
|
@@ -6470,7 +6508,7 @@
|
|
|
6470
6508
|
}
|
|
6471
6509
|
|
|
6472
6510
|
// Fall back to browserify's Buffer polyfill
|
|
6473
|
-
var B = typeof Buffer != 'undefined' ? Buffer : require('buffer').Buffer;
|
|
6511
|
+
var B = typeof Buffer != 'undefined' ? Buffer : require$1('buffer').Buffer;
|
|
6474
6512
|
|
|
6475
6513
|
// This module provides a way for multiple jobs to run together asynchronously
|
|
6476
6514
|
// while keeping job-level context variables (like "defs") separate.
|
|
@@ -6843,6 +6881,7 @@
|
|
|
6843
6881
|
});
|
|
6844
6882
|
}
|
|
6845
6883
|
|
|
6884
|
+
|
|
6846
6885
|
function defaults(dest) {
|
|
6847
6886
|
for (var i=1, n=arguments.length; i<n; i++) {
|
|
6848
6887
|
var src = arguments[i] || {};
|
|
@@ -7267,6 +7306,10 @@
|
|
|
7267
7306
|
}
|
|
7268
7307
|
}
|
|
7269
7308
|
|
|
7309
|
+
function pickOne(arr) {
|
|
7310
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
7311
|
+
}
|
|
7312
|
+
|
|
7270
7313
|
// Sort an array of objects based on one or more properties.
|
|
7271
7314
|
// Usage: sortOn(array, key1, asc?[, key2, asc? ...])
|
|
7272
7315
|
//
|
|
@@ -8004,7 +8047,7 @@
|
|
|
8004
8047
|
function getShapeHitTest(layer, ext, interactionMode, featureFilter) {
|
|
8005
8048
|
var geoType = layer.gui.displayLayer.geometry_type;
|
|
8006
8049
|
var test;
|
|
8007
|
-
if (geoType == 'point' && layer.gui.style.type == 'styled') {
|
|
8050
|
+
if (geoType == 'point' && layer.gui.style.type == 'styled' && !layer.gui.style.dotSize) {
|
|
8008
8051
|
test = getGraduatedCircleTest(getRadiusFunction(layer.gui.style));
|
|
8009
8052
|
} else if (geoType == 'point') {
|
|
8010
8053
|
test = pointTest;
|
|
@@ -8337,7 +8380,7 @@
|
|
|
8337
8380
|
|
|
8338
8381
|
// e: pointer event
|
|
8339
8382
|
return function(e) {
|
|
8340
|
-
var p = ext.
|
|
8383
|
+
var p = ext.pixCoordsToMapCoords(e.x, e.y);
|
|
8341
8384
|
// update SVG hit test on each test, in case SVG layer has been redrawn
|
|
8342
8385
|
// and the symbol container has changed
|
|
8343
8386
|
var svgTest = getSvgHitTest(mapLayer);
|
|
@@ -9273,6 +9316,7 @@
|
|
|
9273
9316
|
persistent: false,
|
|
9274
9317
|
draggable: false // does dragging the map draw a box
|
|
9275
9318
|
}, optsArg),
|
|
9319
|
+
clickToStart = opts.name == 'box-tool', // other versions use shift-drag
|
|
9276
9320
|
box = new EventDispatcher(),
|
|
9277
9321
|
stroke = 2,
|
|
9278
9322
|
activeHandle = null,
|
|
@@ -9280,38 +9324,75 @@
|
|
|
9280
9324
|
boxCoords = null,
|
|
9281
9325
|
_on = false,
|
|
9282
9326
|
_visible = false,
|
|
9327
|
+
clickStartPoint,
|
|
9283
9328
|
handles;
|
|
9284
|
-
|
|
9285
9329
|
if (opts.classname) {
|
|
9286
9330
|
el.addClass(opts.classname);
|
|
9287
9331
|
}
|
|
9288
9332
|
|
|
9333
|
+
function drawing() {
|
|
9334
|
+
return visible() && !activeHandle;
|
|
9335
|
+
}
|
|
9336
|
+
|
|
9337
|
+
function resizing() {
|
|
9338
|
+
return !!activeHandle && visible();
|
|
9339
|
+
}
|
|
9340
|
+
|
|
9341
|
+
function visible() {
|
|
9342
|
+
return _on && !!boxCoords && _visible;
|
|
9343
|
+
}
|
|
9344
|
+
|
|
9289
9345
|
el.hide();
|
|
9290
9346
|
|
|
9291
9347
|
gui.on('map_rendered', function() {
|
|
9292
|
-
if (!
|
|
9348
|
+
if (!visible()) return;
|
|
9293
9349
|
redraw();
|
|
9294
9350
|
});
|
|
9295
9351
|
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9352
|
+
if (clickToStart) {
|
|
9353
|
+
gui.on('map_click', function(e) {
|
|
9354
|
+
if (!_on) {
|
|
9355
|
+
// clickStartPoint = null;
|
|
9356
|
+
return;
|
|
9357
|
+
}
|
|
9358
|
+
|
|
9359
|
+
var p = [e.x, e.y];
|
|
9360
|
+
if (drawing()) {
|
|
9361
|
+
finishDrawingBox(e);
|
|
9362
|
+
} else if (!resizing()) {
|
|
9363
|
+
clickStartPoint = p;
|
|
9364
|
+
}
|
|
9365
|
+
});
|
|
9366
|
+
|
|
9367
|
+
gui.map.getMouse().on('hover', function(e) {
|
|
9368
|
+
if (!_on) return;
|
|
9369
|
+
var p = [e.x, e.y];
|
|
9370
|
+
if (clickStartPoint) {
|
|
9371
|
+
updateDrawnBox(clickStartPoint, p);
|
|
9372
|
+
}
|
|
9373
|
+
// box.dispatchEvent('drag');
|
|
9374
|
+
});
|
|
9375
|
+
}
|
|
9376
|
+
|
|
9377
|
+
if (!clickToStart) {
|
|
9378
|
+
gui.on('shift_drag', function(e) {
|
|
9379
|
+
if (!_on) return;
|
|
9380
|
+
if (!opts.draggable) return;
|
|
9381
|
+
if (clickToStart) return;
|
|
9382
|
+
updateDrawnBox(e.data.b, e.data.a);
|
|
9383
|
+
box.dispatchEvent('drag');
|
|
9384
|
+
});
|
|
9385
|
+
|
|
9386
|
+
gui.on('shift_drag_end', function(e) {
|
|
9387
|
+
if (!_on || !_visible || !opts.draggable) return;
|
|
9388
|
+
if (clickToStart) return;
|
|
9389
|
+
updateDrawnBox(e.data.b, e.data.a, true);
|
|
9390
|
+
if (!opts.persistent) {
|
|
9391
|
+
box.hide();
|
|
9392
|
+
}
|
|
9393
|
+
});
|
|
9394
|
+
}
|
|
9303
9395
|
|
|
9304
|
-
gui.on('shift_drag_end', function(e) {
|
|
9305
|
-
if (!_on || !_visible || !opts.draggable) return;
|
|
9306
|
-
boxCoords = getBoxCoords(e.data);
|
|
9307
|
-
var pix = coordsToPix(boxCoords, gui.map.getExtent());
|
|
9308
|
-
box.dispatchEvent('dragend', {map_bbox: pix});
|
|
9309
|
-
if (!opts.persistent) {
|
|
9310
|
-
box.hide();
|
|
9311
|
-
} else {
|
|
9312
|
-
redraw();
|
|
9313
|
-
}
|
|
9314
|
-
});
|
|
9315
9396
|
|
|
9316
9397
|
if (opts.handles) {
|
|
9317
9398
|
handles = initHandles(el);
|
|
@@ -9324,7 +9405,7 @@
|
|
|
9324
9405
|
});
|
|
9325
9406
|
|
|
9326
9407
|
gui.map.getMouse().on('mousemove', function(e) {
|
|
9327
|
-
if (!
|
|
9408
|
+
if (!resizing() || !prevXY) return;
|
|
9328
9409
|
var xy = {x: e.pageX, y: e.pageY};
|
|
9329
9410
|
var scaling = gui.keyboard.shiftIsPressed() && activeHandle.type == 'corner';
|
|
9330
9411
|
if (scaling) {
|
|
@@ -9350,6 +9431,27 @@
|
|
|
9350
9431
|
});
|
|
9351
9432
|
}
|
|
9352
9433
|
|
|
9434
|
+
// p1: origin
|
|
9435
|
+
// p2: pointer location
|
|
9436
|
+
function updateDrawnBox(p1, p2, final) {
|
|
9437
|
+
if (!boxCoords) {
|
|
9438
|
+
el.classed('hittable', false);
|
|
9439
|
+
}
|
|
9440
|
+
boxCoords = getBoxCoords(p1, p2);
|
|
9441
|
+
redraw();
|
|
9442
|
+
if (final) {
|
|
9443
|
+
el.classed('hittable', true);
|
|
9444
|
+
var pix = coordsToPix(boxCoords, gui.map.getExtent());
|
|
9445
|
+
box.dispatchEvent('dragend', {map_bbox: pix});
|
|
9446
|
+
}
|
|
9447
|
+
}
|
|
9448
|
+
|
|
9449
|
+
function finishDrawingBox(e) {
|
|
9450
|
+
if (!clickStartPoint) return;
|
|
9451
|
+
updateDrawnBox(clickStartPoint, [e.x, e.y], true);
|
|
9452
|
+
clickStartPoint = null;
|
|
9453
|
+
}
|
|
9454
|
+
|
|
9353
9455
|
function resizeBox(dx, dy, activeHandle) {
|
|
9354
9456
|
var shifting = activeHandle.type == 'center';
|
|
9355
9457
|
var centered = gui.keyboard.shiftIsPressed() && activeHandle.type == 'edge';
|
|
@@ -9376,7 +9478,7 @@
|
|
|
9376
9478
|
}
|
|
9377
9479
|
|
|
9378
9480
|
function rescaleBox(x, y) {
|
|
9379
|
-
var p = gui.map.getExtent().
|
|
9481
|
+
var p = gui.map.getExtent().pixCoordsToMapCoords(x, y);
|
|
9380
9482
|
var cx = (boxCoords[0] + boxCoords[2])/2;
|
|
9381
9483
|
var cy = (boxCoords[1] + boxCoords[3])/2;
|
|
9382
9484
|
var dist2 = geom.distance2D(cx, cy, p[0], p[1]);
|
|
@@ -9406,12 +9508,16 @@
|
|
|
9406
9508
|
|
|
9407
9509
|
box.turnOff = function() {
|
|
9408
9510
|
_on = false;
|
|
9511
|
+
box.hide();
|
|
9409
9512
|
};
|
|
9410
9513
|
|
|
9514
|
+
// remove the current box (if any)
|
|
9411
9515
|
box.hide = function() {
|
|
9412
9516
|
el.hide();
|
|
9413
9517
|
boxCoords = null;
|
|
9414
9518
|
_visible = false;
|
|
9519
|
+
clickStartPoint = null;
|
|
9520
|
+
activeHandle = null;
|
|
9415
9521
|
};
|
|
9416
9522
|
|
|
9417
9523
|
box.show = function(x1, y1, x2, y2) {
|
|
@@ -9451,12 +9557,35 @@
|
|
|
9451
9557
|
}
|
|
9452
9558
|
|
|
9453
9559
|
// get bbox coords in the display CRS
|
|
9454
|
-
function getBoxCoords(
|
|
9455
|
-
|
|
9560
|
+
function getBoxCoords(p1, p2) {
|
|
9561
|
+
if (gui.keyboard.shiftIsPressed()) {
|
|
9562
|
+
p2 = getSquareCorner(p1[0], p1[1], p2[0], p2[1]);
|
|
9563
|
+
}
|
|
9564
|
+
var bbox = pixToCoords(p1.concat(p2), gui.map.getExtent());
|
|
9456
9565
|
fixBounds(bbox);
|
|
9457
9566
|
return bbox;
|
|
9458
9567
|
}
|
|
9459
9568
|
|
|
9569
|
+
function getSquareCorner(x1, y1, x2, y2) {
|
|
9570
|
+
var dx = x2 - x1;
|
|
9571
|
+
var dy = y2 - y1;
|
|
9572
|
+
if (dy === 0 && dx === 0) {
|
|
9573
|
+
return [x2, y2];
|
|
9574
|
+
}
|
|
9575
|
+
if (dy === 0) {
|
|
9576
|
+
dy = 1;
|
|
9577
|
+
}
|
|
9578
|
+
if (dx === 0) {
|
|
9579
|
+
dx = 1;
|
|
9580
|
+
}
|
|
9581
|
+
if (Math.abs(dx) > Math.abs(dy)) {
|
|
9582
|
+
dy = dy * Math.abs(dx / dy);
|
|
9583
|
+
} else {
|
|
9584
|
+
dx = dx * Math.abs(dy / dx);
|
|
9585
|
+
}
|
|
9586
|
+
return [x1 + dx, y1 + dy];
|
|
9587
|
+
}
|
|
9588
|
+
|
|
9460
9589
|
function redraw() {
|
|
9461
9590
|
if (!boxCoords) return;
|
|
9462
9591
|
var ext = gui.map.getExtent();
|
|
@@ -9477,12 +9606,12 @@
|
|
|
9477
9606
|
}
|
|
9478
9607
|
|
|
9479
9608
|
function pixToCoords(bbox, ext) {
|
|
9480
|
-
var a = ext.
|
|
9481
|
-
var b = ext.
|
|
9609
|
+
var a = ext.pixCoordsToMapCoords(bbox[0], bbox[1]);
|
|
9610
|
+
var b = ext.pixCoordsToMapCoords(bbox[2], bbox[3]);
|
|
9482
9611
|
return [a[0], b[1], b[0], a[1]];
|
|
9483
9612
|
}
|
|
9484
9613
|
|
|
9485
|
-
|
|
9614
|
+
// enforce [minx, miny, maxx, maxy] order
|
|
9486
9615
|
function fixBounds(bbox) {
|
|
9487
9616
|
var tmp;
|
|
9488
9617
|
if (bbox[0] > bbox[2]) {
|
|
@@ -9614,7 +9743,7 @@
|
|
|
9614
9743
|
mouse.on('drag', function(e) {
|
|
9615
9744
|
if (disabled()) return;
|
|
9616
9745
|
if (shiftDrag) {
|
|
9617
|
-
gui.dispatchEvent('shift_drag', getBoxData(e));
|
|
9746
|
+
gui.dispatchEvent('shift_drag', getBoxData(e, dragStartEvt));
|
|
9618
9747
|
return;
|
|
9619
9748
|
}
|
|
9620
9749
|
if (++panCount == 1) {
|
|
@@ -9634,7 +9763,7 @@
|
|
|
9634
9763
|
if (disabled()) return;
|
|
9635
9764
|
if (shiftDrag) {
|
|
9636
9765
|
shiftDrag = false;
|
|
9637
|
-
gui.dispatchEvent('shift_drag_end', getBoxData(e));
|
|
9766
|
+
gui.dispatchEvent('shift_drag_end', getBoxData(e, dragStartEvt));
|
|
9638
9767
|
zoomBox.turnOff();
|
|
9639
9768
|
} else {
|
|
9640
9769
|
El('body').removeClass('panning').removeClass('pan');
|
|
@@ -9658,10 +9787,10 @@
|
|
|
9658
9787
|
return !'selection_tool,box_tool,rectangle_tool,drawing_tool'.includes(mode);
|
|
9659
9788
|
}
|
|
9660
9789
|
|
|
9661
|
-
function getBoxData(
|
|
9790
|
+
function getBoxData(e1, e2) {
|
|
9662
9791
|
return {
|
|
9663
|
-
a: [
|
|
9664
|
-
b: [
|
|
9792
|
+
a: [e1.x, e1.y],
|
|
9793
|
+
b: [e2.x, e2.y]
|
|
9665
9794
|
};
|
|
9666
9795
|
}
|
|
9667
9796
|
|
|
@@ -10545,8 +10674,8 @@
|
|
|
10545
10674
|
var coords = target.shapes[id];
|
|
10546
10675
|
deleteFeature(target, id);
|
|
10547
10676
|
gui.dispatchEvent('feature_delete', {coords, d, target, fid: id});
|
|
10548
|
-
gui.dispatchEvent('map-needs-refresh');
|
|
10549
10677
|
hit.setHitId(-1);
|
|
10678
|
+
gui.dispatchEvent('map-needs-refresh');
|
|
10550
10679
|
}
|
|
10551
10680
|
|
|
10552
10681
|
hit.on('click', function(e) {
|
|
@@ -10601,12 +10730,12 @@
|
|
|
10601
10730
|
|
|
10602
10731
|
function pixToDataCoords(x, y) {
|
|
10603
10732
|
var target = hit.getHitTarget();
|
|
10604
|
-
return translateDisplayPoint(target, ext.
|
|
10733
|
+
return translateDisplayPoint(target, ext.pixCoordsToMapCoords(x, y));
|
|
10605
10734
|
}
|
|
10606
10735
|
|
|
10607
10736
|
function translateDeltaDisplayCoords(dx, dy, ext) {
|
|
10608
|
-
var a = ext.
|
|
10609
|
-
var b = ext.
|
|
10737
|
+
var a = ext.pixCoordsToMapCoords(0, 0);
|
|
10738
|
+
var b = ext.pixCoordsToMapCoords(dx, dy);
|
|
10610
10739
|
return [b[0] - a[0], b[1] - a[1]];
|
|
10611
10740
|
}
|
|
10612
10741
|
}
|
|
@@ -10886,7 +11015,7 @@
|
|
|
10886
11015
|
e.originalEvent.stopPropagation();
|
|
10887
11016
|
// dragging a vertex
|
|
10888
11017
|
var target = hit.getHitTarget();
|
|
10889
|
-
var p = ext.
|
|
11018
|
+
var p = ext.pixCoordsToMapCoords(e.x, e.y);
|
|
10890
11019
|
if (gui.keyboard.shiftIsPressed()) {
|
|
10891
11020
|
internal.snapPointToArcEndpoint(p, hoverVertexInfo.ids, target.gui.displayArcs);
|
|
10892
11021
|
}
|
|
@@ -10904,8 +11033,8 @@
|
|
|
10904
11033
|
target.gui.displayArcs.transformPoints(function() {});
|
|
10905
11034
|
updateVertexCoords(target, hoverVertexInfo.ids);
|
|
10906
11035
|
gui.dispatchEvent('vertex_dragend', hoverVertexInfo);
|
|
10907
|
-
gui.dispatchEvent('map-needs-refresh'); // redraw basemap
|
|
10908
11036
|
clearHoverVertex();
|
|
11037
|
+
gui.dispatchEvent('map-needs-refresh'); // redraw basemap
|
|
10909
11038
|
});
|
|
10910
11039
|
|
|
10911
11040
|
// shift + double-click deletes a vertex (when not drawing)
|
|
@@ -11019,7 +11148,7 @@
|
|
|
11019
11148
|
|
|
11020
11149
|
function pixToDataCoords(x, y) {
|
|
11021
11150
|
var target = hit.getHitTarget();
|
|
11022
|
-
return translateDisplayPoint(target, ext.
|
|
11151
|
+
return translateDisplayPoint(target, ext.pixCoordsToMapCoords(x, y));
|
|
11023
11152
|
}
|
|
11024
11153
|
|
|
11025
11154
|
// Change the x, y pixel location of thisEvt so that the segment extending
|
|
@@ -11141,7 +11270,7 @@
|
|
|
11141
11270
|
if (!pathDrawing()) return false;
|
|
11142
11271
|
var target = hit.getHitTarget();
|
|
11143
11272
|
var arcId = target.gui.displayArcs.size() - 1;
|
|
11144
|
-
var p1 = ext.
|
|
11273
|
+
var p1 = ext.pixCoordsToMapCoords(e.x, e.y); // mouse coords
|
|
11145
11274
|
var p2 = internal.getArcStartCoords(arcId, target.gui.displayArcs); // vertex coords
|
|
11146
11275
|
var p3 = internal.getArcStartCoords(arcId, target.gui.source.dataset.arcs);
|
|
11147
11276
|
var dist = geom.distance2D(p1[0], p1[1], p2[0], p2[1]);
|
|
@@ -11163,7 +11292,7 @@
|
|
|
11163
11292
|
function findDraggableVertices(e) {
|
|
11164
11293
|
var target = hit.getHitTarget();
|
|
11165
11294
|
var shp = target.shapes[e.id];
|
|
11166
|
-
var p = ext.
|
|
11295
|
+
var p = ext.pixCoordsToMapCoords(e.x, e.y);
|
|
11167
11296
|
var ids = internal.findNearestVertices(p, shp, target.gui.displayArcs);
|
|
11168
11297
|
var p2 = target.gui.displayArcs.getVertex2(ids[0]);
|
|
11169
11298
|
var dist = geom.distance2D(p[0], p[1], p2[0], p2[1]);
|
|
@@ -11185,7 +11314,7 @@
|
|
|
11185
11314
|
var target = hit.getHitTarget();
|
|
11186
11315
|
//// vertex insertion not supported with simplification
|
|
11187
11316
|
// if (!target.arcs.isFlat()) return null;
|
|
11188
|
-
var p = ext.
|
|
11317
|
+
var p = ext.pixCoordsToMapCoords(e.x, e.y);
|
|
11189
11318
|
var minDist = Infinity;
|
|
11190
11319
|
var shp = target.shapes[e.id];
|
|
11191
11320
|
var closest;
|
|
@@ -11410,7 +11539,7 @@
|
|
|
11410
11539
|
};
|
|
11411
11540
|
|
|
11412
11541
|
// convert pixel coords (0,0 is top left corner of map) to display CRS coords
|
|
11413
|
-
this.
|
|
11542
|
+
this.pixCoordsToMapCoords = function(x, y) {
|
|
11414
11543
|
return this.getTransform().invert().transform(x, y);
|
|
11415
11544
|
};
|
|
11416
11545
|
|
|
@@ -11682,7 +11811,7 @@
|
|
|
11682
11811
|
var layer = lyr.gui.displayLayer;
|
|
11683
11812
|
var arcs, filter;
|
|
11684
11813
|
if (layer.geometry_type == 'point') {
|
|
11685
|
-
if (style.type == 'styled') {
|
|
11814
|
+
if (style.type == 'styled' && !style.dotSize) {
|
|
11686
11815
|
canv.drawPoints(layer.shapes, style);
|
|
11687
11816
|
} else {
|
|
11688
11817
|
canv.drawSquareDots(layer.shapes, style);
|
|
@@ -11738,11 +11867,15 @@
|
|
|
11738
11867
|
var canv = El('canvas').node();
|
|
11739
11868
|
canv.width = canv.height = 1;
|
|
11740
11869
|
var ctx = canv.getContext('2d', {willReadFrequently: true});
|
|
11870
|
+
var memos = {};
|
|
11741
11871
|
return function(col) {
|
|
11742
11872
|
var pixels;
|
|
11873
|
+
if (!col) col = 'black';
|
|
11874
|
+
if (col in memos) return memos[col];
|
|
11743
11875
|
ctx.fillStyle = col;
|
|
11744
11876
|
ctx.fillRect(0, 0, 1, 1);
|
|
11745
11877
|
pixels = new Uint32Array(ctx.getImageData(0, 0, 1, 1).data.buffer);
|
|
11878
|
+
memos[col] = pixels[0];
|
|
11746
11879
|
return pixels[0];
|
|
11747
11880
|
};
|
|
11748
11881
|
}
|
|
@@ -11876,43 +12009,48 @@
|
|
|
11876
12009
|
styler = style.styler || null,
|
|
11877
12010
|
xmax = _canvas.width + size,
|
|
11878
12011
|
ymax = _canvas.height + size,
|
|
11879
|
-
|
|
12012
|
+
xmin = -size,
|
|
12013
|
+
ymin = -size,
|
|
12014
|
+
color = style.dotColor || 'black',
|
|
11880
12015
|
shp, x, y, i, j, n, m,
|
|
11881
12016
|
mx = t.mx,
|
|
11882
12017
|
my = t.my,
|
|
11883
12018
|
bx = t.bx,
|
|
11884
12019
|
by = t.by;
|
|
11885
12020
|
if (size === 0) return;
|
|
11886
|
-
if (size <= 6
|
|
12021
|
+
if (size <= 6) {
|
|
11887
12022
|
// optimized drawing of many small same-colored dots
|
|
11888
|
-
|
|
12023
|
+
drawSquareDotsFaster(shapes, style, size, t);
|
|
11889
12024
|
return;
|
|
11890
12025
|
}
|
|
12026
|
+
|
|
11891
12027
|
_ctx.fillStyle = color;
|
|
11892
12028
|
for (i=0, n=shapes.length; i<n; i++) {
|
|
11893
|
-
if (styler !== null) { // e.g. selected points
|
|
11894
|
-
styler(style, i);
|
|
11895
|
-
size = getDotSize(style);
|
|
11896
|
-
if (style.dotColor != color) {
|
|
11897
|
-
color = style.dotColor;
|
|
11898
|
-
_ctx.fillStyle = color;
|
|
11899
|
-
}
|
|
11900
|
-
}
|
|
11901
12029
|
shp = shapes[i];
|
|
11902
12030
|
for (j=0, m=shp ? shp.length : 0; j<m; j++) {
|
|
11903
12031
|
x = shp[j][0] * mx + bx;
|
|
11904
12032
|
y = shp[j][1] * my + by;
|
|
11905
|
-
if (x >
|
|
12033
|
+
if (x > xmin && y > ymin && x < xmax && y < ymax) {
|
|
12034
|
+
if (styler !== null) { // e.g. selected points
|
|
12035
|
+
styler(style, i);
|
|
12036
|
+
// avoid updating dot size for every shape (assuming dotSize is not dynamic)
|
|
12037
|
+
// size = getDotSize(style);
|
|
12038
|
+
if (style.dotColor != color) {
|
|
12039
|
+
color = style.dotColor || style.fillColor;
|
|
12040
|
+
_ctx.fillStyle = color;
|
|
12041
|
+
}
|
|
12042
|
+
}
|
|
11906
12043
|
drawSquare(x, y, size, _ctx);
|
|
11907
12044
|
}
|
|
11908
12045
|
}
|
|
11909
12046
|
}
|
|
11910
12047
|
};
|
|
11911
12048
|
|
|
11912
|
-
|
|
12049
|
+
function drawSquareDotsFaster(shapes, style, size, t) {
|
|
11913
12050
|
var w = _canvas.width,
|
|
11914
12051
|
h = _canvas.height,
|
|
11915
|
-
rgba = _pixelColor(
|
|
12052
|
+
rgba = _pixelColor(style.dotColor || style.fillColor),
|
|
12053
|
+
styler = style.styler,
|
|
11916
12054
|
imageData = _ctx.getImageData(0, 0, w, h),
|
|
11917
12055
|
pixels = new Uint32Array(imageData.data.buffer),
|
|
11918
12056
|
shp, x, y, i, j, n, m,
|
|
@@ -11920,18 +12058,33 @@
|
|
|
11920
12058
|
my = t.my,
|
|
11921
12059
|
bx = t.bx,
|
|
11922
12060
|
by = t.by;
|
|
11923
|
-
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
12061
|
+
if (styler) {
|
|
12062
|
+
for (i=0, n=shapes.length; i<n; i++) {
|
|
12063
|
+
shp = shapes[i];
|
|
12064
|
+
for (j=0, m=shp ? shp.length : 0; j<m; j++) {
|
|
12065
|
+
x = shp[j][0] * mx + bx;
|
|
12066
|
+
y = shp[j][1] * my + by;
|
|
12067
|
+
if (x >= 0 && y >= 0 && x <= w && y <= h) {
|
|
12068
|
+
styler(style, i);
|
|
12069
|
+
rgba = _pixelColor(style.dotColor || style.fillColor);
|
|
12070
|
+
drawSquareFaster(x, y, rgba, size, pixels, w, h);
|
|
12071
|
+
}
|
|
12072
|
+
}
|
|
12073
|
+
}
|
|
12074
|
+
} else {
|
|
12075
|
+
for (i=0, n=shapes.length; i<n; i++) {
|
|
12076
|
+
shp = shapes[i];
|
|
12077
|
+
for (j=0, m=shp ? shp.length : 0; j<m; j++) {
|
|
12078
|
+
x = shp[j][0] * mx + bx;
|
|
12079
|
+
y = shp[j][1] * my + by;
|
|
12080
|
+
if (x >= 0 && y >= 0 && x <= w && y <= h) {
|
|
12081
|
+
drawSquareFaster(x, y, rgba, size, pixels, w, h);
|
|
12082
|
+
}
|
|
11930
12083
|
}
|
|
11931
12084
|
}
|
|
11932
12085
|
}
|
|
11933
12086
|
_ctx.putImageData(imageData, 0, 0);
|
|
11934
|
-
}
|
|
12087
|
+
}
|
|
11935
12088
|
|
|
11936
12089
|
// color: 32-bit integer value containing rgba channel values
|
|
11937
12090
|
// size: pixels on a side (assume integer)
|
|
@@ -12467,6 +12620,14 @@
|
|
|
12467
12620
|
openAddFramePopup(gui, box.getDataCoords());
|
|
12468
12621
|
});
|
|
12469
12622
|
|
|
12623
|
+
gui.keyboard.on('keydown', function(e) {
|
|
12624
|
+
if (e.keyName == 'esc') {
|
|
12625
|
+
reset();
|
|
12626
|
+
e.stopPropagation();
|
|
12627
|
+
}
|
|
12628
|
+
|
|
12629
|
+
}, 10);
|
|
12630
|
+
|
|
12470
12631
|
gui.addMode('box_tool', turnOn, turnOff);
|
|
12471
12632
|
|
|
12472
12633
|
gui.on('interaction_mode_change', function(e) {
|
|
@@ -12477,6 +12638,7 @@
|
|
|
12477
12638
|
showInstructions();
|
|
12478
12639
|
}
|
|
12479
12640
|
} else if (_on) {
|
|
12641
|
+
gui.clearMode();
|
|
12480
12642
|
turnOff();
|
|
12481
12643
|
}
|
|
12482
12644
|
});
|
|
@@ -12501,7 +12663,7 @@
|
|
|
12501
12663
|
function showInstructions() {
|
|
12502
12664
|
var isMac = navigator.userAgent.includes('Mac');
|
|
12503
12665
|
var symbol = isMac ? '⌘' : '^';
|
|
12504
|
-
var msg = `Instructions:
|
|
12666
|
+
var msg = `Instructions: Click to start a rectangle. Drag handles to resize. Press shift key to resize symmetrically.`;
|
|
12505
12667
|
alert = showPopupAlert(msg, null, { non_blocking: true, max_width: '360px'});
|
|
12506
12668
|
}
|
|
12507
12669
|
|
|
@@ -12673,9 +12835,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12673
12835
|
map = this,
|
|
12674
12836
|
_mouse = new MouseArea(el, position),
|
|
12675
12837
|
_ext = new MapExtent(position),
|
|
12676
|
-
_nav = new MapNav(gui, _ext, _mouse),
|
|
12677
12838
|
_visibleLayers = [], // cached visible map layers
|
|
12678
|
-
_hit,
|
|
12839
|
+
_hit, _nav,
|
|
12679
12840
|
_intersectionLyr, _activeLyr, _overlayLyr,
|
|
12680
12841
|
_renderer, _dynamicCRS;
|
|
12681
12842
|
|
|
@@ -12723,8 +12884,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12723
12884
|
this.pixelCoordsToLngLatCoords = function(x, y) {
|
|
12724
12885
|
var crsFrom = this.getDisplayCRS();
|
|
12725
12886
|
if (!crsFrom) return null; // e.g. table view
|
|
12726
|
-
var p1 = internal.toLngLat(_ext.
|
|
12727
|
-
var p2 = internal.toLngLat(_ext.
|
|
12887
|
+
var p1 = internal.toLngLat(_ext.pixCoordsToMapCoords(x, y), crsFrom);
|
|
12888
|
+
var p2 = internal.toLngLat(_ext.pixCoordsToMapCoords(x+1, y+1), crsFrom);
|
|
12728
12889
|
return p1 && p2 && p1[1] <= 90 && p1[1] >= -90 ?
|
|
12729
12890
|
formatCoordsForDisplay(p1, p2) : null;
|
|
12730
12891
|
};
|
|
@@ -12735,8 +12896,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12735
12896
|
if (info && internal.isLatLngCRS(info.crs)) {
|
|
12736
12897
|
return null; // latlon dataset
|
|
12737
12898
|
}
|
|
12738
|
-
var p1 = translateDisplayPoint(_activeLyr, _ext.
|
|
12739
|
-
var p2 = translateDisplayPoint(_activeLyr, _ext.
|
|
12899
|
+
var p1 = translateDisplayPoint(_activeLyr, _ext.pixCoordsToMapCoords(x, y));
|
|
12900
|
+
var p2 = translateDisplayPoint(_activeLyr, _ext.pixCoordsToMapCoords(x+1, y+1));
|
|
12740
12901
|
return p1 && p2 ? formatCoordsForDisplay(p1, p2) : null;
|
|
12741
12902
|
};
|
|
12742
12903
|
|
|
@@ -12823,6 +12984,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12823
12984
|
_ext.setFullBounds(calcFullBounds());
|
|
12824
12985
|
_ext.resize();
|
|
12825
12986
|
_renderer = new LayerRenderer(gui, el);
|
|
12987
|
+
_nav = new MapNav(gui, _ext, _mouse);
|
|
12826
12988
|
|
|
12827
12989
|
if (opts.inspectorControl) {
|
|
12828
12990
|
_hit = new HitControl(gui, _ext, _mouse),
|
|
@@ -12855,6 +13017,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12855
13017
|
|
|
12856
13018
|
// Refresh map display in response to data changes, layer selection, etc.
|
|
12857
13019
|
function onUpdate(e) {
|
|
13020
|
+
var updated = model.getActiveLayer();
|
|
12858
13021
|
var prevLyr = _activeLyr || null;
|
|
12859
13022
|
var fullBounds;
|
|
12860
13023
|
var needReset;
|
|
@@ -12869,8 +13032,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12869
13032
|
|
|
12870
13033
|
// reset simplification after projection (thresholds have changed)
|
|
12871
13034
|
// TODO: preserve simplification pct (need to record pct before change)
|
|
12872
|
-
if (e.flags.proj &&
|
|
12873
|
-
|
|
13035
|
+
if (e.flags.proj && updated.dataset.arcs) {
|
|
13036
|
+
updated.dataset.arcs.setRetainedPct(1);
|
|
12874
13037
|
}
|
|
12875
13038
|
}
|
|
12876
13039
|
|
|
@@ -12883,9 +13046,9 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12883
13046
|
return;
|
|
12884
13047
|
}
|
|
12885
13048
|
|
|
12886
|
-
if (
|
|
12887
|
-
_activeLyr =
|
|
12888
|
-
initActiveLayer(
|
|
13049
|
+
if (updated.layer) {
|
|
13050
|
+
_activeLyr = updated.layer;
|
|
13051
|
+
initActiveLayer();
|
|
12889
13052
|
} else {
|
|
12890
13053
|
_activeLyr = null;
|
|
12891
13054
|
}
|
|
@@ -12974,7 +13137,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12974
13137
|
function calcFullBounds() {
|
|
12975
13138
|
var b;
|
|
12976
13139
|
if (isPreviewView()) {
|
|
12977
|
-
b = new Bounds(
|
|
13140
|
+
b = new Bounds(getFrameLayerData().bbox);
|
|
12978
13141
|
} else {
|
|
12979
13142
|
b = getContentLayerBounds();
|
|
12980
13143
|
}
|
|
@@ -13014,10 +13177,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13014
13177
|
|
|
13015
13178
|
// Preview view: symbols are scaled based on display size of frame layer
|
|
13016
13179
|
function isPreviewView() {
|
|
13017
|
-
return !isTableView() && !!
|
|
13180
|
+
return !isTableView() && !!getFrameLayerData();
|
|
13018
13181
|
}
|
|
13019
13182
|
|
|
13020
|
-
function
|
|
13183
|
+
function getFrameLayerData() {
|
|
13021
13184
|
var lyr = findFrameLayer();
|
|
13022
13185
|
return lyr && internal.getFrameLayerData(lyr, lyr.gui.displayArcs) || null;
|
|
13023
13186
|
}
|
|
@@ -13072,9 +13235,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13072
13235
|
});
|
|
13073
13236
|
}
|
|
13074
13237
|
|
|
13075
|
-
function initActiveLayer(
|
|
13076
|
-
|
|
13077
|
-
|
|
13238
|
+
function initActiveLayer() {
|
|
13239
|
+
var active = model.getActiveLayer();
|
|
13240
|
+
enhanceLayerForDisplay(active.layer, active.dataset, getDisplayOptions());
|
|
13241
|
+
active.layer.gui.style = getActiveLayerStyle(active.layer.gui.displayLayer, getGlobalStyleOptions());
|
|
13078
13242
|
}
|
|
13079
13243
|
|
|
13080
13244
|
function getDrawableFurnitureLayers(layers) {
|
|
@@ -13116,7 +13280,14 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13116
13280
|
});
|
|
13117
13281
|
}
|
|
13118
13282
|
|
|
13119
|
-
|
|
13283
|
+
var skipCounts = {
|
|
13284
|
+
nav: 0,
|
|
13285
|
+
hover: 0,
|
|
13286
|
+
redraw: 0
|
|
13287
|
+
};
|
|
13288
|
+
function drawLayers(actionArg) {
|
|
13289
|
+
var action = actionArg || 'redraw';
|
|
13290
|
+
skipCounts[action]++;
|
|
13120
13291
|
// This seems to smooth out navigation and keep overlay and basemap in sync.
|
|
13121
13292
|
requestAnimationFrame(function() {drawLayers2(action);});
|
|
13122
13293
|
}
|
|
@@ -13124,8 +13295,12 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13124
13295
|
// action:
|
|
13125
13296
|
// 'nav' map was panned/zoomed -- only map extent has changed
|
|
13126
13297
|
// 'hover' highlight has changed -- only refresh overlay
|
|
13127
|
-
//
|
|
13298
|
+
// 'redraw' anything could have changed
|
|
13128
13299
|
function drawLayers2(action) {
|
|
13300
|
+
if (--skipCounts[action] > 0) {
|
|
13301
|
+
// skip redraw if more draws are queued up
|
|
13302
|
+
return;
|
|
13303
|
+
}
|
|
13129
13304
|
// sometimes styles need to be regenerated with 'hover' action (when?)
|
|
13130
13305
|
var layersMayHaveChanged = action != 'nav'; // !action;
|
|
13131
13306
|
var fullBounds;
|
|
@@ -13138,7 +13313,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13138
13313
|
}
|
|
13139
13314
|
if (layersMayHaveChanged) {
|
|
13140
13315
|
// kludge to handle layer visibility toggling
|
|
13141
|
-
_ext.setFrameData(isPreviewView() ?
|
|
13316
|
+
_ext.setFrameData(isPreviewView() ? getFrameLayerData() : null);
|
|
13142
13317
|
updateFullBounds();
|
|
13143
13318
|
updateLayerStyles(contentLayers);
|
|
13144
13319
|
updateLayerStackOrder(model.getLayers());// update menu_order property of all layers
|
|
@@ -13457,8 +13632,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13457
13632
|
}
|
|
13458
13633
|
|
|
13459
13634
|
function refresh() {
|
|
13460
|
-
var
|
|
13461
|
-
|
|
13635
|
+
var off = !enabled() || !map || loading || !activeStyle ||
|
|
13636
|
+
!gui.map.getDisplayCRS(); // may be slow if getting bounds of many shapes
|
|
13462
13637
|
fadeBtn.active(!off);
|
|
13463
13638
|
clearBtn.active(!off);
|
|
13464
13639
|
if (off) {
|
|
@@ -13504,10 +13679,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13504
13679
|
gui.contextMenu = new ContextMenu();
|
|
13505
13680
|
gui.undo = new Undo(gui);
|
|
13506
13681
|
gui.map = new MshpMap(gui);
|
|
13507
|
-
|
|
13508
|
-
new SessionSnapshots(gui);
|
|
13509
|
-
}
|
|
13510
|
-
gui.interaction = new InteractionMode(gui);
|
|
13682
|
+
|
|
13511
13683
|
gui.state = {};
|
|
13512
13684
|
|
|
13513
13685
|
var msgCount = 0;
|
|
@@ -13516,6 +13688,11 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13516
13688
|
initModeRules(gui);
|
|
13517
13689
|
gui.map.init();
|
|
13518
13690
|
|
|
13691
|
+
if (opts.saveControl) {
|
|
13692
|
+
new SessionSnapshots(gui);
|
|
13693
|
+
}
|
|
13694
|
+
gui.interaction = new InteractionMode(gui);
|
|
13695
|
+
|
|
13519
13696
|
gui.showProgressMessage = function(msg) {
|
|
13520
13697
|
if (!gui.progressMessage) {
|
|
13521
13698
|
gui.progressMessage = El('div').addClass('progress-message')
|