Skip to content

Commit

Permalink
Improve OffsetCurve to handle mitre joins for polygons
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-jts committed Jan 7, 2025
1 parent e1c9a7c commit f997d40
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
3 changes: 3 additions & 0 deletions include/geos/operation/buffer/OffsetCurve.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class GEOS_DLL OffsetCurve {

// Methods

std::unique_ptr<Geometry> computePolygonCurve(
const Polygon& polyGeom, double distance);

std::unique_ptr<Geometry> computeCurve(
const LineString& lineGeom, double distance);

Expand Down
26 changes: 17 additions & 9 deletions src/operation/buffer/OffsetCurve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,7 @@ OffsetCurve::getCurve()

if (geom.getGeometryTypeId() == GEOS_POINT) return nullptr;
if (geom.getGeometryTypeId() == GEOS_POLYGON) {
auto boundary = geom.buffer(distance)->getBoundary();

if (boundary->getGeometryTypeId() == GEOS_LINEARRING) {
const LinearRing& ring = static_cast<const LinearRing&>(geom);
auto ringCs = ring.getCoordinatesRO();
std::unique_ptr<Geometry> ls(geom.getFactory()->createLineString(*ringCs));
return ls;
}
return boundary;
return computePolygonCurve(static_cast<const Polygon&>(geom), distance);
}
return computeCurve(static_cast<const LineString&>(geom), distance);
};
Expand Down Expand Up @@ -141,6 +133,22 @@ OffsetCurve::rawOffset(const LineString& line, double dist)
return rawOffsetCurve(line, dist, bufParams);
}

/* private */
std::unique_ptr<Geometry>
OffsetCurve::computePolygonCurve(const Polygon& polyGeom, double dist)
{
auto buffer = BufferOp::bufferOp(&polyGeom, dist, bufferParams);
std::unique_ptr<Geometry> boundary = buffer->getBoundary();
//-- convert LinearRing to LineString if needed
if (boundary->getGeometryTypeId() == GEOS_LINEARRING) {
const LinearRing& ring = static_cast<LinearRing&>(*boundary);
auto ringCs = ring.getCoordinatesRO();
std::unique_ptr<Geometry> ls(polyGeom.getFactory()->createLineString(*ringCs));
return ls;
}
return boundary;
}

/* private */
std::unique_ptr<Geometry>
OffsetCurve::computeCurve(const LineString& lineGeom, double dist)
Expand Down
19 changes: 18 additions & 1 deletion tests/unit/operation/buffer/OffsetCurveTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,23 @@ void object::test<43> ()
);
}


// testPolygonJoinMitre
template<>
template<>
void object::test<44> ()
{
checkOffsetCurve(
"POLYGON ((1 1, 1 7, 5 4, 8 8, 8 1, 1 1))",
1, 0, BufferParameters::JOIN_MITRE, 5,
"LINESTRING (0 0, 0 9, 4.8 5.4, 9 11, 9 0, 0 0)",
0.0001
);
checkOffsetCurve(
"POLYGON ((1 1, 1 7, 5 4, 8 8, 8 1, 1 1))",
-1, 0, BufferParameters::JOIN_MITRE, 5,
"LINESTRING (2 2, 2 5, 5.2 2.6, 7 5, 7 2, 2 2)",
0.0001
);
}

} // namespace tut2

0 comments on commit f997d40

Please sign in to comment.