您的位置:首页 > 其它

重写TiledServiceLayer实现本地缓存

2013-05-28 00:17 204 查看
有时候移动端网络不是很稳定,而且在没有Wifi情况下访问非常费流量,网速也较慢,因此实现本地缓存功能已经显得刻不容缓了。虽然现在Arcgis官方对Android还不支持这个功能,但我们完全可以自己去实现。其实思路很简单,就是在每次访问服务端的之前去判断本地是否有这个图片,如果有就读取本地的,否则去服务端获取并保存到本地。可以更形象一点:

if(本地是否有这个切片){
读取本地图片;
}else{
去服务端获取;
保存到本地;
}
对就是这么简单,下面我们看代码。

一些的参数

private Envelope fullExtent = new Envelope(38271382.590048, 3958604.25302, 38524317.872452, 4118706.90518);//全服范围
private Envelope initExtent = new Envelope(38271382.590048, 3958604.25302, 38524317.872452, 4118706.90518);//初始范围
private TileInfo tileInfo; //TiledServiceLayer.TileInfo
private SpatialReference spatialReference;//空间参考
private String layerurl; //Url
private String cachepath;//本地存储路径
初始化Tileinfo

private void initTileInfo(){
spatialReference = SpatialReference.create(2363); //空间参考
/*原点坐标*/
Point localPoint = new Point(3.28768E7,1.00021E7);
/*地图分辨率*/
double[] arrayOfDoubleres = {529.16772500211675, 264.58386250105838, 132.29193125052919,
66.145965625264594, 33.072982812632297, 16.933367200067735,
8.4666836000338677,4.2333418000169338, 2.1166709000084669,
1.0583354500042335, 0.52916772500211673, 0.26458386250105836};
/*地图比例尺*/
double[] arrayOfDoublescale = {2000000.0, 1000000.0, 500000.0, 250000.0, 125000.0, 64000.0, 32000.0, 16000.0,
8000.0, 4000.0, 2000.0, 1000.0};
int levels = arrayOfDoublescale.length;
int dpi=96;
int tileHeight = 256;//图片高度
int tileWidth = 256;//图片宽度
tileInfo = new TileInfo(localPoint, arrayOfDoublescale, arrayOfDoubleres,levels, dpi, tileWidth, tileHeight);
}
重载initLayer()方法

@Override
protected void initLayer() {
// TODO Auto-generated method stub
if(getID()==0){
this.nativeHandle = create();
}
setFullExtent(fullExtent);//设置全服地图范围
setTileInfo(tileInfo);//设置tileInfo
setInitialExtent(initExtent);//设置初始化地图范围
setDefaultSpatialReference(spatialReference);//设置空间参考
super.initLayer();
}
重载geTile()方法

@Override
protected byte[] getTile(int level, int col, int row) throws Exception {
// TODO Auto-generated method stub
byte[] bytes = getOfflineCacheFile(level,col,row);//从本地获取图片
if (bytes == null) {//如果本地没有则去服务端获取
HashMap localHashMap = new HashMap();
bytes = a.a(strlayer, localHashMap);
AddOfflineCacheFile(level, col, row, bytes);//保存到本地
}
}
return bytes;
}
下面是完整的代码

package com.test.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;

import android.util.Log;

import com.esri.android.map.TiledServiceLayer;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.internal.b.a.a;
/**
*
* @ClassName: OfflineCacheTiledServiceLayer
* @Description: 实现本地缓存
* @author: Zrd
* @version: v1.0
* @modify: TODO(版本修改信息)
*/

