Skip to content

Commit

Permalink
from/toWKB file IO
Browse files Browse the repository at this point in the history
other small things
  • Loading branch information
micycle1 committed Jul 28, 2023
1 parent 4edb64b commit af901f5
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `align()` to `PGS_Transformation`. Aligns one polygon shape to another, by finding the optimal transformation.
* `extractInnerEdges()` to `PGS_Meshing`. Extracts all inner edges from a mesh.
* `centerLine()` to `PGS_Contour`. Determines the longest center line passing through a given shape.
* Additional signatures for `PGS_Conversion.toWKB()` and `.fromWKB()` that write/read the binary shape representation into a file.

### Changed
* Reimplemented `PGS_Processing.equalParition()`. New algorithm is ~2x faster. Also removed `precise` parameter from method signature (no longer necessary).
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/micycle/pgs/PGS_Conversion.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
Expand All @@ -30,6 +31,7 @@
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.io.FileUtils;
import org.jgrapht.alg.drawing.IndexedFRLayoutAlgorithm2D;
import org.jgrapht.alg.drawing.LayoutAlgorithm2D;
import org.jgrapht.alg.drawing.model.Box2D;
Expand Down Expand Up @@ -1093,6 +1095,25 @@ public static byte[] toWKB(PShape shape) {
return writer.write(fromPShape(shape));
}

/**
* Converts a shape into <i>Well-Known Binary</i> format and writes the bytes to
* a file.
*
* @param shape shape to process
* @param filename Absolute file path (with filename and extension). Prefix with
* "./" for a relative path.
* @since 1.3.1
*/
public static void toWKB(PShape shape, String filename) {
WKBWriter writer = new WKBWriter();
byte[] bytes = writer.write(fromPShape(shape));
try {
FileUtils.writeByteArrayToFile(new File(filename), bytes);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* Converts a geometry in <i>Well-Known Binary</i> format into a PShape.
*
Expand All @@ -1110,6 +1131,27 @@ public static PShape fromWKB(byte[] shapeWKB) {
}
}

/**
* Reads a shape from a (binary) file containing the <i>Well-Known Binary</i>
* representation of it.
*
* @param filename Absolute file path (with filename and extension). Prefix with
* "./" for a relative path.
* @return a PShape specified by the WKB in the file
*/
public static PShape fromWKB(String filename) {
byte[] shapeWKB;
try {
shapeWKB = FileUtils.readFileToByteArray(new File(filename));
WKBReader reader = new WKBReader();
return toPShape(reader.read(shapeWKB));
} catch (IOException | ParseException e) {
e.printStackTrace();
return new PShape();
}

}

/**
* Writes a shape into the hexadecimal string representation of its
* <i>Well-Known Binary</i> format.
Expand Down
31 changes: 21 additions & 10 deletions src/main/java/micycle/pgs/PGS_SegmentSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineSegment;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Location;
import org.locationtech.jts.geom.util.LineStringExtracter;
import org.locationtech.jts.geom.util.LinearComponentExtracter;
import org.locationtech.jts.noding.MCIndexSegmentSetMutualIntersector;
import org.locationtech.jts.noding.NodedSegmentString;
import org.locationtech.jts.noding.SegmentIntersector;
Expand Down Expand Up @@ -409,6 +412,9 @@ public static PShape toPShape(Collection<PEdge> segments, @Nullable Integer stro
*/
public static PShape dissolve(Collection<PEdge> segments) {
Geometry g = SegmentStringUtil.toGeometry(fromPEdges(segments), PGS.GEOM_FACTORY);
if (g.isEmpty()) {
return new PShape();
}
Geometry dissolved = LineDissolver.dissolve(g);
return PGS_Conversion.toPShape(dissolved);
}
Expand All @@ -419,25 +425,30 @@ public static PShape dissolve(Collection<PEdge> segments) {
* This method iterates through all the child shapes of the input shape,
* creating PEdge segments for each pair of consecutive vertices.
*
* @param shape shape from which to extract the edges.
* @return list of unique PEdge segments representing the edges of the input
* @param shape The shape from which to extract the edges. Supports holes and
* GROUP shapes.
* @return A list of unique PEdge segments representing the edges of the input
* shape and its child shapes.
* @since 1.3.1
*/
public static List<PEdge> fromPShape(PShape shape) {
Set<PEdge> edges = new HashSet<>(shape.getVertexCount() / 2);
for (PShape child : PGS_Conversion.getChildren(shape)) {
for (int i = 0; i < child.getVertexCount(); i++) {
final PVector a = child.getVertex(i);
final PVector b = child.getVertex((i + 1) % child.getVertexCount());
List<PEdge> edges = new ArrayList<>(shape.getFamily() != PShape.GROUP ? shape.getVertexCount() : shape.getChildCount() * 4);
@SuppressWarnings("unchecked")
List<LineString> strings = LinearComponentExtracter.getLines(PGS_Conversion.fromPShape(shape));
strings.forEach(s -> {
Coordinate[] coords = s.getCoordinates();
boolean closed = coords[0].equals2D(coords[coords.length - 1]);
for (int i = 0; i < coords.length - (closed ? 0 : 1); i++) {
Coordinate a = coords[i];
Coordinate b = coords[(i + 1) % coords.length];
if (a.equals(b)) {
continue;
}
final PEdge e = new PEdge(a, b);
final PEdge e = new PEdge(a.x, a.y, b.x, b.y);
edges.add(e);
}
}
return new ArrayList<>(edges);
});
return edges;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/micycle/pgs/PGS_Transformation.java
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ public static PShape align(PShape sourceShape, PShape transformShape) {
public static PShape align(PShape alignShape, PShape baseShape, double alignmentRatio) {
final Geometry g1 = fromPShape(alignShape);
final Geometry g2 = fromPShape(baseShape);
if (g1.getGeometryType() != Geometry.TYPENAME_POLYGON || g2.getGeometryType() != Geometry.TYPENAME_POLYGON) {
if (!g1.getGeometryType().equals(Geometry.TYPENAME_POLYGON) || !g2.getGeometryType().equals(Geometry.TYPENAME_POLYGON)) {
throw new IllegalArgumentException("Inputs to align() must be polygons.");
}
if (((Polygon) g1).getNumInteriorRing() > 0 || ((Polygon) g2).getNumInteriorRing() > 0) {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/micycle/pgs/commons/AreaMerge.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ private static <V, E> void mergeVertices(Graph<V, E> graph, V keep, V remove) {
static class FaceGroup implements Comparable<FaceGroup> {

private double area;
private Map<PShape, Double> faces; // faces comprising this group (and their areas)
/** A map of faces comprising this group and their respective areas. */
private Map<PShape, Double> faces;
private Set<PShape> neighborFaces; // union of neighbors of each face - faces themselves
private final NeighborCache<PShape, DefaultEdge> neighborCache;

Expand Down

0 comments on commit af901f5

Please sign in to comment.