This is an automated email from the ASF dual-hosted git repository.
jiayu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sedona.git
The following commit(s) were added to refs/heads/master by this push:
new fd01d2a099 [SEDONA-719] Support reading Shapefile with Z/M ordinates
(#1842)
fd01d2a099 is described below
commit fd01d2a09968259979127e7cffeab9f820e465c7
Author: Kristin Cowalcijk <[email protected]>
AuthorDate: Thu Mar 6 02:57:50 2025 +0800
[SEDONA-719] Support reading Shapefile with Z/M ordinates (#1842)
---
.../parseUtils/shp/MultiPointParser.java | 24 +++-
.../parseUtils/shp/PointParser.java | 34 ++++-
.../parseUtils/shp/PolyLineParser.java | 33 +++--
.../parseUtils/shp/PolygonParser.java | 36 ++++--
.../parseUtils/shp/ShapeParser.java | 140 +++++++++++++++++++--
.../shapefileParser/parseUtils/shp/ShapeType.java | 32 +++--
.../shapetypes/linestring/linestring.csv | 11 ++
.../shapetypes/linestring/linestring.dbf | Bin 0 -> 3448 bytes
.../shapetypes/linestring/linestring.prj | 1 +
.../shapetypes/linestring/linestring.shp | Bin 0 -> 1668 bytes
.../shapetypes/linestring/linestring.shx | Bin 0 -> 180 bytes
.../shapetypes/linestringm/linestringm.csv | 11 ++
.../shapetypes/linestringm/linestringm.dbf | Bin 0 -> 4280 bytes
.../shapetypes/linestringm/linestringm.prj | 1 +
.../shapetypes/linestringm/linestringm.shp | Bin 0 -> 2020 bytes
.../shapetypes/linestringm/linestringm.shx | Bin 0 -> 180 bytes
.../shapetypes/linestringz/linestringz.csv | 11 ++
.../shapetypes/linestringz/linestringz.dbf | Bin 0 -> 4280 bytes
.../shapetypes/linestringz/linestringz.prj | 1 +
.../shapetypes/linestringz/linestringz.shp | Bin 0 -> 2020 bytes
.../shapetypes/linestringz/linestringz.shx | Bin 0 -> 180 bytes
.../shapetypes/linestringzm/linestringzm.csv | 11 ++
.../shapetypes/linestringzm/linestringzm.dbf | Bin 0 -> 5112 bytes
.../shapetypes/linestringzm/linestringzm.prj | 1 +
.../shapetypes/linestringzm/linestringzm.shp | Bin 0 -> 2676 bytes
.../shapetypes/linestringzm/linestringzm.shx | Bin 0 -> 180 bytes
.../shapetypes/multipoint/multipoint.csv | 11 ++
.../shapetypes/multipoint/multipoint.dbf | Bin 0 -> 3448 bytes
.../shapetypes/multipoint/multipoint.prj | 1 +
.../shapetypes/multipoint/multipoint.shp | Bin 0 -> 1588 bytes
.../shapetypes/multipoint/multipoint.shx | Bin 0 -> 180 bytes
.../shapetypes/multipointm/multipointm.csv | 11 ++
.../shapetypes/multipointm/multipointm.dbf | Bin 0 -> 4280 bytes
.../shapetypes/multipointm/multipointm.prj | 1 +
.../shapetypes/multipointm/multipointm.shp | Bin 0 -> 1940 bytes
.../shapetypes/multipointm/multipointm.shx | Bin 0 -> 180 bytes
.../shapetypes/multipointz/multipointz.csv | 11 ++
.../shapetypes/multipointz/multipointz.dbf | Bin 0 -> 4280 bytes
.../shapetypes/multipointz/multipointz.prj | 1 +
.../shapetypes/multipointz/multipointz.shp | Bin 0 -> 1940 bytes
.../shapetypes/multipointz/multipointz.shx | Bin 0 -> 180 bytes
.../shapetypes/multipointzm/multipointzm.csv | 11 ++
.../shapetypes/multipointzm/multipointzm.dbf | Bin 0 -> 5112 bytes
.../shapetypes/multipointzm/multipointzm.prj | 1 +
.../shapetypes/multipointzm/multipointzm.shp | Bin 0 -> 2596 bytes
.../shapetypes/multipointzm/multipointzm.shx | Bin 0 -> 180 bytes
.../shapefiles/shapetypes/point/point.csv | 11 ++
.../shapefiles/shapetypes/point/point.dbf | Bin 0 -> 1708 bytes
.../shapefiles/shapetypes/point/point.prj | 1 +
.../shapefiles/shapetypes/point/point.shp | Bin 0 -> 380 bytes
.../shapefiles/shapetypes/point/point.shx | Bin 0 -> 180 bytes
.../shapefiles/shapetypes/pointm/pointm.csv | 11 ++
.../shapefiles/shapetypes/pointm/pointm.dbf | Bin 0 -> 2540 bytes
.../shapefiles/shapetypes/pointm/pointm.prj | 1 +
.../shapefiles/shapetypes/pointm/pointm.shp | Bin 0 -> 460 bytes
.../shapefiles/shapetypes/pointm/pointm.shx | Bin 0 -> 180 bytes
.../shapefiles/shapetypes/pointz/pointz.csv | 11 ++
.../shapefiles/shapetypes/pointz/pointz.dbf | Bin 0 -> 2540 bytes
.../shapefiles/shapetypes/pointz/pointz.prj | 1 +
.../shapefiles/shapetypes/pointz/pointz.shp | Bin 0 -> 460 bytes
.../shapefiles/shapetypes/pointz/pointz.shx | Bin 0 -> 180 bytes
.../shapefiles/shapetypes/pointzm/pointzm.csv | 11 ++
.../shapefiles/shapetypes/pointzm/pointzm.dbf | Bin 0 -> 3432 bytes
.../shapefiles/shapetypes/pointzm/pointzm.prj | 1 +
.../shapefiles/shapetypes/pointzm/pointzm.shp | Bin 0 -> 540 bytes
.../shapefiles/shapetypes/pointzm/pointzm.shx | Bin 0 -> 180 bytes
.../shapefiles/shapetypes/polygon/polygon.csv | 11 ++
.../shapefiles/shapetypes/polygon/polygon.dbf | Bin 0 -> 3448 bytes
.../shapefiles/shapetypes/polygon/polygon.prj | 1 +
.../shapefiles/shapetypes/polygon/polygon.shp | Bin 0 -> 1828 bytes
.../shapefiles/shapetypes/polygon/polygon.shx | Bin 0 -> 180 bytes
.../shapefiles/shapetypes/polygonm/polygonm.csv | 11 ++
.../shapefiles/shapetypes/polygonm/polygonm.dbf | Bin 0 -> 4280 bytes
.../shapefiles/shapetypes/polygonm/polygonm.prj | 1 +
.../shapefiles/shapetypes/polygonm/polygonm.shp | Bin 0 -> 2260 bytes
.../shapefiles/shapetypes/polygonm/polygonm.shx | Bin 0 -> 180 bytes
.../shapefiles/shapetypes/polygonz/polygonz.csv | 11 ++
.../shapefiles/shapetypes/polygonz/polygonz.dbf | Bin 0 -> 4280 bytes
.../shapefiles/shapetypes/polygonz/polygonz.prj | 1 +
.../shapefiles/shapetypes/polygonz/polygonz.shp | Bin 0 -> 2260 bytes
.../shapefiles/shapetypes/polygonz/polygonz.shx | Bin 0 -> 180 bytes
.../shapefiles/shapetypes/polygonzm/polygonzm.csv | 11 ++
.../shapefiles/shapetypes/polygonzm/polygonzm.dbf | Bin 0 -> 5112 bytes
.../shapefiles/shapetypes/polygonzm/polygonzm.prj | 1 +
.../shapefiles/shapetypes/polygonzm/polygonzm.shp | Bin 0 -> 2996 bytes
.../shapefiles/shapetypes/polygonzm/polygonzm.shx | Bin 0 -> 180 bytes
.../unsupported/UrbAdm3D_142166_Bu_Ground.dbf | Bin 6250 -> 0 bytes
.../unsupported/UrbAdm3D_142166_Bu_Ground.prj | 1 -
.../unsupported/UrbAdm3D_142166_Bu_Ground.shp | Bin 9052 -> 0 bytes
.../unsupported/UrbAdm3D_142166_Bu_Ground.shx | Bin 260 -> 0 bytes
.../shapefiles/unsupported/multipatches_pyshp.dbf | Bin 0 -> 1107 bytes
.../shapefiles/unsupported/multipatches_pyshp.shp | Bin 0 -> 14748 bytes
.../shapefiles/unsupported/multipatches_pyshp.shx | Bin 0 -> 180 bytes
.../org/apache/sedona/sql/ShapefileTests.scala | 73 ++++++++---
.../org/apache/sedona/sql/ShapefileTests.scala | 73 ++++++++---
.../org/apache/sedona/sql/ShapefileTests.scala | 73 ++++++++---
96 files changed, 620 insertions(+), 91 deletions(-)
diff --git
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/MultiPointParser.java
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/MultiPointParser.java
index 2821c37e4e..ce65911700 100644
---
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/MultiPointParser.java
+++
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/MultiPointParser.java
@@ -19,20 +19,23 @@
package org.apache.sedona.core.formatMapper.shapefileParser.parseUtils.shp;
import java.io.IOException;
-import org.locationtech.jts.geom.CoordinateSequence;
+import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.MultiPoint;
public class MultiPointParser extends ShapeParser {
+ private final ShapeType shapeType;
+
/**
* create a parser that can abstract a MultiPoint from input source with
given GeometryFactory.
*
* @param geometryFactory the geometry factory
*/
- public MultiPointParser(GeometryFactory geometryFactory) {
+ public MultiPointParser(GeometryFactory geometryFactory, ShapeType
shapeType) {
super(geometryFactory);
+ this.shapeType = shapeType;
}
/**
@@ -46,8 +49,21 @@ public class MultiPointParser extends ShapeParser {
public Geometry parseShape(ShapeReader reader) {
reader.skip(4 * ShapeFileConst.DOUBLE_LENGTH);
int numPoints = reader.readInt();
- CoordinateSequence coordinateSequence = readCoordinates(reader, numPoints);
- MultiPoint multiPoint =
geometryFactory.createMultiPoint(coordinateSequence);
+
+ Coordinate[] coordinates;
+
+ if (shapeType == ShapeType.MULTIPOINTZ) {
+ // Read XY coordinates, then Z and M values
+ coordinates = readCoordinatesWithZM(reader, numPoints);
+ } else if (shapeType == ShapeType.MULTIPOINTM) {
+ // Read XY coordinates, then M values
+ coordinates = readCoordinatesWithM(reader, numPoints);
+ } else {
+ // Standard XY coordinates
+ coordinates = readCoordinates(reader, numPoints);
+ }
+
+ MultiPoint multiPoint =
geometryFactory.createMultiPointFromCoords(coordinates);
return multiPoint;
}
}
diff --git
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PointParser.java
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PointParser.java
index 82cfdecd7a..17bf8fb74b 100644
---
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PointParser.java
+++
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PointParser.java
@@ -18,21 +18,24 @@
*/
package org.apache.sedona.core.formatMapper.shapefileParser.parseUtils.shp;
-import java.io.IOException;
import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.CoordinateXYM;
+import org.locationtech.jts.geom.CoordinateXYZM;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.Point;
public class PointParser extends ShapeParser {
+ private final ShapeType shapeType;
+
/**
* create a parser that can abstract a Point from input source with given
GeometryFactory.
*
* @param geometryFactory the geometry factory
*/
- public PointParser(GeometryFactory geometryFactory) {
+ public PointParser(GeometryFactory geometryFactory, ShapeType shapeType) {
super(geometryFactory);
+ this.shapeType = shapeType;
}
/**
@@ -40,13 +43,32 @@ public class PointParser extends ShapeParser {
*
* @param reader the reader
* @return the geometry
- * @throws IOException Signals that an I/O exception has occurred.
*/
@Override
public Geometry parseShape(ShapeReader reader) {
double x = reader.readDouble();
double y = reader.readDouble();
- Point point = geometryFactory.createPoint(new Coordinate(x, y));
- return point;
+
+ if (shapeType == ShapeType.POINTZ) {
+ // For POINTZ, read both Z and M values
+ double z = reader.readDouble();
+ double m = reader.readDouble();
+ if (isNoData(m)) {
+ return geometryFactory.createPoint(new Coordinate(x, y, z));
+ } else {
+ return geometryFactory.createPoint(new CoordinateXYZM(x, y, z, m));
+ }
+ } else if (shapeType == ShapeType.POINTM) {
+ // For POINTM, read M value only
+ double m = reader.readDouble(); // M value read but not currently used
+ if (isNoData(m)) {
+ return geometryFactory.createPoint(new Coordinate(x, y));
+ } else {
+ return geometryFactory.createPoint(new CoordinateXYM(x, y, m));
+ }
+ } else {
+ // Regular POINT with just XY coordinates
+ return geometryFactory.createPoint(new Coordinate(x, y));
+ }
}
}
diff --git
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PolyLineParser.java
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PolyLineParser.java
index eab4038a50..87faa43a56 100644
---
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PolyLineParser.java
+++
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PolyLineParser.java
@@ -18,21 +18,23 @@
*/
package org.apache.sedona.core.formatMapper.shapefileParser.parseUtils.shp;
-import java.io.IOException;
-import org.locationtech.jts.geom.CoordinateSequence;
+import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
public class PolyLineParser extends ShapeParser {
+ private final ShapeType shapeType;
+
/**
* create a parser that can abstract a MultiPolyline from input source with
given GeometryFactory.
*
* @param geometryFactory the geometry factory
*/
- public PolyLineParser(GeometryFactory geometryFactory) {
+ public PolyLineParser(GeometryFactory geometryFactory, ShapeType shapeType) {
super(geometryFactory);
+ this.shapeType = shapeType;
}
/**
@@ -40,7 +42,6 @@ public class PolyLineParser extends ShapeParser {
*
* @param reader the reader
* @return the geometry
- * @throws IOException Signals that an I/O exception has occurred.
*/
@Override
public Geometry parseShape(ShapeReader reader) {
@@ -50,11 +51,29 @@ public class PolyLineParser extends ShapeParser {
int[] offsets = readOffsets(reader, numParts, numPoints);
+ // Read all coordinates
+ Coordinate[] allCoordinates;
+
+ if (shapeType == ShapeType.POLYLINEZ) {
+ allCoordinates = readCoordinatesWithZM(reader, numPoints);
+ } else if (shapeType == ShapeType.POLYLINEM) {
+ allCoordinates = readCoordinatesWithM(reader, numPoints);
+ } else {
+ allCoordinates = readCoordinates(reader, numPoints);
+ }
+
+ // Create line strings for each part
LineString[] lines = new LineString[numParts];
for (int i = 0; i < numParts; ++i) {
- int readScale = offsets[i + 1] - offsets[i];
- CoordinateSequence csString = readCoordinates(reader, readScale);
- lines[i] = geometryFactory.createLineString(csString);
+ int startIndex = offsets[i];
+ int endIndex = offsets[i + 1];
+ int pointCount = endIndex - startIndex;
+
+ // Extract coordinates for this part
+ Coordinate[] partCoordinates = new Coordinate[pointCount];
+ System.arraycopy(allCoordinates, startIndex, partCoordinates, 0,
pointCount);
+
+ lines[i] = geometryFactory.createLineString(partCoordinates);
}
if (numParts == 1) {
diff --git
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PolygonParser.java
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PolygonParser.java
index 5e26a37c69..c60951fad0 100644
---
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PolygonParser.java
+++
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/PolygonParser.java
@@ -21,7 +21,7 @@ package
org.apache.sedona.core.formatMapper.shapefileParser.parseUtils.shp;
import java.util.ArrayList;
import java.util.List;
import org.locationtech.jts.algorithm.Orientation;
-import org.locationtech.jts.geom.CoordinateSequence;
+import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LinearRing;
@@ -29,13 +29,16 @@ import org.locationtech.jts.geom.Polygon;
public class PolygonParser extends ShapeParser {
+ private final ShapeType shapeType;
+
/**
* create a parser that can abstract a Polygon from input source with given
GeometryFactory.
*
* @param geometryFactory the geometry factory
*/
- public PolygonParser(GeometryFactory geometryFactory) {
+ public PolygonParser(GeometryFactory geometryFactory, ShapeType shapeType) {
super(geometryFactory);
+ this.shapeType = shapeType;
}
/**
@@ -53,6 +56,17 @@ public class PolygonParser extends ShapeParser {
int[] offsets = readOffsets(reader, numRings, numPoints);
+ // Read the coordinates for all rings
+ Coordinate[] allCoordinates;
+
+ if (shapeType == ShapeType.POLYGONZ) {
+ allCoordinates = readCoordinatesWithZM(reader, numPoints);
+ } else if (shapeType == ShapeType.POLYGONM) {
+ allCoordinates = readCoordinatesWithM(reader, numPoints);
+ } else {
+ allCoordinates = readCoordinates(reader, numPoints);
+ }
+
boolean shellsCCW = false;
LinearRing shell = null;
@@ -60,18 +74,24 @@ public class PolygonParser extends ShapeParser {
List<Polygon> polygons = new ArrayList<>();
for (int i = 0; i < numRings; ++i) {
- int readScale = offsets[i + 1] - offsets[i];
- CoordinateSequence csRing = readCoordinates(reader, readScale);
+ int startIndex = offsets[i];
+ int endIndex = offsets[i + 1];
+ int pointCount = endIndex - startIndex;
- if (csRing.size() <= 3) {
+ if (pointCount <= 3) {
continue; // if points less than 3, it's not a ring, we just abandon it
}
- LinearRing ring = geometryFactory.createLinearRing(csRing);
+ // Extract coordinates for this ring
+ Coordinate[] ringCoordinates = new Coordinate[pointCount];
+ System.arraycopy(allCoordinates, startIndex, ringCoordinates, 0,
pointCount);
+
+ LinearRing ring = geometryFactory.createLinearRing(ringCoordinates);
+
if (shell == null) {
shell = ring;
- shellsCCW = Orientation.isCCW(csRing);
- } else if (Orientation.isCCW(csRing) != shellsCCW) {
+ shellsCCW = Orientation.isCCW(ringCoordinates);
+ } else if (Orientation.isCCW(ringCoordinates) != shellsCCW) {
holes.add(ring);
} else {
Polygon polygon =
diff --git
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/ShapeParser.java
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/ShapeParser.java
index 46db5730be..70ec3f6ac8 100644
---
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/ShapeParser.java
+++
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/ShapeParser.java
@@ -18,9 +18,10 @@
*/
package org.apache.sedona.core.formatMapper.shapefileParser.parseUtils.shp;
-import java.io.IOException;
import java.io.Serializable;
-import org.locationtech.jts.geom.CoordinateSequence;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.CoordinateXYM;
+import org.locationtech.jts.geom.CoordinateXYZM;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
@@ -43,26 +44,143 @@ public abstract class ShapeParser implements Serializable {
*
* @param reader the reader
* @return the geometry
- * @throws IOException Signals that an I/O exception has occurred.
*/
public abstract Geometry parseShape(ShapeReader reader);
+ /**
+ * According to the shapefile specification, any floating point number
smaller than -10^38 is
+ * considered a "no data" value. In practice, we also observe that ogrinfo
considers 0 as a "no
+ * data" value.
+ *
+ * @param value The coordinate value to check
+ * @return true if the value is a "no data" value
+ */
+ protected static boolean isNoData(double value) {
+ return value < -1e38 || value == 0;
+ }
+
/**
* read numPoints of coordinates from input source.
*
* @param reader the reader
* @param numPoints the num points
- * @return the coordinate sequence
- * @throws IOException Signals that an I/O exception has occurred.
+ * @return the coordinate array
+ */
+ protected Coordinate[] readCoordinates(ShapeReader reader, int numPoints) {
+ Coordinate[] coordinates = new Coordinate[numPoints];
+
+ for (int i = 0; i < numPoints; ++i) {
+ double x = reader.readDouble();
+ double y = reader.readDouble();
+ coordinates[i] = new Coordinate(x, y);
+ }
+
+ return coordinates;
+ }
+
+ /**
+ * Read coordinates with Z and M values from input source.
+ *
+ * @param reader the reader
+ * @param numPoints the number of points
+ * @return the coordinate array with Z and M values
*/
- protected CoordinateSequence readCoordinates(ShapeReader reader, int
numPoints) {
- CoordinateSequence coordinateSequence =
- geometryFactory.getCoordinateSequenceFactory().create(numPoints, 2);
+ protected Coordinate[] readCoordinatesWithZM(ShapeReader reader, int
numPoints) {
+ double[] x = new double[numPoints];
+ double[] y = new double[numPoints];
+ double[] z = new double[numPoints];
+ double[] m = new double[numPoints];
+
+ // Read all X and Y values
for (int i = 0; i < numPoints; ++i) {
- coordinateSequence.setOrdinate(i, 0, reader.readDouble());
- coordinateSequence.setOrdinate(i, 1, reader.readDouble());
+ x[i] = reader.readDouble();
+ y[i] = reader.readDouble();
}
- return coordinateSequence;
+
+ // Skip Z range (min/max)
+ reader.skip(2 * ShapeFileConst.DOUBLE_LENGTH);
+
+ // Read all Z values
+ for (int i = 0; i < numPoints; ++i) {
+ z[i] = reader.readDouble();
+ }
+
+ // Skip M range (min/max)
+ reader.skip(2 * ShapeFileConst.DOUBLE_LENGTH);
+
+ // Read all M values and check if any are valid data
+ boolean allMNoData = true;
+ for (int i = 0; i < numPoints; ++i) {
+ m[i] = reader.readDouble();
+ // Check if this is a valid M value (not "no data")
+ if (!isNoData(m[i])) {
+ allMNoData = false;
+ }
+ }
+
+ // Create appropriate coordinate objects based on M values
+ Coordinate[] coordinates = new Coordinate[numPoints];
+ if (allMNoData) {
+ // If all M values are nodata, use XYZ coordinates
+ for (int i = 0; i < numPoints; ++i) {
+ coordinates[i] = new Coordinate(x[i], y[i], z[i]);
+ }
+ } else {
+ // If we have valid M values, use XYZM coordinates
+ for (int i = 0; i < numPoints; ++i) {
+ coordinates[i] = new CoordinateXYZM(x[i], y[i], z[i], m[i]);
+ }
+ }
+
+ return coordinates;
+ }
+
+ /**
+ * Read coordinates with M values from input source.
+ *
+ * @param reader the reader
+ * @param numPoints the number of points
+ * @return the coordinate array with M values
+ */
+ protected Coordinate[] readCoordinatesWithM(ShapeReader reader, int
numPoints) {
+ double[] x = new double[numPoints];
+ double[] y = new double[numPoints];
+ double[] m = new double[numPoints];
+
+ // Read all X and Y values
+ for (int i = 0; i < numPoints; ++i) {
+ x[i] = reader.readDouble();
+ y[i] = reader.readDouble();
+ }
+
+ // Skip M range (min/max)
+ reader.skip(2 * ShapeFileConst.DOUBLE_LENGTH);
+
+ // Read all M values
+ boolean allMNoData = true;
+ for (int i = 0; i < numPoints; ++i) {
+ m[i] = reader.readDouble();
+ // Check if this is a valid M value (not "no data")
+ if (!isNoData(m[i])) {
+ allMNoData = false;
+ }
+ }
+
+ // Create appropriate coordinate objects based on M values
+ Coordinate[] coordinates = new Coordinate[numPoints];
+ if (allMNoData) {
+ // If all M values are nodata, use XY coordinates
+ for (int i = 0; i < numPoints; ++i) {
+ coordinates[i] = new Coordinate(x[i], y[i]);
+ }
+ } else {
+ // If we have valid M values, use XYM coordinates
+ for (int i = 0; i < numPoints; ++i) {
+ coordinates[i] = new CoordinateXYM(x[i], y[i], m[i]);
+ }
+ }
+
+ return coordinates;
}
protected int[] readOffsets(ShapeReader reader, int numParts, int maxOffset)
{
diff --git
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/ShapeType.java
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/ShapeType.java
index 12a2191bb3..5f49c2db0f 100644
---
a/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/ShapeType.java
+++
b/spark/common/src/main/java/org/apache/sedona/core/formatMapper/shapefileParser/parseUtils/shp/ShapeType.java
@@ -30,14 +30,14 @@ public enum ShapeType implements Serializable {
POLYLINE(3, true),
POLYGON(5, true),
MULTIPOINT(8, true),
- POINTZ(11, false),
- POLYLINEZ(13, false),
- POLYGONZ(15, false),
- MULTIPOINTZ(18, false),
- POINTM(21, false),
- POLYLINEM(23, false),
- POLYGONM(25, false),
- MULTIPOINTM(28, false),
+ POINTZ(11, true),
+ POLYLINEZ(13, true),
+ POLYGONZ(15, true),
+ MULTIPOINTZ(18, true),
+ POINTM(21, true),
+ POLYLINEM(23, true),
+ POLYGONM(25, true),
+ MULTIPOINTM(28, true),
MULTIPATCH(31, false),
// A normal shapefile should NOT have UNDEFINED type
UNDEFINED(-1, false);
@@ -78,13 +78,21 @@ public enum ShapeType implements Serializable {
public ShapeParser getParser(GeometryFactory geometryFactory) {
switch (this) {
case POINT:
- return new PointParser(geometryFactory);
+ case POINTZ:
+ case POINTM:
+ return new PointParser(geometryFactory, this);
case POLYLINE:
- return new PolyLineParser(geometryFactory);
+ case POLYLINEZ:
+ case POLYLINEM:
+ return new PolyLineParser(geometryFactory, this);
case POLYGON:
- return new PolygonParser(geometryFactory);
+ case POLYGONZ:
+ case POLYGONM:
+ return new PolygonParser(geometryFactory, this);
case MULTIPOINT:
- return new MultiPointParser(geometryFactory);
+ case MULTIPOINTZ:
+ case MULTIPOINTM:
+ return new MultiPointParser(geometryFactory, this);
default:
throw new TypeUnknownException(id);
}
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.csv
new file mode 100644
index 0000000000..2498c8fe2f
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.csv
@@ -0,0 +1,11 @@
+id,wkt
+0,"LINESTRING (90.14286128198324 46.39878836228101, 19.73169683940732
-68.79627191151269, -68.80109593275947 -88.3832775663601, 73.23522915498702
20.223002348641756, 41.61451555920911 -95.88310114083951, 93.98197043239887
66.48852816008434)"
+1,"LINESTRING (-99.84424683179714 98.4423118582435, 23.496301925543307
22.330632097656178, -98.58673895605652 -95.38751499171684, 4.9549320516778295
-20.0278056569489, -90.66686735727691 94.75110376829184, -53.445731913939156
-81.87871309343583, 23.67720186661745 -23.507601746567445, 96.64617716135763
-6.6474213504040165)"
+2,"LINESTRING (21.50897038028768 -65.8951752625417, -86.9896814029441
89.77710745066665, 93.12640661491187 61.67946962329222, -39.07724616532586
-80.46557719872322, 36.846605302431385 -11.969501252079738, -75.59235303104424
-0.9646179777459594, -93.12229577695632 81.8640804157564)"
+3,"LINESTRING (-63.55278244238753 51.07228206353051, -14.968825101751065
-58.411667426362236, 13.540065563998297 -93.73734150888828, 68.45695491899971
-10.04917332604687, -20.969952799637113 85.33177315875884, 45.454399171284166
-34.69184623883292)"
+4,"LINESTRING (-60.80342751617096 -90.95454221789238, -34.933933847347134
-22.2645420621036, -45.730193645220815 65.74750183038586, -28.64933466128214
-43.81309806252385, 8.539216631649694 -71.81515500504747, 60.43939615080794
-85.08987126404584, 97.37738732010345 54.44895385933148, -60.25686369316552
-98.89557657527952)"
+5,"LINESTRING (-60.23151918223897 42.268390549729986, 58.035108106241125
21.19199495620228, 85.26017570266978 30.215405100388892, 82.99193510875617
70.00771555795987, -10.10986517235932 -80.91797670191774)"
+6,"LINESTRING (-34.96333559465059 45.92123566761282, 27.511494271042622
77.44254851526532, -5.557014967610144 -76.08115081233966, 42.648957444599006
52.157009723379474, 12.255439513899248 54.19343599091221, -1.2408807271218478
4.546565876398816, -14.491796328290079 -94.91617465118097, -78.42171460133912
-93.71416286265315)"
+7,"LINESTRING (-37.128803784734664 1.714138232940556, 81.51329478521859
-50.141554170225014, -17.92341539287405 51.11022770860973)"
+8,"LINESTRING (88.5707141115962 19.773093297707206, 38.956986607940905
76.09356780305154, 24.870809626758643 -40.8732628324572, -78.90114803394587
-8.693085903417952, -56.31191255663328 -16.698010425926753, 76.65605178377365
-35.13099579894521)"
+9,"LINESTRING (-28.740432384605015 81.36568830915081, -45.573550123072934
29.538024108272452, -99.89592460093684 -29.4862287331662, -39.04374836839419
-67.06882937141165, 6.817883875088398 -3.034005728203354, 38.48720657805407
-46.11753324029571)"
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.dbf
new file mode 100644
index 0000000000..440aca019a
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.shp
new file mode 100644
index 0000000000..c859c728b3
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.shx
new file mode 100644
index 0000000000..539a21e616
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestring/linestring.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.csv
new file mode 100644
index 0000000000..c88f2e4dec
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_m_value
+0,"LINESTRING M (90.14286128198324 46.39878836228101 59.86584841970366,
-68.79627191151269 -68.80109593275947 5.8083612168199465, 73.23522915498702
20.223002348641756 70.80725777960456, -95.88310114083951 93.98197043239887
83.24426408004217, -57.53217786434477 -63.635006558579875 18.34045098534338,
-39.15155140809246 4.951286326447573 43.194501864211574)",46.87678072428755
+1,"LINESTRING M (4.9549320516778295 -20.0278056569489 4.666566321361543,
94.75110376829184 -53.445731913939156 9.06064345328208, 23.67720186661745
-23.507601746567445 98.32308858067881)",37.35009945177415
+2,"LINESTRING M (-90.70991745600045 21.50897038028768 17.052412368729154,
-86.9896814029441 89.77710745066665 96.56320330745594, 61.67946962329222
-39.07724616532586 9.767211400638388)",41.127609025607825
+3,"LINESTRING M (-51.794906794797654 36.652703765091644 60.99966577826209,
66.63898234723285 -65.3270692984456 39.10606075732408, -63.55278244238753
51.07228206353051 42.51558744912447, -58.411667426362236 13.540065563998297
3.1313292455558583, 68.45695491899971 -10.04917332604687 39.51502360018144,
85.33177315875884 45.454399171284166 32.65407688058354)",36.32029061850525
+4,"LINESTRING M (-60.80342751617096 -90.95454221789238 32.53303307632643,
-22.2645420621036 -45.730193645220815 82.87375091519293, -28.64933466128214
-43.81309806252385 54.26960831582485, -71.81515500504747 60.43939615080794
7.455064367977082, 97.37738732010345 54.44895385933148 19.87156815341724,
-98.89557657527952 63.09228569096683 70.68573438476172, 45.80143360819747
54.25406933718915 7.4044651734090365, -28.306854291145484 -76.82618809497406
86.31034258755935)",45.17544587180858
+5,"LINESTRING M (-33.82039502947016 -87.28832994279527 31.09823217156622,
-34.96333559465059 45.92123566761282 63.75574713552131, 77.44254851526532
-5.557014967610144 11.959424593830171, 42.648957444599006 52.157009723379474
56.127719756949624, 54.19343599091221 -1.2408807271218478 52.27328293819941,
-14.491796328290079 -94.91617465118097 10.789142699330444)",37.66725821589953
+6,"LINESTRING M (-37.128803784734664 1.714138232940556 90.7566473926093,
-50.141554170225014 -17.92341539287405 75.55511385430486, -54.24036690167551
-84.6040180342414 28.9751452913768)",65.09563551276365
+7,"LINESTRING M (76.09356780305154 24.870809626758643 29.5633685837714,
-78.90114803394587 -8.693085903417952 21.84404372168336, -16.698010425926753
76.65605178377365 32.434502100527396, -75.58240905986533 -28.740432384605015
90.6828441545754, -45.573550123072934 29.538024108272452 0.05203769953158188,
-29.4862287331662 -39.04374836839419 16.465585314294174, 6.817883875088398
-3.034005728203354 69.24360328902704, -46.11753324029571 -51.174895550445164
16.829104217293057)",34.639386135087925
+8,"LINESTRING M (-19.23276578839183 -87.02155057820369 25.39154139343447,
-50.62478743227976 39.260854567957665 71.2270589924442, -70.38261400932002
99.54809700978836 26.6781014275285)",41.09890060446906
+9,"LINESTRING M (0.535804645772302 -89.70424975000213 27.864646423661142,
81.65317719333075 -52.08762186660552 14.48948720912231, -2.1094479444873997
97.13009082212014 24.20552715115004, 34.427109481175705 52.323923065743514
23.763754399239968)",22.580853795793367
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.dbf
new file mode 100644
index 0000000000..c83edb3c92
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.shp
new file mode 100644
index 0000000000..001ceb5d97
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.shx
new file mode 100644
index 0000000000..3d84e1343f
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringm/linestringm.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.csv
new file mode 100644
index 0000000000..2e24b6d530
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_z_value
+0,"LINESTRING Z (90.14286128198324 46.39878836228101 29.93292420985183,
-68.79627191151269 -68.80109593275947 2.9041806084099733, 73.23522915498702
20.223002348641756 35.40362888980228, -95.88310114083951 93.98197043239887
41.622132040021086, -57.53217786434477 -63.635006558579875 9.17022549267169,
-39.15155140809246 4.951286326447573 21.597250932105787)",23.438390362143775
+1,"LINESTRING Z (4.9549320516778295 -20.0278056569489 2.3332831606807716,
94.75110376829184 -53.445731913939156 4.53032172664104, 23.67720186661745
-23.507601746567445 49.16154429033941)",18.675049725887074
+2,"LINESTRING Z (-90.70991745600045 21.50897038028768 8.526206184364577,
-86.9896814029441 89.77710745066665 48.28160165372797, 61.67946962329222
-39.07724616532586 4.883605700319194)",20.563804512803912
+3,"LINESTRING Z (-51.794906794797654 36.652703765091644 30.499832889131046,
66.63898234723285 -65.3270692984456 19.55303037866204, -63.55278244238753
51.07228206353051 21.257793724562234, -58.411667426362236 13.540065563998297
1.5656646227779292, 68.45695491899971 -10.04917332604687 19.75751180009072,
85.33177315875884 45.454399171284166 16.32703844029177)",18.160145309252623
+4,"LINESTRING Z (-60.80342751617096 -90.95454221789238 16.266516538163216,
-22.2645420621036 -45.730193645220815 41.436875457596464, -28.64933466128214
-43.81309806252385 27.134804157912424, -71.81515500504747 60.43939615080794
3.727532183988541, 97.37738732010345 54.44895385933148 9.93578407670862,
-98.89557657527952 63.09228569096683 35.34286719238086, 45.80143360819747
54.25406933718915 3.7022325867045183, -28.306854291145484 -76.82618809497406
43.155171293779674)",22.58772293590429
+5,"LINESTRING Z (-33.82039502947016 -87.28832994279527 15.54911608578311,
-34.96333559465059 45.92123566761282 31.877873567760656, 77.44254851526532
-5.557014967610144 5.9797122969150855, 42.648957444599006 52.157009723379474
28.063859878474812, 54.19343599091221 -1.2408807271218478 26.136641469099704,
-14.491796328290079 -94.91617465118097 5.394571349665222)",18.833629107949765
+6,"LINESTRING Z (-37.128803784734664 1.714138232940556 45.37832369630465,
-50.141554170225014 -17.92341539287405 37.77755692715243, -54.24036690167551
-84.6040180342414 14.4875726456884)",32.547817756381825
+7,"LINESTRING Z (76.09356780305154 24.870809626758643 14.7816842918857,
-78.90114803394587 -8.693085903417952 10.92202186084168, -16.698010425926753
76.65605178377365 16.217251050263698, -75.58240905986533 -28.740432384605015
45.3414220772877, -45.573550123072934 29.538024108272452 0.02601884976579094,
-29.4862287331662 -39.04374836839419 8.232792657147087, 6.817883875088398
-3.034005728203354 34.62180164451352, -46.11753324029571 -51.174895550445164
8.414552108646529)",17.319693067543962
+8,"LINESTRING Z (-19.23276578839183 -87.02155057820369 12.695770696717235,
-50.62478743227976 39.260854567957665 35.6135294962221, -70.38261400932002
99.54809700978836 13.33905071376425)",20.54945030223453
+9,"LINESTRING Z (0.535804645772302 -89.70424975000213 13.932323211830571,
81.65317719333075 -52.08762186660552 7.244743604561155, -2.1094479444873997
97.13009082212014 12.10276357557502, 34.427109481175705 52.323923065743514
11.881877199619984)",11.290426897896683
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.dbf
new file mode 100644
index 0000000000..138f29c029
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.shp
new file mode 100644
index 0000000000..f21adf1713
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.shx
new file mode 100644
index 0000000000..cfdcf41747
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringz/linestringz.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.csv
new file mode 100644
index 0000000000..47eb0e1e0c
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_z_value,avg_m_value
+0,"LINESTRING ZM (90.14286128198324 46.39878836228101 29.93292420985183
15.601864044243651, -68.80109593275947 -88.3832775663601 43.308807288746756
60.11150117432088, 41.61451555920911 -95.88310114083951 48.49549260809972
83.24426408004217, -57.53217786434477 -63.635006558579875 9.17022549267169
30.42422429595377, 4.951286326447573 -13.610996271576852 14.561457009902096
61.18528947223795, -72.10122786959164 -41.57107029295637 18.318092164684586
45.606998421703594)",27.297833128992778,49. [...]
+1,"LINESTRING ZM (-60.06524356832805 2.8468876827223255 29.620728443102124
4.645041271999773, 21.50897038028768 -65.8951752625417 3.252579649263976
94.88855372533332, 93.12640661491187 61.67946962329222 15.230688458668535
9.767211400638388, 36.846605302431385 -11.969501252079738 6.101911742238942
49.51769101112702, -93.12229577695632 81.8640804157564 12.938999080000846
66.2522284353982, -37.65778478211781 4.0136042355621555 27.335513967163983
18.485445552552704, 93.91692555291172 55.0265 [...]
+2,"LINESTRING ZM (92.23440486986982 68.90676973563029 37.366005506869044
53.969213238907976, 17.350233132769645 93.05106145282761 30.351712384334235
27.599918202254337, -40.74529885918352 -66.9466121873995 0.7818203370596966
42.340148070636964)",22.833179409420993,41.30309317059976
+3,"LINESTRING ZM (-60.25686369316552 -98.89557657527952 40.77307142274171
70.68573438476172, 45.80143360819747 54.25406933718915 3.7022325867045183
35.84657285442726, -76.82618809497406 72.6206851751187 31.164906341377897
33.08980248526492)",25.213403450274708,46.540703241484636
+4,"LINESTRING ZM (-34.96333559465059 45.92123566761282 31.877873567760656
88.72127425763266, -5.557014967610144 -76.08115081233966 35.66223936114975
76.07850486168974, 12.255439513899248 54.19343599091221 24.689779818219538
52.27328293819941, -14.491796328290079 -94.91617465118097 5.394571349665222
3.142918568673425, 27.282082252756084 -37.128803784734664 25.42853455823514
90.7566473926093, -50.141554170225014 -17.92341539287405 37.77755692715243
22.879816549162246, -84.6040180342414 -42 [...]
+5,"LINESTRING ZM (-16.698010425926753 76.65605178377365 16.217251050263698
12.208795470067335, -28.740432384605015 81.36568830915081 13.606612469231766
64.76901205413623, -99.89592460093684 -29.4862287331662 15.239062907901452
16.465585314294174, 6.817883875088398 -3.034005728203354 34.62180164451352
26.941233379852147, -51.174895550445164 -66.34179156541389 10.938210978653512
55.81020020173412, -19.23276578839183 -87.02155057820369 12.695770696717235
24.68760628386012)",17.2197849578801 [...]
+6,"LINESTRING ZM (42.4541179848884 -70.38261400932002 49.88702425244709
26.6781014275285, 95.32299116653058 -17.792597336353737 1.6525366450274193
34.5071248026683, 26.87026894027275 36.14109031095336 26.54672916585682
44.77831645730917, 10.578617814265584 18.539344775878703 4.042666316635763
36.96544560614045)",20.532239094991773,35.7322470734116
+7,"LINESTRING ZM (45.64326972237191 -26.44337345614936 31.615291529678974
63.35297107608947, 7.1549368149516965 -81.94204598911834 41.7651247794619
32.07800649717358, -62.69629792002915 -91.84497168904721 29.54464715941209
67.75643618422824)",34.308354489517654,54.39580458583043
+8,"LINESTRING ZM (42.22990648760356 61.900209227943094 17.433299364586468
9.617655109142076, 88.1046528979208 -20.485595782495537 25.887567526374006
83.7710105907328, 35.13802340785614 47.04322384815441 10.453581036885684
54.14479738275658, 39.15687986901645 -54.28999564054007 8.74774635479681
98.21683433294356, 3.327178254202863 -47.8341650339182 49.81268498789622
96.54193512887936)",22.466975854107837,68.45844650889087
+9,"LINESTRING ZM (80.08361143266609 26.620291454653582 16.951489552435035
34.92095746126609, 45.191135774047865 79.42205199051543 44.354321213255865
77.98755458576238, 28.40632923085755 -83.17200700099023 8.081435704730689
89.85541885270793, 21.28581193191799 -98.16058967667406 5.0735771433016055
66.35017691080559, -98.98768323075626 -67.83838971650027 27.436689468329305
69.18951976926932, 30.392251900520108 -55.14613810788804 35.6089610673768
23.724908749680008, -34.92006036814645 49.29 [...]
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.dbf
new file mode 100644
index 0000000000..0ccd956c5b
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.shp
new file mode 100644
index 0000000000..1bbe4aace1
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.shx
new file mode 100644
index 0000000000..20e3a953e2
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/linestringzm/linestringzm.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.csv
new file mode 100644
index 0000000000..5b03087d8f
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.csv
@@ -0,0 +1,11 @@
+id,wkt
+0,"MULTIPOINT ((90.14286128198324 46.39878836228101), (19.73169683940732
-68.79627191151269), (-68.80109593275947 -88.3832775663601), (73.23522915498702
20.223002348641756), (41.61451555920911 -95.88310114083951), (93.98197043239887
66.48852816008434))"
+1,"MULTIPOINT ((-99.84424683179714 98.4423118582435), (23.496301925543307
22.330632097656178), (-98.58673895605652 -95.38751499171684),
(4.9549320516778295 -20.0278056569489), (-90.66686735727691 94.75110376829184),
(-53.445731913939156 -81.87871309343583), (23.67720186661745
-23.507601746567445), (96.64617716135763 -6.6474213504040165))"
+2,"MULTIPOINT ((21.50897038028768 -65.8951752625417), (-86.9896814029441
89.77710745066665), (93.12640661491187 61.67946962329222), (-39.07724616532586
-80.46557719872322), (36.846605302431385 -11.969501252079738),
(-75.59235303104424 -0.9646179777459594), (-93.12229577695632
81.8640804157564))"
+3,"MULTIPOINT ((-63.55278244238753 51.07228206353051), (-14.968825101751065
-58.411667426362236), (13.540065563998297 -93.73734150888828),
(68.45695491899971 -10.04917332604687), (-20.969952799637113
85.33177315875884), (45.454399171284166 -34.69184623883292))"
+4,"MULTIPOINT ((-60.80342751617096 -90.95454221789238), (-34.933933847347134
-22.2645420621036), (-45.730193645220815 65.74750183038586),
(-28.64933466128214 -43.81309806252385), (8.539216631649694
-71.81515500504747), (60.43939615080794 -85.08987126404584), (97.37738732010345
54.44895385933148), (-60.25686369316552 -98.89557657527952))"
+5,"MULTIPOINT ((-60.23151918223897 42.268390549729986), (58.035108106241125
21.19199495620228), (85.26017570266978 30.215405100388892), (82.99193510875617
70.00771555795987), (-10.10986517235932 -80.91797670191774))"
+6,"MULTIPOINT ((-34.96333559465059 45.92123566761282), (27.511494271042622
77.44254851526532), (-5.557014967610144 -76.08115081233966),
(42.648957444599006 52.157009723379474), (12.255439513899248
54.19343599091221), (-1.2408807271218478 4.546565876398816),
(-14.491796328290079 -94.91617465118097), (-78.42171460133912
-93.71416286265315))"
+7,"MULTIPOINT ((-37.128803784734664 1.714138232940556), (81.51329478521859
-50.141554170225014), (-17.92341539287405 51.11022770860973))"
+8,"MULTIPOINT ((88.5707141115962 19.773093297707206), (38.956986607940905
76.09356780305154), (24.870809626758643 -40.8732628324572), (-78.90114803394587
-8.693085903417952), (-56.31191255663328 -16.698010425926753),
(76.65605178377365 -35.13099579894521))"
+9,"MULTIPOINT ((-28.740432384605015 81.36568830915081), (-45.573550123072934
29.538024108272452), (-99.89592460093684 -29.4862287331662),
(-39.04374836839419 -67.06882937141165), (6.817883875088398
-3.034005728203354), (38.48720657805407 -46.11753324029571))"
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.dbf
new file mode 100644
index 0000000000..bba4169ad6
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.shp
new file mode 100644
index 0000000000..cb97a7ef17
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.shx
new file mode 100644
index 0000000000..b0e5bbd77e
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipoint/multipoint.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.csv
new file mode 100644
index 0000000000..3bbdc4bf8c
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_m_value
+0,"MULTIPOINT M ((90.14286128198324 46.39878836228101 59.86584841970366),
(-68.79627191151269 -68.80109593275947 5.8083612168199465), (73.23522915498702
20.223002348641756 70.80725777960456), (-95.88310114083951 93.98197043239887
83.24426408004217), (-57.53217786434477 -63.635006558579875 18.34045098534338),
(-39.15155140809246 4.951286326447573 43.194501864211574))",46.87678072428755
+1,"MULTIPOINT M ((4.9549320516778295 -20.0278056569489 4.666566321361543),
(94.75110376829184 -53.445731913939156 9.06064345328208), (23.67720186661745
-23.507601746567445 98.32308858067881))",37.35009945177415
+2,"MULTIPOINT M ((-90.70991745600045 21.50897038028768 17.052412368729154),
(-86.9896814029441 89.77710745066665 96.56320330745594), (61.67946962329222
-39.07724616532586 9.767211400638388))",41.127609025607825
+3,"MULTIPOINT M ((-51.794906794797654 36.652703765091644 60.99966577826209),
(66.63898234723285 -65.3270692984456 39.10606075732408), (-63.55278244238753
51.07228206353051 42.51558744912447), (-58.411667426362236 13.540065563998297
3.1313292455558583), (68.45695491899971 -10.04917332604687 39.51502360018144),
(85.33177315875884 45.454399171284166 32.65407688058354))",36.32029061850525
+4,"MULTIPOINT M ((-60.80342751617096 -90.95454221789238 32.53303307632643),
(-22.2645420621036 -45.730193645220815 82.87375091519293), (-28.64933466128214
-43.81309806252385 54.26960831582485), (-71.81515500504747 60.43939615080794
7.455064367977082), (97.37738732010345 54.44895385933148 19.87156815341724),
(-98.89557657527952 63.09228569096683 70.68573438476172), (45.80143360819747
54.25406933718915 7.4044651734090365), (-28.306854291145484 -76.82618809497406
86.31034258755935))",45.175 [...]
+5,"MULTIPOINT M ((-33.82039502947016 -87.28832994279527 31.09823217156622),
(-34.96333559465059 45.92123566761282 63.75574713552131), (77.44254851526532
-5.557014967610144 11.959424593830171), (42.648957444599006 52.157009723379474
56.127719756949624), (54.19343599091221 -1.2408807271218478 52.27328293819941),
(-14.491796328290079 -94.91617465118097 10.789142699330444))",37.66725821589953
+6,"MULTIPOINT M ((-37.128803784734664 1.714138232940556 90.7566473926093),
(-50.141554170225014 -17.92341539287405 75.55511385430486), (-54.24036690167551
-84.6040180342414 28.9751452913768))",65.09563551276365
+7,"MULTIPOINT M ((76.09356780305154 24.870809626758643 29.5633685837714),
(-78.90114803394587 -8.693085903417952 21.84404372168336), (-16.698010425926753
76.65605178377365 32.434502100527396), (-75.58240905986533 -28.740432384605015
90.6828441545754), (-45.573550123072934 29.538024108272452
0.05203769953158188), (-29.4862287331662 -39.04374836839419
16.465585314294174), (6.817883875088398 -3.034005728203354 69.24360328902704),
(-46.11753324029571 -51.174895550445164 16.829104217293057))" [...]
+8,"MULTIPOINT M ((-19.23276578839183 -87.02155057820369 25.39154139343447),
(-50.62478743227976 39.260854567957665 71.2270589924442), (-70.38261400932002
99.54809700978836 26.6781014275285))",41.09890060446906
+9,"MULTIPOINT M ((0.535804645772302 -89.70424975000213 27.864646423661142),
(81.65317719333075 -52.08762186660552 14.48948720912231), (-2.1094479444873997
97.13009082212014 24.20552715115004), (34.427109481175705 52.323923065743514
23.763754399239968))",22.580853795793367
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.dbf
new file mode 100644
index 0000000000..464f84a3d3
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.shp
new file mode 100644
index 0000000000..3270557c59
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.shx
new file mode 100644
index 0000000000..d87a5c94a1
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointm/multipointm.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.csv
new file mode 100644
index 0000000000..17dcd31701
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_z_value
+0,"MULTIPOINT Z ((90.14286128198324 46.39878836228101 29.93292420985183),
(-68.79627191151269 -68.80109593275947 2.9041806084099733), (73.23522915498702
20.223002348641756 35.40362888980228), (-95.88310114083951 93.98197043239887
41.622132040021086), (-57.53217786434477 -63.635006558579875 9.17022549267169),
(-39.15155140809246 4.951286326447573 21.597250932105787))",23.438390362143775
+1,"MULTIPOINT Z ((4.9549320516778295 -20.0278056569489 2.3332831606807716),
(94.75110376829184 -53.445731913939156 4.53032172664104), (23.67720186661745
-23.507601746567445 49.16154429033941))",18.675049725887074
+2,"MULTIPOINT Z ((-90.70991745600045 21.50897038028768 8.526206184364577),
(-86.9896814029441 89.77710745066665 48.28160165372797), (61.67946962329222
-39.07724616532586 4.883605700319194))",20.563804512803912
+3,"MULTIPOINT Z ((-51.794906794797654 36.652703765091644 30.499832889131046),
(66.63898234723285 -65.3270692984456 19.55303037866204), (-63.55278244238753
51.07228206353051 21.257793724562234), (-58.411667426362236 13.540065563998297
1.5656646227779292), (68.45695491899971 -10.04917332604687 19.75751180009072),
(85.33177315875884 45.454399171284166 16.32703844029177))",18.160145309252623
+4,"MULTIPOINT Z ((-60.80342751617096 -90.95454221789238 16.266516538163216),
(-22.2645420621036 -45.730193645220815 41.436875457596464), (-28.64933466128214
-43.81309806252385 27.134804157912424), (-71.81515500504747 60.43939615080794
3.727532183988541), (97.37738732010345 54.44895385933148 9.93578407670862),
(-98.89557657527952 63.09228569096683 35.34286719238086), (45.80143360819747
54.25406933718915 3.7022325867045183), (-28.306854291145484 -76.82618809497406
43.155171293779674))",22. [...]
+5,"MULTIPOINT Z ((-33.82039502947016 -87.28832994279527 15.54911608578311),
(-34.96333559465059 45.92123566761282 31.877873567760656), (77.44254851526532
-5.557014967610144 5.9797122969150855), (42.648957444599006 52.157009723379474
28.063859878474812), (54.19343599091221 -1.2408807271218478
26.136641469099704), (-14.491796328290079 -94.91617465118097
5.394571349665222))",18.833629107949765
+6,"MULTIPOINT Z ((-37.128803784734664 1.714138232940556 45.37832369630465),
(-50.141554170225014 -17.92341539287405 37.77755692715243), (-54.24036690167551
-84.6040180342414 14.4875726456884))",32.547817756381825
+7,"MULTIPOINT Z ((76.09356780305154 24.870809626758643 14.7816842918857),
(-78.90114803394587 -8.693085903417952 10.92202186084168), (-16.698010425926753
76.65605178377365 16.217251050263698), (-75.58240905986533 -28.740432384605015
45.3414220772877), (-45.573550123072934 29.538024108272452
0.02601884976579094), (-29.4862287331662 -39.04374836839419 8.232792657147087),
(6.817883875088398 -3.034005728203354 34.62180164451352), (-46.11753324029571
-51.174895550445164 8.414552108646529))",1 [...]
+8,"MULTIPOINT Z ((-19.23276578839183 -87.02155057820369 12.695770696717235),
(-50.62478743227976 39.260854567957665 35.6135294962221), (-70.38261400932002
99.54809700978836 13.33905071376425))",20.54945030223453
+9,"MULTIPOINT Z ((0.535804645772302 -89.70424975000213 13.932323211830571),
(81.65317719333075 -52.08762186660552 7.244743604561155), (-2.1094479444873997
97.13009082212014 12.10276357557502), (34.427109481175705 52.323923065743514
11.881877199619984))",11.290426897896683
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.dbf
new file mode 100644
index 0000000000..124a1e5f5b
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.shp
new file mode 100644
index 0000000000..f7fa07583a
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.shx
new file mode 100644
index 0000000000..8f350bc34f
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointz/multipointz.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.csv
new file mode 100644
index 0000000000..282c31031a
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_z_value,avg_m_value
+0,"MULTIPOINT ZM ((90.14286128198324 46.39878836228101 29.93292420985183
15.601864044243651), (-68.80109593275947 -88.3832775663601 43.308807288746756
60.11150117432088), (41.61451555920911 -95.88310114083951 48.49549260809972
83.24426408004217), (-57.53217786434477 -63.635006558579875 9.17022549267169
30.42422429595377), (4.951286326447573 -13.610996271576852 14.561457009902096
61.18528947223795), (-72.10122786959164 -41.57107029295637 18.318092164684586
45.606998421703594))",27.2978331 [...]
+1,"MULTIPOINT ZM ((-60.06524356832805 2.8468876827223255 29.620728443102124
4.645041271999773), (21.50897038028768 -65.8951752625417 3.252579649263976
94.88855372533332), (93.12640661491187 61.67946962329222 15.230688458668535
9.767211400638388), (36.846605302431385 -11.969501252079738 6.101911742238942
49.51769101112702), (-93.12229577695632 81.8640804157564 12.938999080000846
66.2522284353982), (-37.65778478211781 4.0136042355621555 27.335513967163983
18.485445552552704), (93.916925552 [...]
+2,"MULTIPOINT ZM ((92.23440486986982 68.90676973563029 37.366005506869044
53.969213238907976), (17.350233132769645 93.05106145282761 30.351712384334235
27.599918202254337), (-40.74529885918352 -66.9466121873995 0.7818203370596966
42.340148070636964))",22.833179409420993,41.30309317059976
+3,"MULTIPOINT ZM ((-60.25686369316552 -98.89557657527952 40.77307142274171
70.68573438476172), (45.80143360819747 54.25406933718915 3.7022325867045183
35.84657285442726), (-76.82618809497406 72.6206851751187 31.164906341377897
33.08980248526492))",25.213403450274708,46.540703241484636
+4,"MULTIPOINT ZM ((-34.96333559465059 45.92123566761282 31.877873567760656
88.72127425763266), (-5.557014967610144 -76.08115081233966 35.66223936114975
76.07850486168974), (12.255439513899248 54.19343599091221 24.689779818219538
52.27328293819941), (-14.491796328290079 -94.91617465118097 5.394571349665222
3.142918568673425), (27.282082252756084 -37.128803784734664 25.42853455823514
90.7566473926093), (-50.141554170225014 -17.92341539287405 37.77755692715243
22.879816549162246), (-84.6040 [...]
+5,"MULTIPOINT ZM ((-16.698010425926753 76.65605178377365 16.217251050263698
12.208795470067335), (-28.740432384605015 81.36568830915081 13.606612469231766
64.76901205413623), (-99.89592460093684 -29.4862287331662 15.239062907901452
16.465585314294174), (6.817883875088398 -3.034005728203354 34.62180164451352
26.941233379852147), (-51.174895550445164 -66.34179156541389 10.938210978653512
55.81020020173412), (-19.23276578839183 -87.02155057820369 12.695770696717235
24.68760628386012))",17.2 [...]
+6,"MULTIPOINT ZM ((42.4541179848884 -70.38261400932002 49.88702425244709
26.6781014275285), (95.32299116653058 -17.792597336353737 1.6525366450274193
34.5071248026683), (26.87026894027275 36.14109031095336 26.54672916585682
44.77831645730917), (10.578617814265584 18.539344775878703 4.042666316635763
36.96544560614045))",20.532239094991773,35.7322470734116
+7,"MULTIPOINT ZM ((45.64326972237191 -26.44337345614936 31.615291529678974
63.35297107608947), (7.1549368149516965 -81.94204598911834 41.7651247794619
32.07800649717358), (-62.69629792002915 -91.84497168904721 29.54464715941209
67.75643618422824))",34.308354489517654,54.39580458583043
+8,"MULTIPOINT ZM ((42.22990648760356 61.900209227943094 17.433299364586468
9.617655109142076), (88.1046528979208 -20.485595782495537 25.887567526374006
83.7710105907328), (35.13802340785614 47.04322384815441 10.453581036885684
54.14479738275658), (39.15687986901645 -54.28999564054007 8.74774635479681
98.21683433294356), (3.327178254202863 -47.8341650339182 49.81268498789622
96.54193512887936))",22.466975854107837,68.45844650889087
+9,"MULTIPOINT ZM ((80.08361143266609 26.620291454653582 16.951489552435035
34.92095746126609), (45.191135774047865 79.42205199051543 44.354321213255865
77.98755458576238), (28.40632923085755 -83.17200700099023 8.081435704730689
89.85541885270793), (21.28581193191799 -98.16058967667406 5.0735771433016055
66.35017691080559), (-98.98768323075626 -67.83838971650027 27.436689468329305
69.18951976926932), (30.392251900520108 -55.14613810788804 35.6089610673768
23.724908749680008), (-34.9200603 [...]
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.dbf
new file mode 100644
index 0000000000..d42e5b0737
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.shp
new file mode 100644
index 0000000000..8ca0782340
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.shx
new file mode 100644
index 0000000000..b6c4e83e2b
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/multipointzm/multipointzm.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/point/point.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.csv
new file mode 100644
index 0000000000..74fdcef343
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.csv
@@ -0,0 +1,11 @@
+id,wkt
+0,POINT (90.14286128198324 46.39878836228101)
+1,POINT (19.370031589297398 -10.833449429281771)
+2,POINT (-8.150221606826562 -33.258277772195626)
+3,POINT (-95.88310114083951 93.98197043239887)
+4,POINT (87.71054180315002 -99.84424683179714)
+5,POINT (-63.31909802931324 -39.15155140809246)
+6,POINT (-98.58673895605652 -95.38751499171684)
+7,POINT (22.370578944475895 -72.10122786959164)
+8,POINT (94.75110376829184 -53.445731913939156)
+9,POINT (57.03519227860272 -60.06524356832805)
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/point/point.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.dbf
new file mode 100644
index 0000000000..fea3e31ed0
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.dbf differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/point/point.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/point/point.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.shp
new file mode 100644
index 0000000000..bf3ee24f62
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.shp differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/point/point.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.shx
new file mode 100644
index 0000000000..dd0307197b
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/point/point.shx differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.csv
new file mode 100644
index 0000000000..8dcb980856
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_m_value
+0,POINT M (90.14286128198324 46.39878836228101
59.86584841970366),59.86584841970366
+1,POINT M (-68.80109593275947 -88.3832775663601
86.61761457749351),86.61761457749351
+2,POINT M (-71.42663641561185 30.177694589770567
5.641157902710026),5.641157902710026
+3,POINT M (87.71054180315002 -99.84424683179714
99.22115592912175),99.22115592912175
+4,POINT M (-39.15155140809246 4.951286326447573
43.194501864211574),43.194501864211574
+5,POINT M (4.9549320516778295 -20.0278056569489
4.666566321361543),4.666566321361543
+6,POINT M (-26.727631341261656 -8.786003156592813
78.51759613930136),78.51759613930136
+7,POINT M (-23.507601746567445 96.64617716135763
46.67628932479799),46.67628932479799
+8,POINT M (21.50897038028768 -65.8951752625417
6.505159298527952),6.505159298527952
+9,POINT M (88.44035113697055 12.657643569107861
38.54165025399161),38.54165025399161
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.dbf
new file mode 100644
index 0000000000..e068449e7c
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.dbf differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.shp
new file mode 100644
index 0000000000..591ee1d4f4
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.shp differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.shx
new file mode 100644
index 0000000000..711c6c3fe7
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointm/pointm.shx differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.csv
new file mode 100644
index 0000000000..49a65e603e
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_z_value
+0,POINT Z (90.14286128198324 46.39878836228101
29.93292420985183),29.93292420985183
+1,POINT Z (-68.80109593275947 -88.3832775663601
43.308807288746756),43.308807288746756
+2,POINT Z (-71.42663641561185 30.177694589770567
2.820578951355013),2.820578951355013
+3,POINT Z (87.71054180315002 -99.84424683179714
49.610577964560875),49.610577964560875
+4,POINT Z (-39.15155140809246 4.951286326447573
21.597250932105787),21.597250932105787
+5,POINT Z (4.9549320516778295 -20.0278056569489
2.3332831606807716),2.3332831606807716
+6,POINT Z (-26.727631341261656 -8.786003156592813
39.25879806965068),39.25879806965068
+7,POINT Z (-23.507601746567445 96.64617716135763
23.338144662398996),23.338144662398996
+8,POINT Z (21.50897038028768 -65.8951752625417
3.252579649263976),3.252579649263976
+9,POINT Z (88.44035113697055 12.657643569107861
19.270825126995806),19.270825126995806
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.dbf
new file mode 100644
index 0000000000..2df8b4c9a8
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.dbf differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.shp
new file mode 100644
index 0000000000..1d66f40b3b
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.shp differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.shx
new file mode 100644
index 0000000000..29e22cd194
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointz/pointz.shx differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.csv
new file mode 100644
index 0000000000..876be98077
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_z_value,avg_m_value
+0,POINT ZM (90.14286128198324 46.39878836228101 29.93292420985183
15.601864044243651),29.93292420985183,15.601864044243651
+1,POINT ZM (-80.00501683639942 -8.150221606826562 16.685430556951093
14.286681792194077),16.685430556951093,14.286681792194077
+2,POINT ZM (-95.88310114083951 93.98197043239887 41.622132040021086
21.233911067827616),41.622132040021086,21.233911067827616
+3,POINT ZM (-63.31909802931324 -39.15155140809246 26.237821581611893
43.194501864211574),26.237821581611893,43.194501864211574
+4,POINT ZM (4.9549320516778295 -20.0278056569489 2.3332831606807716
97.37555188414592),2.3332831606807716,97.37555188414592
+5,POINT ZM (-81.87871309343583 23.67720186661745 19.12309956335814
98.32308858067881),19.12309956335814,98.32308858067881
+6,POINT ZM (-90.70991745600045 21.50897038028768 8.526206184364577
6.505159298527952),8.526206184364577,6.505159298527952
+7,POINT ZM (88.44035113697055 12.657643569107861 19.270825126995806
1.5966252220214194),19.270825126995806,1.5966252220214194
+8,POINT ZM (36.846605302431385 -11.969501252079738 6.101911742238942
49.51769101112702),6.101911742238942,49.51769101112702
+9,POINT ZM (81.8640804157564 -48.24400367999662 33.1261142176991
31.171107608941096),33.1261142176991,31.171107608941096
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.dbf
new file mode 100644
index 0000000000..86a80d1dd5
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.shp
new file mode 100644
index 0000000000..7ccac35a81
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.shx
new file mode 100644
index 0000000000..ef219aae9b
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/pointzm/pointzm.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.csv
new file mode 100644
index 0000000000..e05dd692f3
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.csv
@@ -0,0 +1,11 @@
+id,wkt
+0,"POLYGON ((41.70666159041656 15.934650307353929, 18.959581443801167
28.276652783158376, 21.33736207785672 31.833345449042223, -8.809610238189547
-6.287791117434656, -5.508830182139233 -48.48443941995607, 41.2381999602147
-13.194778400493654, 41.70666159041656 15.934650307353929))"
+1,"POLYGON ((11.866484469157573 0.05806471562834425, 48.90198180469506
2.1726222417066765, 19.108467324482618 2.788466233357753, -11.015256120419808
8.017762892092229, -34.315448553754464 -5.385239872405156, -19.324263935126194
-16.327458344818417, -36.48929320125967 -33.194953682826224, 28.636193174758077
-1.4024666404171515, 11.866484469157573 0.05806471562834425))"
+2,"POLYGON ((12.761316552870841 5.527226972876495, 17.894869026817627
32.806094236204736, -9.288172563837167 25.99666505166321, -11.611375439319849
-9.30783957239433, 10.693092595921534 -27.823004412101437, 10.793902208628472
-3.5909058213669436, 45.29582369314067 -9.936117322258772, 12.761316552870841
5.527226972876495))"
+3,"POLYGON ((42.848480052114674 8.54080811883779, 11.560640544471475
25.491193492467882, 6.740409478145076 24.91017870847271, -41.95733618454359
21.326595570296963, -35.60727977628798 -16.131289878663168, 0.7767241096988939
-23.048546865470076, 42.848480052114674 8.54080811883779))"
+4,"POLYGON ((30.436177434804762 8.889681184618912, 5.205876646014046
14.744953300091382, -5.628749198805912 41.709792142248915, -2.507423033601905
12.737575210034613, -22.552843800072157 44.03625900121814, -25.41604757630515
32.03122718482692, -13.734095184071233 11.55542513464365, 4.8527464374231855
-8.995406369753473, 30.436177434804762 8.889681184618912))"
+5,"POLYGON ((11.386952331749015 34.19709060745324, -36.6470121080621
-28.782046080507605, -10.583000539990282 -42.70990395413987, 6.987737123421194
-27.091355129963155, 12.361364320934078 -6.171686142652524, 11.386952331749015
34.19709060745324))"
+6,"POLYGON ((23.712381822206865 22.15391735995731, -18.58227654959912
36.366156936157125, -29.299589896589893 5.167693350552343, -20.06550457430521
-23.51087338118386, -6.203361947882142 -26.38213848490893, -1.407808061473616
-10.926444484113661, 0.9693504799194796 -14.28280075025784, 8.546807867930985
-7.326383402385542, 23.712381822206865 22.15391735995731))"
+7,"POLYGON ((-7.8574809247287005 18.3610555703927, -26.37702454642864
-1.421810161882668, 33.62710210803024 -22.068777749944882, -7.8574809247287005
18.3610555703927))"
+8,"POLYGON ((-4.0215267778854225 13.639251900686695, -22.98177276704139
-16.448218120636273, -13.303161989157898 -13.195612537584667,
-9.064775981248731 -25.072029303309883, 33.13610454114727 -30.934078428918916,
21.508692263589055 -8.072898002322466, -4.0215267778854225 13.639251900686695))"
+9,"POLYGON ((22.19113170922037 0.0725569395933478, -2.299072055549393
16.426120362292288, -18.842175030384837 25.072821704921257, -18.20408891679533
23.077506052459825, -22.598278706020157 -30.173082064465298, 17.31686048151462
-11.479939854676935, 22.19113170922037 0.0725569395933478))"
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.dbf
new file mode 100644
index 0000000000..09738efc8d
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++ b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.shp
new file mode 100644
index 0000000000..a458fb392e
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.shx
new file mode 100644
index 0000000000..ed69a07e6f
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygon/polygon.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.csv
new file mode 100644
index 0000000000..20543c98b1
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_m_value
+0,"POLYGON M ((41.70666159041656 15.934650307353929 21.233911067827616,
18.959581443801167 28.276652783158376 18.182496720710063, 21.33736207785672
31.833345449042223 18.34045098534338, -8.809610238189547 -6.287791117434656
30.42422429595377, -5.508830182139233 -48.48443941995607 52.475643163223786,
41.2381999602147 -13.194778400493654 43.194501864211574, 41.70666159041656
15.934650307353929 21.233911067827616))",29.297877023585407
+1,"POLYGON M ((46.86108993758111 14.147874811922128 61.838600933308726,
-15.612887553731037 11.364277788753087 38.24619912671628, -13.459524284903067
-2.1122488528489636 98.32308858067881, 46.86108993758111 14.147874811922128
61.838600933308726))",65.06162239350314
+2,"POLYGON M ((12.06913932621592 3.6260013668623845 80.83973481164611,
22.964184586140956 42.09950922029837 30.46137691733707, -37.940078760941056
-30.413293267135145 9.767211400638388, 12.06913932621592 3.6260013668623845
80.83973481164611))",50.47701448531692
+3,"POLYGON M ((8.00711525635733 15.323542743423822 84.22847745949986,
2.2664377726860865 40.150538780843036 44.975413336976565, -20.92291560185498
17.075372045543055 39.51502360018144, -14.114249819085336 -11.67582367926223
92.66588657937942, -13.316653373277235 -29.87441823237833 72.72719958564208,
5.6177882364384 -9.749867945261256 32.65407688058354, 8.00711525635733
15.323542743423822 84.22847745949986))",64.42779355739468
+4,"POLYGON M ((30.436177434804762 8.889681184618912 81.54614284548342,
5.205876646014046 14.744953300091382 70.68573438476172, -5.628749198805912
41.709792142248915 72.90071680409874, -2.507423033601905 12.737575210034613
77.12703466859458, -22.552843800072157 44.03625900121814 7.4044651734090365,
-25.41604757630515 32.03122718482692 35.84657285442726, -13.734095184071233
11.55542513464365 11.586905952512971, 4.8527464374231855 -8.995406369753473
86.31034258755935, 30.436177434804762 8.8 [...]
+5,"POLYGON M ((41.909216835333304 17.68677639519898 77.0967179954561,
-10.800180712840993 26.79378908576884 49.379559636439076, -6.7268592213431715
13.164695804512663 52.27328293819941, -18.75208353813576 33.65864220610235
42.75410183585496, -26.246991515660678 -30.753759113135715 2.541912674409519,
-4.146852806955778 -32.18503872720037 10.789142699330444, 41.909216835333304
17.68677639519898 77.0967179954561))",44.56163368216367
+6,"POLYGON M ((-7.8574809247287005 18.3610555703927 22.879816549162246,
-26.37702454642864 -1.421810161882668 7.697990982879299, 33.62710210803024
-22.068777749944882 28.9751452913768, -7.8574809247287005 18.3610555703927
22.879816549162246))",20.60819234314515
+7,"POLYGON M ((18.10904811561426 14.137110786580307 30.478125815802905,
2.9320176410473815 14.591860272285897 16.465585314294174, -6.858740820076039
23.26183535093318 53.4089419375442, -40.050910880605834 23.176017921645943
48.48299713589832, -20.111260989428306 5.633162412982033 69.24360328902704,
-25.49335228312198 -25.287251202863953 26.941233379852147, 7.324992504258119
-6.838217580361319 24.412552224777418, 17.906457836703698 -16.133862846217028
16.829104217293057, 18.10904811561426 [...]
+8,"POLYGON M ((18.245752054555567 7.880980070959743 14.808692995339989,
-0.9311175972231766 37.8407169975925 99.77404850489418, -31.67595527153227
21.867266834461514 26.6781014275285, 18.245752054555567 7.880980070959743
14.808692995339989))",39.01738398077566
+9,"POLYGON M ((18.5670135638692 6.224095033703304 24.20552715115004,
-2.827775225751816 15.540618497310001 67.21355474058785, -29.57392013277476
-0.49785888726740746 76.16196153287176, 41.44073501006394 -26.936903189038553
23.763754399239968, 18.5670135638692 6.224095033703304
24.20552715115004))",43.11006499499993
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.dbf
new file mode 100644
index 0000000000..95654229d1
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.shp
new file mode 100644
index 0000000000..79b870f7c3
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.shx
new file mode 100644
index 0000000000..0516e22221
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonm/polygonm.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.csv
new file mode 100644
index 0000000000..20f1ed9023
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_z_value
+0,"POLYGON Z ((41.70666159041656 15.934650307353929 10.616955533913808,
18.959581443801167 28.276652783158376 9.091248360355031, 21.33736207785672
31.833345449042223 9.17022549267169, -8.809610238189547 -6.287791117434656
15.212112147976885, -5.508830182139233 -48.48443941995607 26.237821581611893,
41.2381999602147 -13.194778400493654 21.597250932105787, 41.70666159041656
15.934650307353929 10.616955533913808))",14.648938511792704
+1,"POLYGON Z ((46.86108993758111 14.147874811922128 30.919300466654363,
-15.612887553731037 11.364277788753087 19.12309956335814, -13.459524284903067
-2.1122488528489636 49.16154429033941, 46.86108993758111 14.147874811922128
30.919300466654363))",32.53081119675157
+2,"POLYGON Z ((12.06913932621592 3.6260013668623845 40.419867405823055,
22.964184586140956 42.09950922029837 15.230688458668535, -37.940078760941056
-30.413293267135145 4.883605700319194, 12.06913932621592 3.6260013668623845
40.419867405823055))",25.23850724265846
+3,"POLYGON Z ((8.00711525635733 15.323542743423822 42.11423872974993,
2.2664377726860865 40.150538780843036 22.487706668488283, -20.92291560185498
17.075372045543055 19.75751180009072, -14.114249819085336 -11.67582367926223
46.33294328968971, -13.316653373277235 -29.87441823237833 36.36359979282104,
5.6177882364384 -9.749867945261256 16.32703844029177, 8.00711525635733
15.323542743423822 42.11423872974993))",32.21389677869734
+4,"POLYGON Z ((30.436177434804762 8.889681184618912 40.77307142274171,
5.205876646014046 14.744953300091382 35.34286719238086, -5.628749198805912
41.709792142248915 36.45035840204937, -2.507423033601905 12.737575210034613
38.56351733429729, -22.552843800072157 44.03625900121814 3.7022325867045183,
-25.41604757630515 32.03122718482692 17.92328642721363, -13.734095184071233
11.55542513464365 5.793452976256486, 4.8527464374231855 -8.995406369753473
43.155171293779674, 30.436177434804762 8.8 [...]
+5,"POLYGON Z ((41.909216835333304 17.68677639519898 38.54835899772805,
-10.800180712840993 26.79378908576884 24.689779818219538, -6.7268592213431715
13.164695804512663 26.136641469099704, -18.75208353813576 33.65864220610235
21.37705091792748, -26.246991515660678 -30.753759113135715 1.2709563372047594,
-4.146852806955778 -32.18503872720037 5.394571349665222, 41.909216835333304
17.68677639519898 38.54835899772805))",22.280816841081833
+6,"POLYGON Z ((-7.8574809247287005 18.3610555703927 11.439908274581123,
-26.37702454642864 -1.421810161882668 3.8489954914396494, 33.62710210803024
-22.068777749944882 14.4875726456884, -7.8574809247287005 18.3610555703927
11.439908274581123))",10.304096171572574
+7,"POLYGON Z ((18.10904811561426 14.137110786580307 15.239062907901452,
2.9320176410473815 14.591860272285897 8.232792657147087, -6.858740820076039
23.26183535093318 26.7044709687721, -40.050910880605834 23.176017921645943
24.24149856794916, -20.111260989428306 5.633162412982033 34.62180164451352,
-25.49335228312198 -25.287251202863953 13.470616689926073, 7.324992504258119
-6.838217580361319 12.206276112388709, 17.906457836703698 -16.133862846217028
8.414552108646529, 18.10904811561426 1 [...]
+8,"POLYGON Z ((18.245752054555567 7.880980070959743 7.404346497669994,
-0.9311175972231766 37.8407169975925 49.88702425244709, -31.67595527153227
21.867266834461514 13.33905071376425, 18.245752054555567 7.880980070959743
7.404346497669994))",19.50869199038783
+9,"POLYGON Z ((18.5670135638692 6.224095033703304 12.10276357557502,
-2.827775225751816 15.540618497310001 33.606777370293926, -29.57392013277476
-0.49785888726740746 38.08098076643588, 41.44073501006394 -26.936903189038553
11.881877199619984, 18.5670135638692 6.224095033703304
12.10276357557502))",21.555032497499965
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.dbf
new file mode 100644
index 0000000000..5767ff58b9
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.shp
new file mode 100644
index 0000000000..52cae5a953
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.shx
new file mode 100644
index 0000000000..d3c6a5f135
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonz/polygonz.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.csv
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.csv
new file mode 100644
index 0000000000..199c827b5c
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.csv
@@ -0,0 +1,11 @@
+id,wkt,avg_z_value,avg_m_value
+0,"POLYGON ZM ((41.70666159041656 15.934650307353929 10.616955533913808
18.182496720710063, 18.959581443801167 28.276652783158376 9.17022549267169
30.42422429595377, 21.33736207785672 31.833345449042223 26.237821581611893
43.194501864211574, -8.809610238189547 -6.287791117434656 14.561457009902096
61.18528947223795, -5.508830182139233 -48.48443941995607 6.974693032602092
29.214464853521815, 41.2381999602147 -13.194778400493654 18.318092164684586
45.606998421703594, 41.70666159041656 15.9 [...]
+1,"POLYGON ZM ((46.56898331338859 13.990989132170508 1.7194260557609198
90.9320402078782, 38.84851000096371 16.82620530912882 12.938999080000846
66.2522284353982, 10.623410303615492 19.4755602294708 15.585553804470548
52.00680211778108, 4.324564261851491 13.217396949376441 27.335513967163983
18.485445552552704, -37.21996044033707 -3.337768916723658 48.47923138822793
77.51328233611146, -23.08151370084135 -15.143991173460776 46.97494707820945
89.48273504276489, -11.611375439319849 -9.30783 [...]
+2,"POLYGON ZM ((-0.531856038283361 -31.583207428728333 30.351712384334235
27.599918202254337, 18.73179681209439 -27.737408122860085 14.81367528520412
16.52669390630025, 47.170778631306334 -11.74182193060945 0.7818203370596966
42.340148070636964, -0.531856038283361 -31.583207428728333 30.351712384334235
27.599918202254337))",19.074730097733074,28.51666959536147
+3,"POLYGON ZM ((38.251257885695885 1.327717033925345 3.7022325867045183
35.84657285442726, 12.401338566559199 37.14478237759088 5.793452976256486
86.31034258755935, 16.332441713467276 -37.443829148582616 31.164906341377897
33.08980248526492, 38.251257885695885 1.327717033925345 3.7022325867045183
35.84657285442726))",11.090706122760855,47.773322695419694
+4,"POLYGON ZM ((23.712381822206865 22.15391735995731 31.82052056318902
31.435598107632668, -18.58227654959912 36.366156936157125 25.42853455823514
90.7566473926093, -29.299589896589893 5.167693350552343 12.464611457443747
41.038292303562976, -20.06550457430521 -23.51087338118386 37.77755692715243
22.879816549162246, -6.203361947882142 -26.38213848490893 3.8489954914396494
28.9751452913768, -1.407808061473616 -10.926444484113661 8.061064362700222
92.96976523425731, 0.9693504799194796 -14. [...]
+5,"POLYGON ZM ((15.035854443559627 14.495461997053512 26.7044709687721
48.48299713589832, -16.169907506387755 32.06072636829943 34.62180164451352
26.941233379852147, -6.206191086432835 7.867650669830345 12.206276112388709
16.829104217293057, -20.86172045720219 12.071925371030966 10.938210978653512
55.81020020173412, 16.48636019497653 -14.854343424296557 20.191808552902042
6.4892247108981564, 13.824349345360458 -9.164634616314677 12.695770696717235
24.68760628386012, 15.035854443559627 14 [...]
+6,"POLYGON ZM ((29.314482257709205 39.344579420273355 31.717567235068188
68.07054515547668, -2.78277987909318 26.294638786399297 26.54672916585682
44.77831645730917, -2.658941450370277 -11.005379511691679 27.644654453566396
59.26967238793935, 23.800451188432937 -0.3379165457263681 4.042666316635763
36.96544560614045, 29.314482257709205 39.344579420273355 31.717567235068188
68.07054515547668))",24.33383688123907,55.43090495246846
+7,"POLYGON ZM ((-23.831525817123204 26.097087517639952 41.7651247794619
32.07800649717358, -21.18179386210017 -23.221511048938094 9.325925519992712
4.077514155476392, -1.8572167880639567 -13.484292712931765 29.54464715941209
67.75643618422824, -23.831525817123204 26.097087517639952 41.7651247794619
32.07800649717358))",30.60020555958215,33.99749083351295
+8,"POLYGON ZM ((21.315553634817178 14.717554458327566 10.453581036885684
54.14479738275658, -17.842038538227968 24.995381148908677 34.78921996725411
22.855002179729965, -10.515444022744038 -42.21855843338597 8.74774635479681
98.21683433294356, 13.522773042763449 -34.469959641528824 25.831794563550716
26.0829174830409, 36.68872972595332 -14.386743678640567 49.81268498789622
96.54193512887936, 21.315553634817178 14.717554458327566 10.453581036885684
54.14479738275658))",23.34810132454487,5 [...]
+9,"POLYGON ZM ((-21.860955877920954 34.9160197048927 5.0735771433016055
66.35017691080559, -20.829300271494844 28.970553715541413 0.25307919231093434
16.080805141749867, -8.957792569013405 -9.919535181728836 27.436689468329305
69.18951976926932, -2.478019692722577 -16.27760841247803 32.59806297513003
22.42693094605598, 34.85704665378713 -29.927730567964282 35.6089610673768
23.724908749680008, 27.344476315286652 -20.63571636289331 16.269984907963387
74.64914051180241, 8.403771358961695 -6 [...]
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.dbf
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.dbf
new file mode 100644
index 0000000000..a4ddef237a
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.prj
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.prj
new file mode 100644
index 0000000000..f45cbadf00
--- /dev/null
+++
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.shp
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.shp
new file mode 100644
index 0000000000..9856c3896b
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.shx
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.shx
new file mode 100644
index 0000000000..d52e70bd8e
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/shapetypes/polygonzm/polygonzm.shx
differ
diff --git
a/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.dbf
b/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.dbf
deleted file mode 100644
index 936df45637..0000000000
Binary files
a/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.dbf
and /dev/null differ
diff --git
a/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.prj
b/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.prj
deleted file mode 100644
index 2c385eb31f..0000000000
---
a/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.prj
+++ /dev/null
@@ -1 +0,0 @@
-PROJCS["Belge_Lambert_1972",GEOGCS["GCS_Belge_1972",DATUM["D_Belge_1972",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",150000.01256],PARAMETER["False_Northing",5400088.4378],PARAMETER["Central_Meridian",4.367486666666666],PARAMETER["Standard_Parallel_1",49.8333339],PARAMETER["Standard_Parallel_2",51.16666723333333],PARAMETER["Latitude_Of_Origin",90.0],UNIT["Meter",1.0]]
\ No newline at end of file
diff --git
a/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.shp
b/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.shp
deleted file mode 100644
index 055d2c41ff..0000000000
Binary files
a/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.shp
and /dev/null differ
diff --git
a/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.shx
b/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.shx
deleted file mode 100644
index 46fc61568d..0000000000
Binary files
a/spark/common/src/test/resources/shapefiles/unsupported/UrbAdm3D_142166_Bu_Ground.shx
and /dev/null differ
diff --git
a/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.dbf
b/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.dbf
new file mode 100644
index 0000000000..2682ea95ad
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.dbf
differ
diff --git
a/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.shp
b/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.shp
new file mode 100644
index 0000000000..6bf4724731
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.shp
differ
diff --git
a/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.shx
b/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.shx
new file mode 100644
index 0000000000..d695bc94fb
Binary files /dev/null and
b/spark/common/src/test/resources/shapefiles/unsupported/multipatches_pyshp.shx
differ
diff --git
a/spark/spark-3.3/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
b/spark/spark-3.3/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
index 5f1e34bbe2..bb53131475 100644
--- a/spark/spark-3.3/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
+++ b/spark/spark-3.3/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
@@ -22,10 +22,12 @@ import org.apache.commons.io.FileUtils
import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
import org.apache.spark.sql.types.{DateType, DecimalType, LongType,
StringType, StructField, StructType}
import org.locationtech.jts.geom.{Geometry, MultiPolygon, Point, Polygon}
+import org.locationtech.jts.io.{WKTReader, WKTWriter}
import org.scalatest.BeforeAndAfterAll
import java.io.File
import java.nio.file.Files
+import scala.collection.mutable
class ShapefileTests extends TestBaseScala with BeforeAndAfterAll {
val temporaryLocation: String = resourceFolder + "shapefiles/tmp"
@@ -190,24 +192,12 @@ class ShapefileTests extends TestBaseScala with
BeforeAndAfterAll {
.load(resourceFolder + "shapefiles/unsupported")
val schema = shapefileDf.schema
assert(schema.find(_.name == "geometry").get.dataType == GeometryUDT)
- assert(schema.find(_.name == "ID").get.dataType == StringType)
- assert(schema.find(_.name == "LOD").get.dataType == LongType)
- assert(schema.find(_.name == "Parent_ID").get.dataType == StringType)
- assert(schema.length == 4)
val rows = shapefileDf.collect()
- assert(rows.length == 20)
- var nonNullLods = 0
+ assert(rows.length == 10)
rows.foreach { row =>
assert(row.getAs[Geometry]("geometry") == null)
- assert(row.getAs[String]("ID").nonEmpty)
- val lodIndex = row.fieldIndex("LOD")
- if (!row.isNullAt(lodIndex)) {
- assert(row.getAs[Long]("LOD") == 2)
- nonNullLods += 1
- }
- assert(row.getAs[String]("Parent_ID").nonEmpty)
+ assert(!row.isNullAt(row.fieldIndex("id")))
}
- assert(nonNullLods == 17)
}
it("read bad_shx") {
@@ -723,5 +713,60 @@ class ShapefileTests extends TestBaseScala with
BeforeAndAfterAll {
assert(row.isNullAt(row.fieldIndex("code2")))
}
}
+
+ it("should read shapes of various types") {
+ // There are multiple directories under shapefiles/shapetypes, each
containing a shapefile.
+ // We'll iterate over each directory and read the shapefile within it.
+ val shapeTypesDir = new File(resourceFolder + "shapefiles/shapetypes")
+ val shapeTypeDirs = shapeTypesDir.listFiles().filter(_.isDirectory)
+ shapeTypeDirs.foreach { shapeTypeDir =>
+ val fileName = shapeTypeDir.getName
+ val hasZ = fileName.endsWith("zm") || fileName.endsWith("z")
+ val hasM = fileName.endsWith("zm") || fileName.endsWith("m")
+ val shapeType =
+ if (fileName.startsWith("point")) "POINT"
+ else if (fileName.startsWith("linestring")) "LINESTRING"
+ else if (fileName.startsWith("multipoint")) "MULTIPOINT"
+ else "POLYGON"
+ val expectedWktPrefix =
+ if (!hasZ && !hasM) shapeType
+ else {
+ shapeType + " " + (if (hasZ) "Z" else "") + (if (hasM) "M" else "")
+ }
+
+ val shapefileDf = sparkSession.read
+ .format("shapefile")
+ .load(shapeTypeDir.getAbsolutePath)
+ val schema = shapefileDf.schema
+ assert(schema.find(_.name == "geometry").get.dataType == GeometryUDT)
+ val rows = shapefileDf.collect()
+ assert(rows.length > 0)
+
+ // Validate the geometry type and WKT prefix
+ val wktWriter = new WKTWriter(4)
+ val rowsMap = mutable.Map[String, Geometry]()
+ rows.foreach { row =>
+ val id = row.getAs[String]("id")
+ val geom = row.getAs[Geometry]("geometry")
+ val wkt = wktWriter.write(geom)
+ assert(wkt.startsWith(expectedWktPrefix))
+ assert(geom != null)
+ rowsMap.put(id, geom)
+ }
+
+ // Validate the geometry values by reading the CSV file containing the
same data
+ val csvDf = sparkSession.read
+ .format("csv")
+ .option("header", "true")
+ .load(shapeTypeDir.getAbsolutePath + "/*.csv")
+ val wktReader = new WKTReader()
+ csvDf.collect().foreach { row =>
+ val id = row.getAs[String]("id")
+ val wkt = row.getAs[String]("wkt")
+ val geom = wktReader.read(wkt)
+ assert(rowsMap(id).equals(geom))
+ }
+ }
+ }
}
}
diff --git
a/spark/spark-3.4/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
b/spark/spark-3.4/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
index 5f1e34bbe2..bb53131475 100644
--- a/spark/spark-3.4/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
+++ b/spark/spark-3.4/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
@@ -22,10 +22,12 @@ import org.apache.commons.io.FileUtils
import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
import org.apache.spark.sql.types.{DateType, DecimalType, LongType,
StringType, StructField, StructType}
import org.locationtech.jts.geom.{Geometry, MultiPolygon, Point, Polygon}
+import org.locationtech.jts.io.{WKTReader, WKTWriter}
import org.scalatest.BeforeAndAfterAll
import java.io.File
import java.nio.file.Files
+import scala.collection.mutable
class ShapefileTests extends TestBaseScala with BeforeAndAfterAll {
val temporaryLocation: String = resourceFolder + "shapefiles/tmp"
@@ -190,24 +192,12 @@ class ShapefileTests extends TestBaseScala with
BeforeAndAfterAll {
.load(resourceFolder + "shapefiles/unsupported")
val schema = shapefileDf.schema
assert(schema.find(_.name == "geometry").get.dataType == GeometryUDT)
- assert(schema.find(_.name == "ID").get.dataType == StringType)
- assert(schema.find(_.name == "LOD").get.dataType == LongType)
- assert(schema.find(_.name == "Parent_ID").get.dataType == StringType)
- assert(schema.length == 4)
val rows = shapefileDf.collect()
- assert(rows.length == 20)
- var nonNullLods = 0
+ assert(rows.length == 10)
rows.foreach { row =>
assert(row.getAs[Geometry]("geometry") == null)
- assert(row.getAs[String]("ID").nonEmpty)
- val lodIndex = row.fieldIndex("LOD")
- if (!row.isNullAt(lodIndex)) {
- assert(row.getAs[Long]("LOD") == 2)
- nonNullLods += 1
- }
- assert(row.getAs[String]("Parent_ID").nonEmpty)
+ assert(!row.isNullAt(row.fieldIndex("id")))
}
- assert(nonNullLods == 17)
}
it("read bad_shx") {
@@ -723,5 +713,60 @@ class ShapefileTests extends TestBaseScala with
BeforeAndAfterAll {
assert(row.isNullAt(row.fieldIndex("code2")))
}
}
+
+ it("should read shapes of various types") {
+ // There are multiple directories under shapefiles/shapetypes, each
containing a shapefile.
+ // We'll iterate over each directory and read the shapefile within it.
+ val shapeTypesDir = new File(resourceFolder + "shapefiles/shapetypes")
+ val shapeTypeDirs = shapeTypesDir.listFiles().filter(_.isDirectory)
+ shapeTypeDirs.foreach { shapeTypeDir =>
+ val fileName = shapeTypeDir.getName
+ val hasZ = fileName.endsWith("zm") || fileName.endsWith("z")
+ val hasM = fileName.endsWith("zm") || fileName.endsWith("m")
+ val shapeType =
+ if (fileName.startsWith("point")) "POINT"
+ else if (fileName.startsWith("linestring")) "LINESTRING"
+ else if (fileName.startsWith("multipoint")) "MULTIPOINT"
+ else "POLYGON"
+ val expectedWktPrefix =
+ if (!hasZ && !hasM) shapeType
+ else {
+ shapeType + " " + (if (hasZ) "Z" else "") + (if (hasM) "M" else "")
+ }
+
+ val shapefileDf = sparkSession.read
+ .format("shapefile")
+ .load(shapeTypeDir.getAbsolutePath)
+ val schema = shapefileDf.schema
+ assert(schema.find(_.name == "geometry").get.dataType == GeometryUDT)
+ val rows = shapefileDf.collect()
+ assert(rows.length > 0)
+
+ // Validate the geometry type and WKT prefix
+ val wktWriter = new WKTWriter(4)
+ val rowsMap = mutable.Map[String, Geometry]()
+ rows.foreach { row =>
+ val id = row.getAs[String]("id")
+ val geom = row.getAs[Geometry]("geometry")
+ val wkt = wktWriter.write(geom)
+ assert(wkt.startsWith(expectedWktPrefix))
+ assert(geom != null)
+ rowsMap.put(id, geom)
+ }
+
+ // Validate the geometry values by reading the CSV file containing the
same data
+ val csvDf = sparkSession.read
+ .format("csv")
+ .option("header", "true")
+ .load(shapeTypeDir.getAbsolutePath + "/*.csv")
+ val wktReader = new WKTReader()
+ csvDf.collect().foreach { row =>
+ val id = row.getAs[String]("id")
+ val wkt = row.getAs[String]("wkt")
+ val geom = wktReader.read(wkt)
+ assert(rowsMap(id).equals(geom))
+ }
+ }
+ }
}
}
diff --git
a/spark/spark-3.5/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
b/spark/spark-3.5/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
index b1764e6e21..a0cadc8978 100644
--- a/spark/spark-3.5/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
+++ b/spark/spark-3.5/src/test/scala/org/apache/sedona/sql/ShapefileTests.scala
@@ -22,10 +22,12 @@ import org.apache.commons.io.FileUtils
import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
import org.apache.spark.sql.types.{DateType, DecimalType, LongType,
StringType, StructField, StructType}
import org.locationtech.jts.geom.{Geometry, MultiPolygon, Point, Polygon}
+import org.locationtech.jts.io.{WKTReader, WKTWriter}
import org.scalatest.BeforeAndAfterAll
import java.io.File
import java.nio.file.Files
+import scala.collection.mutable
class ShapefileTests extends TestBaseScala with BeforeAndAfterAll {
val temporaryLocation: String = resourceFolder + "shapefiles/tmp"
@@ -190,24 +192,12 @@ class ShapefileTests extends TestBaseScala with
BeforeAndAfterAll {
.load(resourceFolder + "shapefiles/unsupported")
val schema = shapefileDf.schema
assert(schema.find(_.name == "geometry").get.dataType == GeometryUDT)
- assert(schema.find(_.name == "ID").get.dataType == StringType)
- assert(schema.find(_.name == "LOD").get.dataType == LongType)
- assert(schema.find(_.name == "Parent_ID").get.dataType == StringType)
- assert(schema.length == 4)
val rows = shapefileDf.collect()
- assert(rows.length == 20)
- var nonNullLods = 0
+ assert(rows.length == 10)
rows.foreach { row =>
assert(row.getAs[Geometry]("geometry") == null)
- assert(row.getAs[String]("ID").nonEmpty)
- val lodIndex = row.fieldIndex("LOD")
- if (!row.isNullAt(lodIndex)) {
- assert(row.getAs[Long]("LOD") == 2)
- nonNullLods += 1
- }
- assert(row.getAs[String]("Parent_ID").nonEmpty)
+ assert(!row.isNullAt(row.fieldIndex("id")))
}
- assert(nonNullLods == 17)
}
it("read bad_shx") {
@@ -735,5 +725,60 @@ class ShapefileTests extends TestBaseScala with
BeforeAndAfterAll {
assert(row.isNullAt(row.fieldIndex("code2")))
}
}
+
+ it("should read shapes of various types") {
+ // There are multiple directories under shapefiles/shapetypes, each
containing a shapefile.
+ // We'll iterate over each directory and read the shapefile within it.
+ val shapeTypesDir = new File(resourceFolder + "shapefiles/shapetypes")
+ val shapeTypeDirs = shapeTypesDir.listFiles().filter(_.isDirectory)
+ shapeTypeDirs.foreach { shapeTypeDir =>
+ val fileName = shapeTypeDir.getName
+ val hasZ = fileName.endsWith("zm") || fileName.endsWith("z")
+ val hasM = fileName.endsWith("zm") || fileName.endsWith("m")
+ val shapeType =
+ if (fileName.startsWith("point")) "POINT"
+ else if (fileName.startsWith("linestring")) "LINESTRING"
+ else if (fileName.startsWith("multipoint")) "MULTIPOINT"
+ else "POLYGON"
+ val expectedWktPrefix =
+ if (!hasZ && !hasM) shapeType
+ else {
+ shapeType + " " + (if (hasZ) "Z" else "") + (if (hasM) "M" else "")
+ }
+
+ val shapefileDf = sparkSession.read
+ .format("shapefile")
+ .load(shapeTypeDir.getAbsolutePath)
+ val schema = shapefileDf.schema
+ assert(schema.find(_.name == "geometry").get.dataType == GeometryUDT)
+ val rows = shapefileDf.collect()
+ assert(rows.length > 0)
+
+ // Validate the geometry type and WKT prefix
+ val wktWriter = new WKTWriter(4)
+ val rowsMap = mutable.Map[String, Geometry]()
+ rows.foreach { row =>
+ val id = row.getAs[String]("id")
+ val geom = row.getAs[Geometry]("geometry")
+ val wkt = wktWriter.write(geom)
+ assert(wkt.startsWith(expectedWktPrefix))
+ assert(geom != null)
+ rowsMap.put(id, geom)
+ }
+
+ // Validate the geometry values by reading the CSV file containing the
same data
+ val csvDf = sparkSession.read
+ .format("csv")
+ .option("header", "true")
+ .load(shapeTypeDir.getAbsolutePath + "/*.csv")
+ val wktReader = new WKTReader()
+ csvDf.collect().foreach { row =>
+ val id = row.getAs[String]("id")
+ val wkt = row.getAs[String]("wkt")
+ val geom = wktReader.read(wkt)
+ assert(rowsMap(id).equals(geom))
+ }
+ }
+ }
}
}