`
Virgo_S
  • 浏览: 1138809 次
  • 性别: 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
分享到:
评论
17 楼 Virgo_S 2011-09-17  
眼高手低 写道
您能给我提供一个ArcGIS Server 10的下载地址吗?我在网上找了好几天也没找到。

呵呵,这个你要找esri中国了,不然有侵权的嫌疑了
16 楼 眼高手低 2011-09-16  
您能给我提供一个ArcGIS Server 10的下载地址吗?我在网上找了好几天也没找到。
15 楼 眼高手低 2011-09-16  
我是个新手,不太明白您说的“有一些包你在eclipse里提示可以找到”。您指的是"import com.esri.core.internal.d.k;",然后将光标放在上面后给出的那个提示吗?我的Eclipse给出的是"Note: This element has no attached source and the Javadoc could not be found in the attached Javadoc"。这应该是没有相关信息的意思吧?
14 楼 Virgo_S 2011-09-14  
眼高手低 写道
AgsOfflineTiledLayerModel.java部分从int index = 128 * (col - cGroup) + (row - rGroup);开始我就没看懂,您能给解释一下吗?


这个是瓦片的算法,建议你看一下关于esri的瓦片生成原理
13 楼 Virgo_S 2011-09-14  
眼高手低 写道
您好,我想请教一个问题。就是com.esri.core.internal.d.c和com.esri.core.internal.d.k是什么类啊?我看到工程目录中有很多这样后面是简单字母的包及类。这些在参考中又查不到。当然除了这些之外还有许多查不到的包及类。我能不能知道您是通过什么渠道学习那些参考中查不到的包及类的?我是个新人,刚刚接触ArcGIS API for Android,手上只有一个《ArcGIS API for Android+案例教程》,您能不能给推荐一些资料?我万分感谢!

有一些包你在eclipse里提示可以找到
12 楼 眼高手低 2011-09-08  
AgsOfflineTiledLayerModel.java部分从int index = 128 * (col - cGroup) + (row - rGroup);开始我就没看懂,您能给解释一下吗?
11 楼 眼高手低 2011-09-08  
您好,我想请教一个问题。就是com.esri.core.internal.d.c和com.esri.core.internal.d.k是什么类啊?我看到工程目录中有很多这样后面是简单字母的包及类。这些在参考中又查不到。当然除了这些之外还有许多查不到的包及类。我能不能知道您是通过什么渠道学习那些参考中查不到的包及类的?我是个新人,刚刚接触ArcGIS API for Android,手上只有一个《ArcGIS API for Android+案例教程》,您能不能给推荐一些资料?我万分感谢!
10 楼 anndaming 2011-08-31  
Virgo_S 写道
anndaming 写道
请问一下,你这个离线地图,是自己做的么,怎么做的?

自己做的呀,arcgis server的切图呀,要不数据不大的话,我就上传了,方便大家的

用arcgis server切的图,可以附上自己的图不?
9 楼 Virgo_S 2011-08-31  
anndaming 写道
请问一下,你这个离线地图,是自己做的么,怎么做的?

自己做的呀,arcgis server的切图呀,要不数据不大的话,我就上传了,方便大家的
8 楼 anndaming 2011-08-31  
请问一下,你这个离线地图,是自己做的么,怎么做的?
7 楼 helloandroid 2011-08-25  
呵呵,真在搞android离线地图,谢过
6 楼 Virgo_S 2011-08-17  
hjh811 写道
级别有问题  放大的时候会有问题  放大图调用不了

你需要自己根据自己的地图文件修改一下里面固定参数呀,例如:4326
5 楼 hjh811 2011-08-15  
级别有问题  放大的时候会有问题  放大图调用不了
4 楼 Virgo_S 2011-05-25  
trojantale 写道
楼主有ArcGIS for Android的离线安装包吗?为什么我在线安装老是出现错误?

没有离线安装包,可能是eclipse的版本问题吧,第一次我也有这样的问题,多试几次就好了,个人感觉,ArcGIS for Android的API发布的比较着急,并没有很好的定位
3 楼 sjrhero 2011-05-11  
我哥们儿说你很牛X:特别让我来给你送句祝福的话儿。祝你天天开心。。。他说对你顶礼膜拜  !!!!过两天他就来亲自找你了。。嘿嘿。。。
2 楼 Virgo_S 2011-04-25  
trojantale 写道
楼主有ArcGIS for Android的离线安装包吗?为什么我在线安装老是出现错误?

没有
在线安装挺容易的,是不是eclipse的版本不对呀
1 楼 trojantale 2011-04-23  
楼主有ArcGIS for Android的离线安装包吗?为什么我在线安装老是出现错误?

相关推荐

Global site tag (gtag.js) - Google Analytics