`
Virgo_S
  • 浏览: 1137870 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ArcGIS API For Android离线地图的实现

阅读更多
今天搞了一个ArcGIS API For Android离线地图的实现。
效果如下:



Android的版本是2.1
main.xml,这里要说明的,初始化范围一定要有,不然会不能显示的。
<?xml version="1.0" encoding="utf-8"?>
<com.esri.android.map.MapView 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/map" android:layout_width="fill_parent" 
     android:layout_height="fill_parent"
     initExtent="120.64101459999999 31.280566089 120.6769494 31.303135911">
         
  <com.esri.arcgis.sample.AgsOfflineTiledLayer android:id="@+id/layer"/>
      
</com.esri.android.map.MapView>



AgsLOD.java
package com.esri.arcgis.sample;

import com.esri.core.internal.d.c;

public class AgsLOD extends c {
    private static final long serialVersionUID = 4341699179151728883L;
    
    private int level;
    private double resolution;
    private double scale;

    public AgsLOD(int level, double scale, double resolution) {
	super();

	this.level = level;
	this.scale = scale;
	this.resolution = resolution;
    }

    public int a() {
	return this.level;
    }

    public double b() {
	return this.resolution;
    }

    public double c() {
	return this.scale;
    }
}



AgsOfflineTiledLayer.java
package com.esri.arcgis.sample;

import java.io.File;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;

import com.esri.android.map.TiledLayer;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.internal.d.c;
import com.esri.core.internal.d.k;
import com.esri.core.map.TiledLayerModel;

public class AgsOfflineTiledLayer extends TiledLayer {

	//瓦片文件的路径呀  
	private String location = "/sdcard/BaseMap/Layers";

	//REST里面的空间参考
	private SpatialReference spatialReference = SpatialReference.create(4326);
	//全图范围
	private Envelope fullExtent = new Envelope(120.64101459999999,
			31.280566089, 120.6769494, 31.303135911);
	private k tileInfo;

	public AgsOfflineTiledLayer(Context context, AttributeSet attrs) {
		super(context, attrs);

		try {
			init();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	@Override
	protected TiledLayerModel initModel() throws Exception {
		return new AgsOfflineTiledLayerModel(location, spatialReference, fullExtent, tileInfo);
	}

	private void init() {
		String confPath = location + File.separator + "conf.xml";

		Log.i("conf", confPath);
		try {
			tileInfo = new k();

			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			File file = new File(confPath);
			Document doc = docBuilder.parse(file);

			NodeList nsX = doc.getElementsByTagName("X");
			double originX = Double.valueOf(nsX.item(0).getFirstChild()
					.getNodeValue());
			NodeList nsY = doc.getElementsByTagName("Y");
			double originY = Double.valueOf(nsY.item(0).getFirstChild()
					.getNodeValue());
			tileInfo.f = new Point(originX, originY);

			NodeList nsTileRows = doc.getElementsByTagName("TileRows");
			tileInfo.a = Integer.valueOf(nsTileRows.item(0).getFirstChild()
					.getNodeValue());

			NodeList nsTileCols = doc.getElementsByTagName("TileCols");
			tileInfo.b = Integer.valueOf(nsTileCols.item(0).getFirstChild()
					.getNodeValue());

			NodeList nsLODInfos = doc.getElementsByTagName("LODInfos");
			tileInfo.h = new ArrayList<c>();
			NodeList lodInfos = nsLODInfos.item(0).getChildNodes();
			for (int j = 0, jcount = lodInfos.getLength(); j < jcount; j++) {
				Node lod = lodInfos.item(j);
				NodeList list = lod.getChildNodes();
				int level = Integer.valueOf(list.item(0).getFirstChild()
						.getNodeValue());
				double scale = Double.valueOf(list.item(1).getFirstChild()
						.getNodeValue());
				double resolution = Double.valueOf(list.item(2).getFirstChild()
						.getNodeValue());
				tileInfo.h.add(new AgsLOD(level, scale, resolution));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}



AgsOfflineTiledLayerModel.java
package com.esri.arcgis.sample;

import java.io.File;
import java.io.FileInputStream;

import android.util.Log;

import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.internal.d.k;
import com.esri.core.map.TiledLayerModel;

public class AgsOfflineTiledLayerModel extends TiledLayerModel {
	private static final long serialVersionUID = 7726567118839553087L;

	private String location;

	public AgsOfflineTiledLayerModel(String location, SpatialReference sr,
			Envelope full, k tileInfo) {
		super(sr, full, tileInfo);

		this.location = location;
	}


	@Override
	public byte[] getTile(int level, int row, int col) throws Exception {
		byte[] result = null;
		try {
			String bundlesDir = location + File.separator + "_alllayers";

			Log.i("location", bundlesDir);
			
			String l = "0" + level;
			int lLength = l.length();
			if (lLength > 2) {
				l = l.substring(lLength - 2);
			}
			l = "L" + l;

			int rGroup = 128 * (row / 128);
			String r = "000" + Integer.toHexString(rGroup);
			int rLength = r.length();
			if (rLength > 4) {
				r = r.substring(rLength - 4);
			}
			r = "R" + r;

			int cGroup = 128 * (col / 128);
			String c = "000" + Integer.toHexString(cGroup);
			int cLength = c.length();
			if (cLength > 4) {
				c = c.substring(cLength - 4);
			}
			c = "C" + c;

			String bundleBase = String
					.format("%s/%s/%s%s", bundlesDir, l, r, c);
			String bundlxFileName = bundleBase + ".bundlx";
			String bundleFileName = bundleBase + ".bundle";

			int index = 128 * (col - cGroup) + (row - rGroup);
			FileInputStream isBundlx = new FileInputStream(bundlxFileName);
			isBundlx.skip(16 + 5 * index);
			byte[] buffer = new byte[5];
			isBundlx.read(buffer);
			long offset = (long) (buffer[0] & 0xff) + (long) (buffer[1] & 0xff)
					* 256 + (long) (buffer[2] & 0xff) * 65536
					+ (long) (buffer[3] & 0xff) * 16777216
					+ (long) (buffer[4] & 0xff) * 4294967296L;

			FileInputStream isBundle = new FileInputStream(bundleFileName);
			isBundle.skip(offset);
			byte[] lengthBytes = new byte[4];
			isBundle.read(lengthBytes);
			int length = (int) (lengthBytes[0] & 0xff)
					+ (int) (lengthBytes[1] & 0xff) * 256
					+ (int) (lengthBytes[2] & 0xff) * 65536
					+ (int) (lengthBytes[3] & 0xff) * 16777216;
			result = new byte[length];
			isBundle.read(result);
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return result;
	}

}



AgsOfflineTiles.java
package com.esri.arcgis.sample;

import com.esri.android.map.MapView;

import android.app.Activity;
import android.os.Bundle;

public class AgsOfflineTiles extends Activity {
	
	MapView map = null;
	AgsOfflineTiledLayer layer = null;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        map = (MapView) findViewById(R.id.map);
		layer = (AgsOfflineTiledLayer) findViewById(R.id.layer);       
        
    }
}

在SD卡的瓦片数据的路径




源码和测试数据在附件中

  • 大小: 44.4 KB
  • 大小: 36.8 KB
分享到:
评论
37 楼 冷酷月光 2015-08-01  
楼主。请教一下。arcgis for android 有提供地图导航api没有。新手请教一下
36 楼 zige1012 2014-04-19  
您好,我想问问我想换个自己地图的切片,也有4层(L0-L3),为什么显示不了啊?是不是要改下代码啊?
35 楼 捂不白的小黑 2014-01-25  
为什么少文件不能运行呢
34 楼 polluxll 2013-02-26  
你好,我现在使用最新的2.2 的API,在加载多个切片图层时,涉及到在某一级别可能一个切片图层就没有了,但是上一级别的切片还在地图上,随着地图中MapView的放大不断放大,有解决方法否?
@Override
protected byte[] getTile(int level, int col, int row) throws Exception {
return com.esri.core.internal.b.a.a.a(this.getMapTileUrl(level, col, row), null,d());
}
33 楼 xuyajun1979 2012-10-10  
及时雨啊,非常感谢!正在做一个项目需要做成离线的!
32 楼 Mr羽化 2012-09-28  
arcgis sdk 的版本可以给我不,现在的2.0版本找不到TiledLayerModel
31 楼 jazy 2012-09-11  
楼主,你的这个离线地图支持编辑和保存吗?  这几天在做这个的android 着急
30 楼 minjie0128 2012-04-07  
这个resolution是什么意思
29 楼 yuejie001 2012-03-29  
楼主你好:
  
这个例子我做好了,存在一个问题,就是地图从全图开始放大,放大几级以后,到了数据多的、精细的地方就显示不了了,不知道什么原因,谢谢赐教。
28 楼 ilywhax 2012-03-24  
请问下你这离线地图可不可以加载不是切片的地图?我换成我的地图(不是用切片做的)没法显示
27 楼 眼高手低 2012-02-20  
您好,我还是对com.esri.core.internal.d.c和com.esri.core.internal.d.k比较纠结。您是怎么获取这两个类的用途、属性和方法的详细信息的?或者说您在写代码的时候是怎么知道要用到这些类以及怎么用的?敬求赐教!
26 楼 hardycheng 2012-02-08  
我想问一下 :
如何在Activity中知道现在调用的是第几层的切片。

比如我想让一些信息在第三层的时候才显示,而00,01,02这些切片中地图显示的范围比较大,业务信息点不让显示,怎么实现?
25 楼 jiahui524 2011-12-09  
想问一下,万一离线数据特别大,你不用异步任务去完成不会ANR或者FC???如果用到异步任务或者Handler 又如何实现?能说下吗?
24 楼 ls6576837 2011-12-01  
请问楼主,public byte[] getTile(int level, int row, int col)这个函数返回的就是对应的切片地图的吗?
23 楼 我叫钱多多 2011-11-22  
不错 很强大 学习了
22 楼 sunshine19851 2011-10-28  
你这个是arcgis server 10的切片形式,但是针对arcgis server 10以下的切片形式又改如何处理呢?
21 楼 刀枪剑戟 2011-10-24  
qyc898 写道
楼主,我只要一建arcgis的项目,就在building workspace的时候整个eclipse卡死了...卡很久然后eclipse说内存不足就关掉了...是什么原因啊?

eclipse是3.6.2的版本,ADT是12,jdk是1.6的,操作系统是windows xp..机器配置也没有问题,2G内容双核CPU,开发普通的安卓项目和谷歌地图都正常

你需要改Eclipse的一个参数,在Eclipse目录下有eclipse.ini文件,打开,拖到最后,改成:
-Xms256m
-Xmx1024m
后者可以改得更大。参见addegg.net
20 楼 qyc898 2011-10-19  
楼主,我只要一建arcgis的项目,就在building workspace的时候整个eclipse卡死了...卡很久然后eclipse说内存不足就关掉了...是什么原因啊?

eclipse是3.6.2的版本,ADT是12,jdk是1.6的,操作系统是windows xp..机器配置也没有问题,2G内容双核CPU,开发普通的安卓项目和谷歌地图都正常
19 楼 壮壮203 2011-10-08  
hsjshijiazhuang 写道
哥们。你这程序,有时候,直接调用,会崩溃。然后再次执行,就能加载好。为啥呢???

我也是这样,求解释
18 楼 hsjshijiazhuang 2011-10-08  
哥们。你这程序,有时候,直接调用,会崩溃。然后再次执行,就能加载好。为啥呢???

相关推荐

Global site tag (gtag.js) - Google Analytics