diff --git a/packages/turf-tesselate/index.ts b/packages/turf-tesselate/index.ts index 2bb01f0bda..9354582197 100644 --- a/packages/turf-tesselate/index.ts +++ b/packages/turf-tesselate/index.ts @@ -50,7 +50,8 @@ function tesselate( function processPolygon(coordinates: Position[][]) { const data = flattenCoords(coordinates); - const dim = 2; + // coordinates are normalized to 3 dimensions by passing through original elevation value, or padding with undefined + const dim = 3; const result = earcut(data.vertices, data.holes, dim); const features: Feature[] = []; @@ -58,7 +59,19 @@ function processPolygon(coordinates: Position[][]) { result.forEach(function (vert: any, i: number) { const index = result[i]; - vertices.push([data.vertices[index * dim], data.vertices[index * dim + 1]]); + // if elevation component is included in the original coordinate, include it in the output coordinate + if (data.vertices[index * dim + 2] !== undefined) { + vertices.push([ + data.vertices[index * dim], + data.vertices[index * dim + 1], + data.vertices[index * dim + 2], + ]); + } else { + vertices.push([ + data.vertices[index * dim], + data.vertices[index * dim + 1], + ]); + } }); for (var i = 0; i < vertices.length; i += 3) { @@ -71,7 +84,8 @@ function processPolygon(coordinates: Position[][]) { } function flattenCoords(data: Position[][]) { - const dim: number = data[0][0].length, + // coordinates are normalized to 3 dimensions by passing through original elevation value, or padding with undefined + const dim = 3, result: { vertices: number[]; holes: number[]; dimensions: number } = { vertices: [], holes: [], @@ -81,6 +95,7 @@ function flattenCoords(data: Position[][]) { for (let i = 0; i < data.length; i++) { for (let j = 0; j < data[i].length; j++) { + // elevation member is either included, or undefined is put in its place for (let d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); } if (i > 0) { diff --git a/packages/turf-tesselate/package.json b/packages/turf-tesselate/package.json index 3d769291be..e2059b4496 100644 --- a/packages/turf-tesselate/package.json +++ b/packages/turf-tesselate/package.json @@ -7,7 +7,8 @@ "Abel Vázquez <@AbelVM>", "Morgan Herlocker <@morganherlocker>", "Tom MacWright <@tmcw>", - "Vladimir Agafonkin <@mourner>" + "Vladimir Agafonkin <@mourner>", + "Pavel Rozvora <@prozvora>" ], "license": "MIT", "bugs": { diff --git a/packages/turf-tesselate/test.ts b/packages/turf-tesselate/test.ts index c5b07e1e8a..64a112e2c6 100644 --- a/packages/turf-tesselate/test.ts +++ b/packages/turf-tesselate/test.ts @@ -3499,5 +3499,98 @@ test("tesselate", function (t) { tesselate(featurecollection([])); }, /input must be a Polygon or MultiPolygon/); + var simplePolygonWithElevation = { + type: "Feature", + id: "CoordsWithElevation", + properties: { name: "CoordsWithElevation" }, + geometry: { + type: "Polygon", + coordinates: [ + [ + [-123.233256, 42.006186, 130], + [-114.634459, 35.00118, 130], + [-118.183517, 33.763391, 130], + [-124.213628, 42.000709, 130], + [-123.233256, 42.006186, 130], + ], + ], + }, + }; + + var simpleTrianglesWithElevation = tesselate(simplePolygonWithElevation); + t.equal( + simpleTrianglesWithElevation.type, + "FeatureCollection", + "Polygon returns a FeatureCollection" + ); + t.equal( + simpleTrianglesWithElevation.features[0].geometry.type, + "Polygon", + "contains at least 1 triangle" + ); + t.equal( + simpleTrianglesWithElevation.features[0].geometry.coordinates[0].length, + 4, + "triangle is valid" + ); + t.equal( + simpleTrianglesWithElevation.features[0].geometry.coordinates[0][0][2], + 130, + "triangle coordinates contain elevation" + ); + + var simpleSquareWithVariableElevation = { + type: "Feature", + id: "SquareWithVariableElevation", + properties: { name: "SquareWithVariableElevation" }, + geometry: { + type: "Polygon", + coordinates: [ + [ + [1, 1], + [1, 2, 50], + [2, 2, 75], + [2, 1], + [1, 1], + ], + ], + }, + }; + + var simpleVariableElevationTriangles = tesselate( + simpleSquareWithVariableElevation + ); + + t.equal( + simpleVariableElevationTriangles.type, + "FeatureCollection", + "Polygon returns a FeatureCollection" + ); + + t.deepEqual( + simpleVariableElevationTriangles.features[0].geometry.coordinates, + [ + [ + [1, 2, 50], + [1, 1], + [2, 1], + [1, 2, 50], + ], + ], + "first triangle coordinates contain original elevations" + ); + t.deepEqual( + simpleVariableElevationTriangles.features[1].geometry.coordinates, + [ + [ + [2, 1], + [2, 2, 75], + [1, 2, 50], + [2, 1], + ], + ], + "second triangle coordinates contain original elevations" + ); + t.end(); });