Sophie

Sophie

distrib > Mageia > 5 > i586 > media > core-release > by-pkgid > 50facae208d4a6f280e44a513b104320 > files > 1934

qt-mobility-doc-1.2.0-13.mga5.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- mapsdemo.qdoc -->
  <title>Qt Mobility 1.2: Part 1 - The Map Widget</title>
  <link rel="stylesheet" type="text/css" href="style/offline.css" />
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="content"> 
    <a href="index.html" class="qtref"><span>QtMobility Reference Documentation</span></a>
  </div>
  <div class="breadcrumb toolblock">
    <ul>
      <li class="first"><a href="index.html">Home</a></li>
      <!--  Breadcrumbs go here -->
<li>Part 1 - The Map Widget</li>
    </ul>
  </div>
</div>
<div class="content mainContent">
  <link rel="prev" href="tutorials-mapsdemo.html" />
  <link rel="next" href="tutorials-mapsdemo-part2.html" />
  <link rel="start" href="tutorials-mapsdemo.html" />
<p class="naviNextPrevious headerNavi">
<a class="prevPage" href="tutorials-mapsdemo.html">Maps Demo Tutorial</a>
<a class="nextPage" href="tutorials-mapsdemo-part2.html">Part 2 - Searching for locations</a>
</p><p/>
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level2"><a href="#the-very-basics">The very basics</a></li>
<li class="level2"><a href="#pan-zoom">Pan &amp; zoom</a></li>
<li class="level2"><a href="#map-icons">Map icons</a></li>
</ul>
</div>
<h1 class="title">Part 1 - The Map Widget</h1>
<span class="subtitle"></span>
<!-- $$$tutorials-mapsdemo-part1.html-description -->
<div class="descr"> <a name="details"></a>
<p>To begin with, we will start defining the map widget, which is the central part of the application's user interface. Enough of the map widget will be defined here to work satisfactorily on most desktop platforms -- full consideration for mobile use will be made later along with other parts of the application.</p>
<a name="the-very-basics"></a>
<h3>The very basics</h3>
<p>The Location module provides the <a href="qgraphicsgeomap.html">QGraphicsGeoMap</a> which is a simple, easy way to insert maps into a <a href="http://qt.nokia.com/doc/4.7/qgraphicsscene.html">QGraphicsScene</a>. Since we're going to be extending the map later, we'll create a subclass of <a href="qgraphicsgeomap.html">QGraphicsGeoMap</a> called <tt>GeoMap</tt>, as below:</p>
<pre class="cpp"> <span class="keyword">class</span> GeoMap : <span class="keyword">public</span> <span class="type"><a href="qgraphicsgeomap.html">QGraphicsGeoMap</a></span>
 {
     Q_OBJECT

 <span class="keyword">public</span>:
     GeoMap(<span class="type"><a href="qgeomappingmanager.html">QGeoMappingManager</a></span> <span class="operator">*</span>manager<span class="operator">,</span> MapsWidget <span class="operator">*</span>mapsWidget);
     <span class="operator">~</span>GeoMap();

 <span class="keyword">private</span>:
     MapsWidget <span class="operator">*</span>mapsWidget;
 };

 GeoMap<span class="operator">::</span>GeoMap(<span class="type"><a href="qgeomappingmanager.html">QGeoMappingManager</a></span> <span class="operator">*</span>manager<span class="operator">,</span> MapsWidget <span class="operator">*</span>mapsWidget) :
     <span class="type"><a href="qgraphicsgeomap.html">QGraphicsGeoMap</a></span>(manager)<span class="operator">,</span> mapsWidget(mapsWidget)
 {
 }</pre>
