Files
iD/modules/svg/points.js
Martin Raifer bd1836fd0c fix maki icons, tweak rendering of icons
* maki v7+ doesn't have provide "11px" icons anymore
* use 12px for icons on points & vertices on map (instead of 11px)
* use 12px for icons on QA tool (improveOSM, osmose) markers (instead of 13px)
* drop some unused code
2022-02-14 18:07:27 +01:00

159 lines
5.1 KiB
JavaScript

import deepEqual from 'fast-deep-equal';
import { geoScaleToZoom } from '../geo';
import { osmEntity } from '../osm';
import { svgPointTransform } from './helpers';
import { svgTagClasses } from './tag_classes';
import { presetManager } from '../presets';
export function svgPoints(projection, context) {
function markerPath(selection, klass) {
selection
.attr('class', klass)
.attr('transform', 'translate(-8, -23)')
.attr('d', 'M 17,8 C 17,13 11,21 8.5,23.5 C 6,21 0,13 0,8 C 0,4 4,-0.5 8.5,-0.5 C 13,-0.5 17,4 17,8 z');
}
function sortY(a, b) {
return b.loc[1] - a.loc[1];
}
// Avoid exit/enter if we're just moving stuff around.
// The node will get a new version but we only need to run the update selection.
function fastEntityKey(d) {
var mode = context.mode();
var isMoving = mode && /^(add|draw|drag|move|rotate)/.test(mode.id);
return isMoving ? d.id : osmEntity.key(d);
}
function drawTargets(selection, graph, entities, filter) {
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
var getTransform = svgPointTransform(projection).geojson;
var activeID = context.activeID();
var data = [];
entities.forEach(function(node) {
if (activeID === node.id) return; // draw no target on the activeID
data.push({
type: 'Feature',
id: node.id,
properties: {
target: true,
entity: node
},
geometry: node.asGeoJSON()
});
});
var targets = selection.selectAll('.point.target')
.filter(function(d) { return filter(d.properties.entity); })
.data(data, function key(d) { return d.id; });
// exit
targets.exit()
.remove();
// enter/update
targets.enter()
.append('rect')
.attr('x', -10)
.attr('y', -26)
.attr('width', 20)
.attr('height', 30)
.merge(targets)
.attr('class', function(d) { return 'node point target ' + fillClass + d.id; })
.attr('transform', getTransform);
}
function drawPoints(selection, graph, entities, filter) {
var wireframe = context.surface().classed('fill-wireframe');
var zoom = geoScaleToZoom(projection.scale());
var base = context.history().base();
// Points with a direction will render as vertices at higher zooms..
function renderAsPoint(entity) {
return entity.geometry(graph) === 'point' &&
!(zoom >= 18 && entity.directions(graph, projection).length);
}
// All points will render as vertices in wireframe mode too..
var points = wireframe ? [] : entities.filter(renderAsPoint);
points.sort(sortY);
var drawLayer = selection.selectAll('.layer-osm.points .points-group.points');
var touchLayer = selection.selectAll('.layer-touch.points');
// Draw points..
var groups = drawLayer.selectAll('g.point')
.filter(filter)
.data(points, fastEntityKey);
groups.exit()
.remove();
var enter = groups.enter()
.append('g')
.attr('class', function(d) { return 'node point ' + d.id; })
.order();
enter
.append('path')
.call(markerPath, 'shadow');
enter
.append('ellipse')
.attr('cx', 0.5)
.attr('cy', 1)
.attr('rx', 6.5)
.attr('ry', 3)
.attr('class', 'stroke');
enter
.append('path')
.call(markerPath, 'stroke');
enter
.append('use')
.attr('transform', 'translate(-5.5, -20)')
.attr('class', 'icon')
.attr('width', '12px')
.attr('height', '12px');
groups = groups
.merge(enter)
.attr('transform', svgPointTransform(projection))
.classed('added', function(d) {
return !base.entities[d.id]; // if it doesn't exist in the base graph, it's new
})
.classed('moved', function(d) {
return base.entities[d.id] && !deepEqual(graph.entities[d.id].loc, base.entities[d.id].loc);
})
.classed('retagged', function(d) {
return base.entities[d.id] && !deepEqual(graph.entities[d.id].tags, base.entities[d.id].tags);
})
.call(svgTagClasses());
groups.select('.shadow'); // propagate bound data
groups.select('.stroke'); // propagate bound data
groups.select('.icon') // propagate bound data
.attr('xlink:href', function(entity) {
var preset = presetManager.match(entity, graph);
var picon = preset && preset.icon;
return picon ? '#' + picon : '';
});
// Draw touch targets..
touchLayer
.call(drawTargets, graph, points, filter);
}
return drawPoints;
}