mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 17:23:02 +00:00
mostly working path and point labelling
This commit is contained in:
@@ -284,7 +284,11 @@ text.tag-oneway {
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
text.label {
|
||||
text.textpath-label {
|
||||
text-anchor: middle;
|
||||
}
|
||||
|
||||
text.textpath-label, text.text-label {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
fill: black;
|
||||
|
||||
@@ -1,12 +1,47 @@
|
||||
iD.svg.Labels = function() {
|
||||
|
||||
var pointOffsets = [
|
||||
[15, 3, 'start'], // right
|
||||
[25, 3, 'start'], // right
|
||||
[-15, 3, 'end'], // left
|
||||
];
|
||||
|
||||
var height = 12,
|
||||
width = 6;
|
||||
|
||||
function drawTextPaths(group, labels, filter, classes, t) {
|
||||
|
||||
var reverse = t('reverse');
|
||||
|
||||
var texts = group.selectAll('text.textpath-label')
|
||||
.data(labels);
|
||||
|
||||
var tp = texts.enter()
|
||||
.append('text')
|
||||
.attr({ 'class': classes})
|
||||
.append('textPath')
|
||||
.attr({
|
||||
'class': 'textpath',
|
||||
'startOffset': '50%'
|
||||
});
|
||||
|
||||
var tps = group.selectAll('.textpath-label .textpath')
|
||||
.data(labels)
|
||||
.attr({
|
||||
'xlink:href': function(d, i) { return '#casing-' + d.id},
|
||||
'glyph-orientation-vertical': function(d, i) {return reverse(d, i) ? 180 : 0},
|
||||
'glyph-orientation-horizontal': function(d, i) {return reverse(d, i) ? 180 : 0},
|
||||
'dominant-baseline': 'central'
|
||||
})
|
||||
.text(function(d, i) {
|
||||
return reverse(d, i) ? d.tags.name.split('').reverse().join('') : d.tags.name;
|
||||
});
|
||||
|
||||
texts.exit().remove();
|
||||
|
||||
}
|
||||
|
||||
function drawTexts(group, labels, filter, classes, position) {
|
||||
var texts = group.selectAll('text')
|
||||
var texts = group.selectAll('text.text-label')
|
||||
.filter(filter)
|
||||
.data(labels);
|
||||
|
||||
@@ -24,42 +59,152 @@ iD.svg.Labels = function() {
|
||||
return texts;
|
||||
}
|
||||
|
||||
function getPathTransform(projection) {
|
||||
var nodeCache = {};
|
||||
return function pathTransform(entity) {
|
||||
var length = 0,
|
||||
w = entity.tags.name.length * width;
|
||||
|
||||
var nodes = nodeCache[entity.id];
|
||||
if (typeof nodes === 'undefined') {
|
||||
nodes = nodeCache[entity.id] = _.pluck(entity.nodes, 'loc')
|
||||
.map(iD.svg.RoundProjection(projection));
|
||||
}
|
||||
|
||||
function segmentLength(i) {
|
||||
var dx = nodes[i][0] - nodes[i + 1][0];
|
||||
var dy = nodes[i][1] - nodes[i + 1][1];
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
for (var i = 0; i < nodes.length - 1; i++) {
|
||||
length += segmentLength(i);
|
||||
}
|
||||
|
||||
if (length < w + 20) return null;
|
||||
|
||||
var ends = (length - w) / 2,
|
||||
sofar = 0,
|
||||
start, end,
|
||||
n1, n2;
|
||||
|
||||
for (var i = 0; i < nodes.length - 1; i++) {
|
||||
var current = segmentLength(i);
|
||||
if (!start && sofar + current > ends) {
|
||||
var portion = (ends - sofar) / current;
|
||||
start = [
|
||||
nodes[i][0] + portion * (nodes[i + 1][0] - nodes[i][0]),
|
||||
nodes[i][1] + portion * (nodes[i + 1][1] - nodes[i][1])
|
||||
];
|
||||
n1 = nodes[i + 1];
|
||||
}
|
||||
if (!end && sofar + current > length - ends) {
|
||||
var portion = (length - ends - sofar) / current;
|
||||
end = [
|
||||
nodes[i][0] + portion * (nodes[i + 1][0] - nodes[i][0]),
|
||||
nodes[i][1] + portion * (nodes[i + 1][1] - nodes[i][1])
|
||||
];
|
||||
n2 = nodes[i];
|
||||
}
|
||||
sofar += current;
|
||||
}
|
||||
|
||||
var angle = Math.atan2(n1[1] - start[1], n1[0] - start[0]);
|
||||
var reverse = !(start[0] < end[0] && angle < Math.PI/2 && angle > - Math.PI/2);
|
||||
|
||||
return {
|
||||
length: length,
|
||||
width: Math.abs(start[0] - end[0]),
|
||||
height: Math.abs(start[1] - end[1]),
|
||||
start: start,
|
||||
end: end,
|
||||
reverse: reverse
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return function drawLabels(surface, graph, entities, filter, projection) {
|
||||
|
||||
var points = [];
|
||||
var project = iD.svg.RoundProjection(projection);
|
||||
var rtree = new RTree();
|
||||
|
||||
function addPoint(d, i) {
|
||||
var bbox = this.getBBox();
|
||||
var coords = project(d.loc);
|
||||
var tree = new RTree.Rectangle(coords[0], coords[1], bbox.width, bbox.height);
|
||||
rtree.insert(tree, d.id);
|
||||
}
|
||||
|
||||
//d3.selectAll('.node.point').each(addPoint);
|
||||
|
||||
var points = [],
|
||||
roads = [];
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
if (entity.geometry() === 'point' && entity.tags.name) {
|
||||
if (entity.geometry() === 'line' && entity.tags.highway && entity.tags.name) {
|
||||
roads.push(entity);
|
||||
} else if (entity.geometry() === 'point' && entity.tags.name) {
|
||||
points.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
var labels = points;
|
||||
var positions = [];
|
||||
var entities = roads.concat(points);
|
||||
var rect;
|
||||
var pathTransform = getPathTransform(projection);
|
||||
var textlabels = [],
|
||||
pathlabels = [],
|
||||
textpositions = [],
|
||||
pathpositions = [];
|
||||
|
||||
var project = iD.svg.RoundProjection(projection);
|
||||
|
||||
for (var i = 0; i < labels.length; i ++) {
|
||||
positions[i] = {};
|
||||
var l = labels[i];
|
||||
if (l.type === 'node') {
|
||||
var coord = project(l.loc),
|
||||
offset = pointOffsets[1];
|
||||
positions[i].x = coord[0] + offset[0];
|
||||
positions[i].y = coord[1] + offset[1];
|
||||
positions[i].textAnchor = offset[2];
|
||||
}
|
||||
function nocollisions(rect) {
|
||||
var v = rtree.search(rect, true).length === 0;
|
||||
if (v) rtree.insert(rect);
|
||||
return v;
|
||||
}
|
||||
|
||||
function position(attr) {
|
||||
return function(d, i) { return positions[i][attr] };
|
||||
for (var i = 0; i < entities.length; i ++) {
|
||||
var p = {},
|
||||
entity = entities[i],
|
||||
w = width * entity.tags.name.length,
|
||||
h = 20;
|
||||
|
||||
if (entity.type === 'node') {
|
||||
var coord = project(entity.loc),
|
||||
offset = pointOffsets[0];
|
||||
p.x = coord[0] + offset[0];
|
||||
p.y = coord[1] + offset[1];
|
||||
p.textAnchor = offset[2];
|
||||
rect = new RTree.Rectangle(p.x, p.y, width * entity.tags.name.length, 20);
|
||||
if (nocollisions(rect)) {
|
||||
textpositions.push(p);
|
||||
textlabels.push(entity);
|
||||
}
|
||||
|
||||
} else if (entity.type === 'way' && entity.geometry() === 'line') {
|
||||
p = pathTransform(entity);
|
||||
if (!p) continue;
|
||||
rect = new RTree.Rectangle(Math.min(p.start[0], p.end[0]) - 5, Math.min(p.start[1], p.end[1]) - 5, p.width + 10, p.height + 10);
|
||||
if (nocollisions(rect)) {
|
||||
pathpositions.push(p);
|
||||
pathlabels.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function textposition(attr) {
|
||||
return function(d, i) { return textpositions[i][attr] };
|
||||
}
|
||||
function pathposition(attr) {
|
||||
return function(d, i) { return pathpositions[i][attr] };
|
||||
}
|
||||
|
||||
var label = surface.select('.layer-label'),
|
||||
texts = drawTexts(label, labels, filter, 'label', position);
|
||||
|
||||
|
||||
texts = drawTexts(label, textlabels, filter, 'text-label', textposition),
|
||||
textPaths = drawTextPaths(label, pathlabels, filter, 'textpath-label', pathposition);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -33,13 +33,16 @@ iD.svg.Lines = function() {
|
||||
return as - bs;
|
||||
}
|
||||
|
||||
function drawPaths(group, lines, filter, classes, lineString) {
|
||||
function drawPaths(group, lines, filter, classes, lineString, prefix) {
|
||||
var paths = group.selectAll('path')
|
||||
.filter(filter)
|
||||
.data(lines, iD.Entity.key);
|
||||
|
||||
paths.enter()
|
||||
.append('path')
|
||||
.attr('id', function(d) {
|
||||
return prefix + d.id;
|
||||
})
|
||||
.attr('class', classes);
|
||||
|
||||
paths
|
||||
@@ -87,8 +90,8 @@ iD.svg.Lines = function() {
|
||||
stroke = surface.select('.layer-stroke'),
|
||||
defs = surface.select('defs'),
|
||||
text = surface.select('.layer-text'),
|
||||
casings = drawPaths(casing, lines, filter, 'way line casing', lineString),
|
||||
strokes = drawPaths(stroke, lines, filter, 'way line stroke', lineString);
|
||||
casings = drawPaths(casing, lines, filter, 'way line casing', lineString, 'casing-'),
|
||||
strokes = drawPaths(stroke, lines, filter, 'way line stroke', lineString, 'stroke-');
|
||||
|
||||
// Determine the lengths of oneway paths
|
||||
var lengths = {},
|
||||
|
||||
Reference in New Issue
Block a user