<p>And next we define a <a href="http://qt.nokia.com/doc/4.7/qwidget.html">QWidget</a> subclass, MapsWidget, which handles the creation of <a href="http://qt.nokia.com/doc/4.7/qgraphicsview.html">QGraphicsView</a> and <a href="http://qt.nokia.com/doc/4.7/qgraphicsscene.html">QGraphicsScene</a> to put the GeoMap into. We make use of the Pimpl idiom on this class, since (as we will see) it will grow later to have a large complement of private data members, and some of these have naming conflicts with public methods.</p>
<pre class="cpp"> <span class="keyword">class</span> MapsWidgetPrivate;
 <span class="keyword">class</span> MapsWidget : <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qwidget.html">QWidget</a></span>
 {
     Q_OBJECT

 <span class="keyword">public</span>:
     MapsWidget(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qwidget.html">QWidget</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);
     <span class="operator">~</span>MapsWidget();

 <span class="keyword">public</span> <span class="keyword">slots</span>:
     <span class="type">void</span> initialize(<span class="type"><a href="qgeomappingmanager.html">QGeoMappingManager</a></span> <span class="operator">*</span>manager);

 <span class="keyword">private</span>:
     MapsWidgetPrivate <span class="operator">*</span>d;
 };</pre>
<p>We perform the creation of the <a href="http://qt.nokia.com/doc/4.7/qgraphicsscene.html">QGraphicsScene</a> and GeoMap in the initialize() method:</p>
<pre class="cpp"> <span class="keyword">class</span> MapsWidgetPrivate
 {
 <span class="keyword">public</span>:
     GeoMap <span class="operator">*</span>map;
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsview.html">QGraphicsView</a></span> <span class="operator">*</span>view;
 };

 <span class="type">void</span> MapsWidget<span class="operator">::</span>initialize(<span class="type"><a href="qgeomappingmanager.html">QGeoMappingManager</a></span> <span class="operator">*</span>manager)
 {
     d<span class="operator">-</span><span class="operator">&gt;</span>map <span class="operator">=</span> <span class="keyword">new</span> GeoMap(manager<span class="operator">,</span> <span class="keyword">this</span>);

     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscene.html">QGraphicsScene</a></span> <span class="operator">*</span>sc <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscene.html">QGraphicsScene</a></span>;
     sc<span class="operator">-</span><span class="operator">&gt;</span>addItem(d<span class="operator">-</span><span class="operator">&gt;</span>map);

     d<span class="operator">-</span><span class="operator">&gt;</span>map<span class="operator">-</span><span class="operator">&gt;</span>resize(<span class="number">300</span><span class="operator">,</span> <span class="number">480</span>);

     d<span class="operator">-</span><span class="operator">&gt;</span>view <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsview.html">QGraphicsView</a></span>(sc<span class="operator">,</span> <span class="keyword">this</span>);
     d<span class="operator">-</span><span class="operator">&gt;</span>view<span class="operator">-</span><span class="operator">&gt;</span>setVisible(<span class="keyword">true</span>);
     d<span class="operator">-</span><span class="operator">&gt;</span>view<span class="operator">-</span><span class="operator">&gt;</span>setInteractive(<span class="keyword">true</span>);

     d<span class="operator">-</span><span class="operator">&gt;</span>map<span class="operator">-</span><span class="operator">&gt;</span>setCenter(<span class="type"><a href="qgeocoordinate.html">QGeoCoordinate</a></span>(<span class="operator">-</span><span class="number">27.5796</span><span class="operator">,</span> <span class="number">153.1</span>));
     d<span class="operator">-</span><span class="operator">&gt;</span>map<span class="operator">-</span><span class="operator">&gt;</span>setZoomLevel(<span class="number">15</span>);
 }</pre>
<p>Doing this in the constructor, while possible, is not the preferred approach, as the <a href="qgeomappingmanager.html">QGeoMappingManager</a> may not be available until the user has chosen it, or until a network connection is available. This is especially important in mobile environments, as we'll see later.</p>
<p>To get an instance of <a href="qgeomappingmanager.html">QGeoMappingManager</a> we use the list of service providers available in <a href="qgeoserviceprovider.html#availableServiceProviders">QGeoServiceProvider::availableServiceProviders</a>(). Service providers provide the ability to fetch and draw maps, search for locations, get directions, and a variety of other tasks.</p>
<p>To test out the MapsWidget we just wrote, we can simply get the first available service provider in the main() function, as follows:</p>
<pre class="cpp"> <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>)
 {
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qapplication.html">QApplication</a></span> a(argc<span class="operator">,</span> argv);

     MapsWidget w;
     w<span class="operator">.</span>show();

     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="http://qt.nokia.com/doc/4.7/qstring.html">QString</a></span><span class="operator">&gt;</span> providers <span class="operator">=</span> <span class="type"><a href="qgeoserviceprovider.html">QGeoServiceProvider</a></span><span class="operator">::</span>availableServiceProviders();
     <span class="type"><a href="qgeoserviceprovider.html">QGeoServiceProvider</a></span> <span class="operator">*</span>serviceProvider <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgeoserviceprovider.html">QGeoServiceProvider</a></span>(providers<span class="operator">[</span><span class="number">0</span><span class="operator">]</span>);

     w<span class="operator">.</span>initialize(serviceProvider<span class="operator">-</span><span class="operator">&gt;</span>mappingManager());

     <span class="keyword">return</span> a<span class="operator">.</span>exec();
 }</pre>
