Introduction to the development of cartographic and geolocation mobile applications using QtMobility.location
This post participates in the competition “ Smart Phones for Smart Posts ”.
I have never had to participate in the development of cartographic and geolocation mobile applications, therefore this competition topic has become interesting to me both in terms of professional growth and in terms of ordinary human curiosity. Naturally, I suspected that QtQuick would greatly facilitate the task of studying the subject, but he again pleasantly surprised me with the elegant simplicity of solving the problem.
It's about QtMobility.location . By the way, the application shown in the screenshot contains less than a page of QML code and not a single line in C ++.
Probably, it’s worth starting according to tradition with the minimal “Hello, World !!!” applications. However, this "Hello, World !!!" slightly different from the usual. This is no longer the squeak of a newly hatched chick in a dark, unfriendly console, but rather his little victorious cry when flying to a neighboring yard. It looks like this (a screenshot of this application was given above):
The main element that interests us here is, of course, the Map element . I will tell you about it in more detail. He is responsible for loading and displaying the map. The main work in this element is done by the plugin described by the Plugin element .
The center property - coordinates of the center of the displayed map. To “jump” to a new location on the map, you just need to change the values of the center property of the Map element . You can move around the map not only abruptly, but also smoothly, using the map.pan (dx, dy) function . dx, dy - left / right shift and up \ down relative to the previous position.
zoomLevelresponsible for the scale of the map. By changing the value of this property, you can zoom in / out. The minimum and maximum values are subtracted from the minimumZoomLevel and maximumZoomLevel properties .
mapType is a map type. The following types:
• Map.StreetMap
• Map.SatelliteMapDay
• Map.SatelliteMapNight
• Map.TerrainMap
• Map.HybridMap
• Map.TransitMap
• Map.GrayStreetMap
• Map.MobileStreetMap
• Map.MobileTerrainMap
• Map.MobileHybridMap
• Map.MobileTransitMap
• the Map .MobileGrayStreetMap
For proper display, the card type must, of course, be supported by the provider.
In the screenshot above, the map type Map.StreetMap is used .
In the screenshot below - Map.SatelliteMapDay :
Various elements, such as MapRectangle, MapCircle, MapText, MapImage, MapPolygon, MapPolyline , etc. can be added as child entities of the Map element to the map . These items will be displayed automatically at the specified position. They are very convenient to use to set various labels on the map, display routes, areas and everything that you might need. For example, this is how you can display text on a map in the position we need:
Or, like this - with a yellow circle you can mark the current user coordinates on the map:
But to mark the coordinates of the user, you must first find them out. With QtMobility, this is also done elementarily. And the QML PositionSource Element will help us with this . Through it, you can get information about things like your current coordinates, altitude and speed.
The following piece of code demonstrates what and how to get out of this element:
I was also interested in how to get the global coordinates of an object already displayed on the screen. It turned out - with QtMobility, this is also done very simply. The map.toCoordinate () function translates the screen coordinates of the object into global. We touched an object on the screen - got the coordinates:
In conclusion, I would like to briefly mention acquaintance with the OVI Maps API . Using the OVI Maps API, you can easily organize in the application a search for a location by its name and many, many other things. For example, in the screenshot below, points “A” and “B” are set and the OVI Maps API gives a route from one to another. The maps in it are managed through JavaScript. And as you know - the best friend of QML is JavaScript, which can be directly embedded in the code. Thus, the QML-JavaScript-OVI Maps API combination seemed to me a very powerful tool for creating cartographic and geolocation mobile applications of any complexity. And QtQuick has once again demonstrated all its power and graceful simplicity.
OVI Maps API Playground:
I have never had to participate in the development of cartographic and geolocation mobile applications, therefore this competition topic has become interesting to me both in terms of professional growth and in terms of ordinary human curiosity. Naturally, I suspected that QtQuick would greatly facilitate the task of studying the subject, but he again pleasantly surprised me with the elegant simplicity of solving the problem.
It's about QtMobility.location . By the way, the application shown in the screenshot contains less than a page of QML code and not a single line in C ++.
Probably, it’s worth starting according to tradition with the minimal “Hello, World !!!” applications. However, this "Hello, World !!!" slightly different from the usual. This is no longer the squeak of a newly hatched chick in a dark, unfriendly console, but rather his little victorious cry when flying to a neighboring yard. It looks like this (a screenshot of this application was given above):
- import QtQuick 1.1
- import QtMobility.location 1.2
-
- Item {
- id: page
- anchors.fill: parent
- focus: true
-
- TitleBar { id: titleBar; appname: "Hello World"; z: 5; width: parent.width; height: 40; opacity: 0.8 }
-
- Rectangle {
- id: dataArea
- anchors.top: titleBar.bottom
- anchors.bottom: parent.bottom
- width: parent.width
- color: "#343434"
- Map {
- id: map
- plugin: Plugin {
- name : "nokia"
- }
- anchors.fill: parent
- size.width: parent.width
- size.height: parent.height
- zoomLevel: 6
- center: Coordinate {latitude: 55; longitude: 73.12}
- mapType: Map.StreetMap
- } // map
- }
- } // page
The main element that interests us here is, of course, the Map element . I will tell you about it in more detail. He is responsible for loading and displaying the map. The main work in this element is done by the plugin described by the Plugin element .
The center property - coordinates of the center of the displayed map. To “jump” to a new location on the map, you just need to change the values of the center property of the Map element . You can move around the map not only abruptly, but also smoothly, using the map.pan (dx, dy) function . dx, dy - left / right shift and up \ down relative to the previous position.
zoomLevelresponsible for the scale of the map. By changing the value of this property, you can zoom in / out. The minimum and maximum values are subtracted from the minimumZoomLevel and maximumZoomLevel properties .
mapType is a map type. The following types:
• Map.StreetMap
• Map.SatelliteMapDay
• Map.SatelliteMapNight
• Map.TerrainMap
• Map.HybridMap
• Map.TransitMap
• Map.GrayStreetMap
• Map.MobileStreetMap
• Map.MobileTerrainMap
• Map.MobileHybridMap
• Map.MobileTransitMap
• the Map .MobileGrayStreetMap
For proper display, the card type must, of course, be supported by the provider.
In the screenshot above, the map type Map.StreetMap is used .
In the screenshot below - Map.SatelliteMapDay :
Various elements, such as MapRectangle, MapCircle, MapText, MapImage, MapPolygon, MapPolyline , etc. can be added as child entities of the Map element to the map . These items will be displayed automatically at the specified position. They are very convenient to use to set various labels on the map, display routes, areas and everything that you might need. For example, this is how you can display text on a map in the position we need:
- MapText {
- id: texts
- coordinate: Coordinate {latitude: 54.914; longitude: 73.313}
- color: "yellow"
- text: "Samarka"
- font.pixelSize: 10
- }
Or, like this - with a yellow circle you can mark the current user coordinates on the map:
- MapCircle {
- id: userPosition
- color: "yellow"
- radius: 10
- center: userPositionSource.position.coordinate
- }
But to mark the coordinates of the user, you must first find them out. With QtMobility, this is also done elementarily. And the QML PositionSource Element will help us with this . Through it, you can get information about things like your current coordinates, altitude and speed.
The following piece of code demonstrates what and how to get out of this element:
- import Qt 4.7
- import QtMobility.location 1.2
- Rectangle {
- id: page
- width: 350
- height: 350
- PositionSource {
- id: positionSource
- updateInterval: 1000
- active: true
- // nmeaSource: "nmealog.txt"
- }
- Column {
- Text {text: "<==== PositionSource ====>"}
- Text {text: "positioningMethod: " + printableMethod(positionSource.positioningMethod)}
- Text {text: "nmeaSource: " + positionSource.nmeaSource}
- Text {text: "updateInterval: " + positionSource.updateInterval}
- Text {text: "active: " + positionSource.active}
- Text {text: "<==== Position ====>"}
- Text {text: "latitude: " + positionSource.position.coordinate.latitude}
- Text {text: "longitude: " + positionSource.position.coordinate.longitude}
- Text {text: "altitude: " + positionSource.position.coordinate.altitude}
- Text {text: "speed: " + positionSource.position.speed}
- Text {text: "timestamp: " + positionSource.position.timestamp}
- Text {text: "altitudeValid: " + positionSource.position.altitudeValid}
- Text {text: "longitudeValid: " + positionSource.position.longitudeValid}
- Text {text: "latitudeValid: " + positionSource.position.latitudeValid}
- Text {text: "speedValid: " + positionSource.position.speedValid}
- }
- function printableMethod(method) {
- if (method == PositionSource.SatellitePositioningMethod)
- return "Satellite";
- else if (method == PositionSource.NoPositioningMethod)
- return "Not available"
- else if (method == PositionSource.NonSatellitePositioningMethod)
- return "Non-satellite"
- else if (method == PositionSource.AllPositioningMethods)
- return "All/multiple"
- return "source error";
- }
- }
I was also interested in how to get the global coordinates of an object already displayed on the screen. It turned out - with QtMobility, this is also done very simply. The map.toCoordinate () function translates the screen coordinates of the object into global. We touched an object on the screen - got the coordinates:
- onPressed: {
- console.log('latitude = '+ (map.toCoordinate(Qt.point(mouse.x,mouse.y))).latitude);
- console.log('longitude = '+ (map.toCoordinate(Qt.point(mouse.x,mouse.y))).longitude);
- }
In conclusion, I would like to briefly mention acquaintance with the OVI Maps API . Using the OVI Maps API, you can easily organize in the application a search for a location by its name and many, many other things. For example, in the screenshot below, points “A” and “B” are set and the OVI Maps API gives a route from one to another. The maps in it are managed through JavaScript. And as you know - the best friend of QML is JavaScript, which can be directly embedded in the code. Thus, the QML-JavaScript-OVI Maps API combination seemed to me a very powerful tool for creating cartographic and geolocation mobile applications of any complexity. And QtQuick has once again demonstrated all its power and graceful simplicity.
OVI Maps API Playground: