mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-30 07:27:54 +02:00
add Maki icons to areas
This commit is contained in:
@@ -19,7 +19,7 @@ iD.Map = function(context) {
|
||||
lines = iD.svg.Lines(projection),
|
||||
areas = iD.svg.Areas(roundedProjection),
|
||||
midpoints = iD.svg.Midpoints(roundedProjection),
|
||||
labels = iD.svg.Labels(roundedProjection),
|
||||
labels = iD.svg.Labels(roundedProjection, context),
|
||||
tail = iD.ui.Tail(),
|
||||
surface, tilegroup;
|
||||
|
||||
|
||||
+100
-24
@@ -1,4 +1,4 @@
|
||||
iD.svg.Labels = function(projection) {
|
||||
iD.svg.Labels = function(projection, context) {
|
||||
|
||||
// Replace with dict and iterate over entities tags instead?
|
||||
var label_stack = [
|
||||
@@ -30,16 +30,21 @@ iD.svg.Labels = function(projection) {
|
||||
];
|
||||
|
||||
var default_size = 12;
|
||||
|
||||
var font_sizes = label_stack.map(function(d) {
|
||||
var style = iD.util.getStyle('text.' + d[0] + '.tag-' + d[1]);
|
||||
var m = style && style.cssText.match("font-size: ([0-9]{1,2})px;");
|
||||
var style = iD.util.getStyle('text.' + d[0] + '.tag-' + d[1]),
|
||||
m = style && style.cssText.match("font-size: ([0-9]{1,2})px;");
|
||||
if (m) return parseInt(m[1], 10);
|
||||
|
||||
style = iD.util.getStyle('text.' + d[0]);
|
||||
m = style && style.cssText.match("font-size: ([0-9]{1,2})px;");
|
||||
if (m) return parseInt(m[1], 10);
|
||||
|
||||
return default_size;
|
||||
});
|
||||
|
||||
var iconSize = 18;
|
||||
|
||||
var pointOffsets = [
|
||||
[15, -11, 'start'], // right
|
||||
[10, -11, 'start'], // unused right now
|
||||
@@ -49,20 +54,34 @@ iD.svg.Labels = function(projection) {
|
||||
var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70, 25,
|
||||
75, 20, 80, 15, 95, 10, 90, 5, 95];
|
||||
|
||||
|
||||
var noIcons = ['building', 'landuse', 'natural'];
|
||||
function blacklisted(preset) {
|
||||
return _.any(noIcons, function(s) {
|
||||
return preset.id.indexOf(s) >= 0;
|
||||
});
|
||||
}
|
||||
|
||||
function get(array, prop) {
|
||||
return function(d, i) { return array[i][prop]; };
|
||||
}
|
||||
|
||||
var textWidthCache = {};
|
||||
|
||||
function textWidth(text, size, elem) {
|
||||
var c = textWidthCache[size];
|
||||
if (!c) c = textWidthCache[size] = {};
|
||||
if (c[text]) return c[text];
|
||||
else if (elem) {
|
||||
|
||||
if (c[text]) {
|
||||
return c[text];
|
||||
|
||||
} else if (elem) {
|
||||
c[text] = elem.getComputedTextLength();
|
||||
return c[text];
|
||||
|
||||
} else {
|
||||
return size / 3 * 2 * text.length;
|
||||
}
|
||||
else return size / 3 * 2 * text.length;
|
||||
}
|
||||
|
||||
function drawLineLabels(group, entities, filter, classes, labels) {
|
||||
@@ -150,7 +169,6 @@ iD.svg.Labels = function(projection) {
|
||||
|
||||
texts.attr('x', get(labels, 'x'))
|
||||
.attr('y', get(labels, 'y'))
|
||||
.attr('transform', get(labels, 'transform'))
|
||||
.style('text-anchor', get(labels, 'textAnchor'))
|
||||
.text(function(d) { return name(d); })
|
||||
.each(function(d, i) { textWidth(name(d), labels[i].height, this); });
|
||||
@@ -159,6 +177,45 @@ iD.svg.Labels = function(projection) {
|
||||
return texts;
|
||||
}
|
||||
|
||||
function drawAreaHalos(group, entities, filter, classes, labels) {
|
||||
entities = entities.filter(hasText);
|
||||
labels = labels.filter(hasText);
|
||||
return drawPointHalos(group, entities, filter, classes, labels);
|
||||
|
||||
function hasText(d, i) {
|
||||
return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
|
||||
}
|
||||
}
|
||||
|
||||
function drawAreaLabels(group, entities, filter, classes, labels) {
|
||||
entities = entities.filter(hasText);
|
||||
labels = labels.filter(hasText);
|
||||
return drawPointLabels(group, entities, filter, classes, labels);
|
||||
|
||||
function hasText(d, i) {
|
||||
return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
|
||||
}
|
||||
}
|
||||
|
||||
function drawAreaIcons(group, entities, filter, classes, labels) {
|
||||
|
||||
var icons = group.selectAll('use')
|
||||
.filter(filter)
|
||||
.data(entities, iD.Entity.key);
|
||||
|
||||
icons.enter()
|
||||
.append('use')
|
||||
.attr('xlink:href', function(d) {
|
||||
return '#maki-' + context.presets().match(d, context.graph()).icon + '-18';
|
||||
})
|
||||
.attr('clip-path', 'url(#clip-square-18)')
|
||||
.attr('class', 'icon');
|
||||
|
||||
icons.attr('transform', get(labels, 'transform'));
|
||||
|
||||
icons.exit().remove();
|
||||
}
|
||||
|
||||
function reverse(p) {
|
||||
var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
|
||||
return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > - Math.PI/2);
|
||||
@@ -280,13 +337,18 @@ iD.svg.Labels = function(projection) {
|
||||
// Split entities into groups specified by label_stack
|
||||
for (i = 0; i < entities.length; i++) {
|
||||
entity = entities[i];
|
||||
if (!name(entity)) continue;
|
||||
if (hidePoints && entity.geometry(graph) === 'point') continue;
|
||||
for (k = 0; k < label_stack.length; k ++) {
|
||||
if (entity.geometry(graph) === label_stack[k][0] &&
|
||||
entity.tags[label_stack[k][1]]) {
|
||||
labelable[k].push(entity);
|
||||
break;
|
||||
var geometry = entity.geometry(graph),
|
||||
preset = geometry === 'area' && context.presets().match(entity, graph),
|
||||
icon = preset && !blacklisted(preset) && preset.icon;
|
||||
|
||||
if ((name(entity) || icon) && !(hidePoints && geometry === 'point')) {
|
||||
|
||||
for (k = 0; k < label_stack.length; k ++) {
|
||||
if (entity.geometry(graph) === label_stack[k][0] &&
|
||||
entity.tags[label_stack[k][1]]) {
|
||||
labelable[k].push(entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +370,7 @@ iD.svg.Labels = function(projection) {
|
||||
var font_size = font_sizes[k];
|
||||
for (i = 0; i < labelable[k].length; i ++) {
|
||||
entity = labelable[k][i];
|
||||
var width = textWidth(name(entity), font_size),
|
||||
var width = name(entity) && textWidth(name(entity), font_size),
|
||||
p;
|
||||
if (entity.geometry(graph) === 'point') {
|
||||
p = getPointLabel(entity, width, font_size);
|
||||
@@ -372,16 +434,29 @@ iD.svg.Labels = function(projection) {
|
||||
var path = d3.geo.path().projection(projection),
|
||||
centroid = path.centroid(entity.asGeoJSON(graph, true)),
|
||||
extent = entity.extent(graph),
|
||||
entitywidth = projection(extent[1])[0] - projection(extent[0])[0];
|
||||
entitywidth = projection(extent[1])[0] - projection(extent[0])[0],
|
||||
rect;
|
||||
|
||||
if (entitywidth < 20) return;
|
||||
|
||||
var iconX = centroid[0] - (iconSize/2),
|
||||
iconY = centroid[1] - (iconSize/2),
|
||||
textOffset = iconSize + 5;
|
||||
|
||||
if (entitywidth < width + 20) return;
|
||||
var p = {
|
||||
x: centroid[0],
|
||||
y: centroid[1],
|
||||
textAnchor: 'middle',
|
||||
height: height
|
||||
transform: 'translate(' + iconX + ',' + iconY + ')'
|
||||
};
|
||||
var rect = new RTree.Rectangle(p.x - width/2, p.y, width, height);
|
||||
|
||||
if (width && entitywidth >= width + 20) {
|
||||
p.x = centroid[0];
|
||||
p.y = centroid[1] + textOffset;
|
||||
p.textAnchor = 'middle';
|
||||
p.height = height;
|
||||
rect = new RTree.Rectangle(p.x - width/2, p.y, width, height + textOffset);
|
||||
} else {
|
||||
rect = new RTree.Rectangle(iconX, iconY, iconSize, iconSize);
|
||||
}
|
||||
|
||||
if (tryInsert(rect, entity.id)) return p;
|
||||
|
||||
}
|
||||
@@ -404,8 +479,9 @@ iD.svg.Labels = function(projection) {
|
||||
pointHalos = drawPointHalos(halo, labelled.point, filter, 'pointlabel-halo', positions.point),
|
||||
linesHalos = drawLineHalos(halo, labelled.line, filter, 'linelabel-halo', positions.line),
|
||||
lines = drawLineLabels(label, labelled.line, filter, 'pathlabel', positions.line),
|
||||
areas = drawPointLabels(label, labelled.area, filter, 'arealabel', positions.area),
|
||||
areaHalos = drawPointHalos(halo, labelled.area, filter, 'arealabel-halo', positions.area);
|
||||
areas = drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area),
|
||||
areaHalos = drawAreaHalos(halo, labelled.area, filter, 'arealabel-halo', positions.area),
|
||||
areaIcons = drawAreaIcons(label, labelled.area, filter, 'arealabel-icon', positions.area);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -80,7 +80,7 @@ iD.svg.Surface = function() {
|
||||
.attr('xlink:href', function(d) { return 'img/pattern/' + d[1] + '.png'; });
|
||||
|
||||
defs.selectAll()
|
||||
.data([12, 20])
|
||||
.data([12, 18, 20])
|
||||
.enter().append('clipPath')
|
||||
.attr('id', function(d) { return 'clip-square-' + d; })
|
||||
.append('rect')
|
||||
@@ -113,7 +113,7 @@ iD.svg.Surface = function() {
|
||||
});
|
||||
|
||||
defs.selectAll()
|
||||
.data(sprites("feature-icons.css", /^\.(feature-[a-z0-9-]+-12)$/))
|
||||
.data(sprites("feature-icons.css", /^\.(feature-[a-z0-9-]+-(12|18))$/))
|
||||
.enter().append('use')
|
||||
.attr('id', function(d) { return d.id; })
|
||||
.attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; })
|
||||
|
||||
Reference in New Issue
Block a user