<p>If you compile and run the code so far, you should see a window appear containing a street map of Eight Mile Plains, in Queensland, Australia, rendered by your platform's default geo service provider.</p>
<p class="centerAlign"><img src="images/mapsdemo-verybasic.png" alt="" /></p><a name="pan-zoom"></a>
<h3>Pan &amp; zoom</h3>
<p>Next we'll add some basic pan and zoom capability to the map widget. Like most other classes in Qt, <a href="qgraphicsgeomap.html">QGraphicsGeoMap</a> allows mouse and keyboard events to be handled by private methods.</p>
<p>Into the private section of the GeoMap declaration we add:</p>
<pre class="cpp"> <span class="type">bool</span> panActive;

 <span class="type">void</span> mousePressEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event);
 <span class="type">void</span> mouseReleaseEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event);
 <span class="type">void</span> mouseMoveEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event);</pre>
<p>And their definitions:</p>
<pre class="cpp"> <span class="type">void</span> GeoMap<span class="operator">::</span>mousePressEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event)
 {
     panActive <span class="operator">=</span> <span class="keyword">true</span>;
     event<span class="operator">-</span><span class="operator">&gt;</span>accept();
 }

 <span class="type">void</span> GeoMap<span class="operator">::</span>mouseReleaseEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event)
 {
     panActive <span class="operator">=</span> <span class="keyword">false</span>;
     event<span class="operator">-</span><span class="operator">&gt;</span>accept();
 }

 <span class="type">void</span> GeoMap<span class="operator">::</span>mouseMoveEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event)
 {
     <span class="keyword">if</span> (panActive) {
         <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpointf.html">QPointF</a></span> delta <span class="operator">=</span> event<span class="operator">-</span><span class="operator">&gt;</span>lastPos() <span class="operator">-</span> event<span class="operator">-</span><span class="operator">&gt;</span>pos();
         pan(delta<span class="operator">.</span>x()<span class="operator">,</span> delta<span class="operator">.</span>y());
     }
     event<span class="operator">-</span><span class="operator">&gt;</span>accept();
 }</pre>
<p>These three short methods are enough to add basic panning support to the map. The panning method is a simple mouse-locked one, and moving long distances on a touch screen with it can get quite tedious. Many map applications now make use of &quot;kinetic&quot; panning for a better user experience, especially on touch devices, but in the interests of simplicity, we'll save that for other examples.</p>
<p>Next, to add zoom support on the mouse scrollwheel:</p>
<pre class="cpp"> <span class="type">void</span> GeoMap<span class="operator">::</span>wheelEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscenewheelevent.html">QGraphicsSceneWheelEvent</a></span> <span class="operator">*</span>event)
 {
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> panx <span class="operator">=</span> event<span class="operator">-</span><span class="operator">&gt;</span>pos()<span class="operator">.</span>x() <span class="operator">-</span> size()<span class="operator">.</span>width() <span class="operator">/</span> <span class="number">2.0</span>;
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> pany <span class="operator">=</span> event<span class="operator">-</span><span class="operator">&gt;</span>pos()<span class="operator">.</span>y() <span class="operator">-</span> size()<span class="operator">.</span>height() <span class="operator">/</span> <span class="number">2.0</span>;
     pan(panx<span class="operator">,</span> pany);
     <span class="keyword">if</span> (event<span class="operator">-</span><span class="operator">&gt;</span>delta() <span class="operator">&gt;</span> <span class="number">0</span>) {   <span class="comment">// zoom in</span>
         <span class="keyword">if</span> (zoomLevel() <span class="operator">&lt;</span> maximumZoomLevel()) {
             setZoomLevel(zoomLevel() <span class="operator">+</span> <span class="number">1</span>);
         }
     } <span class="keyword">else</span> {                    <span class="comment">// zoom out</span>
         <span class="keyword">if</span> (zoomLevel() <span class="operator">&gt;</span> minimumZoomLevel()) {
             setZoomLevel(zoomLevel() <span class="operator">-</span> <span class="number">1</span>);
         }
     }
     pan(<span class="operator">-</span>panx<span class="operator">,</span> <span class="operator">-</span>pany);
     event<span class="operator">-</span><span class="operator">&gt;</span>accept();
 }</pre>
