Android地图开发之OpenStreetMap基础教程


【注意】由于OpenStreetMap此类教程在国内不太多,本文是本人花费多日通过一些国外网站论坛总结所得,如要转载,请保留文章出处,尊重一下作者,谢谢。


开端

本文皆在指引大家在自己的项目里嵌入OpenStreetMap,并可以在地图上添加覆盖物、折线等常用地图功能。


1.0 OSM地图简介

the project that creates and provides free geographic data and mapping to anyone who wants it. We started it because most maps you think of as free actually have legal or technical restrictions on their use, holding back people from using them in creative, productive, or unexpected ways这就是Wiki给出的介绍,其实这些东西在google上随便一搜就有的,大致的概念了解一下就OK了,说白了就是一个开源的 地图,使用起来和baidu、高德、google等地图几乎一样的效果。

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);
效果图:

初始化后,地图可以正常显示,双指可以缩放地图比例尺,但是就是不能上下左右平移地图,也就是说只能在这个区域缩放,无法移动,下载了官方链接里的openStreetMapViewer.apk,地图确实可以正常移动使用,至今无法确定具体原因,没有找到能移动的动作事件监听接口。

1.4 ItemizedOverlayWithFocus(overlay)

添加一个ItemizedOerlayWithFoucs类型的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);   
效果图:


可以添加自定义的Overlay,设置image。但是如代码中所示,实现了OnItemGestureListener接口,并返回true,但是单击(SingleTap)或长按(LongPress)makrer始终无法触发回调函数,这样就没办法显示自定义的吹出框了。官方的.apk可以触发此事件,实现方式和示例代码一样,目前还未确定是哪里的问题。

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.csdn.net/detail/mad1989/5864355


130803




  • 14
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 42
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值