当前互联网地图的坐标系现状
地球坐标 (WGS84)
- 国际标准,从专业GPS 设备中取出的数据的坐标系
- 国际地图提供商使用的坐标系
火星坐标 (GCJ-02)也叫国测局坐标系
- 中国标准,从国行移动设备中定位获取的坐标数据使用这个坐标系
- 国家规定: 国内出版的各种地图系统(包括电子形式),必须至少采用GCJ-02对地理位置进行首次加密。
百度坐标 (BD-09)
- 百度标准,百度 SDK,百度地图,Geocoding 使用
从设备获取经纬度(GPS)坐标
如果使用的是百度sdk那么可以获得百度坐标(bd09)或者火星坐标(GCJ02),默认是bd09
如果使用的是ios的原生定位库,那么获得的坐标是WGS84
如果使用的是高德sdk,那么获取的坐标是GCJ02
添加标记
1 private Marker addMarker(LatLng latlng, int icon, String text, String snippet) { 2 MarkerOptions markerOptions = new MarkerOptions(); 3 markerOptions.anchor(0.5f, 1f) 4 .icon(getBitmapDes(this, icon, text)) 5 .alpha(0.9F) 6 .position(latlng) 7 .title(snippet); 8 9 return mAmap.addMarker(markerOptions); 10 } 11 12 private BitmapDescriptor getBitmapDes(Context context, int icon, String title) { 13 TextView textView = new TextView(context); 14 ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( 15 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 16 17 textView.setLayoutParams(layoutParams); 18 textView.setText(title); 19 textView.setGravity(Gravity.CENTER); 20 textView.setTextColor(Color.WHITE); 21 textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17); 22 textView.setBackgroundResource(icon); 23 24 return BitmapDescriptorFactory.fromView(textView); 25 }
添加范围圆圈
1 private Circle addCircle(LatLng latlng, double radius) { 2 CircleOptions options = new CircleOptions(); 3 options.strokeWidth(3f); 4 options.fillColor(FILL_COLOR); 5 options.strokeColor(STROKE_COLOR); 6 options.center(latlng); 7 options.radius(radius); 8 return mAmap.addCircle(options); 9 }
去logo水印
mAmap.getUiSettings().setLogoBottomMargin(-50);
自定义弹出气泡布局
mAmap.setInfoWindowAdapter(new AMap.InfoWindowAdapter() { @Override public View getInfoWindow(Marker marker) { TextView textView = (TextView) View.inflate(SignInActivity.this, R.layout.custom_info_window, null); textView.setText(marker.getTitle()); return textView; } @Override public View getInfoContents(Marker marker) { return null; } });
逆地理编码
mGeocoderSearch = new GeocodeSearch(this); mGeocoderSearch.setOnGeocodeSearchListener(this);
private void geoAddress(LatLonPoint latLonPoint) { if (latLonPoint != null){ // 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系 RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 100, GeocodeSearch.AMAP); mGeocoderSearch.getFromLocationAsyn(query); } }
@Override public void onRegeocodeSearched(RegeocodeResult result, int rCode) { if (rCode == AMapException.CODE_AMAP_SUCCESS) { if (result != null && result.getRegeocodeAddress() != null && result.getRegeocodeAddress().getFormatAddress() != null) { tvLoc.setText(result.getRegeocodeAddress().getFormatAddress()); } } else { Log.e("SignInActivity", "onRegeocodeSearched error:" + rCode); } } @Override public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {}
判断距离
float distance = AMapUtils.calculateLineDistance(checkpoint, myLocLatlng);
坐标转换
1 public class CoordinateConverter { 2 3 private static final double PI = 3.1415926535897932384626; 4 private static final double a = 6378245.0; 5 private static final double ee = 0.00669342162296594323; 6 7 /** 8 * 地球坐标(WGS84)转火星坐标系(GCJ-02) 9 * @param wgs_lon 10 * @param wgs_lat 11 * @return double[lon,lat] 12 */ 13 public static double[] gps2mars(double wgs_lat, double wgs_lon){ 14 if(outOfChina(wgs_lon, wgs_lat)){ 15 return new double[]{wgs_lon,wgs_lat}; 16 } 17 double dlat = transformlat(wgs_lon - 105.0, wgs_lat - 35.0); 18 double dlng = transformlng(wgs_lon - 105.0, wgs_lat - 35.0); 19 double radlat = wgs_lat / 180.0 * PI; 20 double magic = Math.sin(radlat); 21 magic = 1 - ee * magic * magic; 22 double sqrtmagic = Math.sqrt(magic); 23 dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); 24 dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); 25 double[] arr = new double[2]; 26 arr[0] = wgs_lat + dlat; 27 arr[1] = wgs_lon + dlng; 28 return arr; 29 } 30 31 /** 32 * 火星坐标系(GCJ-02) 转 地球坐标(WGS84) 33 * @param gcj_lon 34 * @param gcj_lat 35 * @return double[lon,lat] 36 */ 37 public static double[] mars2gps(double gcj_lat, double gcj_lon){ 38 if(outOfChina(gcj_lon, gcj_lat)){ 39 return new double[]{gcj_lon,gcj_lat}; 40 } 41 double dlat = transformlat(gcj_lon - 105.0, gcj_lat - 35.0); 42 double dlng = transformlng(gcj_lon - 105.0, gcj_lat - 35.0); 43 double radlat = gcj_lat / 180.0 * PI; 44 double magic = Math.sin(radlat); 45 magic = 1 - ee * magic * magic; 46 double sqrtmagic = Math.sqrt(magic); 47 dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); 48 dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); 49 double mglat = gcj_lat + dlat; 50 double mglng = gcj_lon + dlng; 51 52 return new double[]{gcj_lat * 2 - mglat, gcj_lon * 2 - mglng}; 53 } 54 55 public static LatLng mars2gps(LatLng marsLatlng) { 56 double[] coords = mars2gps(marsLatlng.latitude, marsLatlng.longitude); 57 return new LatLng(coords[0], coords[1]); 58 } 59 60 public static LatLng gps2mars(Context context, LatLng gpsLatlng) { 61 double[] c = gps2mars(gpsLatlng.latitude, gpsLatlng.longitude); 62 return new LatLng(c[0], c[1]); 63 } 64 65 private static double transformlat(double lng, double lat) { 66 double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); 67 ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; 68 ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; 69 ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0; 70 return ret; 71 } 72 73 private static double transformlng(double lng,double lat) { 74 double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); 75 ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; 76 ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; 77 ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0; 78 return ret; 79 } 80 81 /** 82 * outOfChina 83 * @描述: 判断是否在国内,不在国内则不做偏移 84 * @param lng 85 * @param lat 86 * @return {boolean} 87 */ 88 private static boolean outOfChina(double lng,double lat) { 89 return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false); 90 } 91 92 }