Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
New OffsetCurve implementation.
Closes #530
  • Loading branch information
pramsey committed Dec 16, 2021
1 parent d30798e commit 0a32f15
Show file tree
Hide file tree
Showing 27 changed files with 1,758 additions and 219 deletions.
11 changes: 4 additions & 7 deletions capi/geos_ts_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include <geos/operation/buffer/BufferBuilder.h>
#include <geos/operation/buffer/BufferOp.h>
#include <geos/operation/buffer/BufferParameters.h>
#include <geos/operation/buffer/OffsetCurve.h>
#include <geos/operation/distance/DistanceOp.h>
#include <geos/operation/distance/IndexedFacetDistance.h>
#include <geos/operation/linemerge/LineMerger.h>
Expand Down Expand Up @@ -170,6 +171,7 @@ using geos::algorithm::distance::DiscreteHausdorffDistance;

using geos::operation::buffer::BufferBuilder;
using geos::operation::buffer::BufferParameters;
using geos::operation::buffer::OffsetCurve;
using geos::operation::distance::IndexedFacetDistance;
using geos::operation::geounion::CascadedPolygonUnion;
using geos::operation::overlayng::OverlayNG;
Expand Down Expand Up @@ -1166,13 +1168,8 @@ extern "C" {
);
bp.setMitreLimit(mitreLimit);

