OSMDroid如何使外部供应商协同工作与地方?协同工作、供应商、地方、OSMDroid

2023-09-07 10:13:58 作者:棒棒糖、狠甜!

所以,我终于得到了osmdroid与本地目录的工作,但我想,当他们在本地缺少从Mapnik的装载瓷砖。我不知道我错过了什么。

我的实现如下:

 私人MapView类MapView类= NULL;@覆盖公共无效的onCreate(捆绑savedInstanceState){    super.onCreate(savedInstanceState);    的setContentView(R.layout.osm_map);    图形页面=(图形页面)findViewById(R.id.mapview);    mapView.setBuiltInZoomControls(真);    mapView.setMultiTouchControls(真);    MapController mapController = mapView.getController();    mapController.setZoom(5);    的GeoPoint点2 =新的GeoPoint(55708545,10006348);    mapController.setCenter(点2);    // TODO保存到SD    AssetManager assetManager = getAssets();    InputStream为;    字符串文件名=test.zip;    字符串路径= Environment.getExternalStorageDirectory()+文件分割符+文件名; // TODO路径将其保存到    尝试{        是= assetManager.open(文件名);        FileOutputStream中FO =新的FileOutputStream(路径);        字节[] B =新的字节[1024];        INT长;        而((长度= is.​​read(二))!=  -  1){            fo.write(B,0,长度);        }        fo.flush();        fo.close();        is.close();    }赶上(IOException异常五){        e.printStackTrace();    }    文件tileFile =新的文件(路径);    IArchiveFile []档案=新IArchiveFile [1];    档案[0] = ArchiveFileFactory.getArchiveFile(tileFile);    CustomTileSource customTiles =新CustomTileSource(Mapnik的,NULL,0,24,256,png格式); //名字应该匹配是压缩文件夹的名称    MapTileModuleProviderBase [] =供应商新MapTileModuleProviderBase [2];    供应商[0] =新MapTileFileArchiveProvider(新SimpleRegisterReceiver(getApplicationContext()),customTiles,档案);    供应商[1] =新MapTileDownloader(TileSourceFactory.MAPNIK);    mapView.setUseDataConnection(假);    mapView.setTileSource(TileSourceFactory.MAPNIK);    MapTileProviderArray tileProvider =新MapTileProviderArray(customTiles,空,供应商);    TilesOverlay tilesOverlay =新TilesOverlay(tileProvider,getApplicationContext());    调用MapView.getOverlays()加(tilesOverlay)。    mapView.invalidate();} 

 公共类CustomTileSource扩展BitmapTileSourceBase {    公共CustomTileSource(字符串aName,串aResourceId,            INT aZoomMinLevel,诠释aZoomMaxLevel,INT aTileSizePixels,            字符串aImageFilenameEnding){        超(aName,aResourceId,aZoomMinLevel,aZoomMaxLevel,aTileSizePixels,                aImageFilenameEnding);    }} 

解决方案

好了,我终于找到了解决办法。它相当复杂,长,但它的工作原理:D

OSMDroid

现在我OsmDroidFragment内(是在地图片段)我有以下几点:

  @覆盖公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,        捆绑savedInstanceState){    RelativeLayout的观点=(RelativeLayout的)inflater.inflate(R.layout.osm_map,集装箱,FALSE);    RelativeLayout的mapContainer =(RelativeLayout的)view.findViewById(R.id.osm_map_parent);    mMapView =新OsmCustomMapView(getActivity(),256,10,13); //我为了限制变焦已经有了一个自定义实现,你可以用普通osmdroid的MapView    的LayoutParams PARAMS =新RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);    mMapView.setLayoutParams(PARAMS);    mapContainer.addView(mMapView);    mMapView.setBuiltInZoomControls(真);    mMapView.setMultiTouchControls(假); //捏缩放功能不好的osmdroid    MapController mapController = mMapView.getController();    mapController.setZoom(11); //必须setCenter之前设置变焦,否则我们得到错误的位置    GeoPoint的中心=新的GeoPoint(0,0);    mapController.setCenter(中心);    //保存压缩到SD    AssetManager assetManager = getActivity()getAssets()。    InputStream为;    字符串文件名=map.zip; // zip文件就在于资产根    字符串路径= this.getActivity()getExternalFilesDir(空)+文件分割符+文件名。 //路径我省SD来    文件tileFile =新的文件(路径);    如果(!tileFile.exists()){        尝试{            是= assetManager.open(文件名);            FileOutputStream中FO =新的FileOutputStream(路径);            字节[] B =新的字节[1024];            INT长;            而((长度= is.​​read(二))!=  -  1){                fo.write(B,0,长度);            }            fo.flush();            fo.close();            is.close();        }赶上(IOException异常五){            e.printStackTrace();        }    }    IArchiveFile []档案=新IArchiveFile [1];    档案[0] = ArchiveFileFactory.getArchiveFile(tileFile);    //扩展BitmapTileSourceBase,没有别的简单实现    CustomTileSource customTiles =新CustomTileSource(Maverik,空,10,14,256,png格式); // Maverik是拉链里面的文件夹的名称(所以拉链是map.zip和里面是一个叫做Maverik文件夹)    MapTileModuleProviderBase [] =供应商新MapTileModuleProviderBase [2];    供应商[0] =新MapTileFileArchiveProvider(新SimpleRegisterReceiver(getActivity()getApplicationContext()),customTiles,档案); //这个人是当地的地砖(邮政编码等)    供应商[1] =新MapTileDownloader(TileSourceFactory.MAPNIK); // Mapnik的网页源瓷砖    mMapView.setUseDataConnection(真);    MapTileProviderArray tileProvider =新MapTileProviderArray(customTiles,            新SimpleRegisterReceiver(getActivity()getApplicationContext()。),供应商);    TilesOverlay tilesOverlay =新TilesOverlay(tileProvider,getActivity()getApplicationContext());    tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT); //这将确保当地砖的瓷砖invisble是透明的,所以我们可以看到网络的瓷砖,透明有一个小的性能下降。    。mMapView.getOverlays()加(tilesOverlay);    mMapView.invalidate();    返回视图。} 

So I've finally gotten osmdroid working with a local directory but I'd like to load tiles from Mapnik when they are missing locally. I'm not sure what I'm missing.

My implementation is as follows:

private MapView mapView = null;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.osm_map);

    mapView = (MapView) findViewById(R.id.mapview);
    mapView.setBuiltInZoomControls(true);
    mapView.setMultiTouchControls(true);

    MapController mapController = mapView.getController();
    mapController.setZoom(5);
    GeoPoint point2 = new GeoPoint(55708545, 10006348);
    mapController.setCenter(point2);

    //TODO Save to SD
    AssetManager assetManager = getAssets();
    InputStream is;
    String fileName = "test.zip";
    String path = Environment.getExternalStorageDirectory() + File.separator + fileName;    //TODO Path to save it to
    try {
        is = assetManager.open(fileName);

        FileOutputStream fo = new FileOutputStream(path);

        byte[] b = new byte[1024];
        int length;
        while((length = is.read(b)) != -1) {
            fo.write(b, 0, length);
        }
        fo.flush();
        fo.close();
        is.close();
    } catch (IOException  e) {
        e.printStackTrace();
    }

    File tileFile = new File(path);
    IArchiveFile[] archives = new IArchiveFile[1];
    archives[0] = ArchiveFileFactory.getArchiveFile(tileFile);

    CustomTileSource customTiles = new CustomTileSource("Mapnik", null, 0, 24, 256, ".png");    // the name should match the name of the folder that is zipped

    MapTileModuleProviderBase[] providers = new MapTileModuleProviderBase[2];
    providers[0] = new MapTileFileArchiveProvider(new SimpleRegisterReceiver(getApplicationContext()), customTiles, archives);
    providers[1] =  new MapTileDownloader(TileSourceFactory.MAPNIK);
    mapView.setUseDataConnection(false);
    mapView.setTileSource(TileSourceFactory.MAPNIK);

    MapTileProviderArray tileProvider = new MapTileProviderArray(customTiles, null, providers);
    TilesOverlay tilesOverlay = new TilesOverlay(tileProvider, getApplicationContext());
    mapView.getOverlays().add(tilesOverlay);
    mapView.invalidate();
}

