×
Namespaces

Variants
Actions
(Difference between revisions)

QML Geohelper Plugin

From Nokia Developer Wiki
Jump to: navigation, search
kpakarin (Talk | contribs)
hamishwillee (Talk | contribs)
m (Text replace - "<code cpp>" to "<code cpp-qt>")
 
(16 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
[[Category:Qt]][[Category:Qt Mobility]][[Category:Qt Quick]][[Category:Symbian]]
 
[[Category:Qt]][[Category:Qt Mobility]][[Category:Qt Quick]][[Category:Symbian]]
__NOTOC__
+
{{ArticleMetaData <!-- v1.2 -->
__NOEDITSECTION__
+
|sourcecode= <!-- Link to example source code (e.g. [[Media:The Code Example ZIP.zip]]) -->
{{CodeSnippet
+
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
|id=...
+
|devices= N8, E7, C7
|platform=Symbian 3
+
|sdk= <!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Nokia Qt SDK 1.1]) -->
|devices=N8, E7, C7
+
|platform= Symbian 3
|category=...
+
|devicecompatability= <!-- Compatible devices (e.g.: All* (must have GPS) ) -->
|subcategory=...
+
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
|creationdate=29.04.2011
+
|signing= <!-- Empty or one of Self-Signed, DevCert, Manufacturer -->
|keywords=QML, Geocoding, Location, Maps
+
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 +
|keywords= QML, Geocoding, Location, Maps, Map objects, JSON stringify
 +
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 +
|translated-by= <!-- [[User:XXXX]] -->
 +
|translated-from-title= <!-- Title only -->
 +
|translated-from-id= <!-- Id of translated revision -->
 +
|review-by= <!-- After re-review: [[User:username]] -->
 +
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 +
|update-by= <!-- After significant update: [[User:username]]-->
 +
|update-timestamp= <!-- After significant update: YYYYMMDD -->
 +
|creationdate= 29.04.2011
 +
|author= [[User:Jahartik]]
 +
<!-- The following are not in current metadata -->
 +
|subcategory= Location
 
}}
 
}}
  
Line 15: Line 28:
  
  
''Delete the guidance text written in italics.''
 
  
 
==Overview==
 
==Overview==
  
Geohelper plugin to expose Qt mobility location geoservice apis to Qml environment
+
{{Abstract|Geohelper plug-in to expose Qt mobility location geoservice APIs to QML environment}}
  
Geohelper source code includes also workaround code for map control: Map object “copy” to construct the map's objects list again. This is because the objects list does not have a method to remove a single object, see method void GeoHelper::removeFromMap(QString id)
+
Geohelper source code includes also workaround to manage several map objects: Map object “copy” to construct the map's objects list again. This is because the objects list does not have a method to remove a single object, see method {{Icode|void GeoHelper::removeFromMap(QString id)}}
  
 
This snippet can be self-signed.
 
This snippet can be self-signed.
Line 27: Line 39:
 
==Preconditions==
 
==Preconditions==
  