bool isLeftSide = true;
if(width < 0) {
isLeftSide = false;
width = -width;
}
BufferBuilder bufBuilder(bp);
std::unique_ptr<Geometry> g3 = bufBuilder.bufferLineSingleSided(g1, width, isLeftSide);
OffsetCurve oc(*g1, width, bp);
std::unique_ptr<Geometry> g3 = oc.getCurve();
g3->setSRID(g1->getSRID());
return g3.release();
});
Expand Down
3 changes: 3 additions & 0 deletions include/geos/geom/GeometryFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ class GEOS_DLL GeometryFactory {
std::unique_ptr<LineString> createLineString(
std::unique_ptr<CoordinateSequence> && coordinates) const;

std::unique_ptr<LineString> createLineString(
std::vector<Coordinate> && coordinates) const;

/// Construct a LineString with a deep-copy of given argument
LineString* createLineString(
const CoordinateSequence& coordinates) const;
Expand Down
16 changes: 16 additions & 0 deletions include/geos/geom/LineSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,22 @@ class GEOS_DLL LineSegment {
double offsetDistance,
Coordinate& ret) const;


/**
* Computes the {@link LineSegment} that is offset from
* the segment by a given distance.
* The computed segment is offset to the left of the line if the offset distance is
* positive, to the right if negative.
*
* @param offsetDistance the distance the point is offset from the segment
* (positive is to the left, negative is to the right)
* @return a line segment offset by the specified distance
*
* @throws IllegalStateException if the segment has zero length
*/
LineSegment offset(double offsetDistance);


/** \brief
* Compute the projection factor for the projection of the point p
* onto this LineSegment.
Expand Down
3 changes: 3 additions & 0 deletions include/geos/geom/LineString.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ class GEOS_DLL LineString: public Geometry {
LineString(CoordinateSequence::Ptr && pts,
const GeometryFactory& newFactory);

LineString(std::vector<Coordinate> && pts,
const GeometryFactory& newFactory);

LineString* cloneImpl() const override { return new LineString(*this); }

LineString* reverseImpl() const override;
Expand Down
115 changes: 115 additions & 0 deletions include/geos/geom/util/GeometryMapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2021 Paul Ramsey <pramsey@cleverelephant.ca>
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Public Licence as published
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************
*
* Last port: geom/util/GeometryMapper.java
*
**********************************************************************/

#pragma once

#include <memory>
#include <vector>
#include <functional>

#include <geos/export.h>

// Forward declarations
namespace geos {
namespace geom {
class Geometry;
class GeometryCollection;
class GeometryFactory;
}
}

namespace geos {
namespace geom { // geos.geom
namespace util { // geos.geom.util


/**
* Methods to map various collections
* of {@link Geometry}s
* via defined mapping functions.
*
* @author Martin Davis
*
*/
class GEOS_DLL GeometryMapper {

public:

/**
* An interface for geometry functions that map a geometry input to a geometry output.
* The output may be nullptr if there is no valid output value for
* the given input value.
*/
typedef std::function<std::unique_ptr<Geometry>(const Geometry&)> mapOp;

/**
* Maps the members of a {@link Geometry}
* (which may be atomic or composite)
* into another Geometry of most specific type.
* null results are skipped.
* In the case of hierarchical {@link GeometryCollection}s,
* only the first level of members are mapped.
*
* @param geom the input atomic or composite geometry
* @param op the mapping operation
* @return a result collection or geometry of most specific type
*/
static std::unique_ptr<Geometry> map(
const Geometry& geom,
mapOp op);

/**
* Maps the atomic elements of a {@link Geometry}
* (which may be atomic or composite)
* using a mapOp mapping operation
* into an atomic Geometry or a flat collection
* of the most specific type.
* null and empty values returned from the mapping operation
* are discarded.
*
* @param geom the geometry to map
* @param emptyDim the dimension of empty geometry to create
* @param op the mapping operation
* @return the mapped result
*/
static std::unique_ptr<Geometry> flatMap(
const Geometry& geom,
int emptyDim,
mapOp op);



private:

static void flatMap(
const Geometry& geom,
mapOp op,
std::vector<std::unique_ptr<Geometry>>& mapped);

static void addFlat(
std::unique_ptr<Geometry>& geom,
std::vector<std::unique_ptr<Geometry>>& geomList);



};

} // namespace geos.geom.util
} // namespace geos.geom
} // namespace geos

Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
*
**********************************************************************
*
* Last port: operation/buffer/OffsetCurveSetBuilder.java r378 (JTS-1.12)
* Last port: operation/buffer/BufferCurveSetBuilder.java r378 (JTS-1.12)
*
**********************************************************************/

#ifndef GEOS_OP_BUFFER_OFFSETCURVESETBUILDER_H
#define GEOS_OP_BUFFER_OFFSETCURVESETBUILDER_H
#pragma once

#include <geos/export.h>
#include <geos/geom/Location.h>
#include <geos/operation/buffer/OffsetCurveBuilder.h>

#include <vector>

Expand All @@ -35,6 +35,7 @@ namespace geos {
namespace geom {
class Geometry;
class CoordinateSequence;
class PrecisionModel;
class GeometryCollection;
class Point;
class LineString;
Expand All @@ -50,6 +51,7 @@ class SegmentString;
namespace operation {
namespace buffer {
class OffsetCurveBuilder;
class BufferParameters;
}
}
}
Expand All @@ -59,7 +61,7 @@ namespace operation { // geos.operation
namespace buffer { // geos.operation.buffer

/**
* \class OffsetCurveSetBuilder
* \class BufferCurveSetBuilder
*
* \brief
* Creates all the raw offset curves for a buffer of a Geometry.
Expand All @@ -68,7 +70,7 @@ namespace buffer { // geos.operation.buffer
* final buffer area.
*
*/
class GEOS_DLL OffsetCurveSetBuilder {
class GEOS_DLL BufferCurveSetBuilder {

private:

Expand All @@ -80,7 +82,7 @@ class GEOS_DLL OffsetCurveSetBuilder {
std::vector<geomgraph::Label*> newLabels;
const geom::Geometry& inputGeom;
double distance;
OffsetCurveBuilder& curveBuilder;
OffsetCurveBuilder curveBuilder;

/// The raw offset curves computed.
/// This class holds ownership of std::vector elements.
Expand Down Expand Up @@ -210,8 +212,8 @@ class GEOS_DLL OffsetCurveSetBuilder {
double bufferDistance);

// Declare type as noncopyable
OffsetCurveSetBuilder(const OffsetCurveSetBuilder& other) = delete;
OffsetCurveSetBuilder& operator=(const OffsetCurveSetBuilder& rhs) = delete;
BufferCurveSetBuilder(const BufferCurveSetBuilder& other) = delete;
BufferCurveSetBuilder& operator=(const BufferCurveSetBuilder& rhs) = delete;

/**
* Computes orientation of a ring using a signed-area orientation test.
Expand All @@ -231,11 +233,20 @@ class GEOS_DLL OffsetCurveSetBuilder {
public:

/// Constructor
OffsetCurveSetBuilder(const geom::Geometry& newInputGeom,
double newDistance, OffsetCurveBuilder& newCurveBuilder);
BufferCurveSetBuilder(
const geom::Geometry& newInputGeom,
double newDistance,
const geom::PrecisionModel* newPm,
const BufferParameters& newBufParams)
: inputGeom(newInputGeom)
, distance(newDistance)
, curveBuilder(newPm, newBufParams)
, curveList()
, isInvertOrientation(false)
{};

/// Destructor
~OffsetCurveSetBuilder();
~BufferCurveSetBuilder();

/** \brief
* Computes the set of raw offset curves for the buffer.
Expand Down Expand Up @@ -279,4 +290,3 @@ class GEOS_DLL OffsetCurveSetBuilder {
#pragma warning(pop)
#endif

#endif // ndef GEOS_OP_BUFFER_OFFSETCURVESETBUILDER_H
5 changes: 5 additions & 0 deletions include/geos/operation/buffer/BufferOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ class GEOS_DLL BufferOp {
int quadrantSegments = BufferParameters::DEFAULT_QUADRANT_SEGMENTS,
int endCapStyle = BufferParameters::CAP_ROUND);

static std::unique_ptr<geom::Geometry> bufferOp(
const geom::Geometry* g,
double distance,
BufferParameters& bufParms);

/** \brief
* Initializes a buffer computation for the given geometry.
*
Expand Down
Loading

0 comments on commit 0a32f15

Please sign in to comment.