0%

安卓高德地图基础设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
<com.amap.api.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>


//地图显示start
private MapView mapView;
private AMap aMap;
private MyLocationStyle myLocationStyle;
private long lastSaveTime = 0;
private static final long SAVE_INTERVAL = 3000; // 每3秒最多写一次

private List<MapPoint> recordedPoints = new ArrayList<>();
private List<Marker> markers = new ArrayList<>();
private Polyline currentPolyline;

//地图显示end
// 初始化地图
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
if (aMap == null) {
aMap = mapView.getMap();
aMap.moveCamera(CameraUpdateFactory.zoomTo(15));
// 添加禁飞 区
// addNoFlyZones();
}
setupMap();

private void setupMap(){
myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。
myLocationStyle.interval(20000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
BitmapDescriptor myIcon = BitmapDescriptorFactory.fromResource(R.mipmap.ic_fly_control);
myLocationStyle.myLocationIcon(myIcon);
aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
//aMap.getUiSettings().setMyLocationButtonEnabled(true);设置默认定位按钮是否显示,非必需设置。
aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);//只定位一次。
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) ;//定位一次,且将视角移动到地图中心点。
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW) ;//连续定位、且将视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);//连续定位、且将视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动。(1秒1次定位)
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。
////以下三种模式从5.1.0版本开始提供
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,并且蓝点会跟随设备移动。
// myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,地图依照设备方向旋转,并且蓝点会跟随设备移动。




// 初始化定位客户端 也可以获取定位信息
// AMapLocationClient mLocationClient = null;
// try {
// mLocationClient = new AMapLocationClient(getApplicationContext());
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
// AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
// mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
// mLocationOption.setInterval(2000); // 定位间隔2秒
// mLocationClient.setLocationOption(mLocationOption);
//
// mLocationClient.setLocationListener(location -> {
// if (location != null) {
// if (location.getErrorCode() == 0) {
// // 定位成功,获取经纬度
// double latitude = location.getLatitude();
// double longitude = location.getLongitude();
// Log.d("定位", "定位成功,纬度:" + latitude + ", 经度:" + longitude);
//
// // 可更新地图中心点或UI
// runOnUiThread(() -> {
// // 比如移动摄像头到当前定位点
// aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
// new LatLng(latitude, longitude), 15));
// });
// } else {
// Log.e("定位", "定位失败,错误码:" + location.getErrorCode() +
// " 错误信息:" + location.getErrorInfo());
// }
// }
// });
// mLocationClient.startLocation();




aMap.setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
if (location != null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();

long now = System.currentTimeMillis();

// 3秒内只保存一次
if (now - lastSaveTime > SAVE_INTERVAL) {
MapPoint mapPoint = new MapPoint(latitude, longitude, "");
SPUtils.putObject(SPKeysConstance.MAP_POINT, mapPoint); // 建议内部用 apply()
lastSaveTime = now;
Log.d("定位变化", "存储纬度: " + latitude + ", 经度: " + longitude);
}

Log.d("定位变化", "纬度: " + latitude + ", 经度: " + longitude);

// 例如:更新 UI 或定位点
}
}
});

// 获取传递过来的 Bundle
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
fullView.setVisibility(GONE);
FrameLayout.LayoutParams fullParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
smallView.setLayoutParams(fullParams);

smallView.animate()
.scaleX(1f)
.scaleY(1f)
.translationX(0f)
.translationY(0f)
.setDuration(300)
.withStartAction(() -> {
fullView.setElevation(1f);
fullView.bringToFront();
})
.start();
String type = bundle.getString("type");
aMap.setOnMapClickListener(new AMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
mapNewCavns(latLng);
}
});

}else{
aMap.setOnMapClickListener(new AMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
addMarker(latLng);
}
});

}


UiSettings uiSettings = aMap.getUiSettings();
uiSettings.setZoomControlsEnabled(false); // 隐藏缩放按钮

coordinateConverter = new CoordinateConverter(this);
coordinateConverter.from(CoordinateConverter.CoordType.GPS);

}


