2012-10-02 28 views
9

Varlıklar Klasörden Yükleme Özel Çevrim fayans OSMDroid. Bunu yapmak için var olan kodun bir kısmını değiştirmenin gerekeceğini biliyorum, ama nerede ve nasıl yapılacağı konusunda kimsenin bir yönü olup olmadığını merak ediyordum.Ben böyle bir şey yapmak mümkün olup olmadığını merak

Haritadaki belirli bir bölgeye, OSM karo tedarikçileri için yeni bir özel döşeme yerleştiriyorum ancak bunların/varlıklar/klasörde depolanması gerekiyor. Herhangi bir fikir?

cevap

9

Bunu yapmak için nexts sınıflarını kullanıyorum.

import java.io.InputStream; 

import org.osmdroid.ResourceProxy.string; 
import org.osmdroid.tileprovider.util.StreamUtils; 

import android.content.res.AssetManager; 
import android.graphics.drawable.Drawable; 

public class AssetsTileSource extends CustomBitmapTileSourceBase { 
     private final AssetManager mAssetManager; 

     public AssetsTileSource(final AssetManager assetManager, final String aName, final string aResourceId, 
         final int aZoomMinLevel, final int aZoomMaxLevel, final int aTileSizePixels, 
         final String aImageFilenameEnding) { 
       super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding); 
       mAssetManager = assetManager; 
     } 

     @Override 
     public Drawable getDrawable(final String aFilePath) { 
       InputStream inputStream = null; 
       try { 
         inputStream = mAssetManager.open(aFilePath); 
         if (inputStream != null) { 
           final Drawable drawable = getDrawable(inputStream); 
           return drawable; 
         } 
       } catch (final Throwable e) { 
         // Tile does not exist in assets folder. 
         // Ignore silently 
       } finally { 
         if (inputStream != null) { 
           StreamUtils.closeStream(inputStream); 
         } 
       } 

       return null; 
     } 
} 

MapTileFileAssetsProvider.java

public class MapTileFileAssetsProvider extends MapTileModuleProviderBase { 

      protected ITileSource mTileSource; 

      public MapTileFileAssetsProvider(final ITileSource pTileSource) { 
        super(OpenStreetMapTileProviderConstants.NUMBER_OF_TILE_FILESYSTEM_THREADS, OpenStreetMapTileProviderConstants.TILE_FILESYSTEM_MAXIMUM_QUEUE_SIZE); 

        mTileSource = pTileSource; 
      } 

      @Override 
      public boolean getUsesDataConnection() { 
        return false; 
      } 

      @Override 
      protected String getName() { 
        return "Assets Folder Provider"; 
      } 

      @Override 
      protected String getThreadGroupName() { 
        return "assetsfolder"; 
      } 

      @Override 
      protected Runnable getTileLoader() { 
        return new TileLoader(); 
      } 

      @Override 
      public int getMinimumZoomLevel() { 
        return mTileSource != null ? mTileSource.getMinimumZoomLevel() : MAXIMUM_ZOOMLEVEL; 
      } 

      @Override 
      public int getMaximumZoomLevel() { 
        return mTileSource != null ? mTileSource.getMaximumZoomLevel() : MINIMUM_ZOOMLEVEL; 
      } 

      @Override 
      public void setTileSource(final ITileSource pTileSource) { 
        mTileSource = pTileSource; 
      } 

      private class TileLoader extends MapTileModuleProviderBase.TileLoader { 

        @Override 
        public Drawable loadTile(final MapTileRequestState pState) throws CantContinueException { 

          if (mTileSource == null) { 
            return null; 
          } 

          final MapTile pTile = pState.getMapTile(); 
          String path = mTileSource.getTileRelativeFilenameString(pTile); 

          Drawable drawable; 
          try { 
            drawable = mTileSource.getDrawable(path); 
          } catch (final LowMemoryException e) { 
            // low memory so empty the queue 
            throw new CantContinueException(e); 
          } 

          return drawable; 
        } 
      } 
    } 

ve

import java.io.File; 
import java.io.InputStream; 
import java.util.Random; 

import org.osmdroid.ResourceProxy; 
import org.osmdroid.ResourceProxy.string; 
import org.osmdroid.tileprovider.ExpirableBitmapDrawable; 
import org.osmdroid.tileprovider.MapTile; 
import org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants; 
import org.osmdroid.tileprovider.tilesource.ITileSource; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.drawable.Drawable; 

