mapshaper 0.5.84 → 0.5.85
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 +3 -0
- package/mapshaper.js +87 -47
- package/package.json +1 -1
- package/www/mapshaper.js +87 -47
package/CHANGELOG.md
CHANGED
package/mapshaper.js
CHANGED
|
@@ -13712,6 +13712,9 @@
|
|
|
13712
13712
|
flipped: 'boolean',
|
|
13713
13713
|
rotated: 'boolean',
|
|
13714
13714
|
direction: 'number',
|
|
13715
|
+
sides: 'number', // polygons and stars
|
|
13716
|
+
points: 'number', // polygons and stars
|
|
13717
|
+
anchor: null, // arrows; takes start, middle, end
|
|
13715
13718
|
'head-angle': 'number',
|
|
13716
13719
|
'head-width': 'number',
|
|
13717
13720
|
'head-length': 'number',
|
|
@@ -20111,10 +20114,11 @@ ${svg}
|
|
|
20111
20114
|
type: 'distance'
|
|
20112
20115
|
})
|
|
20113
20116
|
.option('sides', {
|
|
20114
|
-
describe: 'sides of a polygon
|
|
20117
|
+
describe: 'number of sides of a polygon symbol',
|
|
20115
20118
|
type: 'number'
|
|
20116
20119
|
})
|
|
20117
20120
|
.option('orientation', {
|
|
20121
|
+
// TODO: removed (replaced by flipped and rotated)
|
|
20118
20122
|
// describe: 'use orientation=b for a rotated or flipped orientation'
|
|
20119
20123
|
})
|
|
20120
20124
|
.option('flipped', {
|
|
@@ -20128,8 +20132,8 @@ ${svg}
|
|
|
20128
20132
|
.option('rotation', {
|
|
20129
20133
|
describe: 'rotation of symbol in degrees'
|
|
20130
20134
|
})
|
|
20131
|
-
.option('
|
|
20132
|
-
|
|
20135
|
+
.option('points', {
|
|
20136
|
+
describe: '(star) number of points'
|
|
20133
20137
|
})
|
|
20134
20138
|
.option('point-ratio', {
|
|
20135
20139
|
old_alias: 'star-ratio',
|
|
@@ -20183,6 +20187,9 @@ ${svg}
|
|
|
20183
20187
|
describe: '(arrow) min ratio of stem to total length',
|
|
20184
20188
|
type: 'number'
|
|
20185
20189
|
})
|
|
20190
|
+
.option('anchor', {
|
|
20191
|
+
describe: '(arrow) takes one of: start, middle, end (default is start)'
|
|
20192
|
+
})
|
|
20186
20193
|
.option('stroke', {})
|
|
20187
20194
|
.option('stroke-width', {})
|
|
20188
20195
|
.option('fill', {
|
|
@@ -38075,33 +38082,6 @@ ${svg}
|
|
|
38075
38082
|
// return [a[0] + b[0], a[1] + b[1]];
|
|
38076
38083
|
// }
|
|
38077
38084
|
|
|
38078
|
-
function getFilledArrowCoords(d) {
|
|
38079
|
-
var direction = d.rotation || d.direction || 0,
|
|
38080
|
-
stemTaper = d['stem-taper'] || 0,
|
|
38081
|
-
stemCurve = d['stem-curve'] || 0,
|
|
38082
|
-
size = calcArrowSize(d);
|
|
38083
|
-
|
|
38084
|
-
if (!size) return null;
|
|
38085
|
-
|
|
38086
|
-
var headDx = size.headWidth / 2,
|
|
38087
|
-
stemDx = size.stemWidth / 2,
|
|
38088
|
-
baseDx = stemDx * (1 - stemTaper),
|
|
38089
|
-
coords;
|
|
38090
|
-
|
|
38091
|
-
if (!stemCurve || Math.abs(stemCurve) > 90) {
|
|
38092
|
-
coords = calcStraightArrowCoords(size.stemLen, size.headLen, stemDx, headDx, baseDx);
|
|
38093
|
-
} else {
|
|
38094
|
-
if (direction > 0) stemCurve = -stemCurve;
|
|
38095
|
-
coords = getCurvedArrowCoords(size.stemLen, size.headLen, stemCurve, stemDx, headDx, baseDx);
|
|
38096
|
-
}
|
|
38097
|
-
|
|
38098
|
-
rotateCoords(coords, direction);
|
|
38099
|
-
if (d.flipped) {
|
|
38100
|
-
flipY(coords);
|
|
38101
|
-
}
|
|
38102
|
-
return [coords];
|
|
38103
|
-
}
|
|
38104
|
-
|
|
38105
38085
|
function calcStraightArrowCoords(stemLen, headLen, stemDx, headDx, baseDx) {
|
|
38106
38086
|
return [[baseDx, 0], [stemDx, stemLen], [headDx, stemLen], [0, stemLen + headLen],
|
|
38107
38087
|
[-headDx, stemLen], [-stemDx, stemLen], [-baseDx, 0], [baseDx, 0]];
|
|
@@ -38168,21 +38148,53 @@ ${svg}
|
|
|
38168
38148
|
return 1 / Math.tan(Math.PI * headAngle / 180 / 2) / 2;
|
|
38169
38149
|
}
|
|
38170
38150
|
|
|
38171
|
-
function
|
|
38151
|
+
function getFilledArrowCoords(d) {
|
|
38152
|
+
var direction = d.rotation || d.direction || 0,
|
|
38153
|
+
stemTaper = d['stem-taper'] || 0,
|
|
38154
|
+
curvature = d['stem-curve'] || 0,
|
|
38155
|
+
size = calcArrowSize(d);
|
|
38156
|
+
if (!size) return null;
|
|
38157
|
+
var stemLen = size.stemLen,
|
|
38158
|
+
headLen = size.headLen,
|
|
38159
|
+
headDx = size.headWidth / 2,
|
|
38160
|
+
stemDx = size.stemWidth / 2,
|
|
38161
|
+
baseDx = stemDx * (1 - stemTaper),
|
|
38162
|
+
head, stem, coords, dx, dy;
|
|
38163
|
+
|
|
38164
|
+
if (curvature) {
|
|
38165
|
+
if (direction > 0) curvature = -curvature;
|
|
38166
|
+
var theta = Math.abs(curvature) / 180 * Math.PI;
|
|
38167
|
+
var sign = curvature > 0 ? 1 : -1;
|
|
38168
|
+
var ax = baseDx * Math.cos(theta); // rotate arrow base
|
|
38169
|
+
var ay = baseDx * Math.sin(theta) * -sign;
|
|
38170
|
+
dx = stemLen * Math.sin(theta / 2) * sign;
|
|
38171
|
+
dy = stemLen * Math.cos(theta / 2);
|
|
38172
|
+
var leftStem = getCurvedStemCoords(-ax, -ay, -stemDx + dx, dy, theta);
|
|
38173
|
+
var rightStem = getCurvedStemCoords(ax, ay, stemDx + dx, dy, theta);
|
|
38174
|
+
stem = leftStem.concat(rightStem.reverse());
|
|
38175
|
+
|
|
38176
|
+
} else {
|
|
38177
|
+
dx = 0;
|
|
38178
|
+
dy = stemLen;
|
|
38179
|
+
stem = [[-baseDx, 0], [baseDx, 0], [baseDx, 0]];
|
|
38180
|
+
}
|
|
38181
|
+
|
|
38172
38182
|
// coordinates go counter clockwise, starting from the leftmost head coordinate
|
|
38173
|
-
|
|
38174
|
-
|
|
38175
|
-
|
|
38176
|
-
|
|
38177
|
-
|
|
38178
|
-
|
|
38179
|
-
|
|
38180
|
-
|
|
38181
|
-
|
|
38182
|
-
|
|
38183
|
-
|
|
38184
|
-
|
|
38185
|
-
|
|
38183
|
+
head = [[stemDx + dx, dy], [headDx + dx, dy],
|
|
38184
|
+
[dx, headLen + dy], [-headDx + dx, dy], [-stemDx + dx, dy]];
|
|
38185
|
+
|
|
38186
|
+
coords = stem.concat(head);
|
|
38187
|
+
if (d.anchor == 'end') {
|
|
38188
|
+
scaleAndShiftCoords(coords, 1, [-dx, -dy - headLen]);
|
|
38189
|
+
} else if (d.anchor == 'middle') {
|
|
38190
|
+
scaleAndShiftCoords(coords, 1, [-dx/2, (-dy - headLen)/2]);
|
|
38191
|
+
}
|
|
38192
|
+
|
|
38193
|
+
rotateCoords(coords, direction);
|
|
38194
|
+
if (d.flipped) {
|
|
38195
|
+
flipY(coords);
|
|
38196
|
+
}
|
|
38197
|
+
return [coords];
|
|
38186
38198
|
}
|
|
38187
38199
|
|
|
38188
38200
|
// ax, ay: point on the base
|
|
@@ -38219,6 +38231,30 @@ ${svg}
|
|
|
38219
38231
|
return coords;
|
|
38220
38232
|
}
|
|
38221
38233
|
|
|
38234
|
+
function getMinorRadius(points) {
|
|
38235
|
+
var innerAngle = 360 / points;
|
|
38236
|
+
var pointAngle = getDefaultPointAngle(points);
|
|
38237
|
+
var thetaA = Math.PI / 180 * innerAngle / 2;
|
|
38238
|
+
var thetaB = Math.PI / 180 * pointAngle / 2;
|
|
38239
|
+
var a = Math.tan(thetaB) / (Math.tan(thetaB) + Math.tan(thetaA));
|
|
38240
|
+
var c = a / Math.cos(thetaA);
|
|
38241
|
+
return c;
|
|
38242
|
+
}
|
|
38243
|
+
|
|
38244
|
+
|
|
38245
|
+
function getPointAngle(points, skip) {
|
|
38246
|
+
var unitAngle = 360 / points;
|
|
38247
|
+
var centerAngle = unitAngle * (skip + 1);
|
|
38248
|
+
return 180 - centerAngle;
|
|
38249
|
+
}
|
|
38250
|
+
|
|
38251
|
+
function getDefaultPointAngle(points) {
|
|
38252
|
+
var minSkip = 1;
|
|
38253
|
+
var maxSkip = Math.ceil(points / 2) - 2;
|
|
38254
|
+
var skip = Math.floor((maxSkip + minSkip) / 2);
|
|
38255
|
+
return getPointAngle(points, skip);
|
|
38256
|
+
}
|
|
38257
|
+
|
|
38222
38258
|
// sides: e.g. 5-pointed star has 10 sides
|
|
38223
38259
|
// radius: distance from center to point
|
|
38224
38260
|
//
|
|
@@ -38228,8 +38264,12 @@ ${svg}
|
|
|
38228
38264
|
var type = d.type;
|
|
38229
38265
|
var sides = +d.sides || getDefaultSides(type);
|
|
38230
38266
|
var isStar = type == 'star';
|
|
38231
|
-
if (isStar &&
|
|
38232
|
-
|
|
38267
|
+
if (isStar && d.points > 0) {
|
|
38268
|
+
sides = d.points * 2;
|
|
38269
|
+
}
|
|
38270
|
+
var starRatio = isStar ? d.star_ratio || getMinorRadius(sides / 2) : 0;
|
|
38271
|
+
if (isStar && (sides < 10 || sides % 2 !== 0)) {
|
|
38272
|
+
stop(`Invalid number of points for a star (${sides / 2})`);
|
|
38233
38273
|
} else if (sides >= 3 === false) {
|
|
38234
38274
|
stop(`Invalid number of sides (${sides})`);
|
|
38235
38275
|
}
|
|
@@ -38244,7 +38284,7 @@ ${svg}
|
|
|
38244
38284
|
even = i % 2 == 0;
|
|
38245
38285
|
len = radius;
|
|
38246
38286
|
if (isStar && even) {
|
|
38247
|
-
len *=
|
|
38287
|
+
len *= starRatio;
|
|
38248
38288
|
}
|
|
38249
38289
|
theta = (i + b) * angle % 360;
|
|
38250
38290
|
coords.push(getPlanarSegmentEndpoint(0, 0, theta, len));
|
package/package.json
CHANGED
package/www/mapshaper.js
CHANGED
|
@@ -13712,6 +13712,9 @@
|
|
|
13712
13712
|
flipped: 'boolean',
|
|
13713
13713
|
rotated: 'boolean',
|
|
13714
13714
|
direction: 'number',
|
|
13715
|
+
sides: 'number', // polygons and stars
|
|
13716
|
+
points: 'number', // polygons and stars
|
|
13717
|
+
anchor: null, // arrows; takes start, middle, end
|
|
13715
13718
|
'head-angle': 'number',
|
|
13716
13719
|
'head-width': 'number',
|
|
13717
13720
|
'head-length': 'number',
|
|
@@ -20111,10 +20114,11 @@ ${svg}
|
|
|
20111
20114
|
type: 'distance'
|
|
20112
20115
|
})
|
|
20113
20116
|
.option('sides', {
|
|
20114
|
-
describe: 'sides of a polygon
|
|
20117
|
+
describe: 'number of sides of a polygon symbol',
|
|
20115
20118
|
type: 'number'
|
|
20116
20119
|
})
|
|
20117
20120
|
.option('orientation', {
|
|
20121
|
+
// TODO: removed (replaced by flipped and rotated)
|
|
20118
20122
|
// describe: 'use orientation=b for a rotated or flipped orientation'
|
|
20119
20123
|
})
|
|
20120
20124
|
.option('flipped', {
|
|
@@ -20128,8 +20132,8 @@ ${svg}
|
|
|
20128
20132
|
.option('rotation', {
|
|
20129
20133
|
describe: 'rotation of symbol in degrees'
|
|
20130
20134
|
})
|
|
20131
|
-
.option('
|
|
20132
|
-
|
|
20135
|
+
.option('points', {
|
|
20136
|
+
describe: '(star) number of points'
|
|
20133
20137
|
})
|
|
20134
20138
|
.option('point-ratio', {
|
|
20135
20139
|
old_alias: 'star-ratio',
|
|
@@ -20183,6 +20187,9 @@ ${svg}
|
|
|
20183
20187
|
describe: '(arrow) min ratio of stem to total length',
|
|
20184
20188
|
type: 'number'
|
|
20185
20189
|
})
|
|
20190
|
+
.option('anchor', {
|
|
20191
|
+
describe: '(arrow) takes one of: start, middle, end (default is start)'
|
|
20192
|
+
})
|
|
20186
20193
|
.option('stroke', {})
|
|
20187
20194
|
.option('stroke-width', {})
|
|
20188
20195
|
.option('fill', {
|
|
@@ -38075,33 +38082,6 @@ ${svg}
|
|
|
38075
38082
|
// return [a[0] + b[0], a[1] + b[1]];
|
|
38076
38083
|
// }
|
|
38077
38084
|
|
|
38078
|
-
function getFilledArrowCoords(d) {
|
|
38079
|
-
var direction = d.rotation || d.direction || 0,
|
|
38080
|
-
stemTaper = d['stem-taper'] || 0,
|
|
38081
|
-
stemCurve = d['stem-curve'] || 0,
|
|
38082
|
-
size = calcArrowSize(d);
|
|
38083
|
-
|
|
38084
|
-
if (!size) return null;
|
|
38085
|
-
|
|
38086
|
-
var headDx = size.headWidth / 2,
|
|
38087
|
-
stemDx = size.stemWidth / 2,
|
|
38088
|
-
baseDx = stemDx * (1 - stemTaper),
|
|
38089
|
-
coords;
|
|
38090
|
-
|
|
38091
|
-
if (!stemCurve || Math.abs(stemCurve) > 90) {
|
|
38092
|
-
coords = calcStraightArrowCoords(size.stemLen, size.headLen, stemDx, headDx, baseDx);
|
|
38093
|
-
} else {
|
|
38094
|
-
if (direction > 0) stemCurve = -stemCurve;
|
|
38095
|
-
coords = getCurvedArrowCoords(size.stemLen, size.headLen, stemCurve, stemDx, headDx, baseDx);
|
|
38096
|
-
}
|
|
38097
|
-
|
|
38098
|
-
rotateCoords(coords, direction);
|
|
38099
|
-
if (d.flipped) {
|
|
38100
|
-
flipY(coords);
|
|
38101
|
-
}
|
|
38102
|
-
return [coords];
|
|
38103
|
-
}
|
|
38104
|
-
|
|
38105
38085
|
function calcStraightArrowCoords(stemLen, headLen, stemDx, headDx, baseDx) {
|
|
38106
38086
|
return [[baseDx, 0], [stemDx, stemLen], [headDx, stemLen], [0, stemLen + headLen],
|
|
38107
38087
|
[-headDx, stemLen], [-stemDx, stemLen], [-baseDx, 0], [baseDx, 0]];
|
|
@@ -38168,21 +38148,53 @@ ${svg}
|
|
|
38168
38148
|
return 1 / Math.tan(Math.PI * headAngle / 180 / 2) / 2;
|
|
38169
38149
|
}
|
|
38170
38150
|
|
|
38171
|
-
function
|
|
38151
|
+
function getFilledArrowCoords(d) {
|
|
38152
|
+
var direction = d.rotation || d.direction || 0,
|
|
38153
|
+
stemTaper = d['stem-taper'] || 0,
|
|
38154
|
+
curvature = d['stem-curve'] || 0,
|
|
38155
|
+
size = calcArrowSize(d);
|
|
38156
|
+
if (!size) return null;
|
|
38157
|
+
var stemLen = size.stemLen,
|
|
38158
|
+
headLen = size.headLen,
|
|
38159
|
+
headDx = size.headWidth / 2,
|
|
38160
|
+
stemDx = size.stemWidth / 2,
|
|
38161
|
+
baseDx = stemDx * (1 - stemTaper),
|
|
38162
|
+
head, stem, coords, dx, dy;
|
|
38163
|
+
|
|
38164
|
+
if (curvature) {
|
|
38165
|
+
if (direction > 0) curvature = -curvature;
|
|
38166
|
+
var theta = Math.abs(curvature) / 180 * Math.PI;
|
|
38167
|
+
var sign = curvature > 0 ? 1 : -1;
|
|
38168
|
+
var ax = baseDx * Math.cos(theta); // rotate arrow base
|
|
38169
|
+
var ay = baseDx * Math.sin(theta) * -sign;
|
|
38170
|
+
dx = stemLen * Math.sin(theta / 2) * sign;
|
|
38171
|
+
dy = stemLen * Math.cos(theta / 2);
|
|
38172
|
+
var leftStem = getCurvedStemCoords(-ax, -ay, -stemDx + dx, dy, theta);
|
|
38173
|
+
var rightStem = getCurvedStemCoords(ax, ay, stemDx + dx, dy, theta);
|
|
38174
|
+
stem = leftStem.concat(rightStem.reverse());
|
|
38175
|
+
|
|
38176
|
+
} else {
|
|
38177
|
+
dx = 0;
|
|
38178
|
+
dy = stemLen;
|
|
38179
|
+
stem = [[-baseDx, 0], [baseDx, 0], [baseDx, 0]];
|
|
38180
|
+
}
|
|
38181
|
+
|
|
38172
38182
|
// coordinates go counter clockwise, starting from the leftmost head coordinate
|
|
38173
|
-
|
|
38174
|
-
|
|
38175
|
-
|
|
38176
|
-
|
|
38177
|
-
|
|
38178
|
-
|
|
38179
|
-
|
|
38180
|
-
|
|
38181
|
-
|
|
38182
|
-
|
|
38183
|
-
|
|
38184
|
-
|
|
38185
|
-
|
|
38183
|
+
head = [[stemDx + dx, dy], [headDx + dx, dy],
|
|
38184
|
+
[dx, headLen + dy], [-headDx + dx, dy], [-stemDx + dx, dy]];
|
|
38185
|
+
|
|
38186
|
+
coords = stem.concat(head);
|
|
38187
|
+
if (d.anchor == 'end') {
|
|
38188
|
+
scaleAndShiftCoords(coords, 1, [-dx, -dy - headLen]);
|
|
38189
|
+
} else if (d.anchor == 'middle') {
|
|
38190
|
+
scaleAndShiftCoords(coords, 1, [-dx/2, (-dy - headLen)/2]);
|
|
38191
|
+
}
|
|
38192
|
+
|
|
38193
|
+
rotateCoords(coords, direction);
|
|
38194
|
+
if (d.flipped) {
|
|
38195
|
+
flipY(coords);
|
|
38196
|
+
}
|
|
38197
|
+
return [coords];
|
|
38186
38198
|
}
|
|
38187
38199
|
|
|
38188
38200
|
// ax, ay: point on the base
|
|
@@ -38219,6 +38231,30 @@ ${svg}
|
|
|
38219
38231
|
return coords;
|
|
38220
38232
|
}
|
|
38221
38233
|
|
|
38234
|
+
function getMinorRadius(points) {
|
|
38235
|
+
var innerAngle = 360 / points;
|
|
38236
|
+
var pointAngle = getDefaultPointAngle(points);
|
|
38237
|
+
var thetaA = Math.PI / 180 * innerAngle / 2;
|
|
38238
|
+
var thetaB = Math.PI / 180 * pointAngle / 2;
|
|
38239
|
+
var a = Math.tan(thetaB) / (Math.tan(thetaB) + Math.tan(thetaA));
|
|
38240
|
+
var c = a / Math.cos(thetaA);
|
|
38241
|
+
return c;
|
|
38242
|
+
}
|
|
38243
|
+
|
|
38244
|
+
|
|
38245
|
+
function getPointAngle(points, skip) {
|
|
38246
|
+
var unitAngle = 360 / points;
|
|
38247
|
+
var centerAngle = unitAngle * (skip + 1);
|
|
38248
|
+
return 180 - centerAngle;
|
|
38249
|
+
}
|
|
38250
|
+
|
|
38251
|
+
function getDefaultPointAngle(points) {
|
|
38252
|
+
var minSkip = 1;
|
|
38253
|
+
var maxSkip = Math.ceil(points / 2) - 2;
|
|
38254
|
+
var skip = Math.floor((maxSkip + minSkip) / 2);
|
|
38255
|
+
return getPointAngle(points, skip);
|
|
38256
|
+
}
|
|
38257
|
+
|
|
38222
38258
|
// sides: e.g. 5-pointed star has 10 sides
|
|
38223
38259
|
// radius: distance from center to point
|
|
38224
38260
|
//
|
|
@@ -38228,8 +38264,12 @@ ${svg}
|
|
|
38228
38264
|
var type = d.type;
|
|
38229
38265
|
var sides = +d.sides || getDefaultSides(type);
|
|
38230
38266
|
var isStar = type == 'star';
|
|
38231
|
-
if (isStar &&
|
|
38232
|
-
|
|
38267
|
+
if (isStar && d.points > 0) {
|
|
38268
|
+
sides = d.points * 2;
|
|
38269
|
+
}
|
|
38270
|
+
var starRatio = isStar ? d.star_ratio || getMinorRadius(sides / 2) : 0;
|
|
38271
|
+
if (isStar && (sides < 10 || sides % 2 !== 0)) {
|
|
38272
|
+
stop(`Invalid number of points for a star (${sides / 2})`);
|
|
38233
38273
|
} else if (sides >= 3 === false) {
|
|
38234
38274
|
stop(`Invalid number of sides (${sides})`);
|
|
38235
38275
|
}
|
|
@@ -38244,7 +38284,7 @@ ${svg}
|
|
|
38244
38284
|
even = i % 2 == 0;
|
|
38245
38285
|
len = radius;
|
|
38246
38286
|
if (isStar && even) {
|
|
38247
|
-
len *=
|
|
38287
|
+
len *= starRatio;
|
|
38248
38288
|
}
|
|
38249
38289
|
theta = (i + b) * angle % 360;
|
|
38250
38290
|
coords.push(getPlanarSegmentEndpoint(0, 0, theta, len));
|