Pull to refresh

Введение в разработку картографических и геолокационных мобильных приложений с применением QtMobility.location

Reading time 7 min
Views 2.8K
Qt *
Этот пост участвует в конкурсе „Умные телефоны за умные посты

Никогда ранее не приходилось участвовать в разработке картографических и геолокационных мобильных приложений, поэтому эта конкурсная тема мне стала интересна как в плане профессионального роста, так и в плане обычного человеческого любопытства. Я, естественно, подозревал, что QtQuick значительно облегчит мне задачу изучения сабжа, но он в очередной раз приятно удивил элегантной простотой решения задачи.


Речь пойдет о QtMobility.location. Кстати, изображенное на скриншоте приложение содержит менее страницы кода на QML и ни строчки на C++.




Начать, наверное, стоит по традиции с минимального «Hello, World!!!» приложения. Однако этот «Hello, World!!!» несколько отличается от привычного. Это уже не писк только что вылупившегося птенца в темной неприветливой консоли, а скорее его маленький победный крик при перелете в соседний двор. Выглядит оно так (скриншот этого приложения был приведен выше):
  1. import QtQuick 1.1
  2. import QtMobility.location 1.2
  3.  
  4. Item {
  5.     id: page
  6.     anchors.fill: parent
  7.     focus: true
  8.  
  9. TitleBar { id: titleBar; appname: "Hello World"; z: 5; width: parent.width; height: 40; opacity: 0.8 }
  10.  
  11. Rectangle {
  12.         id: dataArea
  13.         anchors.top: titleBar.bottom
  14.         anchors.bottom: parent.bottom
  15.         width: parent.width
  16.         color: "#343434"
  17.         Map {
  18.             id: map
  19.             plugin: Plugin {
  20.                 name : "nokia"
  21.             }
  22.             anchors.fill: parent
  23.             size.width: parent.width
  24.             size.height: parent.height
  25.             zoomLevel: 6
  26.             center: Coordinate {latitude: 55; longitude: 73.12}
  27.             mapType: Map.StreetMap
  28.         } // map
  29.     }
  30. } // page

Основной интересующий здесь нас элемент – это, конечно же, элемент Map. Расскажу о нем более подробно. Он отвечает за загрузку и отображение карты. Основная работа в этом элементе совершается плагином, описываемым элементом Plugin.

Свойство center – координаты центра отображаемой карты. Чтобы «перепрыгнуть» в новую локацию на карте — достаточно лишь поменять значения свойства center у элемента Map. Передвигаться по карте можно не только скачкообразно, но и плавно, используя функцию map.pan(dx, dy). dx, dy – смещение влево\вправо и верх\вниз относительно предыдущей позиции.

zoomLevel отвечает за масштаб карты. Меняя значение этого свойства можно уменьшать\увеличивать масштаб. Минимальное и максимальное значения вычитываются из свойств minimumZoomLevel и maximumZoomLevel.

mapType — это тип карты. Доступны следующие виды:
• Map.StreetMap
• Map.SatelliteMapDay
• Map.SatelliteMapNight
• Map.TerrainMap
• Map.HybridMap
• Map.TransitMap
• Map.GrayStreetMap
• Map.MobileStreetMap
• Map.MobileTerrainMap
• Map.MobileHybridMap
• Map.MobileTransitMap
• Map.MobileGrayStreetMap

Для корректного отображения тип карты должен, конечно же, поддерживаться провайдером.

На скриншоте выше использован тип карты Map.StreetMap.
На скриншоте ниже — Map.SatelliteMapDay:




В качестве дочерних сущностей элемента Map на карту могут быть добавлены различные элементы, такие как MapRectangle, MapCircle, MapText, MapImage, MapPolygon, MapPolyline и т.п. Эти элементы будут отображаться автоматически в указанной позиции. Их очень удобно использовать для установки различных меток на карте, отображения маршрутов, областей и всего, чего только может понадобиться.
К примеру, вот так можно отобразить текст на карте в нужной нам позиции:
  1. MapText {
  2.                 id: texts
  3.                 coordinate: Coordinate {latitude: 54.914; longitude: 73.313}
  4.                 color: "yellow"
  5.                 text: "Samarka"
  6.                 font.pixelSize: 10
  7. }


