█ 【安卓学习之常见问题】百度地图卫星地图精度不够
█ 系列文章目录
提示:这里是收集了和文件分享有关的文章
- 【安卓学习之常见问题】android路径及文件问题
- 【安卓学习之常见问题】文件分享–文件不存在
- 【安卓学习之常见问题】自定义组件-刷新后跳到第一行
- 【安卓学习之常见问题】初始化spinner、CheckBox和SeekBar不触发事件
- 【安卓学习之常见问题】gradle依赖冲突
- 【安卓学习之常见问题】依赖包不存在(Transform’s input file does not exist xxx.jar)
█ 文章目录
- █ 【安卓学习之常见问题】百度地图卫星地图精度不够
- █ 系列文章目录
- █ 文章目录
- █ 读前说明
- █ 问题
- █ 解决问题
- █ 使用反射修改最大值
- █ 看下设置地图类型的过程(可忽略)
- █ 关于坐标转换
- █ 相关资料
- █ 免责声明
█ 读前说明
- 本文通过学习别人写demo,学习一些课件,参考一些博客,’学习相关知识,如果涉及侵权请告知
- 本文只简单罗列相关的代码实现过程
- 涉及到的逻辑以及说明也只是简单介绍,主要当做笔记,了解过程而已
█ 问题
- 精度不够,安卓百度地图,2D 3D最大2米,卫星最大10米;(从百度官网地app就可以看出)
- >>>>高德卫星地图和百度卫星地图都是最大为10米; 天地图(有次数限制)、谷歌地图(不能直接访问) 放大级数很多。
- 地图level对应距离(比例尺级别对应的多少米)
level | 距离(米) | level | 距离(米) |
---|---|---|---|
22: | 2; | 12: | 5000; |
21: | 5; | 11: | 10000; |
20: | 10; | 10: | 20000; |
19: | 20; | 9: | 25000; |
18: | 50; | 8: | 50000; |
17: | 100; | 7: | 100000; |
16: | 200; | 6: | 200000; |
15: | 500; | 5: | 500000; |
14: | 1000; | 4: | 1000000; |
13: | 2000; | 3: | 2000000; |
- 百度地图SDK支持21级的地图显示
地图类型或图层 | 显示层级 | 地图类型或图层 | 显示层级 |
---|---|---|---|
2D地图 | 4-21 | 路况交通图 | 11-21 |
3D地图 | 19-21 | 百度城市热力图 | 11-21 |
卫星图 | 4-20 | 室内图 | 17-22 |
█ 解决问题
- 百度地图设置最大缩放级数
baiduMap.setMaxAndMinZoomLevel(33,8);
public class BaiduMap {
private d j;// 地图状态、缩放等级等(因为混淆,所以不同版本的aar文件,打开不一定都是 d.class)
/**
* 修改百度地图的缩放级数
*/
public final void setMaxAndMinZoomLevel(float max, float min) {
if (!(max > 21.0F)) {
if (!(min < 4.0F)) {
if (!(max < min)) {
if (this.j != null) {
this.j.a(max, min);
}
}
}
}
}
}
package com.baidu.mapsdkplatform.comapi.map;
public class d implements com.baidu.mapsdkplatform.comjni.a.a.a {
private static final String l = d.class.getSimpleName();
public float a = 21.0F;
public float b = 4.0F;
public float c = 21.0F;
/**
* 修改百度地图的缩放级数 setMaxAndMinZoomLevel
*/
public void a(float max, float min) {
this.a = max;
this.c = max;
this.b = min;
if (this.P != null) {
this.P.setMaxAndMinZoomLevel(max, min);
}
if (this.i != null) {
Bundle b = new Bundle();
b.putInt("maxLevel", (int)max);
b.putInt("minLevel", (int)min);
this.i.setMaxAndMinZoomLevel(b);// nativeSetMaxAndMinZoomLevel(this.b, bundle);
}
}
}
- 可以看出来被限制了最大最小值
█ 使用反射修改最大值
- 使用反射修改最大值
// 设置缩放等级 baiduMap.j.a(max, min);
// baiduMap.setMaxAndMinZoomLevel(33,8);
try {
Class<?> mapClass = baiduMap.getClass();
Field jField = mapClass.getDeclaredField("j");
jField.setAccessible(true);
d dObject = (d) jField.get(baiduMap);
dObject.a(33.0f, 8.0f);
Log.e("999", "当前级数1 cur==" + baiduMap.getMapStatus().zoom + ",最大级数 max==" + baiduMap.getMaxZoomLevel() + ",最小级数 min ==" + baiduMap.getMinZoomLevel());
} catch (Exception e) {
Log.e("999", "修改级数1 出错==" + e.getMessage());
}
- 设置缩放监听
baiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
@Override
public void onMapStatusChangeStart(MapStatus mapStatus) {
}
@Override
public void onMapStatusChangeStart(MapStatus mapStatus, int i) {
}
@Override
public void onMapStatusChange(MapStatus mapStatus) {
}
@Override
public void onMapStatusChangeFinish(MapStatus mapStatus) {// 每次mapStatus地址都不一样
Log.e("999", "onMapStatusChangeFinish=" + mapStatus.zoom + ",cur=" + baiduMap.getMapStatus().zoom + ",max=" + baiduMap.getMaxZoomLevel() + ",min=" + baiduMap.getMinZoomLevel());
}
});
- 第一次测试效果:
2022-12-17 13:47:51.113 9088/com.xxx.debug E/999: 当前级数1 cur==12.0,最大级数 max==33.0,最小级数 min ==8.0
2022-12-17 13:47:51.643 9088/com.xxx.debug E/999: onMapStatusChangeFinish=9.0,cur=9.0,max=20.0,min=8.0
>>>>发现刚开始设置最大放大级数为33,后面又变成了20
- 发现在执行setMapType后会重新检查缩放级数:
package com.baidu.mapsdkplatform.comapi.map;
public class d implements com.baidu.mapsdkplatform.comjni.a.a.a {
private static final String l = d.class.getSimpleName();
public float a = 21.0F;
public float b = 4.0F;
public float c = 21.0F;
AppBaseMap i;
private MapController P = new MapController();
/**
* 检查缩放级数
*/
private void T() {
if (!this.q && !this.n && !this.m && !this.r) {// q=false,n=true(是否显示卫星地图),m=false,r=false
this.a = this.c;
if (this.P != null) {
this.P.mMaxZoomLevel = this.a;
}
} else {
if (this.a > 20.0F) {// a=33.0,b=8.0,c=33.0
this.a = 20.0F;
if (this.P != null) {// P.mMaxZoomLevel=33.0,P.mMinZoomLevel=8.0
this.P.mMaxZoomLevel = 20.0F;
}
}
if (this.D().a > 20.0F) {// this.D().a = 12.0
x mapStatusInner = this.D();// 地图状态的源数据
mapStatusInner.a = 20.0F;
this.a(mapStatusInner);
}
}
}
/**
* 地图状态的源数据 x(SDK中用到的MapStatus也是从这里获取)
* 将状态封装到Bundle中,再封装到x中(每次都是new)
*/
public x D() {
if (this.i == null) {
return null;
} else {
Bundle b = this.i.GetMapStatus();
x mapStatus = new x();
mapStatus.a(b);
return mapStatus;
}
}
}
package com.baidu.mapapi.map;
public class BaiduMap {
private d j;
/**
* 地图状态的源数据 x -> MapStatus
* 将状态封装到Bundle中,再封装到x中,再封装到MapStatus中(每次都是new)
*/
public final MapStatus getMapStatus() {
if (this.j == null) {
return null;
} else {
x inner = this.j.D();// 获取地图状态的源数据
return MapStatus.a(inner);
}
}
}
- 因此要重新修改下地图的缩放等级:
// 设置缩放等级 baiduMap.j.a(max, min);
// baiduMap.setMaxAndMinZoomLevel(33,8);
try {
Class<?> mapClass = baiduMap.getClass();
Field jField = mapClass.getDeclaredField("j");
jField.setAccessible(true);
d dObject = (d) jField.get(baiduMap);
dObject.a(33.0f, 8.0f);
Log.e("999", "当前级数1 cur==" + baiduMap.getMapStatus().zoom + ",最大级数 max==" + baiduMap.getMaxZoomLevel() + ",最小级数 min ==" + baiduMap.getMinZoomLevel());
} catch (Exception e) {
Log.e("999", "修改级数1 出错==" + e.getMessage());
}
// 设置地图类型
baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
// 再次设置缩放等级 baiduMap.j.T();
try {
Class<?> dClass = baiduMap.getClass();
Field nameField = dClass.getDeclaredField("j");
nameField.setAccessible(true);
d dObject = (d) nameField.get(baiduMap);
Class<?> cClass = dObject.getClass();
Field maxField = cClass.getDeclaredField("a");
maxField.setAccessible(true);
maxField.set(dObject, 33.0f);
Field mapControllerField = cClass.getDeclaredField("P");
mapControllerField.setAccessible(true);
MapController mapController = (MapController) mapControllerField.get(dObject);
mapController.mMaxZoomLevel = 33.0f;
Log.e("999", "当前级数2 cur==" + baiduMap.getMapStatus().zoom + ",最大级数 max==" + baiduMap.getMaxZoomLevel() + ",最小级数 min ==" + baiduMap.getMinZoomLevel());
} catch (Exception e) {
Log.e("999", "修改级数2 出错==" + e.getMessage());
}
- 第二次测试效果:
2022-12-17 15:42:15.381 12254/com.xxx.debug E/999: 当前级数1 cur==12.0,最大级数 max==33.0,最小级数 min ==8.0
2022-12-17 15:42:15.399 12254/com.xxx.debug E/999: 当前级数2 cur==12.0,最大级数 max==33.0,最小级数 min ==8.0
2022-12-17 15:42:15.893 12254/com.xxx.debug E/999: onMapStatusChangeFinish=8.0,cur=8.0,max=33.0,min=8.0
2022-12-17 15:43:19.349 12254/com.xxx.debug E/999: onMapStatusChangeFinish=13.777459,cur=13.777459,max=33.0,min=8.0 // 放大
2022-12-17 15:43:20.978 12254/com.xxx.debug E/999: onMapStatusChangeFinish=16.235798,cur=16.235798,max=33.0,min=8.0 // 放大
2022-12-17 15:43:22.579 12254/com.xxx.debug E/999: onMapStatusChangeFinish=20.0,cur=20.0,max=33.0,min=8.0 // 放大
2022-12-17 15:43:22.609 12254/com.xxx.debug E/999: onMapStatusChangeFinish=20.0,cur=20.0,max=33.0,min=8.0 // 放大
2022-12-17 15:46:00.808 12254/com.xxx.debug E/999: onMapStatusChangeFinish=4.0,cur=4.0,max=33.0,min=8.0 // 缩小
2022-12-17 15:46:00.824 12254/com.xxx.debug E/999: onMapStatusChangeFinish=4.0,cur=4.0,max=33.0,min=8.0 // 缩小
>>>>发现最大放大级数始终为33,但是一直放大,也只能放大到20级,而且缩小也是可以缩小到4.0 而不是 8.0,说明这个设置最大最小缩放级数 是无效的
- 要不缩放等级多设置一次(万一和nativeSetMaxAndMinZoomLevel有关系):
// 设置缩放等级 baiduMap.j.a(max, min);
// baiduMap.setMaxAndMinZoomLevel(33,8);
try {
Class<?> mapClass = baiduMap.getClass();
Field jField = mapClass.getDeclaredField("j");
jField.setAccessible(true);
d dObject = (d) jField.get(baiduMap);
dObject.a(33.0f, 8.0f);
Log.e("999", "当前级数1 cur==" + baiduMap.getMapStatus().zoom + ",最大级数 max==" + baiduMap.getMaxZoomLevel() + ",最小级数 min ==" + baiduMap.getMinZoomLevel());
} catch (Exception e) {
Log.e("999", "修改级数1 出错==" + e.getMessage());
}
// 设置地图类型
baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
// 再次设置缩放等级 baiduMap.j.T();
try {
Class<?> dClass = baiduMap.getClass();
Field nameField = dClass.getDeclaredField("j");
nameField.setAccessible(true);
d dObject = (d) nameField.get(baiduMap);
Class<?> cClass = dObject.getClass();
Field maxField = cClass.getDeclaredField("a");
maxField.setAccessible(true);
maxField.set(dObject, 33.0f);
Field mapControllerField = cClass.getDeclaredField("P");
mapControllerField.setAccessible(true);
MapController mapController = (MapController) mapControllerField.get(dObject);
mapController.mMaxZoomLevel = 33.0f;
Log.e("999", "当前级数2 cur==" + baiduMap.getMapStatus().zoom + ",最大级数 max==" + baiduMap.getMaxZoomLevel() + ",最小级数 min ==" + baiduMap.getMinZoomLevel());
} catch (Exception e) {
Log.e("999", "修改级数2 出错==" + e.getMessage());
}
// 设置缩放等级 baiduMap.j.a(max, min);
try {
Class<?> mapClass = baiduMap.getClass();
Field jField = mapClass.getDeclaredField("j");
jField.setAccessible(true);
d dObject = (d) jField.get(baiduMap);
dObject.a(33.0f, 8.0f);
Log.e("999", "当前级数3 cur==" + baiduMap.getMapStatus().zoom + ",最大级数 max==" + baiduMap.getMaxZoomLevel() + ",最小级数 min ==" + baiduMap.getMinZoomLevel());
} catch (Exception e) {
Log.e("999", "修改级数3 出错==" + e.getMessage());
}
- 第三次测试效果:
2022-12-17 15:42:15.381 12254/com.xxx.debug E/999: 当前级数1 cur==12.0,最大级数 max==33.0,最小级数 min ==8.0
2022-12-17 15:42:15.399 12254/com.xxx.debug E/999: 当前级数2 cur==12.0,最大级数 max==33.0,最小级数 min ==8.0
2022-12-17 15:42:15.893 12254/com.xxx.debug E/999: onMapStatusChangeFinish=8.0,cur=8.0,max=33.0,min=8.0
2022-12-17 15:43:19.349 12254/com.xxx.debug E/999: onMapStatusChangeFinish=13.777459,cur=13.777459,max=33.0,min=8.0 // 放大
2022-12-17 15:43:20.978 12254/com.xxx.debug E/999: onMapStatusChangeFinish=16.235798,cur=16.235798,max=33.0,min=8.0 // 放大
2022-12-17 15:43:22.579 12254/com.xxx.debug E/999: onMapStatusChangeFinish=20.0,cur=20.0,max=33.0,min=8.0 // 放大
2022-12-17 15:43:22.609 12254/com.xxx.debug E/999: onMapStatusChangeFinish=20.0,cur=20.0,max=33.0,min=8.0 // 放大
2022-12-17 15:46:00.808 12254/com.xxx.debug E/999: onMapStatusChangeFinish=4.0,cur=4.0,max=33.0,min=8.0 // 缩小
2022-12-17 15:46:00.824 12254/com.xxx.debug E/999: onMapStatusChangeFinish=4.0,cur=4.0,max=33.0,min=8.0 // 缩小
2022-12-17 15:53:20.731 13109/com.xxx.debug E/999: 当前级数1 cur==12.0,最大级数 max==33.0,最小级数 min ==8.0
2022-12-17 15:53:20.738 13109/com.xxx.debug E/999: 当前级数2 cur==12.0,最大级数 max==33.0,最小级数 min ==8.0
2022-12-17 15:53:20.740 13109/com.xxx.debug E/999: 当前级数3 cur==12.0,最大级数 max==33.0,最小级数 min ==8.0
2022-12-17 15:53:21.269 13109/com.xxx.debug E/999: onMapStatusChangeFinish=8.0,cur=8.0,max=33.0,min=8.0 // 放大
2022-12-17 15:53:29.871 13109/com.xxx.debug E/999: onMapStatusChangeFinish=11.021665,cur=11.021665,max=33.0,min=8.0 // 放大
2022-12-17 15:53:30.886 13109/com.xxx.debug E/999: onMapStatusChangeFinish=13.607431,cur=13.607431,max=33.0,min=8.0 // 放大
2022-12-17 15:53:33.068 13109/com.xxx.debug E/999:onMapStatusChangeFinish=21.0,cur=21.0,max=33.0,min=8.0 // 放大
2022-12-17 15:55:34.871 13109/com.xxx.debug E/999:onMapStatusChangeFinish=8.0,cur=8.0,max=33.0,min=8.0 // 缩小
>>>>地图竟然可以放大到了21级5米,比正常多了有一个级数
- 等级虽然放大到21级,但是看不到卫星图,只剩下 标注、高铁和地铁等信息(不显示 高速路、桥、隧道、省道):
█ 看下设置地图类型的过程(可忽略)
baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);// 设置地图类型 2,表示 卫星图
public class BaiduMap {
private d j;// 地图状态、缩放等级等(因为混淆,所以不同版本的aar文件,打开不一定都是 d.class)
/**
* 设置地图类型
*/
public final void setMapType(int type) {
if (this.j != null) {
Map<String, Object> map = new HashMap();
map.put("T", type);
com.baidu.platform.comapi.a.h.a().a("B", "M", "4", map);
switch(type) {// type = 2
case 1:
。。。。。。
break;
case 2:
this.j.a(true);// 执行这个 ShowSatelliteMap
this.j.B(this.T);
this.j.C(this.U);// ShowLayers
this.j.j(true);
break;
case 3:
。。。。。。
}
if (OpenLogUtil.isMapLogEnable()) {
com.baidu.mapsdkplatform.comapi.commonutils.b.a().a("BasicMap setMapType type = " + type);
}
}
}
}
public class d implements com.baidu.mapsdkplatform.comjni.a.a.a {
public void a(boolean on) {
if (this.i != null) {
this.n = on;// 是否显示卫星地图
this.T();// 执行这个
this.i.ShowSatelliteMap(this.n);
if (this.P != null) {
if (on) {
this.P.setMapTheme(2, new Bundle());
} else {
this.P.setMapTheme(1, new Bundle());
}
}
}
}
}
public class d implements com.baidu.mapsdkplatform.comjni.a.a.a {
/**
* 检查缩放级数
*/
private void T() {
if (!this.q && !this.n && !this.m && !this.r) {// q=false,n=true(是否显示卫星地图),m=false,r=false
this.a = this.c;
if (this.P != null) {
this.P.mMaxZoomLevel = this.a;
}
} else {
if (this.a > 20.0F) {// a=33.0,b=8.0,c=33.0
this.a = 20.0F;
if (this.P != null) {// P.mMaxZoomLevel=33.0,P.mMinZoomLevel=8.0
this.P.mMaxZoomLevel = 20.0F;
}
}
if (this.D().a > 20.0F) {// this.D().a = 12.0
x mapStatusInner = this.D();// 地图状态的源数据
mapStatusInner.a = 20.0F;
this.a(mapStatusInner);
}
}
}
}
█ 关于坐标转换
-
坐标系
WGS84坐标系(世界大地坐标系统) GPS坐标系,由美国国防部制图局建立,是目前广泛使用的GPS全球卫星定位系统使用的坐标系 CGCS2000坐标系(国家大地坐标 ) GPS坐标系,自2008年7月1日起,中国全面启用2000国家大地坐标系 GCJ-02(又叫火星坐标系) 国测局02年发布的坐标,经过特殊算法将实际的坐标加密成新的坐标,通常国内多家地图厂商都用这个。 BD09坐标 百度坐标系。在GCJ-02坐标系基础上再次加密 -
不同地图使用的坐标系
地图 | 坐标系 | 说明 |
---|---|---|
手机GPS | WGS-84坐标系 | 安卓和ios原生方法获取到的是WGS84坐标系的坐标 |
天地图 | CGCS-2000坐标系 | 中国当前最新的国家大地坐标系,与WGS84坐标系都是地心坐标系,相差不大。 |
高德-境内 | GCJ-02坐标系 | 在WGS84坐标系上进行了一次加密得到的坐标系 |
google地图-境内 | GCJ-02坐标系 | 数据来源于高德 |
google地图-境外 | WGS-84坐标系 | GPS坐标系 |
百度-境内 | BD-09坐标系 | 在GCJ-02上再进行了一次加密得到的 |
百度-境外 | WGS-84坐标系 | GPS坐标系 |
腾讯地图(soso)-境内 | GCJ-02坐标系 | 在WGS84坐标系上进行了一次加密得到的坐标系 |
微软bing地图(BingMap) | WGS-84坐标系 | GPS坐标系 |
搜狗地图-境内 | 搜狗坐标系 | 在GCJ-02上再进行了一次加密得到的 |
图吧地图(MapBar)-境内 | 图吧坐标系 | 在GCJ-02上再进行了一次加密得到的 |
阿里云地图-境内 | GCJ-02坐标系 | 在WGS84坐标系上进行了一次加密得到的坐标系 |
灵图地图(51ditu)-境内 | GCJ-02坐标系 | 在WGS84坐标系上进行了一次加密得到的坐标系 |
- 百度坐标和火星坐标的转换1:CoordinateConverter
//初始化左边转换工具类,指定源坐标类型和坐标数据
//sourceLatLng 待转换坐标
CoordinateConverter converter = new CoordinateConverter()
.from(COMMON)
.coord(sourceLatLng);
//转换坐标
LatLng desLatLng = converter.convert();
- 百度坐标和火星坐标的转换2:CoordTrans
public class CoordTrans {
public CoordTrans() {
}
public static LatLng baiduToGcj(LatLng latLng) {
if (null == latLng) {
return null;
} else {
double[] gcjLatLng = JNITools.baiduToGcj(latLng.latitude, latLng.longitude);
return null == gcjLatLng ? null : new LatLng(gcjLatLng[0], gcjLatLng[1]);
}
}
public static LatLng gcjToBaidu(LatLng latLng) {
if (null == latLng) {
return null;
} else {
double[] bdLatLng = JNITools.gcjToBaidu(latLng.latitude, latLng.longitude);
return null == bdLatLng ? null : new LatLng(bdLatLng[0], bdLatLng[1]);
}
}
public static LatLng wgsToBaidu(LatLng latLng) {
if (null == latLng) {
return null;
} else {
double[] bdLatLng = JNITools.wgsToBaidu(latLng.latitude, latLng.longitude);
return null == bdLatLng ? null : new LatLng(bdLatLng[0], bdLatLng[1]);
}
}
}
█ 相关资料
提示:这里是参考的相关文章
- 2015-11-27 百度地图API二:根据标注点坐标范围计算显示缩放级别zoom自适应显示地图_liusaint1992的博客-CSDN博客_百度地图不同zoom对应的范围
- 没答案2015-12-21 百度地图提供的安卓API怎样提高最大放大级别?-移动开发-CSDN问答
- js版本2020-07-16 百度地图突破19级缩放限制解决方案_lihefei_coder的博客-CSDN博客
- 最新版本支持2021.08.31 百度地图web端SDK最大只能缩放到20米问题-百度开发者中心
- 2D版本19级10米。BMapGL 3D版本21级5米2022年5月13日 地图升级一下 — 希望缩放级别能提高点 - 点击领取
- 2022-09-03 国内常用地图坐标系_任玉的博客-CSDN博客_地图坐标系
- 2022-08-05 《学习总结》天地图_快学点111的博客-CSDN博客_天地图用的是什么坐标系
█ 免责声明
博主分享的所有文章内容,部分参考网上教程,引用大神高论,部分亲身实践,记下笔录,内容可能存在诸多不实之处,还望海涵,本内容仅供学习研究使用,切勿用于商业用途,若您是部分内容的作者,不喜欢此内容被分享出来,可联系博主说明相关情况通知删除,感谢您的理解与支持! |
---|
转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/128350559