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))
+        }
+      }
+    }
   }
 }

Reply via email to