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); } } } }
shared_ptr<Element> ServicesDbReader::_resultToElement(QSqlQuery& resultIterator, const ElementType& elementType, OsmMap& map, long mapId) { assert(resultIterator.isActive()); //It makes much more sense to have callers call next on the iterator before passing it into this //method. However, I was getting some initialization errors with QSqlQuery when the //ServicesDbReader called it in that way during a partial map read. So, calling it inside here //instead. A side effect is that this method will return a NULL element during the last //iteration. Therefore, callers should check resultIterator->isActive in a loop in place of //calling resultIterator->next() and also should check for the null element. if (resultIterator.next()) { shared_ptr<Element> element; //TODO: this section could be simplified switch (elementType.getEnum()) { case ElementType::Node: { element = _resultToNode(resultIterator, map); } break; case ElementType::Way: { element = _resultToWay(resultIterator, map, mapId); } break; case ElementType::Relation: { element = _resultToRelation(resultIterator, map, mapId); } break; default: throw HootException(QString("Unexpected element type: %1").arg(elementType.toString())); } _addTagsToElement(element); return element; } else { resultIterator.finish(); return shared_ptr<Element>(); } }
void OsmApiDbReader::_read(shared_ptr<OsmMap> map, const ElementType& elementType) { LOG_DEBUG("IN OsmApiDbReader::read(,)..."); long long lastId = LLONG_MIN; shared_ptr<Element> element; QStringList tags; bool firstElement = true; // contact the DB and select all shared_ptr<QSqlQuery> elementResultsIterator = _database.selectElements(elementType); assert(elementResultsIterator->isActive()); while( elementResultsIterator->next() ) { long long id = elementResultsIterator->value(0).toLongLong(); if( lastId != id ) { // process the complete element only after the first element created if(!firstElement) { 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(); } // extract the node contents except for the tags switch (elementType.getEnum()) { case ElementType::Node: element = _resultToNode(*elementResultsIterator, *map); break; case ElementType::Way: element = _resultToWay(*elementResultsIterator, *map); break; case ElementType::Relation: element = _resultToRelation(*elementResultsIterator, *map); break; default: throw HootException(QString("Unexpected element type: %1").arg(elementType.toString())); } lastId = id; firstElement = false; } // read the tag for as many rows as there are tags // need to get into form "key1"=>"val1", "key2"=>"val2", ... QString result = _database.extractTagFromRow(elementResultsIterator, elementType.getEnum()); if(result != "") tags << result; } // process the last complete element only if an element has been created if(!firstElement) { 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(); } LOG_DEBUG("LEAVING OsmApiDbReader::_read..."); }
void OsmApiDbReader::_readBounded(shared_ptr<OsmMap> map, const ElementType& elementType, const Envelope& env) { LOG_DEBUG("IN OsmApiDbReader::readBounded(,)..."); long long lastId = LLONG_MIN; shared_ptr<Element> element; QStringList tags; bool firstElement = true; // contact the DB and select all shared_ptr<QSqlQuery> elementResultsIterator = _database.selectBoundedElements(_osmElemId, elementType, _bbox); // check if db active or not assert(elementResultsIterator->isActive()); switch (elementType.getEnum()) { /////////////////////////////////////////////////////////////////// // NODES /////////////////////////////////////////////////////////////////// case ElementType::Node: while( elementResultsIterator->next() ) { long long id = elementResultsIterator->value(0).toLongLong(); if( lastId != id ) { // process the complete element only after the first element created if(!firstElement) { 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(); } // extract the node contents except for the tags element = _resultToNode(*elementResultsIterator, *map); lastId = id; firstElement = false; } // read the tag for as many rows as there are tags // need to get into form "key1"=>"val1", "key2"=>"val2", ... QString result = _database.extractTagFromRow(elementResultsIterator, elementType.getEnum()); if(result != "") { tags << result; } } // process the last complete element only if an element has been created if(!firstElement) { 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(); } break; /////////////////////////////////////////////////////////////////// // WAYS /////////////////////////////////////////////////////////////////// case ElementType::Way: while( elementResultsIterator->next() ) { long long wayId = elementResultsIterator->value(0).toLongLong(); shared_ptr<QSqlQuery> nodeInfoIterator = _database.selectNodesForWay( wayId ); 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 have a polygon, so now you have to do some work; else go on to the next way_id // process the way into a data structure shared_ptr<Element> element = _resultToWay(*elementResultsIterator, *map); // get the way tags shared_ptr<QSqlQuery> wayTagIterator = _database.selectTagsForWay( wayId ); while( wayTagIterator->next() ) { // test for blank tag QString val1 = wayTagIterator->value(1).toString(); QString val2 = wayTagIterator->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(); } } break; /////////////////////////////////////////////////////////////////// // RELATIONS /////////////////////////////////////////////////////////////////// case ElementType::Relation: while( elementResultsIterator->next() ) { _processRelation(*elementResultsIterator, *map, env); } break; default: throw HootException(QString("Unexpected element type: %1").arg(elementType.toString())); } LOG_DEBUG("LEAVING OsmApiDbReader::_read..."); }