mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 21:48:20 +02:00
Support transitioned circularize action
This commit is contained in:
@@ -14,8 +14,16 @@ export function actionCircularize(wayId, projection, maxAngle) {
|
||||
maxAngle = (maxAngle || 20) * Math.PI / 180;
|
||||
|
||||
|
||||
var action = function(graph) {
|
||||
var way = graph.entity(wayId);
|
||||
var action = function(graph, t) {
|
||||
if (t === null || !isFinite(t)) t = 1;
|
||||
t = Math.min(Math.max(+t, 0), 1);
|
||||
|
||||
var way = graph.entity(wayId),
|
||||
origNodes = {};
|
||||
|
||||
graph.childNodes(way).forEach(function(node) {
|
||||
if (!origNodes[node.id]) origNodes[node.id] = node;
|
||||
});
|
||||
|
||||
if (!way.isConvex(graph)) {
|
||||
graph = action.makeConvex(graph);
|
||||
@@ -56,21 +64,27 @@ export function actionCircularize(wayId, projection, maxAngle) {
|
||||
endNodeIndex = nodes.indexOf(endNode),
|
||||
numberNewPoints = -1,
|
||||
indexRange = endNodeIndex - startNodeIndex,
|
||||
distance, totalAngle, eachAngle, startAngle, endAngle,
|
||||
angle, loc, node, j,
|
||||
inBetweenNodes = [];
|
||||
nearNodes = {},
|
||||
inBetweenNodes = [],
|
||||
startAngle, endAngle, totalAngle, eachAngle,
|
||||
angle, loc, node, origNode, j, k;
|
||||
|
||||
if (indexRange < 0) {
|
||||
indexRange += nodes.length;
|
||||
}
|
||||
|
||||
// position this key node
|
||||
distance = geoEuclideanDistance(centroid, keyPoints[i]);
|
||||
var distance = geoEuclideanDistance(centroid, keyPoints[i]);
|
||||
if (distance === 0) { distance = 1e-4; }
|
||||
keyPoints[i] = [
|
||||
centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
|
||||
centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius];
|
||||
graph = graph.replace(keyNodes[i].move(projection.invert(keyPoints[i])));
|
||||
centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius
|
||||
];
|
||||
loc = projection.invert(keyPoints[i]);
|
||||
node = keyNodes[i];
|
||||
origNode = origNodes[node.id];
|
||||
node = node.move(geoInterp(origNode.loc, loc, t));
|
||||
graph = graph.replace(node);
|
||||
|
||||
// figure out the between delta angle we want to match to
|
||||
startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
|
||||
@@ -87,14 +101,20 @@ export function actionCircularize(wayId, projection, maxAngle) {
|
||||
eachAngle = totalAngle / (indexRange + numberNewPoints);
|
||||
} while (Math.abs(eachAngle) > maxAngle);
|
||||
|
||||
// move existing points
|
||||
|
||||
// move existing nodes
|
||||
for (j = 1; j < indexRange; j++) {
|
||||
angle = startAngle + j * eachAngle;
|
||||
loc = projection.invert([
|
||||
centroid[0] + Math.cos(angle)*radius,
|
||||
centroid[1] + Math.sin(angle)*radius]);
|
||||
centroid[0] + Math.cos(angle) * radius,
|
||||
centroid[1] + Math.sin(angle) * radius
|
||||
]);
|
||||
|
||||
node = nodes[(j + startNodeIndex) % nodes.length].move(loc);
|
||||
node = nodes[(j + startNodeIndex) % nodes.length];
|
||||
origNode = origNodes[node.id];
|
||||
nearNodes[node.id] = angle;
|
||||
|
||||
node = node.move(geoInterp(origNode.loc, loc, t));
|
||||
graph = graph.replace(node);
|
||||
}
|
||||
|
||||
@@ -103,9 +123,21 @@ export function actionCircularize(wayId, projection, maxAngle) {
|
||||
angle = startAngle + (indexRange + j) * eachAngle;
|
||||
loc = projection.invert([
|
||||
centroid[0] + Math.cos(angle) * radius,
|
||||
centroid[1] + Math.sin(angle) * radius]);
|
||||
centroid[1] + Math.sin(angle) * radius
|
||||
]);
|
||||
|
||||
node = osmNode({loc: loc});
|
||||
// choose a nearnode to use as the original
|
||||
var min = Infinity;
|
||||
for (var nodeId in nearNodes) {
|
||||
var nearAngle = nearNodes[nodeId],
|
||||
dist = Math.abs(nearAngle - angle);
|
||||
if (dist < min) {
|
||||
dist = min;
|
||||
origNode = origNodes[nodeId];
|
||||
}
|
||||
}
|
||||
|
||||
node = osmNode({ loc: geoInterp(origNode.loc, loc, t) });
|
||||
graph = graph.replace(node);
|
||||
|
||||
nodes.splice(endNodeIndex + j, 0, node);
|
||||
@@ -195,5 +227,8 @@ export function actionCircularize(wayId, projection, maxAngle) {
|
||||
};
|
||||
|
||||
|
||||
action.transitionable = true;
|
||||
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user