void ServicesDbReader::_read(shared_ptr<OsmMap> map, const ElementType& elementType) { shared_ptr<QSqlQuery> elementResultsIterator = _database.selectAllElements(_mapId, _osmElemId, elementType); //need to check isActive, rather than next() here b/c resultToElement actually calls next() and //it will always return an extra null node at the end, unfortunately (see comments in //ServicesDb::resultToElement) while (elementResultsIterator->isActive()) { shared_ptr<Element> element = _resultToElement(*elementResultsIterator, elementType, *map, _mapId); //this check is necessary due to an inefficiency in ServicesDb::resultToElement if (element.get()) { if (_status != Status::Invalid) { element->setStatus(_status); } map->addElement(element); } } }
shared_ptr<Element> ServicesDbReader::readNextElement() { if (!hasMoreElements()) { throw HootException( "No more elements available to read map with ID: " + QString::number(_mapId)); } ElementType selectElementType = _getCurrentSelectElementType(); //see of another result is available if (!_elementResultIterator.get() || !_elementResultIterator->isActive()) { //no results available, so request some more results _elementResultIterator = _database.selectElements( _mapId, -1, selectElementType, _maxElementsPerMap, _getCurrentElementOffset(selectElementType)); } //results still available, so keep parsing through them shared_ptr<Element> element = _resultToElement(*_elementResultIterator, selectElementType, *_partialMap, _mapId); if (!element.get()) { //exceptional case to deal with having to call QSqlQuery::next() inside of //ServicesDb::resultToElement rather than from inside this method _elementResultIterator.reset(); return shared_ptr<Element>(); } _incrementElementIndex(selectElementType); assert(selectElementType == element->getElementType()); _elementsRead++; if (_elementsRead == _maxElementsPerMap) { _elementResultIterator->finish(); } return element; }
void ServicesDbReader::_read(shared_ptr<OsmMap> map, const ElementType& elementType) { LOG_DEBUG("IN ServicesDbReader::read(,)..."); long long lastId = LLONG_MIN; shared_ptr<Element> element; QStringList tags; bool firstElement = true; // determine is Services or Osm Api DB ServicesDb::DbType connectionType = _database.getDatabaseType(); // contact the DB and select all shared_ptr<QSqlQuery> elementResultsIterator = _database.selectAllElements(_osmElemId, elementType); // split the reading of Services and Osm Api DB upfront to avoid extra inefficiency of if-else calls // inside the isActive loop switch ( connectionType ) { case ServicesDb::DBTYPE_SERVICES: //need to check isActive, rather than next() here b/c resultToElement actually calls next() and //it will always return an extra null node at the end, unfortunately (see comments in //ServicesDb::resultToElement) while (elementResultsIterator->isActive()) { shared_ptr<Element> element = _resultToElement(*elementResultsIterator, elementType, *map ); //this check is necessary due to an inefficiency in ServicesDb::resultToElement if (element.get()) { if (_status != Status::Invalid) { element->setStatus(_status); } map->addElement(element); } } break; case ServicesDb::DBTYPE_OSMAPI: // check if db active or not 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( ServicesDb::unescapeTags(tags.join(", ")) ); _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_OsmApi(*elementResultsIterator, *map); break; case ElementType::Way: element = _resultToWay_OsmApi(*elementResultsIterator, *map); break; case ElementType::Relation: element = _resultToRelation_OsmApi(*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_OsmApi(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( ServicesDb::unescapeTags(tags.join(", ")) ); _addTagsToElement( element ); } if (_status != Status::Invalid) { element->setStatus(_status); } map->addElement(element); tags.clear(); } break; default: throw HootException("_read cannot operate on unsupported database type"); break; } LOG_DEBUG("LEAVING ServicesDbReader::_read..."); }
void ServicesDbReader::_readBounded(shared_ptr<OsmMap> map, const ElementType& elementType) { LOG_DEBUG("IN ServicesDbReader::readBounded(,)..."); long long lastId = LLONG_MIN; shared_ptr<Element> element; QStringList tags; bool firstElement = true; QStringList bboxParts = _bbox.split(","); double minLat = bboxParts[1].toDouble(); double minLon = bboxParts[0].toDouble(); double maxLat = bboxParts[3].toDouble(); double maxLon = bboxParts[2].toDouble(); // determine is Services or Osm Api DB ServicesDb::DbType connectionType = _database.getDatabaseType(); // contact the DB and select all shared_ptr<QSqlQuery> elementResultsIterator = _database.selectBoundedElements(_osmElemId, elementType, _bbox); // split the reading of Services and Osm Api DB upfront to avoid extra inefficiency of if-else calls // inside the isActive loop switch ( connectionType ) { case ServicesDb::DBTYPE_SERVICES: //need to check isActive, rather than next() here b/c resultToElement actually calls next() and //it will always return an extra null node at the end, unfortunately (see comments in //ServicesDb::resultToElement) while (elementResultsIterator->isActive()) { shared_ptr<Element> element = _resultToElement(*elementResultsIterator, elementType, *map ); //this check is necessary due to an inefficiency in ServicesDb::resultToElement if (element.get()) { if (_status != Status::Invalid) { element->setStatus(_status); } map->addElement(element); } } break; case ServicesDb::DBTYPE_OSMAPI: // 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( ServicesDb::unescapeTags(tags.join(", ")) ); _addTagsToElement( element ); } if (_status != Status::Invalid) { element->setStatus(_status); } map->addElement(element); tags.clear(); } // extract the node contents except for the tags element = _resultToNode_OsmApi(*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_OsmApi(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( ServicesDb::unescapeTags(tags.join(", ")) ); _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(ServicesDb::NODES_LATITUDE).toLongLong()/(double)ServicesDb::COORDINATE_SCALE; double lon = nodeInfoIterator->value(ServicesDb::NODES_LONGITUDE).toLongLong()/(double)ServicesDb::COORDINATE_SCALE; if(lat >= minLat && lat <= maxLat && lon >= minLon && lon <= maxLon) foundOne = true; // ToDo: process boundary condition } 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_OsmApi(*elementResultsIterator, *map); // get the way tags shared_ptr<QSqlQuery> wayTagIterator = _database.selectTagsForWay_OsmApi( 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( ServicesDb::unescapeTags(tags.join(", ")) ); _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); } break; default: throw HootException(QString("Unexpected element type: %1").arg(elementType.toString())); } break; default: throw HootException("_read cannot operate on unsupported database type"); break; } LOG_DEBUG("LEAVING ServicesDbReader::_read..."); }