建议从这篇博客读起,本文只是在大神的基础上对一些不明白的东西进行了整理,不做具体的分类,内容在代码注释里有详细的解释
项目成果
项目目录结构
布局文件
<?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"
>
</org.osmdroid.views.MapView>
<!-- android:clickable="true"
android:enabled="true"
一开始是无法移动的,把这两个属性去掉就可以移动了 -->
</RelativeLayout>
清单文件的权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
GoogleChinaTileSource.java
这个文件截取在某个demo里,具体来源记不清了。他的作用是给应用提供一个地图瓦片资源。因为我在实现文中博客的时候,并没有出现对应的地图,只有灰色的格子。一开始我以为是VPN的问题,后来发现不是,又搜了一些其他的资料,不得不说,国内在这方面做的资料确实不多。我猜测有两个原因:
- 地图资源不对
//mMapView.setTileSource(TileSourceFactory.MAPNIK); 本来是这个
mMapView.setTileSource(new GoogleChinaTileSource()); //我换成了这个,结果成功显示了
- 没有设置代理
//重要!设置你的用户代理,以防止被osm服务器禁止(在这里设置没有成功),具体内容可以查看我的上一篇博客
org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants.setUserAgentValue(BuildConfig.DEBUG); //这个报错,因为在BuildConfig中并没有发现按这个变量,
或许自己创建或者从哪申请?
public class GoogleChinaTileSource extends OnlineTileSourceBase {
private static final String[] BASE_URL = {
"http://mt0.google.cn/vt/lyrs=m@6250000&hl=zh-CN&gl=CN&src=app&expIds=201527&rlbl=1&s=Gali&x=%d&y=%d&z=%d",
"http://mt1.google.cn/vt/lyrs=m@6250000&hl=zh-CN&gl=CN&src=app&expIds=201527&rlbl=1&s=Gali&x=%d&y=%d&z=%d",
"http://mt2.google.cn/vt/lyrs=m@6250000&hl=zh-CN&gl=CN&src=app&expIds=201527&rlbl=1&s=Gali&x=%d&y=%d&z=%d",
"http://mt3.google.cn/vt/lyrs=m@6250000&hl=zh-CN&gl=CN&src=app&expIds=201527&rlbl=1&s=Gali&x=%d&y=%d&z=%d" };
private static final String NAME = "Google Map China(Ditu)";
public GoogleChinaTileSource() {
super(NAME, string.bing, 0, 19, 256, ".png", BASE_URL);
}
@Override
public String getTileURLString(MapTile aTile) {
return String.format(getBaseUrl(), aTile.getX(), aTile.getY(),
aTile.getZoomLevel());
}
}
MainActivity.java
在这里实现了
- 1.3 地图实例化
- 1.4 自定义image Overlay
- 1.5 自定义 Overlay
- 1.6 右下角小地图Overlay,但是小地图不显示,不清楚什么原因
- 1.7 PathOverlay(画线)和SimpleLocationOverlay
public class MainActivity extends Activity {
private MapView mMapView;
private MapController mController;
private DefaultResourceProxyImpl mResourceProxy;
private ItemizedOverlayWithFocus<OverlayItem> mLocationOverlay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// -------->>>>1.3 地图实例化------------------------
mMapView = (MapView) findViewById(R.id.myOSMmapview);
mController = mMapView.getController();
// ResourceProxy init
mResourceProxy = new DefaultResourceProxyImpl(this);
// 在这里设置了一个新的瓦片数据源,以前没有显示地图的原因来源于此。当然权限需要首先配置好
// org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants
// .setUserAgentValue(BuildConfig.DEBUG);
// mMapView.setTileSource(TileSourceFactory.MAPNIK);
mMapView.setTileSource(new GoogleChinaTileSource());
mMapView.setBuiltInZoomControls(true);
// 按理说评论这中有说利用它可以实现移动缩放的,缩放实现了,移动没有,问题出在xml文件中
mMapView.setMultiTouchControls(true);
// //定位当前位置,北京市西长安街复兴路
GeoPoint center = new GeoPoint(39.901873, 116.326655);
// ------->>>>>1.5自定义overlay
// 北京朝阳公园
GeoPoint gp1 = new GeoPoint(39.913445, 116.401962);
mController.setCenter(center);
mController.setZoom(14);
// ------------<<<<<<1.3-----------------------
/**
* ------>>>>>>.1.4
* ItemizedOverlayWithFocus(overlay)-----------------------------
* 可以添加自定义的Overlay,设置image。 但是如代码中所示,实现了OnItemGestureListener接口,并返回true,
* 但是单击(SingleTap)或长按(LongPress)makrer始终无法触发回调函数, 这样就没办法显示自定义的吹出框了。
* 官方的.apk可以触发此事件,实现方式和示例代码一样,目前还未确定是哪里的问题。
*/
// 添加自定义image Overlay
Drawable drawable = this.getResources().getDrawable(
R.drawable.ic_launcher);
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);
/**
* 覆盖物ItemizedOerlayWithFoucs类 实现单击(SingleTap)或长按(LongPress) 因为
* this.mLocationOverlay.setFocusItemsOnTap(true);
* 设置可切换this.mLocationOverlay.setFocusedItem(0); 设置选中第一个,所有你点击没反应
* 但是你如果加入两个覆盖物,就可以看到点击和长按的效果了方法中返回true 和返回false是一样的效果。
加入两个覆盖物没有成功?
*/
this.mLocationOverlay.setFocusItemsOnTap(true);
this.mLocationOverlay.setFocusedItem(0);
mMapView.getOverlays().add(mLocationOverlay);
// -------------<<<<<1.4-------------------------------
// 自定义marker图层
ArrayList<OverlayItem> markers = new ArrayList<OverlayItem>();
OverlayItem one = new OverlayItem("~one~", "custom marker", gp1);
one.setMarker(drawable);
markers.add(one);
OnItemGestureListener<OverlayItem> gestureListener = new OnItemGestureListener<OverlayItem>() {
@Override
public boolean onItemLongPress(int arg0, OverlayItem arg1) {
return false;
}
@Override
public boolean onItemSingleTapUp(int arg0, OverlayItem arg1) {
return false;
}
};
CustomMarker marker = new CustomMarker(markers, gestureListener,
mResourceProxy);
mMapView.getOverlays().add(marker);
mController.setCenter(gp1);
mMapView.invalidate();
// ----->>>>>1.6右下角小地图Overlay但是小地图不显示不清楚什么原因
MinimapOverlay overlay = new MinimapOverlay(this,
mMapView.getTileRequestCompleteHandler());
mMapView.getOverlays().add(overlay);
// ------<<<<<1.6----------------------------------
// ----->>>>>>1.7PathOverlay(画线)和SimpleLocationOverlay-----------
// PathOverlay 路线Overlay gp1在上面用过,所以这个抵消了
// 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);
}
/**
* 自定义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;
}
}
}
离线地图
没有成功,欢迎交流
路径规划
正在实验
资源
可以获取经纬度的网址:
http://www.gpsspg.com/maps.htm