今天搞了一个
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
- BaseMap.rar (1.5 MB)
- 下载次数: 395
- AgsOfflineTiles.rar (2.4 MB)
- 下载次数: 381
- 大小: 36.8 KB