modules/ui/tools/structure.js (157 lines of code) (raw):
import { uiToolSegemented } from './segmented';
import { t } from '../../util/locale';
import { osmTagsAllowingBridges, osmTagsAllowingTunnels } from '../../osm/tags';
import { actionChangeTags } from '../../actions/change_tags';
import { actionAddEntity } from '../../actions/add_entity';
import { actionAddVertex } from '../../actions/add_vertex';
import { actionJoin } from '../../actions/join';
import { modeDrawLine } from '../../modes/draw_line';
import { osmWay } from '../../osm/way';
export function uiToolStructure(context) {
var tool = uiToolSegemented(context);
tool.id = 'structure';
tool.label = t('presets.fields.structure.label');
tool.key = t('toolbar.structure.key');
tool.iconName = 'iD-structure-bridge';
tool.iconClass = 'icon-30';
var structureNone = {
id: 'none',
icon: 'iD-structure-none',
label: t('toolbar.structure.none.title'),
iconClass: 'icon-30',
tags: {}
};
var structureBridge = {
id: 'bridge',
icon: 'iD-structure-bridge',
label: t('presets.fields.structure.options.bridge'),
iconClass: 'icon-30',
tags: {
bridge: 'yes'
},
addTags: {
bridge: 'yes',
layer: '1'
}
};
var structureTunnel = {
id: 'tunnel',
icon: 'iD-structure-tunnel',
label: t('presets.fields.structure.options.tunnel'),
iconClass: 'icon-30',
tags: {
tunnel: 'yes'
},
addTags: {
tunnel: 'yes',
layer: '-1'
}
};
var prevWayID;
tool.loadItems = function() {
tool.items = [
structureNone
];
var tags = activeTags();
function allowsStructure(osmTags) {
for (var key in tags) {
if (osmTags[key] && osmTags[key][tags[key]]) return true;
}
return false;
}
if (allowsStructure(osmTagsAllowingBridges)) tool.items.push(structureBridge);
if (allowsStructure(osmTagsAllowingTunnels)) tool.items.push(structureTunnel);
};
tool.chooseItem = function(d) {
var tags = Object.assign({}, activeTags());
var priorStructure = tool.activeItem();
var tagsToRemove = priorStructure.addTags || priorStructure.tags;
for (var key in tagsToRemove) {
if (tags[key]) {
delete tags[key];
}
}
// add tags for structure
Object.assign(tags, d.addTags || d.tags);
var mode = context.mode();
if (mode.id === 'add-line') {
mode.defaultTags = tags;
} else if (mode.id === 'draw-line') {
if (mode.addMode) mode.addMode.defaultTags = tags;
var wayID = mode.wayID;
var way = context.hasEntity(wayID);
var prevWay = context.hasEntity(prevWayID);
if (!way) return;
if (way.nodes.length <= 2) {
context.replace(
actionChangeTags(wayID, tags)
);
// Reload way with updated tags
way = context.hasEntity(wayID);
if (prevWay && JSON.stringify(prevWay.tags) === JSON.stringify(way.tags)) {
var action = actionJoin([prevWay.id, way.id]);
if (!action.disabled(context.graph())) {
context.perform(action);
context.enter(
modeDrawLine(context, {
wayID: prevWay.id,
startGraph: context.graph(),
baselineGraph: context.graph(),
button: mode.button,
addMode: mode.addMode
})
);
}
}
} else {
var isLast = mode.activeID() === way.last();
var splitNodeID = isLast ? way.nodes[way.nodes.length - 2] : way.nodes[1];
mode.finish(true);
var startGraph = context.graph();
var newWay = osmWay({ tags: tags });
context.perform(
actionAddEntity(newWay),
actionAddVertex(newWay.id, splitNodeID)
);
prevWayID = way.id;
context.enter(
modeDrawLine(context, {
wayID: newWay.id,
startGraph: startGraph,
baselineGraph: context.graph(),
button: mode.button,
affix: isLast ? false : 'prefix',
addMode: mode.addMode
})
);
}
}
};
function activeTags() {
var mode = context.mode();
if (mode.id === 'add-line') {
return mode.defaultTags;
} else if (mode.id === 'draw-line') {
var way = context.hasEntity(mode.wayID);
return way ? way.tags : {};
}
return {};
}
tool.activeItem = function() {
var tags = activeTags();
function tagsMatchStructure(structure) {
for (var key in structure.tags) {
if (!tags[key] || tags[key] === 'no') return false;
}
return Object.keys(structure.tags).length !== 0;
}
for (var i in tool.items) {
if (tagsMatchStructure(tool.items[i])) return tool.items[i];
}
return structureNone;
};
var parentAvailable = tool.allowed;
tool.allowed = function() {
var modeID = context.mode().id;
return parentAvailable() && (modeID === 'add-line' || modeID === 'draw-line');
};
return tool;
}