/** * 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; }
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; }
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()); }
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)); }