Files
iD/modules/ui/fields/restrictions.js

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');
}