mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-24 09:04:02 +02:00
98d484fc1f
The issue was: now that selections are immutable you can't add behaviors to them unless they are already entered. i.e. the surface selection in enter does not end up being the real surface after merging to update.
242 lines
6.5 KiB
JavaScript
242 lines
6.5 KiB
JavaScript
import * as d3 from 'd3';
|
|
import { t } from '../../util/locale';
|
|
|
|
import {
|
|
behaviorBreathe,
|
|
behaviorHover
|
|
} from '../../behavior/index';
|
|
|
|
import {
|
|
osmEntity,
|
|
osmIntersection,
|
|
osmInferRestriction,
|
|
osmTurn
|
|
} from '../../osm/index';
|
|
|
|
import {
|
|
actionRestrictTurn,
|
|
actionUnrestrictTurn
|
|
} from '../../actions/index';
|
|
|
|
import {
|
|
geoExtent,
|
|
geoRawMercator
|
|
} from '../../geo/index';
|
|
|
|
import {
|
|
svgLayers,
|
|
svgLines,
|
|
svgTurns,
|
|
svgVertices
|
|
} from '../../svg/index';
|
|
|
|
import { utilRebind } from '../../util/rebind';
|
|
import { utilFunctor } from '../../util/index';
|
|
|
|
import {
|
|
utilGetDimensions,
|
|
utilSetDimensions
|
|
} from '../../util/dimensions';
|
|
|
|
|
|
export function uiFieldRestrictions(field, context) {
|
|
var dispatch = d3.dispatch('change'),
|
|
breathe = behaviorBreathe(context),
|
|
hover = behaviorHover(context),
|
|
vertexID,
|
|
fromNodeID;
|
|
|
|
|
|
function restrictions(selection) {
|
|
// if form field is hidden or has detached from dom, clean up.
|
|
if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
|
|
selection.call(restrictions.off);
|
|
return;
|
|
}
|
|
|
|
var wrap = selection.selectAll('.preset-input-wrap')
|
|
.data([0]);
|
|
|
|
var enter = wrap.enter()
|
|
.append('div')
|
|
.attr('class', 'preset-input-wrap');
|
|
|
|
enter
|
|
.append('div')
|
|
.attr('class', 'restriction-help');
|
|
|
|
|
|
var intersection = osmIntersection(context.graph(), vertexID),
|
|
graph = intersection.graph,
|
|
vertex = graph.entity(vertexID),
|
|
filter = utilFunctor(true),
|
|
extent = geoExtent(),
|
|
projection = geoRawMercator();
|
|
|
|
var d = utilGetDimensions(wrap.merge(enter)),
|
|
c = [d[0] / 2, d[1] / 2],
|
|
z = 24;
|
|
|
|
projection
|
|
.scale(256 * Math.pow(2, z) / (2 * Math.PI));
|
|
|
|
var s = projection(vertex.loc);
|
|
|
|
projection
|
|
.translate([c[0] - s[0], c[1] - s[1]])
|
|
.clipExtent([[0, 0], d]);
|
|
|
|
var drawLayers = svgLayers(projection, context).only('osm').dimensions(d),
|
|
drawVertices = svgVertices(projection, context),
|
|
drawLines = svgLines(projection, context),
|
|
drawTurns = svgTurns(projection, context);
|
|
|
|
enter
|
|
.call(drawLayers);
|
|
|
|
wrap = wrap
|
|
.merge(enter);
|
|
|
|
var surface = wrap.selectAll('.surface');
|
|
|
|
if (!enter.empty()) {
|
|
surface
|
|
.call(breathe)
|
|
.call(hover);
|
|
}
|
|
|
|
surface
|
|
.call(utilSetDimensions, d)
|
|
.call(drawVertices, graph, [vertex], filter, extent, z)
|
|
.call(drawLines, graph, intersection.ways, filter)
|
|
.call(drawTurns, graph, intersection.turns(fromNodeID));
|
|
|
|
surface
|
|
.on('click.restrictions', click)
|
|
.on('mouseover.restrictions', mouseover)
|
|
.on('mouseout.restrictions', mouseout);
|
|
|
|
surface
|
|
.selectAll('.selected')
|
|
.classed('selected', false);
|
|
|
|
if (fromNodeID) {
|
|
surface
|
|
.selectAll('.' + intersection.highways[fromNodeID].id)
|
|
.classed('selected', true);
|
|
}
|
|
|
|
mouseout();
|
|
|
|
context.history()
|
|
.on('change.restrictions', render);
|
|
|
|
d3.select(window)
|
|
.on('resize.restrictions', function() {
|
|
utilSetDimensions(wrap, null);
|
|
render();
|
|
});
|
|
|
|
|
|
function click() {
|
|
surface
|
|
.call(breathe.off)
|
|
.call(breathe);
|
|
|
|
var datum = d3.event.target.__data__;
|
|
if (datum instanceof osmEntity) {
|
|
fromNodeID = intersection.adjacentNodeId(datum.id);
|
|
render();
|
|
} else if (datum instanceof osmTurn) {
|
|
if (datum.restriction) {
|
|
context.perform(
|
|
actionUnrestrictTurn(datum, projection),
|
|
t('operations.restriction.annotation.delete')
|
|
);
|
|
} else {
|
|
context.perform(
|
|
actionRestrictTurn(datum, projection),
|
|
t('operations.restriction.annotation.create')
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function mouseover() {
|
|
var datum = d3.event.target.__data__;
|
|
if (datum instanceof osmTurn) {
|
|
var graph = context.graph(),
|
|
presets = context.presets(),
|
|
preset;
|
|
|
|
if (datum.restriction) {
|
|
preset = presets.match(graph.entity(datum.restriction), graph);
|
|
} else {
|
|
preset = presets.item('type/restriction/' +
|
|
osmInferRestriction(
|
|
graph,
|
|
datum.from,
|
|
datum.via,
|
|
datum.to,
|
|
projection
|
|
)
|
|
);
|
|
}
|
|
|
|
wrap.selectAll('.restriction-help')
|
|
.text(t('operations.restriction.help.' +
|
|
(datum.restriction ? 'toggle_off' : 'toggle_on'),
|
|
{ restriction: preset.name() })
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
function mouseout() {
|
|
wrap.selectAll('.restriction-help')
|
|
.text(t('operations.restriction.help.' +
|
|
(fromNodeID ? 'toggle' : 'select'))
|
|
);
|
|
}
|
|
|
|
|
|
function render() {
|
|
if (context.hasEntity(vertexID)) {
|
|
restrictions(selection);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
restrictions.entity = function(_) {
|
|
if (!vertexID || vertexID !== _.id) {
|
|
fromNodeID = null;
|
|
vertexID = _.id;
|
|
}
|
|
};
|
|
|
|
|
|
restrictions.tags = function() {};
|
|
restrictions.focus = function() {};
|
|
|
|
|
|
restrictions.off = function(selection) {
|
|
selection.selectAll('.surface')
|
|
.call(hover.off)
|
|
.call(breathe.off)
|
|
.on('click.restrictions', null)
|
|
.on('mouseover.restrictions', null)
|
|
.on('mouseout.restrictions', null);
|
|
|
|
context.history()
|
|
.on('change.restrictions', null);
|
|
|
|
d3.select(window)
|
|
.on('resize.restrictions', null);
|
|
};
|
|
|
|
|
|
return utilRebind(restrictions, dispatch, 'on');
|
|
}
|