diff --git a/shp/index.js b/shp/index.js index 8c08f64..d7879ad 100644 --- a/shp/index.js +++ b/shp/index.js @@ -2,10 +2,14 @@ import slice from "slice-source"; import view from "../view"; import shp_cancel from "./cancel"; import parseMultiPoint from "./multipoint"; +import parseMultiPointZ from "./multipointz"; import parseNull from "./null"; import parsePoint from "./point"; import parsePolygon from "./polygon"; import parsePolyLine from "./polyline"; +import parsePointZ from "./pointz"; +import parsePolygonZ from "./polygonz"; +import parsePolyLineZ from "./polylinez"; import shp_read from "./read"; var parsers = { @@ -14,10 +18,10 @@ var parsers = { 3: parsePolyLine, 5: parsePolygon, 8: parseMultiPoint, - 11: parsePoint, // PointZ - 13: parsePolyLine, // PolyLineZ - 15: parsePolygon, // PolygonZ - 18: parseMultiPoint, // MultiPointZ + 11: parsePointZ, // PointZ + 13: parsePolyLineZ, // PolyLineZ + 15: parsePolygonZ, // PolygonZ + 18: parseMultiPointZ, // MultiPointZ 21: parsePoint, // PointM 23: parsePolyLine, // PolyLineM 25: parsePolygon, // PolygonM diff --git a/shp/multipointz.js b/shp/multipointz.js new file mode 100644 index 0000000..60b3c5f --- /dev/null +++ b/shp/multipointz.js @@ -0,0 +1,5 @@ +export default function(record) { + var i = 40, j, n = record.getInt32(36, true), coordinates = new Array(n); + for (j = 0; j < n; ++j, i += 24) coordinates[j] = [record.getFloat64(i, true), record.getFloat64(i + 8, true),record.getFloat64(i + 16, true)]; + return {type: "MultiPoint", coordinates: coordinates}; +}; diff --git a/shp/pointz.js b/shp/pointz.js new file mode 100644 index 0000000..c30cc6c --- /dev/null +++ b/shp/pointz.js @@ -0,0 +1,4 @@ + +export default function(record) { + return {type: "PointZ", coordinates: [record.getFloat64(4, true), record.getFloat64(12, true), record.getFloat64(20, true)]}; +}; diff --git a/shp/polygonz.js b/shp/polygonz.js new file mode 100644 index 0000000..d7ae8ef --- /dev/null +++ b/shp/polygonz.js @@ -0,0 +1,26 @@ + +export default function(record) { + var z=0,i = 44, j, n = record.getInt32(36, true), m = record.getInt32(40, true), parts = new Array(n), points = new Array(m), polygons = [], holes = []; + for (j = 0; j < n; ++j, i += 4) parts[j] = record.getInt32(i, true); + z = i + 16*m + 16 + for (j = 0; j < m; ++j, i += 16,z+=8) points[j] = [record.getFloat64(i, true), record.getFloat64(i + 8, true),record.getFloat64(z, true)]; + + parts.forEach(function(i, j) { + var ring = points.slice(i, parts[j + 1]); + if (ringClockwise(ring)) polygons.push([ring]); + else holes.push(ring); + }); + + holes.forEach(function(hole) { + polygons.some(function(polygon) { + if (ringContainsSome(polygon[0], hole)) { + polygon.push(hole); + return true; + } + }) || polygons.push([hole]); + }); + + return polygons.length === 1 + ? {type: "PolygonZ", coordinates: polygons[0]} + : {type: "MultiPolygonZ", coordinates: polygons}; + }; diff --git a/shp/polylinez.js b/shp/polylinez.js new file mode 100644 index 0000000..87bd66f --- /dev/null +++ b/shp/polylinez.js @@ -0,0 +1,13 @@ +export default function(record) { + var z=0,i = 44, j, n = record.getInt32(36, true), m = record.getInt32(40, true), parts = new Array(n), points = new Array(m); + for (j = 0; j < n; ++j, i += 4) parts[j] = record.getInt32(i, true); + z = i + 16*m + 16 + for (j = 0; j < m; ++j, i += 16,z +=8){ + points[j] = [record.getFloat64(i, true), record.getFloat64(i + 8, true), record.getFloat64(z, true)]; + //console.log([record.getFloat64(i, true), record.getFloat64(i + 8, true), record.getFloat64(z, true)]); + } + + return n === 1 + ? {type: "LineString", coordinates: points} + : {type: "MultiLineString", coordinates: parts.map(function(i, j) { return points.slice(i, parts[j + 1]); })}; +};