Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand All @@ -46,8 +49,21 @@ public MultiPointParser(GeometryFactory geometryFactory) {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,57 @@
*/
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;
}

/**
* abstract a Point shape.
*
* @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));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,30 @@
*/
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;
}

/**
* abstract a Polyline shape.
*
* @param reader the reader
* @return the geometry
* @throws IOException Signals that an I/O exception has occurred.
*/
@Override
public Geometry parseShape(ShapeReader reader) {
Expand All @@ -50,11 +51,29 @@ public Geometry parseShape(ShapeReader reader) {

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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,24 @@
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;
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;
}

/**
Expand All @@ -53,25 +56,42 @@ public Geometry parseShape(ShapeReader reader) {

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;
List<LinearRing> holes = new ArrayList<>();
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 =
Expand Down
Loading
Loading