osmdroid 加载gpkg格式的离线底图

来源:互联网 发布:淘宝店铺用什么软件好 编辑:程序博客网 时间:2024/06/04 19:21

博客介绍了一系列的osmdroid开源地图相关的内容,包括地图基本绘制,导航,缩放,加载各种离线地图等等。接下来继续介绍加载离线的gpkg格式地图。gpkg的全称是geopackage。这篇博客也是在之前的基础上添加的测试代码。

geopackage的github官网:https://github.com/ngageoint/geopackage-android

本博客的代码:http://download.csdn.net/detail/qq_16064871/9908233


android osmdroid 加载常用离线地图格式(开源的在线地图)
android osmdroid 加载离线地图map格式以及地图网格绘制

android 开源库osmdroid绘制点线面(比例尺,缩小放大,导航图标等)



1,加载的图片效果




默认的路径放在根目录的osmdroid文件夹下面。

实现需要使用的相关代码:


2,调用方式


package com.osmdroid.sample;import android.content.Context;import android.content.DialogInterface;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Bundle;import android.support.v4.app.FragmentManager;import android.support.v7.app.AppCompatActivity;import android.util.DisplayMetrics;import android.util.Log;import android.view.View;import android.widget.TextView;import android.widget.Toast;import com.osmdroid.sample.geopakeage.CustomGeopackageUntil;import com.osmdroid.sample.geopakeage.GeoPackageMapTileModuleProvider;import com.osmdroid.sample.geopakeage.GeoPackageProvider;import com.osmdroid.sample.geopakeage.GeopackageSample;import com.osmdroid.sample.overlay.SampleSimpleFastPointOverlay;import org.osmdroid.api.IGeoPoint;import org.osmdroid.api.IMapView;import org.osmdroid.config.Configuration;import org.osmdroid.events.MapListener;import org.osmdroid.events.ScrollEvent;import org.osmdroid.events.ZoomEvent;import org.osmdroid.tileprovider.tilesource.TileSourceFactory;import org.osmdroid.tileprovider.tilesource.XYTileSource;import org.osmdroid.tileprovider.util.StorageUtils;import org.osmdroid.util.GeoPoint;import org.osmdroid.views.MapView;import org.osmdroid.views.overlay.ScaleBarOverlay;import org.osmdroid.views.overlay.compass.CompassOverlay;import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;import java.io.File;import java.io.FileFilter;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.List;import java.util.Set;/** * 测试加载geopackage */public class GeopackageMapTestActivity extends AppCompatActivity implements View.OnClickListener  ,LocationListener{    private MapView mapView;    //地图旋转    private RotationGestureOverlay mRotationGestureOverlay;    //比例尺    private ScaleBarOverlay mScaleBarOverlay;    //指南针方向    private CompassOverlay mCompassOverlay = null;    //设置导航图标的位置    private MyLocationNewOverlay mLocationOverlay;    private LocationManager lm;    private Location currentLocation = null;    private com.osmdroid.sample.geopakeage.GeopackageSample GeopackageSample = null;    TextView textViewCurrentLocation;    GeoPackageProvider.TileSourceBounds tileSourceBounds;    XYTileSource currentSource = null;    GeoPackageProvider geoPackageProvider=null;    public static final DecimalFormat df = new DecimalFormat("#.000000");    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_basic_test_geopackage);        initView();    }    private void initView() {        findViewById(R.id.button1).setOnClickListener(this);        findViewById(R.id.button2).setOnClickListener(this);        textViewCurrentLocation = (TextView) findViewById(R.id.textViewCurrentLocation);        mapView = (MapView) findViewById(R.id.mymapview);        mapView.setDrawingCacheEnabled(true);        mapView.setMaxZoomLevel(20);        mapView.setMinZoomLevel(6);        mapView.getController().setZoom(12);        mapView.setTileSource(TileSourceFactory.MAPNIK);        mapView.setUseDataConnection(true);        mapView.setMultiTouchControls(true);// 触控放大缩小        //是否显示地图数据源        mapView.getOverlayManager().getTilesOverlay().setEnabled(true);        //地图自由旋转        mRotationGestureOverlay = new RotationGestureOverlay(mapView);        mRotationGestureOverlay.setEnabled(true);        mapView.getOverlays().add(this.mRotationGestureOverlay);        //比例尺配置        final DisplayMetrics dm = getResources().getDisplayMetrics();        mScaleBarOverlay = new ScaleBarOverlay(mapView);        mScaleBarOverlay.setCentred(true);        mScaleBarOverlay.setAlignBottom(true); //底部显示        mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 5, 80);        mapView.getOverlays().add(this.mScaleBarOverlay);        //指南针方向        mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this),                mapView);        mCompassOverlay.enableCompass();        mapView.getOverlays().add(this.mCompassOverlay);        //设置导航图标        this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this),                mapView);        mapView.getOverlays().add(this.mLocationOverlay);        mLocationOverlay.enableMyLocation();  //设置可视    }    @Override    public void onLocationChanged(Location location) {        currentLocation=location;    }    @Override    public void onStatusChanged(String provider, int status, Bundle extras) {    }    @Override    public void onProviderEnabled(String provider) {    }    @Override    public void onProviderDisabled(String provider) {    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.button1:                if (currentLocation != null) {                    GeoPoint myPosition = new GeoPoint(currentLocation.getLatitude(), currentLocation.getLongitude());                    mapView.getController().animateTo(myPosition);                }                break;            case R.id.button2:                // TODO: 2017/6/19   Fragment形式的图层//                FragmentManager fm = this.getSupportFragmentManager();//                if (fm.findFragmentByTag("GeopackageSample") == null) {//                    mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);//                    GeopackageSample = new GeopackageSample();//                    fm.beginTransaction().add(R.id.samples_container, GeopackageSample, "SampleGridlines").commit();//                }                addOverlays();                break;        }    }    public void addOverlays() {        //first let's up our map source, mapsforge needs you to explicitly specify which map files to load        //this bit does some basic file system scanning        Set<File> mapfiles = findMapFiles();        //do a simple scan of local storage for .gpkg files.        File[] maps = new File[mapfiles.size()];        maps = mapfiles.toArray(maps);        if (maps.length == 0) {            //show a warning that no map files were found            android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(this);            // set title            alertDialogBuilder.setTitle("No Geopackage files found");            // set dialog message            alertDialogBuilder                    .setMessage("In order to render map tiles, you'll need to either create or obtain .gpkg files. See http://www.geopackage.org/ for more info. Place them in "                            + Configuration.getInstance().getOsmdroidBasePath().getAbsolutePath())                    .setCancelable(false)                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {                        public void onClick(DialogInterface dialog, int id) {                        }                    });            // create alert dialog            android.app.AlertDialog alertDialog = alertDialogBuilder.create();            // show it            alertDialog.show();        } else {            Toast.makeText(this, "Loaded " + maps.length + " map files", Toast.LENGTH_LONG).show();            geoPackageProvider = new GeoPackageProvider(maps, this);            mapView.setTileProvider(geoPackageProvider);            List<GeoPackageMapTileModuleProvider.Container> tileSources = geoPackageProvider.geoPackageMapTileModuleProvider().getTileSources();            //here we're keeping track of the current tile source so we can reference it later, primarly for            //displaying the bounds of the tile set            boolean sourceSet = false;            for (int i = 0; i < tileSources.size(); i++) {                //this is a list of geopackages, since we only support tile tables, pick the first one of those                //ideally this should populate a spinner so that the user can select whatever tile source they want                if (tileSources.get(i) != null && !tileSources.get(i).tiles.isEmpty()) {                    currentSource = (XYTileSource) geoPackageProvider.getTileSource(tileSources.get(i).database,                            tileSources.get(0).tiles.get(i)                    );                    mapView.setTileSource(currentSource);                    sourceSet = true;                    break;                }            }            if (!sourceSet) {                Toast.makeText(this, "No tile source is available, get your geopackages for 'tiles' tables", Toast.LENGTH_LONG).show();            } else {                Toast.makeText(this, "Tile source set to " + mapView.getTileProvider().getTileSource().name(), Toast.LENGTH_LONG).show();                //this part will attempt to zoom to bounds of the selected tile source                tileSourceBounds = geoPackageProvider.getTileSourceBounds();                if (tileSourceBounds != null) {                    mapView.zoomToBoundingBox(tileSourceBounds.bounds, true);                    mapView.getController().setZoom(tileSourceBounds.minzoom);                }            }        }        mapView.setMapListener(new MapListener() {            @Override            public boolean onScroll(ScrollEvent event) {                Log.i(IMapView.LOGTAG, System.currentTimeMillis() + " onScroll " + event.getX() + "," + event.getY());                updateInfo();                return true;            }            @Override            public boolean onZoom(ZoomEvent event) {                Log.i(IMapView.LOGTAG, System.currentTimeMillis() + " onZoom " + event.getZoomLevel());                updateInfo();                return true;            }        });        updateInfo();    }    private void updateInfo() {        StringBuilder sb = new StringBuilder();        IGeoPoint mapCenter = mapView.getMapCenter();        sb.append(df.format(mapCenter.getLatitude()) + "," +                df.format(mapCenter.getLongitude())                + ",zoom=" + mapView.getZoomLevel());        if (currentSource != null) {            sb.append("\n");            sb.append(currentSource.name() + "," + currentSource.getBaseUrl());        }        if (tileSourceBounds != null) {            sb.append("\n");            sb.append(" minzoom=" + tileSourceBounds.minzoom);            sb.append(" maxzoom=" + tileSourceBounds.maxzoom);            sb.append(" bounds=" + df.format(tileSourceBounds.bounds.getLatNorth())                    + "," + df.format(tileSourceBounds.bounds.getLonEast()) + "," +                    df.format(tileSourceBounds.bounds.getLatSouth()) + "," +                    df.format(tileSourceBounds.bounds.getLonWest()));        }        textViewCurrentLocation.setText(sb.toString());    }    /**     * simple function to scan for paths that match /something/osmdroid/*.map to find database files     *     * @return     */    protected static Set<File> findMapFiles() {        Set<File> maps = new HashSet<>();        List<StorageUtils.StorageInfo> storageList = StorageUtils.getStorageList();        for (int i = 0; i < storageList.size(); i++) {            File f = new File(storageList.get(i).path + File.separator + "osmdroid" + File.separator);            if (f.exists()) {                maps.addAll(scan(f));            }        }        return maps;    }    static private Collection<? extends File> scan(File f) {        List<File> ret = new ArrayList<>();        File[] files = f.listFiles(new FileFilter() {            @Override            public boolean accept(File pathname) {                if (pathname.getName().toLowerCase().endsWith(".gpkg"))                    return true;                return false;            }        });        if (files != null) {            for (int i = 0; i < files.length; i++) {                ret.add(files[i]);            }        }        return ret;    }    @Override    public void onDestroy(){        super.onDestroy();        this.currentSource=null;        if (geoPackageProvider!=null)            geoPackageProvider.detach();    }    @Override    public void onPause() {        super.onPause();        try{            lm.removeUpdates(this);        }catch (Exception ex){}        mCompassOverlay.disableCompass();        mLocationOverlay.disableFollowLocation();        mLocationOverlay.disableMyLocation();        mScaleBarOverlay.enableScaleBar();    }    @Override    public void onResume(){        super.onResume();        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);        try{            //this fails on AVD 19s, even with the appcompat check, says no provided named gps is available            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0l,0f,this);        }catch (Exception ex){}        try{            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,0l,0f,this);        }catch (Exception ex){}        mLocationOverlay.enableFollowLocation();        mLocationOverlay.enableMyLocation();        mScaleBarOverlay.disableScaleBar();    }}

第二种调用方式,使用Fragment形式的图层


                // TODO: 2017/6/19   Fragment形式的图层                FragmentManager fm = this.getSupportFragmentManager();                if (fm.findFragmentByTag("GeopackageSample") == null) {                    mapView.setTileSource(TileSourceFactory.DEFAULT_TILE_SOURCE);                    GeopackageSample = new GeopackageSample();                    fm.beginTransaction().add(R.id.samples_container, GeopackageSample, "SampleGridlines").commit();                }                addOverlays();

3,注意事项

如果编译出现google_play_services_version找不到,记得把资源文件夹下面values文件夹下面values拷贝进去。


这里加载是gpkg地图格式的瓦片数据,就是有生成位图那种。如果是gpkg数据库存储的数据库表,没有转化成titles是加载不出来的。



geopackage的github官网:https://github.com/ngageoint/geopackage-android

本博客的代码:http://download.csdn.net/detail/qq_16064871/9908233


android osmdroid 加载常用离线地图格式(开源的在线地图)
android osmdroid 加载离线地图map格式以及地图网格绘制

android 开源库osmdroid绘制点线面(比例尺,缩小放大,导航图标等)