gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15945
  • QQ554730525
  • 铜币25337枚
  • 威望15352点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
阅读:2281回复:0

Android地图开发之OpenStreetMap基础教程

楼主#
更多 发布于:2015-07-09 00:05
开端
本文皆在指引大家在自己的项目里嵌入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:


[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.    android:layout_width="fill_parent"  
  4.    android:layout_height="fill_parent" >  
  5.  
  6.    <org.osmdroid.views.MapView  
  7.        android:id="@+id/myOSMmapview"  
  8.        android:layout_width="match_parent"  
  9.        android:layout_height="match_parent"  
  10.        tilesource="MapquestOSM"  
  11.        android:clickable="true"  
  12.        android:enabled="true" >  
  13.    </org.osmdroid.views.MapView>  
  14.  
  15. </RelativeLayout>  
osm.java:

[java] view plaincopy
  1. 示例代码:  
  2.        mMapView = (MapView) findViewById(R.id.myOSMmapview);  
  3.        mController = mMapView.getController();  
  4.        //ResourceProxy init  
  5.        mResourceProxy = new DefaultResourceProxyImpl(this);  
  6.        mMapView.setTileSource(TileSourceFactory.MAPNIK);  
  7.        mMapView.setBuiltInZoomControls(true);  
  8.        mMapView.setMultiTouchControls(true);  
  9.        //定位当前位置,北京市西长安街复兴路  
  10.        GeoPoint center = new GeoPoint(39.901873, 116.326655);  
  11.        mController.setCenter(center);  
  12.        mController.setZoom(14);  
效果图:
初始化后,地
图可以正常显示,双指可以缩放地图比例尺,但是就是不能上下左右平移地图,也就是说只能在这个区域缩放,无法移动,下载了官方链接里的
openStreetMapViewer.apk,地图确实可以正常移动使用,至今无法确定具体原因,没有找到能移动的动作事件监听接口。
 

 


1.4 ItemizedOverlayWithFocus(overlay)

添加一个ItemizedOerlayWithFoucs类型的overlay


[java] view plaincopy
  1. 示例代码:  
  2.        //添加自定义image Overlay  
  3.        Drawable drawable = this.getResources().getDrawable(  
  4.                R.drawable.marker_gpsvalid);  
  5.        ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();  
  6.        OverlayItem item = new OverlayItem("~title~", "I`m a marker,a subtitile", center);  
  7.        item.setMarker(drawable);  
  8.        items.add(item);  
  9.          
  10.        this.mLocationOverlay = new ItemizedOverlayWithFocus<OverlayItem>(    
  11.                items,    
  12.                new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {    
  13.                    @Override    
  14.                    public boolean onItemSingleTapUp(final int index,    
  15.                            final OverlayItem item) {    
  16.                        return true;    
  17.                    }    
  18.  
  19.                    @Override    
  20.                    public boolean onItemLongPress(final int index,    
  21.                            final OverlayItem item) {    
  22.                        return false;    
  23.                    }    
  24.                }, mResourceProxy);    
  25.        this.mLocationOverlay.setFocusItemsOnTap(true);  
  26.        this.mLocationOverlay.setFocusedItem(0);    
  27.        mMapView.getOverlays().add(mLocationOverlay);    
效果图:

 

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

1.5 自定义Overlay



[java] view plaincopy
  1. 示例代码:  
  2.        //自定义marker图层  
  3.        ArrayList<OverlayItem> markers = new ArrayList<OverlayItem>();  
  4.        OverlayItem one = new OverlayItem("~one~", "custom marker", gp1);  
  5.        one.setMarker(drawable);  
  6.        markers.add(one);  
  7.        CustomMarker marker = new CustomMarker(markers, gestureListener, mResourceProxy);  
  8.        mMapView.getOverlays().add(marker);  
  9.        mController.setCenter(gp1);  
  10.        mMapView.invalidate();  
  11. 自定义Overlay:  
  12.    /**
  13.     * 自定义Marker
  14.     * @author Administrator
  15.     *
  16.     */  
  17.    public class CustomMarker  extends ItemizedOverlayWithFocus<OverlayItem> implements org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener<OverlayItem>{  
  18.        public CustomMarker(  
  19.                List<OverlayItem> aList,  
  20.                org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener<OverlayItem> aOnItemTapListener,  
  21.                ResourceProxy pResourceProxy) {  
  22.            super(aList, aOnItemTapListener, pResourceProxy);  
  23.        }  
  24.          
  25.        @Override  
  26.        public void addItem(int location, OverlayItem item) {  
  27.            super.addItem(location, item);  
  28.        }  
  29.        @Override  
  30.        protected boolean onTap(int index) {  
  31.            return super.onTap(index);  
  32.        }  
  33.        @Override  
  34.        public boolean onSingleTapUp(MotionEvent event, MapView mapView) {  
  35.            return super.onSingleTapUp(event, mapView);  
  36.        }  
  37.        @Override  
  38.        public int size() {  
  39.            return super.size();  
  40.        }  
  41.  
  42.        @Override  
  43.        public boolean onItemLongPress(int arg0, OverlayItem arg1) {  
  44.            return true;  
  45.        }  
  46.  
  47.        @Override  
  48.        public boolean onItemSingleTapUp(int arg0, OverlayItem arg1) {  
  49.            return true;  
  50.        }  
  51.          
  52.    }  

 效果图:

 

 


1.6 MinimapOverlay(小地图)




[java] view plaincopy
  1. 示例代码:  
  2.                   //右下角小地图Overlay  
  3.                   MinimapOverlayoverlay = new MinimapOverlay(this,  
  4.                                     mMapView.getTileRequestCompleteHandler());  
  5.                   mMapView.getOverlays().add(overlay);  
效果图:


1.7PathOverlay(画线)和SimpleLocationOverlay




[java] view plaincopy
  1. 示例代码:  
  2.        //PathOverlay 路线Overlay  
  3.        GeoPoint gp1 = new GeoPoint(40.067225, 116.369758);  
  4.        GeoPoint gp2 = new GeoPoint(40.064808, 116.346362);  
  5.        GeoPoint gp3 = new GeoPoint(40.058669, 116.336648);  
  6.        GeoPoint gp4 = new GeoPoint(40.036685, 116.343619);  
  7.        GeoPoint gp5 = new GeoPoint(40.036368, 116.327699);  
  8.          
  9.        PathOverlay line = new PathOverlay(Color.BLUE, this);  
  10.        line.addPoint(gp1);  
  11.        line.addPoint(gp2);  
  12.        line.addPoint(gp3);  
  13.        line.addPoint(gp4);  
  14.        line.addPoint(gp5);  
  15.        mMapView.getOverlays().add(line);  
  16.        mController.setCenter(gp1);  
  17.        //Simple图层  
  18.        SimpleLocationOverlay simpleLocation = new SimpleLocationOverlay(this);  
  19.        simpleLocation.setEnabled(true);  
  20.        simpleLocation.setLocation(gp5);  
  21.        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
喜欢0 评分0
游客

返回顶部