bool SegmentIntersectionTester::hasIntersection( const LineString &line, const LineString &testLine) { typedef std::size_t size_type; const CoordinateSequence &seq0 = *(line.getCoordinatesRO()); size_type seq0size = seq0.getSize(); const CoordinateSequence &seq1 = *(testLine.getCoordinatesRO()); size_type seq1size = seq1.getSize(); for (size_type i = 1; i<seq0size && !hasIntersectionVar; ++i) { seq0.getAt(i - 1, pt00); seq0.getAt(i, pt01); for (size_type j = 1; j < seq1size && !hasIntersectionVar; ++j) { seq1.getAt(j-1, pt10); seq1.getAt(j, pt11); li.computeIntersection(pt00, pt01, pt10, pt11); if (li.hasIntersection()) hasIntersectionVar = true; } } return hasIntersectionVar; }
/*private*/ bool RectangleContains::isLineStringContainedInBoundary(const LineString& line) { const CoordinateSequence &seq = *(line.getCoordinatesRO()); for (unsigned int i=0, n=seq.getSize()-1; i<n; ++i) { const Coordinate& p0=seq.getAt(i); const Coordinate& p1=seq.getAt(i+1); if (! isLineSegmentContainedInBoundary(p0, p1)) return false; } return true; }
void WKBWriter::writeLineString(const LineString& g) { writeByteOrder(); writeGeometryType(WKBConstants::wkbLineString, g.getSRID()); writeSRID(g.getSRID()); const CoordinateSequence* cs = g.getCoordinatesRO(); assert(cs); writeCoordinateSequence(*cs, true); }
bool SegmentIntersectionTester::hasIntersectionWithEnvelopeFilter( const LineString &line, const LineString &testLine) { typedef std::size_t size_type; const CoordinateSequence &seq0 = *(line.getCoordinatesRO()); size_type seq0size = seq0.getSize(); const CoordinateSequence &seq1 = *(testLine.getCoordinatesRO()); size_type seq1size = seq1.getSize(); const Envelope* lineEnv = line.getEnvelopeInternal(); typedef std::size_t size_type; for (size_type i = 1; i<seq1size && !hasIntersectionVar; ++i) { seq1.getAt(i-1, pt10); seq1.getAt(i, pt11); // skip test if segment does not intersect query envelope if (! lineEnv->intersects(Envelope(pt10, pt11))) continue; for (size_type j = 1; j < seq0size && !hasIntersectionVar; ++j) { seq0.getAt(j - 1, pt00); seq0.getAt(j, pt01); li.computeIntersection(pt00, pt01, pt10, pt11); if (li.hasIntersection()) hasIntersectionVar = true; } } return hasIntersectionVar; }
void RectangleIntersectionBuilder::reconnectPolygons(const Rectangle & rect) { // Build the exterior rings first typedef std::vector< geom::Geometry *> LinearRingVect; typedef std::pair< geom::LinearRing *, LinearRingVect * > ShellAndHoles; typedef std::list< ShellAndHoles > ShellAndHolesList; ShellAndHolesList exterior; const CoordinateSequenceFactory &_csf = *_gf.getCoordinateSequenceFactory(); // If there are no lines, the rectangle must have been // inside the exterior ring. if(lines.empty()) { geom::LinearRing * ring = rect.toLinearRing(_gf); exterior.push_back(make_pair(ring, new LinearRingVect())); } else { // Reconnect all lines into one or more linearrings // using box boundaries if necessary std::vector<Coordinate> *ring = NULL; while(!lines.empty() || ring != NULL) { if(ring == NULL) { ring = new std::vector<Coordinate>(); LineString *line = lines.front(); lines.pop_front(); line->getCoordinatesRO()->toVector(*ring); delete line; } // Distance to own endpoint double own_distance = distance(rect, *ring); // Find line to connect to // TODO: should we use LineMerge op ? double best_distance = -1; std::list<LineString*>::iterator best_pos = lines.begin(); for(std::list<LineString*>::iterator iter=lines.begin(); iter!=lines.end(); ++iter) { double d = distance(rect, *ring, *iter); if(best_distance < 0 || d<best_distance) { best_distance = d; best_pos = iter; } } // If own end point is closest, close the ring and continue if(best_distance < 0 || own_distance < best_distance) { close_ring(rect,ring); normalize_ring(*ring); geom::CoordinateSequence *shell_cs = _csf.create(ring); geom::LinearRing *shell = _gf.createLinearRing(shell_cs); exterior.push_back(make_pair(shell, new LinearRingVect())); ring = NULL; } else { LineString * line = *best_pos; int nr = ring->size(); const CoordinateSequence& cs = *line->getCoordinatesRO(); close_boundary(rect, ring, (*ring)[nr-1].x, (*ring)[nr-1].y, cs[0].x, cs[0].y); // above function adds the 1st point for (size_t i=1; i<cs.size(); ++i) ring->push_back(cs[i]); //ring->addSubLineString(line,1); delete line; lines.erase(best_pos); } } } // Attach holes to polygons for (std::list<geom::Polygon *>::iterator i=polygons.begin(), e=polygons.end(); i!=e; ++i) { geom::Polygon *poly = *i; const geom::LineString *hole = poly->getExteriorRing(); if(exterior.size() == 1) { exterior.front().second->push_back( hole->clone() ); } else { using geos::algorithm::CGAlgorithms; geom::Coordinate c; hole->getCoordinatesRO()->getAt(0, c); for (ShellAndHolesList::iterator i=exterior.begin(), e=exterior.end(); i!=e; ++i) { ShellAndHoles &p = *i; const CoordinateSequence *shell_cs = p.first->getCoordinatesRO(); if( CGAlgorithms::isPointInRing(c, shell_cs) ) { // add hole to shell p.second->push_back(hole->clone()); break; } } } delete poly; } // Build the result polygons std::list<geom::Polygon *> new_polygons; for (ShellAndHolesList::iterator i=exterior.begin(), e=exterior.end(); i!=e; ++i) { ShellAndHoles &p = *i; geom::Polygon * poly = _gf.createPolygon(p.first, p.second); new_polygons.push_back(poly); } clear(); polygons = new_polygons; }