188 lines
4.3 KiB
C
188 lines
4.3 KiB
C
|
/**********************************************************************
|
||
|
*
|
||
|
* GEOS - Geometry Engine Open Source
|
||
|
* http://geos.osgeo.org
|
||
|
*
|
||
|
* Copyright (C) 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: geomgraph/EdgeEnd.java r428 (JTS-1.12+)
|
||
|
*
|
||
|
**********************************************************************/
|
||
|
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <geos/export.h>
|
||
|
#include <geos/geom/Coordinate.h> // for p0,p1
|
||
|
#include <geos/geomgraph/Label.h> // for composition
|
||
|
|
||
|
#include <string>
|
||
|
|
||
|
// Forward declarations
|
||
|
namespace geos {
|
||
|
namespace algorithm {
|
||
|
class BoundaryNodeRule;
|
||
|
}
|
||
|
namespace geomgraph {
|
||
|
class Edge;
|
||
|
class Node;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace geos {
|
||
|
namespace geomgraph { // geos.geomgraph
|
||
|
|
||
|
/** \brief
|
||
|
* Models the end of an edge incident on a node.
|
||
|
*
|
||
|
* EdgeEnds have a direction
|
||
|
* determined by the direction of the ray from the initial
|
||
|
* point to the next point.
|
||
|
* EdgeEnds are comparable under the ordering
|
||
|
* "a has a greater angle with the x-axis than b".
|
||
|
* This ordering is used to sort EdgeEnds around a node.
|
||
|
*/
|
||
|
class GEOS_DLL EdgeEnd /* non-final */ {
|
||
|
|
||
|
public:
|
||
|
|
||
|
friend std::ostream& operator<< (std::ostream&, const EdgeEnd&);
|
||
|
|
||
|
EdgeEnd();
|
||
|
|
||
|
virtual
|
||
|
~EdgeEnd() {}
|
||
|
|
||
|
/**
|
||
|
* NOTES:
|
||
|
* - Copies the given Label
|
||
|
* - keeps a pointer to given Edge, make sure it's
|
||
|
* not deleted before the EdgeEnd.
|
||
|
* - copies given Coordinates (maybe we should avoid that)
|
||
|
*/
|
||
|
EdgeEnd(Edge* newEdge, const geom::Coordinate& newP0,
|
||
|
const geom::Coordinate& newP1,
|
||
|
const Label& newLabel);
|
||
|
|
||
|
/**
|
||
|
* NOTES:
|
||
|
* - keeps a pointer to given Edge, make sure it's
|
||
|
* not deleted before the EdgeEnd.
|
||
|
* - copies given Coordinates (maybe we should avoid that)
|
||
|
*/
|
||
|
EdgeEnd(Edge* newEdge, const geom::Coordinate& newP0,
|
||
|
const geom::Coordinate& newP1);
|
||
|
|
||
|
Edge*
|
||
|
getEdge()
|
||
|
{
|
||
|
return edge;
|
||
|
}
|
||
|
//virtual Edge* getEdge() { return edge; }
|
||
|
|
||
|
Label&
|
||
|
getLabel()
|
||
|
{
|
||
|
return label;
|
||
|
}
|
||
|
|
||
|
const Label&
|
||
|
getLabel() const
|
||
|
{
|
||
|
return label;
|
||
|
}
|
||
|
|
||
|
geom::Coordinate& getCoordinate() {
|
||
|
return p0;
|
||
|
}
|
||
|
|
||
|
const geom::Coordinate&
|
||
|
getCoordinate() const
|
||
|
{
|
||
|
return p0;
|
||
|
}
|
||
|
|
||
|
geom::Coordinate& getDirectedCoordinate();
|
||
|
|
||
|
int getQuadrant();
|
||
|
|
||
|
double getDx();
|
||
|
|
||
|
double getDy();
|
||
|
|
||
|
void setNode(Node* newNode);
|
||
|
|
||
|
Node* getNode();
|
||
|
|
||
|
int compareTo(const EdgeEnd* e) const;
|
||
|
|
||
|
/**
|
||
|
* Implements the total order relation:
|
||
|
*
|
||
|
* a has a greater angle with the positive x-axis than b
|
||
|
*
|
||
|
* Using the obvious algorithm of simply computing the angle
|
||
|
* is not robust, since the angle calculation is obviously
|
||
|
* susceptible to roundoff.
|
||
|
* A robust algorithm is:
|
||
|
* - first compare the quadrant. If the quadrants
|
||
|
* are different, it it trivial to determine which vector
|
||
|
* is "greater".
|
||
|
* - if the vectors lie in the same quadrant, the
|
||
|
* computeOrientation function can be used to decide
|
||
|
* the relative orientation of the vectors.
|
||
|
*/
|
||
|
int compareDirection(const EdgeEnd* e) const;
|
||
|
|
||
|
virtual void computeLabel(const algorithm::BoundaryNodeRule& bnr);
|
||
|
|
||
|
virtual std::string print() const;
|
||
|
|
||
|
protected:
|
||
|
|
||
|
Edge* edge;// the parent edge of this edge end
|
||
|
|
||
|
Label label;
|
||
|
|
||
|
EdgeEnd(Edge* newEdge);
|
||
|
|
||
|
void init(const geom::Coordinate& newP0,
|
||
|
const geom::Coordinate& newP1);
|
||
|
|
||
|
private:
|
||
|
|
||
|
/// the node this edge end originates at
|
||
|
Node* node;
|
||
|
|
||
|
/// points of initial line segment. FIXME: do we need a copy here ?
|
||
|
geom::Coordinate p0, p1;
|
||
|
|
||
|
/// the direction vector for this edge from its starting point
|
||
|
double dx, dy;
|
||
|
|
||
|
int quadrant;
|
||
|
};
|
||
|
|
||
|
std::ostream& operator<< (std::ostream&, const EdgeEnd&);
|
||
|
|
||
|
struct GEOS_DLL EdgeEndLT {
|
||
|
bool
|
||
|
operator()(const EdgeEnd* s1, const EdgeEnd* s2) const
|
||
|
{
|
||
|
return s1->compareTo(s2) < 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // namespace geos.geomgraph
|
||
|
} // namespace geos
|
||
|
|