public abstract class CustomBitmapTileSourceBase implements ITileSource, 
       OpenStreetMapTileProviderConstants { 

     private static final Logger logger = LoggerFactory.getLogger(CustomBitmapTileSourceBase.class); 

     private static int globalOrdinal = 0; 

     private final int mMinimumZoomLevel; 
     private final int mMaximumZoomLevel; 

     private final int mOrdinal; 
     protected final String mName; 
     protected final String mImageFilenameEnding; 
     protected final Random random = new Random(); 

     private final int mTileSizePixels; 

     private final string mResourceId; 

     public CustomBitmapTileSourceBase(final String aName, final string aResourceId, 
         final int aZoomMinLevel, final int aZoomMaxLevel, final int aTileSizePixels, 
         final String aImageFilenameEnding) { 
       mResourceId = aResourceId; 
       mOrdinal = globalOrdinal++; 
       mName = aName; 
       mMinimumZoomLevel = aZoomMinLevel; 
       mMaximumZoomLevel = aZoomMaxLevel; 
       mTileSizePixels = aTileSizePixels; 
       mImageFilenameEnding = aImageFilenameEnding; 
     } 

     @Override 
     public int ordinal() { 
       return mOrdinal; 
     } 

     @Override 
     public String name() { 
       return mName; 
     } 

     public String pathBase() { 
       return mName; 
     } 

     public String imageFilenameEnding() { 
       return mImageFilenameEnding; 
     } 

     @Override 
     public int getMinimumZoomLevel() { 
       return mMinimumZoomLevel; 
     } 

     @Override 
     public int getMaximumZoomLevel() { 
       return mMaximumZoomLevel; 
     } 

     @Override 
     public int getTileSizePixels() { 
       return mTileSizePixels; 
     } 

     @Override 
     public String localizedName(final ResourceProxy proxy) { 
       return proxy.getString(mResourceId); 
     } 

     @Override 
     public Drawable getDrawable(final String aFilePath) { 
       try { 
         // default implementation will load the file as a bitmap and create 
         // a BitmapDrawable from it 
         final Bitmap bitmap = BitmapFactory.decodeFile(aFilePath); 
         if (bitmap != null) { 
           return new ExpirableBitmapDrawable(bitmap); 
         } else { 
           // if we couldn't load it then it's invalid - delete it 
           try { 
             new File(aFilePath).delete(); 
           } catch (final Throwable e) { 
             logger.error("Error deleting invalid file: " + aFilePath, e); 
           } 
         } 
       } catch (final OutOfMemoryError e) { 
         logger.error("OutOfMemoryError loading bitmap: " + aFilePath); 
         System.gc(); 
       } 
       return null; 
     } 

     @Override 
     public String getTileRelativeFilenameString(final MapTile tile) { 
       final StringBuilder sb = new StringBuilder(); 
       sb.append(pathBase()); 
       sb.append('/'); 
       sb.append(tile.getX()); 
       sb.append('_'); 
       sb.append(tile.getY()); 
       sb.append('_'); 
       sb.append(tile.getZoomLevel()); 
       sb.append(imageFilenameEnding()); 
       return sb.toString(); 
     } 


     @Override 
     public Drawable getDrawable(final InputStream aFileInputStream) { 
       try { 
         // default implementation will load the file as a bitmap and create 
         // a BitmapDrawable from it 
         final Bitmap bitmap = BitmapFactory.decodeStream(aFileInputStream); 
         if (bitmap != null) { 
           return new ExpirableBitmapDrawable(bitmap); 
         } 
         System.gc(); 
       } catch (final OutOfMemoryError e) { 
         logger.error("OutOfMemoryError loading bitmap"); 
         System.gc(); 
         //throw new LowMemoryException(e); 
       } 
       return null; 
     } 

     public final class LowMemoryException extends Exception { 
       private static final long serialVersionUID = 146526524087765134L; 

       public LowMemoryException(final String pDetailMessage) { 
         super(pDetailMessage); 
       } 

       public LowMemoryException(final Throwable pThrowable) { 
         super(pThrowable); 
       } 
     } 
} 

değiştirme yöntemi getTileRelativeFilenameString() (i aşağıdaki biçimi kullanın: x_y_zoom.png) yout fayans için

Örnek :

mapView = new MapView(getApplicationContext(), 256); 
mapView.setClickable(true); 
mapView.setTag("Mapa"); 
mapView.setTileSource(TileSourceFactory.MAPNIK); 
mapView.setMultiTouchControls(true); 
mapView.setUseDataConnection(true); 

MapTileModuleProviderBase moduleProvider = 
    new MapTileFileAssetsProvider(ASSETS_TILE_SOURCE); 
SimpleRegisterReceiver simpleReceiver = 
    new SimpleRegisterReceiver(getApplicationContext()); 
