Qt fournit un ensemble de ressources (classes C++ et composants QML) pour la géolocalisation et l’affichage de cartes.
L’API de positionnement Qt est disponible pour Android.
Il faudra ajouter le module dans le fichier de projet .pro :
QT += positioning
import QtPositioning 5.6
#include <QGeoCoordinate>
Liens :
Exemples :
On dispose d’un type coordonnées qui contient les données suivantes :
Il est aussi possible de créer une coordonnée :
property variant coordonneeAvignon: QtPositioning.coordinate(43.95, 4.8167) // Avignon
On dispose aussi d’un type position contenant donc la coordonnée mais aussi la vitesse, l’horodatage, … et la validation de ces information.
Pour récupérer le positionnement, on utilisera un PositionSource qui fournit des informations sur la position actuelle de la machine.
Exemple :
PositionSource {
id: positionSource
updateInterval: 1000 // mise à jour de la position en ms
active: true
onPositionChanged: {
var coord = positionSource.position.coordinate;
// Les données
console.log("Horodatage :", positionSource.position.timestamp);
console.log("Coordonnées :", coord.longitude, coord.latitude, coord.isValid);
console.log("Altitude :", coord.altitude, positionSource.position.altitudeValid);
console.log("Direction :", positionSource.position.direction, positionSource.position.directionValid);
console.log("Vitesse :", positionSource.position.speed, positionSource.position.speedValid);
// Calcul
console.log("Distance (Avignon) :", coord.distanceTo(QtPositioning.coordinate(43.95, 4.8167)));
}
}
Code source : qt-android-map.zip
TODO
L’API de localisation Qt est disponible pour Android.
Il faudra ajouter le module dans le fichier de projet .pro :
QT += location
import QtLocation 5.6
#include <QGeoRoute>
Liens :
L’affichage d’une carte est effectué à l’aide du type QML Map. Le type Map prend en charge les interactions de l’utilisateur via le type QML MapGestureArea. Pour accéder aux données cartographiques qui seront affichées dans un objet Map, QML fournit un Plugin de service.
Exemple :
Window {
id: window
width: 512
height: 512
visible: true
Plugin {
id: mapPlugin
locales: "fr_FR"
name: "osm" // OpenStreetMap
PluginParameter { name: "osm.geocoding.host"; value: "https://nominatim.openstreetmap.org" }
}
Map {
plugin: mapPlugin
center: QtPositioning.coordinate(43.95, 4.8167) // Avignon
zoomLevel: 14
}
}
Les cartes peuvent également contenir des objets de superposition qui sont utilisés pour afficher des informations. Il existe un ensemble d’objets de superposition prédéfinis de base : MapCircle, MapRectangle, MapPolygon, MapPolyline et MapQuickItem.
Code source : qt-android-map.zip
TODO
Le géocodage consiste à associer des coordonnées géographiques (longitude/latitude) à une adresse postale. Qt fournit le type QML GeocodeModel pour rechercher ces information géographiques. Il permettra de connaître l’adresse postale complète à partir de ses coordonnées géographiques (longitude/latitude). Le géocodage inverse est aussi possible grâce à GeocodeModel
.
Le signal onLocationsChanged
indiquera une nouvelle position que l’on pourra récupérer avec la méthode get()
. On disposera des informations de géolocalisation (latitude/longitude) et de l’adresse.
Button {
onClicked: {
// Test GeocodeModel
geocodage.query = "République,Avignon,France"
geocodage.update()
}
}
GeocodeModel {
id: geocodage
plugin: mapPlugin
onLocationsChanged: {
if(error)
console.log("Erreur GeocodeModel : " + error + " - " + errorString)
if (count>=1)
{
console.log("Adresse : " + get(0).address.text + "\n" + get(0).coordinate)
}
}
}
Le type QML RouteModel est utilisé pour extraire des itinéraires géographiques d’un fournisseur (cf. Plugin
). Les itinéraires incluent des données sur les itinéraires entre deux points, des itinéraires avec plusieurs points de passage et divers autres concepts similaires. Il s’utilise avec des vues telles que MapItemView
.
Il faut créer un RouteQuery
avec les points de route. Si autoUpdate
est activé, la mise à jour sera automatiquement effectuée. Les données stockées et renvoyées dans RouteModel
sont constituées d’objets Route
sous forme de liste avec le nom routeData
.
Button {
onClicked: {
// Test RouteModel
map.center = QtPositioning.coordinate(44.0868587, 4.96439917)
routeQuery.clearWaypoints()
routeQuery.addWaypoint(QtPositioning.coordinate(44.0868587, 4.96439917))
routeQuery.addWaypoint(QtPositioning.coordinate(43.95, 4.8167))
map.update()
}
}
Map {
id: map
RouteModel {
id: routeModel
plugin: mapPlugin
query: RouteQuery {
id: routeQuery
travelModes: RouteQuery.CarTravel
routeOptimizations: RouteQuery.ShortestRoute
}
}
MapItemView {
model: routeModel
delegate: MapRoute {
route: routeData
line.color: "blue"
line.width: 5
smooth: true
opacity: 0.5
}
}
}
Les cartes peuvent également contenir des objets de superposition qui sont utilisés pour afficher des informations. Il existe un ensemble d’objets de superposition prédéfinis de base : MapCircle, MapRectangle, MapPolygon, MapPolyline et MapQuickItem.
Tous les éléments de dessin surperposés sur la carte doivent être intégrés dans l’élément Map.
center
. Voir aussi : MapQuickItem.Map {
...
MapCircle {
id: cercle
center: map.center
radius: 40
color: 'green'
border.width: 3
opacity: 0.25
}
}
coordinate
et anchorPoint
.MapQuickItem {
id: marker
anchorPoint.x: image.width/4
anchorPoint.y: image.height
sourceItem: Image {
id: image
source: "images/marqueur.png"
}
}
Map {
RouteModel {
id: routeModel
plugin: mapPlugin
query: RouteQuery {
id: routeQuery
travelModes: RouteQuery.CarTravel
routeOptimizations: RouteQuery.ShortestRoute
}
}
MapItemView {
model: routeModel
delegate: MapRoute {
route: routeData
line.color: "blue"
line.width: 5
smooth: true
opacity: 0.5
}
}
}
Il est possible d’obtenir des erreurs liées à SSL.
Messages d’erreur du type : qt.network.ssl QSslSocket ...
Actuellement la version de Qt ne supporte que la version 1.0 de ssl (et non la version 1.1). Pour pallier au problème, il faut installer :
$ sudo apt-get install libssl1.0-dev
Messages d’erreur liés à libcrypto.so
et libssl.so
.
Il faut télécharger la bibliothèque openssl
et la compiler pour la cible Android. La version de Qt utilisée ici est la 5.10.1. La fabrication nécessite une installation de Qt5 pour Android fonctionnelle.
Une fois fabriquées les deux bibliothèques seront copiées dans le répertoire android/libs/arm
du projet Qt. Il faudra lier l’application en l’indiquant dans le fichier .pro
.
On utilisera le script Setenv-android.sh qu’il faudra paramétrer en fonction de son installation :
$ wget https://www.openssl.org/source/openssl-1.0.2q.tar.gz
$ tar zxvf openssl-1.0.2q.tar.gz
$ cd openssl-1.0.2q/
$ wget https://wiki.openssl.org/images/7/70/Setenv-android.sh
$ vim Setenv-android.sh
_ANDROID_NDK="android-ndk-r10e"
_ANDROID_EABI="arm-linux-androideabi-4.9"
_ANDROID_ARCH=arch-arm
_ANDROID_API="android-18"
ANDROID_NDK_ROOT="/.../Android/Sdk/$_ANDROID_NDK"
$ . ./Setenv-android.sh
$ ./Configure shared android
$ make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" build_libs
$ mkdir -p /.../Qt_Projets/.../android/libs/arm
$ cp libcrypto.so /.../Qt_Projets/.../android/libs/arm
$ cp libssl.so /.../Qt_Projets/.../android/libs/arm
$ vim *.pro
ANDROID_EXTRA_LIBS = \
$$PWD/android/libs/arm/libcrypto.so \
$$PWD/android/libs/arm/libssl.so
Les deux bibliothèques sont fournies dans l’archive de l’exemple qt-android-map.zip.
Site : tvaira.free.fr