diff --git a/src/lib/create_midpoint.js b/src/lib/create_midpoint.js index e58ff58cc..74e77a977 100644 --- a/src/lib/create_midpoint.js +++ b/src/lib/create_midpoint.js @@ -1,27 +1,40 @@ import * as Constants from '../constants'; +/** + * Returns GeoJSON for a Point representing the + * midpoint of another feature. + * + * @param {GeoJSON} parent + * @param {GeoJSON} startVertex + * @param {GeoJSON} endVertex + * @param {Object} map + * @return {GeoJSON} Point + */ export default function(parent, startVertex, endVertex, map) { const startCoord = startVertex.geometry.coordinates; const endCoord = endVertex.geometry.coordinates; // If a coordinate exceeds the projection, we can't calculate a midpoint, // so run away - if (startCoord[1] > Constants.LAT_RENDERED_MAX || + if ( + startCoord[1] > Constants.LAT_RENDERED_MAX || startCoord[1] < Constants.LAT_RENDERED_MIN || endCoord[1] > Constants.LAT_RENDERED_MAX || - endCoord[1] < Constants.LAT_RENDERED_MIN) { + endCoord[1] < Constants.LAT_RENDERED_MIN + ) { return null; } - const ptA = map.project([ startCoord[0], startCoord[1] ]); - const ptB = map.project([ endCoord[0], endCoord[1] ]); - const mid = map.unproject([ (ptA.x + ptB.x) / 2, (ptA.y + ptB.y) / 2 ]); + const ptA = map.project([startCoord[0], startCoord[1]]); + const ptB = map.project([endCoord[0], endCoord[1]]); + const mid = map.unproject([(ptA.x + ptB.x) / 2, (ptA.y + ptB.y) / 2]); - return { + const midpoint = { type: Constants.geojsonTypes.FEATURE, properties: { + ...parent.properties, meta: Constants.meta.MIDPOINT, - parent, + parent: parent.properties && parent.properties.id, lng: mid.lng, lat: mid.lat, coord_path: endVertex.properties.coord_path @@ -31,4 +44,6 @@ export default function(parent, startVertex, endVertex, map) { coordinates: [mid.lng, mid.lat] } }; + delete midpoint.properties.id; + return midpoint; } diff --git a/src/lib/create_supplementary_points.js b/src/lib/create_supplementary_points.js index 506941d5e..6d5eb1dcc 100644 --- a/src/lib/create_supplementary_points.js +++ b/src/lib/create_supplementary_points.js @@ -4,13 +4,12 @@ import * as Constants from '../constants'; function createSupplementaryPoints(geojson, options = {}, basePath = null) { const { type, coordinates } = geojson.geometry; - const featureId = geojson.properties && geojson.properties.id; let supplementaryPoints = []; if (type === Constants.geojsonTypes.POINT) { // For points, just create a vertex - supplementaryPoints.push(createVertex(featureId, coordinates, basePath, isSelectedPath(basePath))); + supplementaryPoints.push(createVertex(geojson, coordinates, basePath, isSelectedPath(basePath))); } else if (type === Constants.geojsonTypes.POLYGON) { // Cycle through a Polygon's rings and // process each line @@ -28,13 +27,13 @@ function createSupplementaryPoints(geojson, options = {}, basePath = null) { let lastVertex = null; line.forEach((point, pointIndex) => { const pointPath = (lineBasePath !== undefined && lineBasePath !== null) ? `${lineBasePath}.${pointIndex}` : String(pointIndex); - const vertex = createVertex(featureId, point, pointPath, isSelectedPath(pointPath)); + const vertex = createVertex(geojson, point, pointPath, isSelectedPath(pointPath)); // If we're creating midpoints, check if there was a // vertex before this one. If so, add a midpoint // between that vertex and this one. if (options.midpoints && lastVertex) { - const midpoint = createMidpoint(featureId, lastVertex, vertex, options.map); + const midpoint = createMidpoint(geojson, lastVertex, vertex, options.map); if (midpoint) { supplementaryPoints.push(midpoint); } diff --git a/src/lib/create_vertex.js b/src/lib/create_vertex.js index 682b83738..806d06b18 100644 --- a/src/lib/create_vertex.js +++ b/src/lib/create_vertex.js @@ -4,25 +4,30 @@ import * as Constants from '../constants'; * Returns GeoJSON for a Point representing the * vertex of another feature. * - * @param {string} parentId + * @param {GeoJSON} parent * @param {Array} coordinates * @param {string} path - Dot-separated numbers indicating exactly * where the point exists within its parent feature's coordinates. * @param {boolean} selected * @return {GeoJSON} Point */ -export default function(parentId, coordinates, path, selected) { - return { +export default function(parent, coordinates, path, selected) { + const vertex = { type: Constants.geojsonTypes.FEATURE, properties: { + ...parent.properties, meta: Constants.meta.VERTEX, - parent: parentId, + parent: parent.properties && parent.properties.id, coord_path: path, - active: (selected) ? Constants.activeStates.ACTIVE : Constants.activeStates.INACTIVE + active: selected ? + Constants.activeStates.ACTIVE : + Constants.activeStates.INACTIVE }, geometry: { type: Constants.geojsonTypes.POINT, coordinates } }; + delete vertex.properties.id; + return vertex; } diff --git a/src/modes/draw_line_string.js b/src/modes/draw_line_string.js index 71a0c5564..843da4bed 100644 --- a/src/modes/draw_line_string.js +++ b/src/modes/draw_line_string.js @@ -140,7 +140,7 @@ DrawLineString.toDisplayFeatures = function(state, geojson, display) { if (geojson.geometry.coordinates.length < 2) return; geojson.properties.meta = Constants.meta.FEATURE; display(createVertex( - state.line.id, + geojson, geojson.geometry.coordinates[state.direction === 'forward' ? geojson.geometry.coordinates.length - 2 : 1], `${state.direction === 'forward' ? geojson.geometry.coordinates.length - 2 : 1}`, false diff --git a/src/modes/draw_polygon.js b/src/modes/draw_polygon.js index 30c640691..9fc469871 100644 --- a/src/modes/draw_polygon.js +++ b/src/modes/draw_polygon.js @@ -103,12 +103,12 @@ DrawPolygon.toDisplayFeatures = function(state, geojson, display) { return; } geojson.properties.meta = Constants.meta.FEATURE; - display(createVertex(state.polygon.id, geojson.geometry.coordinates[0][0], '0.0', false)); + display(createVertex(geojson, geojson.geometry.coordinates[0][0], '0.0', false)); if (coordinateCount > 3) { // Add a start position marker to the map, clicking on this will finish the feature // This should only be shown when we're in a valid spot const endPos = geojson.geometry.coordinates[0].length - 3; - display(createVertex(state.polygon.id, geojson.geometry.coordinates[0][endPos], `0.${endPos}`, false)); + display(createVertex(geojson, geojson.geometry.coordinates[0][endPos], `0.${endPos}`, false)); } if (coordinateCount <= 4) { // If we've only drawn two positions (plus the closer), diff --git a/test/create_supplementary_points.test.js b/test/create_supplementary_points.test.js index cc2995401..bfae84845 100644 --- a/test/create_supplementary_points.test.js +++ b/test/create_supplementary_points.test.js @@ -658,3 +658,95 @@ test('createSupplementaryPoints with a line, not all midpoints rendered because t.end(); }); + +test('createSupplementaryPoints with line, midpoints, selected coordinate, userProperties', (t) => { + const line = { + type: 'Feature', + properties: { + id: 'foo', + bar: 'baz' + }, + geometry: { + type: 'LineString', + coordinates: [[0, 0], [4, 4], [8, 8]] + } + }; + const map = createMap(); + + const results = createSupplementaryPoints(line, { + map, + midpoints: true, + selectedPaths: '1' + }); + + t.deepEqual(results, [{ + geometry: { + coordinates: [0, 0], + type: 'Point' + }, + properties: { + active: 'false', + coord_path: '0', + meta: 'vertex', + parent: 'foo', + bar: 'baz' + }, + type: 'Feature' + }, { + geometry: { + coordinates: [2, 2], + type: 'Point' + }, + properties: { + coord_path: '1', + lat: 2, + lng: 2, + meta: 'midpoint', + parent: 'foo', + bar: 'baz' + }, + type: 'Feature' + }, { + geometry: { + coordinates: [4, 4], + type: 'Point' + }, + properties: { + active: 'true', + coord_path: '1', + meta: 'vertex', + parent: 'foo', + bar: 'baz' + }, + type: 'Feature' + }, { + geometry: { + coordinates: [6, 6], + type: 'Point' + }, + properties: { + coord_path: '2', + lat: 6, + lng: 6, + meta: 'midpoint', + parent: 'foo', + bar: 'baz' + }, + type: 'Feature' + }, { + geometry: { + coordinates: [8, 8], + type: 'Point' + }, + properties: { + active: 'false', + coord_path: '2', + meta: 'vertex', + parent: 'foo', + bar: 'baz' + }, + type: 'Feature' + }], 'adds vertices and midpoints with userProperties'); + + t.end(); +}); diff --git a/test/create_vertex.test.js b/test/create_vertex.test.js index 65633a68f..fb79b7743 100644 --- a/test/create_vertex.test.js +++ b/test/create_vertex.test.js @@ -2,33 +2,62 @@ import test from 'tape'; import createVertex from '../src/lib/create_vertex'; test('createVertex', (t) => { - t.deepEqual(createVertex('foo', [1, 2], '3.4.5', true), { - type: 'Feature', - properties: { - meta: 'vertex', - parent: 'foo', - coord_path: '3.4.5', - active: 'true' - }, - geometry: { - type: 'Point', - coordinates: [1, 2] + t.deepEqual( + createVertex({ properties: { id: 'foo' } }, [1, 2], '3.4.5', true), + { + type: 'Feature', + properties: { + meta: 'vertex', + parent: 'foo', + coord_path: '3.4.5', + active: 'true' + }, + geometry: { + type: 'Point', + coordinates: [1, 2] + } + } + ); + t.deepEqual( + createVertex({ properties: { id: 'bar' } }, [99, 199], '1', false), + { + type: 'Feature', + properties: { + meta: 'vertex', + parent: 'bar', + coord_path: '1', + active: 'false' + }, + geometry: { + type: 'Point', + coordinates: [99, 199] + } } - }); + ); - t.deepEqual(createVertex('bar', [99, 199], '1', false), { - type: 'Feature', - properties: { - meta: 'vertex', - parent: 'bar', - coord_path: '1', - active: 'false' + t.deepEqual( + createVertex( + { properties: { id: 'bar', baz: 'qux' } }, + [99, 199], + '1', + false + ), + { + type: 'Feature', + properties: { + meta: 'vertex', + parent: 'bar', + coord_path: '1', + active: 'false', + baz: 'qux' + }, + geometry: { + type: 'Point', + coordinates: [99, 199] + } }, - geometry: { - type: 'Point', - coordinates: [99, 199] - } - }); + 'userProperties are copied to vertices' + ); t.end(); });