在手机上,离线地图包一般放在SD卡上,然后通过文件读取。引路蜂地图开发包支持同时读取多个地图包,这是通过MapTiledZone类和MapTileStreamReader类来完成的。每个地图包对应于一个MapTiledZone,地图包对每张地图建立的索引以加速图片检索将记录地图包存放的区域和缩放级别。而类MapTileStreamReader提供了管理这些地图包的方法.
离线地图工具参见:离线地图生成工具结构图 和 离线地图生成工具使用方法。
下面的示例从SD卡guidebee子目录读取world.map, china.map, nanjing.map ,更一般的做法是读取子目录下所有扩展名为.map 离线地图包,这样可以随时添加或删除离线地图包。因为是示例,所以在代码中指定读取这三个地图包。下面离线地图包为例子中用到的,是使用离线工具制作的。
文件名 | 大小 | 说明 | 下载 |
world.map | 449k | 世界地图 1-4级 | 下载 |
china.map | 181M | 中国地图 4-11级 | 下载 |
nanjing.map | 64M | 南京地图 11-17级 | 下载 |
随着缩放级别的增大,需下载的离线地图图片呈现指数增长,一般不可能将一个国家从1到17放在一个离线地图包,可以分几个层次下载制作离线地图包。如上图分3个层次。世界?>中国?>南京。
例子从SD卡中读取地图文件,在项目中添加一个MapTiledZone的派生类FileMapTiledZone ,从文件中读取离线地图。
package com.pstreets.gisengine.demo; import com.mapdigit.gis.raster.MapTiledZone; import com.mapdigit.util.Log; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileMapTiledZone extends MapTiledZone{ //////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 14AUG2009 James Shen Code review //////////////////////////////////////////////////////////////////////////// /** * constructor. * @param fileName file name of the map zone. * @param isMarkSupported does device support mark or not. * @throws FileNotFoundException */ public FileMapTiledZone(String fileName,boolean isMarkSupported) throws FileNotFoundException { super(null); this.fileName=fileName; this.isMarkSupported=isMarkSupported; } //////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 14AUG2009 James Shen Code review //////////////////////////////////////////////////////////////////////////// /** * constructor. * @param fileName file name of the map zone. * @throws FileNotFoundException */ public FileMapTiledZone(String fileName) throws FileNotFoundException { this(fileName,false); } public void ensureClose() throws IOException { if (!isMarkSupported) { super.ensureClose(); try { dataInputStream.close(); fileConnection.close(); } catch (IOException ex) { ex.printStackTrace(); } } } public DataInputStream skipBytes(long offset) { try { fileConnection=new FileInputStream(fileName); dataInputStream=new DataInputStream(fileConnection); if (offset > 0) { fileConnection.skip(offset); } } catch (Exception e) { Log.p("seek error:" + e.getMessage(), Log.ERROR); } return dataInputStream; } private FileInputStream fileConnection=null; private DataInputStream dataInputStream; }
下面代码从SD卡上读取离线地图信息:
package com.pstreets.gisengine.demo; import com.mapdigit.gis.geometry.GeoLatLng; import com.mapdigit.gis.raster.MapTileStreamReader; import com.mapdigit.gis.raster.MapType; import com.pstreets.gisengine.R; import com.pstreets.gisengine.SharedMapInstance; import android.app.Activity; import android.os.Bundle; public class StoredMap extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void onStart() { super.onStart(); GeoLatLng center = new GeoLatLng(32.0616667, 118.7777778); SharedMapInstance.map.setCenter(center, 4, MapType.MICROSOFTCHINA); MapTileStreamReader streamReader=SharedMapInstance .mapTileDownloadManager.getInteralMapTileStreamReader(); try{ FileMapTiledZone mapTileZone =new FileMapTiledZone("/sdcard/guidebee/world.map",false); streamReader.addZone(mapTileZone); mapTileZone=new FileMapTiledZone("/sdcard/guidebee/china.map",false); streamReader.addZone(mapTileZone); mapTileZone=new FileMapTiledZone("/sdcard/guidebee/nanjing.map",false); streamReader.addZone(mapTileZone); streamReader.open(); }catch(Exception e){ } } }
MapTileManager 内部定义一个MapTileStreamReader ,如果设置了本地地图,MapTileManager会先从本地读取,如果本地没有需要图片,然后再从地图服务器上下载。可以使用MapTileStreamReader的addZone 方法添加多个地图包,地图包可以有重叠的区域,这时添加的先后顺序对结果就会影响,如果有多个,则取第一个。