{"id":1090,"date":"2011-11-14T11:16:32","date_gmt":"2011-11-14T14:16:32","guid":{"rendered":"http:\/\/realnorth.net\/blog\/?p=1090"},"modified":"2012-01-17T19:40:02","modified_gmt":"2012-01-17T22:40:02","slug":"maps-qml","status":"publish","type":"post","link":"https:\/\/realnorth.net\/blog\/maps-qml\/","title":{"rendered":"[Actualizado] Integrando Mapas con QML"},"content":{"rendered":"<p>El objetivo de este post es mostrarles de forma practica, un par de opciones para que puedan integrar mapas en sus aplicaciones Qt, tanto en Symbian como en MeeGo, la primera opci\u00f3n hace uso de la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/location-overview.html\" title=\"Location API\" target=\"_blank\">Location API<\/a> incluida en <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/index.html\" title=\"QtMobility 1.2\" target=\"_blank\">QtMobility<\/a>, la segunda opci\u00f3n permite integrar servicios como Google Maps, Bing Map o Nokia Maps (ex Ovi Maps) haciendo uso de <a href=\"http:\/\/doc.qt.nokia.com\/latest\/qtwebkit.html\" title=\"QtWebkit Documentation\" target=\"_blank\">QtWebKit<\/a>.<\/p>\n<h3>Usted esta aqu\u00ed<\/h3>\n<p>Las opciones que describo en este post permiten ubicar en el mapa un punto especifico, este punto lo podemos obtener de diversas maneras, desde una DB, ingresando los datos manualmente u obteniendo las coordenadas desde el GPS del dispositivo, para hacer esto ultimo solo debemos primero, agregar a nuestro proyecto la dependencia a la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/location-overview.html\" title=\"Location QML Plugin\">Location API<\/a> de <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/index.html\" title=\"QtMobility 1.2 Documentation\" target=\"_blank\">QtMobility<\/a><\/p>\n<pre>\r\nimport QtMobility.location 1.2\r\n<\/pre>\n<p>Luego vamos a declarar unas propiedades en las cuales almacenaremos la longitud y la latitud que obtendremos usando el elemento <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-positionsource.html\" title=\"QML PositionSource Element\" target=\"_blank\">PositionSource<\/a>, para luego mostrarlos usando un elemento Text.<\/p>\n<pre>\r\nproperty double mapLat\r\nproperty double mapLong\r\nmapLat: positionSource.position.coordinate.latitude\r\nmapLong: positionSource.position.coordinate.longitude\r\n\r\nPositionSource {\r\n    id: positionSource\r\n    active: true\r\n    updateInterval: 1000\r\n}\r\n\r\nText {\r\n    color:\"#fff\"\r\n    text: \"Latitud: \" + mapLat + \"&#60;br&#47;&#62;\" + \"Longitud: \" + mapLong\r\n    anchors.horizontalCenter: parent.horizontalCenter\r\n    anchors.verticalCenter: parent.verticalCenter\r\n}\r\n<\/pre>\n<p><img decoding=\"async\" id=\"geoMaps1\" src=\"http:\/\/realnorth.net\/blog\/wp-content\/uploads\/2011\/11\/locationDemo011.jpg\" alt=\"QML &amp; Maps - Get Position Demo\" title=\"QML &amp; Maps - Get Position Demo\" \/><\/p>\n<h4>Simulando el GPS<\/h4>\n<p>Si no cuentan con un dispositivo para probar, pueden simular el uso del GPS usando la opciones de Location que vienen incluidas en Qt Simulator.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/realnorth.net\/blog\/wp-content\/uploads\/2011\/11\/Qt-Simulator-Control_922.png\" alt=\"QML &amp; Maps - Qt Simulator\" title=\"QML &amp; Maps - Qt Simulator\" \/><\/p>\n<h3>QtMobility Location API<\/h3>\n<p>Esta opci\u00f3n hace uso de algunos de los <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-location-plugin.html\" title=\"Location QML Plugin\" target=\"_blank\">elementos QML<\/a> que nos provee la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/index.html\" title=\"Location API\" target=\"_blank\">Location API<\/a>, en este ejemplo usaremos un elemento <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-coordinate.html\" title=\"QML Coordinate Element\">Coordinate<\/a>, para almacenar la latitud y la longitud que obtenemos del <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-positionsource.html\" title=\"QML Position Siurce Element\" target=\"_blank\">PositionSource<\/a>, luego crearemos un elemento <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-map.html\" title=\"QML Map Element\" target=\"_blank\">Map<\/a>, el cual a su vez contiene una <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-mapimage.html\" title=\"QML MapImage Element\" target=\"_blank\">MapImage<\/a>, tanto la propiedad <em>center<\/em> del Map, como la propiedad <em>coordinate<\/em> del <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-mapimage.html\" title=\"QML MapImage Element\" target=\"_blank\">MapImage<\/a> van a usar los datos de la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-coordinate.html\" title=\"QML Coordinate Element\" target=\"_blank\">Coordinate<\/a> previamente declarada.<\/p>\n<pre>\r\nproperty double mapLat\r\nproperty double mapLong\r\nmapLat: positionSource.position.coordinate.latitude\r\nmapLong: positionSource.position.coordinate.longitude\r\n\r\nPositionSource {\r\n    id: positionSource\r\n    active: true\r\n    updateInterval: 1000\r\n}\r\n\r\nCoordinate { \r\n    id: defaultMapCenter\r\n    latitude: mapLat\r\n    longitude: mapLong\r\n}\r\n\r\nMap {\r\n    id: map\r\n    anchors.fill: parent\r\n    plugin : Plugin {name : \"nokia\"}\r\n    size.width: parent.width\r\n    size.height: parent.height\r\n    zoomLevel: 16\r\n    center: defaultMapCenter\r\n\r\n    MapImage {\r\n        id : pin\r\n        coordinate: defaultMapCenter\r\n        source:\"images\/pin.png\"\r\n    }\r\n}\r\n<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/realnorth.net\/blog\/wp-content\/uploads\/2011\/11\/locationDemo02.jpg\" alt=\"QML &amp; Maps - Qt Mobility Sample\" title=\"QML &amp; Maps - Qt Mobility Sample\"\/><\/p>\n<h3>QtWebKit y Nokia Maps<\/h3>\n<p>Esta opci\u00f3n quiz\u00e1s no se integra de forma 100% nativa de la misma manera que podemos hacer usando la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/index.html\" title=\"Location API\" target=\"_blank\">Location API<\/a>, pero tiene la ventaja de que podemos usar a nuestro proveedor preferido y ademas nos permite reutilizar c\u00f3digo que hayamos creado con anterioridad, este ejemplo hace uso de la <a href=\"http:\/\/api.maps.ovi.com\/devguide\/overview.html\" title=\"Nokia Maps API\" target=\"_blank\">API<\/a> de Nokia Maps y para comenzar crearemos una pagina web con el siguiente c\u00f3digo (ver abajo) y la incluiremos en nuestro proyecto, el c\u00f3digo en si no tiene mucha magia, al principio hay una referencia a la librer\u00eda de Nokia Maps, luego inicializamos el mapa, configuramos los elementos que vamos a utilizar en el, el nivel de zoom, una posici\u00f3n por default y finalmente crearemos la funci\u00f3n <em>setLocation<\/em> que sera la encargada de ubicar el pin y centrar el mapa usando las coordenadas obtenidas por el <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-positionsource.html\" title=\"QML Position Source Element\" target=\"_blank\">PositionSource<\/a><\/p>\n<pre>\r\n&#60;!DOCTYPE html PUBLIC \"-&#47;&#47;W3C&#47;&#47;DTD XHTML 1.0 Transitional&#47;&#47;EN\" \"http:&#47;&#47;www.w3.org&#47;TR&#47;xhtml1&#47;DTD&#47;xhtml1-transitional.dtd\"&#62;\r\n&#60;html xmlns=\"http:&#47;&#47;www.w3.org&#47;1999&#47;xhtml\"&#62;\r\n&#60;head&#62;\r\n&#60;meta http-equiv=\"Content-Type\" content=\"text&#47;html; charset=UTF-8\" &#47;&#62;\r\n&#60;title&#62;Ovi Maps&#60;&#47;title&#62;\r\n&#60;script src=\"http:&#47;&#47;api.maps.ovi.com&#47;jsl.js\" type=\"text&#47;javascript\" charset=\"utf-8\"&#62;&#60;&#47;script&#62;\r\n&#60;script type=\"text&#47;javascript\"&#62;\r\n    var map;\r\n    function initialize() {\r\n        map = new ovi.mapsapi.map.Display(document.getElementById(\"map\"), {\r\n        components: [\r\n            new ovi.mapsapi.map.component.ZoomBar(),\r\n            new ovi.mapsapi.map.component.Overview(),\r\n            new ovi.mapsapi.map.component.TypeSelector()],\r\n            'zoomLevel':16,\r\n            'center':[-34.603000, -58.380000]\r\n        });\r\n        \r\n        ovi.mapsapi.util.ApplicationContext.set(\"defaultLanguage\", \"es-ES\")\r\n        map.addComponent(new ovi.mapsapi.map.component.panning.Drag());\r\n        map.addComponent(new ovi.mapsapi.map.component.panning.Kinetic());\r\n    }\r\n\r\n    function setLocation(lat, lon) {\r\n        pin = new ovi.mapsapi.map.Marker([lat, lon], { icon: \"images&#47;pin.png\" }),\r\n        map.objects.add(pin);\r\n        map.setCenter(new ovi.mapsapi.geo.Coordinate(lat,lon));\r\n    }\r\n&#60;&#47;script&#62;\r\n&#60;&#47;head&#62;\r\n&#60;body onload=\"initialize()\"&#62;\r\n    &#60;div id=\"map\"&#62;&#60;&#47;div&#62;\r\n&#60;&#47;body&#62;\r\n&#60;&#47;html&#62;\r\n<\/pre>\n<p>Del lado del QML, lo primero que haremos sera importar a <a href=\"http:\/\/doc.qt.nokia.com\/latest\/qtwebkit.html\" title=\"QtWebkit Documentation\" target=\"_blank\">QtWebKit<\/a> como dependencia.<\/p>\n<pre>\r\nimport QtWebKit 1.0\r\n<\/pre>\n<p>Luego crearemos una <a href=\"http:\/\/doc.qt.nokia.com\/4.7-snapshot\/qml-webview.html\" title=\"QML WebView Element\" target=\"_blank\">WebView<\/a> que va a cargar la pagina web anteriormente creada.<\/p>\n<p>Solo resta esperar que se dispare el evento <em>onLoadFinished<\/em> que ejecutara la funci\u00f3n <em>updatePosition<\/em> que usando el metodo <a href=\"http:\/\/doc.qt.nokia.com\/4.7-snapshot\/qml-webview.html#evaluateJavaScript-method\" title=\"evaluateJavaScript Method\" target=\"_blank\">evaluateJavaScript<\/a> le pasara a la funci\u00f3n <em>setLocation<\/em> que se encuentra en la pagina web, los par\u00e1metros que necesita para centrar y ubicar el pin en el mapa.<\/p>\n<pre>\r\nproperty double mapLat\r\nproperty double mapLong\r\nmapLat: positionSource.position.coordinate.latitude\r\nmapLong: positionSource.position.coordinate.longitude\r\n\r\nPositionSource {\r\n    id: positionSource\r\n    active: true\r\n    updateInterval: 1000\r\n}\r\n\r\nfunction updatePosition(mapLat, mapLong){\r\n    mapView.evaluateJavaScript(\"setLocation(\"+mapLat+\",\"+mapLong+\");\");\r\n}\r\n\r\nWebView {\r\n    id: mapView\r\n    url: \"map.html\"\r\n    preferredWidth: parent.width\r\n    preferredHeight: parent.height\r\n    scale: 1\r\n    onLoadFinished: {\r\n        updatePosition(mapLat, mapLong);\r\n    }\r\n}\r\n<\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/realnorth.net\/blog\/wp-content\/uploads\/2011\/11\/locationDemo03.jpg\" alt=\"QML &amp; Maps - QtWebKit + Nokia Maps Sample\" title=\"QML &amp; Maps - QtWebKit + Nokia Maps Sample\"\/><\/p>\n<h3>Algunas consideraciones<\/h3>\n<p>Todos los ejemplos descriptos anteriormente son b\u00e1sicos, no intenten usarlos directamente en aplicaciones reales sin antes crear cierta l\u00f3gica para manejar los fallos y demoras que acompa\u00f1an siempre a las aplicaciones que dependen del uso del GPS.<\/p>\n<h4>\u00bfCual opci\u00f3n usar?<\/h4>\n<p>Mas all\u00e1 de las ventajas antes descriptas, como por ejemplo, la flexibilidad de proveedores, la reutilizaci\u00f3n de c\u00f3digo o la integraci\u00f3n de forma nativa, hay un punto muy importante que deben tener en cuenta a la hora de decidir que camino seguir, este punto es la <strong>performance<\/strong>, mi experiencia me ha demostrado que la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/location-overview.html\" title=\"Location API\" target=\"_blank\">Location API<\/a> no tiene un buen rendimiento cuando es usada en Symbian si lo comparamos con MeeGo, el obtener los datos del GPS puede demorar bastante, desde m\u00ednimo 5 segundos hasta 30 segundos o mas, en cambio en MeeGo este proceso es casi instant\u00e1neo, esto en parte se puede subsanar en Symbian usando un <a href=\"http:\/\/doc.qt.nokia.com\/qt-components-symbian\/qml-busyindicator.html\" title=\"QML BusyIndicator Element\" target=\"_blank\">BusyIndicator<\/a> y pidiendo paciencia al usuario, esta lentitud tambi\u00e9n se ve reflejada a la hora de cargar el <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/qml-map.html\" title=\"QML Map Element\" target=\"_blank\">Map<\/a>, el cual puede tardar entre 5 y 10 segundos en completar su tarea en Symbian, todo lo contrario en MeeGo, en el cual la carga es casi inmediata usando WiFi y demorando no mas de 2 segundos si usamos 3G, es por ello que la opci\u00f3n <a href=\"http:\/\/doc.qt.nokia.com\/latest\/qtwebkit.html\" title=\"QtWebkit Documentation\" target=\"_blank\">QtWebKit<\/a> + <a href=\"http:\/\/api.maps.ovi.com\/devguide\/overview.html\" title=\"Nokia Maps API\" target=\"_blank\">Nokia Maps<\/a> puede llegar a ser \u00fatil en algunos casos, ya que su performance no es deslumbrante pero si un poco mejor que la que proporciona la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/location-overview.html\" title=\"Location API\" target=\"_blank\">Location API<\/a> en Symbian, ademas de que es mas consistente y regular en los tiempos de carga del mapa, lo que ayuda a que su rendimiento sea mas predecible.<\/p>\n<p>El porque de esta diferencia de performance de la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/location-overview.html\" title=\"Location API\" target=\"_blank\">Location API<\/a> entre Symbian y MeeGo no he podido dilucidarlo aun, puede ser la diferencia de velocidad entre los dispositivos (N8\/C7 680Mhz vs. N9\/N950 1Gz ) o una falta de optimizaci\u00f3n en la versi\u00f3n para Symbian, por mientras pueden usar alguna de las opciones antes detalladas seg\u00fan el caso de uso que quieran resolver.<\/p>\n<h4>Actualizaci\u00f3n &#8211; 15\/11\/2011<\/h4>\n<p>Hoy luego de algunas pruebas usando Qt Mobility 1.2.1, versi\u00f3n que esta incluida en el nuevo <a href=\"https:\/\/www.developer.nokia.com\/info\/sw.nokia.com\/id\/da8df288-e615-443d-be5c-00c8a72435f8\/Qt_SDK.html\" title=\"Download Qt SDK 1.1.4\" target=\"_blank\">Qt SDK 1.1.4<\/a>, pude comprobar que la performance de la versi\u00f3n para Symbian de la <a href=\"http:\/\/doc.qt.nokia.com\/qtmobility-1.2\/location-overview.html\" title=\"Location API\" target=\"_blank\">Location API<\/a> ha mejorado bastante, no esta al nivel de la versi\u00f3n para MeeGo aun, pero entra en el terreno de lo usable.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>El objetivo de este post es mostrarles de forma practica, un par de opciones para que puedan integrar mapas en sus aplicaciones Qt, tanto en Symbian como en MeeGo, la primera opci\u00f3n hace uso de la Location API incluida en QtMobility, la segunda opci\u00f3n permite integrar servicios como Google Maps, Bing Map o Nokia Maps [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[74,73,25,43,44,45,54],"class_list":["post-1090","post","type-post","status-publish","format-standard","hentry","category-development","tag-geolocation","tag-maps","tag-meego","tag-qml","tag-qt","tag-qt-mobility","tag-symbian"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/posts\/1090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/comments?post=1090"}],"version-history":[{"count":66,"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/posts\/1090\/revisions"}],"predecessor-version":[{"id":1480,"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/posts\/1090\/revisions\/1480"}],"wp:attachment":[{"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/media?parent=1090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/categories?post=1090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/realnorth.net\/blog\/wp-json\/wp\/v2\/tags?post=1090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}