Example #1
0
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...");
}
Example #2
0
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);
      }
    }
  }
}
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...");
}