前置準備Preparation
Mapsforge是一個很棒的Vector Map Library,相信讀者一定很想要趕快著手開發 但在開始前需要先準備好一些東西
API部分
- mapsforge-core: 這是Mapsforge的核心Library所有相關Mapsforge的Library都是以他為基礎
- mapsforge-map: 這個是負責Mapsforge中地圖相關處裡的Library
- mapsforge-map-android: 這個Library中提供了一些如MapView, AndroidGraphicFactory等讓Android可以充分使用Mapsforge的物件
- mapsforge-map-reader: 這個Mapsforge的.map檔的解析器Library
圖資部分
這個範例是離線地圖,所以首先你需要2個圖資- 1. world-lowres-0-7.map
- 2. taiwan.map
- 1. mapsforge/maps/world/world-lowres-0-7.map
- 2. mapsforge/maps/asia/taiwan.map
範例程式Sample(本範例所使用的Mapsforge版本為0.6.0-rc1)
SampleMapView.java
import android.app.Activity;
import android.os.Bundle;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.MapPosition;
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
import org.mapsforge.map.android.util.AndroidUtil;
import org.mapsforge.map.android.view.MapView;
import org.mapsforge.map.datastore.MapDataStore;
import org.mapsforge.map.datastore.MultiMapDataStore;
import org.mapsforge.map.layer.cache.TileCache;
import org.mapsforge.map.layer.renderer.TileRendererLayer;
import org.mapsforge.map.reader.MapFile;
import org.mapsforge.map.rendertheme.InternalRenderTheme;
import java.io.File;
/**
* Created by lienching on 10/17/15.
*/
public class SimpleMapView extends Activity {
private MapView mapView;
private MultiMapDataStore multiMapDataStore;
private MapDataStore worldMap,taiwanMap;
private TileCache tileCache;
private TileRendererLayer tileRendererLayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidGraphicFactory.createInstance(this.getApplication());//使用Mapsforge Library必須呼叫此方法來初始化
mapView = new MapView(this);
mapView.setClickable(true);
mapView.getMapScaleBar().setVisible(true);
mapView.setBuiltInZoomControls(true);
mapView.getMapZoomControls().setZoomLevelMin((byte) 5);
mapView.getMapZoomControls().setZoomLevelMax((byte) 20);
worldMap = new MapFile(new File(Constant.PATH_WORLDMAP));
taiwanMap = new MapFile(new File(Constant.PATH_TAIWANMAP));
multiMapDataStore = new MultiMapDataStore(MultiMapDataStore.DataPolicy.RETURN_ALL);
tileCache = AndroidUtil.createTileCache(this, "mapcache", mapView.getModel().displayModel.getTileSize(), 1f, this.mapView.getModel().frameBufferModel.getOverdrawFactor());
setContentView(mapView);
}
@Override
protected void onStart() {
super.onStart();
multiMapDataStore.addMapDataStore(worldMap,true,true);
multiMapDataStore.addMapDataStore(taiwanMap,false,false);
//multiMapDataStore.setStartPosition(new LatLong(23, 121));
//multiMapDataStore.setStartZoomLevel((byte) 7);
tileRendererLayer = new TileRendererLayer(tileCache,multiMapDataStore,mapView.getModel().mapViewPosition,false,true, AndroidGraphicFactory.INSTANCE);
tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.OSMARENDER);
mapView.getModel().mapViewPosition.setMapPosition(new MapPosition(new LatLong(23, 121), (byte) 7));
mapView.getLayerManager().getLayers().add(tileRendererLayer);
}
@Override
protected void onDestroy() {
super.onDestroy();
this.mapView.destroyAll();
}
}
Constant.java
import android.os.Environment;
/**
* Created by lienching on 10/19/15.
*/
public class Constant {
private static final String PATH_MAPSFORGE = Environment.getExternalStorageDirectory().toString() + "/mapsforge/maps/";
public static final String PATH_WORLDMAP = PATH_MAPSFORGE + "world/world-lowres-0-7.map";
public static final String PATH_TAIWANMAP = PATH_MAPSFORGE + "asia/taiwan.map";
}
Q&A
1. 如果我很懶,我有甚麼辦法可以讓App自己下載圖資呢?
那妳可以建立一個專門下載圖資的類別,範例如下
import android.app.DownloadManager;
import android.content.Context;
import android.net.Uri;
import android.os.Environment;
/**
* Created by lienching on 10/14/15.
* The purpose of this class is to define the map resource download methods, so we
* can easily download a map resource by this class.
*/
public class MapDownloadManager{
private DownloadManager downloadManager;
private DownloadManager.Request request;
private String external_path = Environment.getExternalStorageDirectory().toString();
private Context context;
public MapDownloadManager(Context context){
this.context = context;
downloadManager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
}
public void downloadMapResource(String mapfile){
Uri download_URI = Uri.parse("http://download.mapsforge.org/maps/"+mapfile);
request = new DownloadManager.Request(download_URI);
//Set the network type which is allow to process the download request
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
//Set whether this download may proceed over a roaming connection.
request.setAllowedOverRoaming(false);
request.setTitle("Mapsforge Map Download");
request.setDestinationInExternalPublicDir("/mapsforge/maps/",mapfile);
downloadManager.enqueue(request);
}
}
之後只要在主類別中呼叫就能使用囉~