Или, вот так — желтым кружочком можно пометить на карте текущие координаты пользователя:
  1. MapCircle {
  2.     id: userPosition
  3.     color: "yellow"
  4.     radius: 10
  5.     center: userPositionSource.position.coordinate
  6. }


Но чтобы пометить координаты пользователя, нужно сначала их узнать. С QtMobility это тоже делается элементарно. И поможет нам в этом QML PositionSource Element. Через него вы можете получить информацию о таких вещах, как ваши текущие координаты, высота над уровнем моря и скорость.



Следующий кусок кода демонстрирует, что и как можно вытащить из этого элемента:
  1. import Qt 4.7
  2. import QtMobility.location 1.2
  3. Rectangle {
  4.     id: page
  5.     width: 350
  6.     height: 350
  7.     PositionSource {
  8.         id: positionSource
  9.         updateInterval: 1000
  10.         active: true
  11.         // nmeaSource: "nmealog.txt"
  12.     }
  13.     Column {
  14.         Text {text: "<==== PositionSource ====>"}
  15.         Text {text: "positioningMethod: " + printableMethod(positionSource.positioningMethod)}
  16.         Text {text: "nmeaSource: "         + positionSource.nmeaSource}
  17.         Text {text: "updateInterval: "     + positionSource.updateInterval}
  18.         Text {text: "active: "     + positionSource.active}
  19.         Text {text: "<==== Position ====>"}
  20.         Text {text: "latitude: "  + positionSource.position.coordinate.latitude}
  21.         Text {text: "longitude: "  + positionSource.position.coordinate.longitude}
  22.         Text {text: "altitude: "  + positionSource.position.coordinate.altitude}
  23.         Text {text: "speed: " + positionSource.position.speed}
  24.         Text {text: "timestamp: " + positionSource.position.timestamp}
  25.         Text {text: "altitudeValid: " + positionSource.position.altitudeValid}
  26.         Text {text: "longitudeValid: " + positionSource.position.longitudeValid}
  27.         Text {text: "latitudeValid: " + positionSource.position.latitudeValid}
  28.         Text {text: "speedValid: "     + positionSource.position.speedValid}
  29.     }
  30.     function printableMethod(method) {
  31.         if (method == PositionSource.SatellitePositioningMethod)
  32.             return "Satellite";
  33.         else if (method == PositionSource.NoPositioningMethod)
  34.             return "Not available"
  35.         else if (method == PositionSource.NonSatellitePositioningMethod)
  36.             return "Non-satellite"
  37.         else if (method == PositionSource.AllPositioningMethods)
  38.             return "All/multiple"
  39.         return "source error";
  40.     }
  41. }






Еще меня заинтересовало, как получить глобальные координаты какого-либо объекта, уже отображенного на экране. Оказалось — с QtMobility это делается так же очень просто. Функция map.toCoordinate() переводит экранные координаты объекта в глобальные. Коснулись объекта на экране – получили координаты:
  1. onPressed: {
  2.   console.log('latitude = '+ (map.toCoordinate(Qt.point(mouse.x,mouse.y))).latitude);
  3.   console.log('longitude = '+ (map.toCoordinate(Qt.point(mouse.x,mouse.y))).longitude);
  4. }




В заключении хотелось бы вкратце упомянуть о знакомстве с OVI Maps API. Посредством OVI Maps API можно легко организовать в приложении поиск локации по ее названию и много-много всего остального. К примеру, на скриншоте ниже задаются точки “A” и ”B” и OVI Maps API выдает маршрут от одной к другой. Карты в нем управляются посредством JavaScript. А как известно — лучший друг QML – это JavaScript, который можно напрямую встраивать в код. Таким образом, связка QML – JavaScript — OVI Maps API мне показалась очень мощным инструментом для создания картографических и геолокационных мобильных приложений любой сложности. А QtQuick в очередной раз продемонстрировал всю свою мощь и грациозную простоту.

OVI Maps API Playground:
Tags:
Hubs:
Total votes 33: ↑15 and ↓18 -3
Comments 10
Comments Comments 10

Posts