mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-20 15:34:49 +02:00
Merge pull request #5888 from openstreetmap/dynamic-line-icon-lines
Dynamic line previews in line preset icons
This commit is contained in:
+101
-97
@@ -23,111 +23,15 @@ export function svgTagClasses() {
|
||||
var tagClasses = function(selection) {
|
||||
selection.each(function tagClassesEach(entity) {
|
||||
var value = this.className;
|
||||
var primary, status;
|
||||
|
||||
if (value.baseVal !== undefined) {
|
||||
value = value.baseVal;
|
||||
}
|
||||
|
||||
var t = _tags(entity);
|
||||
var i, k, v;
|
||||
|
||||
// in some situations we want to render perimeter strokes a certain way
|
||||
var overrideGeometry;
|
||||
if (/\bstroke\b/.test(value)) {
|
||||
if (!!t.barrier && t.barrier !== 'no') {
|
||||
overrideGeometry = 'line';
|
||||
} else if (t.type === 'multipolygon' && !entity.hasInterestingTags()) {
|
||||
overrideGeometry = 'area';
|
||||
}
|
||||
}
|
||||
var computed = tagClasses.getClassesString(t, value, entity);
|
||||
|
||||
// preserve base classes (nothing with `tag-`)
|
||||
var classes = value.trim().split(/\s+/)
|
||||
.filter(function(klass) {
|
||||
return klass.length && !/^tag-/.test(klass);
|
||||
})
|
||||
.map(function(klass) { // special overrides for some perimeter strokes
|
||||
return (klass === 'line' || klass === 'area') ? (overrideGeometry || klass) : klass;
|
||||
});
|
||||
|
||||
|
||||
|
||||
// pick at most one primary classification tag..
|
||||
for (i = 0; i < primaries.length; i++) {
|
||||
k = primaries[i];
|
||||
v = t[k];
|
||||
if (!v || v === 'no') continue;
|
||||
|
||||
if (k === 'piste:type') { // avoid a ':' in the class name
|
||||
k = 'piste';
|
||||
}
|
||||
|
||||
primary = k;
|
||||
if (statuses.indexOf(v) !== -1) { // e.g. `railway=abandoned`
|
||||
status = v;
|
||||
classes.push('tag-' + k);
|
||||
} else {
|
||||
classes.push('tag-' + k);
|
||||
classes.push('tag-' + k + '-' + v);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// add at most one status tag, only if relates to primary tag..
|
||||
if (!status) {
|
||||
for (i = 0; i < statuses.length; i++) {
|
||||
k = statuses[i];
|
||||
v = t[k];
|
||||
if (!v || v === 'no') continue;
|
||||
|
||||
if (v === 'yes') { // e.g. `railway=rail + abandoned=yes`
|
||||
status = k;
|
||||
}
|
||||
else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway`
|
||||
status = k;
|
||||
} else if (!primary && primaries.indexOf(v) !== -1) { // e.g. `abandoned=railway`
|
||||
status = k;
|
||||
primary = v;
|
||||
classes.push('tag-' + v);
|
||||
} // else ignore e.g. `highway=path + abandoned=railway`
|
||||
|
||||
if (status) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status) {
|
||||
classes.push('tag-status');
|
||||
classes.push('tag-status-' + status);
|
||||
}
|
||||
|
||||
// add any secondary tags
|
||||
for (i = 0; i < secondaries.length; i++) {
|
||||
k = secondaries[i];
|
||||
v = t[k];
|
||||
if (!v || v === 'no') continue;
|
||||
classes.push('tag-' + k);
|
||||
classes.push('tag-' + k + '-' + v);
|
||||
}
|
||||
|
||||
// For highways, look for surface tagging..
|
||||
if (primary === 'highway' || primary === 'aeroway') {
|
||||
var paved = (t.highway !== 'track');
|
||||
for (k in t) {
|
||||
v = t[k];
|
||||
if (k in osmPavedTags) {
|
||||
paved = !!osmPavedTags[k][v];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!paved) {
|
||||
classes.push('tag-unpaved');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var computed = classes.join(' ').trim();
|
||||
if (computed !== value) {
|
||||
d3_select(this).attr('class', computed);
|
||||
}
|
||||
@@ -135,6 +39,106 @@ export function svgTagClasses() {
|
||||
};
|
||||
|
||||
|
||||
tagClasses.getClassesString = function(t, value, entity) {
|
||||
var primary, status;
|
||||
var i, k, v;
|
||||
|
||||
// in some situations we want to render perimeter strokes a certain way
|
||||
var overrideGeometry;
|
||||
if (/\bstroke\b/.test(value)) {
|
||||
if (!!t.barrier && t.barrier !== 'no') {
|
||||
overrideGeometry = 'line';
|
||||
} else if (t.type === 'multipolygon' && !entity.hasInterestingTags()) {
|
||||
overrideGeometry = 'area';
|
||||
}
|
||||
}
|
||||
|
||||
// preserve base classes (nothing with `tag-`)
|
||||
var classes = value.trim().split(/\s+/)
|
||||
.filter(function(klass) {
|
||||
return klass.length && !/^tag-/.test(klass);
|
||||
})
|
||||
.map(function(klass) { // special overrides for some perimeter strokes
|
||||
return (klass === 'line' || klass === 'area') ? (overrideGeometry || klass) : klass;
|
||||
});
|
||||
|
||||
// pick at most one primary classification tag..
|
||||
for (i = 0; i < primaries.length; i++) {
|
||||
k = primaries[i];
|
||||
v = t[k];
|
||||
if (!v || v === 'no') continue;
|
||||
|
||||
if (k === 'piste:type') { // avoid a ':' in the class name
|
||||
k = 'piste';
|
||||
}
|
||||
|
||||
primary = k;
|
||||
if (statuses.indexOf(v) !== -1) { // e.g. `railway=abandoned`
|
||||
status = v;
|
||||
classes.push('tag-' + k);
|
||||
} else {
|
||||
classes.push('tag-' + k);
|
||||
classes.push('tag-' + k + '-' + v);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// add at most one status tag, only if relates to primary tag..
|
||||
if (!status) {
|
||||
for (i = 0; i < statuses.length; i++) {
|
||||
k = statuses[i];
|
||||
v = t[k];
|
||||
if (!v || v === 'no') continue;
|
||||
|
||||
if (v === 'yes') { // e.g. `railway=rail + abandoned=yes`
|
||||
status = k;
|
||||
}
|
||||
else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway`
|
||||
status = k;
|
||||
} else if (!primary && primaries.indexOf(v) !== -1) { // e.g. `abandoned=railway`
|
||||
status = k;
|
||||
primary = v;
|
||||
classes.push('tag-' + v);
|
||||
} // else ignore e.g. `highway=path + abandoned=railway`
|
||||
|
||||
if (status) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status) {
|
||||
classes.push('tag-status');
|
||||
classes.push('tag-status-' + status);
|
||||
}
|
||||
|
||||
// add any secondary tags
|
||||
for (i = 0; i < secondaries.length; i++) {
|
||||
k = secondaries[i];
|
||||
v = t[k];
|
||||
if (!v || v === 'no') continue;
|
||||
classes.push('tag-' + k);
|
||||
classes.push('tag-' + k + '-' + v);
|
||||
}
|
||||
|
||||
// For highways, look for surface tagging..
|
||||
if (primary === 'highway' || primary === 'aeroway') {
|
||||
var paved = (t.highway !== 'track');
|
||||
for (k in t) {
|
||||
v = t[k];
|
||||
if (k in osmPavedTags) {
|
||||
paved = !!osmPavedTags[k][v];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!paved) {
|
||||
classes.push('tag-unpaved');
|
||||
}
|
||||
}
|
||||
|
||||
return classes.join(' ').trim();
|
||||
};
|
||||
|
||||
|
||||
tagClasses.tags = function(val) {
|
||||
if (!arguments.length) return _tags;
|
||||
_tags = val;
|
||||
|
||||
+53
-18
@@ -1,9 +1,8 @@
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
|
||||
import { svgIcon } from '../svg';
|
||||
import { svgIcon, svgTagClasses } from '../svg';
|
||||
import { utilFunctor } from '../util';
|
||||
|
||||
|
||||
export function uiPresetIcon() {
|
||||
var preset, geometry;
|
||||
|
||||
@@ -34,22 +33,17 @@ export function uiPresetIcon() {
|
||||
var isTemaki = /^temaki-/.test(picon);
|
||||
var isFa = /^fa[srb]-/.test(picon);
|
||||
var isPOI = isMaki || isTemaki || isFa;
|
||||
var isFramed = (geom === 'area' || geom === 'vertex');
|
||||
var isCategory = !p.setTags;
|
||||
var drawLine = geom === 'line' && !isCategory;
|
||||
var isFramed = (geom === 'area' || drawLine || geom === 'vertex');
|
||||
|
||||
var tagClasses = '';
|
||||
for (var k in p.tags) {
|
||||
var v = p.tags[k];
|
||||
tagClasses += ' tag-' + k;
|
||||
if (v !== '*') {
|
||||
tagClasses += ' tag-' + k + '-' + v;
|
||||
var tags = !isCategory ? p.setTags({}, geom) : {};
|
||||
for (var k in tags) {
|
||||
if (tags[k] === '*') {
|
||||
tags[k] = 'yes';
|
||||
}
|
||||
}
|
||||
|
||||
// if the preset includes a `building_area` field, class it as a building
|
||||
if (p.fields && p.fields.filter(function(d) { return d.id === 'building_area'; }).length) {
|
||||
tagClasses += ' tag-building';
|
||||
}
|
||||
|
||||
var tagClasses = svgTagClasses().getClassesString(tags, '');
|
||||
|
||||
var fill = selection.selectAll('.preset-icon-fill')
|
||||
.data([0]);
|
||||
@@ -60,9 +54,50 @@ export function uiPresetIcon() {
|
||||
|
||||
fill
|
||||
.attr('class', function() {
|
||||
return 'preset-icon-fill preset-icon-fill-' + geom + tagClasses;
|
||||
return 'preset-icon-fill preset-icon-fill-' + geom + ' ' + tagClasses;
|
||||
});
|
||||
|
||||
var line = selection.selectAll('.preset-icon-line')
|
||||
.data(drawLine ? [0] : []);
|
||||
|
||||
line.exit()
|
||||
.remove();
|
||||
|
||||
// draw the line parametrically
|
||||
var w = 60, h = 60, y = 43, l = 36, r = 2.5;
|
||||
var x1 = (w - l)/2, x2 = x1 + l;
|
||||
|
||||
var lineEnter = line.enter()
|
||||
.append('svg')
|
||||
.attr('class', 'preset-icon-line')
|
||||
.attr('width', w)
|
||||
.attr('height', h)
|
||||
.attr('viewBox', '0 0 ' + w + ' ' + h);
|
||||
|
||||
lineEnter.append('path')
|
||||
.attr('d', 'M' + x1 + ' ' + y + ' L' + x2 + ' ' + y)
|
||||
.attr('class', 'line casing');
|
||||
lineEnter.append('path')
|
||||
.attr('d', 'M' + x1 + ' ' + y + ' L' + x2 + ' ' + y)
|
||||
.attr('class', 'line stroke');
|
||||
lineEnter.append('circle')
|
||||
.attr('class', 'vertex')
|
||||
.attr('cx', x1 - 1)
|
||||
.attr('cy', y)
|
||||
.attr('r', r);
|
||||
lineEnter.append('circle')
|
||||
.attr('class', 'vertex')
|
||||
.attr('cx', x2 + 1)
|
||||
.attr('cy', y)
|
||||
.attr('r', r);
|
||||
|
||||
line = lineEnter.merge(line);
|
||||
|
||||
line.selectAll('path.stroke')
|
||||
.attr('class', 'line stroke ' + tagClasses);
|
||||
line.selectAll('path.casing')
|
||||
.attr('class', 'line casing ' + tagClasses);
|
||||
|
||||
|
||||
var areaFrame = selection.selectAll('.preset-icon-frame')
|
||||
.data((geom === 'area') ? [0] : []);
|
||||
@@ -86,13 +121,13 @@ export function uiPresetIcon() {
|
||||
.merge(icon);
|
||||
|
||||
icon
|
||||
.attr('class', 'preset-icon preset-icon-' +
|
||||
.attr('class', 'preset-icon ' + geom + '-geom ' + 'preset-icon-' +
|
||||
(isPOI ? (isFramed ? '24' : '28') : (isFramed ? '44' : '60'))
|
||||
);
|
||||
|
||||
icon.selectAll('svg')
|
||||
.attr('class', function() {
|
||||
return 'icon ' + picon + (isPOI ? '' : tagClasses);
|
||||
return 'icon ' + picon + ' ' + (isPOI && geom !== 'line' ? '' : tagClasses);
|
||||
});
|
||||
|
||||
icon.selectAll('use')
|
||||
|
||||
Reference in New Issue
Block a user