mapshaper 0.6.106 → 0.6.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/mapshaper.js +8 -11
- package/package.json +1 -1
- package/www/elements.css +2 -1
- package/www/index.html +20 -15
- package/www/mapshaper-gui.js +134 -102
- package/www/mapshaper.js +8 -11
- package/www/page.css +15 -11
package/README.md
CHANGED
|
@@ -80,6 +80,14 @@ npm run build # bundle source code files
|
|
|
80
80
|
npm link # (optional) add global symlinks so scripts are available systemwide
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
## Using mapshaper with Bun
|
|
84
|
+
|
|
85
|
+
Mapshaper's command line tools can be run with [Bun](https://bun.sh/) as an alternative to Node.js. The simplest option is to use `bunx`, like this:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
bunx mapshaper [commands]
|
|
89
|
+
```
|
|
90
|
+
|
|
83
91
|
## Building and testing
|
|
84
92
|
|
|
85
93
|
From the project directory, run `npm run build` to build both the cli and web UI modules.
|
package/mapshaper.js
CHANGED
|
@@ -3927,7 +3927,10 @@
|
|
|
3927
3927
|
|
|
3928
3928
|
function getValueType(val) {
|
|
3929
3929
|
var type = null;
|
|
3930
|
-
if (
|
|
3930
|
+
if (val === null || val === undefined) {
|
|
3931
|
+
// optimization, when scanning columns containing mostly null values
|
|
3932
|
+
type = null;
|
|
3933
|
+
} else if (utils.isString(val)) {
|
|
3931
3934
|
type = 'string';
|
|
3932
3935
|
} else if (utils.isNumber(val)) {
|
|
3933
3936
|
type = 'number';
|
|
@@ -13542,14 +13545,8 @@
|
|
|
13542
13545
|
function getBoundsPrecisionForDisplay(bbox) {
|
|
13543
13546
|
var w = Math.abs(bbox[2] - bbox[0]),
|
|
13544
13547
|
h = Math.abs(bbox[3] - bbox[1]),
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
range = Math.max(w, h) + 1e-8,
|
|
13548
|
-
digits = 0;
|
|
13549
|
-
while (range < 2000 && digits < 1) {
|
|
13550
|
-
range *= 10;
|
|
13551
|
-
digits++;
|
|
13552
|
-
}
|
|
13548
|
+
range = (w + h) / 2 + 1e-8,
|
|
13549
|
+
digits = Math.max(0, Math.round(3 - Math.log10(range)));
|
|
13553
13550
|
return digits;
|
|
13554
13551
|
}
|
|
13555
13552
|
|
|
@@ -46041,7 +46038,7 @@ ${svg}
|
|
|
46041
46038
|
});
|
|
46042
46039
|
}
|
|
46043
46040
|
|
|
46044
|
-
var version = "0.6.
|
|
46041
|
+
var version = "0.6.108";
|
|
46045
46042
|
|
|
46046
46043
|
// Parse command line args into commands and run them
|
|
46047
46044
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -46095,7 +46092,7 @@ ${svg}
|
|
|
46095
46092
|
}
|
|
46096
46093
|
if (!loggingEnabled()) argv += ' -quiet'; // kludge to pass logging setting to subprocess
|
|
46097
46094
|
var mb = Math.round(gb * 1000);
|
|
46098
|
-
var command = [process.execPath
|
|
46095
|
+
var command = [`"${process.execPath}"`, '--max-old-space-size=' + mb, `"${mapshaperScript}"`, argv].join(' ');
|
|
46099
46096
|
var child = require$1('child_process').exec(command, {}, function(err, stdout, stderr) {
|
|
46100
46097
|
opts.callback(err);
|
|
46101
46098
|
});
|
package/package.json
CHANGED
package/www/elements.css
CHANGED
package/www/index.html
CHANGED
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
<input type="text" value="label" class="clicktext" />
|
|
77
77
|
</div></div>
|
|
78
78
|
<div id="mode-buttons" class="page-header-buttons">
|
|
79
|
-
<span class="console-btn header-btn btn">Console</span><span class="
|
|
79
|
+
<span class="console-btn header-btn btn">Console</span><span class="display-btn header-btn btn">Display</span><span class="separator"></span><span class="separator"></span><span class="simplify-btn header-btn btn">Simplify</span><span class="separator"></span><span class="export-btn header-btn btn">Export</span>
|
|
80
80
|
</div>
|
|
81
81
|
<div id="splash-buttons" class="page-header-buttons">
|
|
82
82
|
<a href="https://github.com/mbloch/mapshaper/wiki"><span id="wiki-btn" class="header-btn btn">Wiki</span></a><span class="separator"></span><a href="https://github.com/mbloch/mapshaper"><span id="github-btn" class="header-btn btn">GitHub</span></a>
|
|
@@ -174,23 +174,30 @@ precision=0.001. Click to see all options.</div></div></div></a>
|
|
|
174
174
|
<div><span id="save-preference" style="display: none;"><input type="checkbox"/>choose output directory</span></div>
|
|
175
175
|
<div><span id="save-to-clipboard" style="display: inline-block;"><input type="checkbox"/>save to clipboard</span></div>
|
|
176
176
|
</div>
|
|
177
|
-
<div id="export-btn" class="btn dialog-btn" style="margin-top:
|
|
177
|
+
<div id="export-btn" class="btn dialog-btn" style="margin-top: 5px;">Export</div>
|
|
178
178
|
|
|
179
179
|
</div>
|
|
180
180
|
</div>
|
|
181
181
|
|
|
182
|
-
<div class="
|
|
182
|
+
<div class="display-options main-area popup-dialog">
|
|
183
183
|
<div class="info-box">
|
|
184
184
|
<div class="close2-btn"></div>
|
|
185
|
-
<h3>
|
|
186
|
-
|
|
187
|
-
<
|
|
188
|
-
<div class="
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
<
|
|
192
|
-
<
|
|
193
|
-
|
|
185
|
+
<h3>Display options</h3>
|
|
186
|
+
|
|
187
|
+
<div class=""><label for="intersections-opt"><input type="checkbox" id="intersections-opt" class="checkbox intersections-opt"/>detect line intersections</label></div>
|
|
188
|
+
<div class=""><label for="ghost-opt"><input type="checkbox" id="ghost-opt" class="checkbox ghost-opt"/>show reference lines</label></div>
|
|
189
|
+
|
|
190
|
+
<div class="basemap-opts">
|
|
191
|
+
<h4>Basemaps</h4>
|
|
192
|
+
<p class="basemap-warning"></p>
|
|
193
|
+
<div class="basemap-styles basemap-buttons"></div>
|
|
194
|
+
<p class="basemap-note"></p>
|
|
195
|
+
<div>
|
|
196
|
+
<!-- <div class="close-btn btn dialog-btn">Close</div> -->
|
|
197
|
+
<div class="clear-btn btn dialog-btn disabled">Clear</div>
|
|
198
|
+
<div class="fade-btn btn dialog-btn disabled">Fade</div>
|
|
199
|
+
<!-- <div class="hide-btn btn dialog-btn disabled">Hide</div> -->
|
|
200
|
+
</div>
|
|
194
201
|
</div>
|
|
195
202
|
</div>
|
|
196
203
|
</div>
|
|
@@ -237,7 +244,6 @@ of more acute angles are
|
|
|
237
244
|
preferentially removed, for
|
|
238
245
|
a smoother appearance.</div></div></div></div>
|
|
239
246
|
|
|
240
|
-
|
|
241
247
|
</div> <!-- option menu -->
|
|
242
248
|
|
|
243
249
|
<div>
|
|
@@ -295,8 +301,7 @@ encoding=big5</span>. Click to see all options.</div></div></div></div>
|
|
|
295
301
|
</div>
|
|
296
302
|
<div class="mshp-main-map main-area map-area">
|
|
297
303
|
<div class="intersection-display">
|
|
298
|
-
<span class="intersection-
|
|
299
|
-
<img class="close-btn" draggable="false" src="images/close.png">
|
|
304
|
+
<span class="intersection-count">0 line intersections</span>
|
|
300
305
|
<div class="repair-btn text-btn colored-text">Repair</div>
|
|
301
306
|
</div>
|
|
302
307
|
<div class="basemap-overlay-buttons basemap-buttons"></div>
|
package/www/mapshaper-gui.js
CHANGED
|
@@ -1162,7 +1162,7 @@
|
|
|
1162
1162
|
var topTier = 10000; // short-circuit counting here
|
|
1163
1163
|
var count = 0;
|
|
1164
1164
|
layers = layers.filter(function(lyr) {
|
|
1165
|
-
return lyr.geometry_type == 'point' && lyr.gui.style
|
|
1165
|
+
return lyr.geometry_type == 'point' && lyr.gui.style?.dotSize > 0;
|
|
1166
1166
|
});
|
|
1167
1167
|
layers.forEach(function(lyr) {
|
|
1168
1168
|
count += countPoints(lyr.gui.displayLayer.shapes, topTier, bbox);
|
|
@@ -3042,7 +3042,7 @@
|
|
|
3042
3042
|
displayLayer: null,
|
|
3043
3043
|
source: {dataset},
|
|
3044
3044
|
bounds: null,
|
|
3045
|
-
style: null,
|
|
3045
|
+
// style: null, // protect old style in projectLayerForDisplay()
|
|
3046
3046
|
dynamic_crs: null,
|
|
3047
3047
|
invertPoint: null,
|
|
3048
3048
|
projectPoint: null
|
|
@@ -4209,18 +4209,20 @@
|
|
|
4209
4209
|
model = gui.model,
|
|
4210
4210
|
el = gui.container.findChild(".intersection-display"),
|
|
4211
4211
|
readout = el.findChild(".intersection-count"),
|
|
4212
|
-
checkBtn = el.findChild(".intersection-check"),
|
|
4213
4212
|
repairBtn = el.findChild(".repair-btn"),
|
|
4213
|
+
optBox = gui.container.findChild('.intersections-opt'),
|
|
4214
4214
|
_simplifiedXX, // saved simplified intersections, for repair
|
|
4215
|
-
_unsimplifiedXX
|
|
4216
|
-
_disabled = false,
|
|
4217
|
-
_on = false;
|
|
4218
|
-
|
|
4219
|
-
el.findChild('.close-btn').on('click', dismissForever);
|
|
4215
|
+
_unsimplifiedXX; // saved unsimplified intersection data, for performance
|
|
4220
4216
|
|
|
4221
4217
|
gui.on('simplify_drag_start', function() {
|
|
4222
|
-
|
|
4223
|
-
|
|
4218
|
+
hide();
|
|
4219
|
+
});
|
|
4220
|
+
|
|
4221
|
+
gui.on('mode', updateRepairBtn);
|
|
4222
|
+
|
|
4223
|
+
gui.on('display_option_change', function(e) {
|
|
4224
|
+
if (e.option == 'intersectionsOn') {
|
|
4225
|
+
updateAsync();
|
|
4224
4226
|
}
|
|
4225
4227
|
});
|
|
4226
4228
|
|
|
@@ -4228,12 +4230,6 @@
|
|
|
4228
4230
|
updateSync('simplify_drag_end');
|
|
4229
4231
|
});
|
|
4230
4232
|
|
|
4231
|
-
checkBtn.on('click', function() {
|
|
4232
|
-
checkBtn.hide();
|
|
4233
|
-
_on = true;
|
|
4234
|
-
updateSync();
|
|
4235
|
-
});
|
|
4236
|
-
|
|
4237
4233
|
repairBtn.on('click', function() {
|
|
4238
4234
|
var e = model.getActiveLayer();
|
|
4239
4235
|
if (!_simplifiedXX || !e.dataset.arcs) return;
|
|
@@ -4245,59 +4241,46 @@
|
|
|
4245
4241
|
});
|
|
4246
4242
|
|
|
4247
4243
|
model.on('update', function(e) {
|
|
4248
|
-
if (!intersectionsAreOn()) {
|
|
4249
|
-
reset(); // need this?
|
|
4250
|
-
return;
|
|
4251
|
-
}
|
|
4252
4244
|
var needRefresh = e.flags.simplify_method || e.flags.simplify ||
|
|
4253
|
-
e.flags.repair || e.flags.clean;
|
|
4254
|
-
if (
|
|
4245
|
+
e.flags.repair || e.flags.clean || e.flags.select || intersectionsMayHaveChanged(e.flags);
|
|
4246
|
+
if (!intersectionsAreOn()) {
|
|
4247
|
+
reset();
|
|
4248
|
+
} else if (needRefresh) {
|
|
4255
4249
|
updateAsync();
|
|
4256
4250
|
} else if (e.flags.simplify_amount) {
|
|
4257
4251
|
// slider is being dragged - hide readout and dots, retain data
|
|
4258
4252
|
hide();
|
|
4259
|
-
} else if (intersectionsMayHaveChanged(e.flags)) {
|
|
4260
|
-
// intersections may have changed -- reset the display
|
|
4261
|
-
reset();
|
|
4262
4253
|
} else {
|
|
4263
4254
|
// keep displaying the current intersections
|
|
4264
4255
|
}
|
|
4265
4256
|
});
|
|
4266
4257
|
|
|
4258
|
+
function updateRepairBtn() {
|
|
4259
|
+
if (intersectionsAreOn() && gui.getMode() == 'simplify' &&
|
|
4260
|
+
_simplifiedXX?.length > 0) {
|
|
4261
|
+
repairBtn.show();
|
|
4262
|
+
} else {
|
|
4263
|
+
repairBtn.hide();
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
4266
|
+
|
|
4267
4267
|
function intersectionsAreOn() {
|
|
4268
|
-
|
|
4268
|
+
var e = model.getActiveLayer();
|
|
4269
|
+
return !!(gui.display.getOptions().intersectionsOn &&
|
|
4270
|
+
e && e.dataset.arcs && internal.layerHasPaths(e.layer));
|
|
4269
4271
|
}
|
|
4270
4272
|
|
|
4271
|
-
function
|
|
4273
|
+
function reset() {
|
|
4272
4274
|
hide();
|
|
4273
|
-
_on = false;
|
|
4274
4275
|
_simplifiedXX = null;
|
|
4275
4276
|
_unsimplifiedXX = null;
|
|
4276
4277
|
}
|
|
4277
4278
|
|
|
4278
|
-
function reset() {
|
|
4279
|
-
turnOff();
|
|
4280
|
-
if (_disabled) {
|
|
4281
|
-
return;
|
|
4282
|
-
}
|
|
4283
|
-
var e = model.getActiveLayer();
|
|
4284
|
-
if (!e) return;
|
|
4285
|
-
if (internal.layerHasPaths(e.layer)) {
|
|
4286
|
-
el.show();
|
|
4287
|
-
checkBtn.show();
|
|
4288
|
-
readout.hide();
|
|
4289
|
-
repairBtn.hide();
|
|
4290
|
-
}
|
|
4291
|
-
}
|
|
4292
|
-
|
|
4293
|
-
function dismissForever() {
|
|
4294
|
-
_disabled = true;
|
|
4295
|
-
turnOff();
|
|
4296
|
-
}
|
|
4297
|
-
|
|
4298
4279
|
function hide() {
|
|
4299
4280
|
map.setIntersectionLayer(null);
|
|
4300
4281
|
el.hide();
|
|
4282
|
+
repairBtn.hide();
|
|
4283
|
+
readout.hide();
|
|
4301
4284
|
}
|
|
4302
4285
|
|
|
4303
4286
|
// Update intersection display, after a short delay so map can redraw after previous
|
|
@@ -4307,16 +4290,16 @@
|
|
|
4307
4290
|
}
|
|
4308
4291
|
|
|
4309
4292
|
function updateSync(action) {
|
|
4310
|
-
if (!intersectionsAreOn()) return;
|
|
4311
4293
|
var e = model.getActiveLayer();
|
|
4312
4294
|
var arcs = e.dataset && e.dataset.arcs;
|
|
4295
|
+
if (!intersectionsAreOn() || !arcs || !internal.layerHasPaths(e.layer)) {
|
|
4296
|
+
reset();
|
|
4297
|
+
return;
|
|
4298
|
+
}
|
|
4313
4299
|
var intersectionOpts = {
|
|
4314
4300
|
unique: true,
|
|
4315
4301
|
tolerance: 0
|
|
4316
4302
|
};
|
|
4317
|
-
if (!arcs || !internal.layerHasPaths(e.layer)) {
|
|
4318
|
-
return;
|
|
4319
|
-
}
|
|
4320
4303
|
if (arcs.getRetainedInterval() > 0) {
|
|
4321
4304
|
// simplification
|
|
4322
4305
|
_simplifiedXX = internal.findSegmentIntersections(arcs, intersectionOpts);
|
|
@@ -4336,7 +4319,6 @@
|
|
|
4336
4319
|
var pointLyr, count = 0, html;
|
|
4337
4320
|
el.show();
|
|
4338
4321
|
readout.show();
|
|
4339
|
-
checkBtn.hide();
|
|
4340
4322
|
if (xx.length > 0) {
|
|
4341
4323
|
pointLyr = internal.getIntersectionLayer(xx, lyr, arcs);
|
|
4342
4324
|
count = internal.countPointsInLayer(pointLyr);
|
|
@@ -4349,12 +4331,7 @@
|
|
|
4349
4331
|
html = utils$1.format('<span class="icon"></span>%s line intersection%s', count, utils$1.pluralSuffix(count));
|
|
4350
4332
|
}
|
|
4351
4333
|
readout.html(html);
|
|
4352
|
-
|
|
4353
|
-
if (_simplifiedXX && count > 0) {
|
|
4354
|
-
repairBtn.show();
|
|
4355
|
-
} else {
|
|
4356
|
-
repairBtn.hide();
|
|
4357
|
-
}
|
|
4334
|
+
updateRepairBtn();
|
|
4358
4335
|
}
|
|
4359
4336
|
}
|
|
4360
4337
|
|
|
@@ -10093,7 +10070,7 @@
|
|
|
10093
10070
|
};
|
|
10094
10071
|
|
|
10095
10072
|
function getOverlayLayers(activeLyr, hitData, styleOpts) {
|
|
10096
|
-
if (activeLyr
|
|
10073
|
+
if (activeLyr?.hidden || !activeLyr?.gui?.style) return [];
|
|
10097
10074
|
var displayLyr = activeLyr.gui.displayLayer;
|
|
10098
10075
|
var layers, lyr, outlineStyle, ids;
|
|
10099
10076
|
if (styleOpts.interactionMode == 'vertices') {
|
|
@@ -11282,8 +11259,8 @@
|
|
|
11282
11259
|
dotSize: 1
|
|
11283
11260
|
},
|
|
11284
11261
|
intersectionStyle = {
|
|
11285
|
-
dotColor: "#
|
|
11286
|
-
dotSize: 1
|
|
11262
|
+
dotColor: "#FF421D",
|
|
11263
|
+
dotSize: 1.3
|
|
11287
11264
|
};
|
|
11288
11265
|
|
|
11289
11266
|
function getIntersectionStyle(lyr, opts) {
|
|
@@ -11316,6 +11293,11 @@
|
|
|
11316
11293
|
} else {
|
|
11317
11294
|
style = copyBaseStyle(activeStyle);
|
|
11318
11295
|
}
|
|
11296
|
+
// kludge: no ghosted lines if not enabled
|
|
11297
|
+
if (style.strokeColors && !opts.ghostingOn) {
|
|
11298
|
+
style.strokeColors = [null, style.strokeColors[1]];
|
|
11299
|
+
}
|
|
11300
|
+
|
|
11319
11301
|
return style;
|
|
11320
11302
|
}
|
|
11321
11303
|
|
|
@@ -11780,22 +11762,23 @@
|
|
|
11780
11762
|
var arcs;
|
|
11781
11763
|
var style = lyr.gui.style;
|
|
11782
11764
|
var arcCounts = lyr.gui.arcCounts;
|
|
11783
|
-
var
|
|
11784
|
-
|
|
11765
|
+
var fgStyle = {strokeWidth: style.strokeWidth, strokeColor: style.strokeColors[1]},
|
|
11766
|
+
bgStyle = {strokeWidth: style.strokeWidth, strokeColor: style.strokeColors[0]};
|
|
11785
11767
|
var filter;
|
|
11768
|
+
|
|
11786
11769
|
if (internal.layerHasPaths(lyr.gui.displayLayer)) {
|
|
11787
11770
|
if (!arcCounts) {
|
|
11788
11771
|
arcCounts = lyr.gui.arcCounts = new Uint8Array(lyr.gui.displayArcs.size());
|
|
11789
11772
|
internal.countArcsInShapes(lyr.gui.displayLayer.shapes, arcCounts);
|
|
11790
11773
|
}
|
|
11791
11774
|
arcs = getArcsForRendering(lyr, ext);
|
|
11792
|
-
if (
|
|
11775
|
+
if (bgStyle.strokeColor) {
|
|
11793
11776
|
filter = getArcFilter(arcs, ext, false, arcCounts);
|
|
11794
|
-
canv.drawArcs(arcs,
|
|
11777
|
+
canv.drawArcs(arcs, bgStyle, filter);
|
|
11795
11778
|
}
|
|
11796
|
-
if (
|
|
11779
|
+
if (fgStyle.strokeColor && lyr.gui.displayLayer.geometry_type != 'point') {
|
|
11797
11780
|
filter = getArcFilter(arcs, ext, true, arcCounts);
|
|
11798
|
-
canv.drawArcs(arcs,
|
|
11781
|
+
canv.drawArcs(arcs, fgStyle, filter);
|
|
11799
11782
|
}
|
|
11800
11783
|
}
|
|
11801
11784
|
if (lyr.gui.displayLayer.geometry_type == 'point') {
|
|
@@ -12577,7 +12560,7 @@
|
|
|
12577
12560
|
var self = new EventDispatcher();
|
|
12578
12561
|
var box = new HighlightBox(gui, {name: 'box-tool', persistent: true, handles: true, draggable: true});
|
|
12579
12562
|
var popup = gui.container.findChild('.box-tool-options');
|
|
12580
|
-
var coords = popup.findChild('.box-coords');
|
|
12563
|
+
var coords = popup.findChild('.box-coords').hide();
|
|
12581
12564
|
var _on = false;
|
|
12582
12565
|
var instructionsShown = false;
|
|
12583
12566
|
var alert;
|
|
@@ -12958,7 +12941,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12958
12941
|
clearAllDisplayArcs();
|
|
12959
12942
|
|
|
12960
12943
|
// Reproject all visible map layers
|
|
12961
|
-
getContentLayers().forEach(function(lyr) {
|
|
12944
|
+
getContentLayers().concat(_intersectionLyr || []).forEach(function(lyr) {
|
|
12962
12945
|
projectLayerForDisplay(lyr, newCRS);
|
|
12963
12946
|
});
|
|
12964
12947
|
|
|
@@ -13001,7 +12984,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13001
12984
|
darkMode: !!gui.state.dark_basemap,
|
|
13002
12985
|
outlineMode: mode == 'vertices',
|
|
13003
12986
|
interactionMode: mode
|
|
13004
|
-
}, opts);
|
|
12987
|
+
}, opts, gui.display.getOptions()); // intersectionsOn, ghostingOn
|
|
13005
12988
|
}
|
|
13006
12989
|
|
|
13007
12990
|
// Refresh map display in response to data changes, layer selection, etc.
|
|
@@ -13220,14 +13203,13 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13220
13203
|
// regenerating active style everytime, to support style change when
|
|
13221
13204
|
// switching between outline and preview modes.
|
|
13222
13205
|
style = getActiveLayerStyle(mapLayer.gui.displayLayer, getGlobalStyleOptions());
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
}
|
|
13206
|
+
// changed: ghosting is set in gui-layer-styler.mjs
|
|
13207
|
+
// if (style.type != 'styled' && layers.length > 1 && style.strokeColors) {
|
|
13208
|
+
// // kludge to hide ghosted layers when reference layers are present
|
|
13209
|
+
// style = utils.defaults({
|
|
13210
|
+
// strokeColors: [null, style.strokeColors[1]]
|
|
13211
|
+
// }, style);
|
|
13212
|
+
// }
|
|
13231
13213
|
} else {
|
|
13232
13214
|
if (mapLayer == _activeLyr) {
|
|
13233
13215
|
console.error("Error: shared map layer");
|
|
@@ -13363,14 +13345,12 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13363
13345
|
}
|
|
13364
13346
|
|
|
13365
13347
|
function Basemap(gui) {
|
|
13366
|
-
var menu = gui.container.findChild('.
|
|
13348
|
+
var menu = gui.container.findChild('.display-options');
|
|
13367
13349
|
var fadeBtn = new SimpleButton(menu.findChild('.fade-btn'));
|
|
13368
|
-
var closeBtn = new SimpleButton(menu.findChild('.close2-btn'));
|
|
13369
13350
|
var clearBtn = new SimpleButton(menu.findChild('.clear-btn'));
|
|
13370
13351
|
var menuButtons = menu.findChild('.basemap-styles');
|
|
13371
13352
|
var overlayButtons = gui.container.findChild('.basemap-overlay-buttons');
|
|
13372
13353
|
var container = gui.container.findChild('.basemap-container');
|
|
13373
|
-
var basemapBtn = gui.container.findChild('.basemap-btn');
|
|
13374
13354
|
var basemapNote = gui.container.findChild('.basemap-note');
|
|
13375
13355
|
var basemapWarning = gui.container.findChild('.basemap-warning');
|
|
13376
13356
|
var mapEl = gui.container.findChild('.basemap');
|
|
@@ -13385,22 +13365,25 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13385
13365
|
// TODO: check page URL for compatibility with mapbox key
|
|
13386
13366
|
init();
|
|
13387
13367
|
} else {
|
|
13388
|
-
|
|
13368
|
+
menu.findChild('.basemap-opts').hide();
|
|
13389
13369
|
}
|
|
13390
13370
|
|
|
13391
13371
|
function init() {
|
|
13392
|
-
gui.
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13372
|
+
gui.on('mode', function(e) {
|
|
13373
|
+
if (e.prev == 'display_options') {
|
|
13374
|
+
basemapWarning.hide();
|
|
13375
|
+
basemapNote.hide();
|
|
13376
|
+
}
|
|
13377
|
+
if (e.name == 'display_options') {
|
|
13378
|
+
onUpdate();
|
|
13379
|
+
}
|
|
13397
13380
|
});
|
|
13398
13381
|
|
|
13399
13382
|
clearBtn.on('click', function() {
|
|
13400
13383
|
if (activeStyle) {
|
|
13401
13384
|
turnOffBasemap();
|
|
13402
13385
|
updateButtons();
|
|
13403
|
-
closeMenu();
|
|
13386
|
+
// closeMenu();
|
|
13404
13387
|
}
|
|
13405
13388
|
});
|
|
13406
13389
|
|
|
@@ -13441,7 +13424,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13441
13424
|
showBasemap(style);
|
|
13442
13425
|
}
|
|
13443
13426
|
updateButtons();
|
|
13444
|
-
closeMenu();
|
|
13427
|
+
// closeMenu();
|
|
13445
13428
|
}
|
|
13446
13429
|
});
|
|
13447
13430
|
}
|
|
@@ -13481,11 +13464,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13481
13464
|
});
|
|
13482
13465
|
}
|
|
13483
13466
|
|
|
13484
|
-
function turnOn() {
|
|
13485
|
-
onUpdate();
|
|
13486
|
-
menu.show();
|
|
13487
|
-
}
|
|
13488
|
-
|
|
13489
13467
|
function onUpdate() {
|
|
13490
13468
|
var activeLyr = gui.model.getActiveLayer(); // may be null
|
|
13491
13469
|
var info = getDatasetCrsInfo(activeLyr?.dataset); // defaults to wgs84
|
|
@@ -13507,19 +13485,13 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13507
13485
|
activeStyle = null;
|
|
13508
13486
|
updateButtons();
|
|
13509
13487
|
} else {
|
|
13510
|
-
note = `
|
|
13488
|
+
note = `Note: basemaps use the Mercator projection.`;
|
|
13511
13489
|
basemapNote.text(note).show();
|
|
13512
13490
|
overlayButtons.show();
|
|
13513
13491
|
overlayButtons.removeClass('disabled');
|
|
13514
13492
|
}
|
|
13515
13493
|
}
|
|
13516
13494
|
|
|
13517
|
-
function turnOff() {
|
|
13518
|
-
basemapWarning.hide();
|
|
13519
|
-
basemapNote.hide();
|
|
13520
|
-
menu.hide();
|
|
13521
|
-
}
|
|
13522
|
-
|
|
13523
13495
|
function enabled() {
|
|
13524
13496
|
return !!(mapEl && params);
|
|
13525
13497
|
}
|
|
@@ -13635,6 +13607,64 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13635
13607
|
return {refresh, show: onUpdate};
|
|
13636
13608
|
}
|
|
13637
13609
|
|
|
13610
|
+
function DisplayOptions(gui) {
|
|
13611
|
+
var menuBtn = gui.container.findChild('.display-btn');
|
|
13612
|
+
var menu = gui.container.findChild('.display-options');
|
|
13613
|
+
var closeBtn = new SimpleButton(menu.findChild('.close2-btn'));
|
|
13614
|
+
var xxBox = menu.findChild('.intersections-opt');
|
|
13615
|
+
var ghostBox = menu.findChild('.ghost-opt');
|
|
13616
|
+
|
|
13617
|
+
var savedOpts = GUI.getSavedValue('display_options') || {};
|
|
13618
|
+
xxBox.node().checked = savedOpts.intersectionsOn;
|
|
13619
|
+
ghostBox.node().checked = savedOpts.ghostingOn;
|
|
13620
|
+
|
|
13621
|
+
|
|
13622
|
+
gui.addMode('display_options', turnOn, turnOff, menuBtn);
|
|
13623
|
+
|
|
13624
|
+
closeBtn.on('click', function() {
|
|
13625
|
+
gui.clearMode();
|
|
13626
|
+
turnOff();
|
|
13627
|
+
});
|
|
13628
|
+
|
|
13629
|
+
gui.on('display_option_change', function() {
|
|
13630
|
+
GUI.setSavedValue('display_options', getOptions());
|
|
13631
|
+
});
|
|
13632
|
+
|
|
13633
|
+
xxBox.on('change', function() {
|
|
13634
|
+
gui.dispatchEvent('display_option_change', {
|
|
13635
|
+
option: 'intersectionsOn',
|
|
13636
|
+
value: getOptions().intersectionsOn
|
|
13637
|
+
});
|
|
13638
|
+
});
|
|
13639
|
+
|
|
13640
|
+
ghostBox.on('change', function() {
|
|
13641
|
+
gui.dispatchEvent('display_option_change', {
|
|
13642
|
+
option: 'ghostingOn',
|
|
13643
|
+
value: getOptions().ghostingOn
|
|
13644
|
+
});
|
|
13645
|
+
gui.dispatchEvent('map-needs-refresh');
|
|
13646
|
+
});
|
|
13647
|
+
|
|
13648
|
+
function getOptions() {
|
|
13649
|
+
return {
|
|
13650
|
+
intersectionsOn: xxBox.node().checked,
|
|
13651
|
+
ghostingOn: ghostBox.node().checked
|
|
13652
|
+
};
|
|
13653
|
+
}
|
|
13654
|
+
|
|
13655
|
+
function turnOn() {
|
|
13656
|
+
menu.show();
|
|
13657
|
+
}
|
|
13658
|
+
|
|
13659
|
+
function turnOff() {
|
|
13660
|
+
menu.hide();
|
|
13661
|
+
}
|
|
13662
|
+
|
|
13663
|
+
return {
|
|
13664
|
+
getOptions
|
|
13665
|
+
};
|
|
13666
|
+
}
|
|
13667
|
+
|
|
13638
13668
|
function GuiInstance(container, opts) {
|
|
13639
13669
|
var gui = new ModeSwitcher();
|
|
13640
13670
|
opts = utils$1.extend({
|
|
@@ -13652,12 +13682,14 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
13652
13682
|
gui.model = new Model(gui);
|
|
13653
13683
|
gui.keyboard = new KeyboardEvents(gui);
|
|
13654
13684
|
gui.buttons = new SidebarButtons(gui);
|
|
13685
|
+
gui.display = new DisplayOptions(gui);
|
|
13655
13686
|
gui.basemap = new Basemap(gui);
|
|
13656
13687
|
gui.session = new SessionHistory(gui);
|
|
13657
13688
|
gui.contextMenu = new ContextMenu();
|
|
13658
13689
|
gui.undo = new Undo(gui);
|
|
13659
13690
|
gui.map = new MshpMap(gui);
|
|
13660
13691
|
|
|
13692
|
+
|
|
13661
13693
|
gui.state = {};
|
|
13662
13694
|
|
|
13663
13695
|
var msgCount = 0;
|
package/www/mapshaper.js
CHANGED
|
@@ -3927,7 +3927,10 @@
|
|
|
3927
3927
|
|
|
3928
3928
|
function getValueType(val) {
|
|
3929
3929
|
var type = null;
|
|
3930
|
-
if (
|
|
3930
|
+
if (val === null || val === undefined) {
|
|
3931
|
+
// optimization, when scanning columns containing mostly null values
|
|
3932
|
+
type = null;
|
|
3933
|
+
} else if (utils.isString(val)) {
|
|
3931
3934
|
type = 'string';
|
|
3932
3935
|
} else if (utils.isNumber(val)) {
|
|
3933
3936
|
type = 'number';
|
|
@@ -13542,14 +13545,8 @@
|
|
|
13542
13545
|
function getBoundsPrecisionForDisplay(bbox) {
|
|
13543
13546
|
var w = Math.abs(bbox[2] - bbox[0]),
|
|
13544
13547
|
h = Math.abs(bbox[3] - bbox[1]),
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
range = Math.max(w, h) + 1e-8,
|
|
13548
|
-
digits = 0;
|
|
13549
|
-
while (range < 2000 && digits < 1) {
|
|
13550
|
-
range *= 10;
|
|
13551
|
-
digits++;
|
|
13552
|
-
}
|
|
13548
|
+
range = (w + h) / 2 + 1e-8,
|
|
13549
|
+
digits = Math.max(0, Math.round(3 - Math.log10(range)));
|
|
13553
13550
|
return digits;
|
|
13554
13551
|
}
|
|
13555
13552
|
|
|
@@ -46041,7 +46038,7 @@ ${svg}
|
|
|
46041
46038
|
});
|
|
46042
46039
|
}
|
|
46043
46040
|
|
|
46044
|
-
var version = "0.6.
|
|
46041
|
+
var version = "0.6.108";
|
|
46045
46042
|
|
|
46046
46043
|
// Parse command line args into commands and run them
|
|
46047
46044
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
|
@@ -46095,7 +46092,7 @@ ${svg}
|
|
|
46095
46092
|
}
|
|
46096
46093
|
if (!loggingEnabled()) argv += ' -quiet'; // kludge to pass logging setting to subprocess
|
|
46097
46094
|
var mb = Math.round(gb * 1000);
|
|
46098
|
-
var command = [process.execPath
|
|
46095
|
+
var command = [`"${process.execPath}"`, '--max-old-space-size=' + mb, `"${mapshaperScript}"`, argv].join(' ');
|
|
46099
46096
|
var child = require$1('child_process').exec(command, {}, function(err, stdout, stderr) {
|
|
46100
46097
|
opts.callback(err);
|
|
46101
46098
|
});
|
package/www/page.css
CHANGED
|
@@ -325,18 +325,18 @@ div.alert-box {
|
|
|
325
325
|
/* --- Splash screen -------------- */
|
|
326
326
|
|
|
327
327
|
.import-instructions {
|
|
328
|
-
margin:
|
|
328
|
+
margin: 8px 0 0 0;
|
|
329
|
+
font-size: 15px;
|
|
329
330
|
}
|
|
330
331
|
|
|
331
332
|
.mini-drop-area {
|
|
332
333
|
border: 1.5px dashed #999;
|
|
333
|
-
max-width:
|
|
334
|
+
max-width: 260px;
|
|
334
335
|
border-radius: 9px;
|
|
335
|
-
|
|
336
|
-
line-height: 1.5;
|
|
336
|
+
line-height: 1.45;
|
|
337
337
|
padding: 9px 11px 6px 11px;
|
|
338
338
|
margin: 9px -1px 3px -1px;
|
|
339
|
-
min-height:
|
|
339
|
+
min-height: 130px;
|
|
340
340
|
background: #f8fdff;
|
|
341
341
|
}
|
|
342
342
|
|
|
@@ -503,7 +503,7 @@ div.alert-box {
|
|
|
503
503
|
text-align: left;
|
|
504
504
|
margin-top: 12px;
|
|
505
505
|
margin-right: 20px;
|
|
506
|
-
padding:
|
|
506
|
+
padding: 12px 16px 12px 18px;
|
|
507
507
|
vertical-align: top;
|
|
508
508
|
display: inline-block;
|
|
509
509
|
/* border: 1px solid #aaa; */
|
|
@@ -533,7 +533,7 @@ div.alert-box {
|
|
|
533
533
|
}
|
|
534
534
|
|
|
535
535
|
.info-box h3 {
|
|
536
|
-
font-size:
|
|
536
|
+
font-size: 20px;
|
|
537
537
|
line-height: 1.1;
|
|
538
538
|
padding: 0;
|
|
539
539
|
margin: 0 0 0.4em 0;
|
|
@@ -821,7 +821,7 @@ img.close-btn {
|
|
|
821
821
|
float: right;
|
|
822
822
|
height: 18px;
|
|
823
823
|
width: 18px;
|
|
824
|
-
|
|
824
|
+
margin-top: 1px;
|
|
825
825
|
margin-right: -3px;
|
|
826
826
|
cursor: pointer;
|
|
827
827
|
border-radius: 4px;
|
|
@@ -1101,11 +1101,11 @@ img.close-btn:hover,
|
|
|
1101
1101
|
height: 100%;
|
|
1102
1102
|
}
|
|
1103
1103
|
|
|
1104
|
-
.
|
|
1104
|
+
.display-options {
|
|
1105
1105
|
pointer-events: none;
|
|
1106
1106
|
}
|
|
1107
1107
|
|
|
1108
|
-
.
|
|
1108
|
+
.display-options .info-box {
|
|
1109
1109
|
width: min-content;
|
|
1110
1110
|
pointer-events: initial;
|
|
1111
1111
|
}
|
|
@@ -1134,6 +1134,10 @@ img.close-btn:hover,
|
|
|
1134
1134
|
color: #cc0000;
|
|
1135
1135
|
}
|
|
1136
1136
|
|
|
1137
|
+
.basemap-note {
|
|
1138
|
+
font-size: 90%;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1137
1141
|
.basemap-prompt {
|
|
1138
1142
|
width: 100%;
|
|
1139
1143
|
text-align: center;
|
|
@@ -1146,7 +1150,7 @@ img.close-btn:hover,
|
|
|
1146
1150
|
|
|
1147
1151
|
.basemap-styles > div {
|
|
1148
1152
|
display: inline-block;
|
|
1149
|
-
margin-bottom:
|
|
1153
|
+
margin-bottom: 4px;
|
|
1150
1154
|
}
|
|
1151
1155
|
|
|
1152
1156
|
.basemap-styles > div:nth-child(even) {
|