1052 lines
35 KiB
C++
1052 lines
35 KiB
C++
/**********************************************************************
|
|
*
|
|
* GEOS - Geometry Engine Open Source
|
|
* http://geos.osgeo.org
|
|
*
|
|
* Copyright (C) 2009 2011 Sandro Santilli <strk@kbt.io>
|
|
* Copyright (C) 2005 2006 Refractions Research Inc.
|
|
* Copyright (C) 2001-2002 Vivid Solutions Inc.
|
|
*
|
|
* 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/Geometry.java rev. 1.112
|
|
*
|
|
**********************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#ifndef USE_UNSTABLE_GEOS_CPP_API
|
|
#ifndef _MSC_VER
|
|
# warning "The GEOS C++ API is unstable, please use the C API instead"
|
|
# warning "HINT: #include geos_c.h"
|
|
#else
|
|
#pragma message("The GEOS C++ API is unstable, please use the C API instead")
|
|
#pragma message("HINT: #include geos_c.h")
|
|
#endif
|
|
#endif
|
|
|
|
#include <geos/export.h>
|
|
#include <geos/geom/Envelope.h>
|
|
#include <geos/geom/Dimension.h> // for Dimension::DimensionType
|
|
#include <geos/geom/GeometryComponentFilter.h> // for inheritance
|
|
#include <geos/geom/CoordinateSequence.h> // to materialize CoordinateSequence
|
|
|
|
#include <algorithm>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <memory>
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(push)
|
|
#pragma warning(disable: 4251) // warning C4251: needs to have dll-interface to be used by clients of class
|
|
#pragma warning(disable: 4355) // warning C4355: 'this' : used in base member initializer list
|
|
#endif
|
|
|
|
// Forward declarations
|
|
namespace geos {
|
|
namespace geom {
|
|
class Coordinate;
|
|
class CoordinateFilter;
|
|
class CoordinateSequence;
|
|
class CoordinateSequenceFilter;
|
|
class GeometryComponentFilter;
|
|
class GeometryFactory;
|
|
class GeometryFilter;
|
|
class PrecisionModel;
|
|
class Point;
|
|
class IntersectionMatrix;
|
|
}
|
|
namespace io { // geos.io
|
|
class Unload;
|
|
} // namespace geos.io
|
|
}
|
|
|
|
namespace geos { // geos
|
|
namespace geom { // geos::geom
|
|
|
|
/// Geometry types
|
|
enum GeometryTypeId : int {
|
|
/// a point
|
|
GEOS_POINT,
|
|
/// a linestring
|
|
GEOS_LINESTRING,
|
|
/// a linear ring (linestring with 1st point == last point)
|
|
GEOS_LINEARRING,
|
|
/// a polygon
|
|
GEOS_POLYGON,
|
|
/// a collection of points
|
|
GEOS_MULTIPOINT,
|
|
/// a collection of linestrings
|
|
GEOS_MULTILINESTRING,
|
|
/// a collection of polygons
|
|
GEOS_MULTIPOLYGON,
|
|
/// a collection of heterogeneus geometries
|
|
GEOS_GEOMETRYCOLLECTION,
|
|
GEOS_CIRCULARSTRING,
|
|
GEOS_COMPOUNDCURVE,
|
|
GEOS_CURVEPOLYGON,
|
|
GEOS_MULTICURVE,
|
|
GEOS_MULTISURFACE,
|
|
};
|
|
|
|
enum GeometrySortIndex {
|
|
SORTINDEX_POINT = 0,
|
|
SORTINDEX_MULTIPOINT = 1,
|
|
SORTINDEX_LINESTRING = 2,
|
|
SORTINDEX_LINEARRING = 3,
|
|
SORTINDEX_MULTILINESTRING = 4,
|
|
SORTINDEX_POLYGON = 5,
|
|
SORTINDEX_MULTIPOLYGON = 6,
|
|
SORTINDEX_GEOMETRYCOLLECTION = 7,
|
|
SORTINDEX_CIRCULARSTRING = 8,
|
|
SORTINDEX_COMPOUNDCURVE = 9,
|
|
SORTINDEX_CURVEPOLYGON = 10,
|
|
SORTINDEX_MULTICURVE = 11,
|
|
SORTINDEX_MULTISURFACE = 12,
|
|
};
|
|
|
|
/**
|
|
* \class Geometry geom.h geos.h
|
|
*
|
|
* \brief Basic implementation of Geometry, constructed and
|
|
* destructed by GeometryFactory.
|
|
*
|
|
* <code>clone</code> returns a deep copy of the object.
|
|
* Use GeometryFactory to construct.
|
|
*
|
|
* <H3>Binary Predicates</H3>
|
|
* Because it is not clear at this time
|
|
* what semantics for spatial
|
|
* analysis methods involving <code>GeometryCollection</code>s would be useful,
|
|
* <code>GeometryCollection</code>s are not supported as arguments to binary
|
|
* predicates (other than <code>convexHull</code>) or the <code>relate</code>
|
|
* method.
|
|
*
|
|
* <H3>Set-Theoretic Methods</H3>
|
|
*
|
|
* The spatial analysis methods will
|
|
* return the most specific class possible to represent the result. If the
|
|
* result is homogeneous, a <code>Point</code>, <code>LineString</code>, or
|
|
* <code>Polygon</code> will be returned if the result contains a single
|
|
* element; otherwise, a <code>MultiPoint</code>, <code>MultiLineString</code>,
|
|
* or <code>MultiPolygon</code> will be returned. If the result is
|
|
* heterogeneous a <code>GeometryCollection</code> will be returned. <P>
|
|
*
|
|
* Because it is not clear at this time what semantics for set-theoretic
|
|
* methods involving <code>GeometryCollection</code>s would be useful,
|
|
* <code>GeometryCollections</code>
|
|
* are not supported as arguments to the set-theoretic methods.
|
|
*
|
|
* <H4>Representation of Computed Geometries </H4>
|
|
*
|
|
* The SFS states that the result
|
|
* of a set-theoretic method is the "point-set" result of the usual
|
|
* set-theoretic definition of the operation (SFS 3.2.21.1). However, there are
|
|
* sometimes many ways of representing a point set as a <code>Geometry</code>.
|
|
* <P>
|
|
*
|
|
* The SFS does not specify an unambiguous representation of a given point set
|
|
* returned from a spatial analysis method. One goal of JTS is to make this
|
|
* specification precise and unambiguous. JTS will use a canonical form for
|
|
* <code>Geometry</code>s returned from spatial analysis methods. The canonical
|
|
* form is a <code>Geometry</code> which is simple and noded:
|
|
* <UL>
|
|
* <LI> Simple means that the Geometry returned will be simple according to
|
|
* the JTS definition of <code>isSimple</code>.
|
|
* <LI> Noded applies only to overlays involving <code>LineString</code>s. It
|
|
* means that all intersection points on <code>LineString</code>s will be
|
|
* present as endpoints of <code>LineString</code>s in the result.
|
|
* </UL>
|
|
* This definition implies that non-simple geometries which are arguments to
|
|
* spatial analysis methods must be subjected to a line-dissolve process to
|
|
* ensure that the results are simple.
|
|
*
|
|
* <H4> Constructed Points And The Precision Model </H4>
|
|
*
|
|
* The results computed by the set-theoretic methods may
|
|
* contain constructed points which are not present in the input Geometry.
|
|
* These new points arise from intersections between line segments in the
|
|
* edges of the input Geometry. In the general case it is not
|
|
* possible to represent constructed points exactly. This is due to the fact
|
|
* that the coordinates of an intersection point may contain twice as many bits
|
|
* of precision as the coordinates of the input line segments. In order to
|
|
* represent these constructed points explicitly, JTS must truncate them to fit
|
|
* the PrecisionModel.
|
|
*
|
|
* Unfortunately, truncating coordinates moves them slightly. Line segments
|
|
* which would not be coincident in the exact result may become coincident in
|
|
* the truncated representation. This in turn leads to "topology collapses" --
|
|
* situations where a computed element has a lower dimension than it would in
|
|
* the exact result.
|
|
*
|
|
* When JTS detects topology collapses during the computation of spatial
|
|
* analysis methods, it will throw an exception. If possible the exception will
|
|
* report the location of the collapse.
|
|
*
|
|
* equals(Object) and hashCode are not overridden, so that when two
|
|
* topologically equal Geometries are added to HashMaps and HashSets, they
|
|
* remain distinct. This behaviour is desired in many cases.
|
|
*
|
|
*/
|
|
class GEOS_DLL Geometry {
|
|
|
|
public:
|
|
|
|
friend class GeometryFactory;
|
|
|
|
/// A vector of const Geometry pointers
|
|
using ConstVect = std::vector<const Geometry*>;
|
|
|
|
/// A vector of non-const Geometry pointers
|
|
using NonConstVect = std::vector<Geometry*>;
|
|
|
|
/// An unique_ptr of Geometry
|
|
using Ptr = std::unique_ptr<Geometry> ;
|
|
|
|
/// Make a deep-copy of this Geometry
|
|
std::unique_ptr<Geometry> clone() const { return std::unique_ptr<Geometry>(cloneImpl()); }
|
|
|
|
/// Destroy Geometry and all components
|
|
virtual ~Geometry();
|
|
|
|
|
|
/**
|
|
* \brief
|
|
* Gets the factory which contains the context in which this
|
|
* geometry was created.
|
|
*
|
|
* @return the factory for this geometry
|
|
*/
|
|
const GeometryFactory*
|
|
getFactory() const
|
|
{
|
|
return _factory;
|
|
}
|
|
|
|
/**
|
|
* \brief
|
|
* A simple scheme for applications to add their own custom data to
|
|
* a Geometry.
|
|
* An example use might be to add an object representing a
|
|
* Coordinate Reference System.
|
|
*
|
|
* Note that user data objects are not present in geometries created
|
|
* by construction methods.
|
|
*
|
|
* @param newUserData an object, the semantics for which are
|
|
* defined by the application using this Geometry
|
|
*/
|
|
void
|
|
setUserData(void* newUserData)
|
|
{
|
|
_userData = newUserData;
|
|
}
|
|
|
|
/**
|
|
* \brief
|
|
* Gets the user data object for this geometry, if any.
|
|
*
|
|
* @return the user data object, or <code>null</code> if none set
|
|
*/
|
|
void*
|
|
getUserData() const
|
|
{
|
|
return _userData;
|
|
}
|
|
|
|
/** \brief
|
|
* Returns the ID of the Spatial Reference System used by the Geometry.
|
|
*
|
|
* GEOS supports Spatial Reference System information in the simple way
|
|
* defined in the SFS. A Spatial Reference System ID (SRID) is present
|
|
* in each Geometry object. Geometry provides basic accessor operations
|
|
* for this field, but no others. The SRID is represented as an integer.
|
|
*
|
|
* @return the ID of the coordinate space in which the Geometry is defined.
|
|
*/
|
|
virtual int
|
|
getSRID() const
|
|
{
|
|
return SRID;
|
|
}
|
|
|
|
/** \brief
|
|
* Sets the ID of the Spatial Reference System used by the Geometry.
|
|
*/
|
|
virtual void
|
|
setSRID(int newSRID)
|
|
{
|
|
SRID = newSRID;
|
|
}
|
|
|
|
/**
|
|
* \brief
|
|
* Get the PrecisionModel used to create this Geometry.
|
|
*/
|
|
const PrecisionModel* getPrecisionModel() const;
|
|
|
|
/// Returns a vertex of this Geometry, or NULL if this is the empty geometry.
|
|
virtual const CoordinateXY* getCoordinate() const = 0; //Abstract
|
|
|
|
/**
|
|
* \brief
|
|
* Returns this Geometry vertices.
|
|
* Caller takes ownership of the returned object.
|
|
*/
|
|
virtual std::unique_ptr<CoordinateSequence> getCoordinates() const = 0; //Abstract
|
|
|
|
/// Returns the count of this Geometrys vertices.
|
|
virtual std::size_t getNumPoints() const = 0; //Abstract
|
|
|
|
/// Returns false if the Geometry not simple.
|
|
virtual bool isSimple() const;
|
|
|
|
/// Return a string representation of this Geometry type
|
|
virtual std::string getGeometryType() const = 0; //Abstract
|
|
|
|
/// Returns whether the Geometry contains curved components
|
|
virtual bool hasCurvedComponents() const;
|
|
|
|
/// Return an integer representation of this Geometry type
|
|
virtual GeometryTypeId getGeometryTypeId() const = 0; //Abstract
|
|
|
|
/**
|
|
* \brief Returns the number of geometries in this collection,
|
|
* or 1 if this is not a collection.
|
|
*
|
|
* Empty collection or multi-geometry types return 0,
|
|
* and empty simple geometry types return 1.
|
|
*/
|
|
virtual std::size_t
|
|
getNumGeometries() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/// \brief Returns a pointer to the nth Geometry in this collection
|
|
/// (or self if this is not a collection)
|
|
virtual const Geometry*
|
|
getGeometryN(std::size_t /*n*/) const
|
|
{
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* \brief Tests the validity of this <code>Geometry</code>.
|
|
*
|
|
* Subclasses provide their own definition of "valid".
|
|
*
|
|
* @return <code>true</code> if this <code>Geometry</code> is valid
|
|
*
|
|
* @see IsValidOp
|
|
*/
|
|
virtual bool isValid() const;
|
|
|
|
/// Returns whether or not the set of points in this Geometry is empty.
|
|
virtual bool isEmpty() const = 0; //Abstract
|
|
|
|
/// Polygon overrides to check for actual rectangle
|
|
virtual bool
|
|
isRectangle() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/// Returns the dimension of this Geometry (0=point, 1=line, 2=surface)
|
|
virtual Dimension::DimensionType getDimension() const = 0; //Abstract
|
|
|
|
/// Checks whether any component of this geometry has dimension d
|
|
virtual bool hasDimension(Dimension::DimensionType d) const {
|
|
return getDimension() == d;
|
|
}
|
|
|
|
/// Checks whether this Geometry consists only of components having dimension d.
|
|
virtual bool isDimensionStrict(Dimension::DimensionType d) const {
|
|
return d == getDimension();
|
|
}
|
|
|
|
bool isPuntal() const {
|
|
return isDimensionStrict(Dimension::P);
|
|
}
|
|
|
|
bool isLineal() const {
|
|
return isDimensionStrict(Dimension::L);
|
|
}
|
|
|
|
bool isPolygonal() const {
|
|
return isDimensionStrict(Dimension::A);
|
|
}
|
|
|
|
bool isMixedDimension() const;
|
|
bool isMixedDimension(Dimension::DimensionType* baseDim) const;
|
|
|
|
bool isCollection() const {
|
|
int t = getGeometryTypeId();
|
|
return t == GEOS_GEOMETRYCOLLECTION ||
|
|
t == GEOS_MULTIPOINT ||
|
|
t == GEOS_MULTILINESTRING ||
|
|
t == GEOS_MULTIPOLYGON;
|
|
}
|
|
|
|
static GeometryTypeId multiTypeId(GeometryTypeId typeId) {
|
|
switch (typeId) {
|
|
case GEOS_POINT: return GEOS_MULTIPOINT;
|
|
case GEOS_LINESTRING: return GEOS_MULTILINESTRING;
|
|
case GEOS_POLYGON: return GEOS_MULTIPOLYGON;
|
|
default: return typeId;
|
|
}
|
|
}
|
|
|
|
/// Returns the coordinate dimension of this Geometry (2=XY, 3=XYZ or XYM, 4=XYZM).
|
|
virtual uint8_t getCoordinateDimension() const = 0; //Abstract
|
|
|
|
virtual bool hasZ() const = 0;
|
|
|
|
virtual bool hasM() const = 0;
|
|
|
|
/**
|
|
* \brief
|
|
* Returns the boundary, or an empty geometry of appropriate
|
|
* dimension if this <code>Geometry</code> is empty.
|
|
*
|
|
* (In the case of zero-dimensional geometries,
|
|
* an empty GeometryCollection is returned.)
|
|
* For a discussion of this function, see the OpenGIS Simple
|
|
* Features Specification. As stated in SFS Section 2.1.13.1,
|
|
* "the boundary of a Geometry is a set of Geometries of the
|
|
* next lower dimension."
|
|
*
|
|
* @return the closure of the combinatorial boundary
|
|
* of this <code>Geometry</code>.
|
|
* Ownershipof the returned object transferred to caller.
|
|
*/
|
|
virtual std::unique_ptr<Geometry> getBoundary() const = 0; //Abstract
|
|
|
|
/// Returns the dimension of this Geometrys inherent boundary.
|
|
virtual int getBoundaryDimension() const = 0; //Abstract
|
|
|
|
/// Returns this Geometrys bounding box.
|
|
virtual std::unique_ptr<Geometry> getEnvelope() const;
|
|
|
|
/** \brief
|
|
* Returns the minimum and maximum x and y values in this Geometry,
|
|
* or a null Envelope if this Geometry is empty.
|
|
*/
|
|
virtual const Envelope* getEnvelopeInternal() const = 0;
|
|
|
|
/**
|
|
* Tests whether this geometry is disjoint from the specified geometry.
|
|
*
|
|
* The <code>disjoint</code> predicate has the following equivalent
|
|
* definitions:
|
|
* - The two geometries have no point in common
|
|
* - The DE-9IM Intersection Matrix for the two geometries matches
|
|
* <code>[FF*FF****]</code>
|
|
* - <code>! g.intersects(this)</code>
|
|
* (<code>disjoint</code> is the inverse of <code>intersects</code>)
|
|
*
|
|
* @param other the Geometry with which to compare this Geometry
|
|
* @return true if the two <code>Geometry</code>s are disjoint
|
|
*
|
|
* @see Geometry::intersects
|
|
*/
|
|
virtual bool disjoint(const Geometry* other) const;
|
|
|
|
/** \brief
|
|
* Returns true if the DE-9IM intersection matrix for the two
|
|
* Geometrys is FT*******, F**T***** or F***T****.
|
|
*/
|
|
virtual bool touches(const Geometry* other) const;
|
|
|
|
/// Returns true if disjoint returns false.
|
|
virtual bool intersects(const Geometry* g) const;
|
|
|
|
/**
|
|
* Tests whether this geometry crosses the specified geometry.
|
|
*
|
|
* The <code>crosses</code> predicate has the following equivalent
|
|
* definitions:
|
|
* - The geometries have some but not all interior points in common.
|
|
* - The DE-9IM Intersection Matrix for the two geometries matches
|
|
* - <code>[T*T******]</code> (for P/L, P/A, and L/A situations)
|
|
* - <code>[T*****T**]</code> (for L/P, A/P, and A/L situations)
|
|
* - <code>[0********]</code> (for L/L situations)
|
|
* For any other combination of dimensions this predicate returns
|
|
* <code>false</code>.
|
|
*
|
|
* The SFS defined this predicate only for P/L, P/A, L/L, and L/A
|
|
* situations.
|
|
* JTS extends the definition to apply to L/P, A/P and A/L situations
|
|
* as well, in order to make the relation symmetric.
|
|
*
|
|
* @param g the <code>Geometry</code> with which to compare this
|
|
* <code>Geometry</code>
|
|
*@return <code>true</code> if the two <code>Geometry</code>s cross.
|
|
*/
|
|
virtual bool crosses(const Geometry* g) const;
|
|
|
|
/** \brief
|
|
* Returns true if the DE-9IM intersection matrix for the two
|
|
* Geometrys is T*F**F***.
|
|
*/
|
|
virtual bool within(const Geometry* g) const;
|
|
|
|
/// Returns true if other.within(this) returns true.
|
|
virtual bool contains(const Geometry* g) const;
|
|
|
|
/** \brief
|
|
* Returns true if the DE-9IM intersection matrix for the two
|
|
* Geometrys is T*T***T** (for two points or two surfaces)
|
|
* 1*T***T** (for two curves).
|
|
*/
|
|
virtual bool overlaps(const Geometry* g) const;
|
|
|
|
/**
|
|
* \brief
|
|
* Returns true if the elements in the DE-9IM intersection matrix
|
|
* for the two Geometrys match the elements in intersectionPattern.
|
|
*
|
|
* IntersectionPattern elements may be: 0 1 2 T ( = 0, 1 or 2)
|
|
* F ( = -1) * ( = -1, 0, 1 or 2).
|
|
*
|
|
* For more information on the DE-9IM, see the OpenGIS Simple
|
|
* Features Specification.
|
|
*
|
|
* @throws util::IllegalArgumentException if either arg is a collection
|
|
*
|
|
*/
|
|
bool relate(const Geometry* g,
|
|
const std::string& intersectionPattern) const;
|
|
|
|
bool
|
|
relate(const Geometry& g, const std::string& intersectionPattern) const
|
|
{
|
|
return relate(&g, intersectionPattern);
|
|
}
|
|
|
|
/// Returns the DE-9IM intersection matrix for the two Geometrys.
|
|
std::unique_ptr<IntersectionMatrix> relate(const Geometry* g) const;
|
|
|
|
std::unique_ptr<IntersectionMatrix> relate(const Geometry& g) const;
|
|
|
|
/**
|
|
* \brief
|
|
* Returns true if the DE-9IM intersection matrix for the two
|
|
* Geometrys is T*F**FFF*.
|
|
*/
|
|
virtual bool equals(const Geometry* g) const;
|
|
|
|
/** \brief
|
|
* Returns <code>true</code> if this geometry covers the
|
|
* specified geometry.
|
|
*
|
|
* The <code>covers</code> predicate has the following
|
|
* equivalent definitions:
|
|
*
|
|
* - Every point of the other geometry is a point of this geometry.
|
|
* - The DE-9IM Intersection Matrix for the two geometries is
|
|
* <code>T*****FF*</code>
|
|
* or <code>*T****FF*</code>
|
|
* or <code>***T**FF*</code>
|
|
* or <code>****T*FF*</code>
|
|
* - <code>g.coveredBy(this)</code>
|
|
* (<code>covers</code> is the inverse of <code>coveredBy</code>)
|
|
*
|
|
* If either geometry is empty, the value of this predicate
|
|
* is <tt>false</tt>.
|
|
*
|
|
* This predicate is similar to {@link #contains},
|
|
* but is more inclusive (i.e. returns <tt>true</tt> for more cases).
|
|
* In particular, unlike <code>contains</code> it does not distinguish
|
|
* between points in the boundary and in the interior of geometries.
|
|
* For most situations, <code>covers</code> should be used in
|
|
* preference to <code>contains</code>.
|
|
* As an added benefit, <code>covers</code> is more amenable to
|
|
* optimization, and hence should be more performant.
|
|
*
|
|
* @param g
|
|
* the <code>Geometry</code> with which to compare this
|
|
* <code>Geometry</code>
|
|
*
|
|
* @return <code>true</code> if this <code>Geometry</code>
|
|
* covers <code>g</code>
|
|
*
|
|
* @see Geometry::contains
|
|
* @see Geometry::coveredBy
|
|
*/
|
|
bool covers(const Geometry* g) const;
|
|
|
|
/** \brief
|
|
* Tests whether this geometry is covered by the
|
|
* specified geometry.
|
|
*
|
|
* The <code>coveredBy</code> predicate has the following
|
|
* equivalent definitions:
|
|
*
|
|
* - Every point of this geometry is a point of the other geometry.
|
|
* - The DE-9IM Intersection Matrix for the two geometries matches
|
|
* <code>[T*F**F***]</code>
|
|
* or <code>[*TF**F***]</code>
|
|
* or <code>[**FT*F***]</code>
|
|
* or <code>[**F*TF***]</code>
|
|
* - <code>g.covers(this)</code>
|
|
* (<code>coveredBy</code> is the converse of <code>covers</code>)
|
|
*
|
|
* If either geometry is empty, the value of this predicate
|
|
* is <tt>false</tt>.
|
|
*
|
|
* This predicate is similar to {@link #within},
|
|
* but is more inclusive (i.e. returns <tt>true</tt> for more cases).
|
|
*
|
|
* @param g the <code>Geometry</code> with which to compare
|
|
* this <code>Geometry</code>
|
|
* @return <code>true</code> if this <code>Geometry</code>
|
|
* is covered by <code>g</code>
|
|
*
|
|
* @see Geometry#within
|
|
* @see Geometry#covers
|
|
*/
|
|
bool coveredBy(const Geometry* g) const;
|
|
|
|
|
|
/// Returns the Well-known Text representation of this Geometry.
|
|
virtual std::string toString() const;
|
|
|
|
virtual std::string toText() const;
|
|
|
|
/// Returns a buffer region around this Geometry having the given width.
|
|
///
|
|
/// @throws util::TopologyException if a robustness error occurs
|
|
///
|
|
std::unique_ptr<Geometry> buffer(double distance) const;
|
|
|
|
/// \brief
|
|
/// Returns a buffer region around this Geometry having the
|
|
/// given width and with a specified number of segments used
|
|
/// to approximate curves.
|
|
///
|
|
/// @throws util::TopologyException if a robustness error occurs
|
|
///
|
|
std::unique_ptr<Geometry> buffer(double distance, int quadrantSegments) const;
|
|
|
|
/** \brief
|
|
* Computes a buffer area around this geometry having the given
|
|
* width and with a specified accuracy of approximation for circular
|
|
* arcs, and using a specified end cap style.
|
|
*
|
|
* Buffer area boundaries can contain circular arcs.
|
|
* To represent these arcs using linear geometry they must be
|
|
* approximated with line segments.
|
|
*
|
|
* The <code>quadrantSegments</code> argument allows controlling the
|
|
* accuracy of the approximation by specifying the number of line
|
|
* segments used to represent a quadrant of a circle
|
|
*
|
|
* The end cap style specifies the buffer geometry that will be
|
|
* created at the ends of linestrings. The styles provided are:
|
|
*
|
|
* - BufferOp::CAP_ROUND - (default) a semi-circle
|
|
* - BufferOp::CAP_BUTT - a straight line perpendicular to the
|
|
* end segment
|
|
* - BufferOp::CAP_SQUARE - a half-square
|
|
*
|
|
*
|
|
* @param distance the width of the buffer
|
|
* (may be positive, negative or 0)
|
|
*
|
|
* @param quadrantSegments the number of line segments used
|
|
* to represent a quadrant of a circle
|
|
*
|
|
* @param endCapStyle the end cap style to use
|
|
*
|
|
* @return an area geometry representing the buffer region
|
|
*
|
|
* @throws util::TopologyException if a robustness error occurs
|
|
*
|
|
* @see BufferOp
|
|
*/
|
|
std::unique_ptr<Geometry> buffer(double distance, int quadrantSegments,
|
|
int endCapStyle) const;
|
|
|
|
/// \brief
|
|
/// Returns the smallest convex Polygon that contains
|
|
/// all the points in the Geometry.
|
|
virtual std::unique_ptr<Geometry> convexHull() const;
|
|
|
|
/** \brief
|
|
* Computes a new geometry which has all component coordinate sequences
|
|
* in reverse order (opposite orientation) to this one.
|
|
*
|
|
* @return a reversed geometry
|
|
*/
|
|
std::unique_ptr<Geometry> reverse() const { return std::unique_ptr<Geometry>(reverseImpl()); }
|
|
|
|
/** \brief
|
|
* Returns a Geometry representing the points shared by
|
|
* this Geometry and other.
|
|
*
|
|
* @throws util::TopologyException if a robustness error occurs
|
|
* @throws util::IllegalArgumentException if either input is a
|
|
* non-empty GeometryCollection
|
|
*
|
|
*/
|
|
std::unique_ptr<Geometry> intersection(const Geometry* other) const;
|
|
|
|
/** \brief
|
|
* Returns a Geometry representing all the points in this Geometry
|
|
* and other.
|
|
*
|
|
* @throws util::TopologyException if a robustness error occurs
|
|
* @throws util::IllegalArgumentException if either input is a
|
|
* non-empty GeometryCollection
|
|
*
|
|
*/
|
|
std::unique_ptr<Geometry> Union(const Geometry* other) const;
|
|
// throw(IllegalArgumentException *, TopologyException *);
|
|
|
|
/** \brief
|
|
* Computes the union of all the elements of this geometry. Heterogeneous
|
|
* [GeometryCollections](@ref GeometryCollection) are fully supported.
|
|
*
|
|
* The result obeys the following contract:
|
|
*
|
|
* - Unioning a set of [LineStrings](@ref LineString) has the effect of fully noding
|
|
* and dissolving the linework.
|
|
* - Unioning a set of [Polygons](@ref Polygon) will always
|
|
* return a polygonal geometry (unlike Geometry::Union(const Geometry* other) const),
|
|
* which may return geometrys of lower dimension if a topology collapse
|
|
* occurred.
|
|
*
|
|
* @return the union geometry
|
|
*
|
|
* @see UnaryUnionOp
|
|
*/
|
|
Ptr Union() const;
|
|
// throw(IllegalArgumentException *, TopologyException *);
|
|
|
|
/**
|
|
* \brief
|
|
* Returns a Geometry representing the points making up this
|
|
* Geometry that do not make up other.
|
|
*
|
|
* @throws util::TopologyException if a robustness error occurs
|
|
* @throws util::IllegalArgumentException if either input is a
|
|
* non-empty GeometryCollection
|
|
*
|
|
*/
|
|
std::unique_ptr<Geometry> difference(const Geometry* other) const;
|
|
|
|
/** \brief
|
|
* Returns a set combining the points in this Geometry not in other,
|
|
* and the points in other not in this Geometry.
|
|
*
|
|
* @throws util::TopologyException if a robustness error occurs
|
|
* @throws util::IllegalArgumentException if either input is a
|
|
* non-empty GeometryCollection
|
|
*
|
|
*/
|
|
std::unique_ptr<Geometry> symDifference(const Geometry* other) const;
|
|
|
|
/** \brief
|
|
* Returns true iff the two Geometrys are of the same type and their
|
|
* vertices corresponding by index are equal up to a specified distance
|
|
* tolerance. Geometries are not required to have the same dimemsion;
|
|
* any Z/M values are ignored.
|
|
*/
|
|
virtual bool equalsExact(const Geometry* other, double tolerance = 0)
|
|
const = 0; // Abstract
|
|
|
|
/** \brief
|
|
* Returns true if the two geometries are of the same type and their
|
|
* vertices corresponding by index are equal in all dimensions.
|
|
*/
|
|
virtual bool equalsIdentical(const Geometry* other) const = 0;
|
|
|
|
virtual void apply_rw(const CoordinateFilter* filter) = 0; //Abstract
|
|
virtual void apply_ro(CoordinateFilter* filter) const = 0; //Abstract
|
|
virtual void apply_rw(GeometryFilter* filter);
|
|
virtual void apply_ro(GeometryFilter* filter) const;
|
|
virtual void apply_rw(GeometryComponentFilter* filter);
|
|
virtual void apply_ro(GeometryComponentFilter* filter) const;
|
|
|
|
/**
|
|
* Performs an operation on the coordinates in this Geometry's
|
|
* CoordinateSequences.
|
|
* If the filter reports that a coordinate value has been changed,
|
|
* {@link #geometryChanged} will be called automatically.
|
|
*
|
|
* @param filter the filter to apply
|
|
*/
|
|
virtual void apply_rw(CoordinateSequenceFilter& filter) = 0;
|
|
|
|
/**
|
|
* Performs a read-only operation on the coordinates in this
|
|
* Geometry's CoordinateSequences.
|
|
*
|
|
* @param filter the filter to apply
|
|
*/
|
|
virtual void apply_ro(CoordinateSequenceFilter& filter) const = 0;
|
|
|
|
/** \brief
|
|
* Apply a filter to each component of this geometry.
|
|
* The filter is expected to provide a .filter(const Geometry*)
|
|
* method.
|
|
*
|
|
* I intend similar templated methods to replace
|
|
* all the virtual apply_rw and apply_ro functions...
|
|
* --strk(2005-02-06);
|
|
*/
|
|
template <class T>
|
|
void
|
|
applyComponentFilter(T& f) const
|
|
{
|
|
for(std::size_t i = 0, n = getNumGeometries(); i < n; ++i) {
|
|
f.filter(getGeometryN(i));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reorganizes this Geometry into normal form (or canonical form).
|
|
* Starting point of rings is lower left, collections are ordered
|
|
* by geometry type, etc.
|
|
*/
|
|
virtual void normalize() = 0; //Abstract
|
|
|
|
/// Comparator for sorting geometry
|
|
virtual int compareTo(const Geometry* geom) const;
|
|
|
|
/// Returns the area of this Geometry.
|
|
virtual double getArea() const;
|
|
|
|
/// Returns the length of this Geometry.
|
|
virtual double getLength() const;
|
|
|
|
/** Returns the minimum distance between this Geometry and the Geometry g
|
|
*
|
|
* @param g the Geometry to calculate distance to
|
|
* @return the distance in cartesian units
|
|
*/
|
|
virtual double distance(const Geometry* g) const;
|
|
|
|
|
|
/** \brief
|
|
* Tests whether the distance from this Geometry to another
|
|
* is less than or equal to a specified value.
|
|
*
|
|
* @param geom the Geometry to check the distance to
|
|
* @param cDistance the distance value to compare
|
|
* @return <code>true</code> if the geometries are less than
|
|
* <code>distance</code> apart.
|
|
*
|
|
* @todo doesn't seem to need being virtual, make it concrete
|
|
*/
|
|
virtual bool isWithinDistance(const Geometry* geom,
|
|
double cDistance) const;
|
|
|
|
/** \brief
|
|
* Computes the centroid of this <code>Geometry</code>.
|
|
*
|
|
* The centroid is equal to the centroid of the set of component
|
|
* Geometries of highest dimension (since the lower-dimension geometries
|
|
* contribute zero "weight" to the centroid)
|
|
*
|
|
* @return a {@link Point} which is the centroid of this Geometry
|
|
*/
|
|
virtual std::unique_ptr<Point> getCentroid() const;
|
|
|
|
/// Computes the centroid of this Geometry as a Coordinate
|
|
//
|
|
/// Returns false if centroid cannot be computed (EMPTY geometry)
|
|
///
|
|
virtual bool getCentroid(CoordinateXY& ret) const;
|
|
|
|
/** \brief
|
|
* Computes an interior point of this <code>Geometry</code>.
|
|
*
|
|
* An interior point is guaranteed to lie in the interior of the Geometry,
|
|
* if it possible to calculate such a point exactly. Otherwise,
|
|
* the point may lie on the boundary of the geometry.
|
|
*
|
|
* @return a Point which is in the interior of this Geometry, or
|
|
* null if the geometry doesn't have an interior (empty)
|
|
*/
|
|
std::unique_ptr<Point> getInteriorPoint() const;
|
|
|
|
/**
|
|
* \brief
|
|
* Notifies this Geometry that its Coordinates have been changed
|
|
* by an external party (using a CoordinateFilter, for example).
|
|
*/
|
|
virtual void geometryChanged();
|
|
|
|
/**
|
|
* \brief
|
|
* Notifies this Geometry that its Coordinates have been changed
|
|
* by an external party.
|
|
*/
|
|
virtual void geometryChangedAction() = 0;
|
|
|
|
protected:
|
|
/// Make a deep-copy of this Geometry
|
|
virtual Geometry* cloneImpl() const = 0;
|
|
|
|
/// Make a geometry with coordinates in reverse order
|
|
virtual Geometry* reverseImpl() const = 0;
|
|
|
|
/// Returns true if the array contains any non-empty Geometrys.
|
|
template<typename T>
|
|
static bool hasNonEmptyElements(const std::vector<T>* geometries) {
|
|
return std::any_of(geometries->begin(), geometries->end(), [](const T& g) { return !g->isEmpty(); });
|
|
}
|
|
|
|
/// Returns true if the CoordinateSequence contains any null elements.
|
|
static bool hasNullElements(const CoordinateSequence* list);
|
|
|
|
/// Returns true if the vector contains any null elements.
|
|
template<typename T>
|
|
static bool hasNullElements(const std::vector<T>* geometries) {
|
|
return std::any_of(geometries->begin(), geometries->end(), [](const T& g) { return g == nullptr; });
|
|
}
|
|
|
|
// static void reversePointOrder(CoordinateSequence* coordinates);
|
|
// static Coordinate& minCoordinate(CoordinateSequence* coordinates);
|
|
// static void scroll(CoordinateSequence* coordinates,Coordinate* firstCoordinate);
|
|
// static int indexOf(Coordinate* coordinate,CoordinateSequence* coordinates);
|
|
//
|
|
/** \brief
|
|
* Returns whether the two Geometrys are equal, from the point
|
|
* of view of the equalsExact method.
|
|
*/
|
|
virtual bool isEquivalentClass(const Geometry* other) const;
|
|
|
|
static void checkNotGeometryCollection(const Geometry* g);
|
|
|
|
virtual int compareToSameClass(const Geometry* geom) const = 0; //Abstract
|
|
|
|
template<typename T>
|
|
static int compare(const T& a, const T& b)
|
|
{
|
|
std::size_t i = 0;
|
|
std::size_t j = 0;
|
|
while(i < a.size() && j < b.size()) {
|
|
const auto& aGeom = *a[i];
|
|
const auto& bGeom = *b[j];
|
|
|
|
int comparison = aGeom.compareTo(&bGeom);
|
|
if(comparison != 0) {
|
|
return comparison;
|
|
}
|
|
|
|
i++;
|
|
j++;
|
|
}
|
|
|
|
if(i < a.size()) {
|
|
return 1;
|
|
}
|
|
|
|
if(j < b.size()) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool equal(const CoordinateXY& a, const CoordinateXY& b,
|
|
double tolerance) const;
|
|
int SRID;
|
|
|
|
Geometry(const Geometry& geom);
|
|
|
|
/** \brief
|
|
* Construct a geometry with the given GeometryFactory.
|
|
*
|
|
* Will keep a reference to the factory, so don't
|
|
* delete it until al Geometry objects referring to
|
|
* it are deleted.
|
|
*
|
|
* @param factory
|
|
*/
|
|
Geometry(const GeometryFactory* factory);
|
|
|
|
template<typename T>
|
|
static std::vector<std::unique_ptr<Geometry>> toGeometryArray(std::vector<std::unique_ptr<T>> && v) {
|
|
static_assert(std::is_base_of<Geometry, T>::value, "");
|
|
std::vector<std::unique_ptr<Geometry>> gv(v.size());
|
|
for (std::size_t i = 0; i < v.size(); i++) {
|
|
gv[i] = std::move(v[i]);
|
|
}
|
|
return gv;
|
|
}
|
|
|
|
static std::vector<std::unique_ptr<Geometry>> toGeometryArray(std::vector<std::unique_ptr<Geometry>> && v) {
|
|
return std::move(v);
|
|
}
|
|
|
|
protected:
|
|
|
|
virtual int getSortIndex() const = 0;
|
|
|
|
|
|
private:
|
|
|
|
class GEOS_DLL GeometryChangedFilter : public GeometryComponentFilter {
|
|
public:
|
|
void filter_rw(Geometry* geom) override;
|
|
};
|
|
|
|
static GeometryChangedFilter geometryChangedFilter;
|
|
|
|
/// The GeometryFactory used to create this Geometry
|
|
///
|
|
/// Externally owned
|
|
///
|
|
const GeometryFactory* _factory;
|
|
|
|
void* _userData;
|
|
};
|
|
|
|
/// \brief
|
|
/// Write the Well-known Binary representation of this Geometry
|
|
/// as an HEX string to the given output stream
|
|
///
|
|
GEOS_DLL std::ostream& operator<< (std::ostream& os, const Geometry& geom);
|
|
|
|
struct GEOS_DLL GeometryGreaterThen {
|
|
bool operator()(const Geometry* first, const Geometry* second);
|
|
};
|
|
|
|
|
|
/// Return current GEOS version
|
|
GEOS_DLL std::string geosversion();
|
|
|
|
/**
|
|
* \brief
|
|
* Return the version of JTS this GEOS
|
|
* release has been ported from.
|
|
*/
|
|
GEOS_DLL std::string jtsport();
|
|
|
|
// We use this instead of std::pair<unique_ptr<Geometry>> because C++11
|
|
// forbids that construct:
|
|
// http://lwg.github.com/issues/lwg-closed.html#2068
|
|
struct GeomPtrPair {
|
|
typedef std::unique_ptr<Geometry> GeomPtr;
|
|
GeomPtr first;
|
|
GeomPtr second;
|
|
};
|
|
|
|
} // namespace geos::geom
|
|
} // namespace geos
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(pop)
|
|
#endif
|
|
|