MapTileProviderArray tileProviderArray = 
    new MapTileProviderArray(ASSETS_TILE_SOURCE, simpleReceiver, 
     new MapTileModuleProviderBase[] { moduleProvider }); 
TilesOverlay tilesOverlay = 
    new TilesOverlay(tileProviderArray, getApplicationContext()); 

mapView.getOverlays().add(tilesOverlay); 
+0

Yakınlaştırma/uzaklaştırma ile birlikte navigasyon için koordinatlar nasıl uygulanır? – Zyoo

+0

Sınıflar kullanışlıdır, ancak örnek tam değildir. ASSETS_TILE_SOURCE için sabit değil, AssetsTileSource sınıfından yeni bir nesne. TileProviderArray oluşturulduğunda, bir argüman olarak alabilen kurucu kullanarak mapView öğesini oluştururken kullanın. MapView mapView = new MapView (bu, 256, resourceProxy, tileProviderArray). MapView'ın bindirme ile ilişkilendirmek yerine kiremit kaynağı ile ilişkilendirmesi benim için daha sezgisel ... belki de sadece ben. – Yam

+0

@jzafrilla örnek sayesinde. Ana UI iş parçacığı üzerinde '' GC_FOR_ALLOC' 'Bitmap.decodeStream()' değil mi? – zIronManBox

3

Onun yerine osmdroid maptiles dizine (osmdroid harita parçaları dizin yapısı biçiminde aşağıdaki) sıkıştırılmış maptiles dağıtmak varlık doğrudan/kopya okumak ve daha sonra 3 kiremit sağlayıcıları, arşiv, önbellek ve çevrimiçi sağlayıcı ilan ediyoruz.

