mapshaper 0.5.71 → 0.5.72
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/CHANGELOG.md +7 -1
- package/mapshaper.js +67 -7
- package/package.json +3 -3
- package/www/mapshaper.js +67 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
v0.5.72
|
|
2
|
+
* Improved performance of non-adjacent polygon coloring using DSATUR algorithm.
|
|
3
|
+
|
|
4
|
+
v0.5.71
|
|
5
|
+
* Added -classify non-adjacent option, for assigning non-adjacent colors to a polygon layer in a randomish pattern.
|
|
6
|
+
|
|
1
7
|
v0.5.70
|
|
2
8
|
* Added -join duplication option, which duplicates features in the target layer when many-to-one joins occur.
|
|
3
9
|
|
|
@@ -23,7 +29,7 @@ v0.5.64
|
|
|
23
29
|
* Bug fixes
|
|
24
30
|
|
|
25
31
|
v0.5.63
|
|
26
|
-
* Added -o decimal-comma
|
|
32
|
+
* Added -o decimal-comma option, for exporting CSV numbers with decimal commas.
|
|
27
33
|
* Fix for issue #497 (error erasing with overlapping polygons).
|
|
28
34
|
|
|
29
35
|
v0.5.62
|
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.5.
|
|
3
|
+
var VERSION = "0.5.72";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -28208,6 +28208,8 @@ ${svg}
|
|
|
28208
28208
|
findPairsOfNeighbors: findPairsOfNeighbors
|
|
28209
28209
|
});
|
|
28210
28210
|
|
|
28211
|
+
var BALANCE_COLORS = true;
|
|
28212
|
+
|
|
28211
28213
|
function getNonAdjacentClassifier(lyr, dataset, colors) {
|
|
28212
28214
|
requirePolygonLayer(lyr);
|
|
28213
28215
|
var getNeighbors = getNeighborLookupFunction(lyr, dataset.arcs);
|
|
@@ -28215,25 +28217,30 @@ ${svg}
|
|
|
28215
28217
|
var data = utils.range(getFeatureCount(lyr)).map(function(shpId) {
|
|
28216
28218
|
var nabes = getNeighbors(shpId) || [];
|
|
28217
28219
|
return {
|
|
28220
|
+
// id: shpId,
|
|
28218
28221
|
nabes: nabes,
|
|
28219
|
-
|
|
28220
|
-
|
|
28222
|
+
colorId: -1,
|
|
28223
|
+
nabeColors: [],
|
|
28224
|
+
uncolored: nabes.length,
|
|
28225
|
+
saturation: 0,
|
|
28226
|
+
saturation2: 0
|
|
28221
28227
|
};
|
|
28222
28228
|
});
|
|
28223
28229
|
var getSortedColorIds = getUpdateFunction(colors.length);
|
|
28224
28230
|
var colorIds = getSortedColorIds();
|
|
28225
28231
|
// Sort adjacency data by number of neighbors in descending order
|
|
28226
|
-
var
|
|
28227
|
-
utils.sortOn(sorted, 'n', false);
|
|
28232
|
+
var iter = getNodeIterator(data);
|
|
28228
28233
|
// Assign colors, starting with polygons with the largest number of neighbors
|
|
28229
|
-
|
|
28234
|
+
iter.forEach(function(d) {
|
|
28230
28235
|
var colorId = pickColor(d, data, colorIds);
|
|
28231
28236
|
if (colorId == -1) {
|
|
28232
28237
|
errorCount++;
|
|
28233
28238
|
colorId = colorIds[0];
|
|
28234
28239
|
}
|
|
28235
28240
|
d.colorId = colorId;
|
|
28236
|
-
|
|
28241
|
+
if (BALANCE_COLORS) {
|
|
28242
|
+
colorIds = getSortedColorIds(colorId);
|
|
28243
|
+
}
|
|
28237
28244
|
});
|
|
28238
28245
|
|
|
28239
28246
|
if (errorCount > 0) {
|
|
@@ -28244,6 +28251,59 @@ ${svg}
|
|
|
28244
28251
|
};
|
|
28245
28252
|
}
|
|
28246
28253
|
|
|
28254
|
+
function getNodeIterator(data) {
|
|
28255
|
+
var sorted = data.concat();
|
|
28256
|
+
utils.sortOn(sorted, 'uncolored', true);
|
|
28257
|
+
function forEach(cb) {
|
|
28258
|
+
var item;
|
|
28259
|
+
while(sorted.length > 0) {
|
|
28260
|
+
item = sorted.pop();
|
|
28261
|
+
cb(item);
|
|
28262
|
+
updateNeighbors(item, sorted, data);
|
|
28263
|
+
}
|
|
28264
|
+
}
|
|
28265
|
+
|
|
28266
|
+
return {
|
|
28267
|
+
forEach: forEach
|
|
28268
|
+
};
|
|
28269
|
+
}
|
|
28270
|
+
|
|
28271
|
+
function updateNeighbors(item, sorted, data) {
|
|
28272
|
+
var nabe;
|
|
28273
|
+
var ids = item.nabes;
|
|
28274
|
+
for (var i=0; i<ids.length; i++) {
|
|
28275
|
+
nabe = data[ids[i]];
|
|
28276
|
+
if (nabe.colorId > -1) continue;
|
|
28277
|
+
updateNeighbor(nabe, item.colorId, sorted);
|
|
28278
|
+
}
|
|
28279
|
+
}
|
|
28280
|
+
|
|
28281
|
+
function updateNeighbor(a, colorId, sorted) {
|
|
28282
|
+
var i = sorted.indexOf(a); // could optimize with a binary search
|
|
28283
|
+
var n = sorted.length;
|
|
28284
|
+
var b;
|
|
28285
|
+
if (i == -1) {
|
|
28286
|
+
error('Indexing error');
|
|
28287
|
+
}
|
|
28288
|
+
a.uncolored--;
|
|
28289
|
+
a.saturation2++;
|
|
28290
|
+
if (!a.nabeColors.includes(colorId)) {
|
|
28291
|
+
a.saturation++;
|
|
28292
|
+
a.nabeColors.push(colorId);
|
|
28293
|
+
}
|
|
28294
|
+
// insertion sort with a stopping condition
|
|
28295
|
+
while (++i < n) {
|
|
28296
|
+
b = sorted[i];
|
|
28297
|
+
// standard dsatur
|
|
28298
|
+
if (a.saturation < b.saturation || a.saturation == b.saturation && a.uncolored > b.uncolored) break;
|
|
28299
|
+
// based on 4-color tests with counties and zipcodes, this condition adds a bit of strength
|
|
28300
|
+
if (a.saturation == b.saturation && a.uncolored == b.uncolored && a.saturation2 < b.saturation2) break; // 332
|
|
28301
|
+
sorted[i-1] = b;
|
|
28302
|
+
sorted[i] = a;
|
|
28303
|
+
}
|
|
28304
|
+
}
|
|
28305
|
+
|
|
28306
|
+
|
|
28247
28307
|
// Pick the id of a color that is not shared with a neighboring polygon
|
|
28248
28308
|
function pickColor(d, data, colorIds) {
|
|
28249
28309
|
var candidateId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapshaper",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.72",
|
|
4
4
|
"description": "A tool for editing vector datasets for mapping and GIS.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shapefile",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"test": "mocha -r esm --parallel --jobs 4 --check-leaks -R dot",
|
|
26
26
|
"build": "rollup --config",
|
|
27
|
-
"prepublishOnly": "npm test",
|
|
28
|
-
"postpublish": "./
|
|
27
|
+
"prepublishOnly": "npm test; ./pre-publish",
|
|
28
|
+
"postpublish": "./release_web_ui; ./release_github_version",
|
|
29
29
|
"browserify_old": "browserify -r sync-request -r mproj -r buffer -r iconv-lite -r fs -r flatbush -r rw -r path -r d3-scale-chromatic -r d3-color -r d3-interpolate -o www/modules.js",
|
|
30
30
|
"browserify": "browserify -r sync-request -r mproj -r buffer -r iconv-lite -r fs -r flatbush -r rw -r path -r d3-scale-chromatic -r d3-color -r d3-interpolate -r kdbush -o www/modules.js",
|
|
31
31
|
"watch": "rollup --config --watch",
|
package/www/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.5.
|
|
3
|
+
var VERSION = "0.5.72";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -28208,6 +28208,8 @@ ${svg}
|
|
|
28208
28208
|
findPairsOfNeighbors: findPairsOfNeighbors
|
|
28209
28209
|
});
|
|
28210
28210
|
|
|
28211
|
+
var BALANCE_COLORS = true;
|
|
28212
|
+
|
|
28211
28213
|
function getNonAdjacentClassifier(lyr, dataset, colors) {
|
|
28212
28214
|
requirePolygonLayer(lyr);
|
|
28213
28215
|
var getNeighbors = getNeighborLookupFunction(lyr, dataset.arcs);
|
|
@@ -28215,25 +28217,30 @@ ${svg}
|
|
|
28215
28217
|
var data = utils.range(getFeatureCount(lyr)).map(function(shpId) {
|
|
28216
28218
|
var nabes = getNeighbors(shpId) || [];
|
|
28217
28219
|
return {
|
|
28220
|
+
// id: shpId,
|
|
28218
28221
|
nabes: nabes,
|
|
28219
|
-
|
|
28220
|
-
|
|
28222
|
+
colorId: -1,
|
|
28223
|
+
nabeColors: [],
|
|
28224
|
+
uncolored: nabes.length,
|
|
28225
|
+
saturation: 0,
|
|
28226
|
+
saturation2: 0
|
|
28221
28227
|
};
|
|
28222
28228
|
});
|
|
28223
28229
|
var getSortedColorIds = getUpdateFunction(colors.length);
|
|
28224
28230
|
var colorIds = getSortedColorIds();
|
|
28225
28231
|
// Sort adjacency data by number of neighbors in descending order
|
|
28226
|
-
var
|
|
28227
|
-
utils.sortOn(sorted, 'n', false);
|
|
28232
|
+
var iter = getNodeIterator(data);
|
|
28228
28233
|
// Assign colors, starting with polygons with the largest number of neighbors
|
|
28229
|
-
|
|
28234
|
+
iter.forEach(function(d) {
|
|
28230
28235
|
var colorId = pickColor(d, data, colorIds);
|
|
28231
28236
|
if (colorId == -1) {
|
|
28232
28237
|
errorCount++;
|
|
28233
28238
|
colorId = colorIds[0];
|
|
28234
28239
|
}
|
|
28235
28240
|
d.colorId = colorId;
|
|
28236
|
-
|
|
28241
|
+
if (BALANCE_COLORS) {
|
|
28242
|
+
colorIds = getSortedColorIds(colorId);
|
|
28243
|
+
}
|
|
28237
28244
|
});
|
|
28238
28245
|
|
|
28239
28246
|
if (errorCount > 0) {
|
|
@@ -28244,6 +28251,59 @@ ${svg}
|
|
|
28244
28251
|
};
|
|
28245
28252
|
}
|
|
28246
28253
|
|
|
28254
|
+
function getNodeIterator(data) {
|
|
28255
|
+
var sorted = data.concat();
|
|
28256
|
+
utils.sortOn(sorted, 'uncolored', true);
|
|
28257
|
+
function forEach(cb) {
|
|
28258
|
+
var item;
|
|
28259
|
+
while(sorted.length > 0) {
|
|
28260
|
+
item = sorted.pop();
|
|
28261
|
+
cb(item);
|
|
28262
|
+
updateNeighbors(item, sorted, data);
|
|
28263
|
+
}
|
|
28264
|
+
}
|
|
28265
|
+
|
|
28266
|
+
return {
|
|
28267
|
+
forEach: forEach
|
|
28268
|
+
};
|
|
28269
|
+
}
|
|
28270
|
+
|
|
28271
|
+
function updateNeighbors(item, sorted, data) {
|
|
28272
|
+
var nabe;
|
|
28273
|
+
var ids = item.nabes;
|
|
28274
|
+
for (var i=0; i<ids.length; i++) {
|
|
28275
|
+
nabe = data[ids[i]];
|
|
28276
|
+
if (nabe.colorId > -1) continue;
|
|
28277
|
+
updateNeighbor(nabe, item.colorId, sorted);
|
|
28278
|
+
}
|
|
28279
|
+
}
|
|
28280
|
+
|
|
28281
|
+
function updateNeighbor(a, colorId, sorted) {
|
|
28282
|
+
var i = sorted.indexOf(a); // could optimize with a binary search
|
|
28283
|
+
var n = sorted.length;
|
|
28284
|
+
var b;
|
|
28285
|
+
if (i == -1) {
|
|
28286
|
+
error('Indexing error');
|
|
28287
|
+
}
|
|
28288
|
+
a.uncolored--;
|
|
28289
|
+
a.saturation2++;
|
|
28290
|
+
if (!a.nabeColors.includes(colorId)) {
|
|
28291
|
+
a.saturation++;
|
|
28292
|
+
a.nabeColors.push(colorId);
|
|
28293
|
+
}
|
|
28294
|
+
// insertion sort with a stopping condition
|
|
28295
|
+
while (++i < n) {
|
|
28296
|
+
b = sorted[i];
|
|
28297
|
+
// standard dsatur
|
|
28298
|
+
if (a.saturation < b.saturation || a.saturation == b.saturation && a.uncolored > b.uncolored) break;
|
|
28299
|
+
// based on 4-color tests with counties and zipcodes, this condition adds a bit of strength
|
|
28300
|
+
if (a.saturation == b.saturation && a.uncolored == b.uncolored && a.saturation2 < b.saturation2) break; // 332
|
|
28301
|
+
sorted[i-1] = b;
|
|
28302
|
+
sorted[i] = a;
|
|
28303
|
+
}
|
|
28304
|
+
}
|
|
28305
|
+
|
|
28306
|
+
|
|
28247
28307
|
// Pick the id of a color that is not shared with a neighboring polygon
|
|
28248
28308
|
function pickColor(d, data, colorIds) {
|
|
28249
28309
|
var candidateId;
|