Results 1 to 9 of 9

Thread: creating custom mapping plugin for QtLocation

  1. #1
    Join Date
    Nov 2010
    Posts
    9
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default creating custom mapping plugin for QtLocation

    Hello,
    I was playing with new QtLocation API for mapping and I liked it. Now I'd like to create my own map, for starters based on OpenStreetMap tiles.

    As documentation instructs, I subclassed QGeoTiledMappingManagerEngine, QGeoTiledMapReply and QGeoServiceProviderFactory. As far as I can see, documentation leaves me in middle of nowhere - those classes are useless alone. Ideally, QGeoServiceProvider::availableServiceProviders(); should return names ("nokia", "myosm"), then I could call serviceProvider = new QGeoServiceProvider("myosm"); but only "nokia" is avilable.

    What should I do next?
    I expect I should somehow use TEMPLATE = lib, CONFIG += plugin, PLUGIN_TYPE=geoservices (found those in nokia plugin source code), Q_EXPORT_PLUGIN2(mlosm, OsmMapServiceProviderFactory) (for some reason I DIDN'T find this) and maybe some TARTGET/DESTDIR/$$qtLibraryTarget magic, but so far I had no luck.
    I have none experience in writing plugins, and all examples I find show how to write some types of plugins (styles, image formats...), but I can't find equivalent type for mapping.
    Plese help me.

    EDIT:
    forgot to mention: Currently I try to work it out on desktop qt and simulator, later I'll add maemo target. I have installed QtSDK, separate desktop Qt-4.7.4 and QtMobility-1.2 for that desktop qt. mapsdemo (from QtMobilityExamples) works flawlessly with "nokia" plugin both on desktop and simulator.
    Last edited by mateuszzz88; 8th September 2011 at 10:32.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: creating custom mapping plugin for QtLocation

    The classes are not useless alone. They are interfaces you need to implement to create a new data provider. For instance you need to subclass QGeoServiceProviderFactory and reimplement providerName() to return "myosm" if that's what you want your provider to be called. You should also reimplement the remaining methods that will return instances of subclasses of the interfaces provided there that perform the actual tasks.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Nov 2010
    Posts
    9
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: creating custom mapping plugin for QtLocation

    Quote Originally Posted by wysota View Post
    The classes are not useless alone.
    By no means I meant they are not needed for the task. It's just that I have subclasses of QGeoServiceProviderFactory and QGeoMappingManagerEngine but to display map I need QGeoMappingManager and I can't find bridge between those two.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: creating custom mapping plugin for QtLocation

    You return the engine that is then used by QGeoMappingManager to perform its tasks. You don't create QGeoMappingManager yourself. You only implement interfaces that are then used by existing classes to fetch required data and do the tasks they are designed to do. It's exactly like with all other kinds of Qt plugins, for instance to provide a plugin for handling image formats you don't return your own "QImageReader" instances but instead you implement QImageIOHandler interface which QImageReader uses to do its job.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Nov 2010
    Posts
    9
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: creating custom mapping plugin for QtLocation

    Ok, I read some more about writing plugins and source code of nokia plugin. So far I think I understand what must be done, but it doesn't work. Here's what I have:

    I complied and installed qtmobility with ./configure -prefix /mybin/qtmobility12_custom_forqt474 -qmake-exec /mybin/qt474_custom/bin/qmake (...)

    Currently I try to make it work on desktop, so I only use qt from above version, located in /mybin/qt474_custom . I'll worry about other versions when at least this one works.


    Qt Code:
    1. # OsmPlugin.pro
    2.  
    3. QT += core gui network
    4.  
    5. TARGET = $$qtLibraryTarget(qtgeoservices_mlosm)
    6. TEMPLATE = lib
    7. CONFIG += plugin mobility
    8. MOBILITY = location
    9. PLUGIN_TYPE=geoservices
    10.  
    11. DESTDIR = $$[QT_INSTALL_PLUGINS]/geoservices
    12.  
    13. SOURCES += \
    14. osmtilereply.cpp \
    15. osmmapserviceproviderfactory.cpp \
    16. osmmappingmanagerengine.cpp
    17.  
    18. HEADERS += \
    19. osmtilereply.h \
    20. osmmapserviceproviderfactory.h \
    21. osmmappingmanagerengine.h
    22.  
    23. # To use my suplied version of qtmobility for desktop
    24. INCLUDEPATH +=/mybin/qtmobility12_custom_forqt474/include/QtLocation \
    25. /mybin/qtmobility12_custom_forqt474/include/QtMobility
    26. LIBS += -L/mybin/qtmobility12_custom_forqt474/lib -lQtLocation
    27.  
    28. symbian {
    29. # Load predefined include paths (e.g. QT_PLUGINS_BASE_DIR) to be used in the pro-files
    30. load(data_caging_paths)
    31. MMP_RULES += EXPORTUNFROZEN
    32. TARGET.UID3 = 0xE7FBA200
    33. TARGET.CAPABILITY =
    34. TARGET.EPOCALLOWDLLDATA = 1
    35. pluginDeploy.sources = OsmPlugin.dll
    36. pluginDeploy.path = $$QT_PLUGINS_BASE_DIR/OsmPlugin
    37. DEPLOYMENT += pluginDeploy
    38. }
    39.  
    40. unix:!symbian {
    41. maemo5 {
    42. target.path = /opt/usr/lib
    43. } else {
    44. target.path = /usr/lib
    45. }
    46. INSTALLS += target
    47. }
    48.  
    49. OTHER_FILES += \
    50. qtc_packaging/debian_fremantle/rules \
    51. qtc_packaging/debian_fremantle/README \
    52. qtc_packaging/debian_fremantle/copyright \
    53. qtc_packaging/debian_fremantle/control \
    54. qtc_packaging/debian_fremantle/compat \
    55. qtc_packaging/debian_fremantle/changelog
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #header for my plugin class
    2.  
    3. #ifndef OSMMAPSERVICEPROVIDERFACTORY_H
    4. #define OSMMAPSERVICEPROVIDERFACTORY_H
    5.  
    6. #include <QGeoServiceProviderFactory>
    7. #include "osmmappingmanagerengine.h"
    8. using namespace QtMobility;
    9.  
    10. class OsmMapServiceProviderFactory : public QObject, public QGeoServiceProviderFactory
    11. {
    12. //QObject is needed for Q_EXPORT_PLUGIN2 - it works only with QObject derived classes,
    13. //and QGeoServiceProviderFactory is not one of them.
    14. Q_OBJECT
    15. public:
    16. explicit OsmMapServiceProviderFactory();
    17. QString providerName() const {return "mlosm";}
    18. int providerVersion() const {return 1; }
    19. QGeoMappingManagerEngine* createMappingManagerEngine(
    20. const QMap<QString, QVariant> & parameters,
    21. QGeoServiceProvider::Error * error,
    22. QString * errorString ) const;
    23.  
    24. };
    25.  
    26. #endif // OSMMAPSERVICEPROVIDERFACTORY_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #implementation for my plugin class
    2.  
    3. #include "osmmapserviceproviderfactory.h"
    4.  
    5. OsmMapServiceProviderFactory::OsmMapServiceProviderFactory()
    6. {}
    7.  
    8. QGeoMappingManagerEngine *
    9. OsmMapServiceProviderFactory::createMappingManagerEngine(
    10. const QMap<QString, QVariant> &parameters,
    11. QGeoServiceProvider::Error *error,
    12. QString *errorString) const
    13. {
    14. return new OsmMappingManagerEngine(parameters,0);
    15. }
    16.  
    17. Q_EXPORT_PLUGIN2(qtgeoservices_mlosm, OsmMapServiceProviderFactory)
    To copy to clipboard, switch view to plain text mode 

    When building a project, the file /mybin/qt474_custom/plugins/geoservices/libqtgeoservices_mlosm.so is created, as expected. To be on save side, I copy it to /mybin/qtmobility12_custom_forqt474/plugins/geoservices/ where libqtgeoservices_nokia.so (default nokia plugin) was put after I compiled and installed qtmobility.

    In different project
    Qt Code:
    1. QApplication a(argc, argv);
    2. qDebug()<<a.libraryPaths();
    To copy to clipboard, switch view to plain text mode 
    shows:
    ("/mybin/qt474_custom/plugins", "/home/pro/tests/mapsdemo-build-desktop-Qt_4_7_4__qt474_custom__Release", "/usr/lib/kde4/plugins")
    so the first path contains my plugin file, but
    Qt Code:
    1. QList<QString> providers = QGeoServiceProvider::availableServiceProviders();
    2. qDebug()<<providers;
    To copy to clipboard, switch view to plain text mode 
    shows only ("nokia")
    I expected to see ("nokia", "mlosm") and later use
    QGeoServiceProvider *serviceProvider2 = new QGeoServiceProvider("mlosm");

    What am I doing wrong? As I said earlier, this is my first attempt at writing qt plugin.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: creating custom mapping plugin for QtLocation

    Did you implement all the required methods for the factory class and for the engine class?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Nov 2010
    Posts
    9
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: creating custom mapping plugin for QtLocation

    Quote Originally Posted by wysota View Post
    Did you implement all the required methods for the factory class and for the engine class?
    I think so.
    For factory I implemented name and version functions and createMappingManagerEngine(...) all those shown above. I believe this is bare minimum, but should be sufficient. Beside that I have subclasses of QGeoTiledMappingManagerEngine and QGeoTiledMapReply:

    Qt Code:
    1. class OsmMappingManagerEngine : public QGeoTiledMappingManagerEngine
    2. {
    3. Q_OBJECT
    4. QNetworkAccessManager *iNet;
    5. public:
    6. explicit OsmMappingManagerEngine(const QMap<QString, QVariant> & parameters, QObject *parent = 0);
    7. QGeoTiledMapReply* getTileImage(const QGeoTiledMapRequest& request);
    8.  
    9. };
    10. // implementation:
    11.  
    12. OsmMappingManagerEngine::OsmMappingManagerEngine(const QMap<QString, QVariant> & parameters, QObject *parent) :
    13. QGeoTiledMappingManagerEngine(parameters, parent),
    14. iNet(new QNetworkAccessManager(this))
    15. {
    16. setTileSize(QSize(256,256));
    17. QNetworkDiskCache *cache = new QNetworkDiskCache(this);
    18. cache->setCacheDirectory("cacheDir_tmpdel");
    19. iNet->setCache(cache);
    20. }
    21.  
    22. QtMobility::QGeoTiledMapReply * OsmMappingManagerEngine::getTileImage(const QtMobility::QGeoTiledMapRequest &request)
    23. {
    24. QString urlSchema = "http://tile.openstreetmap.org/%1/%2/%3.png";
    25. QString urlstr = urlSchema.arg(request.zoomLevel())
    26. .arg(request.column())
    27. .arg(request.row());
    28. QNetworkRequest req(urlstr);
    29. req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
    30. QNetworkReply *repl = iNet->get(req);
    31. return new OsmTileReply(request, repl);
    32. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. class OsmTileReply : public QGeoTiledMapReply
    2. {
    3. Q_OBJECT
    4. QNetworkReply *iNetReply;
    5. public:
    6. explicit OsmTileReply(const QGeoTiledMapRequest &req, QNetworkReply *netRep);
    7. QByteArray mapImageData () const;
    8. QString mapImageFormat () const {return "png";}
    9. };
    10.  
    11. //implementation:
    12. OsmTileReply::OsmTileReply(const QGeoTiledMapRequest &req, QNetworkReply *netRep) :
    13. QGeoTiledMapReply(req, netRep),
    14. iNetReply(netRep)
    15. {
    16. connect(iNetReply,SIGNAL(finished()),this,SIGNAL(finished()));
    17. }
    18.  
    19. QByteArray OsmTileReply::mapImageData() const
    20. {
    21. if (iNetReply->error()) {
    22. qDebug()<<"OsmTileReply::mapImageData(): error in network reply: "
    23. <<iNetReply->errorString();
    24. } else if (!iNetReply->isFinished()) {
    25. qDebug()<<"OsmTileReply::mapImageData(): reply not yet finished?!";
    26. } else {
    27. ret = iNetReply->readAll();
    28. }
    29. return ret;
    30. }
    To copy to clipboard, switch view to plain text mode 

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: creating custom mapping plugin for QtLocation

    Check if any of your methods are ever called (you can use qDebug() for that). Also remove your DESTDIR directive from the project file. Unless you are compiling as root, it will fail. Also make sure your plugin is linked against the same version of mobility as your test application is using (you can do that using ldd).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. The following user says thank you to wysota for this useful post:

    mateuszzz88 (8th September 2011)

  10. #9
    Join Date
    Nov 2010
    Posts
    9
    Thanks
    1
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default [SOLVED] creating custom mapping plugin for QtLocation

    I thought it might be the problem with complicated setup of my dev platform, so I simplified it a little. Now I use almost original QtSDK, only I installed QtMobility libraries on top of QtSdk's desktop qt library. I no longer have separate qt library in /mybin/qt474_custom nor separate mobility install in qtgeoservices_nokia. It is much simpler now and I no longer use additional LIB+= in .pro file. Sample app with nokia map works, so probably I didn't break anything.
    Now as for your advices:
    Quote Originally Posted by wysota View Post
    Check if any of your methods are ever called (you can use qDebug() for that).
    When I start test app, Factory's constructor IS called - it's better than I expected.

    Quote Originally Posted by wysota View Post
    Also remove your DESTDIR directive from the project file. Unless you are compiling as root, it will fail.
    No, I have whole QtSdk installed in folder that is accessible by normal user, /mybin . I know it's unconventional, but I like short absolute paths and I like to install programs without giving any part of them at any time root privileges. Furthermore, DESTDIR does for me copying the resulting plugin to accesible directory.

    Quote Originally Posted by wysota View Post
    Also make sure your plugin is linked against the same version of mobility as your test application is using (you can do that using ldd).
    Outputs for ldd for test app and plugin are line by line identical. I mean the paths, values in brackets differ.

    I tried to solve problem from other angle. Instead of making the most basic implementation possible from scratch, I copied the whole nokia plugin to devel directory, changed it's name (in Q_EXPORT_PLUGIN2, TARGET and QGeoServiceProviderFactoryNokia:roviderName() ) and build it. It compiled and test app was aware of new plugin. Therefore I think the problem is in my source code.

    Wysota, thank you very much for your input, it is really appreciated. I am going offline for 3-4 days, but if you have any other advices, I'll try them as soon as I come back. Otherwise I'll try to strip the copied nokia plugin function by function untill it is bare working minimum and build my plugin from there. It'll take time, but should eventually work.
    Again: thank you for your time, and if You have any other ideas, please share them.


    Added after 20 minutes:


    SOLVED!
    comparing nokia's and my plugin, I found I was missing Q_INTERFACES(QtMobility::QGeoServiceProviderFactor y) in class definition. It sucks to be newbie... Plugin doesn't work properly, but is visible and loadable.
    Thank You Wysota for your input!
    Last edited by mateuszzz88; 8th September 2011 at 23:44. Reason: added [SOLVED] to title

Similar Threads

  1. Creating custom plugin
    By T4ng10r in forum Qt Programming
    Replies: 9
    Last Post: 17th August 2012, 23:37
  2. Replies: 4
    Last Post: 22nd May 2011, 17:26
  3. creating designer plugin
    By GrahamLabdon in forum Newbie
    Replies: 3
    Last Post: 21st March 2011, 11:58
  4. QtLocation and QtEmbedded
    By kaikai24 in forum Qt for Embedded and Mobile
    Replies: 0
    Last Post: 29th September 2009, 11:58
  5. creating table plugin
    By mgurbuz in forum Qt Programming
    Replies: 3
    Last Post: 28th April 2006, 13:50

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.