public class MapTileProviderAssets extends MapTileProviderArray 
     implements IMapTileProviderCallback { 

    private static final String LOG_TAG = "MapTileProviderAssets"; 

    private static final String ASSETS_MAP_DIRECTORY = "map"; 
    private static final String SDCARD_PATH = Environment.getExternalStorageDirectory().getPath(); 
    private static final String OSMDROID_MAP_FILE_SOURCE_DIRECTORY = "osmdroid"; 
    private static final String OSMDROID_MAP_FILE_SOURCE_DIRECTORY_PATH = 
      SDCARD_PATH + "/" + OSMDROID_MAP_FILE_SOURCE_DIRECTORY; 

    public MapTileProviderAssets(final Context pContext) { 
     this(pContext, TileSourceFactory.DEFAULT_TILE_SOURCE); 
    } 

    public MapTileProviderAssets(final Context pContext, final ITileSource pTileSource) { 
     this(pContext, new SimpleRegisterReceiver(pContext), 
       new NetworkAvailabliltyCheck(pContext), pTileSource); 

    } 

    public MapTileProviderAssets(final Context pContext, final IRegisterReceiver pRegisterReceiver, 
           final INetworkAvailablityCheck aNetworkAvailablityCheck, 
           final ITileSource pTileSource) { 
     super(pTileSource, pRegisterReceiver); 

     final TileWriter tileWriter = new TileWriter(); 

     // copy assets delivered in apk into osmdroid map source dir 
     // load zip archive first, then cache, then online 
     final List<String> zipArchivesRelativePathInAssets = 
       listArchives(pContext.getAssets(), ASSETS_MAP_DIRECTORY); 
     for (final String zipFileRelativePathInAssets : zipArchivesRelativePathInAssets) { 
      final String copiedFilePath = copyAssetFile(
        pContext.getAssets(), zipFileRelativePathInAssets, 
        OSMDROID_MAP_FILE_SOURCE_DIRECTORY); 
      Log.d(LOG_TAG, String.format(
        "Archive zip file copied into map source directory %s", copiedFilePath)); 
     } 
     // list zip files in map archive directory 
     final Set<String> setZipFileArchivesPath = new HashSet<String>(); 
     FileTools.listFiles(setZipFileArchivesPath, new File(
       OSMDROID_MAP_FILE_SOURCE_DIRECTORY_PATH), ".zip", true); 
     final Set<IArchiveFile> setZipFileArchives = new HashSet<IArchiveFile>(); 
     for (final String zipFileArchivesPath : setZipFileArchivesPath) { 
      final File zipfile = new File(zipFileArchivesPath); 
      final IArchiveFile archiveFile = ArchiveFileFactory.getArchiveFile(zipfile); 
      if (archiveFile != null) { 
       setZipFileArchives.add(archiveFile); 
      } 
      setZipFileArchives.add(archiveFile); 
      Log.d(LOG_TAG, String.format(
        "Archive zip file %s added to map source ", zipFileArchivesPath)); 
     } 

     final MapTileFileArchiveProvider archiveProvider; 
     Log.d(LOG_TAG, String.format(
       "%s archive zip files will be used as source", setZipFileArchives.size())); 
     if (setZipFileArchives.size() > 0) { 
      final IArchiveFile[] pArchives = 
        setZipFileArchives.toArray(new IArchiveFile[setZipFileArchives.size()]); 
      archiveProvider = new MapTileFileArchiveProvider(
        pRegisterReceiver, pTileSource, pArchives); 
     } else { 
      archiveProvider = new MapTileFileArchiveProvider(
        pRegisterReceiver, pTileSource); 
     } 
     mTileProviderList.add(archiveProvider); 

     // cache 
     final MapTileFilesystemProvider fileSystemProvider = 
       new MapTileFilesystemProvider(pRegisterReceiver, pTileSource); 
     mTileProviderList.add(fileSystemProvider); 

     // online tiles 
     final MapTileDownloader downloaderProvider = 
       new MapTileDownloader(pTileSource, tileWriter, aNetworkAvailablityCheck); 
     mTileProviderList.add(downloaderProvider); 
    } 

    public static List<String> listArchives(final AssetManager assetManager, 
              final String subDirectory) { 
     final List<String> listArchives = new ArrayList<String>(); 
     try { 
      final String[] lstFiles = assetManager.list(subDirectory); 
      if (lstFiles != null && lstFiles.length > 0) { 
       for (final String file : lstFiles) { 
        if (isZip(file)) { 
         listArchives.add(subDirectory + "/" + file); 
        } 
        // filter files (xxxxx.xxx format) and parse only directories, 
        // with out this all files are parsed and 
        // the process is VERY slow 
        // WARNNING: we could have directories with dot for versioning 
        else if (isDirectory(file)) {// (file.lastIndexOf(".") != (file.length() - 4)) { 
         listArchives(assetManager, subDirectory + "/" + file); 
        } 
       } 
      } 
     } catch (final IOException e) { 
      Log.w(LOG_TAG, String.format("List error: can't list %s, exception %s", 
        subDirectory, Log.getStackTraceString(e))); 
     } catch (final Exception e) { 
      Log.w(LOG_TAG, String.format("List error: can't list %s, exception %s", 
        subDirectory, Log.getStackTraceString(e))); 
     } 
     return listArchives; 
    } 

    private static boolean isZip(final String file) { 
     return file.endsWith(".zip"); 
    } 

    private static boolean isDirectory(final String file) { 
     return file.lastIndexOf(".") != (file.length() - 4); 
    } 

    private static String copyAssetFile(final AssetManager assetManager, 
             final String assetRelativePath, 
             final String destinationDirectoryOnSdcard) { 
     InputStream in = null; 
     OutputStream out = null; 
     final String newfilePath = SDCARD_PATH + "/" + 
       destinationDirectoryOnSdcard + "/" + assetRelativePath; 
     final File newFile = new File(newfilePath); 
     // copy file only if it doesn't exist yet 
     if (!newFile.exists()) { 
      Log.d(LOG_TAG, String.format(
        "Copy %s map archive in assets into %s", assetRelativePath, newfilePath)); 
      try { 
       final File directory = newFile.getParentFile(); 
       if (!directory.exists()) { 
        if (directory.mkdirs()) { 
         // Log.d(LOG_TAG, "Directory created: " + directory.getAbsolutePath()); 
        } 
       } 
       in = assetManager.open(assetRelativePath); 
       out = new FileOutputStream(newfilePath); 
       copyFile(in, out); 
       in.close(); 
       in = null; 
       out.flush(); 
       out.close(); 
       out = null; 
      } catch (final Exception e) { 
       Log.e(LOG_TAG, "Exception during copyAssetFile: " + Log.getStackTraceString(e)); 
      } 
     } 
     return newfilePath; 
    } 

    private static void copyFile(final InputStream in, final OutputStream out) throws IOException { 
     final byte[] buffer = new byte[1024]; 
     int read; 
     while ((read = in.read(buffer)) != -1) { 
      out.write(buffer, 0, read); 
     } 
    } 

} 
+0

Kodunuz eksik. Erişilemeyen bir yöntem vardır: FileTools.listFiles. Onu Yorum ettik ve bunu değiştirmek için bu satırı eklendi: setZipFileArchivesPath.add ("name_of_your_map_file.zip"); .... .zip dizesini dosyaya eklemem gerekirse hala emin değilim. Kendim kontrol edeceğim. –

+0

Evet, çünkü uygulanması kolay olduğundan FileTools.listFiles kodu mevcut değil. Bu yöntem, girilen harita arşiv dizininin tüm zip dosyalarını listeler. –

İlgili konular