double WayMergeManipulation::_calculateExpertProbability(ConstOsmMapPtr map) const { OsmMapPtr theMap(new OsmMap()); CopyMapSubsetOp(map, ElementId(ElementType::Way, _left), ElementId(ElementType::Way, _right)).apply(theMap); WayPtr left = theMap->getWay(_left); WayPtr right = theMap->getWay(_right); // use the maximal nearest subline code to find the best subline WayPtr mnsLeft = MaximalNearestSubline::getMaximalNearestSubline(theMap, left, right, _minSplitSize, left->getCircularError() + right->getCircularError()); if (mnsLeft == 0) { return 0.0; } WayPtr mnsRight = MaximalNearestSubline::getMaximalNearestSubline(theMap, right, mnsLeft, _minSplitSize, left->getCircularError() + right->getCircularError()); if (mnsRight == 0) { return 0.0; } // what portion of the original lines is the MNS double pl = ElementConverter(theMap).convertToLineString(mnsLeft)->getLength() / ElementConverter(theMap).convertToLineString(left)->getLength(); double pr = ElementConverter(theMap).convertToLineString(mnsRight)->getLength() / ElementConverter(theMap).convertToLineString(right)->getLength(); // give it a score double ps = std::min(pl, pr) / 2.0 + 0.5; double p; // if either of the lines are zero in length. if (pl == 0 || pr == 0) { p = 0.0; } else { p = ps * ProbabilityOfMatch::getInstance().expertProbability(theMap, mnsLeft, mnsRight); } return p; }
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()); }
void verifyFullReadOutput(OsmMapPtr map) { //nodes CPPUNIT_ASSERT_EQUAL(2, (int)map->getNodes().size()); HOOT_STR_EQUALS(true, map->containsNode(1)); NodePtr node = map->getNode(1); CPPUNIT_ASSERT_EQUAL((long)1, node->getId()); CPPUNIT_ASSERT_EQUAL(38.4, node->getY()); CPPUNIT_ASSERT_EQUAL(-106.5, node->getX()); CPPUNIT_ASSERT_EQUAL(15.0, node->getCircularError()); CPPUNIT_ASSERT_EQUAL(2, node->getTags().size()); NodePtr node1 = map->getNode(2); CPPUNIT_ASSERT_EQUAL((long)2, node1->getId()); CPPUNIT_ASSERT_EQUAL(38.0, node1->getY()); CPPUNIT_ASSERT_EQUAL(-104.0, node1->getX()); //ways HOOT_STR_EQUALS(true, map->containsWay(1)); WayPtr way = map->getWay(1); CPPUNIT_ASSERT_EQUAL((long)1, way->getId()); CPPUNIT_ASSERT_EQUAL(2, (int)way->getNodeCount()); CPPUNIT_ASSERT_EQUAL((long)1, way->getNodeId(0)); CPPUNIT_ASSERT_EQUAL((long)2, way->getNodeId(1)); CPPUNIT_ASSERT_EQUAL(15.0, way->getCircularError()); CPPUNIT_ASSERT_EQUAL(1, way->getTags().size()); //relations HOOT_STR_EQUALS(true, map->containsRelation(1)); RelationPtr relation = map->getRelation(1); CPPUNIT_ASSERT_EQUAL((long)1, relation->getId()); vector<RelationData::Entry> relationData = relation->getMembers(); CPPUNIT_ASSERT_EQUAL(2, (int)relation->getMembers().size()); HOOT_STR_EQUALS("wayrole", relationData[0].getRole()); HOOT_STR_EQUALS("noderole",relationData[1].getRole()); CPPUNIT_ASSERT_EQUAL(15.0, relation->getCircularError()); }
void WayMergeManipulation::applyManipulation(OsmMapPtr map, set<ElementId> &impactedElements, set<ElementId> &newElements) const { OsmMapPtr result = map; // insert the impacted ways impactedElements = getImpactedElementIds(map); impactedElements.erase(ElementId::way(_left)); impactedElements.erase(ElementId::way(_right)); // remove any ways that spanned the left & right _removeSpans(result, impactedElements); WayPtr left = result->getWay(_left); WayPtr right = result->getWay(_right); Meters minSplitSize = _minSplitSize; minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(left)->getLength() * .7); minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(right)->getLength() * .7); // split left into its maximal nearest sublines MaximalNearestSubline mns1(map, left, right, minSplitSize, left->getCircularError() + right->getCircularError()); int mnsLeftIndex; vector< WayPtr > splitsLeft = mns1.splitWay(result, mnsLeftIndex); assert(splitsLeft.size() != 0); WayPtr mnsLeft = splitsLeft[mnsLeftIndex]; // split right into its maximal nearest sublines MaximalNearestSubline mns2(map, right, mnsLeft, minSplitSize, left->getCircularError() + right->getCircularError()); int mnsRightIndex; vector< WayPtr > splitsRight = mns2.splitWay(result, mnsRightIndex); assert(splitsRight.size() != 0); WayPtr mnsRight = splitsRight[mnsRightIndex]; for (size_t i = 0; i < splitsLeft.size(); i++) { if ((int)i != mnsLeftIndex) { newElements.insert(ElementId::way(splitsLeft[i]->getId())); } result->addWay(splitsLeft[i]); } for (size_t i = 0; i < splitsRight.size(); i++) { if ((int)i != mnsRightIndex) { newElements.insert(ElementId::way(splitsRight[i]->getId())); } result->addWay(splitsRight[i]); } // average the two MNSs WayPtr w = WayAverager::average(map, mnsRight, mnsLeft); w->setStatus(Status::Conflated); RemoveWayOp::removeWay(result, _left); RemoveWayOp::removeWay(result, _right); result->addWay(w); // insert the new merged way newElements.insert(ElementId::way(w->getId())); for (set<ElementId>::iterator it = impactedElements.begin(); it != impactedElements.end(); ++it) { if (result->containsElement(*it) == false) { LOG_ERROR("" << "Internal error: bad way " << it->toString()); } } }
void WayMergeManipulation::_splitWays(OsmMapPtr map, WayPtr& left, WayPtr& right) const { OsmMapPtr result = map; // insert the impacted ways set<ElementId> impactedElements = getImpactedElementIds(map); impactedElements.erase(ElementId::way(_left)); impactedElements.erase(ElementId::way(_right)); // remove any ways that spanned the left & right _removeSpans(result, impactedElements); left = result->getWay(_left); right = result->getWay(_right); Meters minSplitSize = _minSplitSize; minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(left)->getLength() * .7); minSplitSize = min(minSplitSize, ElementConverter(map).convertToLineString(right)->getLength() * .7); // split left into its maximal nearest sublines MaximalNearestSubline mns1(result, left, right, minSplitSize, left->getCircularError() + right->getCircularError()); int mnsLeftIndex; vector< WayPtr > splitsLeft = mns1.splitWay(result, mnsLeftIndex); assert(splitsLeft.size() != 0); WayPtr mnsLeft = splitsLeft[mnsLeftIndex]; // split right into its maximal nearest sublines MaximalNearestSubline mns2(result, right, mnsLeft, minSplitSize, left->getCircularError() + right->getCircularError()); int mnsRightIndex; vector< WayPtr > splitsRight = mns2.splitWay(result, mnsRightIndex); assert(splitsRight.size() != 0); WayPtr mnsRight = splitsRight[mnsRightIndex]; for (size_t i = 0; i < splitsLeft.size(); i++) { if (splitsLeft[i] != left) { result->addWay(splitsLeft[i]); } } for (size_t i = 0; i < splitsRight.size(); i++) { if (splitsRight[i] != right) { result->addWay(splitsRight[i]); } } RemoveWayOp::removeWay(result, _left); RemoveWayOp::removeWay(result, _right); for (set<ElementId>::iterator it = impactedElements.begin(); it != impactedElements.end(); ++it) { if (result->containsElement(*it) == false) { LOG_ERROR("" << "Internal error: bad way " << it->toString()); } } left = mnsLeft; right = mnsRight; }