Using the MAP Library
The Mosync MAP library is a standard library that provides a MapWidget for displaying geographical maps, sometimes called slippy or panning maps, consisting of tiles provided by a map source. This guide introduces the basics of the MAP library and shows you how to create map applications from scratch.
Important: MoSync 2.5 includes an improved MAP Library. If you want to compile in MoSync 2.5 an existing application that uses the 2.4 MAP Library you will need to update that application. See Migrating to the 2.5 MAP Library.
Introduction
At the heart of the MAP Library is MapWidget.
You can use it as is, or extend it to overlay information on top of the
map. The library contains map classes for using one or more tile-based
map servers such as OpenStreetMap, CloudMade, and Google Maps.
Latitude
and longitude co-ordinates can be converted to meters and pixels (both
global and device). Connection to a location-aware sensor is performed
by the client, and is outside of the scope of the library itself.
The primary public map source is OpenStreetMap (openstreetmap.org).
There is a working hook into Google Static Maps; however use of Google
Static Maps requires a license agreement with Google, so this is more of
a code sample.
Example Programs
There are two examples programs you can use to study the use of the MAP Library:
- HelloMap is a simple Moblet that displays an OpenStreetMap across the entire device screen. The user can use the phone keys to pan the map and to zoom in and out. The core of the HelloMap sample application is in HelloMapScreen.cpp.
- MapDemo is a more full-blown example that illustrates the use of the map library in an application.
These examples are written using a memory tracker to allocate and deallocate memory. This makes the code a little more complex than is strictly necessary, but will prove useful if you want to use a memory tracker in your application.
The MAP Library
The Map Library provides classes for downloading, managing and displaying map tiles. The library includes:
- MapSource is a base class with implementations for OpenStreetMap, Google Static Maps, CloudMade, as well as an extensible API for other map sources.
- MapWidget is a class for displaying a slippy map in a Mosync Moblet-based application. MapWidget uses class MapViewport to handle panning and zooming of the map.
- Tile management and caching classes, notably the MapCache class which is a singleton that provides map tiles.
- Utility and support classes.
Important MAP classes
| MapSource | Abstract base class for provider of map tiles |
| CloudMadeMapSource | MapSource using CloudMade public map tile server |
| GoogleMapSource | MapSource using Google Static Maps as map tile server |
| OpenStreetMapSource | MapSource using OpenStreetMap tile server |
| MapCache | Caches tiles provided by MapSource |
| MapTile | Single tile from MapSource |
| LonLat | Coordinate class |
| PixelCoordinate | Global map pixel coordinate at a specified magnification |
| MapTileCoordinate | Describes a tile’s position in global grid of tiles at a certain magnification |
| MapWidget | Widget displaying slippy map |
| MapViewport | Handles panning and zooming of the map |
| DateTime | Utility class for date |
| Timespan | Utility class for time span |
| MemoryMgr | Utility class for heap resource tracking for debugging |
| Broadcaster | Utility template class for broadcasting to multiple listeners |
| Queue | Utility template class for a simple object queue |
| DebugPrintf | Utility functions for debug output under MSVC compiler |
How to use map sources
Include the header files for the map sources you wish to use, for example:
#include <MAP/OpenStreetMapSource.h> #include <MAP/GoogleMapSource.h>
Generally, it is a good idea to use instance variables in your class to refer to the map sources, for example:
MapSource* mOpenStreetMapSource; MapSource* mGoogleStreetMapSource; MapSource* mGoogleAerialMapSource; MapSource* mGoogleHybridMapSource;
The map library comes with two map sources that have been set up for you, OpenStreetMap and GoogleMaps. Here is how to create and set up map sources:
mOpenStreetMapSource = new OpenStreetMapSource(); mGoogleStreetMapSource = new GoogleMapSource(GoogleMapKind_StreetMap); mGoogleAerialMapSource = new GoogleMapSource(GoogleMapKind_Aerial); mGoogleHybridMapSource = new GoogleMapSource(GoogleMapKind_Hybrid);
Set the current map source like this:
mMapWidget->setMapSource(mGoogleAerialMapSource);
Basic example
This is a bare-bones application with touch interaction -- single touch and drag pans the map; a second touch zooms in a fixed step while pressed, and zooms out when released.
#include <MAUtil/Moblet.h>
#include <MAUI/Screen.h>
#include <MAP/MapWidget.h>
#include <MAP/OpenStreetMapSource.h>
using namespace MAUtil;
using namespace MAUI;
using namespace MAP;
class MapMoblet : public Moblet
{
public:
MapMoblet()
{
mMapWidget = new MapWidget(
0,
0,
EXTENT_X(maGetScrSize()),
EXTENT_Y(maGetScrSize()),
NULL);
// Create a MapViewport for the MapWidget.
// The MapWidget will deallocate the viewport upon destruction.
mMapWidget->setViewport(new MapViewport());
mOpenStreetMapSource = new OpenStreetMapSource();
mMapWidget->setMapSource(mOpenStreetMapSource);
mMapWidget->getViewport()->setCenterPosition(
LonLat(18.07, 59.33), // Position for Stockholm.
true, // Redraw now.
false // Not called from pointer event.
);
// Magnification level (logarithmic scale).
mMagnification = 11.0;
setMagnification(mMagnification);
mScreen = new Screen();
mScreen->setMain(mMapWidget);
mScreen->show();
}
virtual ~MapMoblet()
{
delete mScreen;
delete mMapWidget;
delete mOpenStreetMapSource;
}
void keyPressEvent(int keyCode, int nativeCode)
{
if (MAK_BACK == keyCode || MAK_0 == keyCode)
{
close();
}
}
void multitouchPressEvent(MAPoint2d point, int touchId)
{
if (0 == touchId)
{
beginPanning(point);
}
else if (1 == touchId)
{
zoomIn();
}
}
void multitouchMoveEvent(MAPoint2d point, int touchId)
{
if (0 == touchId)
{
updatePanning(point);
}
}
void multitouchReleaseEvent(MAPoint2d point, int touchId)
{
if (0 == touchId)
{
endPanning();
}
else if (1 == touchId)
{
zoomOut();
}
}
void beginPanning(MAPoint2d point)
{
mMapWidget->getViewport()->beginPanning(point);
}
void updatePanning(MAPoint2d point)
{
mMapWidget->getViewport()->updatePanning(point);
}
void endPanning()
{
mMapWidget->getViewport()->endPanning();
}
void zoomIn()
{
mMagnification += 3.0;
setMagnification(mMagnification);
}
void zoomOut()
{
mMagnification -= 3.0;
setMagnification(mMagnification);
}
void setMagnification(double magnification)
{
mMapWidget->getViewport()->setMagnification(
MagnificationType(magnification));
}
private:
Screen* mScreen;
MapWidget* mMapWidget;
MapSource* mOpenStreetMapSource;
double mMagnification;
};
extern "C" int MAMain()
{
// Optionally, for example if you encounter memory problems, you can
// experiment with the size of the tile cache. Set the cache size like this:
//MapCache::get()->setCapacity(30);
Moblet* moblet = new MapMoblet();
Moblet::run(moblet);
delete moblet;
MapCache::shutdown();
return 0;
}Migrating to the 2.5 MAP Library
To
be able to compile them with MoSync SDK 2.5, existing applications that
use an older versions of the MAP Library need to be updated, since the
new API is not backwards compatible. Here we explain how to update your
existing code.
The
major change in the API is how map sources are represented. A map
source is a map provider, like OpenStreetMap or GoogleMaps. The old API
used a predefined enumeration of map providers. The new API, by
contrast, uses a more flexible model where the application can define
map source providers.
Initialize/shutdown
MoSync 2.4 and earlier:
MapMoblet* moblet = new MapMoblet(); Moblet::run(moblet); delete moblet;
MoSync 2.5:
// Create and run the moblet in the same way as before. MapMoblet* moblet = new MapMoblet(); Moblet::run(moblet); delete moblet; // Free resources allocated by the Map cache. MapCache::shutdown();
Header files
The header files for the map source has been changed.
MoSync 2.4 and earlier:
// This header file has been removed from the new map library. #include <MAP/MapSourceMgr.h>
MoSync 2.5:
#include <MAP/MapSource.h> // Typically you include only the header files for the map sources you // wish to use, for example: #include <MAP/OpenStreetMapSource.h> #include <MAP/GoogleMapSource.h>
Using map sources
The MapSourceKind enumeration is replaced by map source classes.
MoSync 2.4 and earlier:
MapSourceKind mMapSourceKind;
MoSync 2.5:
MapSource* mOpenStreetMapSource; MapSource* mGoogleStreetMapSource; MapSource* mGoogleAerialMapSource; MapSource* mGoogleHybridMapSource;
Create the MapWidget
MoSync 2.4 and earlier:
mMapWidget = new MapWidget(0, 0, width, height, NULL);
MoSync 2.5:
// You need to create a MapViewport for the MapWidget. // The MapWidget will deallocate the viewport upon destruction. mMapWidget = new MapWidget(0, 0, width, height, NULL); mMapWidget->setViewport(new MapViewport());
How to create/set the map source
MoSync 2.4 and earlier:
// In the old API an enumeration constant was used to // specify the map source (this was inflexible). mMapWidget->setMapSourceKind(MapSourceKind_OpenStreetMap);
MoSync 2.5:
// In the new API, the application can create the map source, // which is a more flexible approach. The map library comes // with two map sources that have been set up for you, // OpenStreetMap and GoogleMaps. This is how to create and // set these map sources: mOpenStreetMapSource = new OpenStreetMapSource(); mGoogleStreetMapSource = new GoogleMapSource(GoogleMapKind_StreetMap); mGoogleAerialMapSource = new GoogleMapSource(GoogleMapKind_Aerial); mGoogleHybridMapSource = new GoogleMapSource(GoogleMapKind_Hybrid); // Set the map source like this: mMapWidget->setMapSource(mGoogleAerialMapSource);
- Printer-friendly version
- Login or register to post comments
Share on Facebook