Arcgis runtime for Android 加载在线地
2020-09-10 本文已影响0人
_执_念__
上代码,直接复制使用,只需配置其中的一些属性即可
package com.zydl.leaderdecisionbozhou.map;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.util.Log;
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
import com.esri.arcgisruntime.arcgisservices.LevelOfDetail;
import com.esri.arcgisruntime.arcgisservices.TileInfo;
import com.esri.arcgisruntime.data.TileKey;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.SpatialReference;
import com.esri.arcgisruntime.layers.ImageTiledLayer;
import com.esri.arcgisruntime.mapping.Basemap;
import com.zydl.leaderdecisionbozhou.MyApplication;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Sch.
* Date: 2020/9/10
* description: 带有缓存功能的切片图层
*/
public class CacheTiledLayer extends ImageTiledLayer {
private String mUrl;//地图服务地址
private static String CACHE_PATH;//缓存路径
private static SpatialReference SRID = SpatialReference.create(4326);//坐标系
//tileInfo
private static int TILE_HEIGHT = 256;
private static int TILE_WIDTH = 256;
private static int DPI = 96;
private static TileInfo.ImageFormat IMAGE_FORMAT = TileInfo.ImageFormat.PNG;
private static Point sOriginPoint = new Point(-180, 90, SRID);
//lods
private static List<LevelOfDetail> sLevelOfDetails = new ArrayList<LevelOfDetail>() {
{
add(new LevelOfDetail(0, 1.40625, 591657527.594076));
add(new LevelOfDetail(1, 0.703125, 295828763.797038));
add(new LevelOfDetail(2, 0.3515625, 147914381.898519));
add(new LevelOfDetail(3, 0.17578125, 73957190.949259));
add(new LevelOfDetail(4, 0.087890625, 36978595.47463));
add(new LevelOfDetail(5, 0.0439453125, 18489297.737315));
add(new LevelOfDetail(6, 0.02197265625, 9244648.868657));
add(new LevelOfDetail(7, 0.010986328125, 4622324.434329));
add(new LevelOfDetail(8, 0.005493164062, 2311162.217164));
add(new LevelOfDetail(9, 0.002746582031, 1155581.108582));
add(new LevelOfDetail(10, 0.001373291016, 577790.554291));
add(new LevelOfDetail(11, 0.000686645508, 288895.277146));
add(new LevelOfDetail(12, 0.000343322754, 144447.638573));
add(new LevelOfDetail(13, 0.000171661377, 72223.819286));
add(new LevelOfDetail(14, 0.000085830688, 36111.909643));
add(new LevelOfDetail(15, 0.000042915344, 18055.954822));
add(new LevelOfDetail(16, 0.000021457672, 9027.977411));
add(new LevelOfDetail(17, 0.000010728836, 4513.988705));
add(new LevelOfDetail(18, 0.000005364418, 2256.994353));
}
};
private static Envelope sEnvelope = new Envelope(115.7058620453, 33.7499141693, 115.8587265015, 33.9134216309, SRID);
/**
* @param context 上下文
* @param url 地图地址
* @return Basemap
*/
public static Basemap creatBaseMap(Context context, String url) {
//去水印
ArcGISRuntimeEnvironment.setLicense("runtimelite,1000,rud4449636536,none,NKMFA0PL4S0DRJE15166");
TileInfo tileInfo = new TileInfo(DPI, IMAGE_FORMAT,
sLevelOfDetails, sOriginPoint, SRID, TILE_HEIGHT, TILE_WIDTH);
Basemap basemap = new Basemap();
basemap.getBaseLayers().add(new CacheTiledLayer(context, url, tileInfo, sEnvelope));
return basemap;
}
private CacheTiledLayer(Context context, String url, TileInfo tileInfo, Envelope envelope) {
super(tileInfo, envelope);
this.mUrl = url;
//判断SD卡是否可用
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
CACHE_PATH = context.getExternalFilesDir("MapCache").getAbsolutePath();
} else {
//没内存卡就存机身内存
CACHE_PATH = context.getFilesDir() + File.separator + "MapCache";
}
File file = new File(CACHE_PATH);
if (!file.exists()) {//判断文件目录是否存在
file.mkdirs();
}
}
@Override
protected byte[] getTile(TileKey tileKey) {
int level = tileKey.getLevel();
int col = tileKey.getColumn();
int row = tileKey.getRow();
// 若缓存存在则返回缓存字节
String fileName = col + "_" + row + ".png";
if (hasCached(level + "", fileName)) {
//本地存在
File _cacheLevelDir = new File(CACHE_PATH + "/" + level);
byte[] cachedBytes = null;
for (File _file : _cacheLevelDir.listFiles()) {
if (_file.getName().equals(fileName)) {
cachedBytes = new byte[(int) _file.length()];
try {
FileInputStream _fis = new FileInputStream(_file);
_fis.read(cachedBytes);
_fis.close();
return cachedBytes;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//本地不存在,从网络加载
if (isNetworkConnected()) {
byte[] result = downloadData(level, row, col);
return result;
}
return null;
}
/**
* 判断是否有缓存数据
*
* @param level 级别
* @param fileName 瓦片名称 row_col.png
* @return
*/
private boolean hasCached(String level, String fileName) {
File _cacheLevelDir = new File(CACHE_PATH + "/" + level);
if (!_cacheLevelDir.exists()) {
_cacheLevelDir.mkdir();
return false;
}
for (File _file : _cacheLevelDir.listFiles()) {
if (_file.getName().equals(fileName)) {//存在同名文件
try {
byte[] cachedBytes = new byte[(int) _file.length()];
FileInputStream _fis = new FileInputStream(_file);
_fis.read(cachedBytes); //文件可读
_fis.close();
return true;
} catch (Exception e) {
//文件不可读
return false;
}
}
}
//不存在同名文件
return false;
}
/**
* 是否有网络
* 需要权限 ACCESS_NETWORK_STATE
*
* @return true or false
*/
public static boolean isNetworkConnected() {
ConnectivityManager mConnectivityManager = (ConnectivityManager) MyApplication.getInstance()
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
return false;
}
/**
* 从网络加载瓦片,并保存本地
*
* @param level 级别
* @param row 行
* @param col 列
* @return 瓦片数据
*/
private byte[] downloadData(int level, int row, int col) {
byte[] result = null;
try {
URL url = new URL(mUrl + "/tile/" + level + "/" + row + "/" + col);
byte[] buf = new byte[1024];
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.connect();
BufferedInputStream is = new BufferedInputStream(httpConnection.getInputStream());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int temp = -1;
while ((temp = is.read(buf)) > 0) {
bos.write(buf, 0, temp);
}
is.close();
httpConnection.disconnect();
result = bos.toByteArray();
saveMapCache(result, col + "_" + row + ".png", level + "");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 保存瓦片本地
*
* @param bytes 瓦片数据
* @param fileName 瓦片命名
* @param level 级别
*/
private void saveMapCache(byte[] bytes, String fileName, String level) {
try {
File _cacheDir = new File(CACHE_PATH);
if (!_cacheDir.exists()) {
_cacheDir.mkdir();
}
File _cacheLevelDir = new File(CACHE_PATH + "/" + level);
if (!_cacheLevelDir.exists()) {
_cacheLevelDir.mkdir();
}
File _cacheFile = new File(_cacheLevelDir, fileName);
_cacheFile.createNewFile();
FileOutputStream _fos = new FileOutputStream(_cacheFile);
_fos.write(bytes);
_fos.close();
} catch (IOException e) {
Log.e("mapCache", "saveMapCache:" + e.toString());
}
}
}
其中
image.png
这些数据要根据地图服务中的参数去配置,
用浏览器打开地图服务,如下
image.png
替换参数即可
使用
ArcGISMap arcGISMap = new ArcGISMap();
arcGISMap.setBasemap(CacheTiledLayer.creatBaseMap(this, 地图服务地址));
mMapView.setMap(arcGISMap);
说明:根据应用规范,缓存文件存储在SDCard/Android/data/你的应用的包名/files/ 目录下,不用动态申请权限,只需在清单文件中声明即可,卸载后会一并删除,净化安卓文件环境,人人有责