Osmdroid加载第三方地图googlemap、bingmap等

1.osmdroid加载第三方地图的方式

第一种:通过拓展图源的方式

第二种:通过包装(如对google地图的api进行包装),用统一的接口进行调用。

2.osmdroid-third-party源码介绍

osmdroid提供了加载第三方地图的扩展,主要通过学习其源码,学会使用osmdroid提供的接口实现加载第三方地图,但更重要的是学习其中的思想。

在osmdroid源码中实现的module是osmdroid-third-party,先看一下结构:

           Osmdroid加载第三方地图googlemap、bingmap等_第1张图片

api定义了一些接口和自己的实现类

google中通过第二种方式定义了overlay和wrapper包装类

bing中通过第一种方式加载bing地图

3.google的包装设计

先看几个样类:

GeoPoint类

public class GeoPoint implements IGeoPoint {

   private final com.google.android.maps.GeoPoint mGeoPoint;

   public GeoPoint(final com.google.android.maps.GeoPoint pGeoPoint) {
      mGeoPoint = pGeoPoint;
   }

MapController

public class MapController implements IMapController {

   private final com.google.android.maps.MapController mController;

   public MapController(final com.google.android.maps.MapController pController) {
      mController = pController;
   }
MapView
public class MapView implements IMapView {

   private final com.google.android.maps.MapView mMapView;

   public MapView(final com.google.android.maps.MapView pMapView) {
      mMapView = pMapView;
   }

MapWrapper实现IMap接口并使用持有的googlemap实现对应的地图操作

class MapWrapper implements IMap {

   private GoogleMap mGoogleMap;
   private HashMap, com.google.android.gms.maps.model.Polyline> mPolylines;
   private static final Random random = new Random();

   MapWrapper(final GoogleMap aGoogleMap) {
      mGoogleMap = aGoogleMap;

   }

   @Override
   public float getZoomLevel() {
      final CameraPosition cameraPosition = mGoogleMap.getCameraPosition();
      return cameraPosition.zoom;
   }

我们可以很明显看出来这几个类的特点,都是自定义了一个类,然后都持有google对应的类,具体的实现是通过google的api实现的,但是调用的时候却是调用的自己定义的接口,比如调用的时候,简单来讲就是调用依赖抽象,不依赖具体的实现(这句话真的是真理)。


IMap mMap = MapFactory.getMap(mMapViewV2);

final Position position = new Position(52.370816, 9.735936); // Hannover
position.setZoomLevel(14);
mMap.setPosition(position);
mMap.setMyLocationEnabled(false);
mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
    @Override
    public void onCameraChange(final IPosition position) {
        Log.d(Constants.LOGTAG, "onCameraChange");
    }
});
MapFactory.getMap的源码
public static IMap getMap(final com.google.android.gms.maps.MapView aMapView) {
   final GoogleMap map = aMapView.getMap();
   MapsInitializer.initialize(aMapView.getContext());
   return map != null ? new MapWrapper(map) : null;
}
其中IMap是api包中定义的接口,其中定义了很多地图有关操作的接口,比如放大缩小,设置中心点,边界,监听等等,iMap的源码如下,
public interface IMap {

  
   float getZoomLevel();

   
   void setZoom(float zoomLevel);

   IGeoPoint getCenter();

   
   void setCenter(double latitude, double longitude);

   
   float getBearing();

  
   void setBearing(float bearing);

  
   void setPosition(IPosition position);

   
   boolean zoomIn();

  
   boolean zoomOut();

   void setMyLocationEnabled(boolean enabled);

   
   boolean isMyLocationEnabled();

  
   IProjection getProjection();

   
   void addMarker(Marker marker);

  
   int addPolyline(Polyline polyline);

   
   void addPointsToPolyline(int id, IGeoPoint... points);

  
   void clearPolyline(int id);

   
   void clear();

   
   void setOnCameraChangeListener(OnCameraChangeListener listener);
}

问题来了,这么费劲的要自定义这么多的类到底有什么好处!!!不能只出活不讨好吧。其实这应用了一种设计模式--装饰设计,没了解过的可以看一下我的另一篇博客http://blog.csdn.net/qq_30124547/article/details/53184754很简单的一个例子,但是基本上可以理解了。

现在,突然google地图不能用了,我们需要换成bing地图,也就是微软的地图,该怎么办,我们只需要写一个BingWrapper继承IMap并实现对应的地图操作即可,实际调用的地方改动的地方很小,以前总是不注重设计模式,但是自从知道它的好之后,就再也停不下来了,其实还有一种代理模式跟装饰设计很想——代理模式,虽然很像,但还是有区别的。


注意:要想用谷歌的api,必须用注册一个api-key的东西,需要包名+签名文件的sha1值生成,而且更换签名、包名、电脑、、、、key都将不能使用,需要重新生成,详细的还是看官方的中文指南。点我穿越

还有要注意一点的就是,在国内使用google地图需要才能显示。不然只会显示网格,没有地图数据。

4.拓展图源的方式加载bing地图

拓展图源的方式相对来说比包装的形式更方便快捷,但是同时也会有很多的问题

官方给的示例是使用bing地图的图源

public class BingMapTileSource extends QuadTreeTileSource implements IStyledTileSource

实现方式是继承QuadTreeTileSource,实现IStyledTileSource接口,实现对应的方法即可,其中比较重要的就是瓦片源地址

// URL used to get imageryData. It is requested in order to get tiles url patterns
private static final String BASE_URL_PATTERN = "http://dev.virtualearth.net/REST/V1/Imagery/Metadata/%s?mapVersion=v1&output=json&key=%s";

具体便不再详细介绍,具体调用就很简单:

BingMapTileSource source = new BingMapTileSource(null);

mMapView.setTileSource(source);
然后所有逻辑都是osmdroid自身的逻辑相同。


你可能感兴趣的:(Android,Maps)