AND

public class CustomTileSource extends BitmapTileSourceBase {

    public CustomTileSource(String aName, string aResourceId,
            int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels,
            String aImageFilenameEnding) {
        super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels,
                aImageFilenameEnding);
    }

}

解决方案

Okay so I've finally found a solution. Its quite complex and long but it works :D

Now inside my OsmDroidFragment (yes map in fragment) I have following:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    RelativeLayout view = (RelativeLayout) inflater.inflate(R.layout.osm_map, container, false);
    RelativeLayout mapContainer = (RelativeLayout) view.findViewById(R.id.osm_map_parent);

    mMapView = new OsmCustomMapView(getActivity(), 256, 10, 13);    // I've made a custom implementation in order to limit zoom, you can just use regular osmdroid mapview
    LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    mMapView.setLayoutParams(params);
    mapContainer.addView(mMapView);

    mMapView.setBuiltInZoomControls(true);
    mMapView.setMultiTouchControls(false);  // pinch zoom works bad on osmdroid

    MapController mapController = mMapView.getController();
    mapController.setZoom(11);  // must set zoom before setCenter, else we get the wrong position
    GeoPoint center = new GeoPoint(0,0);
    mapController.setCenter(center);

    // save zip to sd
    AssetManager assetManager = getActivity().getAssets();
    InputStream is;
    String fileName = "map.zip";    // the zip file lies in assets root
    String path = this.getActivity().getExternalFilesDir(null) + File.separator + fileName; // the path I save SD to

    File tileFile = new File(path);
    if(!tileFile.exists()) {
        try {
            is = assetManager.open(fileName);

            FileOutputStream fo = new FileOutputStream(path);

            byte[] b = new byte[1024];
            int length;
            while((length = is.read(b)) != -1) {
                fo.write(b, 0, length);
            }

            fo.flush();
            fo.close();
            is.close();
        } catch (IOException  e) {
            e.printStackTrace();
        }
    }

    IArchiveFile[] archives = new IArchiveFile[1];
    archives[0] = ArchiveFileFactory.getArchiveFile(tileFile);

    // Simple implementation that extends BitmapTileSourceBase and nothing else
    CustomTileSource customTiles = new CustomTileSource("Maverik", null, 10, 14, 256, ".png");  // Maverik is the name of the folder inside the zip (so zip is map.zip and inside it is a folder called Maverik)

    MapTileModuleProviderBase[] providers = new MapTileModuleProviderBase[2];
    providers[0] = new MapTileFileArchiveProvider(new SimpleRegisterReceiver(getActivity().getApplicationContext()), customTiles, archives);    // this one is for local tiles (zip etc.)
    providers[1] =  new MapTileDownloader(TileSourceFactory.MAPNIK);    // MAPNIK web tile source

    mMapView.setUseDataConnection(true);

    MapTileProviderArray tileProvider = new MapTileProviderArray(customTiles, 
            new SimpleRegisterReceiver(getActivity().getApplicationContext()), providers);
    TilesOverlay tilesOverlay = new TilesOverlay(tileProvider, getActivity().getApplicationContext());
    tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT);  // this makes sure that the invisble tiles of local tiles are transparent so we can see tiles from web, transparent have a minor performance decline.

    mMapView.getOverlays().add(tilesOverlay);

    mMapView.invalidate();

    return view;
}