【注意】由于OpenStreetMap此类教程在国内不太多,本文是本人花费多日通过一些国外网站论坛总结所得,如要转载,请保留文章出处,尊重一下作者,谢谢。
开端
本文皆在指引大家在自己的项目里嵌入OpenStreetMap,并可以在地图上添加覆盖物、折线等常用地图功能。
1.0 OSM地图简介
1.1 API和文档
osm android版 : https://code.google.com/p/osmdroid/
osm android官方简介:http://wiki.openstreetmap.org/wiki/Android#OpenStreetMap_editing_features
osm 官方入口:http://wiki.openstreetmap.org/wiki/Main_Page
wiki 开发FAQ:http://wiki.openstreetmap.org/wiki/Developer_FAQ#Do_you_have_an_API.3F
osm tracker 简介:https://code.google.com/p/osmtracker-android/
1.2osmroid-android-3.0.10.jar
从openstreetmap android版官方网站下载jar包:osmroid-android-3.0.10.jar和slf4j-api-1.7.2.jar包,前者是地图库后者是个输出日志库,因为地图类库里使用到了,所以两者缺一不可。
1.3地图实例化
layout.xml:
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<org.osmdroid.views.MapView
android:id="@+id/myOSMmapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tilesource="MapquestOSM"
android:clickable="true"
android:enabled="true" >
</org.osmdroid.views.MapView>
</RelativeLayout>
osm.java:
示例代码:
mMapView = (MapView) findViewById(R.id.myOSMmapview);
mController = mMapView.getController();
//ResourceProxy init
mResourceProxy = new DefaultResourceProxyImpl(this);
mMapView.setTileSource(TileSourceFactory.MAPNIK);
mMapView.setBuiltInZoomControls(true);
mMapView.setMultiTouchControls(true);
//定位当前位置,北京市西长安街复兴路
GeoPoint center = new GeoPoint(39.901873, 116.326655);
mController.setCenter(center);
mController.setZoom(14);
效果图:
1.4 ItemizedOverlayWithFocus(overlay)
示例代码:
//添加自定义image Overlay
Drawable drawable = this.getResources().getDrawable(
R.drawable.marker_gpsvalid);
ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
OverlayItem item = new OverlayItem("~title~", "I`m a marker,a subtitile", center);
item.setMarker(drawable);
items.add(item);
this.mLocationOverlay = new ItemizedOverlayWithFocus<OverlayItem>(
items,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
@Override
public boolean onItemSingleTapUp(final int index,
final OverlayItem item) {
return true;
}
@Override
public boolean onItemLongPress(final int index,
final OverlayItem item) {
return false;
}
}, mResourceProxy);
this.mLocationOverlay.setFocusItemsOnTap(true);
this.mLocationOverlay.setFocusedItem(0);
mMapView.getOverlays().add(mLocationOverlay);
效果图:
1.5 自定义Overlay
示例代码:
//自定义marker图层
ArrayList<OverlayItem> markers = new ArrayList<OverlayItem>();
OverlayItem one = new OverlayItem("~one~", "custom marker", gp1);
one.setMarker(drawable);
markers.add(one);
CustomMarker marker = new CustomMarker(markers, gestureListener, mResourceProxy);
mMapView.getOverlays().add(marker);
mController.setCenter(gp1);
mMapView.invalidate();
自定义Overlay:
/**
* 自定义Marker
* @author Administrator
*
*/
public class CustomMarker extends ItemizedOverlayWithFocus<OverlayItem> implements org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener<OverlayItem>{
public CustomMarker(
List<OverlayItem> aList,
org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener<OverlayItem> aOnItemTapListener,
ResourceProxy pResourceProxy) {
super(aList, aOnItemTapListener, pResourceProxy);
}
@Override
public void addItem(int location, OverlayItem item) {
super.addItem(location, item);
}
@Override
protected boolean onTap(int index) {
return super.onTap(index);
}
@Override
public boolean onSingleTapUp(MotionEvent event, MapView mapView) {
return super.onSingleTapUp(event, mapView);
}
@Override
public int size() {
return super.size();
}
@Override
public boolean onItemLongPress(int arg0, OverlayItem arg1) {
return true;
}
@Override
public boolean onItemSingleTapUp(int arg0, OverlayItem arg1) {
return true;
}
}
效果图:
1.6 MinimapOverlay(小地图)
示例代码:
//右下角小地图Overlay
MinimapOverlayoverlay = new MinimapOverlay(this,
mMapView.getTileRequestCompleteHandler());
mMapView.getOverlays().add(overlay);
效果图:
1.7PathOverlay(画线)和SimpleLocationOverlay
示例代码:
//PathOverlay 路线Overlay
GeoPoint gp1 = new GeoPoint(40.067225, 116.369758);
GeoPoint gp2 = new GeoPoint(40.064808, 116.346362);
GeoPoint gp3 = new GeoPoint(40.058669, 116.336648);
GeoPoint gp4 = new GeoPoint(40.036685, 116.343619);
GeoPoint gp5 = new GeoPoint(40.036368, 116.327699);
PathOverlay line = new PathOverlay(Color.BLUE, this);
line.addPoint(gp1);
line.addPoint(gp2);
line.addPoint(gp3);
line.addPoint(gp4);
line.addPoint(gp5);
mMapView.getOverlays().add(line);
mController.setCenter(gp1);
//Simple图层
SimpleLocationOverlay simpleLocation = new SimpleLocationOverlay(this);
simpleLocation.setEnabled(true);
simpleLocation.setLocation(gp5);
mMapView.getOverlays().add(simpleLocation);
效果图:
黄色的小人便是simpleLocationOverlay
1.8离线地图
OpenStreetMap可以使用离线地图,使用一个工具抓取GoogleMap,然后制作成压缩包放在SK卡osmdroid下就可以使用了。
所需的工具:
1.Mobile Atlas Creator:
注意,1.8版本的能抓取 google map的地图数据。在Map source中选 Google Maps
然后选择需要抓取的zoom levels,地图上选好抓取的区域,add selection之后Format选择Osmdroid ZIP(方便assets拷贝到sdcard中)。
生成一个zip文件,放入app项目的assets中。之后app需要把这个文件拷贝到sdcard/osmdroid目录下,此zip文件中应该包括一个Google Maps的文件夹。
2.osmdroid
注意:
保持mapView.setTileSource(new OnlineTileSourceBase("GoogleMaps",...
这里的参数与zip文件中的文件夹名相同。当希望用online mode用到自己的tile时需要把zip文件解压到sdcard/osmdroid/tiles文件夹下,并且给每个png文件增加.tile,例如new OnlineTIleSourceBase时参数为“Google Maps”,sdcard/osmdroid/tiles文件夹下就应该有一个Google Maps文件,里面包括每个zoomlevel的文件夹。可用Mobile Atlas Creator直接生成 Osmtracker tile storage的format,效果如下:
1.9路径规划
自带的jar包没有包含路线导航相关功能,需要使用开源项目OSMBonusPack实现线路和气泡等相关功能。
下载地址:
https://code.google.com/p/osmbonuspack/downloads/detail?name=osmbonuspack_3.0.jar&can=4&q=
OSMBonusPack中几个重要的特性:
* 1.根据地点名称查询POI
* 2.查询附近的POI
* 3.根据起始点规划线路
* 4.marker气泡重写和定制
* 5.地图poi点的响应处理
OpenStreetMap是一个开源的地图,任何人可以进行编辑,不需要使用key,可以实现覆盖物、折线、多边形、路径规划、POI查询等常用功能,不过不像googleMap 百度Map,有一个统一的地图资源库,导入jar包,直接使用各功能类。若要实现路径规划、poi查询等功能,还需要导入其它的关联类库。
使用起来还有很多的问题,想要继续了解,大家还是多看看源码较好,国内资源太少,要看只能找国外的网站。
slf4j-api-1.7.2.jar
osmdroid-android-3.0.10.jar
osmbonuspack_v3.6.jar
OpenStreetMapViewer-3.0.10-aligned.apk
3个必备jar包+1个官方预览版apk,一起放到了我的资源里,欢迎大家下载:
http://download.youkuaiyun.com/detail/mad1989/5864355
130803