Support transitioned circularize action

This commit is contained in:
Bryan Housel
2016-12-23 10:52:00 -05:00
parent d917424fc4
commit fdc37287ec
+49 -14
View File
@@ -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;
}