osmium icon indicating copy to clipboard operation
osmium copied to clipboard

Compile error when using ObjectStore to feed CoordinatesForWays Handler

Open graylock opened this issue 10 years ago • 3 comments

Hi osmium developer team,

i am using osmium quite a while and at since point I want to thank you for the great work!

Currently, I am working on an application that will have multiple osmium handlers and I would like to feed the data from one ObjectStore to all handlers. I have a handler that is similar to the CoordinatesForWays handler and i run into some problems. Therefore, I build an example application reading an OSM file, loading it into an ObjectStore object and feed it to the CoordinatesForWays handler. Unfortunately, I get a compile error that tells me that there is no match to bind (boost) the method way() from CoordinatesForWays class inside the ObjectStore class in method feed_to(). I think that this has something to do with const correctness but I don't know how to fix this.

Code:

// ...
// Open file and create the object store for reading in the file
Osmium::OSMFile lOSMFile(arOSMFile);
Osmium::Storage::ObjectStore lObjectStore;

// Read OSM file data into object store
Osmium::Input::read(lOSMFile, lObjectStore);

// Create handler
typedef Osmium::Storage::ById::SparseTable<Osmium::OSM::Position> lTSparseTable;
typedef Osmium::Storage::ById::MmapAnon<Osmium::OSM::Position> lTMmapAnon;
typedef Osmium::Handler::CoordinatesForWays<lTSparseTable, lTMmapAnon> lTHandler;

lTSparseTable lSpareTable;
lTMmapAnon lMmapAnon;
lTHandler lHandler(lSpareTable, lMmapAnon);

// Feed OSM data into handler
Osmium::OSM::Meta lMeta;
lObjectStore.feed_to(&lHandler, lMeta, false);
// ...

Best regards

graylock avatar Aug 23 '13 10:08 graylock

It would help if you show us the full code of your program and the full error message you get.

joto avatar Aug 23 '13 21:08 joto

I reduced the code to a minimum example to show the error message. Here is the code:

// Defines
#define OSMIUM_WITH_PBF_INPUT
#define OSMIUM_WITH_XML_INPUT

// Osmium
#include <osmium.hpp>
#include <osmium/storage/byid/sparse_table.hpp>
#include <osmium/storage/byid/mmap_anon.hpp>
#include <osmium/storage/objectstore.hpp>
#include <osmium/handler/coordinates_for_ways.hpp>

typedef Osmium::Storage::ById::SparseTable<Osmium::OSM::Position> TStorageSparsetable;
typedef Osmium::Storage::ById::MmapAnon<Osmium::OSM::Position> TStorageMMap;
typedef Osmium::Handler::CoordinatesForWays<TStorageSparsetable, TStorageMMap> TCFWHandler;

int main(int argc, char* argv[])
{
    // Not used currently
    (void)argc;
    (void)argv;

    // Create storages
    TStorageSparsetable store_pos;
    TStorageMMap store_neg;

    // Select OSM file
    Osmium::OSMFile lInFile("/home/chris/test.osm");

    // Create object store to read the OSM data into
    Osmium::Storage::ObjectStore lObjectStore;
    Osmium::Input::read(lInFile, lObjectStore);

    // Construct coordinates for ways handler and feed OSM data from object store into it
    TCFWHandler lCoordinatesForWaysHandler(store_pos, store_neg);
    Osmium::OSM::Meta lMeta;
    lObjectStore.feed_to(&lCoordinatesForWaysHandler, lMeta, false); // error occurs through this code line

    google::protobuf::ShutdownProtobufLibrary();
}

The full error message is as follows:

/usr/local/include/boost/bind/bind.hpp:313: error: no match for call to '(boost::_mfi::mf1<void, Osmium::Handler::CoordinatesForWays<Osmium::Storage::ById::SparseTable<Osmium::OSM::Position>, Osmium::Storage::ById::MmapAnon<Osmium::OSM::Position> >, const boost::shared_ptr<Osmium::OSM::Way>&>) (Osmium::Handler::CoordinatesForWays<Osmium::Storage::ById::SparseTable<Osmium::OSM::Position>, Osmium::Storage::ById::MmapAnon<Osmium::OSM::Position> >*&, const boost::shared_ptr<const Osmium::OSM::Way>&)'

The bind method from boost is in objectstore.hpp at line 135 in method feed_to().

graylock avatar Aug 26 '13 07:08 graylock

Okay. The problem ist that you are trying to change the ways stored in the ObjectStore (by adding coordinates), but objects in the ObjectStore are marked as const (see objectstore.hpp:154). They have to be const, because ObjectStore uses std::set so store them and a std::set can only store const values. (I have just added a sentence to that effect in the ObjectStore documentation.)

If the CoordinatesForWays handler is the only handler you use that changes the objects, you can run it first before storing the objects. If you have more handlers modifying the objects you have to change tactics. The ObjectStore handler is pretty (memory and time) inefficient anways, so maybe it is better to avoid it. This obviously depends on what else you are doing in your application. Maybe it is okay for you to just add all the object shared_ptr's to a std::vector and read them out again later.

joto avatar Aug 26 '13 08:08 joto