<p>This method is a little more complicated. To provide a suitable zoom feel, we have to actually combine panning with zooming, so that the user's point of interest (the mouse cursor) remains in the same part of the view. So, we actually pan the mouse cursor's location into the center, then adjust the zoom level, then pan back at the end.</p>
<a name="map-icons"></a>
<h3>Map icons</h3>
<p>Another important basic feature is the ability to render icons on the map to represent points of interest. The <a href="qgeomappixmapobject.html">QGeoMapPixmapObject</a> class provides most of the functionality necessary to achieve this, and we'll use a subclass of it in similar vein to our GeoMap, above.</p>
<p>For our application, we want to deal with 6 different kinds of icons:</p>
<ul>
<li>A &quot;my location&quot; icon</li>
<li>&quot;Search&quot; icons for search results</li>
<li>User waypoints for direction routes</li>
<li>Start points for directions</li>
<li>End points for directions</li>
<li>&quot;Path&quot; markers for individual steps in the direction route</li>
</ul>
<p>Once again we make use of the Pimpl idiom to separate the private data members from the interface:</p>
<pre class="cpp"> <span class="keyword">class</span> MarkerPrivate;
 <span class="keyword">class</span> Marker : <span class="keyword">public</span> <span class="type"><a href="qgeomappixmapobject.html">QGeoMapPixmapObject</a></span>
 {
     Q_OBJECT
 <span class="keyword">public</span>:
     <span class="keyword">enum</span> MarkerType {
         MyLocationMarker<span class="operator">,</span>
         SearchMarker<span class="operator">,</span>
         WaypointMarker<span class="operator">,</span>
         StartMarker<span class="operator">,</span>
         EndMarker<span class="operator">,</span>
         PathMarker
     };

     <span class="keyword">explicit</span> Marker(MarkerType type);

     <span class="keyword">inline</span> MarkerType markerType() <span class="keyword">const</span> { <span class="keyword">return</span> m_type; }
     <span class="type">void</span> setMarkerType(MarkerType type);

 <span class="keyword">private</span>:
     MarkerPrivate <span class="operator">*</span>d;

 };</pre>
