随着ArcGIS 10.3的正式发布,Esri推出了新的紧凑型缓存格式以增强用户的访问体验。新的缓存格式下,Esri将缓存的索引信息.bundlx包含在了缓存的切片文件.bundle中。具体如下图所示:
对于bundle格式的具体解析,这里就不再详述,具体可以查阅的博文《》,本文内容就是根据其所述实现。再熟悉bundle实现机理后,结合相关加密算法,可以实现进一步缓存数据的加密解密过程。
转载请注明出处:
以下仅列出Bundle格式数据的两种加载方式:
1、api默认加载方式
// Add Local tiled layer to MapView ArcGISLocalTiledLayer agsLocaltiledlyr = new ArcGISLocalTiledLayer("file:///mnt/sdcard/ArcGIS/sample/HelloWorld/Layers"); map.addLayer(agsLocaltiledlyr);
2、利用图层扩展自定义加载Bundle
package com.gis_luq.bundleandroid;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.RandomAccessFile;import java.util.ArrayList;import java.util.List;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Environment;import android.util.Log;import com.esri.android.map.TiledServiceLayer;import com.esri.android.map.TiledServiceLayer.TileInfo;import com.esri.core.geometry.Envelope;import com.esri.core.geometry.Point;import com.esri.core.geometry.SpatialReference;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;public class BundleLayer extends TiledServiceLayer { private String TAG = "BundleLayer"; private TileInfo tileInfo; private SpatialReference spatialReference; private Envelope fullExtent; private String compactTileLoc; //web墨卡托默认值// private double xmin = 8176078.237600003;// private double ymin = 2056264.7502700;// private double xmax = 15037808.29357646;// private double ymax = 7087593.892070787;// private Point origin = new Point(-20037508.342787001, 20037508.342787001);// private double[] scale = new double[]{591657527.591555, 295828763.79577702, 147914381.89788899, 73957190.948944002, 36978595.474472001, 18489297.737236001, 9244648.8686180003,// 4622324.4343090001,2311162.2171550002,1155581.108577,577790.55428899999,288895.27714399999,144447.638572,72223.819285999998,36111.909642999999,18055.954822,9027.9774109999998,// 4513.9887049999998,2256.994353,1128.4971760000001};// private double[] res = new double[]{156543.03392799999,78271.516963999893, 39135.758482000099, 19567.879240999901, 9783.9396204999593,4891.9698102499797, 2445.9849051249898, 1222.9924525624899, 611.49622628138002,// 305.74811314055802,152.874056570411,76.437028285073197,38.218514142536598,19.109257071268299,9.5546285356341496,4.7773142679493699,2.38865713397468,// 1.1943285668550501,0.59716428355981699,0.29858214164761698};// private int levels = 20;// private int dpi = 96;// private int tileWidth = 256;// private int tileHeight = 256; public BundleLayer(String compactTileLoc) { super(compactTileLoc); this.compactTileLoc = compactTileLoc; this.initTileInfo(compactTileLoc); this.initLayer(); } private void initTileInfo( String compactTileLoc){ //以下为需要从配置文件获取到的信息 int wkid = 102100,dpi =96,levels=20,tileCols=256,tileRows=256; double xmin =8176078.237600003, ymin = 2056264.7502700, xmax = 15037808.29357646, ymax = 7087593.892070787; double TileOrigin_x =-20037508.342787001 ,TileOrigin_y = 20037508.342787001; ListlodInfoList = new ArrayList<>(); //初始化budle相关信息 String strConf = compactTileLoc + "/Conf.xml"; DocumentBuilderFactory factory=null; DocumentBuilder builder=null; Document document=null; InputStream inputStream=null; //首先找到xml文件 factory= DocumentBuilderFactory.newInstance(); try { //找到xml,并加载文档 builder= factory.newDocumentBuilder(); File f = new File(strConf); inputStream=new FileInputStream(f); document=builder.parse(inputStream); //找到根Element Element root=document.getDocumentElement(); wkid =Integer.parseInt( root.getElementsByTagName("WKID").item(0).getChildNodes().item(0).getNodeValue()); dpi = Integer.parseInt( root.getElementsByTagName("DPI").item(0).getChildNodes().item(0).getNodeValue()); tileCols = Integer.parseInt( root.getElementsByTagName("TileCols").item(0).getChildNodes().item(0).getNodeValue()); tileRows = Integer.parseInt( root.getElementsByTagName("TileRows").item(0).getChildNodes().item(0).getNodeValue()); TileOrigin_x = Double.valueOf(root.getElementsByTagName("TileOrigin").item(0).getChildNodes().item(0).getChildNodes().item(0).getNodeValue()); TileOrigin_y = Double.valueOf(root.getElementsByTagName("TileOrigin").item(0).getChildNodes().item(1).getChildNodes().item(0).getNodeValue()); //LODInfos NodeList nodes = root.getElementsByTagName("LODInfos").item(0).getChildNodes(); levels = nodes.getLength(); //遍历根节点所有子节点,rivers 下所有river LODInfo lodInfo=null; for(int i=0;i 0){ bytesRead = isBundle.read(tileBytes, 0, tileBytes.length); if(bytesRead > 0){ bos.write(tileBytes, 0, bytesRead); } } byte[] tile = bos.toByteArray(); return tile; } public void saveBitmap(String picName, Bitmap bm) { System.out.println("保存图片"); File f = new File(Environment.getExternalStorageDirectory() + "/arcgis", picName); if (f.exists()) { f.delete(); } try { FileOutputStream out = new FileOutputStream(f); bm.compress(Bitmap.CompressFormat.PNG, 90, out); out.flush(); out.close(); System.out.println("已经保存"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public class LODInfo{ public int LevelID; public double Scale; public double Resolution; }}
使用方法:
//默认bundle数据读取方式 String localUrl= Environment.getExternalStorageDirectory().getPath() +"/bundle/Layers"; ArcGISLocalTiledLayer arcGISLocalTiledLayer = new ArcGISLocalTiledLayer(localUrl); this.mapView.addLayer(arcGISLocalTiledLayer); //自定义bundle数据读取 String local= Environment.getExternalStorageDirectory().getPath() +"/bundle/Layers"; BundleLayer bundleLayer = new BundleLayer(local); this.mapView.addLayer(bundleLayer);