Files
iD/js/id/svg/midpoints.js
T
tyr e8d637f2bb Add iD.geo.sphericalDistance
iD.geo.euclideanDistance should only be used for calculations of 
projected coordinates or display (pixel) coordinates.

iD.geo.sphericalDistance calculates approximate geographical 
distances, accounting for distortions at higher latitudes. This 
can be used for determining the nearest node (operations.Delete,
actions.Circularize) or relative length comparisons (actions.Split).
2013-09-29 07:45:04 -07:00

61 lines
2.0 KiB
JavaScript

iD.svg.Midpoints = function(projection, context) {
return function drawMidpoints(surface, graph, entities, filter, extent) {
var midpoints = {};
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
if (entity.type !== 'way') continue;
if (context.selectedIDs().indexOf(entity.id) < 0) continue;
var nodes = graph.childNodes(entity);
// skip the last node because it is always repeated
for (var j = 0; j < nodes.length - 1; j++) {
var a = nodes[j],
b = nodes[j + 1],
id = [a.id, b.id].sort().join('-');
// If neither of the nodes changed, no need to redraw midpoint
if (!midpoints[id] && (filter(a) || filter(b))) {
var loc = iD.geo.interp(a.loc, b.loc, 0.5);
if (extent.intersects(loc) && iD.geo.euclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
midpoints[id] = {
type: 'midpoint',
id: id,
loc: loc,
edge: [a.id, b.id]
};
}
}
}
}
var groups = surface.select('.layer-hit').selectAll('g.midpoint')
.filter(filter)
.data(_.values(midpoints), function(d) { return d.id; });
var group = groups.enter()
.insert('g', ':first-child')
.attr('class', 'midpoint');
group.append('circle')
.attr('r', 7)
.attr('class', 'shadow');
group.append('circle')
.attr('r', 3)
.attr('class', 'fill');
groups.attr('transform', iD.svg.PointTransform(projection));
// Propagate data bindings.
groups.select('circle.shadow');
groups.select('circle.fill');
groups.exit()
.remove();
};
};