mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 17:23:02 +00:00
246 lines
6.5 KiB
JavaScript
246 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),
|
|
initialized = false,
|
|
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()) {
|
|
initialized = true;
|
|
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) {
|
|
if (!initialized) return;
|
|
|
|
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');
|
|
}
|