<p>So we can construct Marker instances of different types, but we need QPixmaps to represent each one. In our implementation we will simply use a <tt>switch</tt> statement to map MarkerTypes to QPixmaps.</p>
<pre class="cpp"> <span class="keyword">class</span> MarkerPrivate
 {
 <span class="keyword">public</span>:
     Marker<span class="operator">::</span>MarkerType type;
 };

 Marker<span class="operator">::</span>Marker(MarkerType type) :
     <span class="type"><a href="qgeomappixmapobject.html">QGeoMapPixmapObject</a></span>()
 {
     setMarkerType(type);
 }

 <span class="type">void</span> Marker<span class="operator">::</span>setMarkerType(MarkerType type)
 {
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qstring.html">QString</a></span> filename;
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpoint.html">QPoint</a></span> offset;
     <span class="type">int</span> scale;

     d<span class="operator">-</span><span class="operator">&gt;</span>type <span class="operator">=</span> type;

     <span class="keyword">switch</span> (d<span class="operator">-</span><span class="operator">&gt;</span>type) {
     <span class="keyword">case</span> MyLocationMarker:
         filename <span class="operator">=</span> <span class="string">&quot;:/icons/mylocation.png&quot;</span>;
         <span class="keyword">break</span>;
     <span class="keyword">case</span> SearchMarker:
         filename <span class="operator">=</span> <span class="string">&quot;:/icons/searchmarker.png&quot;</span>;
         <span class="keyword">break</span>;
     <span class="keyword">case</span> WaypointMarker:
         filename <span class="operator">=</span> <span class="string">&quot;:/icons/waypointmarker.png&quot;</span>;
         <span class="keyword">break</span>;
     <span class="keyword">case</span> StartMarker:
         filename <span class="operator">=</span> <span class="string">&quot;:/icons/startmarker.png&quot;</span>;
         <span class="keyword">break</span>;
     <span class="keyword">case</span> EndMarker:
         filename <span class="operator">=</span> <span class="string">&quot;:/icons/endmarker.png&quot;</span>;
         <span class="keyword">break</span>;
     <span class="keyword">case</span> PathMarker:
         filename <span class="operator">=</span> <span class="string">&quot;:/icons/pathmarker.png&quot;</span>;
         <span class="keyword">break</span>;
     }

     <span class="keyword">if</span> (d<span class="operator">-</span><span class="operator">&gt;</span>type <span class="operator">=</span><span class="operator">=</span> MyLocationMarker) {
         offset <span class="operator">=</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpoint.html">QPoint</a></span>(<span class="operator">-</span><span class="number">13</span><span class="operator">,</span><span class="operator">-</span><span class="number">13</span>);
         scale <span class="operator">=</span> <span class="number">25</span>;
     } <span class="keyword">else</span> {
         offset <span class="operator">=</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpoint.html">QPoint</a></span>(<span class="operator">-</span><span class="number">15</span><span class="operator">,</span> <span class="operator">-</span><span class="number">36</span>);
         scale <span class="operator">=</span> <span class="number">30</span>;
     }

     setOffset(offset);
     setPixmap(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qpixmap.html">QPixmap</a></span>(filename)<span class="operator">.</span>scaledToWidth(scale<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qt.html">Qt</a></span><span class="operator">::</span>SmoothTransformation));
 }</pre>
<p>The icon PNG images can be found in the <tt>examples/mapsdemo/icons</tt> directory in the QtMobility distribution. All we have to do to have this working is simply add the PNG icons to a <tt>.qrc</tt> file and add it to the project.</p>
<p>The QGraphicsGeoMap::addMapObject method is used to add markers to a map. We can add a call to create a marker at our starting point into MapsWidget::initialize() as a demonstration:</p>
<pre class="cpp"> <span class="comment">// in MapsWidget::initialize()</span>
 Marker <span class="operator">*</span>me <span class="operator">=</span> <span class="keyword">new</span> Marker(Marker<span class="operator">::</span>MyLocationMarker);
 me<span class="operator">-</span><span class="operator">&gt;</span>setCoordinate(<span class="type"><a href="qgeocoordinate.html">QGeoCoordinate</a></span>(<span class="operator">-</span><span class="number">27.5796</span><span class="operator">,</span> <span class="number">153.1</span>));
 geoMap<span class="operator">-</span><span class="operator">&gt;</span>addMapObject(me);</pre>
<p>Build and start the application, and we now have a &quot;My Location&quot; icon in the centre of the initial view.</p>
<p>This now concludes the basic functionality of the map widget. We'll be making a few modifications and improvements to it as we go along, but the basic skeleton will remain the same.</p>
<p>Next, we'll add a basic GUI around the map widget, and the ability to search for locations like addresses.</p>
</div>
<!-- @@@tutorials-mapsdemo-part1.html -->
<p class="naviNextPrevious footerNavi">
<a class="prevPage" href="tutorials-mapsdemo.html">Maps Demo Tutorial</a>
<a class="nextPage" href="tutorials-mapsdemo-part2.html">Part 2 - Searching for locations</a>
</p>
  <div class="ft">
    <span></span>
  </div>
</div> 
<div class="footer">
  <p>
     <acronym title="Copyright">&copy;</acronym> 2008-2011 Nokia Corporation and/or its
     subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation 
     in Finland and/or other countries worldwide.</p>
  <p>
     All other trademarks are property of their respective owners. <a title="Privacy Policy"
     href="http://qt.nokia.com/about/privacy-policy">Privacy Policy</a></p>
  <br />
  <p>
    Licensees holding valid Qt Commercial licenses may use this document in accordance with the    Qt Commercial License Agreement provided with the Software or, alternatively, in accordance    with the terms contained in a written agreement between you and Nokia.</p>
  <p>
    Alternatively, this document may be used under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU
    Free Documentation License version 1.3</a>
    as published by the Free Software Foundation.</p>
</div>
</body>
</html>