package org.osmdroid.mapsforge; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.Log; import org.osmdroid.api.IMapView; import org.osmdroid.config.Configuration; import org.osmdroid.tileprovider.IRegisterReceiver; import org.osmdroid.tileprovider.MapTile; import org.osmdroid.tileprovider.MapTileRequestState; import org.osmdroid.tileprovider.modules.IFilesystemCache; import org.osmdroid.tileprovider.modules.MapTileFileStorageProviderBase; import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase; import org.osmdroid.tileprovider.tilesource.ITileSource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; /** * Adapted from code from here: https://github.com/MKergall/osmbonuspack, which is LGPL * http://www.salidasoftware.com/how-to-render-mapsforge-tiles-in-osmdroid/ * @author Salida Software * Adapted from code found here : http://www.sieswerda.net/2012/08/15/upping-the-developer-friendliness/ */ public class MapsForgeTileModuleProvider extends MapTileFileStorageProviderBase { protected MapsForgeTileSource tileSource; protected IFilesystemCache tilewriter; /** * Constructor * * @param receiverRegistrar * @param tileSource */ public MapsForgeTileModuleProvider(IRegisterReceiver receiverRegistrar, MapsForgeTileSource tileSource, IFilesystemCache tilewriter) { super(receiverRegistrar, Configuration.getInstance().getTileFileSystemThreads(), Configuration.getInstance().getTileFileSystemMaxQueueSize()); this.tileSource = tileSource; this.tilewriter = tilewriter; } @Override protected String getName() { return "MapsforgeTiles Provider"; } @Override protected String getThreadGroupName() { return "mapsforgetilesprovider"; } @Override protected Runnable getTileLoader() { return new TileLoader(); } @Override public boolean getUsesDataConnection() { return false; } @Override public int getMinimumZoomLevel() { return tileSource.getMinimumZoomLevel(); } @Override public int getMaximumZoomLevel() { return tileSource.getMaximumZoomLevel(); } @Override public void setTileSource(ITileSource tileSource) { //prevent re-assignment of tile source if (tileSource instanceof MapsForgeTileSource) { this.tileSource = (MapsForgeTileSource) tileSource; } } private class TileLoader extends MapTileModuleProviderBase.TileLoader { @Override public Drawable loadTile(final MapTileRequestState pState) { //TODO find a more efficient want to do this, seems overly complicated MapTile mapTile = pState.getMapTile(); String dbgPrefix = null; if (Configuration.getInstance().isDebugTileProviders()) { dbgPrefix = "MapsForgeTileModuleProvider.TileLoader.loadTile(" + mapTile + "): "; Log.d(IMapView.LOGTAG,dbgPrefix + "tileSource.renderTile"); } Drawable image= tileSource.renderTile(mapTile); if (image!=null && image instanceof BitmapDrawable) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); ((BitmapDrawable)image).getBitmap().compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] bitmapdata = stream.toByteArray(); if (Configuration.getInstance().isDebugTileProviders()) { Log.d(IMapView.LOGTAG, dbgPrefix + "save tile " + bitmapdata.length + " bytes to " + tileSource.getTileRelativeFilenameString(mapTile)); } tilewriter.saveFile(tileSource, mapTile, new ByteArrayInputStream(bitmapdata)); } return image; } } }