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; } }
|