void OsmApiDbReader::_addNodesForWay(vector<long> nodeIds, OsmMap& map) { for (unsigned int i = 0; i < nodeIds.size(); i++) { QStringList tags; if (map.containsNode(nodeIds[i]) == false) { shared_ptr<QSqlQuery> queryIterator = _database.selectNodeById(nodeIds[i]); while (queryIterator->next()) { shared_ptr<Node> node = _resultToNode(*queryIterator.get(), map); QString result = _database.extractTagFromRow(queryIterator, ElementType::Node); if(result != "") { tags << result; } if(tags.size()>0) { node->setTags(ApiDb::unescapeTags(tags.join(", ")) ); ApiDbReader::addTagsToElement(node); } if (_status != Status::Invalid) { node->setStatus(_status); } map.addElement(node); } } } }
ElementId OsmApiDbReader::_mapElementId(const OsmMap& map, ElementId oldId) { ElementId result; if (_useDataSourceIds) { result = oldId; } else { long id = oldId.getId(); switch (oldId.getType().getEnum()) { case ElementType::Node: if (_nodeIdMap.count(id) > 0) { result = ElementId::node(_nodeIdMap.at(id)); } else { long newId = map.createNextNodeId(); _nodeIdMap[id] = newId; result = ElementId::node(newId); } break; case ElementType::Way: if (_wayIdMap.count(id) > 0) { result = ElementId::way(_wayIdMap.at(id)); } else { long newId = map.createNextWayId(); _wayIdMap[id] = newId; result = ElementId::way(newId); } break; case ElementType::Relation: if (_relationIdMap.count(id) > 0) { result = ElementId::relation(_relationIdMap.at(id)); } else { long newId = map.createNextRelationId(); _relationIdMap[id] = newId; result = ElementId::relation(newId); } break; default: throw IllegalArgumentException("Expected a valid element type, but got: " + QString::number(oldId.getType().getEnum())); } } return result; }
bool WayCleaner::hasDuplicateCoords(ConstWayPtr way, const OsmMap& map, const bool logDetails) { const vector<long> nodeIds = way->getNodeIds(); if (nodeIds.size() == 2 && map.getNode(nodeIds.at(0))->toCoordinate() == map.getNode(nodeIds.at(1))->toCoordinate()) { if (logDetails) { LOG_WARN( "Duplicate coordinate " << map.getNode(nodeIds.at(0))->toCoordinate() << " for node with ID:'s " << nodeIds[0] << " and " << nodeIds[1] << " found at indexes 0 and 1; For way with ID: " << way->getElementId().getId()); LOG_VARW(nodeIds); } return true; } bool found = false; QList<Coordinate> coords; for (size_t i = 0; i < nodeIds.size(); i++) { const Coordinate coord = map.getNode(nodeIds[i])->toCoordinate(); if (coords.contains(coord)) { //the only duplicated coords allowed are the first and last for a closed way, if the node ID's //match if (i == (nodeIds.size() - 1) && nodeIds[0] == nodeIds[i]) { found = false; } else { found = true; } if (found) { if (logDetails) { LOG_WARN( "Duplicate coord " << map.getNode(nodeIds[i])->toCoordinate() << " for node with ID: " << nodeIds[i] << " found at index: " << i << " For way with ID: " << way->getElementId().getId()); LOG_VARW(nodeIds); } return found; } } else { coords.append(coord); } } return found; }
double SmallerOverlapExtractor::extract(const OsmMap& map, const ConstElementPtr& target, const ConstElementPtr& candidate) const { ElementConverter ec(map.shared_from_this()); shared_ptr<Geometry> g1 = ec.convertToGeometry(target); shared_ptr<Geometry> g2 = ec.convertToGeometry(candidate); if (g1->isEmpty() || g2->isEmpty()) { return nullValue(); } auto_ptr<Geometry> overlap; try { overlap.reset(g1->intersection(g2.get())); } catch (geos::util::TopologyException& e) { g1.reset(GeometryUtils::validateGeometry(g1.get())); g2.reset(GeometryUtils::validateGeometry(g2.get())); overlap.reset(g2->intersection(g1.get())); } double a1 = g1->getArea(); double a2 = g2->getArea(); double overlapArea = overlap->getArea(); if (a1 == 0.0 || a2 == 0.0) { return 0.0; } return std::min(1.0, overlapArea / min(a1, a2)); }
double AbstractDistanceExtractor::combinedEnvelopeDiagonalDistance(const OsmMap& map, const boost::shared_ptr<const Element>& target, const boost::shared_ptr<const Element>& candidate) const { ConstOsmMapPtr m = map.shared_from_this(); boost::shared_ptr<Envelope> env(target->getEnvelope(m)); boost::shared_ptr<Envelope> candidateEnv(candidate->getEnvelope(m)); env->expandToInclude(candidateEnv.get()); return sqrt(env->getWidth() * env->getWidth() + env->getHeight() * env->getHeight()); }
double WayFeatureExtractor::extract(const OsmMap& map, const shared_ptr<const Element>& target, const shared_ptr<const Element>& candidate) const { vector<double> scores; if (target->getElementType() == ElementType::Way && candidate->getElementType() == ElementType::Way) { scores.push_back(_extract(map, dynamic_pointer_cast<const Way>(target), dynamic_pointer_cast<const Way>(candidate))); } else if (target->getElementType() == ElementType::Relation && candidate->getElementType() == ElementType::Relation) { ConstRelationPtr r1 = dynamic_pointer_cast<const Relation>(target); ConstRelationPtr r2 = dynamic_pointer_cast<const Relation>(candidate); if (r1->getType() == Relation::MULTILINESTRING && r2->getType() == Relation::MULTILINESTRING && r1->getMembers().size() == r2->getMembers().size()) { for (size_t i = 0; i < r1->getMembers().size(); i++) { ElementId eid1 = r1->getMembers()[i].getElementId(); ElementId eid2 = r2->getMembers()[i].getElementId(); if (eid1.getType() != ElementType::Way || eid2.getType() != ElementType::Way) { return nullValue(); } scores.push_back(_extract(map, map.getWay(eid1), map.getWay(eid2))); } } else { return nullValue(); } } else { return nullValue(); } return _agg->aggregate(scores); }
InWayNodeFilter::InWayNodeFilter(FilterType type, const OsmMap& map, const vector<long>& wids) { _type = type; for (size_t i = 0; i < wids.size(); i++) { shared_ptr<const Way> w = map.getWay(wids[i]); const vector<long>& nids = w->getNodeIds(); _nids.insert(nids.begin(), nids.end()); } }
KnnWayIterator::KnnWayIterator(const OsmMap& map, ConstWayPtr way, const RStarTree* tree, const vector<long>& treeIdToWid, bool addError) : KnnIterator(tree, 0.0, 0.0, Box()), _map(map), _treeIdToWid(treeIdToWid) { _wayId = way->getId(); _ls = ElementConverter(map.shared_from_this()).convertToLineString(way); _lsFast = _ls.get(); _indexSlush = _map.getIndex().getIndexSlush(); _distanceCount = 0; _addError = addError; _baseAccuracy = way->getCircularError(); }
double HausdorffDistanceExtractor::distance(const OsmMap &map, const shared_ptr<const Element>& target, const shared_ptr<const Element> &candidate) const { ElementConverter ec(map.shared_from_this()); shared_ptr<Geometry> g1 = ec.convertToGeometry(target); shared_ptr<Geometry> g2 = ec.convertToGeometry(candidate); if (g1->isEmpty() || g2->isEmpty()) { return nullValue(); } return max(VertexHausdorffDistance(*g1, *g2).getDistance(), VertexHausdorffDistance(*g2, *g1).getDistance()); }
double WeightedShapeDistanceExtractor::_extract(const OsmMap& map, const ConstWayPtr& w1, const ConstWayPtr& w2) const { return ProbabilityOfMatch::getInstance().parallelScore(map.shared_from_this(), w1, w2); }
void OsmApiDbReader::_processRelation(const QSqlQuery& resultIterator, OsmMap& map, const Envelope& env) { QStringList tags; long long relId = resultIterator.value(0).toLongLong(); vector<RelationData::Entry> members = _database.selectMembersForRelation( relId ); for(vector<RelationData::Entry>::iterator it = members.begin(); it != members.end(); ++it) { ElementId eid = (*it).getElementId(); QString type = eid.getType().toString(); long idFromRelation = eid.getId(); if(type=="Node") { shared_ptr<QSqlQuery> nodeIterator = _database.selectBoundedElements(idFromRelation, ElementType::Node, _bbox); if( nodeIterator->next() ) // we found a relation in the bounds { // process the relation into a data structure shared_ptr<Element> element = _resultToRelation(resultIterator, map); // get the way tags shared_ptr<QSqlQuery> relationTagIterator = _database.selectTagsForRelation( relId ); while( relationTagIterator->next() ) { // test for blank tag QString val1 = relationTagIterator->value(1).toString(); QString val2 = relationTagIterator->value(2).toString(); QString tag = ""; if(val1!="" || val2!="") tag = "\""+val1+"\"=>\""+val2+"\""; if(tag != "") tags << tag; } if(tags.size()>0) { element->setTags(ApiDb::unescapeTags(tags.join(", ")) ); ApiDbReader::addTagsToElement( element ); } if (_status != Status::Invalid) {element->setStatus(_status); } map.addElement(element); tags.clear(); } } else if(type == "Way") { shared_ptr<QSqlQuery> nodeInfoIterator = _database.selectNodesForWay( idFromRelation ); bool foundOne = false; while( nodeInfoIterator->next() && !foundOne) { // do the bounds check double lat = nodeInfoIterator->value(ApiDb::NODES_LATITUDE).toLongLong()/(double)ApiDb::COORDINATE_SCALE; double lon = nodeInfoIterator->value(ApiDb::NODES_LONGITUDE).toLongLong()/(double)ApiDb::COORDINATE_SCALE; Coordinate c(lon, lat); if (env.contains(c)) { foundOne = true; } } if( foundOne ) // we found a relation in the bounds { // process the relation into a data structure shared_ptr<Element> element = _resultToRelation(resultIterator, map); // get the way tags shared_ptr<QSqlQuery> relationTagIterator = _database.selectTagsForRelation( relId ); while( relationTagIterator->next() ) { // test for blank tag QString val1 = relationTagIterator->value(1).toString(); QString val2 = relationTagIterator->value(2).toString(); QString tag = ""; if(val1!="" || val2!="") tag = "\""+val1+"\"=>\""+val2+"\""; if(tag != "") tags << tag; } if(tags.size()>0) { element->setTags( ApiDb::unescapeTags(tags.join(", ")) ); ApiDbReader::addTagsToElement( element ); } if (_status != Status::Invalid) { element->setStatus(_status); } map.addElement(element); tags.clear(); } } else if(type == "Relation") { shared_ptr<QSqlQuery> relIterator = _database.selectBoundedElements(idFromRelation, ElementType::Relation, _bbox); while(relIterator->next()) { _processRelation(*relIterator, map, env); } } } }
double LengthScoreExtractor::_extract(const OsmMap& map, const ConstWayPtr& w1, const ConstWayPtr& w2) const { return ProbabilityOfMatch::getInstance().lengthScore(map.shared_from_this(), w1, w2); }
void Node::visitRo(const OsmMap& map, ElementVisitor& filter) const { filter.visit(map.getNode(getId())); }
void Node::visitRw(OsmMap& map, ElementVisitor& filter) { filter.visit(map.getNode(getId())); }