Skip to content

Commit

Permalink
Multi-dimensional CoordinateSequence (#721)
Browse files Browse the repository at this point in the history
* Convert CoordinateSequence from abstract to concrete class

Implementation is taken from CoordinateArraySequence.
FixedSizeCoordinateSequence is removed.

* Implement CoordinateSequence using std::vector<double>

* Support XYZM in WKTReader, WKTWriter

* Update WKTReader behavior and tests

* Pad XYM CoordinateSequences to XYZM, for now

* Support M values in WKBReader

* Support M values in WKBWriter

* Add some tests, resolve TODOs

* Handle M values in CAPI CoordSeq array and buffer functions

Improves performance of copy-to-buffer by about 75%

* Remove CoordinateSequenceFactory

* Optimize CoordinateSequence::initialize

* Fix MSVC linking error

* Add tests

* Allow autogenerated CoordinateSequence move ctr

* Avoid changing LineString::normalize behavior for zero-length LineString

* Update NEWS

* Avoid change in Coordinate::toString (breaks PostGIS test)

* Remove commented-out code

* Avoid repetition in Coordinate isNull methods

* Fix copyright

* Remove commented-out code

* Remove duplicated import
  • Loading branch information
dbaston authored Nov 30, 2022
1 parent 0e8d436 commit 60edf0e
Show file tree
Hide file tree
Showing 225 changed files with 4,705 additions and 4,072 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Makefile
*.cmake
CMakeFiles
CMakeCache.txt
CMakeLists.txt.user
DartConfiguration.tcl
.DS_Store
macros/libtool.m4
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ xxxx-xx-xx
- New things:
- Polygonal coverage operations: CoverageValidator, CoveragePolygonValidator,
CoverageGapFinder, CoverageUnion (JTS-900, Martin Davis & Paul Ramsey)
- Support reading and writing M values through WKB and WKT readers/writers
(GH-721, Dan Baston)
- CAPI: GEOSPreparedContainsXY, GEOSPreparedIntersectsXY (GH-677, Dan Baston)
- Add CoordinateSequenceIterator (GH-685, Dan Baston)
- Geometry clustering: DBSCAN, geometry intersection/distance, envelope
Expand Down
7 changes: 2 additions & 5 deletions benchmarks/ClassSizes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@

#include <geos/geom/GeometryFactory.h>
#include <geos/io/WKTReader.h>
#include <geos/geom/CoordinateArraySequence.h>
#include <geos/geom/FixedSizeCoordinateSequence.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/Point.h>
#include <geos/geom/LinearRing.h>
Expand Down Expand Up @@ -73,9 +72,7 @@ main()
check(geom::MultiPoint);
check(geom::MultiLineString);
check(geom::MultiPolygon);
check(geom::CoordinateArraySequence);
check(geom::FixedSizeCoordinateSequence<1>);
check(geom::FixedSizeCoordinateSequence<2>);
check(geom::CoordinateSequence);
check(triangulate::quadedge::QuadEdge);
check(triangulate::quadedge::QuadEdgeQuartet);
check(triangulate::quadedge::Vertex);
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/algorithm/UnaryUnionSegmentsPerfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#include <geos/triangulate/DelaunayTriangulationBuilder.h>
#include <geos/triangulate/VoronoiDiagramBuilder.h>
#include <geos/geom/CoordinateArraySequence.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/profiler.h>

Expand All @@ -36,7 +36,7 @@ class SegmentUnaryUnionPerfTest {
std::vector<std::unique_ptr<LineString>> lines;

for (std::size_t i = 0; i < num_lines; i++) {
CoordinateArraySequence cas(2, 2);
CoordinateSequence cas(2, 2);
cas.setAt(Coordinate(dis(e), dis(e)), 0);
cas.setAt(Coordinate(dis(e), dis(e)), 1);

Expand Down
7 changes: 3 additions & 4 deletions benchmarks/algorithm/VoronoiPerfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#include <geos/triangulate/DelaunayTriangulationBuilder.h>
#include <geos/triangulate/VoronoiDiagramBuilder.h>
#include <geos/geom/CoordinateArraySequence.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/profiler.h>

Expand All @@ -32,11 +32,10 @@ class VoronoiPerfTest {
std::default_random_engine e(12345);
std::uniform_real_distribution<> dis(0, 100);

std::unique_ptr<std::vector<Coordinate>> coords(new std::vector<Coordinate>(num_points));
std::generate(coords->begin(), coords->end(), [&dis, &e]() {
CoordinateSequence seq(num_points);
std::generate(seq.items<Coordinate>().begin(), seq.items<Coordinate>().end(), [&dis, &e]() {
return Coordinate(dis(e), dis(e));
});
CoordinateArraySequence seq(coords.release());
auto geom = gfact->createLineString(seq.clone());

voronoi(seq);
Expand Down
12 changes: 12 additions & 0 deletions benchmarks/geom/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@ IF(benchmark_FOUND)
target_link_libraries(perf_envelope PRIVATE
benchmark::benchmark geos_cxx_flags)
endif()

IF(benchmark_FOUND)
add_executable(perf_coordseq
CoordinateSequencePerfTest.cpp
${PROJECT_SOURCE_DIR}/src/geom/CoordinateSequence.cpp
${PROJECT_SOURCE_DIR}/src/geom/Coordinate.cpp)
target_include_directories(perf_coordseq PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>)
target_link_libraries(perf_coordseq PRIVATE
benchmark::benchmark geos_cxx_flags)
endif()
56 changes: 56 additions & 0 deletions benchmarks/geom/CoordinateSequencePerfTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2022 ISciences, LLC
*
* 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.
*
**********************************************************************/

#include <benchmark/benchmark.h>

#include <geos/geom/CoordinateSequence.h>

using geos::geom::Coordinate;
using geos::geom::CoordinateSequence;

static void BM_Size(benchmark::State& state) {
CoordinateSequence z(1533);

for (auto _ : state) {
benchmark::DoNotOptimize(z.size());
}
}

static void BM_Initialize(benchmark::State& state) {
bool hasZ = false;
bool hasM = false;

for (auto _ : state) {
CoordinateSequence seq(1000, hasZ, hasM, true);
}
}

static void BM_HasRepeatedPoints(benchmark::State & state) {
CoordinateSequence seq(12345, false, false);
for (std::size_t i = 0; i < seq.size(); ++i) {
double di = static_cast<double>(i);
seq.setAt(Coordinate(di, di + 0.1), i);
}

for (auto _ : state) {
benchmark::DoNotOptimize(seq.hasRepeatedPoints());
}
}

BENCHMARK(BM_Size);
BENCHMARK(BM_Initialize);
BENCHMARK(BM_HasRepeatedPoints);

BENCHMARK_MAIN();

6 changes: 3 additions & 3 deletions benchmarks/index/SpatialIndexPerfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <geos/index/quadtree/Quadtree.h>
#include <geos/index/intervalrtree/SortedPackedIntervalRTree.h>

using geos::geom::Coordinate;
using geos::geom::CoordinateXY;
using geos::geom::Envelope;
using geos::index::intervalrtree::SortedPackedIntervalRTree;
using geos::index::quadtree::Quadtree;
Expand Down Expand Up @@ -65,10 +65,10 @@ static std::vector<Envelope> generate_envelopes(std::default_random_engine & e,
return envelopes;
}

std::vector<Coordinate> generate_uniform_points(std::default_random_engine& eng,
std::vector<CoordinateXY> generate_uniform_points(std::default_random_engine& eng,
const Envelope& box,
std::size_t n) {
std::vector<Coordinate> pts(n);
std::vector<CoordinateXY> pts(n);

std::uniform_real_distribution<> qx(box.getMinX(), box.getMaxX());
std::uniform_real_distribution<> qy(box.getMinY(), box.getMaxY());
Expand Down
6 changes: 3 additions & 3 deletions benchmarks/index/chain/MonotoneChainBuilderPerfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

#include <benchmark/benchmark.h>

#include <geos/geom/CoordinateArraySequence.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/index/chain/MonotoneChain.h>
#include <geos/index/chain/MonotoneChainBuilder.h>

using geos::geom::Coordinate;
using geos::geom::LineSegment;
using geos::geom::CoordinateArraySequence;
using geos::geom::CoordinateSequence;
using geos::geom::Envelope;
using geos::index::chain::MonotoneChain;
using geos::index::chain::MonotoneChainBuilder;
Expand All @@ -42,7 +42,7 @@ static void BM_MonotoneChainBuilder(benchmark::State& state) {

std::size_t num_points = 1000;

CoordinateArraySequence cs;
CoordinateSequence cs;
Coordinate prev(0, 0);
while(cs.size() <= num_points) {
size_t chain_length = 1 + static_cast<size_t>(chain_length_dist(e));
Expand Down
8 changes: 4 additions & 4 deletions benchmarks/index/chain/MonotoneChainPerfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@

#include <benchmark/benchmark.h>

#include <geos/geom/CoordinateArraySequence.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/index/chain/MonotoneChain.h>
#include <geos/index/chain/MonotoneChainOverlapAction.h>

using geos::geom::Coordinate;
using geos::geom::LineSegment;
using geos::geom::CoordinateArraySequence;
using geos::geom::CoordinateSequence;
using geos::geom::Envelope;
using geos::index::chain::MonotoneChain;
using geos::index::chain::MonotoneChainOverlapAction;

static void BM_MonotoneChainOverlaps(benchmark::State& state) {
CoordinateArraySequence cs1;
CoordinateArraySequence cs2;
CoordinateSequence cs1;
CoordinateSequence cs2;

std::default_random_engine e(12345);
std::uniform_real_distribution<> dist(0, 1);
Expand Down
Loading

0 comments on commit 60edf0e

Please sign in to comment.