// 在指定坐标添加标记点
private Marker addMarkerNew(AMap aMap, LatLng latLng, String title) {
// 数字 Marker(模拟 InfoWindow)
Bitmap bitmap = createNumberMarker(recordedPoints.size() + 1);
BitmapDescriptor numberIcon = BitmapDescriptorFactory.fromBitmap(bitmap);
aMap.addMarker(new MarkerOptions()
.position(new LatLng(latLng.latitude + 0.00008, latLng.longitude)) // 上方偏移一点
.icon(numberIcon)
.anchor(0.5f, 1f)
.zIndex(10)); // 保证浮在上层

return aMap.addMarker(new MarkerOptions()
.position(latLng)
.title(title)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
.draggable(true));// 确保标记点是可拖动的

}
// 连接多个点形成折线
private Polyline addPolylineNew(AMap aMap, List<LatLng> points) {
return aMap.addPolyline(new PolylineOptions()
.addAll(points)
.width(15) // 线宽
.color(Color.RED) // 醒目颜色
.zIndex(10)); // 置于上层
}
private void updatePolylineNew() {
// 如果有旧折线,先移除
if (currentPolyline != null) {
currentPolyline.remove();
}

// 如果有至少2个点,绘制连线
if (recordedPoints.size() >= 2) {
List<LatLng> points = new ArrayList<>();
for (MapPoint point : recordedPoints) {
points.add(new LatLng(point.getLatitude(), point.getLongitude()));
}
currentPolyline = addPolylineNew(aMap, points);
}
}

private void clearAllMarkers() {
// 清除所有标记
for (Marker marker : markers) {
marker.remove();
}
markers.clear();

// 清除折线
if (currentPolyline != null) {
currentPolyline.remove();
currentPolyline = null;
}

// 清空记录
recordedPoints.clear();
}



@Override
protected void onResume() {
super.onResume();

if(mapView != null){
mapView.onResume();
}

}

@Override
protected void onPause() {
super.onPause();

mapView.onPause();
}

@Override
protected void onDestroy() {
super.onDestroy();

mapView.onDestroy();
}


高德地图画矩形:
center:正方形中心点,类型是 LatLng(经纬度);

size:正方形边长(单位:米);
private void createSquare(LatLng center, double size) {
double dLat = GeometryUtils.meterToLat(size / 2);
double dLng = GeometryUtils.meterToLng(size / 2, center.latitude);

LatLng p1 = new LatLng(center.latitude + dLat, center.longitude - dLng);
LatLng p2 = new LatLng(center.latitude + dLat, center.longitude + dLng);
LatLng p3 = new LatLng(center.latitude - dLat, center.longitude + dLng);
LatLng p4 = new LatLng(center.latitude - dLat, center.longitude - dLng);

List<LatLng> points = Arrays.asList(p1, p2, p3, p4);
square = aMap.addPolygon(new PolygonOptions()
.addAll(points)
.strokeColor(Color.BLUE)
.fillColor(0x220000FF)
.strokeWidth(4));
}
获取两点间的距离:
public class GeometryUtils {
private static final double R = 6378137; // 地球半径
/**
* 将“米”转换为“纬度差”(1纬度 ≈ 111km)
* @param meter 距离(米)
* @return 纬度差值
*/
public static double meterToLat(double meter) {
return (meter / R) * (180 / PI);
}
/**
* 将“米”转换为“经度差”(因纬度不同,1经度代表的实际米数不同)
* @param meter 距离(米)
* @param lat 当前纬度
* @return 经度差值
*/
public static double meterToLng(double meter, double lat) {
return (meter / (R * cos(toRadians(lat)))) * (180 / PI);
}
/**
* 计算一组“航线段”的总长度
* 假设传入的点序列是成对出现的,每两个点组成一条线段:p0→p1、p2→p3、...
* @param points 航线点列表(经纬度)
* @return 所有线段的总长度(单位:米)
*/
public static double calculateLength(java.util.List<LatLng> points) {
double sum = 0;
for (int i = 1; i < points.size(); i += 2) {
sum += distance(points.get(i - 1), points.get(i));
}
return sum;
}
/**
* 计算两个坐标点之间的球面距离(单位:米)
* 使用 Haversine 公式,适合短距离精确计算
* @param p1 起点(纬度经度)
* @param p2 终点(纬度经度)
* @return 球面两点距离(米)
*/
public static double distance(LatLng p1, LatLng p2) {
double dLat = toRadians(p2.latitude - p1.latitude);
double dLng = toRadians(p2.longitude - p1.longitude);
double a = sin(dLat / 2) * sin(dLat / 2) + cos(toRadians(p1.latitude)) * cos(toRadians(p2.latitude)) * sin(dLng / 2) * sin(dLng / 2);
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
return R * c;
}
}