/** * Create a new "split edge" with the section of points between * (and including) the two intersections. * The label for the new edge is the same as the label for the parent edge. */ SegmentString* SegmentNodeList::createSplitEdge(SegmentNode *ei0, SegmentNode *ei1) { //Debug.print("\ncreateSplitEdge"); Debug.print(ei0); Debug.print(ei1); int npts = ei1->segmentIndex - ei0->segmentIndex + 2; Coordinate lastSegStartPt=edge->getCoordinate(ei1->segmentIndex); // if the last intersection point is not equal to the its segment start pt, // add it to the points list as well. // (This check is needed because the distance metric is not totally reliable!) // The check for point equality is 2D only - Z values are ignored bool useIntPt1=ei1->dist > 0.0 || ! ei1->coord->equals2D(lastSegStartPt); if (! useIntPt1) { npts--; } CoordinateSequence *pts = new DefaultCoordinateSequence(npts); int ipt = 0; //pts->setAt(Coordinate(*(ei0->coord)),ipt++); pts->setAt(*(ei0->coord), ipt++); for (int i = ei0->segmentIndex + 1; i <= ei1->segmentIndex; i++) { pts->setAt(edge->getCoordinate(i),ipt++); } if (useIntPt1) pts->setAt(*(ei1->coord),ipt++); SegmentString *ret = new SegmentString(pts,edge->getContext()); splitEdges.push_back(ret); splitCoordLists.push_back(pts); return ret; }
/*static*/ string WKTWriter::toLineString(const CoordinateSequence& seq) { stringstream buf("LINESTRING ", ios_base::in|ios_base::out); unsigned int npts = seq.getSize(); if ( npts == 0 ) { buf << "EMPTY"; } else { buf << "("; for (unsigned int i=0; i<npts; ++i) { if (i) buf << ", "; buf << seq.getX(i) << " " << seq.getY(i); #if PRINT_Z buf << seq.getZ(i); #endif } buf << ")"; } return buf.str(); }
void coordinateSeq() { CoordinateSequence *cl = new CoordinateArraySequence(); cl->add(Coordinate(100,100)); cl->add(Coordinate(100,200)); cl->add(Coordinate(200,200)); cl->add(Coordinate(200,100)); cl->add(Coordinate(180,180)); //cl->add(Coordinate(100,100)); cl->add(geos::geom::Coordinate(150, 150)); cl->add(geos::geom::Coordinate(190, 190)); cl->add(geos::geom::Coordinate(150, 250)); cl->add(geos::geom::Coordinate(250, 250)); cl->add(geos::geom::Coordinate(250, 150)); //cl->add(geos::geom::Coordinate(150, 150)); LinearRing *lr = global_factory->createLinearRing(cl); geos::geom::Polygon *poly=NULL; poly = global_factory->createPolygon(lr,NULL); CoordinateSequence *cr = new CoordinateArraySequence(); cr->add(geos::geom::Coordinate(120, 120)); cr->add(geos::geom::Coordinate(120, 170)); cr->add(geos::geom::Coordinate(170, 170)); cr->add(geos::geom::Coordinate(170, 120)); //cr->add(geos::geom::Coordinate(120, 120)); LinearRing *li = global_factory->createLinearRing(cr); geos::geom::Polygon *poly1=global_factory->createPolygon(li,NULL); geos::geom::Geometry *pint = poly1->intersection(poly); io::WKTWriter *wkt = new io::WKTWriter(); string tmp=wkt->write(pint); cout<<" (WKT coordinateSeq Intersection) "<<tmp<<endl; }
shared_ptr<LineString> ElementConverter::convertToLineString(const ConstWayPtr& w) const { const std::vector<long>& ids = w->getNodeIds(); int size = ids.size(); if (size == 1) { size = 2; } CoordinateSequence* cs = GeometryFactory::getDefaultInstance()->getCoordinateSequenceFactory()-> create(size, 2); for (size_t i = 0; i < ids.size(); i++) { shared_ptr<const Node> n = _constProvider->getNode(ids[i]); cs->setAt(n->toCoordinate(), i); } // a linestring cannot contain 1 point. Do this to keep it valid. if (ids.size() == 1) { shared_ptr<const Node> n = _constProvider->getNode(ids[0]); cs->setAt(n->toCoordinate(), 1); } shared_ptr<LineString> result(GeometryFactory::getDefaultInstance()->createLineString(cs)); return result; }
CoordinateSequence* WKTReader::getCoordinates(StringTokenizer *tokenizer) { string nextToken=getNextEmptyOrOpener(tokenizer); if (nextToken=="EMPTY") { return geometryFactory->getCoordinateSequenceFactory()->create(NULL); //new CoordinateArraySequence(); } CoordinateSequence *coordinates = \ geometryFactory->getCoordinateSequenceFactory()->create(NULL); Coordinate coord; getPreciseCoordinate(tokenizer, coord); coordinates->add(coord); try { nextToken=getNextCloserOrComma(tokenizer); while (nextToken==",") { getPreciseCoordinate(tokenizer, coord); coordinates->add(coord); nextToken=getNextCloserOrComma(tokenizer); } } catch (...) { delete coordinates; throw; } return coordinates; }
Edge* Edge::getCollapsedEdge() { testInvariant(); CoordinateSequence *newPts = new CoordinateArraySequence(2); newPts->setAt(pts->getAt(0),0); newPts->setAt(pts->getAt(1),1); return new Edge(newPts, Label::toLineLabel(label)); }
void DelaunayTriangulationBuilder::unique(CoordinateSequence& coords) { std::vector<Coordinate> coordVector; coords.toVector(coordVector); std::sort(coordVector.begin(), coordVector.end(), geos::geom::CoordinateLessThen()); coords.setPoints(coordVector); coords.removeRepeatedPoints(); }
CoordinateArraySequence::CoordinateArraySequence( const CoordinateSequence &c ) : CoordinateSequence(c), vect(new vector<Coordinate>(c.size())), dimension(c.getDimension()) { for (size_t i = 0, n = vect->size(); i < n; ++i) { (*vect)[i] = c.getAt(i); } }
void WKBWriter::writeCoordinateSequence(const CoordinateSequence &cs, bool sized) { int size = cs.getSize(); bool is3d=false; if ( cs.getDimension() > 2 && outputDimension > 2) is3d = true; if (sized) writeInt(size); for (int i=0; i<size; i++) writeCoordinate(cs, i, is3d); }
CoordinateSequence * WKBReader::readCoordinateSequence(int size) { CoordinateSequence *seq = factory.getCoordinateSequenceFactory()->create(size, inputDimension); unsigned int targetDim = seq->getDimension(); if ( targetDim > inputDimension ) targetDim = inputDimension; for (int i=0; i<size; i++) { readCoordinate(); for (unsigned int j=0; j<targetDim; j++) { seq->setOrdinate(i, j, ordValues[j]); } } return seq; }
shared_ptr<Polygon> ElementConverter::convertToPolygon(const ConstWayPtr& w) const { const std::vector<long>& ids = w->getNodeIds(); size_t size = ids.size(); if (size == 1) { size = 2; } // if the first and last nodes aren't the same. if (ids.size() > 0 && ids[0] != ids[ids.size() - 1]) { size++; } if (size <= 3) { return shared_ptr<Polygon>(GeometryFactory::getDefaultInstance()->createPolygon()); } CoordinateSequence* cs = GeometryFactory::getDefaultInstance()->getCoordinateSequenceFactory()-> create(size, 2); size_t i; for (i = 0; i < ids.size(); i++) { shared_ptr<const Node> n = _constProvider->getNode(ids[i]); cs->setAt(n->toCoordinate(), i); } // if there are fewer than two points, or the last point does not equal the first while (i < size) { // add the first point onto the end. shared_ptr<const Node> n = _constProvider->getNode(ids[0]); cs->setAt(n->toCoordinate(), i); i++; } // an empty set of holes vector<Geometry*>* holes = new vector<Geometry*>(); // create the outer line LinearRing* outer = GeometryFactory::getDefaultInstance()->createLinearRing(cs); shared_ptr<Polygon> result(GeometryFactory::getDefaultInstance()->createPolygon(outer, holes)); return result; }
/*private*/ SegmentString* SegmentNodeList::createSplitEdge(SegmentNode *ei0, SegmentNode *ei1) { assert(ei0); assert(ei1); size_t npts = ei1->segmentIndex - ei0->segmentIndex + 2; const Coordinate &lastSegStartPt=edge.getCoordinate(ei1->segmentIndex); // if the last intersection point is not equal to the its // segment start pt, add it to the points list as well. // (This check is needed because the distance metric is not // totally reliable!) // The check for point equality is 2D only - Z values are ignored // Added check for npts being == 2 as in that case NOT using second point // would mean creating a SegmentString with a single point // FIXME: check with mbdavis about this, ie: is it a bug in the caller ? // bool useIntPt1 = npts == 2 || (ei1->isInterior() || ! ei1->coord.equals2D(lastSegStartPt)); if (! useIntPt1) { npts--; } CoordinateSequence *pts = new CoordinateArraySequence(npts); size_t ipt = 0; pts->setAt(ei0->coord, ipt++); for (size_t i=ei0->segmentIndex+1; i<=ei1->segmentIndex; i++) { pts->setAt(edge.getCoordinate(i),ipt++); } if (useIntPt1) pts->setAt(ei1->coord, ipt++); SegmentString *ret = new SegmentString(pts, edge.getData()); #if GEOS_DEBUG std::cerr<<" SegmentString created"<<std::endl; #endif splitEdges.push_back(ret); // Keep track of created CoordinateSequence to release // it at this SegmentNodeList destruction time splitCoordLists.push_back(pts); return ret; }
bool WayMergeManipulation::_directConnect(const OsmMapPtr& map, WayPtr w) const { boost::shared_ptr<LineString> ls = ElementConverter(map).convertToLineString(w); CoordinateSequence* cs = GeometryFactory::getDefaultInstance()->getCoordinateSequenceFactory()-> create(2, 2); cs->setAt(map->getNode(w->getNodeId(0))->toCoordinate(), 0); cs->setAt(map->getNode(w->getLastNodeId())->toCoordinate(), 1); // create a straight line and buffer it boost::shared_ptr<LineString> straight(GeometryFactory::getDefaultInstance()->createLineString(cs)); boost::shared_ptr<Geometry> g(straight->buffer(w->getCircularError())); // is the way in question completely contained in the buffer? return g->contains(ls.get()); }
Coordinate WayAverager::_moveToLineAsCoordinate(long ni, double nWeight, const LineString* ls, double lWeight) { shared_ptr<Node> n = _map.getNode(ni); Point* point(GeometryFactory::getDefaultInstance()->createPoint(n->toCoordinate())); // find the two closest points CoordinateSequence* cs = DistanceOp::closestPoints(point, const_cast<LineString*>(ls)); Coordinate result = Coordinate(cs->getAt(0).x * nWeight + cs->getAt(1).x * lWeight, cs->getAt(0).y * nWeight + cs->getAt(1).y * lWeight); delete cs; delete point; return result; }
void DelaunayTriangulationBuilder::setSites(const CoordinateSequence& coords) { if(siteCoords) delete siteCoords; siteCoords = coords.clone(); // remove any duplicate points (they will cause the triangulation to fail) unique(*siteCoords); }
/* private */ void Centroid::addHole(const CoordinateSequence& pts) { bool isPositiveArea = CGAlgorithms::isCCW(&pts); for (size_t i = 0, e = pts.size() - 1; i < e; ++i) { addTriangle(*areaBasePt, pts[i], pts[i+1], isPositiveArea); } addLineSegments(pts); }
Coordinate BaseComparator::_findNearestPointOnFeature(shared_ptr<OsmMap> map, Coordinate c) { Coordinate result; // find the nearest feature long wId = map->getIndex().findNearestWay(c); shared_ptr<Way> w = map->getWay(wId); // find the nearest point on that feature. shared_ptr<Point> p(GeometryFactory::getDefaultInstance()->createPoint(c)); shared_ptr<LineString> ls = ElementConverter(map).convertToLineString(w); CoordinateSequence* cs = DistanceOp::closestPoints(p.get(), ls.get()); cs->getAt(0, result); delete cs; return result; }
/* private */ void BufferBuilder::computeNodedEdges(SegmentString::NonConstVect& bufferSegStrList, const PrecisionModel *precisionModel) // throw(GEOSException) { Noder* noder = getNoder( precisionModel ); noder->computeNodes(&bufferSegStrList); SegmentString::NonConstVect* nodedSegStrings = \ noder->getNodedSubstrings(); for (SegmentString::NonConstVect::iterator i=nodedSegStrings->begin(), e=nodedSegStrings->end(); i!=e; ++i) { SegmentString* segStr = *i; const Label* oldLabel = static_cast<const Label*>(segStr->getData()); CoordinateSequence* cs = CoordinateSequence::removeRepeatedPoints(segStr->getCoordinates()); if ( cs->size() < 2 ) { delete cs; // we need to take care of the memory here as cs is a new sequence return; // don't insert collapsed edges } // we need to clone SegmentString coordinates // as Edge will take ownership of them // TODO: find a way to transfer ownership instead // Who will own the edge ? FIXME: find out and handle that! Edge* edge = new Edge(cs, new Label(*oldLabel)); // will take care of the Edge ownership insertUniqueEdge(edge); } if ( nodedSegStrings != &bufferSegStrList ) { delete nodedSegStrings; } if ( noder != workingNoder ) delete noder; }
void WKBWriter::writeCoordinate(const CoordinateSequence& cs, size_t idx, bool is3d) { #if DEBUG_WKB_WRITER cout << "writeCoordinate: X:" << cs.getX(idx) << " Y:" << cs.getY(idx) << endl; #endif assert(outStream); ByteOrderValues::putDouble(cs.getX(idx), buf, byteOrder); outStream->write(reinterpret_cast<char*>(buf), 8); ByteOrderValues::putDouble(cs.getY(idx), buf, byteOrder); outStream->write(reinterpret_cast<char*>(buf), 8); if(is3d) { ByteOrderValues::putDouble( cs.getOrdinate(idx, CoordinateSequence::Z), buf, byteOrder); outStream->write(reinterpret_cast<char*>(buf), 8); } }
/* private */ void Centroid::addShell(const CoordinateSequence& pts) { size_t len = pts.size(); if (len > 0) setBasePoint(pts[0]); bool isPositiveArea = ! CGAlgorithms::isCCW(&pts); for (size_t i = 0; i < len - 1; ++i) { addTriangle(*areaBasePt, pts[i], pts[i+1], isPositiveArea); } addLineSegments(pts); }
void object::test<1>() { CoordinateSequence* cs = new CoordinateArraySequence(); cs->add(Coordinate(0.0, 0.0)); cs->add(Coordinate(1.0, DoubleNotANumber)); GeomPtr line ( factory_.createLineString(cs) ); IsValidOp isValidOp(line.get()); bool valid = isValidOp.isValid(); TopologyValidationError* err = isValidOp.getValidationError(); ensure(0 != err); const Coordinate& errCoord = err->getCoordinate(); ensure_equals( err->getErrorType(), TopologyValidationError::eInvalidCoordinate ); ensure(0 != ISNAN(errCoord.y)); ensure_equals(valid, false); }
/*private*/ void OffsetCurveBuilder::computeRingBufferCurve(const CoordinateSequence& inputPts, int side) { int n=inputPts.size()-1; initSideSegments(inputPts[n-1], inputPts[0], side); for (int i=1; i<=n; i++) { bool addStartPoint=i != 1; addNextSegment(inputPts[i], addStartPoint); } vertexList->closeRing(); }
/// Tries to add another sequence onto the start or end of this one. /// If it succeeds, the other sequence may also be modified and /// should be considered "spent". bool tryAdd(CoordinateSequence &other) { //add the sequence at the end if (last()==other.first()) { coordinates.pop_back(); addToEnd(other.coordinates); return true; } //add the sequence backwards at the end if (last()==other.last()) { coordinates.pop_back(); other.reverse(); addToEnd(other.coordinates); return true; } //add the sequence at the beginning if (first()==other.last()) { coordinates.pop_front(); addToBegin(other.coordinates); return true; } //add the sequence backwards at the beginning if (first()==other.first()) { coordinates.pop_front(); other.reverse(); addToBegin(other.coordinates); return true; } return false; }
void object::test<13>() { Coordinate p1(-123456789, -40); Coordinate p2(381039468754763.0, 123456789); Coordinate q(0, 0); using geos::geom::CoordinateSequence; using geos::geom::GeometryFactory; using geos::geom::LineString; GeometryFactory::Ptr factory = GeometryFactory::create(); CoordinateSequence* cs = new CoordinateArraySequence(); cs->add(p1); cs->add(p2); GeomPtr l ( factory->createLineString(cs) ); GeomPtr p ( factory->createPoint(q) ); ensure(!l->intersects(p.get())); ensure(!CGAlgorithms::isOnLine(q, cs)); ensure_equals(CGAlgorithms::computeOrientation(p1, p2, q), -1); }
// This function will create a LinearString // geometry with the shape of the letter U // having top-left corner at given coordinates // and 'side' height and width LineString * create_ushaped_linestring(double xoffset, double yoffset, double side) { // We will use a coordinate list to build the linestring CoordinateSequence *cl = new CoordinateArraySequence(); cl->add(Coordinate(xoffset, yoffset)); cl->add(Coordinate(xoffset, yoffset+side)); cl->add(Coordinate(xoffset+side, yoffset+side)); cl->add(Coordinate(xoffset+side, yoffset)); // Now that we have a CoordinateSequence we can create // the linestring. // The newly created LineString will take ownership // of the CoordinateSequence. LineString *ls = global_factory->createLineString(cl); // This is what you do if you want the new LineString // to make a copy of your CoordinateSequence: // LineString *ls = global_factory->createLineString(*cl); return ls; // our LineString }
int CoordinateSequence::increasingDirection(const CoordinateSequence& pts) { size_t ptsize = pts.size(); for (size_t i=0, n=ptsize/2; i<n; ++i) { size_t j = ptsize - 1 - i; // skip equal points on both ends int comp = pts[i].compareTo(pts[j]); if (comp != 0) return comp; } // array must be a palindrome - defined to be in positive direction return 1; }
void RectangleIntersectionBuilder::reconnect() { // Nothing to reconnect if there aren't at least two lines if(lines.size() < 2) return; geom::LineString * line1 = lines.front(); const geom::CoordinateSequence &cs1 = *line1->getCoordinatesRO(); geom::LineString * line2 = lines.back(); const geom::CoordinateSequence &cs2 = *line2->getCoordinatesRO(); const int n1 = cs1.size(); const int n2 = cs2.size(); // Safety check against bad input to prevent segfaults if(n1==0 || n2==0) return; if (cs1[0] != cs2[n2-1]) return; // Merge the two linestrings CoordinateSequence *ncs = CoordinateSequence::removeRepeatedPoints(&cs2); ncs->add(&cs1, false, true); delete line1; delete line2; LineString * nline = _gf.createLineString(ncs); lines.pop_front(); lines.pop_back(); lines.push_front(nline); }
void LineMergeGraph::addEdge(const LineString *lineString) { if (lineString->isEmpty()) return; #if GEOS_DEBUG cerr<<"Adding LineString "<<lineString->toString()<<endl; #endif CoordinateSequence *coordinates = CoordinateSequence::removeRepeatedPoints(lineString->getCoordinatesRO()); const Coordinate& startCoordinate=coordinates->getAt(0); const Coordinate& endCoordinate=coordinates->getAt(coordinates->getSize()-1); planargraph::Node* startNode=getNode(startCoordinate); planargraph::Node* endNode=getNode(endCoordinate); #if GEOS_DEBUG cerr<<" startNode: "<<*startNode<<endl; cerr<<" endNode: "<<*endNode<<endl; #endif planargraph::DirectedEdge *directedEdge0=new LineMergeDirectedEdge(startNode, endNode,coordinates->getAt(1), true); newDirEdges.push_back(directedEdge0); planargraph::DirectedEdge *directedEdge1=new LineMergeDirectedEdge(endNode, startNode,coordinates->getAt(coordinates->getSize()-2), false); newDirEdges.push_back(directedEdge1); planargraph::Edge *edge=new LineMergeEdge(lineString); newEdges.push_back(edge); edge->setDirectedEdges(directedEdge0, directedEdge1); #if GEOS_DEBUG cerr<<" planargraph::Edge: "<<*edge<<endl; #endif add(edge); #if GEOS_DEBUG cerr<<" After addition to the graph:"<<endl; cerr<<" startNode: "<<*startNode<<endl; cerr<<" endNode: "<<*endNode<<endl; #endif delete coordinates; }
void WKBWriter::writeCoordinateSequence(const CoordinateSequence& cs, bool sized) { std::size_t size = cs.getSize(); bool is3d = false; if(outputDimension > 2) { is3d = true; } if(sized) { writeInt(static_cast<int>(size)); } for(std::size_t i = 0; i < size; i++) { writeCoordinate(cs, i, is3d); } }
/* private */ void Centroid::addLineSegments(const CoordinateSequence& pts) { size_t npts = pts.size(); double lineLen = 0.0; for (size_t i = 0; i < npts - 1; i++) { double segmentLen = pts[i].distance(pts[i + 1]); if (segmentLen == 0.0) continue; lineLen += segmentLen; double midx = (pts[i].x + pts[i + 1].x) / 2; lineCentSum.x += segmentLen * midx; double midy = (pts[i].y + pts[i + 1].y) / 2; lineCentSum.y += segmentLen * midy; } totalLength += lineLen; if (lineLen == 0.0 && npts > 0) addPoint(pts[0]); }