diff --git a/data/core.yaml b/data/core.yaml index 4b64931b1..ce1b23974 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -369,6 +369,8 @@ en: description: vertex: single: Extract this point from its parent lines/areas. + line: + single: Extract a point from this line. area: single: Extract a point from this area. annotation: diff --git a/dist/locales/en.json b/dist/locales/en.json index 55a37ddb3..bf0dd4c93 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -481,6 +481,9 @@ "vertex": { "single": "Extract this point from its parent lines/areas." }, + "line": { + "single": "Extract a point from this line." + }, "area": { "single": "Extract a point from this area." } diff --git a/modules/actions/extract.js b/modules/actions/extract.js index 5e5a391dc..08cbee56b 100644 --- a/modules/actions/extract.js +++ b/modules/actions/extract.js @@ -13,7 +13,7 @@ export function actionExtract(entityID) { return extractFromNode(entity, graph); } - return extractFromArea(entity, graph); + return extractFromWayOrRelation(entity, graph); }; function extractFromNode(node, graph) { @@ -37,19 +37,26 @@ export function actionExtract(entityID) { }, graph); } - function extractFromArea(entity, graph) { + function extractFromWayOrRelation(entity, graph) { + + var fromGeometry = entity.geometry(graph); var keysToCopyAndRetain = ['source', 'wheelchair']; - var keysToRetain = ['area', 'type']; + var keysToRetain = ['area']; var buildingKeysToRetain = ['architect', 'building', 'height', 'layer']; var centroid = d3_geoCentroid(entity.asGeoJSON(graph)); - var isBuilding = entity.tags.building; + var isBuilding = entity.tags.building && entity.tags.building !== 'no'; - var areaTags = Object.assign({}, entity.tags); // shallow copy + var entityTags = Object.assign({}, entity.tags); // shallow copy var pointTags = {}; - for (var key in areaTags) { + for (var key in entityTags) { + + if (entity.type === 'relation' && + key === 'type') { + continue; + } if (keysToRetain.indexOf(key) !== -1) { continue; @@ -62,21 +69,22 @@ export function actionExtract(entityID) { key.match(/^roof:.{1,}/)) continue; } - // copy the tag from the area to the point - pointTags[key] = areaTags[key]; + // copy the tag from the entity to the point + pointTags[key] = entityTags[key]; // leave addresses and some other tags so they're on both features - if (keysToCopyAndRetain.indexOf(key) !== -1 || key.match(/^addr:.{1,}/)) { + if (keysToCopyAndRetain.indexOf(key) !== -1 || + key.match(/^addr:.{1,}/)) { continue; } - // remove the tag from the area - delete areaTags[key]; + // remove the tag from the entity + delete entityTags[key]; } - if (!isBuilding) { - // ensure that the area keeps the area geometry - areaTags.area = 'yes'; + if (!isBuilding && fromGeometry === 'area') { + // ensure that areas keep area geometry + entityTags.area = 'yes'; } var replacement = osmNode({ loc: centroid, tags: pointTags }); @@ -84,7 +92,7 @@ export function actionExtract(entityID) { extractedNodeID = replacement.id; - return graph.replace(entity.update({tags: areaTags})); + return graph.replace(entity.update({tags: entityTags})); } action.getExtractedNodeID = function() { diff --git a/modules/operations/extract.js b/modules/operations/extract.js index 6a660ac78..51858111d 100644 --- a/modules/operations/extract.js +++ b/modules/operations/extract.js @@ -9,7 +9,7 @@ export function operationExtract(selectedIDs, context) { var action = actionExtract(entityID); var geometry = entityID && context.graph().hasEntity(entityID) && context.graph().geometry(entityID); - var extent = geometry === 'area' && context.entity(entityID).extent(context.graph()); + var extent = (geometry === 'area' || geometry === 'line') && context.entity(entityID).extent(context.graph()); var operation = function () { @@ -27,8 +27,9 @@ export function operationExtract(selectedIDs, context) { if (!entity.hasInterestingTags()) return false; - if (geometry === 'area') { + if (geometry === 'area' || geometry === 'line') { var preset = presetManager.match(entity, graph); + // only allow extraction from ways/multipolygons if the preset supports points return preset.geometry.indexOf('point') !== -1; }