Путь, содержащий NodeRefs с неверным расположением - PullRequest
3 голосов
/ 17 апреля 2019

Я анализирую mayotte pbf с осмием, и мой обработчик ищет пути. Когда я нахожу один, я обрабатываю его барицентр и печатаю его. Проблема, с которой я столкнулся, состоит в том, что все способы, которые я обрабатываю, имеют invalid location. И если распечатать местоположение, я получу undefined для широты и долготы.

Есть ли проблема с моим файлом PBF или с моим пониманием библиотеки osmium ?

Вот MCVE:

/**
 * To compile this script, you should first install `libosmium` and its
 * dependencies. Then:
 *   g++ -std=c++11 -lz -lexpat -lbz2 mcve.cpp -o mcve
 */
#include <iostream>

#include <osmium/handler.hpp>
#include <osmium/io/any_input.hpp>
#include <osmium/osm/node.hpp>
#include <osmium/osm/way.hpp>
#include <osmium/visitor.hpp>

class ParkingAndCarpoolingAreasHandler : public osmium::handler::Handler {
public:
    void way(const osmium::Way& way) {
      double lng;
      double lat;
      double count = 0.0;
      for (const osmium::NodeRef& nr : way.nodes()) {
          if (!nr.location().valid()) {
            std::cerr << "Way (id=" << way.id()
                      << " version=" << way.version()
                      << " timestamp=" << way.timestamp()
                      << " visible=" << (way.visible() ? "true" : "false")
                      << " changeset=" << way.changeset()
                      << " uid=" << way.uid()
                      << " user=" << way.user() << ")\n";
            std::cerr << "NodeRef (ref=" << nr.ref() << " location=" << nr.location() << ")\n";
            std::cerr << std::endl;
            return;
          }
          count++;
          lng += nr.location().lon();
          lat += nr.location().lat();
      }
      lng /= count;
      lat /= count;
      std::cout << "POINT(" << lat << ' ' << lng << ")\n";
    }
};

int main() {
    auto otypes = osmium::osm_entity_bits::node | osmium::osm_entity_bits::way;
    osmium::io::Reader reader{"tmp/mayotte-latest.osm.pbf", otypes};
    ParkingAndCarpoolingAreasHandler handler;
    osmium::apply(reader, handler);
    reader.close();
}

1 Ответ

2 голосов
/ 17 апреля 2019

В OSM способ обычно хранит только ссылки на узел, из которого он состоит. Эти ссылки содержат только идентификатор узла, но не содержат дополнительную информацию (например, координаты и теги). Чтобы получить координаты узла, вы должны смотреть на фактические узлы, а не только на их ссылку.

См. OSM XML и Формат PBF для получения дополнительной информации.

Поскольку у меня нет опыта работы с осмием, я не могу рассказать вам, как получить соответствующие узлы по их идентификаторам. Тем не менее, согласно Руководству по осмиевым понятиям , вы можете использовать обработчик NodeLocationsForWays для заполнения ваших NodeRef объектов местоположениями. examples / osmium_road_length.cpp содержит пример.

...