public class OfflineCacheTiledServiceLayer extends TiledServiceLayer {
private SpatialReference spatialReference; //空间参考
private Envelope fullExtent = new Envelope(38271382.590048, 3958604.25302, 38524317.872452, 4118706.90518);//全服范围
private Envelope initExtent = new Envelope(38271382.590048, 3958604.25302, 38524317.872452, 4118706.90518);//初始范围
private TileInfo tileInfo; //TiledServiceLayer.TileInfo

private String layerurl; //Url
private String cachepath;//本地存储路径

public OfflineCacheTiledServiceLayer(String layerurl,String cachepath) {
super(layerurl);
// TODO Auto-generated constructor stub
this.layerurl = layerurl;
this.cachepath = cachepath;
initTileInfo();
OfflineCacheTiledServiceLayer.this.initLayer();
}
private void initTileInfo(){
spatialReference = SpatialReference.create(2363); //空间参考
/*原点坐标*/
Point localPoint = new Point(3.28768E7,1.00021E7);
/*地图分辨率*/
double[] arrayOfDoubleres = {529.16772500211675, 264.58386250105838, 132.29193125052919,
66.145965625264594, 33.072982812632297, 16.933367200067735,
8.4666836000338677,4.2333418000169338, 2.1166709000084669,
1.0583354500042335, 0.52916772500211673, 0.26458386250105836};
/*地图比例尺*/
double[] arrayOfDoublescale = {2000000.0, 1000000.0, 500000.0, 250000.0, 125000.0, 64000.0, 32000.0, 16000.0, 8000.0, 4000.0, 2000.0, 1000.0};
int k = arrayOfDoublescale.length;
int dpi=96;
int tileHeight = 256;//图片高度
int tileWidth = 256;//图片宽度
tileInfo = new TileInfo(localPoint, arrayOfDoublescale, arrayOfDoubleres, k, dpi, tileWidth, tileHeight);
}

@Override protected void initLayer() { // TODO Auto-generated method stub if(getID()==0){ this.nativeHandle = create(); } setFullExtent(fullExtent);//设置全服地图范围 setTileInfo(tileInfo);//设置tileInfo setInitialExtent(initExtent);//设置初始化地图范围 setDefaultSpatialReference(spatialReference);//设置空间参考 super.initLayer(); }

@Override
public TileInfo getTileInfo() {
// TODO Auto-generated method stub
return this.tileInfo;
}

@Override
public Envelope getFullExtent() {
// TODO Auto-generated method stub
return this.fullExtent;
}

@Override
public SpatialReference getSpatialReference() {
// TODO Auto-generated method stub
return this.spatialReference;
}

@Override
protected byte[] getTile(int level, int col, int row) throws Exception {
// TODO Auto-generated method stub
System.out.println("level=" + level + " col=" + col + " row=" + row);
String strlayer = layerurl+"/tile/"+level+"/"+row+"/"+col;
System.out.println(strlayer);
Log.i("strlayer", strlayer);
byte[] bytes = getOfflineCacheFile(level,col,row);
if (bytes == null) {
HashMap localHashMap = new HashMap();
bytes = a.a(strlayer, localHashMap);
Log.e("test", bytes.toString());
AddOfflineCacheFile(level, col, row, bytes);
}
}
return bytes;
}
//将图片保存到本地 目录结构可以随便定义 只要你找得到对应的图片
private byte[] AddOfflineCacheFile(int level, int col, int row,byte[] bytes){
File file = new File(cachepath);
if(!file.exists()){
file.mkdirs();
}
File levelfile = new File(cachepath+"/"+level);
if(!levelfile.exists()){
levelfile.mkdirs();
}
File colfile = new File(cachepath+"/"+level+"/"+col);
if(!colfile.exists()){
colfile.mkdirs();
}
File rowfile = new File(cachepath+"/"+level+"/"+col+"/"+row+".dat");
if(!rowfile.exists()){
try {
FileOutputStream out = new FileOutputStream(rowfile);
out.write(bytes);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return bytes;

}
//从本地获取图片
private byte[] getOfflineCacheFile(int level, int col, int row){
byte[] bytes = null;
File rowfile = new File(cachepath+"/"+level+"/"+col+"/"+row+".dat");
if(rowfile.exists()){
try {
bytes = CopySdcardbytes(rowfile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
bytes = null;
}
return bytes;
}
//读取本地图片流
public byte[] CopySdcardbytes(File file) throws IOException
{
FileInputStream in = new FileInputStream(file);

ByteArrayOutputStream out = new ByteArrayOutputStream(1024);

byte[] temp=new byte[1024];

int size=0;

while((size=in.read(temp))!=-1)
{
out.write(temp,0,size);
}
in.close();
byte[] bytes=out.toByteArray();
return bytes;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: