Skip to content

Commit

Permalink
Merge branch 'overlay-sr'
Browse files Browse the repository at this point in the history
  • Loading branch information
pramsey committed Jul 28, 2020
2 parents 5586055 + e79f2af commit a375140
Show file tree
Hide file tree
Showing 251 changed files with 43,969 additions and 919 deletions.
73 changes: 73 additions & 0 deletions DEVELOPER-NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
## GEOS is a port of JTS

* The algorithms that form the core value of GEOS are developed in Java in the [JTS library](https://github.com/locationtech/jts/). C++ developers will find this annoying, but:

* This is just history, JTS was written first and GEOS was a slavish port.
* Being memory managed, JTS is an easier language to prototype in.
* Having various visual tooling, JTS is an easier platform to debug spatial algorithms in.
* Being Java, JTS has less language legacy than GEOS, which was originally ported when STL was still not part of the standard, and therefor reflects a mix of styles and eras.

* Ideally, new algorithms will be implemented in JTS and then ported to GEOS.
* Smaller performance optimizations in GEOS can travel back to JTS.

* Short circuits, indexes, other non-language optimizations, should be ticketed in JTS when they are added to GEOS.

### Follow JTS as Much as Possible

* Don't rename things! It makes it harder to port updates and fixes.

* Class names
* Method names
* Variable names
* Class members

* Yes, we know in your last job you were taught all member variables are prefixed with `m_`, but please don't.



### Manage Lifecycles

* Frequently objects are only used local to a method and not returned to the caller.
* In such cases, avoid lifecycle issues entirely by **instantiating on the local stack**.

```java
MyObj foo = new MyObj("bar");
```

```c++
MyObj foo("bar");
```
* Long-lived members of objects that are passed around should be held using [std::unique_ptr<>](https://en.cppreference.com/w/cpp/memory/unique_ptr).
```java
private MyMember foo = new MyMember();
```

```c++
private:

std::unique_ptr<MyMember> foo;

public:

MyMember()
: foo(new MyMember())
{}
```
* You can pass pointers to the object to other methods using `std::unique_ptr<>.get()`.
### Avoid Many Small Heap Allocations
* Heap allocations (objects created using `new`) are more expensive than stack allocations, but they can show up in batchs in JTS in places where structures are built, like index trees, or graphs.
* To both lower the overhead of heap allocations, and to manage the life-cycle of the objects, we recommend storing small objects in an appropriate "double-ended queue", like [std::deque<>](https://en.cppreference.com/w/cpp/container/deque).
* The implementation of `edgegraph` is an example.
* The `edgegraph` consists of a structure of many `HalfEdge` objects (two for each edge!), created in the `EdgeGraph::createEdge()` method and stored in a `std::deque<>`.
* The `std::deque<>` provides two benefits:
* It lowers the number of heap allocations, because it allocates larger blocks of space to store multiple `HalfEdge` objects.
* It handles the lifecycle of the `HalfEdge` objects that make up the `EdgeGraph`, because when the `EdgeGraph` is deallocated, the `std::deque<>` and all its contents are also automatically deallocated.
8 changes: 8 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ AC_OUTPUT([
src/algorithm/construct/Makefile
src/algorithm/distance/Makefile
src/algorithm/locate/Makefile
src/edgegraph/Makefile
src/geom/Makefile
src/geom/prep/Makefile
src/geom/util/Makefile
Expand All @@ -378,13 +379,15 @@ AC_OUTPUT([
include/geos/algorithm/locate/Makefile
include/geos/algorithm/distance/Makefile
include/geos/algorithm/construct/Makefile
include/geos/edgegraph/Makefile
include/geos/geom/Makefile
include/geos/geom/prep/Makefile
include/geos/geom/util/Makefile
include/geos/geomgraph/Makefile
include/geos/geomgraph/index/Makefile
include/geos/index/Makefile
include/geos/index/bintree/Makefile
include/geos/index/kdtree/Makefile
include/geos/index/chain/Makefile
include/geos/index/intervalrtree/Makefile
include/geos/index/quadtree/Makefile
Expand All @@ -394,6 +397,7 @@ AC_OUTPUT([
include/geos/linearref/Makefile
include/geos/math/Makefile
include/geos/noding/Makefile
include/geos/noding/snap/Makefile
include/geos/noding/snapround/Makefile
include/geos/operation/Makefile
include/geos/operation/buffer/Makefile
Expand All @@ -402,6 +406,7 @@ AC_OUTPUT([
include/geos/operation/linemerge/Makefile
include/geos/operation/overlay/Makefile
include/geos/operation/overlay/snap/Makefile
include/geos/operation/overlayng/Makefile
include/geos/operation/polygonize/Makefile
include/geos/operation/predicate/Makefile
include/geos/operation/relate/Makefile
Expand All @@ -418,6 +423,7 @@ AC_OUTPUT([
include/geos/version.h
src/index/Makefile
src/index/bintree/Makefile
src/index/kdtree/Makefile
src/index/chain/Makefile
src/index/intervalrtree/Makefile
src/index/quadtree/Makefile
Expand All @@ -427,13 +433,15 @@ AC_OUTPUT([
src/linearref/Makefile
src/math/Makefile
src/noding/Makefile
src/noding/snap/Makefile
src/noding/snapround/Makefile
src/operation/Makefile
src/operation/buffer/Makefile
src/operation/distance/Makefile
src/operation/intersection/Makefile
src/operation/linemerge/Makefile
src/operation/overlay/Makefile
src/operation/overlayng/Makefile
src/operation/polygonize/Makefile
src/operation/predicate/Makefile
src/operation/relate/Makefile
Expand Down
1 change: 1 addition & 0 deletions include/geos/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#
SUBDIRS = \
algorithm \
edgegraph \
geom \
geomgraph \
index \
Expand Down
13 changes: 10 additions & 3 deletions include/geos/algorithm/CGAlgorithmsDD.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ class GEOS_DLL CGAlgorithmsDD {
static int orientationIndex(const geom::Coordinate& p1,
const geom::Coordinate& p2,
const geom::Coordinate& q);


static int orientationIndex(double p1x, double p1y,
double p2x, double p2y,
double qx, double qy);

/** \brief
* A filter for computing the orientation index of three coordinates.
*
Expand All @@ -87,9 +93,10 @@ class GEOS_DLL CGAlgorithmsDD {
* @return the orientation index if it can be computed safely
* @return `i > 1` if the orientation index cannot be computed safely
*/
static int orientationIndexFilter(const geom::Coordinate& pa,
const geom::Coordinate& pb,
const geom::Coordinate& pc);
static int orientationIndexFilter(double pax, double pay,
double pbx, double pby,
double pcx, double pcy);


static int
orientation(double x)
Expand Down
144 changes: 144 additions & 0 deletions include/geos/edgegraph/EdgeGraph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2020 Paul Ramsey <[email protected]>
*
* 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.
*
**********************************************************************/


#pragma once

#include <geos/edgegraph/HalfEdge.h>

#include <geos/export.h>
#include <string>
#include <cassert>
#include <map>
#include <array>
#include <memory>
#include <vector>

// Forward declarations
namespace geos {
namespace geom {
class Coordinate;
}
}

#undef EDGEGRAPH_HEAPHACK

namespace geos {
namespace edgegraph { // geos.edgegraph


/**
* A graph comprised of {@link HalfEdge}s.
* It supports tracking the vertices in the graph
* via edges incident on them,
* to allow efficient lookup of edges and vertices.
* <p>
* This class may be subclassed to use a
* different subclass of HalfEdge,
* by overriding {@link #createEdge(Coordinate)}.
* If additional logic is required to initialize
* edges then {@link EdgeGraph#addEdge(Coordinate, Coordinate)}
* can be overridden as well.
*
* @author Martin Davis
*
*/

class GEOS_DLL EdgeGraph {

private:

std::deque<HalfEdge> edges;
std::map<geom::Coordinate, HalfEdge*> vertexMap;

HalfEdge* create(const geom::Coordinate& p0, const geom::Coordinate& p1);


protected:

/**
* Creates a single HalfEdge.
* Override to use a different HalfEdge subclass.
*
* @param orig the origin location
* @return a new HalfEdge with the given origin
*/
HalfEdge* createEdge(const geom::Coordinate& orig);

/**
* Inserts an edge not already present into the graph.
*
* @param orig the edge origin location
* @param dest the edge destination location
* @param eAdj an existing edge with same orig (if any)
* @return the created edge
*/
HalfEdge* insert(const geom::Coordinate& orig, const geom::Coordinate& dest, HalfEdge* eAdj);


public:

/**
* Initialized
*/
EdgeGraph() {};

/**
* Adds an edge between the coordinates orig and dest
* to this graph.
* Only valid edges can be added (in particular, zero-length segments cannot be added)
*
* @param orig the edge origin location
* @param dest the edge destination location.
* @return the created edge
* @return null if the edge was invalid and not added
*
* @see #isValidEdge(Coordinate, Coordinate)
*/
HalfEdge* addEdge(const geom::Coordinate& orig, const geom::Coordinate& dest);

/**
* Tests if the given coordinates form a valid edge (with non-zero length).
*
* @param orig the start coordinate
* @param dest the end coordinate
* @return true if the edge formed is valid
*/
static bool isValidEdge(const geom::Coordinate& orig, const geom::Coordinate& dest);

void getVertexEdges(std::vector<const HalfEdge*>& edgesOut);

/**
* Finds an edge in this graph with the given origin
* and destination, if one exists.
*
* @param orig the origin location
* @param dest the destination location.
* @return an edge with the given orig and dest, or null if none exists
*/
HalfEdge* findEdge(const geom::Coordinate& orig, const geom::Coordinate& dest);






};


} // namespace geos.edgegraph
} // namespace geos



Loading

0 comments on commit a375140

Please sign in to comment.