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

源码和测试数据在附件中

BaseMap.rar (1.5 MB)

AgsOfflineTiles.rar (2.4 MB)

原文链接:http://virgoooos.iteye.com/blog/969772

原文地址:https://www.cnblogs.com/dwf07223/p/3090776.html