203 lines
5.2 KiB
C
203 lines
5.2 KiB
C
|
/**********************************************************************
|
||
|
*
|
||
|
* GEOS - Geometry Engine Open Source
|
||
|
* http://geos.osgeo.org
|
||
|
*
|
||
|
* Copyright (C) 2006 Refractions Research 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: noding/IntersectionAdder.java rev. 1.6 (JTS-1.9)
|
||
|
*
|
||
|
**********************************************************************/
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include <geos/export.h>
|
||
|
|
||
|
#include <vector>
|
||
|
#include <iostream>
|
||
|
#include <cstdlib> // for abs()
|
||
|
|
||
|
#include <geos/geom/Coordinate.h>
|
||
|
#include <geos/noding/SegmentIntersector.h> // for inheritance
|
||
|
|
||
|
// Forward declarations
|
||
|
namespace geos {
|
||
|
namespace noding {
|
||
|
class SegmentString;
|
||
|
}
|
||
|
namespace algorithm {
|
||
|
class LineIntersector;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace geos {
|
||
|
namespace noding { // geos.noding
|
||
|
|
||
|
/** \brief
|
||
|
* Computes the intersections between two line segments in SegmentString
|
||
|
* and adds them to each string.
|
||
|
*
|
||
|
* The SegmentIntersector is passed to a Noder.
|
||
|
* The NodedSegmentString::addIntersections(algorithm::LineIntersector* li, std::size_t segmentIndex, std::size_t geomIndex)
|
||
|
* method is called whenever the Noder
|
||
|
* detects that two SegmentStrings *might* intersect.
|
||
|
* This class is an example of the *Strategy* pattern.
|
||
|
*
|
||
|
*/
|
||
|
class GEOS_DLL IntersectionAdder: public SegmentIntersector {
|
||
|
|
||
|
private:
|
||
|
|
||
|
/**
|
||
|
* These variables keep track of what types of intersections were
|
||
|
* found during ALL edges that have been intersected.
|
||
|
*/
|
||
|
bool hasIntersectionVar;
|
||
|
bool hasProper;
|
||
|
bool hasProperInterior;
|
||
|
bool hasInterior;
|
||
|
|
||
|
// the proper intersection point found
|
||
|
geom::CoordinateXYZM properIntersectionPoint;
|
||
|
|
||
|
algorithm::LineIntersector& li;
|
||
|
// bool isSelfIntersection;
|
||
|
// bool intersectionFound;
|
||
|
|
||
|
/**
|
||
|
* A trivial intersection is an apparent self-intersection which
|
||
|
* in fact is simply the point shared by adjacent line segments.
|
||
|
* Note that closed edges require a special check for the point
|
||
|
* shared by the beginning and end segments.
|
||
|
*/
|
||
|
bool isTrivialIntersection(const SegmentString* e0, std::size_t segIndex0,
|
||
|
const SegmentString* e1, std::size_t segIndex1);
|
||
|
|
||
|
// Declare type as noncopyable
|
||
|
IntersectionAdder(const IntersectionAdder& other) = delete;
|
||
|
IntersectionAdder& operator=(const IntersectionAdder& rhs) = delete;
|
||
|
|
||
|
public:
|
||
|
|
||
|
int numIntersections;
|
||
|
int numInteriorIntersections;
|
||
|
int numProperIntersections;
|
||
|
|
||
|
// testing only
|
||
|
int numTests;
|
||
|
|
||
|
IntersectionAdder(algorithm::LineIntersector& newLi)
|
||
|
:
|
||
|
hasIntersectionVar(false),
|
||
|
hasProper(false),
|
||
|
hasProperInterior(false),
|
||
|
hasInterior(false),
|
||
|
properIntersectionPoint(),
|
||
|
li(newLi),
|
||
|
numIntersections(0),
|
||
|
numInteriorIntersections(0),
|
||
|
numProperIntersections(0),
|
||
|
numTests(0)
|
||
|
{}
|
||
|
|
||
|
algorithm::LineIntersector&
|
||
|
getLineIntersector()
|
||
|
{
|
||
|
return li;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return the proper intersection point, or `Coordinate::getNull()`
|
||
|
* if none was found
|
||
|
*/
|
||
|
const geom::CoordinateXYZM&
|
||
|
getProperIntersectionPoint()
|
||
|
{
|
||
|
return properIntersectionPoint;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
hasIntersection()
|
||
|
{
|
||
|
return hasIntersectionVar;
|
||
|
}
|
||
|
|
||
|
/** \brief
|
||
|
* A proper intersection is an intersection which is interior to
|
||
|
* at least two line segments.
|
||
|
*
|
||
|
* Note that a proper intersection is not necessarily in the interior
|
||
|
* of the entire Geometry, since another edge may have an endpoint equal
|
||
|
* to the intersection, which according to SFS semantics can result in
|
||
|
* the point being on the Boundary of the Geometry.
|
||
|
*/
|
||
|
bool
|
||
|
hasProperIntersection()
|
||
|
{
|
||
|
return hasProper;
|
||
|
}
|
||
|
|
||
|
/** \brief
|
||
|
* A proper interior intersection is a proper intersection which is
|
||
|
* *not* contained in the set of boundary nodes set for this SegmentIntersector.
|
||
|
*/
|
||
|
bool
|
||
|
hasProperInteriorIntersection()
|
||
|
{
|
||
|
return hasProperInterior;
|
||
|
}
|
||
|
|
||
|
/** \brief
|
||
|
* An interior intersection is an intersection which is
|
||
|
* in the interior of some segment.
|
||
|
*/
|
||
|
bool
|
||
|
hasInteriorIntersection()
|
||
|
{
|
||
|
return hasInterior;
|
||
|
}
|
||
|
|
||
|
|
||
|
/** \brief
|
||
|
* This method is called by clients of the SegmentIntersector class to
|
||
|
* process intersections for two segments of the SegmentStrings being intersected.
|
||
|
*
|
||
|
* Note that some clients (such as MonotoneChains) may optimize away
|
||
|
* this call for segment pairs which they have determined do not
|
||
|
* intersect (e.g. by an disjoint envelope test).
|
||
|
*/
|
||
|
void processIntersections(
|
||
|
SegmentString* e0, std::size_t segIndex0,
|
||
|
SegmentString* e1, std::size_t segIndex1) override;
|
||
|
|
||
|
|
||
|
static bool
|
||
|
isAdjacentSegments(std::size_t i1, std::size_t i2)
|
||
|
{
|
||
|
return (i1 > i2 ? i1 - i2 : i2 - i1) == 1;
|
||
|
}
|
||
|
|
||
|
/** \brief
|
||
|
* Always process all intersections.
|
||
|
*
|
||
|
* @return false always
|
||
|
*/
|
||
|
bool
|
||
|
isDone() const override
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
} // namespace geos.noding
|
||
|
} // namespace geos
|
||
|
|