mapshaper 0.6.102 → 0.6.104
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 +959 -816
- package/package.json +7 -7
- package/www/index.html +1 -1
- package/www/mapshaper-gui.js +381 -204
- package/www/mapshaper.js +959 -816
- package/www/modules.js +32141 -24119
- package/www/page.css +4 -0
package/www/mapshaper-gui.js
CHANGED
|
@@ -2,104 +2,105 @@
|
|
|
2
2
|
|
|
3
3
|
var utils = /*#__PURE__*/Object.freeze({
|
|
4
4
|
__proto__: null,
|
|
5
|
+
get addThousandsSep () { return addThousandsSep; },
|
|
6
|
+
get addslashes () { return addslashes; },
|
|
7
|
+
get arrayToIndex () { return arrayToIndex; },
|
|
8
|
+
get clamp () { return clamp; },
|
|
9
|
+
get cleanNumericString () { return cleanNumericString; },
|
|
10
|
+
get contains () { return contains; },
|
|
11
|
+
get copyElements () { return copyElements; },
|
|
12
|
+
get countValues () { return countValues; },
|
|
13
|
+
get createBuffer () { return createBuffer; },
|
|
5
14
|
get default () { return utils; },
|
|
15
|
+
get defaults () { return defaults; },
|
|
16
|
+
get difference () { return difference; },
|
|
17
|
+
get endsWith () { return endsWith; },
|
|
18
|
+
get every () { return every; },
|
|
19
|
+
get expandoBuffer () { return expandoBuffer; },
|
|
20
|
+
get extend () { return extend; },
|
|
21
|
+
get extendBuffer () { return extendBuffer; },
|
|
22
|
+
get find () { return find; },
|
|
23
|
+
get findMedian () { return findMedian; },
|
|
24
|
+
get findQuantile () { return findQuantile; },
|
|
25
|
+
get findRankByValue () { return findRankByValue; },
|
|
26
|
+
get findStringPrefix () { return findStringPrefix; },
|
|
27
|
+
get findValueByPct () { return findValueByPct; },
|
|
28
|
+
get findValueByRank () { return findValueByRank; },
|
|
29
|
+
get forEach () { return forEach; },
|
|
30
|
+
get forEachProperty () { return forEachProperty; },
|
|
31
|
+
get format () { return format; },
|
|
32
|
+
get formatDateISO () { return formatDateISO; },
|
|
33
|
+
get formatIntlNumber () { return formatIntlNumber; },
|
|
34
|
+
get formatNumber () { return formatNumber; },
|
|
35
|
+
get formatNumberForDisplay () { return formatNumberForDisplay; },
|
|
36
|
+
get formatVersionedName () { return formatVersionedName; },
|
|
37
|
+
get formatter () { return formatter; },
|
|
38
|
+
get genericSort () { return genericSort; },
|
|
39
|
+
get getArrayBounds () { return getArrayBounds; },
|
|
40
|
+
get getGenericComparator () { return getGenericComparator; },
|
|
41
|
+
get getKeyComparator () { return getKeyComparator; },
|
|
42
|
+
get getSortedIds () { return getSortedIds; },
|
|
6
43
|
get getUniqueName () { return getUniqueName; },
|
|
7
|
-
get
|
|
8
|
-
get
|
|
9
|
-
get
|
|
10
|
-
get
|
|
44
|
+
get groupBy () { return groupBy; },
|
|
45
|
+
get htmlEscape () { return htmlEscape; },
|
|
46
|
+
get indexOf () { return indexOf; },
|
|
47
|
+
get indexOn () { return indexOn; },
|
|
48
|
+
get inherit () { return inherit; },
|
|
49
|
+
get initializeArray () { return initializeArray; },
|
|
50
|
+
get intersection () { return intersection; },
|
|
11
51
|
get isArray () { return isArray; },
|
|
12
|
-
get
|
|
13
|
-
get
|
|
52
|
+
get isArrayLike () { return isArrayLike; },
|
|
53
|
+
get isBoolean () { return isBoolean; },
|
|
54
|
+
get isDate () { return isDate; },
|
|
55
|
+
get isEven () { return isEven; },
|
|
14
56
|
get isFiniteNumber () { return isFiniteNumber; },
|
|
15
|
-
get
|
|
57
|
+
get isFunction () { return isFunction; },
|
|
16
58
|
get isInteger () { return isInteger; },
|
|
17
|
-
get
|
|
59
|
+
get isNonNegNumber () { return isNonNegNumber; },
|
|
60
|
+
get isNumber () { return isNumber; },
|
|
61
|
+
get isObject () { return isObject; },
|
|
18
62
|
get isOdd () { return isOdd; },
|
|
63
|
+
get isPromise () { return isPromise; },
|
|
19
64
|
get isString () { return isString; },
|
|
20
|
-
get
|
|
21
|
-
get
|
|
22
|
-
get
|
|
23
|
-
get
|
|
24
|
-
get isArrayLike () { return isArrayLike; },
|
|
25
|
-
get addslashes () { return addslashes; },
|
|
26
|
-
get regexEscape () { return regexEscape; },
|
|
27
|
-
get htmlEscape () { return htmlEscape; },
|
|
28
|
-
get defaults () { return defaults; },
|
|
29
|
-
get extend () { return extend; },
|
|
30
|
-
get inherit () { return inherit; },
|
|
31
|
-
get promisify () { return promisify; },
|
|
32
|
-
get reduceAsync () { return reduceAsync; },
|
|
65
|
+
get isValidNumber () { return isValidNumber; },
|
|
66
|
+
get lpad () { return lpad; },
|
|
67
|
+
get ltrim () { return ltrim; },
|
|
68
|
+
get mean () { return mean; },
|
|
33
69
|
get merge () { return merge; },
|
|
34
|
-
get
|
|
35
|
-
get
|
|
36
|
-
get
|
|
37
|
-
get
|
|
38
|
-
get
|
|
39
|
-
get
|
|
40
|
-
get
|
|
70
|
+
get mergeNames () { return mergeNames; },
|
|
71
|
+
get numToStr () { return numToStr; },
|
|
72
|
+
get parseIntlNumber () { return parseIntlNumber; },
|
|
73
|
+
get parseNumber () { return parseNumber; },
|
|
74
|
+
get parsePercent () { return parsePercent; },
|
|
75
|
+
get parseString () { return parseString; },
|
|
76
|
+
get pickOne () { return pickOne; },
|
|
77
|
+
get pluck () { return pluck; },
|
|
78
|
+
get pluralSuffix () { return pluralSuffix; },
|
|
79
|
+
get promisify () { return promisify; },
|
|
80
|
+
get quicksort () { return quicksort; },
|
|
81
|
+
get quicksortPartition () { return quicksortPartition; },
|
|
41
82
|
get range () { return range; },
|
|
83
|
+
get reduceAsync () { return reduceAsync; },
|
|
84
|
+
get regexEscape () { return regexEscape; },
|
|
85
|
+
get reorderArray () { return reorderArray; },
|
|
42
86
|
get repeat () { return repeat; },
|
|
43
|
-
get sum () { return sum; },
|
|
44
|
-
get getArrayBounds () { return getArrayBounds; },
|
|
45
|
-
get uniq () { return uniq; },
|
|
46
|
-
get pluck () { return pluck; },
|
|
47
|
-
get countValues () { return countValues; },
|
|
48
|
-
get indexOn () { return indexOn; },
|
|
49
|
-
get groupBy () { return groupBy; },
|
|
50
|
-
get arrayToIndex () { return arrayToIndex; },
|
|
51
|
-
get forEach () { return forEach; },
|
|
52
|
-
get forEachProperty () { return forEachProperty; },
|
|
53
|
-
get initializeArray () { return initializeArray; },
|
|
54
|
-
get replaceArray () { return replaceArray; },
|
|
55
87
|
get repeatString () { return repeatString; },
|
|
56
|
-
get
|
|
57
|
-
get pluralSuffix () { return pluralSuffix; },
|
|
58
|
-
get endsWith () { return endsWith; },
|
|
59
|
-
get lpad () { return lpad; },
|
|
88
|
+
get replaceArray () { return replaceArray; },
|
|
60
89
|
get rpad () { return rpad; },
|
|
61
|
-
get trim () { return trim; },
|
|
62
|
-
get ltrim () { return ltrim; },
|
|
63
90
|
get rtrim () { return rtrim; },
|
|
64
|
-
get addThousandsSep () { return addThousandsSep; },
|
|
65
|
-
get numToStr () { return numToStr; },
|
|
66
|
-
get formatNumber () { return formatNumber; },
|
|
67
|
-
get formatIntlNumber () { return formatIntlNumber; },
|
|
68
|
-
get formatNumberForDisplay () { return formatNumberForDisplay; },
|
|
69
91
|
get shuffle () { return shuffle; },
|
|
70
|
-
get
|
|
71
|
-
get genericSort () { return genericSort; },
|
|
72
|
-
get getSortedIds () { return getSortedIds; },
|
|
92
|
+
get some () { return some; },
|
|
73
93
|
get sortArrayIndex () { return sortArrayIndex; },
|
|
74
|
-
get
|
|
75
|
-
get
|
|
76
|
-
get
|
|
77
|
-
get
|
|
78
|
-
get quicksortPartition () { return quicksortPartition; },
|
|
79
|
-
get findRankByValue () { return findRankByValue; },
|
|
80
|
-
get findValueByPct () { return findValueByPct; },
|
|
81
|
-
get findValueByRank () { return findValueByRank; },
|
|
82
|
-
get findMedian () { return findMedian; },
|
|
83
|
-
get findQuantile () { return findQuantile; },
|
|
84
|
-
get mean () { return mean; },
|
|
85
|
-
get format () { return format; },
|
|
86
|
-
get formatter () { return formatter; },
|
|
87
|
-
get wildcardToRegExp () { return wildcardToRegExp; },
|
|
88
|
-
get createBuffer () { return createBuffer; },
|
|
94
|
+
get sortOn () { return sortOn; },
|
|
95
|
+
get splitLines () { return splitLines; },
|
|
96
|
+
get sum () { return sum; },
|
|
97
|
+
get toArray () { return toArray; },
|
|
89
98
|
get toBuffer () { return toBuffer; },
|
|
90
|
-
get
|
|
91
|
-
get
|
|
92
|
-
get
|
|
93
|
-
get mergeNames () { return mergeNames; },
|
|
94
|
-
get findStringPrefix () { return findStringPrefix; },
|
|
95
|
-
get parsePercent () { return parsePercent; },
|
|
96
|
-
get formatVersionedName () { return formatVersionedName; },
|
|
99
|
+
get trim () { return trim; },
|
|
100
|
+
get trimQuotes () { return trimQuotes; },
|
|
101
|
+
get uniq () { return uniq; },
|
|
97
102
|
get uniqifyNames () { return uniqifyNames; },
|
|
98
|
-
get
|
|
99
|
-
get parseNumber () { return parseNumber; },
|
|
100
|
-
get parseIntlNumber () { return parseIntlNumber; },
|
|
101
|
-
get cleanNumericString () { return cleanNumericString; },
|
|
102
|
-
get trimQuotes () { return trimQuotes; }
|
|
103
|
+
get wildcardToRegExp () { return wildcardToRegExp; }
|
|
103
104
|
});
|
|
104
105
|
|
|
105
106
|
var api = window.mapshaper; // assuming mapshaper is in global scope
|
|
@@ -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.
|
|
@@ -7268,6 +7306,10 @@
|
|
|
7268
7306
|
}
|
|
7269
7307
|
}
|
|
7270
7308
|
|
|
7309
|
+
function pickOne(arr) {
|
|
7310
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
7311
|
+
}
|
|
7312
|
+
|
|
7271
7313
|
// Sort an array of objects based on one or more properties.
|
|
7272
7314
|
// Usage: sortOn(array, key1, asc?[, key2, asc? ...])
|
|
7273
7315
|
//
|
|
@@ -8005,7 +8047,7 @@
|
|
|
8005
8047
|
function getShapeHitTest(layer, ext, interactionMode, featureFilter) {
|
|
8006
8048
|
var geoType = layer.gui.displayLayer.geometry_type;
|
|
8007
8049
|
var test;
|
|
8008
|
-
if (geoType == 'point' && layer.gui.style.type == 'styled') {
|
|
8050
|
+
if (geoType == 'point' && layer.gui.style.type == 'styled' && !layer.gui.style.dotSize) {
|
|
8009
8051
|
test = getGraduatedCircleTest(getRadiusFunction(layer.gui.style));
|
|
8010
8052
|
} else if (geoType == 'point') {
|
|
8011
8053
|
test = pointTest;
|
|
@@ -8338,7 +8380,7 @@
|
|
|
8338
8380
|
|
|
8339
8381
|
// e: pointer event
|
|
8340
8382
|
return function(e) {
|
|
8341
|
-
var p = ext.
|
|
8383
|
+
var p = ext.pixCoordsToMapCoords(e.x, e.y);
|
|
8342
8384
|
// update SVG hit test on each test, in case SVG layer has been redrawn
|
|
8343
8385
|
// and the symbol container has changed
|
|
8344
8386
|
var svgTest = getSvgHitTest(mapLayer);
|
|
@@ -9274,6 +9316,7 @@
|
|
|
9274
9316
|
persistent: false,
|
|
9275
9317
|
draggable: false // does dragging the map draw a box
|
|
9276
9318
|
}, optsArg),
|
|
9319
|
+
clickToStart = opts.name == 'box-tool', // other versions use shift-drag
|
|
9277
9320
|
box = new EventDispatcher(),
|
|
9278
9321
|
stroke = 2,
|
|
9279
9322
|
activeHandle = null,
|
|
@@ -9281,38 +9324,75 @@
|
|
|
9281
9324
|
boxCoords = null,
|
|
9282
9325
|
_on = false,
|
|
9283
9326
|
_visible = false,
|
|
9327
|
+
clickStartPoint,
|
|
9284
9328
|
handles;
|
|
9285
|
-
|
|
9286
9329
|
if (opts.classname) {
|
|
9287
9330
|
el.addClass(opts.classname);
|
|
9288
9331
|
}
|
|
9289
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
|
+
|
|
9290
9345
|
el.hide();
|
|
9291
9346
|
|
|
9292
9347
|
gui.on('map_rendered', function() {
|
|
9293
|
-
if (!
|
|
9348
|
+
if (!visible()) return;
|
|
9294
9349
|
redraw();
|
|
9295
9350
|
});
|
|
9296
9351
|
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
|
|
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
|
+
}
|
|
9304
9395
|
|
|
9305
|
-
gui.on('shift_drag_end', function(e) {
|
|
9306
|
-
if (!_on || !_visible || !opts.draggable) return;
|
|
9307
|
-
boxCoords = getBoxCoords(e.data);
|
|
9308
|
-
var pix = coordsToPix(boxCoords, gui.map.getExtent());
|
|
9309
|
-
box.dispatchEvent('dragend', {map_bbox: pix});
|
|
9310
|
-
if (!opts.persistent) {
|
|
9311
|
-
box.hide();
|
|
9312
|
-
} else {
|
|
9313
|
-
redraw();
|
|
9314
|
-
}
|
|
9315
|
-
});
|
|
9316
9396
|
|
|
9317
9397
|
if (opts.handles) {
|
|
9318
9398
|
handles = initHandles(el);
|
|
@@ -9325,7 +9405,7 @@
|
|
|
9325
9405
|
});
|
|
9326
9406
|
|
|
9327
9407
|
gui.map.getMouse().on('mousemove', function(e) {
|
|
9328
|
-
if (!
|
|
9408
|
+
if (!resizing() || !prevXY) return;
|
|
9329
9409
|
var xy = {x: e.pageX, y: e.pageY};
|
|
9330
9410
|
var scaling = gui.keyboard.shiftIsPressed() && activeHandle.type == 'corner';
|
|
9331
9411
|
if (scaling) {
|
|
@@ -9351,6 +9431,27 @@
|
|
|
9351
9431
|
});
|
|
9352
9432
|
}
|
|
9353
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
|
+
|
|
9354
9455
|
function resizeBox(dx, dy, activeHandle) {
|
|
9355
9456
|
var shifting = activeHandle.type == 'center';
|
|
9356
9457
|
var centered = gui.keyboard.shiftIsPressed() && activeHandle.type == 'edge';
|
|
@@ -9377,7 +9478,7 @@
|
|
|
9377
9478
|
}
|
|
9378
9479
|
|
|
9379
9480
|
function rescaleBox(x, y) {
|
|
9380
|
-
var p = gui.map.getExtent().
|
|
9481
|
+
var p = gui.map.getExtent().pixCoordsToMapCoords(x, y);
|
|
9381
9482
|
var cx = (boxCoords[0] + boxCoords[2])/2;
|
|
9382
9483
|
var cy = (boxCoords[1] + boxCoords[3])/2;
|
|
9383
9484
|
var dist2 = geom.distance2D(cx, cy, p[0], p[1]);
|
|
@@ -9407,12 +9508,16 @@
|
|
|
9407
9508
|
|
|
9408
9509
|
box.turnOff = function() {
|
|
9409
9510
|
_on = false;
|
|
9511
|
+
box.hide();
|
|
9410
9512
|
};
|
|
9411
9513
|
|
|
9514
|
+
// remove the current box (if any)
|
|
9412
9515
|
box.hide = function() {
|
|
9413
9516
|
el.hide();
|
|
9414
9517
|
boxCoords = null;
|
|
9415
9518
|
_visible = false;
|
|
9519
|
+
clickStartPoint = null;
|
|
9520
|
+
activeHandle = null;
|
|
9416
9521
|
};
|
|
9417
9522
|
|
|
9418
9523
|
box.show = function(x1, y1, x2, y2) {
|
|
@@ -9452,12 +9557,35 @@
|
|
|
9452
9557
|
}
|
|
9453
9558
|
|
|
9454
9559
|
// get bbox coords in the display CRS
|
|
9455
|
-
function getBoxCoords(
|
|
9456
|
-
|
|
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());
|
|
9457
9565
|
fixBounds(bbox);
|
|
9458
9566
|
return bbox;
|
|
9459
9567
|
}
|
|
9460
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
|
+
|
|
9461
9589
|
function redraw() {
|
|
9462
9590
|
if (!boxCoords) return;
|
|
9463
9591
|
var ext = gui.map.getExtent();
|
|
@@ -9478,12 +9606,12 @@
|
|
|
9478
9606
|
}
|
|
9479
9607
|
|
|
9480
9608
|
function pixToCoords(bbox, ext) {
|
|
9481
|
-
var a = ext.
|
|
9482
|
-
var b = ext.
|
|
9609
|
+
var a = ext.pixCoordsToMapCoords(bbox[0], bbox[1]);
|
|
9610
|
+
var b = ext.pixCoordsToMapCoords(bbox[2], bbox[3]);
|
|
9483
9611
|
return [a[0], b[1], b[0], a[1]];
|
|
9484
9612
|
}
|
|
9485
9613
|
|
|
9486
|
-
|
|
9614
|
+
// enforce [minx, miny, maxx, maxy] order
|
|
9487
9615
|
function fixBounds(bbox) {
|
|
9488
9616
|
var tmp;
|
|
9489
9617
|
if (bbox[0] > bbox[2]) {
|
|
@@ -9615,7 +9743,7 @@
|
|
|
9615
9743
|
mouse.on('drag', function(e) {
|
|
9616
9744
|
if (disabled()) return;
|
|
9617
9745
|
if (shiftDrag) {
|
|
9618
|
-
gui.dispatchEvent('shift_drag', getBoxData(e));
|
|
9746
|
+
gui.dispatchEvent('shift_drag', getBoxData(e, dragStartEvt));
|
|
9619
9747
|
return;
|
|
9620
9748
|
}
|
|
9621
9749
|
if (++panCount == 1) {
|
|
@@ -9635,7 +9763,7 @@
|
|
|
9635
9763
|
if (disabled()) return;
|
|
9636
9764
|
if (shiftDrag) {
|
|
9637
9765
|
shiftDrag = false;
|
|
9638
|
-
gui.dispatchEvent('shift_drag_end', getBoxData(e));
|
|
9766
|
+
gui.dispatchEvent('shift_drag_end', getBoxData(e, dragStartEvt));
|
|
9639
9767
|
zoomBox.turnOff();
|
|
9640
9768
|
} else {
|
|
9641
9769
|
El('body').removeClass('panning').removeClass('pan');
|
|
@@ -9659,10 +9787,10 @@
|
|
|
9659
9787
|
return !'selection_tool,box_tool,rectangle_tool,drawing_tool'.includes(mode);
|
|
9660
9788
|
}
|
|
9661
9789
|
|
|
9662
|
-
function getBoxData(
|
|
9790
|
+
function getBoxData(e1, e2) {
|
|
9663
9791
|
return {
|
|
9664
|
-
a: [
|
|
9665
|
-
b: [
|
|
9792
|
+
a: [e1.x, e1.y],
|
|
9793
|
+
b: [e2.x, e2.y]
|
|
9666
9794
|
};
|
|
9667
9795
|
}
|
|
9668
9796
|
|
|
@@ -10546,8 +10674,8 @@
|
|
|
10546
10674
|
var coords = target.shapes[id];
|
|
10547
10675
|
deleteFeature(target, id);
|
|
10548
10676
|
gui.dispatchEvent('feature_delete', {coords, d, target, fid: id});
|
|
10549
|
-
gui.dispatchEvent('map-needs-refresh');
|
|
10550
10677
|
hit.setHitId(-1);
|
|
10678
|
+
gui.dispatchEvent('map-needs-refresh');
|
|
10551
10679
|
}
|
|
10552
10680
|
|
|
10553
10681
|
hit.on('click', function(e) {
|
|
@@ -10602,12 +10730,12 @@
|
|
|
10602
10730
|
|
|
10603
10731
|
function pixToDataCoords(x, y) {
|
|
10604
10732
|
var target = hit.getHitTarget();
|
|
10605
|
-
return translateDisplayPoint(target, ext.
|
|
10733
|
+
return translateDisplayPoint(target, ext.pixCoordsToMapCoords(x, y));
|
|
10606
10734
|
}
|
|
10607
10735
|
|
|
10608
10736
|
function translateDeltaDisplayCoords(dx, dy, ext) {
|
|
10609
|
-
var a = ext.
|
|
10610
|
-
var b = ext.
|
|
10737
|
+
var a = ext.pixCoordsToMapCoords(0, 0);
|
|
10738
|
+
var b = ext.pixCoordsToMapCoords(dx, dy);
|
|
10611
10739
|
return [b[0] - a[0], b[1] - a[1]];
|
|
10612
10740
|
}
|
|
10613
10741
|
}
|
|
@@ -10887,7 +11015,7 @@
|
|
|
10887
11015
|
e.originalEvent.stopPropagation();
|
|
10888
11016
|
// dragging a vertex
|
|
10889
11017
|
var target = hit.getHitTarget();
|
|
10890
|
-
var p = ext.
|
|
11018
|
+
var p = ext.pixCoordsToMapCoords(e.x, e.y);
|
|
10891
11019
|
if (gui.keyboard.shiftIsPressed()) {
|
|
10892
11020
|
internal.snapPointToArcEndpoint(p, hoverVertexInfo.ids, target.gui.displayArcs);
|
|
10893
11021
|
}
|
|
@@ -10905,8 +11033,8 @@
|
|
|
10905
11033
|
target.gui.displayArcs.transformPoints(function() {});
|
|
10906
11034
|
updateVertexCoords(target, hoverVertexInfo.ids);
|
|
10907
11035
|
gui.dispatchEvent('vertex_dragend', hoverVertexInfo);
|
|
10908
|
-
gui.dispatchEvent('map-needs-refresh'); // redraw basemap
|
|
10909
11036
|
clearHoverVertex();
|
|
11037
|
+
gui.dispatchEvent('map-needs-refresh'); // redraw basemap
|
|
10910
11038
|
});
|
|
10911
11039
|
|
|
10912
11040
|
// shift + double-click deletes a vertex (when not drawing)
|
|
@@ -11020,7 +11148,7 @@
|
|
|
11020
11148
|
|
|
11021
11149
|
function pixToDataCoords(x, y) {
|
|
11022
11150
|
var target = hit.getHitTarget();
|
|
11023
|
-
return translateDisplayPoint(target, ext.
|
|
11151
|
+
return translateDisplayPoint(target, ext.pixCoordsToMapCoords(x, y));
|
|
11024
11152
|
}
|
|
11025
11153
|
|
|
11026
11154
|
// Change the x, y pixel location of thisEvt so that the segment extending
|
|
@@ -11142,7 +11270,7 @@
|
|
|
11142
11270
|
if (!pathDrawing()) return false;
|
|
11143
11271
|
var target = hit.getHitTarget();
|
|
11144
11272
|
var arcId = target.gui.displayArcs.size() - 1;
|
|
11145
|
-
var p1 = ext.
|
|
11273
|
+
var p1 = ext.pixCoordsToMapCoords(e.x, e.y); // mouse coords
|
|
11146
11274
|
var p2 = internal.getArcStartCoords(arcId, target.gui.displayArcs); // vertex coords
|
|
11147
11275
|
var p3 = internal.getArcStartCoords(arcId, target.gui.source.dataset.arcs);
|
|
11148
11276
|
var dist = geom.distance2D(p1[0], p1[1], p2[0], p2[1]);
|
|
@@ -11164,7 +11292,7 @@
|
|
|
11164
11292
|
function findDraggableVertices(e) {
|
|
11165
11293
|
var target = hit.getHitTarget();
|
|
11166
11294
|
var shp = target.shapes[e.id];
|
|
11167
|
-
var p = ext.
|
|
11295
|
+
var p = ext.pixCoordsToMapCoords(e.x, e.y);
|
|
11168
11296
|
var ids = internal.findNearestVertices(p, shp, target.gui.displayArcs);
|
|
11169
11297
|
var p2 = target.gui.displayArcs.getVertex2(ids[0]);
|
|
11170
11298
|
var dist = geom.distance2D(p[0], p[1], p2[0], p2[1]);
|
|
@@ -11186,7 +11314,7 @@
|
|
|
11186
11314
|
var target = hit.getHitTarget();
|
|
11187
11315
|
//// vertex insertion not supported with simplification
|
|
11188
11316
|
// if (!target.arcs.isFlat()) return null;
|
|
11189
|
-
var p = ext.
|
|
11317
|
+
var p = ext.pixCoordsToMapCoords(e.x, e.y);
|
|
11190
11318
|
var minDist = Infinity;
|
|
11191
11319
|
var shp = target.shapes[e.id];
|
|
11192
11320
|
var closest;
|
|
@@ -11411,7 +11539,7 @@
|
|
|
11411
11539
|
};
|
|
11412
11540
|
|
|
11413
11541
|
// convert pixel coords (0,0 is top left corner of map) to display CRS coords
|
|
11414
|
-
this.
|
|
11542
|
+
this.pixCoordsToMapCoords = function(x, y) {
|
|
11415
11543
|
return this.getTransform().invert().transform(x, y);
|
|
11416
11544
|
};
|
|
11417
11545
|
|
|
@@ -11683,7 +11811,7 @@
|
|
|
11683
11811
|
var layer = lyr.gui.displayLayer;
|
|
11684
11812
|
var arcs, filter;
|
|
11685
11813
|
if (layer.geometry_type == 'point') {
|
|
11686
|
-
if (style.type == 'styled') {
|
|
11814
|
+
if (style.type == 'styled' && !style.dotSize) {
|
|
11687
11815
|
canv.drawPoints(layer.shapes, style);
|
|
11688
11816
|
} else {
|
|
11689
11817
|
canv.drawSquareDots(layer.shapes, style);
|
|
@@ -11739,11 +11867,15 @@
|
|
|
11739
11867
|
var canv = El('canvas').node();
|
|
11740
11868
|
canv.width = canv.height = 1;
|
|
11741
11869
|
var ctx = canv.getContext('2d', {willReadFrequently: true});
|
|
11870
|
+
var memos = {};
|
|
11742
11871
|
return function(col) {
|
|
11743
11872
|
var pixels;
|
|
11873
|
+
if (!col) col = 'black';
|
|
11874
|
+
if (col in memos) return memos[col];
|
|
11744
11875
|
ctx.fillStyle = col;
|
|
11745
11876
|
ctx.fillRect(0, 0, 1, 1);
|
|
11746
11877
|
pixels = new Uint32Array(ctx.getImageData(0, 0, 1, 1).data.buffer);
|
|
11878
|
+
memos[col] = pixels[0];
|
|
11747
11879
|
return pixels[0];
|
|
11748
11880
|
};
|
|
11749
11881
|
}
|
|
@@ -11877,43 +12009,48 @@
|
|
|
11877
12009
|
styler = style.styler || null,
|
|
11878
12010
|
xmax = _canvas.width + size,
|
|
11879
12011
|
ymax = _canvas.height + size,
|
|
11880
|
-
|
|
12012
|
+
xmin = -size,
|
|
12013
|
+
ymin = -size,
|
|
12014
|
+
color = style.dotColor || 'black',
|
|
11881
12015
|
shp, x, y, i, j, n, m,
|
|
11882
12016
|
mx = t.mx,
|
|
11883
12017
|
my = t.my,
|
|
11884
12018
|
bx = t.bx,
|
|
11885
12019
|
by = t.by;
|
|
11886
12020
|
if (size === 0) return;
|
|
11887
|
-
if (size <= 6
|
|
12021
|
+
if (size <= 6) {
|
|
11888
12022
|
// optimized drawing of many small same-colored dots
|
|
11889
|
-
|
|
12023
|
+
drawSquareDotsFaster(shapes, style, size, t);
|
|
11890
12024
|
return;
|
|
11891
12025
|
}
|
|
12026
|
+
|
|
11892
12027
|
_ctx.fillStyle = color;
|
|
11893
12028
|
for (i=0, n=shapes.length; i<n; i++) {
|
|
11894
|
-
if (styler !== null) { // e.g. selected points
|
|
11895
|
-
styler(style, i);
|
|
11896
|
-
size = getDotSize(style);
|
|
11897
|
-
if (style.dotColor != color) {
|
|
11898
|
-
color = style.dotColor;
|
|
11899
|
-
_ctx.fillStyle = color;
|
|
11900
|
-
}
|
|
11901
|
-
}
|
|
11902
12029
|
shp = shapes[i];
|
|
11903
12030
|
for (j=0, m=shp ? shp.length : 0; j<m; j++) {
|
|
11904
12031
|
x = shp[j][0] * mx + bx;
|
|
11905
12032
|
y = shp[j][1] * my + by;
|
|
11906
|
-
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
|
+
}
|
|
11907
12043
|
drawSquare(x, y, size, _ctx);
|
|
11908
12044
|
}
|
|
11909
12045
|
}
|
|
11910
12046
|
}
|
|
11911
12047
|
};
|
|
11912
12048
|
|
|
11913
|
-
|
|
12049
|
+
function drawSquareDotsFaster(shapes, style, size, t) {
|
|
11914
12050
|
var w = _canvas.width,
|
|
11915
12051
|
h = _canvas.height,
|
|
11916
|
-
rgba = _pixelColor(
|
|
12052
|
+
rgba = _pixelColor(style.dotColor || style.fillColor),
|
|
12053
|
+
styler = style.styler,
|
|
11917
12054
|
imageData = _ctx.getImageData(0, 0, w, h),
|
|
11918
12055
|
pixels = new Uint32Array(imageData.data.buffer),
|
|
11919
12056
|
shp, x, y, i, j, n, m,
|
|
@@ -11921,18 +12058,33 @@
|
|
|
11921
12058
|
my = t.my,
|
|
11922
12059
|
bx = t.bx,
|
|
11923
12060
|
by = t.by;
|
|
11924
|
-
|
|
11925
|
-
|
|
11926
|
-
|
|
11927
|
-
|
|
11928
|
-
|
|
11929
|
-
|
|
11930
|
-
|
|
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
|
+
}
|
|
11931
12083
|
}
|
|
11932
12084
|
}
|
|
11933
12085
|
}
|
|
11934
12086
|
_ctx.putImageData(imageData, 0, 0);
|
|
11935
|
-
}
|
|
12087
|
+
}
|
|
11936
12088
|
|
|
11937
12089
|
// color: 32-bit integer value containing rgba channel values
|
|
11938
12090
|
// size: pixels on a side (assume integer)
|
|
@@ -12468,6 +12620,14 @@
|
|
|
12468
12620
|
openAddFramePopup(gui, box.getDataCoords());
|
|
12469
12621
|
});
|
|
12470
12622
|
|
|
12623
|
+
gui.keyboard.on('keydown', function(e) {
|
|
12624
|
+
if (e.keyName == 'esc') {
|
|
12625
|
+
reset();
|
|
12626
|
+
e.stopPropagation();
|
|
12627
|
+
}
|
|
12628
|
+
|
|
12629
|
+
}, 10);
|
|
12630
|
+
|
|
12471
12631
|
gui.addMode('box_tool', turnOn, turnOff);
|
|
12472
12632
|
|
|
12473
12633
|
gui.on('interaction_mode_change', function(e) {
|
|
@@ -12478,6 +12638,7 @@
|
|
|
12478
12638
|
showInstructions();
|
|
12479
12639
|
}
|
|
12480
12640
|
} else if (_on) {
|
|
12641
|
+
gui.clearMode();
|
|
12481
12642
|
turnOff();
|
|
12482
12643
|
}
|
|
12483
12644
|
});
|
|
@@ -12502,7 +12663,7 @@
|
|
|
12502
12663
|
function showInstructions() {
|
|
12503
12664
|
var isMac = navigator.userAgent.includes('Mac');
|
|
12504
12665
|
var symbol = isMac ? '⌘' : '^';
|
|
12505
|
-
var msg = `Instructions:
|
|
12666
|
+
var msg = `Instructions: Click to start a rectangle. Drag handles to resize. Press shift key to resize symmetrically.`;
|
|
12506
12667
|
alert = showPopupAlert(msg, null, { non_blocking: true, max_width: '360px'});
|
|
12507
12668
|
}
|
|
12508
12669
|
|
|
@@ -12674,9 +12835,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12674
12835
|
map = this,
|
|
12675
12836
|
_mouse = new MouseArea(el, position),
|
|
12676
12837
|
_ext = new MapExtent(position),
|
|
12677
|
-
_nav = new MapNav(gui, _ext, _mouse),
|
|
12678
12838
|
_visibleLayers = [], // cached visible map layers
|
|
12679
|
-
_hit,
|
|
12839
|
+
_hit, _nav,
|
|
12680
12840
|
_intersectionLyr, _activeLyr, _overlayLyr,
|
|
12681
12841
|
_renderer, _dynamicCRS;
|
|
12682
12842
|
|
|
@@ -12724,8 +12884,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12724
12884
|
this.pixelCoordsToLngLatCoords = function(x, y) {
|
|
12725
12885
|
var crsFrom = this.getDisplayCRS();
|
|
12726
12886
|
if (!crsFrom) return null; // e.g. table view
|
|
12727
|
-
var p1 = internal.toLngLat(_ext.
|
|
12728
|
-
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);
|
|
12729
12889
|
return p1 && p2 && p1[1] <= 90 && p1[1] >= -90 ?
|
|
12730
12890
|
formatCoordsForDisplay(p1, p2) : null;
|
|
12731
12891
|
};
|
|
@@ -12736,8 +12896,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12736
12896
|
if (info && internal.isLatLngCRS(info.crs)) {
|
|
12737
12897
|
return null; // latlon dataset
|
|
12738
12898
|
}
|
|
12739
|
-
var p1 = translateDisplayPoint(_activeLyr, _ext.
|
|
12740
|
-
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));
|
|
12741
12901
|
return p1 && p2 ? formatCoordsForDisplay(p1, p2) : null;
|
|
12742
12902
|
};
|
|
12743
12903
|
|
|
@@ -12824,6 +12984,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12824
12984
|
_ext.setFullBounds(calcFullBounds());
|
|
12825
12985
|
_ext.resize();
|
|
12826
12986
|
_renderer = new LayerRenderer(gui, el);
|
|
12987
|
+
_nav = new MapNav(gui, _ext, _mouse);
|
|
12827
12988
|
|
|
12828
12989
|
if (opts.inspectorControl) {
|
|
12829
12990
|
_hit = new HitControl(gui, _ext, _mouse),
|
|
@@ -12856,6 +13017,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12856
13017
|
|
|
12857
13018
|
// Refresh map display in response to data changes, layer selection, etc.
|
|
12858
13019
|
function onUpdate(e) {
|
|
13020
|
+
var updated = model.getActiveLayer();
|
|
12859
13021
|
var prevLyr = _activeLyr || null;
|
|
12860
13022
|
var fullBounds;
|
|
12861
13023
|
var needReset;
|
|
@@ -12870,8 +13032,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12870
13032
|
|
|
12871
13033
|
// reset simplification after projection (thresholds have changed)
|
|
12872
13034
|
// TODO: preserve simplification pct (need to record pct before change)
|
|
12873
|
-
if (e.flags.proj &&
|
|
12874
|
-
|
|
13035
|
+
if (e.flags.proj && updated.dataset.arcs) {
|
|
13036
|
+
updated.dataset.arcs.setRetainedPct(1);
|
|
12875
13037
|
}
|
|
12876
13038
|
}
|
|
12877
13039
|
|
|
@@ -12884,9 +13046,9 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12884
13046
|
return;
|
|
12885
13047
|
}
|
|
12886
13048
|
|
|
12887
|
-
if (
|
|
12888
|
-
_activeLyr =
|
|
12889
|
-
initActiveLayer(
|
|
13049
|
+
if (updated.layer) {
|
|
13050
|
+
_activeLyr = updated.layer;
|
|
13051
|
+
initActiveLayer();
|
|
12890
13052
|
} else {
|
|
12891
13053
|
_activeLyr = null;
|
|
12892
13054
|
}
|
|
@@ -13073,9 +13235,10 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13073
13235
|
});
|
|
13074
13236
|
}
|
|
13075
13237
|
|
|
13076
|
-
function initActiveLayer(
|
|
13077
|
-
|
|
13078
|
-
|
|
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());
|
|
13079
13242
|
}
|
|
13080
13243
|
|
|
13081
13244
|
function getDrawableFurnitureLayers(layers) {
|
|
@@ -13117,7 +13280,14 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13117
13280
|
});
|
|
13118
13281
|
}
|
|
13119
13282
|
|
|
13120
|
-
|
|
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]++;
|
|
13121
13291
|
// This seems to smooth out navigation and keep overlay and basemap in sync.
|
|
13122
13292
|
requestAnimationFrame(function() {drawLayers2(action);});
|
|
13123
13293
|
}
|
|
@@ -13125,8 +13295,12 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13125
13295
|
// action:
|
|
13126
13296
|
// 'nav' map was panned/zoomed -- only map extent has changed
|
|
13127
13297
|
// 'hover' highlight has changed -- only refresh overlay
|
|
13128
|
-
//
|
|
13298
|
+
// 'redraw' anything could have changed
|
|
13129
13299
|
function drawLayers2(action) {
|
|
13300
|
+
if (--skipCounts[action] > 0) {
|
|
13301
|
+
// skip redraw if more draws are queued up
|
|
13302
|
+
return;
|
|
13303
|
+
}
|
|
13130
13304
|
// sometimes styles need to be regenerated with 'hover' action (when?)
|
|
13131
13305
|
var layersMayHaveChanged = action != 'nav'; // !action;
|
|
13132
13306
|
var fullBounds;
|
|
@@ -13458,8 +13632,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13458
13632
|
}
|
|
13459
13633
|
|
|
13460
13634
|
function refresh() {
|
|
13461
|
-
var
|
|
13462
|
-
|
|
13635
|
+
var off = !enabled() || !map || loading || !activeStyle ||
|
|
13636
|
+
!gui.map.getDisplayCRS(); // may be slow if getting bounds of many shapes
|
|
13463
13637
|
fadeBtn.active(!off);
|
|
13464
13638
|
clearBtn.active(!off);
|
|
13465
13639
|
if (off) {
|
|
@@ -13505,10 +13679,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13505
13679
|
gui.contextMenu = new ContextMenu();
|
|
13506
13680
|
gui.undo = new Undo(gui);
|
|
13507
13681
|
gui.map = new MshpMap(gui);
|
|
13508
|
-
|
|
13509
|
-
new SessionSnapshots(gui);
|
|
13510
|
-
}
|
|
13511
|
-
gui.interaction = new InteractionMode(gui);
|
|
13682
|
+
|
|
13512
13683
|
gui.state = {};
|
|
13513
13684
|
|
|
13514
13685
|
var msgCount = 0;
|
|
@@ -13517,6 +13688,11 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13517
13688
|
initModeRules(gui);
|
|
13518
13689
|
gui.map.init();
|
|
13519
13690
|
|
|
13691
|
+
if (opts.saveControl) {
|
|
13692
|
+
new SessionSnapshots(gui);
|
|
13693
|
+
}
|
|
13694
|
+
gui.interaction = new InteractionMode(gui);
|
|
13695
|
+
|
|
13520
13696
|
gui.showProgressMessage = function(msg) {
|
|
13521
13697
|
if (!gui.progressMessage) {
|
|
13522
13698
|
gui.progressMessage = El('div').addClass('progress-message')
|
|
@@ -13585,6 +13761,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13585
13761
|
|
|
13586
13762
|
// This is the entry point for bundling mapshaper's web UI
|
|
13587
13763
|
|
|
13764
|
+
|
|
13588
13765
|
onload(function() {
|
|
13589
13766
|
if (!GUI.browserIsSupported()) {
|
|
13590
13767
|
El("#mshp-not-supported").show();
|