Qt 4.7.1 or newer and Qt mobility 1.1.0 or newer installed
+
[http://qt.nokia.com/downloads Qt SDK ]4.7.1 or newer and [http://qt.nokia.com/products/qt-addons/mobility Qt mobility ]1.1.0 or newer installed
 +
 
  
 
==Pro file ==
 
==Pro file ==
  
The following capabilities are required:
+
The following capabilities and libraries are required:
  
 +
<code cpp-qt>
 
CAPABILITY:  
 
CAPABILITY:  
 
symbian:TARGET.CAPABILITY = NetworkServices Location ReadUserData WriteUserData
 
symbian:TARGET.CAPABILITY = NetworkServices Location ReadUserData WriteUserData
 +
CONFIG += mobility
 +
MOBILITY = location
 +
</code>
  
 
==Header file==
 
==Header file==
  
geohelper.h applying this macro to definitions of member functions to allow them to be invoked via the meta-object system
+
'''geohelper.h''' applying this macro to definitions of member functions to allow them to be invoked via the''' meta-object system'''
  
<code>
+
<code cpp-qt>
  
 
#ifndef GEOHELPER_H
 
#ifndef GEOHELPER_H
Line 135: Line 152:
 
geohelper source code  
 
geohelper source code  
  
<code>
+
<code cpp-qt>
 
#include "geohelper.h"
 
#include "geohelper.h"
  
Line 556: Line 573:
 
To register the C++ type in the QML system with the name GeoHelper include following code in your main.cpp file
 
To register the C++ type in the QML system with the name GeoHelper include following code in your main.cpp file
  
<code>  
+
<code cpp-qt>  
 
qmlRegisterType<GeoHelper>("GeoHelper",1,0,"GeoHelper");
 
qmlRegisterType<GeoHelper>("GeoHelper",1,0,"GeoHelper");
 
</code>  
 
</code>  
  
 
Import geohelper plugin in QML
 
Import geohelper plugin in QML
<code>  
+
<code cpp-qt>  
 
import GeoHelper 1.0
 
import GeoHelper 1.0
 
</code>  
 
</code>  
  
 
Example use QML
 
Example use QML
<code>  
+
<code cpp-qt>  
 
GeoHelper {  
 
GeoHelper {  
 
id: geohelper…
 
id: geohelper…
 
----
 
----
mapid.center = mapid.toCoordinate(Qt.point(x, y))  
+
Geohelper developer APIs
geohelper.findAddress(mapid.center.latitude, mapid.center.longitude)
+
 
 +
Constructor and destructor
 +
GeoHelper(QObject *parent = 0);
 +
~GeoHelper();
 +
 
 +
Public slots:
 +
void findRoute(double fromLatitude, double fromLongitude, double toLatitude, double toLongitude);
 +
void findAddress(double latitude, double longitude);
 +
void findCoordinates(QString street, QString city, QString country = QString("FINLAND"));
 +
void clearMap();
 +
void removeFromMap(QString id);
 +
void drawPolyline(QString id, QString coordinateArr);
 +
void drawImage(QString id, double latitude, double longitude, QString imagepath, int xOffset, int yOffset);
 +
void drawText(QString id, double latitude, double longitude, QString text);
 +
void findObjectsInCoordinates(double latitude, double longitude);
 +
 
 +
Public signals
 +
void searchError(const QString &error);
 +
void routingError(const QString &error);
 +
void searchReply(const QString &reply);
 +
void routingReply(const QString &reply);
 +
void geomapobjectSelected(QString id, bool selected);
 +
void debugMsg(const QString &reply);
 +
 
 
</code>
 
</code>

Latest revision as of 04:18, 11 October 2012

Article Metadata
Tested with
Devices(s): N8, E7, C7
Compatibility
Platform(s): Symbian 3
Symbian
Article
Keywords: QML, Geocoding, Location, Maps, Map objects, JSON stringify
Created: jahartik (29 Apr 2011)
Last edited: hamishwillee (11 Oct 2012)



Contents

[edit] Overview

Geohelper plug-in to expose Qt mobility location geoservice APIs to QML environment

Geohelper source code includes also workaround to manage several map objects: Map object “copy” to construct the map's objects list again. This is because the objects list does not have a method to remove a single object, see method void GeoHelper::removeFromMap(QString id)

This snippet can be self-signed.

[edit] Preconditions

Qt SDK 4.7.1 or newer and Qt mobility 1.1.0 or newer installed


[edit] Pro file

The following capabilities and libraries are required:

CAPABILITY: 
symbian:TARGET.CAPABILITY = NetworkServices Location ReadUserData WriteUserData
CONFIG += mobility
MOBILITY = location

[edit] Header file

geohelper.h applying this macro to definitions of member functions to allow them to be invoked via the meta-object system

#ifndef GEOHELPER_H
#define GEOHELPER_H
 
#include <QObject>
#include <QMap>
 
#include <QGeoServiceProvider>
#include <QGeoMappingManager>
#include <QGeoSearchManager>
#include <QGeoRoutingManager>
 
#include <QDeclarativeEngine>
#include <QGeoRouteReply>
#include <QGeoRouteRequest>
 
#include <QGeoCoordinate>
 
#include <QDeclarativeItem>
#include <QGeoMapPolylineObject>
#include <QGeoMapPixmapObject>
#include <QGeoMapTextObject>
 
 
QTM_USE_NAMESPACE
 
 
class GeoHelper : public QObject
{
Q_OBJECT
Q_PROPERTY(QDeclarativeItem* map READ map WRITE setMap)
public:
explicit GeoHelper(QObject *parent = 0);
~GeoHelper();
 
QDeclarativeItem *map() const {return mapitem; }
void setMap(QDeclarativeItem *map) { mapitem = map; listRef = QDeclarativeListReference(mapitem, "objects");};
 
Q_INVOKABLE void findRoute(double fromLatitude, double fromLongitude, double toLatitude, double toLongitude);
Q_INVOKABLE void findAddress(double latitude, double longitude);
Q_INVOKABLE void findCoordinates(QString street, QString city, QString country = QString("FINLAND"));
Q_INVOKABLE void clearMap();
Q_INVOKABLE void removeFromMap(QString id);
Q_INVOKABLE void drawPolyline(QString id, QString coordinateArr);
Q_INVOKABLE void drawImage(QString id, double latitude, double longitude, QString imagepath, int xOffset, int yOffset);
Q_INVOKABLE void drawText(QString id, double latitude, double longitude, QString text);
Q_INVOKABLE void findObjectsInCoordinates(double latitude, double longitude);
 
 
signals:
void searchError(const QString &error);
void routingError(const QString &error);
 
void searchReply(const QString &reply);
void routingReply(const QString &reply);
 
void geomapobjectSelected(QString id, bool selected);
 
void debugMsg(const QString &reply);
 
 
private slots:
void searchErrorSlot(QGeoSearchReply *reply, QGeoSearchReply::Error error, QString errorString = QString());
void searchFinishedSlot(QGeoSearchReply *reply);
 
void routingErrorSlot(QGeoRouteReply *reply, QGeoRouteReply::Error error, QString errorString);
void routingFinishedSlot(QGeoRouteReply * reply);
 
 
 
private:
 
QGeoServiceProvider* provider;
QGeoMappingManager* mappingManager;
QGeoSearchManager* searchManager;
QGeoRoutingManager* routingManager;
QDeclarativeContext* context;
QDeclarativeItem* mapitem;
 
 
QMap<QString, QGeoMapObject *> mapobjects;
QDeclarativeListReference listRef;
 
};
 
#endif // GEOHELPER_H


[edit] Source file

geohelper source code

#include "geohelper.h"
 
#include <QScriptEngine>
#include <QScriptValue>
#include <QScriptValueIterator>
 
#include <QDeclarativeListReference>
#include <QGeoMapRouteObject>
 
 
GeoHelper::GeoHelper(QObject *parent) :
QObject(parent)
{
provider = new QGeoServiceProvider("nokia");
mappingManager = provider->mappingManager();
searchManager = provider->searchManager();
routingManager = provider->routingManager();
mapitem = NULL;
 
QObject::connect(searchManager, SIGNAL(error(QGeoSearchReply *, QGeoSearchReply::Error, QString)), this, SLOT(searchErrorSlot(QGeoSearchReply *, QGeoSearchReply::Error, QString)));
QObject::connect(searchManager, SIGNAL(finished(QGeoSearchReply*)), this, SLOT(searchFinishedSlot(QGeoSearchReply*)));
 
QObject::connect(routingManager, SIGNAL(error(QGeoRouteReply*, QGeoRouteReply::Error, QString)), this, SLOT(routingErrorSlot(QGeoRouteReply*, QGeoRouteReply::Error, QString)));
QObject::connect(routingManager, SIGNAL(finished(QGeoRouteReply*)), this, SLOT(routingFinishedSlot(QGeoRouteReply*)));
}
 
GeoHelper::~GeoHelper()
{
clearMap();
 
if (provider)
{
delete provider;
provider = NULL;
}
}
 
 
void GeoHelper::searchErrorSlot(QGeoSearchReply *reply, QGeoSearchReply::Error error, QString errorString)
{
emit searchError(errorString);
}
 
void GeoHelper::searchFinishedSlot(QGeoSearchReply *reply)
{
if (reply->error() == QGeoSearchReply::NoError)
{
QScriptEngine scriptEngine;
QScriptValue replyObject = scriptEngine.newArray();
 
QList<QGeoPlace> places = reply->places();
for (int i = 0; i < places.count(); i++)
{
QScriptValue placeObject = scriptEngine.newObject();
 
QScriptValue coordinateObject = scriptEngine.newObject();
QGeoCoordinate coordinate = places[i].coordinate();
coordinateObject.setProperty("latitude", QScriptValue(coordinate.latitude()));
coordinateObject.setProperty("longitude", QScriptValue(coordinate.longitude()));
placeObject.setProperty("coordinate", coordinateObject);
 
QScriptValue addressObject = scriptEngine.newObject();
QGeoAddress address = places[i].address();
 
if (!address.isEmpty())
{
addressObject.setProperty("country", address.country());
addressObject.setProperty("countryCode", address.countryCode());
addressObject.setProperty("state", address.state());
addressObject.setProperty("county", address.county());
addressObject.setProperty("city", address.city());
addressObject.setProperty("district", address.district());
addressObject.setProperty("street", address.street());
addressObject.setProperty("postcode", address.postcode());
 
}
 
placeObject.setProperty("address", addressObject);
replyObject.setProperty(i, placeObject);
}
 
 
QScriptValue fun = scriptEngine.evaluate("(function(a) { return JSON.stringify(a); })");
QScriptValueList args;
args << replyObject;
QScriptValue result = fun.call(QScriptValue(), args);
 
emit searchReply(result.toString());
}
 
 
}
 
void GeoHelper::routingErrorSlot(QGeoRouteReply *reply, QGeoRouteReply::Error error, QString errorString)
{
emit routingError(errorString);
}
 
 
void GeoHelper::routingFinishedSlot(QGeoRouteReply * reply)
{
 
if (reply->error() == QGeoRouteReply::NoError)
{
QScriptEngine scriptEngine;
QScriptValue replyObject = scriptEngine.newArray();
 
QList<QGeoCoordinate> waypoints = reply->request().waypoints();
double lat1 = 0;
double lon1 = 0;
double lat2 = 0;
double lon2 = 0;
 
if (waypoints.count() > 0)
{
/*
QString msg = QString("lat %1, lon %2 => lat %3, lon %4").
arg(waypoints.at(0).latitude()).arg(waypoints.at(0).longitude()).
arg(waypoints.at((waypoints.count()-1)).latitude()).arg(waypoints.at((waypoints.count()-1)).longitude());
emit routingError(msg);
*/

lat1 = waypoints.at(0).latitude();
lon1 = waypoints.at(0).longitude();
lat2 = waypoints.at((waypoints.count()-1)).latitude();
lon2 = waypoints.at((waypoints.count()-1)).longitude();
 
}
 
 
for (int i = 0; i < reply->routes().size(); ++i)
{
QScriptValue routeObject = scriptEngine.newObject();
QGeoRoute route = reply->routes().at(i);
 
routeObject.setProperty("distance", QScriptValue(route.distance()));
routeObject.setProperty("travelTime", QScriptValue(route.travelTime()));
routeObject.setProperty("lat1", QScriptValue(lat1));
routeObject.setProperty("lon1", QScriptValue(lon1));
routeObject.setProperty("lat2", QScriptValue(lat2));
routeObject.setProperty("lon2", QScriptValue(lon2));
 
 
QScriptValue pathObject = scriptEngine.newArray();
QList<QGeoCoordinate> path = route.path();
for (int p = 0; p < path.length(); p++)
{
QScriptValue coordinateObject = scriptEngine.newObject();
coordinateObject.setProperty("latitude", QScriptValue(path[p].latitude()));
coordinateObject.setProperty("longitude", QScriptValue(path[p].longitude()));
pathObject.setProperty(p, coordinateObject);
 
}
 
routeObject.setProperty("path", pathObject);
 
replyObject.setProperty(i, routeObject);
 
}
 
QScriptValue fun = scriptEngine.evaluate("(function(a) { return JSON.stringify(a); })");
QScriptValueList args;
args << replyObject;
QScriptValue result = fun.call(QScriptValue(), args);
 
emit routingReply(result.toString());
 
}
}
 
// ------------- Q_INVOKABLE METHODS -------
 
void GeoHelper::removeFromMap(QString id)
{
if (mapobjects.contains(id))
{
 
QGeoMapObject *obj = mapobjects.take(id);
if (obj != NULL)
{
delete obj;
obj = NULL;
}
 
// Now we have to construct the map's objects list again
// this is because the objects list does not have a method
// to remove a single object.
for (int i = 0; i < listRef.count(); i++)
listRef.at(i)->deleteLater();
 
listRef.clear();
 
QStringList keys = mapobjects.keys();
foreach (QString id, keys)
{
emit debugMsg("lisaa uudestaan " + id);
QGeoMapObject *obj = mapobjects.value(id);
if (obj != NULL)
{
if (obj->type() == QGeoMapObject::PolylineType)
{
QGeoMapPolylineObject *newobj = new QGeoMapPolylineObject;
newobj->setPath(((QGeoMapPolylineObject *)obj)->path());
newobj->setPen(QPen(QBrush(Qt::blue), 4));
newobj->setObjectName(obj->objectName());
 
listRef.append(newobj);
}
else if (obj->type() == QGeoMapObject::PixmapType)
{
QGeoMapPixmapObject *newobj = new QGeoMapPixmapObject;
newobj->setCoordinate(((QGeoMapPixmapObject *)obj)->coordinate());
newobj->setPixmap(((QGeoMapPixmapObject *)obj)->pixmap());
newobj->setOffset(QPoint(-10,-34));
newobj->setObjectName(obj->objectName());
 
listRef.append(newobj);
}
}
}
}
}
 
void GeoHelper::clearMap()
{
 
QStringList keys = mapobjects.keys();
foreach (QString id, keys)
{
QGeoMapObject *obj = mapobjects.take(id);
if (obj != NULL)
{
delete obj;
obj = NULL;
}
}
 
mapobjects.clear();
 
for (int i = 0; i < listRef.count(); i++)
listRef.at(i)->deleteLater();
 
listRef.clear();
}
 
void GeoHelper::drawPolyline(QString id, QString coordinateArr)
{
/*
[
{"latitude":61.4735985,"longitude":23.7550697},
{"latitude":61.4735985,"longitude":23.7550697}
]
 
*/

 
 
if (mapitem != NULL)
{
removeFromMap(id);
 
QScriptValue sc;
QScriptEngine engine;
sc = engine.evaluate("(" + QString(coordinateArr) + ")");
 
if (sc.isArray())
{
 
QScriptValueIterator it(sc);
QList<QGeoCoordinate> coordinates;
 
while (it.hasNext())
{
it.next();
if (it.value().property("latitude").toString() != "" && it.value().property("longitude").toString() != "")
{
coordinates << QGeoCoordinate(it.value().property("latitude").toNumber(),it.value().property("longitude").toNumber());
}
}
 
QGeoMapPolylineObject *obj = new QGeoMapPolylineObject;
obj->setPath(coordinates);
obj->setPen(QPen(QBrush(Qt::blue), 4));
obj->setObjectName(id);
 
listRef.append(obj);
 
// keep a copy to construct the map objects list again
QGeoMapPolylineObject *copyobj = new QGeoMapPolylineObject;
copyobj->setPath(coordinates);
copyobj->setPen(QPen(QBrush(Qt::blue), 4));
copyobj->setObjectName(id);
mapobjects.insert(id,copyobj);
 
 
 
}
}
}
 
void GeoHelper::drawImage(QString id, double latitude, double longitude, QString imagepath, int xOffset, int yOffset)
{
 
if (mapitem != NULL)
{
 
//emit debugMsg(QString("offset: %1, %2").arg(xOffset).arg(yOffset));
 
removeFromMap(id);
QGeoMapPixmapObject *obj = new QGeoMapPixmapObject;
obj->setCoordinate(QGeoCoordinate(latitude,longitude));
obj->setPixmap(imagepath);
obj->setOffset(QPoint(xOffset,yOffset));
//obj->setOffset(QPoint(-10,-34));
obj->setObjectName(id);
 
listRef.append(obj);
 
// keep a copy to construct the map objects list again
QGeoMapPixmapObject *copyobj = new QGeoMapPixmapObject;
copyobj->setCoordinate(QGeoCoordinate(latitude,longitude));
copyobj->setPixmap(imagepath);
copyobj->setOffset(QPoint(xOffset,yOffset));
//copyobj->setOffset(QPoint(-10,-34));
copyobj->setObjectName(id);
mapobjects.insert(id,copyobj);
 
 
}
 
}
 
 
 
QBrush usebrush(Qt::darkRed);
QPen usepen(usebrush,1);
QFont usefont("Terminal", 12);
 
 
 
void GeoHelper::drawText(QString id, double latitude, double longitude, QString text)
{
 
if (mapitem != NULL)
{
 
//emit debugMsg(QString("offset: %1, %2").arg(xOffset).arg(yOffset));
 
removeFromMap(id);
QGeoMapTextObject *obj = new QGeoMapTextObject;
obj->setCoordinate(QGeoCoordinate(latitude,longitude));
obj->setText(text);
obj->setFont(usefont);
obj->setOffset(QPoint(20,-10));
obj->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
obj->setBrush(usebrush);
obj->setPen(usepen);
obj->setObjectName(id);
 
listRef.append(obj);
 
// keep a copy to construct the map objects list again
QGeoMapTextObject *copyobj = new QGeoMapTextObject;
copyobj->setCoordinate(QGeoCoordinate(latitude,longitude));
copyobj->setText(text);
copyobj->setFont(usefont);
copyobj->setOffset(QPoint(20,-10));
copyobj->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
copyobj->setBrush(usebrush);
copyobj->setPen(usepen);
copyobj->setObjectName(id);
mapobjects.insert(id,copyobj);
 
}
 
}
 
void GeoHelper::findObjectsInCoordinates(double latitude, double longitude)
{
QGeoCoordinate coord(latitude, longitude);
 
for (int i = 0; i < listRef.count(); i++)
{
if ( ((QGeoMapObject *)listRef.at(i))->contains(coord))
{
emit geomapobjectSelected(listRef.at(i)->objectName(), true);
}
}
 
}
 
void GeoHelper::findRoute(double fromLatitude, double fromLongitude, double toLatitude, double toLongitude)
{
QGeoRouteRequest *geoRouteRequest = new QGeoRouteRequest(QGeoCoordinate(fromLatitude, fromLongitude), QGeoCoordinate(toLatitude, toLongitude));
routingManager->calculateRoute(*geoRouteRequest);
}
 
void GeoHelper::findAddress(double latitude, double longitude)
{
QGeoCoordinate location(latitude,longitude);
searchManager->reverseGeocode(location);
}
 
void GeoHelper::findCoordinates(QString street, QString city, QString country)
{
/*
NOTE! This geocode method is not capable to handle the number of the street address.
But the use of the plain search alternative seems to work.
QGeoAddress address;
address.setStreet(street);
address.setCity(city);
address.setCountry(country);
searchManager->geocode(address);
*/

QString str = QString("%1,%2,%3").arg(street).arg(city).arg(country);
searchManager->search(str, QGeoSearchManager::SearchGeocode);
}

To register the C++ type in the QML system with the name GeoHelper include following code in your main.cpp file

qmlRegisterType<GeoHelper>("GeoHelper",1,0,"GeoHelper");

Import geohelper plugin in QML

import GeoHelper 1.0

Example use QML

GeoHelper { 
id: geohelper…
----
Geohelper developer APIs
 
Constructor and destructor
GeoHelper(QObject *parent = 0);
~GeoHelper();
 
Public slots:
void findRoute(double fromLatitude, double fromLongitude, double toLatitude, double toLongitude);
void findAddress(double latitude, double longitude);
void findCoordinates(QString street, QString city, QString country = QString("FINLAND"));
void clearMap();
void removeFromMap(QString id);
void drawPolyline(QString id, QString coordinateArr);
void drawImage(QString id, double latitude, double longitude, QString imagepath, int xOffset, int yOffset);
void drawText(QString id, double latitude, double longitude, QString text);
void findObjectsInCoordinates(double latitude, double longitude);
 
Public signals
void searchError(const QString &error);
void routingError(const QString &error);
void searchReply(const QString &reply);
void routingReply(const QString &reply);
void geomapobjectSelected(QString id, bool selected);
void debugMsg(const QString &reply);
This page was last modified on 11 October 2012, at 04:18.
147 page views in the last 30 days.
×