ArcGIS API For Android离线地图的实现

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

[img]http://dl.iteye.com/upload/attachment/442180/f7be8282-3f31-3422-8d0d-035a1aaec30c.jpg[/img]

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卡的瓦片数据的路径

[img]http://dl.iteye.com/upload/attachment/442375/b12cda38-85f3-38f3-bfc8-d4bea527c84f.jpg[/img]


源码和测试数据在附件中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值