云计算百科
云计算领域专业知识百科平台

高德地图自定义服务器瓦片

项目之前用的天地图,现要求替换成自己服务器的地图瓦片!

1.添加瓦片API

官网和网上很多使用瓦片的教程

private void useOMCMap() {

final String url = "http://tile.opencyclemap.org/cycle/%d/%d/%d.png";

TileOverlayOptions tileOverlayOptions = new TileOverlayOptions().tileProvider(new UrlTileProvider(256, 256) {

@Override

public URL getTileUrl(int x, int y, int zoom) {

try {

return new URL(String.format(url, zoom, x, y));

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

});

tileOverlayOptions.diskCacheEnabled(true)

.diskCacheDir("/storage/emulated/0/amap/OMCcache")

.diskCacheSize(100000)

.memoryCacheEnabled(true)

.memCacheSize(100000)

.zIndex(-9999);

mtileOverlay = aMap.addTileOverlay(tileOverlayOptions);

}}

其中URL为在线瓦片地址,具体地址可以查看 天地图API

但我们的需求是使用自己后台提供的URL 可能涉及用户授权获取其他

2.获取服务器自定义瓦片数据

通过网络请求获取瓦片数据 这里使用okhttp

public synchronized void getImageStream(String url, Callback callback) throws Exception {
HttpRequestManager.Header[] headers = getHeaders();
OkHttpClient okhttpclient = HttpRequestManager.manager().getOkClient();
FormBody formBody = new FormBody.Builder().build();
Headers head = HttpRequestManager.manager().getDefaultHeaders(null, headers);
Request request1 = new Request.Builder()
.url(url)
.post(formBody)
.headers(head)
.build();
Call call = okhttpclient.newCall(request1);
call.enqueue(callback);
}

3.将瓦片数据保存到本地

getImageStream(real_url, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("AnbUrlTileProvider", "获取瓦片fail");
}

@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e("AnbUrlTileProvider", "获取瓦片成功 ==== " + response.toString());
if (response.code() == 200 && response.body() != null) {
InputStream in = response.body().byteStream();
try {
//保存瓦片图片数据到本地
saveFile(getImageBitmap(in), mFileName, mFileDirName);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

}
);

4.返回本地瓦片地址 

完整代码如下:

public class AnbUrlTileProvider extends UrlTileProvider {
private final String url = Constants.URL_MAP_TITLE_PROVIDER;//agrcontent/dmz/map/getMap/{z}/{x}/{y}

private final String ALBUM_PATH;

public AnbUrlTileProvider(Context context) {
super(256, 256);
ALBUM_PATH = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getPath() + "/Cache/";
}

@Override
public URL getTileUrl(int x, int y, int zoom) {
String mFileDirName = String.format("L%02d/", zoom + 1) + "title/";
String mFileName = String.format("%s", TileXYToQuadKey(x, y, zoom));//为了不在手机的图片中显示,取消jpg后缀,文件名自己定义,写入和读取一致即可,由于有自己的bingmap图源服务,所以此处我用的bingmap的文件名

String LJ = ALBUM_PATH + mFileDirName + mFileName;
Log.e("名称是否存在: ", mFileName + "getTileUrl: " + (MapImageCache.getInstance().isBitmapExit(mFileName, ALBUM_PATH + mFileDirName)) + "");
if (MapImageCache.getInstance().isBitmapExit(mFileName, ALBUM_PATH + mFileDirName)) {//判断本地是否有图片文件,如果有返回本地url,如果没有,缓存到本地并返回googleurl

try {
return new URL("file://" + LJ);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
} else {
String real_url = String.format(url, zoom, x, y);
try {
//获取服务器 图片二进制数据流
getImageStream(real_url, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("AnbUrlTileProvider", "获取瓦片fail");
}

@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e("AnbUrlTileProvider", "获取瓦片成功 ==== " + response.toString());
if (response.code() == 200 && response.body() != null) {
InputStream in = response.body().byteStream();
try {
//保存瓦片图片数据到本地
saveFile(getImageBitmap(in), mFileName, mFileDirName);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

}
);
return new URL("file://" + LJ);//返回本地瓦片图片路径
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

/**
* 瓦片数据坐标转换
*/
private String TileXYToQuadKey(int tileX, int tileY, int levelOfDetail) {
StringBuilder quadKey = new StringBuilder();
for (int i = levelOfDetail; i > 0; i–) {
char digit = '0';
int mask = 1 << (i – 1);
if ((tileX & mask) != 0) {
digit++;
}
if ((tileY & mask) != 0) {
digit++;
digit++;
}
quadKey.append(digit);
}
return quadKey.toString();
}

/**
* 保存文件
*/
public void saveFile(final Bitmap bm, final String fileName, final String fileDirName) throws IOException {
new Thread(new Runnable() {
@Override
public void run() {
try {
if (bm != null) {
File dirFile = new File(ALBUM_PATH + fileDirName);
if (!dirFile.exists()) {
dirFile.mkdirs();
Log.e("创建文件夹", (dirFile.exists()) + "");
}
File myCaptureFile = new File(ALBUM_PATH + fileDirName + fileName);
Log.e("保存路径", myCaptureFile.getPath());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bm.compress(Bitmap.CompressFormat.PNG, 80, bos);
try {
bos.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
bos.close();
}

} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}

public Bitmap getImageBitmap(InputStream imputStream) {
// 将所有InputStream写到byte数组当中
byte[] targetData = null;
if (imputStream != null) {

byte[] bytePart = new byte[4096];
while (true) {
try {
int readLength = imputStream.read(bytePart);
if (readLength == -1) {
break;
} else {
byte[] temp = new byte[readLength + (targetData == null ? 0 : targetData.length)];
if (targetData != null) {
System.arraycopy(targetData, 0, temp, 0, targetData.length);
System.arraycopy(bytePart, 0, temp, targetData.length, readLength);
} else {
System.arraycopy(bytePart, 0, temp, 0, readLength);
}
targetData = temp;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

// 指使Bitmap通过byte数组获取数据

return BitmapFactory.decodeByteArray(targetData, 0, targetData.length);
}

public synchronized void getImageStream(String url, Callback callback) throws Exception {
HttpRequestManager.Header[] headers = getHeaders();
OkHttpClient okhttpclient = HttpRequestManager.manager().getOkClient();
FormBody formBody = new FormBody.Builder().build();
Headers head = HttpRequestManager.manager().getDefaultHeaders(null, headers);
Request request1 = new Request.Builder()
.url(url)
.post(formBody)
.headers(head)
.build();
Call call = okhttpclient.newCall(request1);
call.enqueue(callback);
}

private HttpRequestManager.Header[] getHeaders() {
return new HttpRequestManager.Header[]{new HttpRequestManager.Header() {
public String getName() {
return "Content-Type";
}

public String getValue() {
return "image/webp";
}
}, new HttpRequestManager.Header() {
public String getName() {
return HttpRequestManager.SPARTA_ID;
}

public String getValue() {
return DeviceInfoUtil.getDeviceNo(MainApplication.getInstance());
}
}};
}
}

 使用瓦片后,会涉及地图坐标转换问题 参考Android中GPS坐标转换为高德地图坐标详解_Android_脚本之家 

定位小蓝点坐标会出现漂移

可以通过marker自定义定位图标   在定位后刷新

参考文章:Android 高德地图 添加 天地图 卫星瓦片图片 离线缓存_天地图 离线缓存-CSDN博客 

赞(0)
未经允许不得转载:网硕互联帮助中心 » 高德地图自定义服务器瓦片
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!