mapshaper 0.6.33 → 0.6.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mapshaper.js +45 -9
- package/package.json +1 -1
- package/www/mapshaper.js +45 -9
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.35";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -12719,7 +12719,7 @@
|
|
|
12719
12719
|
}
|
|
12720
12720
|
var sliverControl = opts.sliver_control >= 0 ? opts.sliver_control : 0; // 0 is default
|
|
12721
12721
|
var crs = getDatasetCRS(dataset);
|
|
12722
|
-
var threshold = areaArg ?
|
|
12722
|
+
var threshold = areaArg && areaArg != 'auto' ?
|
|
12723
12723
|
convertAreaParam(areaArg, crs) :
|
|
12724
12724
|
getDefaultSliverThreshold(lyr, dataset.arcs);
|
|
12725
12725
|
var filter = sliverControl > 0 ?
|
|
@@ -16653,7 +16653,8 @@
|
|
|
16653
16653
|
overlap_rule: opts.overlap_rule
|
|
16654
16654
|
};
|
|
16655
16655
|
var mosaicIndex = new MosaicIndex(lyr, nodes, mosaicOpts);
|
|
16656
|
-
|
|
16656
|
+
// gap fill doesn't work yet with overlapping shapes
|
|
16657
|
+
var fillGaps = !opts.allow_overlaps && (opts.sliver_control || opts.gap_fill_area);
|
|
16657
16658
|
var cleanupData, filterData;
|
|
16658
16659
|
if (fillGaps) {
|
|
16659
16660
|
var sliverOpts = utils.extend({sliver_control: 1}, opts);
|
|
@@ -16935,6 +16936,7 @@
|
|
|
16935
16936
|
|
|
16936
16937
|
function cleanPolygonLayerGeometry(lyr, dataset, opts) {
|
|
16937
16938
|
// clean polygons by apply the 'dissolve2' function to each feature
|
|
16939
|
+
opts = Object.assign({gap_fill_area: 'auto'}, opts);
|
|
16938
16940
|
var groups = lyr.shapes.map(function(shp, i) {
|
|
16939
16941
|
return [i];
|
|
16940
16942
|
});
|
|
@@ -18213,6 +18215,7 @@
|
|
|
18213
18215
|
dy: 'measure',
|
|
18214
18216
|
fill: 'color',
|
|
18215
18217
|
'fill-pattern': 'pattern',
|
|
18218
|
+
'fill-effect': null, // todo: validate effect names
|
|
18216
18219
|
'font-family': null,
|
|
18217
18220
|
'font-size': null,
|
|
18218
18221
|
'font-style': null,
|
|
@@ -18261,7 +18264,7 @@
|
|
|
18261
18264
|
var commonProperties = 'css,class,opacity,stroke,stroke-width,stroke-dasharray,stroke-opacity,fill-opacity,vector-effect'.split(',');
|
|
18262
18265
|
|
|
18263
18266
|
var propertiesBySymbolType = {
|
|
18264
|
-
polygon: utils.arrayToIndex(commonProperties.concat('fill', 'fill-pattern')),
|
|
18267
|
+
polygon: utils.arrayToIndex(commonProperties.concat('fill', 'fill-pattern', 'fill-effect')),
|
|
18265
18268
|
polyline: utils.arrayToIndex(commonProperties.concat('stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit')),
|
|
18266
18269
|
point: utils.arrayToIndex(commonProperties.concat('fill', 'r')),
|
|
18267
18270
|
label: utils.arrayToIndex(commonProperties.concat(
|
|
@@ -19146,6 +19149,9 @@
|
|
|
19146
19149
|
if (obj.tag == 'path' && obj.properties['fill-pattern']) {
|
|
19147
19150
|
convertFillPattern(obj.properties, defs);
|
|
19148
19151
|
}
|
|
19152
|
+
if (obj.tag == 'path' && obj.properties['fill-effect'] == 'sphere') {
|
|
19153
|
+
convertSphereEffect(obj.properties, defs);
|
|
19154
|
+
}
|
|
19149
19155
|
if (obj.tag == 'image') {
|
|
19150
19156
|
if (/\.svg/.test(obj.properties.href || '')) {
|
|
19151
19157
|
convertSvgImage(obj, defs);
|
|
@@ -19156,6 +19162,25 @@
|
|
|
19156
19162
|
}
|
|
19157
19163
|
}
|
|
19158
19164
|
|
|
19165
|
+
function convertSphereEffect(obj, defs) {
|
|
19166
|
+
var id = 'mapshaper_sphere_effect';
|
|
19167
|
+
var href = `url(#${ id })`;
|
|
19168
|
+
var svg =
|
|
19169
|
+
`<radialGradient id="${id}" cx="0.5" cy="0.5" r=".56" fx="0.4" fy="0.35">
|
|
19170
|
+
<stop offset=".35" stop-opacity="0"/>
|
|
19171
|
+
<stop offset=".65" stop-opacity="0.1" />
|
|
19172
|
+
<stop offset=".85" stop-opacity="0.45" />
|
|
19173
|
+
<stop offset=".95" stop-opacity="1" />
|
|
19174
|
+
</radialGradient>` ;
|
|
19175
|
+
if (!utils.find(defs, function(o) { return o.id == id; })) {
|
|
19176
|
+
defs.push({svg, id, href});
|
|
19177
|
+
}
|
|
19178
|
+
obj.fill = href;
|
|
19179
|
+
if ('opacity' in obj === false && 'fill-opacity' in obj === false) {
|
|
19180
|
+
obj['fill-opacity'] = 0.35;
|
|
19181
|
+
}
|
|
19182
|
+
}
|
|
19183
|
+
|
|
19159
19184
|
function convertSvgImage(obj, defs) {
|
|
19160
19185
|
// Same-origin policy prevents embedding images in the web UI
|
|
19161
19186
|
var href = obj.properties.href;
|
|
@@ -23675,7 +23700,10 @@ ${svg}
|
|
|
23675
23700
|
.option('calc', calcOpt)
|
|
23676
23701
|
.option('sum-fields', sumFieldsOpt)
|
|
23677
23702
|
.option('copy-fields', copyFieldsOpt)
|
|
23678
|
-
.option('gap-fill-area',
|
|
23703
|
+
.option('gap-fill-area', {
|
|
23704
|
+
describe: 'threshold for filling gaps, e.g. 1.5km2',
|
|
23705
|
+
type: 'area'
|
|
23706
|
+
})
|
|
23679
23707
|
.option('sliver-control', sliverControlOpt)
|
|
23680
23708
|
.option('allow-overlaps', {
|
|
23681
23709
|
describe: 'allow dissolved polygons to overlap (disables gap fill)',
|
|
@@ -23917,7 +23945,9 @@ ${svg}
|
|
|
23917
23945
|
.option('polygon', {
|
|
23918
23946
|
describe: 'create a polygon to match the outline of the graticule',
|
|
23919
23947
|
type: 'flag'
|
|
23920
|
-
})
|
|
23948
|
+
})
|
|
23949
|
+
.option('name', nameOpt);
|
|
23950
|
+
|
|
23921
23951
|
|
|
23922
23952
|
parser.command('grid')
|
|
23923
23953
|
.describe('create a grid of square or hexagonal polygons')
|
|
@@ -24447,6 +24477,9 @@ ${svg}
|
|
|
24447
24477
|
.option('fill-pattern', {
|
|
24448
24478
|
describe: 'pattern fill, ex: "hatches 2px grey 2px blue"'
|
|
24449
24479
|
})
|
|
24480
|
+
.option('fill-effect', {
|
|
24481
|
+
describe: 'use "sphere" on a circle for a 3d globe effect'
|
|
24482
|
+
})
|
|
24450
24483
|
.option('fill-opacity', {
|
|
24451
24484
|
describe: 'fill opacity'
|
|
24452
24485
|
})
|
|
@@ -37929,7 +37962,8 @@ ${svg}
|
|
|
37929
37962
|
return {
|
|
37930
37963
|
gnom: 60,
|
|
37931
37964
|
laea: 179,
|
|
37932
|
-
ortho: 89.9, //
|
|
37965
|
+
//ortho: 89.9, // projection errors betwen lat +/-35 to 55
|
|
37966
|
+
ortho: 89.85, // TODO: investigate
|
|
37933
37967
|
stere: 142,
|
|
37934
37968
|
sterea: 142,
|
|
37935
37969
|
ups: 10.5 // TODO: should be 6.5 deg at north pole
|
|
@@ -38308,7 +38342,7 @@ ${svg}
|
|
|
38308
38342
|
});
|
|
38309
38343
|
|
|
38310
38344
|
cmd.graticule = function(dataset, opts) {
|
|
38311
|
-
var name = opts.polygon
|
|
38345
|
+
var name = opts.name || opts.polygon && 'polygon' || 'graticule';
|
|
38312
38346
|
var graticule, destInfo;
|
|
38313
38347
|
if (dataset && !isLatLngDataset(dataset)) {
|
|
38314
38348
|
// project graticule to match dataset
|
|
@@ -38374,7 +38408,7 @@ ${svg}
|
|
|
38374
38408
|
//
|
|
38375
38409
|
function createGraticule(P, outlined, opts) {
|
|
38376
38410
|
var interval = opts.interval || 10;
|
|
38377
|
-
if (![5,10,15,30,45].includes(interval)) stop('Invalid interval:', interval);
|
|
38411
|
+
if (![5,10,15,20,30,45].includes(interval)) stop('Invalid interval:', interval);
|
|
38378
38412
|
P.lam0 * 180 / Math.PI;
|
|
38379
38413
|
var precision = interval > 10 ? 1 : 0.5; // degrees between each vertex
|
|
38380
38414
|
var xstep = interval;
|
|
@@ -40104,6 +40138,7 @@ ${svg}
|
|
|
40104
40138
|
};
|
|
40105
40139
|
|
|
40106
40140
|
if (opts.calc) {
|
|
40141
|
+
if (!lyr.data) initDataTable(lyr);
|
|
40107
40142
|
records2 = recombineDataRecords(lyr.data.getRecords(), mosaicIndex.getSourceIdsByTileId, mosaicShapes.length, opts);
|
|
40108
40143
|
lyr2.data = new DataTable(records2);
|
|
40109
40144
|
}
|
|
@@ -40962,6 +40997,7 @@ ${svg}
|
|
|
40962
40997
|
}
|
|
40963
40998
|
commandStr = runGlobalExpression(opts.expression, targets);
|
|
40964
40999
|
if (commandStr) {
|
|
41000
|
+
message(`command: [${commandStr}]`);
|
|
40965
41001
|
commands = parseCommands(commandStr);
|
|
40966
41002
|
runParsedCommands(commands, job, cb);
|
|
40967
41003
|
} else {
|
package/package.json
CHANGED
package/www/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.35";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -12719,7 +12719,7 @@
|
|
|
12719
12719
|
}
|
|
12720
12720
|
var sliverControl = opts.sliver_control >= 0 ? opts.sliver_control : 0; // 0 is default
|
|
12721
12721
|
var crs = getDatasetCRS(dataset);
|
|
12722
|
-
var threshold = areaArg ?
|
|
12722
|
+
var threshold = areaArg && areaArg != 'auto' ?
|
|
12723
12723
|
convertAreaParam(areaArg, crs) :
|
|
12724
12724
|
getDefaultSliverThreshold(lyr, dataset.arcs);
|
|
12725
12725
|
var filter = sliverControl > 0 ?
|
|
@@ -16653,7 +16653,8 @@
|
|
|
16653
16653
|
overlap_rule: opts.overlap_rule
|
|
16654
16654
|
};
|
|
16655
16655
|
var mosaicIndex = new MosaicIndex(lyr, nodes, mosaicOpts);
|
|
16656
|
-
|
|
16656
|
+
// gap fill doesn't work yet with overlapping shapes
|
|
16657
|
+
var fillGaps = !opts.allow_overlaps && (opts.sliver_control || opts.gap_fill_area);
|
|
16657
16658
|
var cleanupData, filterData;
|
|
16658
16659
|
if (fillGaps) {
|
|
16659
16660
|
var sliverOpts = utils.extend({sliver_control: 1}, opts);
|
|
@@ -16935,6 +16936,7 @@
|
|
|
16935
16936
|
|
|
16936
16937
|
function cleanPolygonLayerGeometry(lyr, dataset, opts) {
|
|
16937
16938
|
// clean polygons by apply the 'dissolve2' function to each feature
|
|
16939
|
+
opts = Object.assign({gap_fill_area: 'auto'}, opts);
|
|
16938
16940
|
var groups = lyr.shapes.map(function(shp, i) {
|
|
16939
16941
|
return [i];
|
|
16940
16942
|
});
|
|
@@ -18213,6 +18215,7 @@
|
|
|
18213
18215
|
dy: 'measure',
|
|
18214
18216
|
fill: 'color',
|
|
18215
18217
|
'fill-pattern': 'pattern',
|
|
18218
|
+
'fill-effect': null, // todo: validate effect names
|
|
18216
18219
|
'font-family': null,
|
|
18217
18220
|
'font-size': null,
|
|
18218
18221
|
'font-style': null,
|
|
@@ -18261,7 +18264,7 @@
|
|
|
18261
18264
|
var commonProperties = 'css,class,opacity,stroke,stroke-width,stroke-dasharray,stroke-opacity,fill-opacity,vector-effect'.split(',');
|
|
18262
18265
|
|
|
18263
18266
|
var propertiesBySymbolType = {
|
|
18264
|
-
polygon: utils.arrayToIndex(commonProperties.concat('fill', 'fill-pattern')),
|
|
18267
|
+
polygon: utils.arrayToIndex(commonProperties.concat('fill', 'fill-pattern', 'fill-effect')),
|
|
18265
18268
|
polyline: utils.arrayToIndex(commonProperties.concat('stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit')),
|
|
18266
18269
|
point: utils.arrayToIndex(commonProperties.concat('fill', 'r')),
|
|
18267
18270
|
label: utils.arrayToIndex(commonProperties.concat(
|
|
@@ -19146,6 +19149,9 @@
|
|
|
19146
19149
|
if (obj.tag == 'path' && obj.properties['fill-pattern']) {
|
|
19147
19150
|
convertFillPattern(obj.properties, defs);
|
|
19148
19151
|
}
|
|
19152
|
+
if (obj.tag == 'path' && obj.properties['fill-effect'] == 'sphere') {
|
|
19153
|
+
convertSphereEffect(obj.properties, defs);
|
|
19154
|
+
}
|
|
19149
19155
|
if (obj.tag == 'image') {
|
|
19150
19156
|
if (/\.svg/.test(obj.properties.href || '')) {
|
|
19151
19157
|
convertSvgImage(obj, defs);
|
|
@@ -19156,6 +19162,25 @@
|
|
|
19156
19162
|
}
|
|
19157
19163
|
}
|
|
19158
19164
|
|
|
19165
|
+
function convertSphereEffect(obj, defs) {
|
|
19166
|
+
var id = 'mapshaper_sphere_effect';
|
|
19167
|
+
var href = `url(#${ id })`;
|
|
19168
|
+
var svg =
|
|
19169
|
+
`<radialGradient id="${id}" cx="0.5" cy="0.5" r=".56" fx="0.4" fy="0.35">
|
|
19170
|
+
<stop offset=".35" stop-opacity="0"/>
|
|
19171
|
+
<stop offset=".65" stop-opacity="0.1" />
|
|
19172
|
+
<stop offset=".85" stop-opacity="0.45" />
|
|
19173
|
+
<stop offset=".95" stop-opacity="1" />
|
|
19174
|
+
</radialGradient>` ;
|
|
19175
|
+
if (!utils.find(defs, function(o) { return o.id == id; })) {
|
|
19176
|
+
defs.push({svg, id, href});
|
|
19177
|
+
}
|
|
19178
|
+
obj.fill = href;
|
|
19179
|
+
if ('opacity' in obj === false && 'fill-opacity' in obj === false) {
|
|
19180
|
+
obj['fill-opacity'] = 0.35;
|
|
19181
|
+
}
|
|
19182
|
+
}
|
|
19183
|
+
|
|
19159
19184
|
function convertSvgImage(obj, defs) {
|
|
19160
19185
|
// Same-origin policy prevents embedding images in the web UI
|
|
19161
19186
|
var href = obj.properties.href;
|
|
@@ -23675,7 +23700,10 @@ ${svg}
|
|
|
23675
23700
|
.option('calc', calcOpt)
|
|
23676
23701
|
.option('sum-fields', sumFieldsOpt)
|
|
23677
23702
|
.option('copy-fields', copyFieldsOpt)
|
|
23678
|
-
.option('gap-fill-area',
|
|
23703
|
+
.option('gap-fill-area', {
|
|
23704
|
+
describe: 'threshold for filling gaps, e.g. 1.5km2',
|
|
23705
|
+
type: 'area'
|
|
23706
|
+
})
|
|
23679
23707
|
.option('sliver-control', sliverControlOpt)
|
|
23680
23708
|
.option('allow-overlaps', {
|
|
23681
23709
|
describe: 'allow dissolved polygons to overlap (disables gap fill)',
|
|
@@ -23917,7 +23945,9 @@ ${svg}
|
|
|
23917
23945
|
.option('polygon', {
|
|
23918
23946
|
describe: 'create a polygon to match the outline of the graticule',
|
|
23919
23947
|
type: 'flag'
|
|
23920
|
-
})
|
|
23948
|
+
})
|
|
23949
|
+
.option('name', nameOpt);
|
|
23950
|
+
|
|
23921
23951
|
|
|
23922
23952
|
parser.command('grid')
|
|
23923
23953
|
.describe('create a grid of square or hexagonal polygons')
|
|
@@ -24447,6 +24477,9 @@ ${svg}
|
|
|
24447
24477
|
.option('fill-pattern', {
|
|
24448
24478
|
describe: 'pattern fill, ex: "hatches 2px grey 2px blue"'
|
|
24449
24479
|
})
|
|
24480
|
+
.option('fill-effect', {
|
|
24481
|
+
describe: 'use "sphere" on a circle for a 3d globe effect'
|
|
24482
|
+
})
|
|
24450
24483
|
.option('fill-opacity', {
|
|
24451
24484
|
describe: 'fill opacity'
|
|
24452
24485
|
})
|
|
@@ -37929,7 +37962,8 @@ ${svg}
|
|
|
37929
37962
|
return {
|
|
37930
37963
|
gnom: 60,
|
|
37931
37964
|
laea: 179,
|
|
37932
|
-
ortho: 89.9, //
|
|
37965
|
+
//ortho: 89.9, // projection errors betwen lat +/-35 to 55
|
|
37966
|
+
ortho: 89.85, // TODO: investigate
|
|
37933
37967
|
stere: 142,
|
|
37934
37968
|
sterea: 142,
|
|
37935
37969
|
ups: 10.5 // TODO: should be 6.5 deg at north pole
|
|
@@ -38308,7 +38342,7 @@ ${svg}
|
|
|
38308
38342
|
});
|
|
38309
38343
|
|
|
38310
38344
|
cmd.graticule = function(dataset, opts) {
|
|
38311
|
-
var name = opts.polygon
|
|
38345
|
+
var name = opts.name || opts.polygon && 'polygon' || 'graticule';
|
|
38312
38346
|
var graticule, destInfo;
|
|
38313
38347
|
if (dataset && !isLatLngDataset(dataset)) {
|
|
38314
38348
|
// project graticule to match dataset
|
|
@@ -38374,7 +38408,7 @@ ${svg}
|
|
|
38374
38408
|
//
|
|
38375
38409
|
function createGraticule(P, outlined, opts) {
|
|
38376
38410
|
var interval = opts.interval || 10;
|
|
38377
|
-
if (![5,10,15,30,45].includes(interval)) stop('Invalid interval:', interval);
|
|
38411
|
+
if (![5,10,15,20,30,45].includes(interval)) stop('Invalid interval:', interval);
|
|
38378
38412
|
P.lam0 * 180 / Math.PI;
|
|
38379
38413
|
var precision = interval > 10 ? 1 : 0.5; // degrees between each vertex
|
|
38380
38414
|
var xstep = interval;
|
|
@@ -40104,6 +40138,7 @@ ${svg}
|
|
|
40104
40138
|
};
|
|
40105
40139
|
|
|
40106
40140
|
if (opts.calc) {
|
|
40141
|
+
if (!lyr.data) initDataTable(lyr);
|
|
40107
40142
|
records2 = recombineDataRecords(lyr.data.getRecords(), mosaicIndex.getSourceIdsByTileId, mosaicShapes.length, opts);
|
|
40108
40143
|
lyr2.data = new DataTable(records2);
|
|
40109
40144
|
}
|
|
@@ -40962,6 +40997,7 @@ ${svg}
|
|
|
40962
40997
|
}
|
|
40963
40998
|
commandStr = runGlobalExpression(opts.expression, targets);
|
|
40964
40999
|
if (commandStr) {
|
|
41000
|
+
message(`command: [${commandStr}]`);
|
|
40965
41001
|
commands = parseCommands(commandStr);
|
|
40966
41002
|
runParsedCommands(commands, job, cb);
|
|
40967
41003
|
} else {
|