mapshaper 0.6.115 → 0.6.117
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 +884 -35
- package/package.json +1 -1
- package/www/mapshaper.js +884 -35
package/mapshaper.js
CHANGED
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
get isBoolean () { return isBoolean; },
|
|
54
54
|
get isDate () { return isDate; },
|
|
55
55
|
get isEven () { return isEven; },
|
|
56
|
-
get isFiniteNumber () { return isFiniteNumber; },
|
|
56
|
+
get isFiniteNumber () { return isFiniteNumber$1; },
|
|
57
57
|
get isFunction () { return isFunction; },
|
|
58
58
|
get isInteger () { return isInteger; },
|
|
59
59
|
get isNonNegNumber () { return isNonNegNumber; },
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
get mergeNames () { return mergeNames; },
|
|
71
71
|
get numToStr () { return numToStr; },
|
|
72
72
|
get parseIntlNumber () { return parseIntlNumber; },
|
|
73
|
-
get parseNumber () { return parseNumber; },
|
|
73
|
+
get parseNumber () { return parseNumber$1; },
|
|
74
74
|
get parsePercent () { return parsePercent; },
|
|
75
75
|
get parseString () { return parseString; },
|
|
76
76
|
get pickOne () { return pickOne; },
|
|
@@ -188,7 +188,7 @@
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
// Similar to isFinite() but does not coerce strings or other types
|
|
191
|
-
function isFiniteNumber(val) {
|
|
191
|
+
function isFiniteNumber$1(val) {
|
|
192
192
|
return isValidNumber(val) && val !== Infinity && val !== -Infinity;
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -1182,7 +1182,7 @@
|
|
|
1182
1182
|
// Use null instead of NaN for unparsable values
|
|
1183
1183
|
// (in part because if NaN is used, empty strings get converted to "NaN"
|
|
1184
1184
|
// when re-exported).
|
|
1185
|
-
function parseNumber(raw) {
|
|
1185
|
+
function parseNumber$1(raw) {
|
|
1186
1186
|
return parseToNum(raw, cleanNumericString);
|
|
1187
1187
|
}
|
|
1188
1188
|
|
|
@@ -5248,7 +5248,7 @@
|
|
|
5248
5248
|
}
|
|
5249
5249
|
|
|
5250
5250
|
function toLngLat(xy, P) {
|
|
5251
|
-
return projectPoint(xy, P, parseCrsString('wgs84'));
|
|
5251
|
+
return projectPoint(xy, P, parseCrsString$1('wgs84'));
|
|
5252
5252
|
}
|
|
5253
5253
|
|
|
5254
5254
|
function projectPoint(xy, crsFrom, crsTo) {
|
|
@@ -5335,11 +5335,11 @@
|
|
|
5335
5335
|
function getCrsInfo(str) {
|
|
5336
5336
|
return {
|
|
5337
5337
|
crs_string: str,
|
|
5338
|
-
crs: parseCrsString(str)
|
|
5338
|
+
crs: parseCrsString$1(str)
|
|
5339
5339
|
};
|
|
5340
5340
|
}
|
|
5341
5341
|
|
|
5342
|
-
function parseCrsString(str) {
|
|
5342
|
+
function parseCrsString$1(str) {
|
|
5343
5343
|
var defn = getProjDefn(str); // defn is a string or a Proj object
|
|
5344
5344
|
var P;
|
|
5345
5345
|
if (!utils.isString(defn)) {
|
|
@@ -5374,15 +5374,15 @@
|
|
|
5374
5374
|
function getDatasetCrsInfo(dataset) {
|
|
5375
5375
|
var info = copyCrsProperties(dataset.info || {});
|
|
5376
5376
|
if (!info.crs && info.wkt1) {
|
|
5377
|
-
info.crs = parseCrsString(wkt1ToProj(info.wkt1));
|
|
5377
|
+
info.crs = parseCrsString$1(wkt1ToProj(info.wkt1));
|
|
5378
5378
|
} else if (!info.crs && info.crs_string) {
|
|
5379
|
-
info.crs = parseCrsString(info.crs_string);
|
|
5379
|
+
info.crs = parseCrsString$1(info.crs_string);
|
|
5380
5380
|
}
|
|
5381
5381
|
if (!info.crs) {
|
|
5382
5382
|
if (probablyDecimalDegreeBounds(getDatasetBounds(dataset))) {
|
|
5383
5383
|
// use wgs84 for probable latlong datasets with unknown datums
|
|
5384
5384
|
info.crs_string = 'wgs84';
|
|
5385
|
-
info.crs = parseCrsString(info.crs_string);
|
|
5385
|
+
info.crs = parseCrsString$1(info.crs_string);
|
|
5386
5386
|
}
|
|
5387
5387
|
}
|
|
5388
5388
|
return info;
|
|
@@ -5473,7 +5473,7 @@
|
|
|
5473
5473
|
|
|
5474
5474
|
// Convert contents of a .prj file to a projection object
|
|
5475
5475
|
function parsePrj(str) {
|
|
5476
|
-
return parseCrsString(wkt1ToProj(str));
|
|
5476
|
+
return parseCrsString$1(wkt1ToProj(str));
|
|
5477
5477
|
}
|
|
5478
5478
|
|
|
5479
5479
|
var Projections = /*#__PURE__*/Object.freeze({
|
|
@@ -5499,7 +5499,7 @@
|
|
|
5499
5499
|
isWGS84: isWGS84,
|
|
5500
5500
|
isWebMercator: isWebMercator,
|
|
5501
5501
|
looksLikeProj4String: looksLikeProj4String,
|
|
5502
|
-
parseCrsString: parseCrsString,
|
|
5502
|
+
parseCrsString: parseCrsString$1,
|
|
5503
5503
|
parsePrj: parsePrj,
|
|
5504
5504
|
printProjections: printProjections,
|
|
5505
5505
|
projectPoint: projectPoint,
|
|
@@ -11611,7 +11611,7 @@
|
|
|
11611
11611
|
function guessInputFileType(file) {
|
|
11612
11612
|
var ext = getFileExtension(file || '').toLowerCase(),
|
|
11613
11613
|
type = null;
|
|
11614
|
-
if (ext == 'dbf' || ext == 'shp' || ext == 'kml' || ext == 'fgb' || ext == 'gpkg') {
|
|
11614
|
+
if (ext == 'dbf' || ext == 'shp' || ext == 'kml' || ext == 'svg' || ext == 'fgb' || ext == 'gpkg') {
|
|
11615
11615
|
type = ext;
|
|
11616
11616
|
} else if (isAuxiliaryInputFileType(ext)) {
|
|
11617
11617
|
type = ext;
|
|
@@ -11634,7 +11634,8 @@
|
|
|
11634
11634
|
var type = null;
|
|
11635
11635
|
if (utils.isString(content)) {
|
|
11636
11636
|
type = stringLooksLikeJSON(content) && 'json' ||
|
|
11637
|
-
stringLooksLikeKML(content) && 'kml' ||
|
|
11637
|
+
stringLooksLikeKML(content) && 'kml' ||
|
|
11638
|
+
stringLooksLikeSVG(content) && 'svg' || 'text';
|
|
11638
11639
|
} else if (utils.isObject(content) && content.type || utils.isArray(content)) {
|
|
11639
11640
|
type = 'json';
|
|
11640
11641
|
}
|
|
@@ -11654,6 +11655,11 @@
|
|
|
11654
11655
|
return str.includes('<kml ') && str.includes('xmlns="http://www.opengis.net/kml/');
|
|
11655
11656
|
}
|
|
11656
11657
|
|
|
11658
|
+
function stringLooksLikeSVG(str) {
|
|
11659
|
+
str = String(str);
|
|
11660
|
+
return str.includes('<svg ') && str.includes('xmlns="http://www.w3.org/2000/svg"');
|
|
11661
|
+
}
|
|
11662
|
+
|
|
11657
11663
|
function couldBeDsvFile(name) {
|
|
11658
11664
|
var ext = getFileExtension(name).toLowerCase();
|
|
11659
11665
|
return /csv|tsv|txt$/.test(ext);
|
|
@@ -11725,7 +11731,8 @@
|
|
|
11725
11731
|
looksLikeContentFile: looksLikeContentFile,
|
|
11726
11732
|
looksLikeImportableFile: looksLikeImportableFile,
|
|
11727
11733
|
stringLooksLikeJSON: stringLooksLikeJSON,
|
|
11728
|
-
stringLooksLikeKML: stringLooksLikeKML
|
|
11734
|
+
stringLooksLikeKML: stringLooksLikeKML,
|
|
11735
|
+
stringLooksLikeSVG: stringLooksLikeSVG
|
|
11729
11736
|
});
|
|
11730
11737
|
|
|
11731
11738
|
// input: A file path or a buffer
|
|
@@ -24493,22 +24500,28 @@ ${svg}
|
|
|
24493
24500
|
}
|
|
24494
24501
|
|
|
24495
24502
|
async function exportLayerToGeoPackage(lyr, dataset, gpkg, opts) {
|
|
24496
|
-
var features, fields, columns;
|
|
24503
|
+
var features, fields, columns, tableName, targetSrs;
|
|
24497
24504
|
if (!lyr.geometry_type) return;
|
|
24498
24505
|
features = exportLayerAsGeoJSON(lyr, dataset, opts, true, null)
|
|
24499
24506
|
.filter(feat => !!(feat && feat.geometry));
|
|
24500
24507
|
if (features.length === 0) return;
|
|
24501
24508
|
fields = inferFieldTypes(features);
|
|
24502
|
-
|
|
24509
|
+
tableName = getTableName(lyr.name);
|
|
24503
24510
|
columns = fields.map(function(field) {
|
|
24504
24511
|
return {
|
|
24505
24512
|
name: field.name,
|
|
24506
24513
|
dataType: field.type
|
|
24507
24514
|
};
|
|
24508
24515
|
});
|
|
24509
|
-
|
|
24516
|
+
targetSrs = getExportSrs(dataset);
|
|
24517
|
+
await ensureSrsExists(gpkg, targetSrs);
|
|
24518
|
+
// createFeatureTableFromProperties() hardcodes EPSG:4326
|
|
24519
|
+
await gpkg.createFeatureTable(tableName, null, columns, undefined, targetSrs.srs_id);
|
|
24510
24520
|
var featureDao = gpkg.getFeatureDao(tableName);
|
|
24511
|
-
|
|
24521
|
+
// addGeoJSONFeatureToGeoPackageWithFeatureDaoAndSrs() assumes source
|
|
24522
|
+
// GeoJSON is EPSG:4326 and reprojects unless given EPSG:4326 metadata.
|
|
24523
|
+
// Mapshaper output coords are already in target CRS, so suppress reprojection.
|
|
24524
|
+
var srs = getSourceSrsWithoutReprojection(featureDao && featureDao.srs, targetSrs);
|
|
24512
24525
|
for (var i = 0; i < features.length; i++) {
|
|
24513
24526
|
var feat = features[i];
|
|
24514
24527
|
var normalized = normalizeFeature(feat, fields);
|
|
@@ -24607,6 +24620,143 @@ ${svg}
|
|
|
24607
24620
|
return removeUndefinedValues(output);
|
|
24608
24621
|
}
|
|
24609
24622
|
|
|
24623
|
+
function getExportSrs(dataset) {
|
|
24624
|
+
var info = dataset.info || {};
|
|
24625
|
+
var gpkgCrs = normalizeSrsForInsert(info.geopackage_crs);
|
|
24626
|
+
if (gpkgCrs) {
|
|
24627
|
+
if (!gpkgCrs.definition && info.wkt1) {
|
|
24628
|
+
gpkgCrs.definition = info.wkt1;
|
|
24629
|
+
}
|
|
24630
|
+
return gpkgCrs;
|
|
24631
|
+
}
|
|
24632
|
+
var parsed = parseCrsString(info.crs_string);
|
|
24633
|
+
if (parsed) {
|
|
24634
|
+
if (info.wkt1) parsed.definition = info.wkt1;
|
|
24635
|
+
return parsed;
|
|
24636
|
+
}
|
|
24637
|
+
var fromWkt = parseWktAuthority(info.wkt1);
|
|
24638
|
+
if (fromWkt) {
|
|
24639
|
+
fromWkt.definition = info.wkt1;
|
|
24640
|
+
return fromWkt;
|
|
24641
|
+
}
|
|
24642
|
+
if (info.wkt1) {
|
|
24643
|
+
return buildCustomSrsFromWkt(info.wkt1);
|
|
24644
|
+
}
|
|
24645
|
+
return {
|
|
24646
|
+
srs_id: 4326,
|
|
24647
|
+
organization: 'EPSG',
|
|
24648
|
+
organization_coordsys_id: 4326
|
|
24649
|
+
};
|
|
24650
|
+
}
|
|
24651
|
+
|
|
24652
|
+
function parseCrsString(str) {
|
|
24653
|
+
if (!str || typeof str != 'string') return null;
|
|
24654
|
+
var match = str.match(/^([a-z]+):(\d+)$/i);
|
|
24655
|
+
if (!match) return null;
|
|
24656
|
+
var org = match[1].toUpperCase();
|
|
24657
|
+
var code = +match[2];
|
|
24658
|
+
if (!code) return null;
|
|
24659
|
+
return {
|
|
24660
|
+
srs_id: code,
|
|
24661
|
+
organization: org,
|
|
24662
|
+
organization_coordsys_id: code
|
|
24663
|
+
};
|
|
24664
|
+
}
|
|
24665
|
+
|
|
24666
|
+
function parseWktAuthority(wkt) {
|
|
24667
|
+
if (!wkt || typeof wkt != 'string') return null;
|
|
24668
|
+
var rootAuthority = findTopLevelWktAuthority(wkt);
|
|
24669
|
+
if (!rootAuthority) return null;
|
|
24670
|
+
var org = String(rootAuthority[1]).toUpperCase();
|
|
24671
|
+
var code = +rootAuthority[2];
|
|
24672
|
+
if (!code) return null;
|
|
24673
|
+
return {
|
|
24674
|
+
srs_id: code,
|
|
24675
|
+
organization: org,
|
|
24676
|
+
organization_coordsys_id: code
|
|
24677
|
+
};
|
|
24678
|
+
}
|
|
24679
|
+
|
|
24680
|
+
function findTopLevelWktAuthority(wkt) {
|
|
24681
|
+
var depth = 0;
|
|
24682
|
+
var inQuote = false;
|
|
24683
|
+
for (var i = 0; i < wkt.length; i++) {
|
|
24684
|
+
var c = wkt.charAt(i);
|
|
24685
|
+
if (c == '"') {
|
|
24686
|
+
inQuote = !inQuote;
|
|
24687
|
+
continue;
|
|
24688
|
+
}
|
|
24689
|
+
if (inQuote) continue;
|
|
24690
|
+
if (c == '[') {
|
|
24691
|
+
depth++;
|
|
24692
|
+
continue;
|
|
24693
|
+
}
|
|
24694
|
+
if (c == ']') {
|
|
24695
|
+
depth--;
|
|
24696
|
+
continue;
|
|
24697
|
+
}
|
|
24698
|
+
if (depth != 1) continue;
|
|
24699
|
+
if (wkt.slice(i, i + 10).toUpperCase() == 'AUTHORITY[') {
|
|
24700
|
+
return wkt.slice(i).match(/^AUTHORITY\["([^"]+)","(\d+)"\]/i);
|
|
24701
|
+
}
|
|
24702
|
+
}
|
|
24703
|
+
return null;
|
|
24704
|
+
}
|
|
24705
|
+
|
|
24706
|
+
function buildCustomSrsFromWkt(wkt) {
|
|
24707
|
+
var srsId = getCustomSrsId(wkt);
|
|
24708
|
+
return {
|
|
24709
|
+
srs_id: srsId,
|
|
24710
|
+
srs_name: getWktName(wkt) || 'CUSTOM_CRS',
|
|
24711
|
+
organization: 'NONE',
|
|
24712
|
+
organization_coordsys_id: srsId,
|
|
24713
|
+
definition: wkt,
|
|
24714
|
+
description: 'Custom projection'
|
|
24715
|
+
};
|
|
24716
|
+
}
|
|
24717
|
+
|
|
24718
|
+
function getWktName(wkt) {
|
|
24719
|
+
var match = wkt && String(wkt).match(/^(?:PROJCS|GEOGCS)\["([^"]+)"/i);
|
|
24720
|
+
return match ? match[1] : null;
|
|
24721
|
+
}
|
|
24722
|
+
|
|
24723
|
+
function getCustomSrsId(wkt) {
|
|
24724
|
+
var str = String(wkt || '');
|
|
24725
|
+
var hash = 2166136261; // FNV-1a
|
|
24726
|
+
for (var i = 0; i < str.length; i++) {
|
|
24727
|
+
hash ^= str.charCodeAt(i);
|
|
24728
|
+
hash = (hash * 16777619) >>> 0;
|
|
24729
|
+
}
|
|
24730
|
+
return 100000 + (hash % 900000);
|
|
24731
|
+
}
|
|
24732
|
+
|
|
24733
|
+
async function ensureSrsExists(gpkg, srs) {
|
|
24734
|
+
if (!srs || !srs.srs_id) return;
|
|
24735
|
+
var existing = gpkg.getSrs(srs.srs_id);
|
|
24736
|
+
if (existing) return;
|
|
24737
|
+
if (!srs.definition) {
|
|
24738
|
+
stop$1('Unable to export GeoPackage with missing CRS definition for SRS ' + srs.srs_id);
|
|
24739
|
+
}
|
|
24740
|
+
var geopackage = require$1('@ngageoint/geopackage');
|
|
24741
|
+
var spatialReferenceSystem = new geopackage.SpatialReferenceSystem();
|
|
24742
|
+
spatialReferenceSystem.srs_id = srs.srs_id;
|
|
24743
|
+
spatialReferenceSystem.srs_name = srs.srs_name || (srs.organization + ':' + srs.organization_coordsys_id);
|
|
24744
|
+
spatialReferenceSystem.organization = srs.organization;
|
|
24745
|
+
spatialReferenceSystem.organization_coordsys_id = srs.organization_coordsys_id;
|
|
24746
|
+
spatialReferenceSystem.definition = srs.definition;
|
|
24747
|
+
spatialReferenceSystem.description = srs.description || null;
|
|
24748
|
+
gpkg.createSpatialReferenceSystem(spatialReferenceSystem);
|
|
24749
|
+
}
|
|
24750
|
+
|
|
24751
|
+
function getSourceSrsWithoutReprojection(tableSrs, fallbackSrs) {
|
|
24752
|
+
var target = normalizeSrsForInsert(tableSrs) || normalizeSrsForInsert(fallbackSrs);
|
|
24753
|
+
return {
|
|
24754
|
+
srs_id: target.srs_id,
|
|
24755
|
+
organization: 'EPSG',
|
|
24756
|
+
organization_coordsys_id: 4326
|
|
24757
|
+
};
|
|
24758
|
+
}
|
|
24759
|
+
|
|
24610
24760
|
function normalizeValue(value, type) {
|
|
24611
24761
|
if (value === null || value === undefined) return null;
|
|
24612
24762
|
if (type == 'TEXT' && typeof value != 'string') {
|
|
@@ -24664,14 +24814,14 @@ ${svg}
|
|
|
24664
24814
|
}
|
|
24665
24815
|
|
|
24666
24816
|
function normalizeSrsForInsert(srs) {
|
|
24667
|
-
if (!srs)
|
|
24668
|
-
return {
|
|
24669
|
-
srs_id: 4326,
|
|
24670
|
-
organization: 'EPSG',
|
|
24671
|
-
organization_coordsys_id: 4326
|
|
24672
|
-
};
|
|
24673
|
-
}
|
|
24817
|
+
if (!srs) return null;
|
|
24674
24818
|
var normalized = Object.assign({}, srs);
|
|
24819
|
+
if (normalized.srs_id == null && normalized.id != null) {
|
|
24820
|
+
normalized.srs_id = normalized.id;
|
|
24821
|
+
}
|
|
24822
|
+
if (normalized.organization_coordsys_id == null && normalized.code != null) {
|
|
24823
|
+
normalized.organization_coordsys_id = normalized.code;
|
|
24824
|
+
}
|
|
24675
24825
|
if (normalized.srs_id == null && normalized.srsId != null) {
|
|
24676
24826
|
normalized.srs_id = normalized.srsId;
|
|
24677
24827
|
}
|
|
@@ -24685,6 +24835,7 @@ ${svg}
|
|
|
24685
24835
|
if (!normalized.organization) {
|
|
24686
24836
|
normalized.organization = 'EPSG';
|
|
24687
24837
|
}
|
|
24838
|
+
normalized.organization = String(normalized.organization).toUpperCase();
|
|
24688
24839
|
if (normalized.organization_coordsys_id == null) {
|
|
24689
24840
|
normalized.organization_coordsys_id = normalized.srs_id || 4326;
|
|
24690
24841
|
}
|
|
@@ -31313,17 +31464,26 @@ ${svg}
|
|
|
31313
31464
|
var gpkg;
|
|
31314
31465
|
var datasets;
|
|
31315
31466
|
var source;
|
|
31467
|
+
var tmpPath = null;
|
|
31316
31468
|
|
|
31317
31469
|
if (!geopackage || !geopackage.GeoPackageAPI) {
|
|
31318
31470
|
stop$1('GeoPackage library is not loaded');
|
|
31319
31471
|
}
|
|
31320
31472
|
|
|
31321
|
-
|
|
31473
|
+
if (utils.isString(content)) {
|
|
31474
|
+
source = content;
|
|
31475
|
+
} else if (!runningInBrowser()) {
|
|
31476
|
+
tmpPath = writeGeoPackageTempFile(content);
|
|
31477
|
+
source = tmpPath;
|
|
31478
|
+
} else {
|
|
31479
|
+
source = new Uint8Array(content);
|
|
31480
|
+
}
|
|
31322
31481
|
gpkg = await geopackage.GeoPackageAPI.open(source);
|
|
31323
31482
|
try {
|
|
31324
31483
|
datasets = readFeatureTableDatasets(gpkg, opts);
|
|
31325
31484
|
} finally {
|
|
31326
31485
|
gpkg.close();
|
|
31486
|
+
removeTempGeoPackageFile(tmpPath);
|
|
31327
31487
|
}
|
|
31328
31488
|
|
|
31329
31489
|
if (datasets.length === 0) {
|
|
@@ -31338,6 +31498,24 @@ ${svg}
|
|
|
31338
31498
|
return mergeDatasets(datasets);
|
|
31339
31499
|
}
|
|
31340
31500
|
|
|
31501
|
+
function writeGeoPackageTempFile(content) {
|
|
31502
|
+
var fs = require$1('fs');
|
|
31503
|
+
var os = require$1('os');
|
|
31504
|
+
var path = require$1('path');
|
|
31505
|
+
var unique = Date.now() + '-' + process.pid + '-' + Math.random().toString(36).slice(2);
|
|
31506
|
+
var tmpPath = path.join(os.tmpdir(), 'mapshaper-gpkg-import-' + unique + '.gpkg');
|
|
31507
|
+
fs.writeFileSync(tmpPath, Buffer.from(new Uint8Array(content)));
|
|
31508
|
+
return tmpPath;
|
|
31509
|
+
}
|
|
31510
|
+
|
|
31511
|
+
function removeTempGeoPackageFile(filepath) {
|
|
31512
|
+
if (!filepath) return;
|
|
31513
|
+
var fs = require$1('fs');
|
|
31514
|
+
if (fs.existsSync(filepath)) {
|
|
31515
|
+
fs.unlinkSync(filepath);
|
|
31516
|
+
}
|
|
31517
|
+
}
|
|
31518
|
+
|
|
31341
31519
|
// load lookup tables for epsg codes if needed (for browser)
|
|
31342
31520
|
async function initProjLib(datasets) {
|
|
31343
31521
|
for (const dataset of datasets) {
|
|
@@ -31449,6 +31627,672 @@ ${svg}
|
|
|
31449
31627
|
return obj;
|
|
31450
31628
|
}
|
|
31451
31629
|
|
|
31630
|
+
var INHERITED_STYLE_KEYS = [
|
|
31631
|
+
'fill', 'fill-opacity',
|
|
31632
|
+
'stroke', 'stroke-width', 'stroke-opacity', 'stroke-dasharray',
|
|
31633
|
+
'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit',
|
|
31634
|
+
'opacity', 'vector-effect',
|
|
31635
|
+
'font-family', 'font-size', 'font-style', 'font-stretch', 'font-weight',
|
|
31636
|
+
'text-anchor', 'dominant-baseline', 'letter-spacing', 'line-height'
|
|
31637
|
+
];
|
|
31638
|
+
|
|
31639
|
+
var INHERITED_STYLE_INDEX = INHERITED_STYLE_KEYS.reduce(function(memo, key) {
|
|
31640
|
+
memo[key] = true;
|
|
31641
|
+
return memo;
|
|
31642
|
+
}, {});
|
|
31643
|
+
|
|
31644
|
+
var LAYER_SUFFIX = {
|
|
31645
|
+
polygon: 'polygons',
|
|
31646
|
+
polyline: 'lines',
|
|
31647
|
+
point: 'points'
|
|
31648
|
+
};
|
|
31649
|
+
|
|
31650
|
+
function importSVG(str, optsArg) {
|
|
31651
|
+
var opts = optsArg || {};
|
|
31652
|
+
var Parser = typeof DOMParser == 'undefined' ? require$1('@xmldom/xmldom').DOMParser : DOMParser;
|
|
31653
|
+
var doc = new Parser().parseFromString(str, 'text/xml');
|
|
31654
|
+
var root = doc && doc.documentElement;
|
|
31655
|
+
var groups = getTopLevelLayerGroups(root);
|
|
31656
|
+
var layerData = [];
|
|
31657
|
+
var datasets = [];
|
|
31658
|
+
|
|
31659
|
+
groups.forEach(function(group) {
|
|
31660
|
+
var features = [];
|
|
31661
|
+
collectFeatures(group.node, {}, features, {
|
|
31662
|
+
forcePolylinePaths: layerHasOpenPaths(group.node)
|
|
31663
|
+
});
|
|
31664
|
+
if (features.length === 0) return;
|
|
31665
|
+
layerData.push({
|
|
31666
|
+
name: group.name,
|
|
31667
|
+
features: features
|
|
31668
|
+
});
|
|
31669
|
+
});
|
|
31670
|
+
|
|
31671
|
+
flipYCoordinates(layerData);
|
|
31672
|
+
|
|
31673
|
+
layerData.forEach(function(layer) {
|
|
31674
|
+
datasets.push(importLayerFeatures(layer.name, layer.features, opts));
|
|
31675
|
+
});
|
|
31676
|
+
|
|
31677
|
+
if (datasets.length === 0) {
|
|
31678
|
+
return {layers: [], info: {}};
|
|
31679
|
+
}
|
|
31680
|
+
if (datasets.length === 1) {
|
|
31681
|
+
return datasets[0];
|
|
31682
|
+
}
|
|
31683
|
+
return mergeDatasets(datasets);
|
|
31684
|
+
}
|
|
31685
|
+
|
|
31686
|
+
function importLayerFeatures(layerName, features, opts) {
|
|
31687
|
+
var dataset = importGeoJSON({
|
|
31688
|
+
type: 'FeatureCollection',
|
|
31689
|
+
features: features
|
|
31690
|
+
}, opts);
|
|
31691
|
+
if (dataset.layers.length === 1) {
|
|
31692
|
+
dataset.layers[0].name = layerName;
|
|
31693
|
+
} else {
|
|
31694
|
+
dataset.layers.forEach(function(lyr) {
|
|
31695
|
+
var suffix = LAYER_SUFFIX[lyr.geometry_type] || 'features';
|
|
31696
|
+
lyr.name = layerName + '_' + suffix;
|
|
31697
|
+
});
|
|
31698
|
+
}
|
|
31699
|
+
return dataset;
|
|
31700
|
+
}
|
|
31701
|
+
|
|
31702
|
+
function getTopLevelLayerGroups(root) {
|
|
31703
|
+
var groups = [];
|
|
31704
|
+
var childNodes = getElementChildren(root);
|
|
31705
|
+
var defaultNode = null;
|
|
31706
|
+
var layerCount = 0;
|
|
31707
|
+
|
|
31708
|
+
childNodes.forEach(function(node) {
|
|
31709
|
+
var tag = getTagName(node);
|
|
31710
|
+
if (tag == 'defs') return;
|
|
31711
|
+
if (tag == 'g') {
|
|
31712
|
+
groups.push({
|
|
31713
|
+
node: node,
|
|
31714
|
+
name: node.getAttribute('id') || getDefaultLayerName(++layerCount)
|
|
31715
|
+
});
|
|
31716
|
+
} else if (tag == 'path' || tag == 'circle' || tag == 'text') {
|
|
31717
|
+
if (!defaultNode) {
|
|
31718
|
+
defaultNode = {
|
|
31719
|
+
tagName: 'g',
|
|
31720
|
+
childNodes: [],
|
|
31721
|
+
attributes: []
|
|
31722
|
+
};
|
|
31723
|
+
groups.push({
|
|
31724
|
+
node: defaultNode,
|
|
31725
|
+
name: getDefaultLayerName(++layerCount)
|
|
31726
|
+
});
|
|
31727
|
+
}
|
|
31728
|
+
defaultNode.childNodes.push(node);
|
|
31729
|
+
}
|
|
31730
|
+
});
|
|
31731
|
+
|
|
31732
|
+
if (groups.length === 0 && root) {
|
|
31733
|
+
groups.push({
|
|
31734
|
+
node: root,
|
|
31735
|
+
name: getDefaultLayerName(1)
|
|
31736
|
+
});
|
|
31737
|
+
}
|
|
31738
|
+
return groups;
|
|
31739
|
+
}
|
|
31740
|
+
|
|
31741
|
+
function getDefaultLayerName(i) {
|
|
31742
|
+
return 'layer' + i;
|
|
31743
|
+
}
|
|
31744
|
+
|
|
31745
|
+
function collectFeatures(node, inheritedStyles, features, layerOpts) {
|
|
31746
|
+
var tag = getTagName(node);
|
|
31747
|
+
var nodeStyles = getNodeStyles(node);
|
|
31748
|
+
var inherited = extendProps(inheritedStyles, nodeStyles);
|
|
31749
|
+
|
|
31750
|
+
if (tag == 'defs') return;
|
|
31751
|
+
if (tag == 'g' || tag == 'svg') {
|
|
31752
|
+
getElementChildren(node).forEach(function(child) {
|
|
31753
|
+
collectFeatures(child, inherited, features, layerOpts);
|
|
31754
|
+
});
|
|
31755
|
+
return;
|
|
31756
|
+
}
|
|
31757
|
+
if (tag == 'path') {
|
|
31758
|
+
collectPathFeature(node, inherited, features, layerOpts);
|
|
31759
|
+
} else if (tag == 'circle') {
|
|
31760
|
+
collectCircleFeature(node, inherited, features);
|
|
31761
|
+
} else if (tag == 'text') {
|
|
31762
|
+
collectTextFeature(node, inherited, features);
|
|
31763
|
+
}
|
|
31764
|
+
}
|
|
31765
|
+
|
|
31766
|
+
function collectPathFeature(node, inherited, features, layerOpts) {
|
|
31767
|
+
var d = node.getAttribute('d');
|
|
31768
|
+
var geom = parsePathGeometry(d, layerOpts && layerOpts.forcePolylinePaths);
|
|
31769
|
+
var props;
|
|
31770
|
+
if (!geom) return;
|
|
31771
|
+
props = getFeatureProperties(node, inherited, {d: true});
|
|
31772
|
+
features.push({
|
|
31773
|
+
type: 'Feature',
|
|
31774
|
+
geometry: geom,
|
|
31775
|
+
properties: props
|
|
31776
|
+
});
|
|
31777
|
+
}
|
|
31778
|
+
|
|
31779
|
+
function collectCircleFeature(node, inherited, features) {
|
|
31780
|
+
var x = parseNumber(node.getAttribute('cx'));
|
|
31781
|
+
var y = parseNumber(node.getAttribute('cy'));
|
|
31782
|
+
var props;
|
|
31783
|
+
if (!isFiniteNumber(x) || !isFiniteNumber(y)) return;
|
|
31784
|
+
props = getFeatureProperties(node, inherited, {cx: true, cy: true});
|
|
31785
|
+
addNumericProperty(props, 'r', node.getAttribute('r'));
|
|
31786
|
+
features.push({
|
|
31787
|
+
type: 'Feature',
|
|
31788
|
+
geometry: {
|
|
31789
|
+
type: 'Point',
|
|
31790
|
+
coordinates: [x, y]
|
|
31791
|
+
},
|
|
31792
|
+
properties: props
|
|
31793
|
+
});
|
|
31794
|
+
}
|
|
31795
|
+
|
|
31796
|
+
function collectTextFeature(node, inherited, features) {
|
|
31797
|
+
var baseX = parseNumber(node.getAttribute('x')) || 0;
|
|
31798
|
+
var baseY = parseNumber(node.getAttribute('y')) || 0;
|
|
31799
|
+
var translate = parseTranslate(node.getAttribute('transform'));
|
|
31800
|
+
var hasTranslate = nodeHasTranslate(node.getAttribute('transform'));
|
|
31801
|
+
var x = hasTranslate ? translate[0] : baseX;
|
|
31802
|
+
var y = hasTranslate ? translate[1] : baseY;
|
|
31803
|
+
var text = (node.textContent || '').trim();
|
|
31804
|
+
var props = getFeatureProperties(node, inherited, {x: true, y: true, transform: true});
|
|
31805
|
+
|
|
31806
|
+
props['label-text'] = text;
|
|
31807
|
+
if (hasTranslate && node.getAttribute('x') !== null) {
|
|
31808
|
+
props.dx = baseX;
|
|
31809
|
+
}
|
|
31810
|
+
if (hasTranslate && node.getAttribute('y') !== null) {
|
|
31811
|
+
props.dy = baseY;
|
|
31812
|
+
}
|
|
31813
|
+
features.push({
|
|
31814
|
+
type: 'Feature',
|
|
31815
|
+
geometry: {
|
|
31816
|
+
type: 'Point',
|
|
31817
|
+
coordinates: [x, y]
|
|
31818
|
+
},
|
|
31819
|
+
properties: props
|
|
31820
|
+
});
|
|
31821
|
+
}
|
|
31822
|
+
|
|
31823
|
+
function getFeatureProperties(node, inherited, excluded) {
|
|
31824
|
+
var props = extendProps({}, inherited);
|
|
31825
|
+
var attrs = node.attributes || [];
|
|
31826
|
+
var styleMap = parseStyleString(node.getAttribute && node.getAttribute('style'));
|
|
31827
|
+
|
|
31828
|
+
Object.keys(styleMap).forEach(function(name) {
|
|
31829
|
+
if (name == 'fill-rule') return;
|
|
31830
|
+
props[name] = styleMap[name];
|
|
31831
|
+
});
|
|
31832
|
+
for (var i = 0; i < attrs.length; i++) {
|
|
31833
|
+
var attr = attrs[i];
|
|
31834
|
+
var key = attr && attr.name;
|
|
31835
|
+
var val = attr && attr.value;
|
|
31836
|
+
if (!key || key == 'style' || (excluded && excluded[key])) continue;
|
|
31837
|
+
if (key == 'id' || key == 'class' || key.indexOf('data-') === 0 || INHERITED_STYLE_INDEX[key]) {
|
|
31838
|
+
props[key] = val;
|
|
31839
|
+
}
|
|
31840
|
+
}
|
|
31841
|
+
return props;
|
|
31842
|
+
}
|
|
31843
|
+
|
|
31844
|
+
function getNodeStyles(node) {
|
|
31845
|
+
var styles = {};
|
|
31846
|
+
var attrs = node.attributes || [];
|
|
31847
|
+
var styleMap = parseStyleString(node.getAttribute && node.getAttribute('style'));
|
|
31848
|
+
var i, attr, key;
|
|
31849
|
+
|
|
31850
|
+
Object.keys(styleMap).forEach(function(name) {
|
|
31851
|
+
if (INHERITED_STYLE_INDEX[name]) {
|
|
31852
|
+
styles[name] = styleMap[name];
|
|
31853
|
+
}
|
|
31854
|
+
});
|
|
31855
|
+
|
|
31856
|
+
for (i = 0; i < attrs.length; i++) {
|
|
31857
|
+
attr = attrs[i];
|
|
31858
|
+
key = attr && attr.name;
|
|
31859
|
+
if (key && INHERITED_STYLE_INDEX[key]) {
|
|
31860
|
+
styles[key] = attr.value;
|
|
31861
|
+
}
|
|
31862
|
+
}
|
|
31863
|
+
return styles;
|
|
31864
|
+
}
|
|
31865
|
+
|
|
31866
|
+
function parseStyleString(style) {
|
|
31867
|
+
var out = {};
|
|
31868
|
+
var parts, i, part, idx, key, val;
|
|
31869
|
+
if (!style) return out;
|
|
31870
|
+
parts = String(style).split(';');
|
|
31871
|
+
for (i = 0; i < parts.length; i++) {
|
|
31872
|
+
part = parts[i].trim();
|
|
31873
|
+
if (!part) continue;
|
|
31874
|
+
idx = part.indexOf(':');
|
|
31875
|
+
if (idx == -1) continue;
|
|
31876
|
+
key = part.substr(0, idx).trim();
|
|
31877
|
+
val = part.substr(idx + 1).trim();
|
|
31878
|
+
if (!key) continue;
|
|
31879
|
+
out[key] = val;
|
|
31880
|
+
}
|
|
31881
|
+
return out;
|
|
31882
|
+
}
|
|
31883
|
+
|
|
31884
|
+
function parsePathGeometry(d, forcePolylinePaths) {
|
|
31885
|
+
var subpaths = parsePathData(d);
|
|
31886
|
+
var lines = [];
|
|
31887
|
+
var rings = [];
|
|
31888
|
+
var parts = [];
|
|
31889
|
+
var polygonGeom, polylineGeom;
|
|
31890
|
+
|
|
31891
|
+
subpaths.forEach(function(path) {
|
|
31892
|
+
var coords = path.coords;
|
|
31893
|
+
if (coords.length < 2) return;
|
|
31894
|
+
if (forcePolylinePaths) {
|
|
31895
|
+
lines.push(path.closed || pointsEqual(coords[0], coords[coords.length - 1]) ? closeRing(coords) : coords);
|
|
31896
|
+
return;
|
|
31897
|
+
}
|
|
31898
|
+
if (path.closed || pointsEqual(coords[0], coords[coords.length - 1])) {
|
|
31899
|
+
if (coords.length >= 3) {
|
|
31900
|
+
rings.push(closeRing(coords));
|
|
31901
|
+
}
|
|
31902
|
+
} else {
|
|
31903
|
+
lines.push(coords);
|
|
31904
|
+
}
|
|
31905
|
+
});
|
|
31906
|
+
|
|
31907
|
+
if (rings.length > 0) {
|
|
31908
|
+
polygonGeom = buildPolygonGeometry(rings);
|
|
31909
|
+
if (polygonGeom) parts.push(polygonGeom);
|
|
31910
|
+
}
|
|
31911
|
+
if (lines.length > 0) {
|
|
31912
|
+
polylineGeom = lines.length == 1 ? {
|
|
31913
|
+
type: 'LineString',
|
|
31914
|
+
coordinates: lines[0]
|
|
31915
|
+
} : {
|
|
31916
|
+
type: 'MultiLineString',
|
|
31917
|
+
coordinates: lines
|
|
31918
|
+
};
|
|
31919
|
+
parts.push(polylineGeom);
|
|
31920
|
+
}
|
|
31921
|
+
if (parts.length === 0) return null;
|
|
31922
|
+
if (parts.length === 1) return parts[0];
|
|
31923
|
+
return {
|
|
31924
|
+
type: 'GeometryCollection',
|
|
31925
|
+
geometries: parts
|
|
31926
|
+
};
|
|
31927
|
+
}
|
|
31928
|
+
|
|
31929
|
+
function buildPolygonGeometry(rings) {
|
|
31930
|
+
var ringData = rings.map(function(coords, i) {
|
|
31931
|
+
return {
|
|
31932
|
+
id: i,
|
|
31933
|
+
coords: coords,
|
|
31934
|
+
area: Math.abs(getRingArea(coords)),
|
|
31935
|
+
containers: [],
|
|
31936
|
+
depth: 0,
|
|
31937
|
+
parent: null
|
|
31938
|
+
};
|
|
31939
|
+
});
|
|
31940
|
+
|
|
31941
|
+
ringData.forEach(function(ring, i) {
|
|
31942
|
+
var point = getRingSamplePoint(ring.coords);
|
|
31943
|
+
ringData.forEach(function(other, j) {
|
|
31944
|
+
if (i == j) return;
|
|
31945
|
+
if (pointInRing(point, other.coords)) {
|
|
31946
|
+
ring.containers.push(other.id);
|
|
31947
|
+
}
|
|
31948
|
+
});
|
|
31949
|
+
ring.depth = ring.containers.length;
|
|
31950
|
+
});
|
|
31951
|
+
|
|
31952
|
+
ringData.forEach(function(ring) {
|
|
31953
|
+
var parentDepth = ring.depth - 1;
|
|
31954
|
+
if (parentDepth < 0) return;
|
|
31955
|
+
ring.containers.forEach(function(parentId) {
|
|
31956
|
+
var candidate = ringData[parentId];
|
|
31957
|
+
if (candidate.depth != parentDepth) return;
|
|
31958
|
+
if (!ring.parent || candidate.area < ring.parent.area) {
|
|
31959
|
+
ring.parent = candidate;
|
|
31960
|
+
}
|
|
31961
|
+
});
|
|
31962
|
+
});
|
|
31963
|
+
|
|
31964
|
+
var polygons = [];
|
|
31965
|
+
ringData.forEach(function(ring) {
|
|
31966
|
+
if (ring.depth % 2 !== 0) return;
|
|
31967
|
+
polygons.push([ring.coords]);
|
|
31968
|
+
});
|
|
31969
|
+
|
|
31970
|
+
ringData.forEach(function(ring) {
|
|
31971
|
+
var polygon;
|
|
31972
|
+
if (ring.depth % 2 !== 1 || !ring.parent) return;
|
|
31973
|
+
polygon = polygons.find(function(coords) {
|
|
31974
|
+
return coords[0] === ring.parent.coords;
|
|
31975
|
+
});
|
|
31976
|
+
if (polygon) {
|
|
31977
|
+
polygon.push(ring.coords);
|
|
31978
|
+
}
|
|
31979
|
+
});
|
|
31980
|
+
|
|
31981
|
+
if (polygons.length === 0) return null;
|
|
31982
|
+
if (polygons.length == 1) {
|
|
31983
|
+
return {
|
|
31984
|
+
type: 'Polygon',
|
|
31985
|
+
coordinates: polygons[0]
|
|
31986
|
+
};
|
|
31987
|
+
}
|
|
31988
|
+
return {
|
|
31989
|
+
type: 'MultiPolygon',
|
|
31990
|
+
coordinates: polygons.map(function(coords) {
|
|
31991
|
+
return [coords[0]].concat(coords.slice(1));
|
|
31992
|
+
})
|
|
31993
|
+
};
|
|
31994
|
+
}
|
|
31995
|
+
|
|
31996
|
+
function parsePathData(d) {
|
|
31997
|
+
var tokens = tokenizePath(d || '');
|
|
31998
|
+
var paths = [];
|
|
31999
|
+
var cmd = null;
|
|
32000
|
+
var i = 0;
|
|
32001
|
+
var currX = 0;
|
|
32002
|
+
var currY = 0;
|
|
32003
|
+
var startX = 0;
|
|
32004
|
+
var startY = 0;
|
|
32005
|
+
var path = null;
|
|
32006
|
+
|
|
32007
|
+
function startPath(x, y) {
|
|
32008
|
+
if (path && path.coords.length > 0) {
|
|
32009
|
+
paths.push(path);
|
|
32010
|
+
}
|
|
32011
|
+
path = {
|
|
32012
|
+
coords: [[x, y]],
|
|
32013
|
+
closed: false
|
|
32014
|
+
};
|
|
32015
|
+
currX = x;
|
|
32016
|
+
currY = y;
|
|
32017
|
+
startX = x;
|
|
32018
|
+
startY = y;
|
|
32019
|
+
}
|
|
32020
|
+
|
|
32021
|
+
function addPoint(x, y) {
|
|
32022
|
+
if (!path) {
|
|
32023
|
+
startPath(x, y);
|
|
32024
|
+
return;
|
|
32025
|
+
}
|
|
32026
|
+
path.coords.push([x, y]);
|
|
32027
|
+
currX = x;
|
|
32028
|
+
currY = y;
|
|
32029
|
+
}
|
|
32030
|
+
|
|
32031
|
+
while (i < tokens.length) {
|
|
32032
|
+
if (isPathCommand(tokens[i])) {
|
|
32033
|
+
cmd = tokens[i++];
|
|
32034
|
+
if (cmd == 'Z' || cmd == 'z') {
|
|
32035
|
+
if (path) {
|
|
32036
|
+
path.closed = true;
|
|
32037
|
+
currX = startX;
|
|
32038
|
+
currY = startY;
|
|
32039
|
+
}
|
|
32040
|
+
}
|
|
32041
|
+
continue;
|
|
32042
|
+
}
|
|
32043
|
+
if (!cmd) {
|
|
32044
|
+
i++;
|
|
32045
|
+
continue;
|
|
32046
|
+
}
|
|
32047
|
+
|
|
32048
|
+
if (cmd == 'M' || cmd == 'm') {
|
|
32049
|
+
if (!hasPair(tokens, i)) break;
|
|
32050
|
+
var moveX = Number(tokens[i++]);
|
|
32051
|
+
var moveY = Number(tokens[i++]);
|
|
32052
|
+
if (cmd == 'm') {
|
|
32053
|
+
moveX += currX;
|
|
32054
|
+
moveY += currY;
|
|
32055
|
+
}
|
|
32056
|
+
startPath(moveX, moveY);
|
|
32057
|
+
cmd = cmd == 'm' ? 'l' : 'L';
|
|
32058
|
+
continue;
|
|
32059
|
+
}
|
|
32060
|
+
|
|
32061
|
+
if (cmd == 'L' || cmd == 'l') {
|
|
32062
|
+
if (!hasPair(tokens, i)) break;
|
|
32063
|
+
var lineX = Number(tokens[i++]);
|
|
32064
|
+
var lineY = Number(tokens[i++]);
|
|
32065
|
+
if (cmd == 'l') {
|
|
32066
|
+
lineX += currX;
|
|
32067
|
+
lineY += currY;
|
|
32068
|
+
}
|
|
32069
|
+
addPoint(lineX, lineY);
|
|
32070
|
+
continue;
|
|
32071
|
+
}
|
|
32072
|
+
|
|
32073
|
+
if (cmd == 'H' || cmd == 'h') {
|
|
32074
|
+
var x = Number(tokens[i++]);
|
|
32075
|
+
if (cmd == 'h') x += currX;
|
|
32076
|
+
addPoint(x, currY);
|
|
32077
|
+
continue;
|
|
32078
|
+
}
|
|
32079
|
+
|
|
32080
|
+
if (cmd == 'V' || cmd == 'v') {
|
|
32081
|
+
var y = Number(tokens[i++]);
|
|
32082
|
+
if (cmd == 'v') y += currY;
|
|
32083
|
+
addPoint(currX, y);
|
|
32084
|
+
continue;
|
|
32085
|
+
}
|
|
32086
|
+
|
|
32087
|
+
// Unsupported command -- skip following numeric tokens until next command.
|
|
32088
|
+
while (i < tokens.length && !isPathCommand(tokens[i])) {
|
|
32089
|
+
i++;
|
|
32090
|
+
}
|
|
32091
|
+
}
|
|
32092
|
+
|
|
32093
|
+
if (path && path.coords.length > 0) {
|
|
32094
|
+
paths.push(path);
|
|
32095
|
+
}
|
|
32096
|
+
return paths;
|
|
32097
|
+
}
|
|
32098
|
+
|
|
32099
|
+
function layerHasOpenPaths(node) {
|
|
32100
|
+
var hasOpenPath = false;
|
|
32101
|
+
|
|
32102
|
+
function scan(el) {
|
|
32103
|
+
var tag = getTagName(el);
|
|
32104
|
+
if (!tag || tag == 'defs' || hasOpenPath) return;
|
|
32105
|
+
if (tag == 'path') {
|
|
32106
|
+
hasOpenPath = pathContainsOpenSubpath(el.getAttribute('d'));
|
|
32107
|
+
return;
|
|
32108
|
+
}
|
|
32109
|
+
getElementChildren(el).forEach(scan);
|
|
32110
|
+
}
|
|
32111
|
+
|
|
32112
|
+
scan(node);
|
|
32113
|
+
return hasOpenPath;
|
|
32114
|
+
}
|
|
32115
|
+
|
|
32116
|
+
function pathContainsOpenSubpath(d) {
|
|
32117
|
+
var subpaths = parsePathData(d);
|
|
32118
|
+
for (var i = 0; i < subpaths.length; i++) {
|
|
32119
|
+
var coords = subpaths[i].coords;
|
|
32120
|
+
if (coords.length < 2) continue;
|
|
32121
|
+
if (!subpaths[i].closed && !pointsEqual(coords[0], coords[coords.length - 1])) {
|
|
32122
|
+
return true;
|
|
32123
|
+
}
|
|
32124
|
+
}
|
|
32125
|
+
return false;
|
|
32126
|
+
}
|
|
32127
|
+
|
|
32128
|
+
function flipYCoordinates(layerData) {
|
|
32129
|
+
var range = getYRange(layerData);
|
|
32130
|
+
if (!range) return;
|
|
32131
|
+
layerData.forEach(function(layer) {
|
|
32132
|
+
layer.features.forEach(function(feature) {
|
|
32133
|
+
if (feature && feature.geometry) {
|
|
32134
|
+
flipGeometryY(feature.geometry, range);
|
|
32135
|
+
}
|
|
32136
|
+
});
|
|
32137
|
+
});
|
|
32138
|
+
}
|
|
32139
|
+
|
|
32140
|
+
function getYRange(layerData) {
|
|
32141
|
+
var minY = Infinity;
|
|
32142
|
+
var maxY = -Infinity;
|
|
32143
|
+
layerData.forEach(function(layer) {
|
|
32144
|
+
layer.features.forEach(function(feature) {
|
|
32145
|
+
forEachGeometryCoordinate(feature && feature.geometry, function(coord) {
|
|
32146
|
+
if (coord[1] < minY) minY = coord[1];
|
|
32147
|
+
if (coord[1] > maxY) maxY = coord[1];
|
|
32148
|
+
});
|
|
32149
|
+
});
|
|
32150
|
+
});
|
|
32151
|
+
if (!isFinite(minY) || !isFinite(maxY)) return null;
|
|
32152
|
+
return {min: minY, max: maxY};
|
|
32153
|
+
}
|
|
32154
|
+
|
|
32155
|
+
function flipGeometryY(geom, range) {
|
|
32156
|
+
forEachGeometryCoordinate(geom, function(coord) {
|
|
32157
|
+
coord[1] = range.min + range.max - coord[1];
|
|
32158
|
+
});
|
|
32159
|
+
}
|
|
32160
|
+
|
|
32161
|
+
function forEachGeometryCoordinate(geom, cb) {
|
|
32162
|
+
if (!geom || !geom.type) return;
|
|
32163
|
+
if (geom.type == 'Point') {
|
|
32164
|
+
cb(geom.coordinates);
|
|
32165
|
+
} else if (geom.type == 'LineString' || geom.type == 'MultiPoint') {
|
|
32166
|
+
geom.coordinates.forEach(cb);
|
|
32167
|
+
} else if (geom.type == 'Polygon' || geom.type == 'MultiLineString') {
|
|
32168
|
+
geom.coordinates.forEach(function(path) {
|
|
32169
|
+
path.forEach(cb);
|
|
32170
|
+
});
|
|
32171
|
+
} else if (geom.type == 'MultiPolygon') {
|
|
32172
|
+
geom.coordinates.forEach(function(poly) {
|
|
32173
|
+
poly.forEach(function(ring) {
|
|
32174
|
+
ring.forEach(cb);
|
|
32175
|
+
});
|
|
32176
|
+
});
|
|
32177
|
+
} else if (geom.type == 'GeometryCollection') {
|
|
32178
|
+
(geom.geometries || []).forEach(function(child) {
|
|
32179
|
+
forEachGeometryCoordinate(child, cb);
|
|
32180
|
+
});
|
|
32181
|
+
}
|
|
32182
|
+
}
|
|
32183
|
+
|
|
32184
|
+
function tokenizePath(d) {
|
|
32185
|
+
var rxp = /[a-zA-Z]|-?(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?/ig;
|
|
32186
|
+
return String(d).match(rxp) || [];
|
|
32187
|
+
}
|
|
32188
|
+
|
|
32189
|
+
function parseTranslate(str) {
|
|
32190
|
+
var match = String(str || '').match(/translate\(\s*([^\s,()]+)(?:[\s,]+([^\s,()]+))?/i);
|
|
32191
|
+
var x = 0;
|
|
32192
|
+
var y = 0;
|
|
32193
|
+
if (match) {
|
|
32194
|
+
x = parseNumber(match[1]) || 0;
|
|
32195
|
+
y = parseNumber(match[2]) || 0;
|
|
32196
|
+
}
|
|
32197
|
+
return [x, y];
|
|
32198
|
+
}
|
|
32199
|
+
|
|
32200
|
+
function nodeHasTranslate(str) {
|
|
32201
|
+
return /translate\(/i.test(String(str || ''));
|
|
32202
|
+
}
|
|
32203
|
+
|
|
32204
|
+
function closeRing(coords) {
|
|
32205
|
+
var ring = coords.map(function(p) { return [p[0], p[1]]; });
|
|
32206
|
+
if (!pointsEqual(ring[0], ring[ring.length - 1])) {
|
|
32207
|
+
ring.push([ring[0][0], ring[0][1]]);
|
|
32208
|
+
}
|
|
32209
|
+
return ring;
|
|
32210
|
+
}
|
|
32211
|
+
|
|
32212
|
+
function getRingSamplePoint(ring) {
|
|
32213
|
+
return ring[0];
|
|
32214
|
+
}
|
|
32215
|
+
|
|
32216
|
+
function getRingArea(ring) {
|
|
32217
|
+
var area = 0;
|
|
32218
|
+
for (var i = 0, n = ring.length - 1; i < n; i++) {
|
|
32219
|
+
area += ring[i][0] * ring[i + 1][1] - ring[i + 1][0] * ring[i][1];
|
|
32220
|
+
}
|
|
32221
|
+
return area / 2;
|
|
32222
|
+
}
|
|
32223
|
+
|
|
32224
|
+
function pointInRing(point, ring) {
|
|
32225
|
+
var x = point[0];
|
|
32226
|
+
var y = point[1];
|
|
32227
|
+
var inside = false;
|
|
32228
|
+
var i, j, xi, yi, xj, yj, intersects;
|
|
32229
|
+
for (i = 0, j = ring.length - 1; i < ring.length; j = i++) {
|
|
32230
|
+
xi = ring[i][0];
|
|
32231
|
+
yi = ring[i][1];
|
|
32232
|
+
xj = ring[j][0];
|
|
32233
|
+
yj = ring[j][1];
|
|
32234
|
+
intersects = ((yi > y) != (yj > y)) &&
|
|
32235
|
+
(x < (xj - xi) * (y - yi) / ((yj - yi) || 1e-30) + xi);
|
|
32236
|
+
if (intersects) inside = !inside;
|
|
32237
|
+
}
|
|
32238
|
+
return inside;
|
|
32239
|
+
}
|
|
32240
|
+
|
|
32241
|
+
function addNumericProperty(props, key, strVal) {
|
|
32242
|
+
var num = parseNumber(strVal);
|
|
32243
|
+
if (isFiniteNumber(num)) {
|
|
32244
|
+
props[key] = num;
|
|
32245
|
+
}
|
|
32246
|
+
}
|
|
32247
|
+
|
|
32248
|
+
function parseNumber(str) {
|
|
32249
|
+
var num = Number(str);
|
|
32250
|
+
return isFiniteNumber(num) ? num : null;
|
|
32251
|
+
}
|
|
32252
|
+
|
|
32253
|
+
function hasPair(tokens, i) {
|
|
32254
|
+
return i + 1 < tokens.length && !isPathCommand(tokens[i]) && !isPathCommand(tokens[i + 1]);
|
|
32255
|
+
}
|
|
32256
|
+
|
|
32257
|
+
function isPathCommand(token) {
|
|
32258
|
+
return /^[a-z]$/i.test(token);
|
|
32259
|
+
}
|
|
32260
|
+
|
|
32261
|
+
function pointsEqual(a, b) {
|
|
32262
|
+
return a && b && a[0] == b[0] && a[1] == b[1];
|
|
32263
|
+
}
|
|
32264
|
+
|
|
32265
|
+
function isFiniteNumber(val) {
|
|
32266
|
+
return typeof val == 'number' && isFinite(val);
|
|
32267
|
+
}
|
|
32268
|
+
|
|
32269
|
+
function getTagName(node) {
|
|
32270
|
+
return node && node.tagName ? String(node.tagName).toLowerCase() : '';
|
|
32271
|
+
}
|
|
32272
|
+
|
|
32273
|
+
function getElementChildren(node) {
|
|
32274
|
+
var out = [];
|
|
32275
|
+
var childNodes = node && node.childNodes ? node.childNodes : [];
|
|
32276
|
+
for (var i = 0; i < childNodes.length; i++) {
|
|
32277
|
+
if (childNodes[i] && childNodes[i].nodeType == 1) {
|
|
32278
|
+
out.push(childNodes[i]);
|
|
32279
|
+
}
|
|
32280
|
+
}
|
|
32281
|
+
return out;
|
|
32282
|
+
}
|
|
32283
|
+
|
|
32284
|
+
function extendProps(dest, src) {
|
|
32285
|
+
var out = {};
|
|
32286
|
+
var key;
|
|
32287
|
+
if (dest) {
|
|
32288
|
+
for (key in dest) out[key] = dest[key];
|
|
32289
|
+
}
|
|
32290
|
+
if (src) {
|
|
32291
|
+
for (key in src) out[key] = src[key];
|
|
32292
|
+
}
|
|
32293
|
+
return out;
|
|
32294
|
+
}
|
|
32295
|
+
|
|
31452
32296
|
// Parse content of one or more input files and return a dataset
|
|
31453
32297
|
// @obj: file data, indexed by file type
|
|
31454
32298
|
// File data objects have two properties:
|
|
@@ -31491,6 +32335,11 @@ ${svg}
|
|
|
31491
32335
|
data = obj.kml;
|
|
31492
32336
|
dataset = importKML(data.content, opts);
|
|
31493
32337
|
|
|
32338
|
+
} else if (obj.svg) {
|
|
32339
|
+
dataFmt = 'svg';
|
|
32340
|
+
data = obj.svg;
|
|
32341
|
+
dataset = importSVG(data.content, opts);
|
|
32342
|
+
|
|
31494
32343
|
} else if (obj.fgb) {
|
|
31495
32344
|
stop$1("FlatGeobuf import requires async import path");
|
|
31496
32345
|
} else if (obj.gpkg) {
|
|
@@ -31690,7 +32539,7 @@ ${svg}
|
|
|
31690
32539
|
if (o.crs_string) {
|
|
31691
32540
|
// load external files (e.g. epsg definitions) if needed in GUI
|
|
31692
32541
|
await initProjLibrary({crs: o.crs_string});
|
|
31693
|
-
o.crs = parseCrsString(o.crs_string);
|
|
32542
|
+
o.crs = parseCrsString$1(o.crs_string);
|
|
31694
32543
|
} else if (o.prj) {
|
|
31695
32544
|
o.crs = parsePrj(o.prj);
|
|
31696
32545
|
}
|
|
@@ -35072,7 +35921,7 @@ ${svg}
|
|
|
35072
35921
|
// Make a single geodetic circle
|
|
35073
35922
|
function getCircleGeoJSON(center, radius, vertices, opts) {
|
|
35074
35923
|
var n = 360;
|
|
35075
|
-
var geod = getGeodeticSegmentFunction(parseCrsString('wgs84')); // ?
|
|
35924
|
+
var geod = getGeodeticSegmentFunction(parseCrsString$1('wgs84')); // ?
|
|
35076
35925
|
if (opts.inset) {
|
|
35077
35926
|
radius -= opts.inset;
|
|
35078
35927
|
}
|
|
@@ -43702,23 +44551,23 @@ ${svg}
|
|
|
43702
44551
|
};
|
|
43703
44552
|
|
|
43704
44553
|
function createUnprojectedPolygon(opts) {
|
|
43705
|
-
var crs = parseCrsString('wgs84');
|
|
44554
|
+
var crs = parseCrsString$1('wgs84');
|
|
43706
44555
|
return getPolygonDataset$1(crs, crs, opts);
|
|
43707
44556
|
}
|
|
43708
44557
|
|
|
43709
44558
|
function createProjectedPolygon(dest, opts) {
|
|
43710
|
-
var src = parseCrsString('wgs84');
|
|
44559
|
+
var src = parseCrsString$1('wgs84');
|
|
43711
44560
|
return getPolygonDataset$1(src, dest, opts);
|
|
43712
44561
|
}
|
|
43713
44562
|
|
|
43714
44563
|
function createUnprojectedGraticule(opts) {
|
|
43715
|
-
var src = parseCrsString('wgs84');
|
|
44564
|
+
var src = parseCrsString$1('wgs84');
|
|
43716
44565
|
var graticule = importGeoJSON(createGraticule(src, false, opts));
|
|
43717
44566
|
return graticule;
|
|
43718
44567
|
}
|
|
43719
44568
|
|
|
43720
44569
|
function createProjectedGraticule(dest, opts) {
|
|
43721
|
-
var src = parseCrsString('wgs84');
|
|
44570
|
+
var src = parseCrsString$1('wgs84');
|
|
43722
44571
|
var outline = getOutlineDataset(src, dest, {});
|
|
43723
44572
|
var graticule = importGeoJSON(createGraticule(dest, !!outline, opts));
|
|
43724
44573
|
projectDataset(graticule, src, dest, {no_clip: false}); // TODO: densify?
|
|
@@ -46752,7 +47601,7 @@ ${svg}
|
|
|
46752
47601
|
stop$1('Missing required radius parameter.');
|
|
46753
47602
|
}
|
|
46754
47603
|
var cp = opts.center || [0, 0];
|
|
46755
|
-
var radius = opts.radius || getCircleRadiusFromAngle(parseCrsString('wgs84'), opts.radius_angle);
|
|
47604
|
+
var radius = opts.radius || getCircleRadiusFromAngle(parseCrsString$1('wgs84'), opts.radius_angle);
|
|
46756
47605
|
return getCircleGeoJSON(cp, radius, null, {geometry_type : opts.geometry || 'polygon'});
|
|
46757
47606
|
}
|
|
46758
47607
|
|
|
@@ -49343,7 +50192,7 @@ ${svg}
|
|
|
49343
50192
|
});
|
|
49344
50193
|
}
|
|
49345
50194
|
|
|
49346
|
-
var version = "0.6.
|
|
50195
|
+
var version = "0.6.117";
|
|
49347
50196
|
|
|
49348
50197
|
// Parse command line args into commands and run them
|
|
49349
50198
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|