EVOLUTION-MANAGER
Edit File: IndexedPointInAreaLocator.cpp
/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2001-2002 Vivid Solutions Inc. * Copyright (C) 2018 Daniel Baston <dbaston@gmail.com> * * 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 <geos/algorithm/locate/IndexedPointInAreaLocator.h> #include <geos/geom/Geometry.h> #include <geos/geom/Polygon.h> #include <geos/geom/MultiPolygon.h> #include <geos/geom/LineString.h> #include <geos/geom/LineSegment.h> #include <geos/geom/LinearRing.h> #include <geos/geom/CoordinateSequence.h> #include <geos/geom/util/LinearComponentExtracter.h> #include <geos/index/intervalrtree/SortedPackedIntervalRTree.h> #include <geos/util.h> #include <geos/algorithm/RayCrossingCounter.h> #include <geos/index/ItemVisitor.h> #include <algorithm> #include <typeinfo> namespace geos { namespace algorithm { namespace locate { // // private: // IndexedPointInAreaLocator::IntervalIndexedGeometry::IntervalIndexedGeometry(const geom::Geometry& g) : isEmpty(0) { if (g.isEmpty()) isEmpty = true; else init(g); } void IndexedPointInAreaLocator::IntervalIndexedGeometry::init(const geom::Geometry& g) { geom::LineString::ConstVect lines; geom::util::LinearComponentExtracter::getLines(g, lines); for(const geom::LineString* line : lines) { addLine(line->getCoordinatesRO()); } for(geom::LineSegment& seg : segments) { index.insert( std::min(seg.p0.y, seg.p1.y), std::max(seg.p0.y, seg.p1.y), &seg); } } void IndexedPointInAreaLocator::IntervalIndexedGeometry::addLine(const geom::CoordinateSequence* pts) { for(size_t i = 1, ni = pts->size(); i < ni; i++) { segments.emplace_back((*pts)[i - 1], (*pts)[i]); } } void IndexedPointInAreaLocator::buildIndex(const geom::Geometry& g) { index = detail::make_unique<IntervalIndexedGeometry>(g); } // // protected: // // // public: // IndexedPointInAreaLocator::IndexedPointInAreaLocator(const geom::Geometry& g) : areaGeom(g) { const std::type_info& areaGeomId = typeid(areaGeom); if(areaGeomId != typeid(geom::Polygon) && areaGeomId != typeid(geom::MultiPolygon) && areaGeomId != typeid(geom::LinearRing)) { throw util::IllegalArgumentException("Argument must be Polygonal or LinearRing"); } buildIndex(areaGeom); } geom::Location IndexedPointInAreaLocator::locate(const geom::Coordinate* /*const*/ p) { algorithm::RayCrossingCounter rcc(*p); IndexedPointInAreaLocator::SegmentVisitor visitor(&rcc); index->query(p->y, p->y, &visitor); return rcc.getLocation(); } void IndexedPointInAreaLocator::SegmentVisitor::visitItem(void* item) { geom::LineSegment* seg = static_cast<geom::LineSegment*>(item); counter->countSegment(seg->p0, seg->p1); } void IndexedPointInAreaLocator::IntervalIndexedGeometry::query(double min, double max, index::ItemVisitor* visitor) { if (isEmpty) return; index.query(min, max, visitor); } } // geos::algorithm::locate } // geos::algorithm } // geos