1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 《ArcGIS Runtime SDK for Android开发笔记》——(12) 自定义方式加载Bundle格式缓存数据...

《ArcGIS Runtime SDK for Android开发笔记》——(12) 自定义方式加载Bundle格式缓存数据...

时间:2019-03-12 10:36:13

相关推荐

《ArcGIS Runtime SDK for Android开发笔记》——(12) 自定义方式加载Bundle格式缓存数据...

随着ArcGIS 10.3的正式发布,Esri推出了新的紧凑型缓存格式以增强用户的访问体验。新的缓存格式下,Esri将缓存的索引信息.bundlx包含在了缓存的切片文件.bundle中。具体如下图所示:

对于bundle格式的具体解析,这里就不再详述,具体可以查阅8013是我的博文《ArcGIS for Server 10.3.X 新型紧凑型缓存的解读和应用 》,本文内容就是根据其所述实现。再熟悉bundle实现机理后,结合相关加密算法,可以实现进一步缓存数据的加密解密过程。

转载请注明出处:/gis-luq/p/5390343.html

以下仅列出Bundle格式数据的两种加载方式:

1、api默认加载方式

// Add Local tiled layer to MapViewArcGISLocalTiledLayer 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(-7508.342787001, 7508.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);pactTileLoc = 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 =-7508.342787001 ,TileOrigin_y = 7508.342787001;List<LODInfo> lodInfoList = 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);//找到根ElementElement 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());//LODInfosNodeList nodes = root.getElementsByTagName("LODInfos").item(0).getChildNodes();levels = nodes.getLength();//遍历根节点所有子节点,rivers 下所有riverLODInfo lodInfo=null;for(int i=0;i<nodes.getLength();i++){lodInfo=new LODInfo();//获取river元素节点Element riverElement=(Element)(nodes.item(i));lodInfo.LevelID =Integer.parseInt(riverElement.getChildNodes().item(0).getChildNodes().item(0).getNodeValue());lodInfo.Scale = (Double.valueOf(riverElement.getChildNodes().item(1).getChildNodes().item(0).getNodeValue()));lodInfo.Resolution = (Double.valueOf(riverElement.getChildNodes().item(2).getChildNodes().item(0).getNodeValue()));Log.d(TAG,"LevelID:"+lodInfo.LevelID +" Scale:"+lodInfo.Scale + " Resolution:"+lodInfo.Resolution);lodInfoList.add(lodInfo);}}catch (Exception e){e.printStackTrace();}finally{try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}spatialReference = SpatialReference.create(wkid);fullExtent = new Envelope(xmin, ymin, xmax, ymax);setFullExtent(fullExtent);Point origin = new Point(TileOrigin_x, TileOrigin_y);double[] scal = new double[lodInfoList.size()];double[] resls = new double[lodInfoList.size()];for (int i=0;i<lodInfoList.size();i++){scal[i] = lodInfoList.get(i).Scale;resls[i] = lodInfoList.get(i).Resolution;}tileInfo = new TileInfo(origin,scal ,resls, levels, dpi, tileCols, tileRows);} protected void initLayer() {if(getID()==0){this.nativeHandle = create();}setFullExtent(fullExtent);setTileInfo(tileInfo);setDefaultSpatialReference(spatialReference);super.initLayer();}@Overridepublic TileInfo getTileInfo() {return this.tileInfo;}@Overridepublic Envelope getFullExtent() {return this.fullExtent;}@Overridepublic SpatialReference getSpatialReference() {return this.spatialReference;}@Overrideprotected byte[] getTile(int mLevel, int mColumn, int mRow) throws Exception {//第一步,根据参数中的比例级别、列号和行号定位到Bundle文件。String level = Integer.toString(mLevel);int levelLength = level.length();if(levelLength == 1){level = "0" + level;}level = "L" + level;int rowGroup = 128*(mRow/128);String row = Integer.toHexString(rowGroup);int rowLength = row.length();if(rowLength < 4){for(int i=0; i<4-rowLength; i++){row = "0" + row;}}row = "R" + row;int columnGroup = 128*(mColumn/128);String column = Integer.toHexString(columnGroup);int columnLength = column.length();if(columnLength < 4) {for(int i=0; i<4-columnLength; i++){column = "0" + column;}}column = "C" + column;String bundleFileName = String.format("%s/%s/%s%s", compactTileLoc+"/_alllayers", level, row, column) + ".bundle";//第二步,读取bundle文件,根据前面分析中所推断出的切片的起始位置和切片的长度获取对应的切片并返回int index = 128*(mRow - rowGroup) + (mColumn-columnGroup);RandomAccessFile isBundle = new RandomAccessFile(bundleFileName, "r");isBundle.skipBytes(64 + 8*index);//获取位置索引并计算切片位置偏移量byte[] indexBytes = new byte[4];isBundle.read(indexBytes, 0, 4);long offset = (long)(indexBytes[0]&0xff) +(long)(indexBytes[1]&0xff)*256 + (long)(indexBytes[2]&0xff)*65536+ (long)(indexBytes[3]&0xff)*16777216;//获取切片长度索引并计算切片长度long startOffset = offset - 4;isBundle.seek(startOffset);byte[] lengthBytes = new byte[4];isBundle.read(lengthBytes, 0, 4);int length = (int)(lengthBytes[0] & 0xff) + (int)(lengthBytes[1] & 0xff)*256 + (int)(lengthBytes[2] & 0xff) * 65536+ (int)(lengthBytes[3] & 0xff) * 16777216;//根据切片位置和切片长度获取切片ByteArrayOutputStream bos = new ByteArrayOutputStream();byte[] tileBytes = new byte[length];int bytesRead = 0;if(length > 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);press(pressFormat.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);

文章若无特殊说明均为原创,原创作品,允许转载,转载时请务必以超链接形式标明文章出处、作者信息和本声明。博客:/gis-luq​ 作者:gis-luq 邮箱:luqiang.gis@

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。