[geos-commits] [SCM] GEOS branch master updated. 708d32b2cd2dd3bedc38ff1d839368656b1f9626
git at osgeo.org
git at osgeo.org
Fri Oct 30 08:12:12 PDT 2020
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".
The branch, master has been updated
via 708d32b2cd2dd3bedc38ff1d839368656b1f9626 (commit)
from 07532c3afd174a5f0767569e07aba6c7782f7087 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 708d32b2cd2dd3bedc38ff1d839368656b1f9626
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Fri Oct 30 08:12:06 2020 -0700
Create new EMPTY geometry with 2D coordinates by default. Parse Z EMPTY geometry in WKT reader, for simple (non-multi) geometries. Closes #1048
diff --git a/include/geos/geom/GeometryFactory.h b/include/geos/geom/GeometryFactory.h
index 341e978..9dcfa45 100644
--- a/include/geos/geom/GeometryFactory.h
+++ b/include/geos/geom/GeometryFactory.h
@@ -164,7 +164,7 @@ public:
const PrecisionModel* getPrecisionModel() const;
/// Creates an EMPTY Point
- std::unique_ptr<Point> createPoint() const;
+ std::unique_ptr<Point> createPoint(std::size_t coordinateDimension = 2) const;
/// Creates a Point using the given Coordinate
Point* createPoint(const Coordinate& coordinate) const;
@@ -269,7 +269,7 @@ public:
const std::vector<Coordinate>& fromCoords) const;
/// Construct an EMPTY Polygon
- std::unique_ptr<Polygon> createPolygon() const;
+ std::unique_ptr<Polygon> createPolygon(std::size_t coordinateDimension = 2) const;
/// Construct a Polygon taking ownership of given arguments
Polygon* createPolygon(LinearRing* shell,
@@ -285,7 +285,7 @@ public:
const std::vector<LinearRing*>& holes) const;
/// Construct an EMPTY LineString
- std::unique_ptr<LineString> createLineString() const;
+ std::unique_ptr<LineString> createLineString(std::size_t coordinateDimension = 2) const;
/// Copy a LineString
std::unique_ptr<LineString> createLineString(const LineString& ls) const;
diff --git a/include/geos/io/WKTReader.h b/include/geos/io/WKTReader.h
index d43e1ee..bbaf46c 100644
--- a/include/geos/io/WKTReader.h
+++ b/include/geos/io/WKTReader.h
@@ -88,7 +88,7 @@ public:
protected:
std::unique_ptr<geom::CoordinateSequence> getCoordinates(io::StringTokenizer* tokenizer);
double getNextNumber(io::StringTokenizer* tokenizer);
- std::string getNextEmptyOrOpener(io::StringTokenizer* tokenizer);
+ std::string getNextEmptyOrOpener(io::StringTokenizer* tokenizer, std::size_t& dim);
std::string getNextCloserOrComma(io::StringTokenizer* tokenizer);
std::string getNextCloser(io::StringTokenizer* tokenizer);
std::string getNextWord(io::StringTokenizer* tokenizer);
diff --git a/src/geom/GeometryFactory.cpp b/src/geom/GeometryFactory.cpp
index 1d2afeb..3618ee7 100644
--- a/src/geom/GeometryFactory.cpp
+++ b/src/geom/GeometryFactory.cpp
@@ -298,8 +298,12 @@ GeometryFactory::getPrecisionModel() const
/*public*/
std::unique_ptr<Point>
-GeometryFactory::createPoint() const
+GeometryFactory::createPoint(std::size_t coordinateDimension) const
{
+ if (coordinateDimension == 3) {
+ geos::geom::FixedSizeCoordinateSequence<0> seq(coordinateDimension);
+ return std::unique_ptr<Point>(createPoint(seq));
+ }
return std::unique_ptr<Point>(new Point(nullptr, this));
}
@@ -553,9 +557,11 @@ GeometryFactory::createMultiPoint(const std::vector<Coordinate>& fromCoords) con
/*public*/
std::unique_ptr<Polygon>
-GeometryFactory::createPolygon() const
+GeometryFactory::createPolygon(std::size_t coordinateDimension) const
{
- return std::unique_ptr<Polygon>(new Polygon(nullptr, nullptr, this));
+ auto cs = coordinateListFactory->create(std::size_t(0), coordinateDimension);
+ auto lr = createLinearRing(cs.release());
+ return std::unique_ptr<Polygon>(createPolygon(lr, nullptr));
}
/*public*/
@@ -600,8 +606,11 @@ const
/*public*/
std::unique_ptr<LineString>
-GeometryFactory::createLineString() const
+GeometryFactory::createLineString(std::size_t coordinateDimension) const
{
+ if (coordinateDimension == 3) {
+ return createLineString(coordinateListFactory->create(std::size_t(0), coordinateDimension));
+ }
return std::unique_ptr<LineString>(new LineString(nullptr, this));
}
diff --git a/src/geom/Point.cpp b/src/geom/Point.cpp
index 864e883..5c3d083 100644
--- a/src/geom/Point.cpp
+++ b/src/geom/Point.cpp
@@ -54,7 +54,7 @@ Point::Point(CoordinateSequence* newCoords, const GeometryFactory* factory)
std::unique_ptr<CoordinateSequence> coords(newCoords);
if(coords == nullptr) {
- empty3d = true;
+ empty2d = true;
return;
}
@@ -82,7 +82,7 @@ Point::Point(const Point& p)
:
Geometry(p),
coordinates(p.coordinates),
- empty2d(p.empty3d),
+ empty2d(p.empty2d),
empty3d(p.empty3d)
{
}
diff --git a/src/io/WKTReader.cpp b/src/io/WKTReader.cpp
index 11a3bea..384c8bd 100644
--- a/src/io/WKTReader.cpp
+++ b/src/io/WKTReader.cpp
@@ -70,10 +70,10 @@ WKTReader::read(const string& wellKnownText)
std::unique_ptr<CoordinateSequence>
WKTReader::getCoordinates(StringTokenizer* tokenizer)
{
- size_t dim;
- string nextToken = getNextEmptyOrOpener(tokenizer);
+ size_t dim = 2;
+ string nextToken = getNextEmptyOrOpener(tokenizer, dim);
if(nextToken == "EMPTY") {
- return geometryFactory->getCoordinateSequenceFactory()->create();
+ return geometryFactory->getCoordinateSequenceFactory()->create(std::size_t(0), dim);
}
Coordinate coord;
@@ -148,11 +148,16 @@ WKTReader::getNextNumber(StringTokenizer* tokenizer)
}
string
-WKTReader::getNextEmptyOrOpener(StringTokenizer* tokenizer)
+WKTReader::getNextEmptyOrOpener(StringTokenizer* tokenizer, std::size_t& dim)
{
string nextWord = getNextWord(tokenizer);
// Skip the Z, M or ZM of an SF1.2 3/4 dim coordinate.
+ if(nextWord == "Z" || nextWord == "ZM") {
+ dim = 3;
+ }
+
+ // Skip the Z, M or ZM of an SF1.2 3/4 dim coordinate.
if(nextWord == "Z" || nextWord == "M" || nextWord == "ZM") {
nextWord = getNextWord(tokenizer);
}
@@ -249,10 +254,10 @@ WKTReader::readGeometryTaggedText(StringTokenizer* tokenizer)
std::unique_ptr<Point>
WKTReader::readPointText(StringTokenizer* tokenizer)
{
- size_t dim;
- string nextToken = getNextEmptyOrOpener(tokenizer);
+ size_t dim = 2;
+ string nextToken = getNextEmptyOrOpener(tokenizer, dim);
if(nextToken == "EMPTY") {
- return geometryFactory->createPoint();
+ return geometryFactory->createPoint(dim);
}
Coordinate coord;
@@ -279,7 +284,8 @@ WKTReader::readLinearRingText(StringTokenizer* tokenizer)
std::unique_ptr<MultiPoint>
WKTReader::readMultiPointText(StringTokenizer* tokenizer)
{
- string nextToken = getNextEmptyOrOpener(tokenizer);
+ size_t dim = 2;
+ string nextToken = getNextEmptyOrOpener(tokenizer, dim);
if(nextToken == "EMPTY") {
return geometryFactory->createMultiPoint();
}
@@ -287,7 +293,6 @@ WKTReader::readMultiPointText(StringTokenizer* tokenizer)
int tok = tokenizer->peekNextToken();
if(tok == StringTokenizer::TT_NUMBER) {
- size_t dim;
// Try to parse deprecated form "MULTIPOINT(0 0, 1 1)"
auto coords = detail::make_unique<CoordinateArraySequence>();
@@ -350,9 +355,10 @@ WKTReader::readMultiPointText(StringTokenizer* tokenizer)
std::unique_ptr<Polygon>
WKTReader::readPolygonText(StringTokenizer* tokenizer)
{
- string nextToken = getNextEmptyOrOpener(tokenizer);
+ size_t dim = 2;
+ string nextToken = getNextEmptyOrOpener(tokenizer, dim);
if(nextToken == "EMPTY") {
- return geometryFactory->createPolygon();
+ return geometryFactory->createPolygon(dim);
}
std::vector<std::unique_ptr<LinearRing>> holes;
@@ -369,7 +375,8 @@ WKTReader::readPolygonText(StringTokenizer* tokenizer)
std::unique_ptr<MultiLineString>
WKTReader::readMultiLineStringText(StringTokenizer* tokenizer)
{
- string nextToken = getNextEmptyOrOpener(tokenizer);
+ size_t dim = 2;
+ string nextToken = getNextEmptyOrOpener(tokenizer, dim);
if(nextToken == "EMPTY") {
return geometryFactory->createMultiLineString();
}
@@ -386,7 +393,8 @@ WKTReader::readMultiLineStringText(StringTokenizer* tokenizer)
std::unique_ptr<MultiPolygon>
WKTReader::readMultiPolygonText(StringTokenizer* tokenizer)
{
- string nextToken = getNextEmptyOrOpener(tokenizer);
+ size_t dim = 2;
+ string nextToken = getNextEmptyOrOpener(tokenizer, dim);
if(nextToken == "EMPTY") {
return geometryFactory->createMultiPolygon();
}
@@ -403,7 +411,8 @@ WKTReader::readMultiPolygonText(StringTokenizer* tokenizer)
std::unique_ptr<GeometryCollection>
WKTReader::readGeometryCollectionText(StringTokenizer* tokenizer)
{
- string nextToken = getNextEmptyOrOpener(tokenizer);
+ size_t dim = 2;
+ string nextToken = getNextEmptyOrOpener(tokenizer, dim);
if(nextToken == "EMPTY") {
return geometryFactory->createGeometryCollection();
}
diff --git a/src/operation/buffer/BufferInputLineSimplifier.cpp b/src/operation/buffer/BufferInputLineSimplifier.cpp
index 2fd6e92..1ada936 100644
--- a/src/operation/buffer/BufferInputLineSimplifier.cpp
+++ b/src/operation/buffer/BufferInputLineSimplifier.cpp
@@ -128,7 +128,7 @@ BufferInputLineSimplifier::findNextNonDeletedIndex(size_t index) const
std::unique_ptr<geom::CoordinateSequence>
BufferInputLineSimplifier::collapseLine() const
{
- auto coordList = detail::make_unique<CoordinateArraySequence>();
+ auto coordList = new CoordinateArraySequence();
for(size_t i = 0, n = inputLine.size(); i < n; ++i) {
if(isDeleted[i] != DELETE) {
@@ -136,7 +136,7 @@ BufferInputLineSimplifier::collapseLine() const
}
}
- return coordList;
+ return std::unique_ptr<CoordinateSequence>(coordList);
}
/* private */
diff --git a/tests/unit/geom/PointTest.cpp b/tests/unit/geom/PointTest.cpp
index 5aeb1e4..3880eb8 100644
--- a/tests/unit/geom/PointTest.cpp
+++ b/tests/unit/geom/PointTest.cpp
@@ -566,7 +566,7 @@ void object::test<45>
()
{
auto empty3d = factory_->createPoint();
- ensure_equals(empty3d->getCoordinateDimension(), 3);
+ ensure_equals(empty3d->getCoordinateDimension(), 2);
geos::geom::FixedSizeCoordinateSequence<0> seq2(2);
ensure_equals(seq2.getDimension(), 2u);
diff --git a/tests/unit/io/WKBWriterTest.cpp b/tests/unit/io/WKBWriterTest.cpp
index 381449c..fae8fbc 100644
--- a/tests/unit/io/WKBWriterTest.cpp
+++ b/tests/unit/io/WKBWriterTest.cpp
@@ -197,6 +197,74 @@ void object::test<6>
assert(geom->equals(geom2.get()));
}
+// https://trac.osgeo.org/geos/ticket/1048
+// Higher dimension empty. Need correct support in WKT reader and in
+// WKB writer.
+template<>
+template<>
+void object::test<7>
+()
+{
+ auto geom = wktreader.read("POINT Z EMPTY");
+ geom->setSRID(4326);
+ std::stringstream result_stream;
+
+ wkbwriter.setOutputDimension(3);
+ wkbwriter.setByteOrder(1);
+ wkbwriter.setIncludeSRID(1);
+ wkbwriter.writeHEX(*geom, result_stream);
+
+ std::string actual = result_stream.str();
+ ensure_equals(actual, "01010000A0E6100000000000000000F87F000000000000F87F000000000000F87F");
+
+ auto geom2 = wkbreader.readHEX(result_stream);
+ assert(geom->equals(geom2.get()));
+}
+
+template<>
+template<>
+void object::test<8>
+()
+{
+ auto geom = wktreader.read("LINESTRING Z EMPTY");
+ geom->setSRID(4326);
+ std::stringstream result_stream;
+
+ wkbwriter.setOutputDimension(3);
+ wkbwriter.setByteOrder(1);
+ wkbwriter.setIncludeSRID(1);
+ wkbwriter.writeHEX(*geom, result_stream);
+
+ std::string actual = result_stream.str();
+ ensure_equals(actual, "01020000A0E610000000000000");
+
+ auto geom2 = wkbreader.readHEX(result_stream);
+ assert(geom->equals(geom2.get()));
+}
+
+template<>
+template<>
+void object::test<9>
+()
+{
+ auto geom = wktreader.read("GEOMETRYCOLLECTION (POINT EMPTY)");
+ geom->setSRID(4326);
+ std::stringstream result_stream;
+
+ wkbwriter.setOutputDimension(3);
+ wkbwriter.setByteOrder(1);
+ wkbwriter.setIncludeSRID(0);
+ wkbwriter.writeHEX(*geom, result_stream);
+
+ std::string actual = result_stream.str();
+ ensure_equals(actual, "0107000000010000000101000000000000000000F87F000000000000F87F");
+
+ auto geom2 = wkbreader.readHEX(result_stream);
+ assert(geom->equals(geom2.get()));
+}
+
+
+
} // namespace tut
diff --git a/tests/unit/io/WKTReaderTest.cpp b/tests/unit/io/WKTReaderTest.cpp
index a50fe6f..f7808fb 100644
--- a/tests/unit/io/WKTReaderTest.cpp
+++ b/tests/unit/io/WKTReaderTest.cpp
@@ -193,4 +193,30 @@ void object::test<8>
}
}
+// Correctly read higher dimensional empty
+template<>
+template<>
+void object::test<9>
+()
+{
+ auto geom1(wktreader.read("POINT EMPTY"));
+ ensure("dimension(POINT EMPTY) == 2", geom1->getCoordinateDimension() == 2);
+
+ auto geom2(wktreader.read("POINT Z EMPTY"));
+ ensure("dimension(POINT Z EMPTY) == 3", geom2->getCoordinateDimension() == 3);
+
+ auto geom3(wktreader.read("LINESTRING EMPTY"));
+ ensure("dimension(LINESTRING EMPTY) == 2", geom3->getCoordinateDimension() == 2);
+
+ auto geom4(wktreader.read("LINESTRING Z EMPTY"));
+ ensure("dimension(LINESTRING Z EMPTY) == 3", geom4->getCoordinateDimension() == 3);
+
+ auto geom5(wktreader.read("POLYGON EMPTY"));
+ ensure("dimension(POLYGON EMPTY) == 2", geom5->getCoordinateDimension() == 2);
+
+ auto geom6(wktreader.read("POLYGON Z EMPTY"));
+ ensure("dimension(POLYGON Z EMPTY) == 3", geom6->getCoordinateDimension() == 3);
+}
+
+
} // namespace tut
-----------------------------------------------------------------------
Summary of changes:
include/geos/geom/GeometryFactory.h | 6 +-
include/geos/io/WKTReader.h | 2 +-
src/geom/GeometryFactory.cpp | 17 ++++--
src/geom/Point.cpp | 4 +-
src/io/WKTReader.cpp | 37 +++++++-----
src/operation/buffer/BufferInputLineSimplifier.cpp | 4 +-
tests/unit/geom/PointTest.cpp | 2 +-
tests/unit/io/WKBWriterTest.cpp | 68 ++++++++++++++++++++++
tests/unit/io/WKTReaderTest.cpp | 26 +++++++++
9 files changed, 139 insertions(+), 27 deletions(-)
hooks/post-receive
--
GEOS
More information about the geos-commits
mailing list