Android 开发日志之LBS相关开发

   根据公司业务需求的展开,需要接入地图,并且在地图上画轨迹曲线以及自定义画区域等等。地图api可以接入百度,高德,或者google。下面以项目接入的高德地图api为例;

高德开放平台文档:https://lbs.amap.com/api/webservice/guide/create-project/get-key

按照项目具体需求下载相应的SDK,放入项目libs中;

(注意为了兼容不同手机配置的地图.so文件比较多,而.so文件比较大,为了控制包大小,可以放弃部分兼容,这涉及到包大小优化,在文章里面有讲到 https://blog.csdn.net/and_caicai/article/details/105508306

1.配置 AndroidManifest.xml 文件

在AndroidManifest.xml的application标签中配置Key:(key需要在高德开放平台创建项目获得)

<meta-data
    android:name="com.amap.api.v2.apikey"
    android:value="您的Key"/>

2.在AndroidManifest.xml中配置权限:

//地图包、搜索包需要的基础权限 <!--允许程序打开网络套接字--> <uses-permission android:name="android.permission.INTERNET" /> <!--允许程序设置内置sd卡的写权限--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!--允许程序获取网络状态--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!--允许程序访问WiFi网络信息--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!--允许程序读写手机状态和身份--> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!--允许程序访问CellID或WiFi热点来获取粗略的位置--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

3.配置XML布局文件  在布局xml文件中添加地图控件;

<com.amap.api.maps.MapView
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</com.amap.api.maps.MapView>

4..地图展示

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.basicmap_activity);//设置对应的XML布局文件
    
    MapView mapView = (MapView) findViewById(R.id.map);
    mapView.onCreate(savedInstanceState);// 此方法必须重写
    AMap aMap = mapView.getMap();
    
}

5.地图显示时候的一些设置

	    mMapTracking.onCreate(savedInstanceState);// 此方法须覆写。
		//地图
		if (mAMap == null) {
			mAMap = mMapTracking.getMap();
		}
		UiSettings mUiSettings = mAMap.getUiSettings();
		mUiSettings.setZoomGesturesEnabled(true);//设置地图是否可以手势缩放大小
		mUiSettings.setScrollGesturesEnabled(true);//设置地图是否可以手势滑动
		mUiSettings.setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示
		mUiSettings.setZoomControlsEnabled(false);//设置地图默认的缩放按钮是否显示
		mUiSettings.setLogoBottomMargin(-100);//隐藏logo
		mAMap.moveCamera(CameraUpdateFactory.zoomTo(8));

		/*将GPS定位座标类型转换为高德*/
		CoordinateConverter converter = new CoordinateConverter(context);
		// CoordType.GPS 待转换座标类型
		converter.from(CoordinateConverter.CoordType.GPS);

在这里需要提一句,

* WGS84: Google Earth采用,Google Map中国范围外使用
* GCJ02: 火星座标系,中国国家测绘局制定的座标系统,由WGS84机密后的座标。Google Map中国和搜搜地图使用,高德
* BD09:百度座标,GCJ02机密后的座标系
* 搜狗座标系,图吧座标等,估计也是在GCJ02基础上加密而成的

百度地图 高德地图座标系不同,通过接口获得数据点 如果是不同座标系需要进行转换。

6.根据座标获取具体位置

   //异步查询座标
  private void getAddressByLatlng(LatLng latLng) {
		//逆地理编码查询条件:逆地理编码查询的地理座标点、查询范围、座标类型。
		LatLonPoint latLonPoint = new LatLonPoint(latLng.latitude, latLng.longitude);
		RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 500f, GeocodeSearch.AMAP);
		//异步查询
		geocodeSearch.getFromLocationAsyn(query);
	}



    //异步查询结果监听
    geocodeSearch = new GeocodeSearch(context);
	geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
			@Override
			public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {//得到逆地理编码异步查询结果
				RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();
				String formatAddress = regeocodeAddress.getFormatAddress();
				simpleAddress = formatAddress.substring(9);
				if(!Tools.isEmpty(simpleAddress)){
					tv_out_address.setText(simpleAddress+"");
				}else{
					tv_out_address.setText("");
				}
				DLog.e("LocusFragment","查询经纬度对应详细地址:\n" + simpleAddress);
			}

			@Override
			public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

			}
		});

7.根据获取的点在地图上画轨迹曲线(及自定义画线)

	/*车辆行驶轨迹*/
	private void setMapTracking(final List<GPSDataBean> gpsDataList, RealTimeTruckBean bean) {
		List<Integer> colorList=new ArrayList<>();
		List<LatLng> latList=new ArrayList<>();
		mPolylineOptions = new PolylineOptions();
		mPolylineOptions.width(10);
		mPolylineOptions.zIndex(10f);
		markerOption = new MarkerOptions();
		if (NotNull.isNotNull(bean)) {
			//			addTruckOnTimeMarker(bean);
		}

		mAMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
			@Override
			public boolean onMarkerClick(Marker marker) {
				LatLng latLngMarker = new LatLng(marker.getPosition().latitude, marker.getPosition().longitude);
				newbounds.include(latLngMarker);
				CameraUpdate mCameraUpdate = CameraUpdateFactory.newLatLngBounds(newbounds.build(), 15);
				//加上这句好像点击mark后不能显示在屏幕内
				// mAMap.animateCamera(mCameraUpdate);
				return false;
			}
		});

		mAMap.setOnInfoWindowClickListener(new AMap.OnInfoWindowClickListener() {
			@Override
			public void onInfoWindowClick(Marker marker) {
				marker.hideInfoWindow();
			}
		});
		if (!NotNull.isNotNull(gpsDataList) || gpsDataList.size() <= 0) {
			mHandler.post(new Runnable() {
				@Override
				public void run() {
					showTips("无GPS数据");
					closeProgressDialog();
				}
			});

			if (bean != null) {
				if (NotNull.isNotNull(bean.getY()) && NotNull.isNotNull(bean.getX())) {
					LatLng mCenterLatLng = new LatLng(Double.parseDouble(bean.getY()), Double.parseDouble(bean.getX()));
					CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(mCenterLatLng, 10, 0, 0));
					mAMap.animateCamera(mCameraUpdate);
				}
			}
			return;
		}
		double x=0;
		double y=0;
		for (int i = 0; i < gpsDataList.size(); i++) {
			// sourceLatLng待转换座标点 LatLng类型
			if (NotNull.isNotNull(gpsDataList.get(i).getY())&& NotNull.isNotNull(gpsDataList.get(i).getX())){
				LatLng sourceLatLng = new LatLng(Double.parseDouble(gpsDataList.get(i).getY()), Double.parseDouble(gpsDataList.get(i).getX()));
				converter.coord(sourceLatLng);
				// 执行转换操作
				LatLng desLatLng = converter.convert();
				latList.add(desLatLng);
				colorList.add(getColorList(gpsDataList.get(i)));
				 x += sourceLatLng.latitude;
				 y += sourceLatLng.longitude;


				if (i == 0) {
					converter.coord(new LatLng(Double.parseDouble(gpsDataList.get(0).getY()), Double.parseDouble(gpsDataList.get(0).getX())));
					// 执行转换操作
					LatLng startLatLng = converter.convert();
					markerOption.position(startLatLng);
					if (NotNull.isNotNull(gpsDataList.get(0).getWeight())) {
						double gpsDataWeight = Double.parseDouble(gpsDataList.get(0).getWeight());
						gpsWeightStart = myformat.format(gpsDataWeight);
					}

					markerOption.title("设备ID:" + truckModel.getDeviceId() + "\n车牌号:" + truckModel.getCarNumber() + "\n车重:" + gpsWeightStart + "(吨)").snippet("日期:" + gpsDataList.get(0).getDate());
					markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.start)));
				} else if (i == gpsDataList.size() - 1) {
					converter.coord(new LatLng(Double.parseDouble(gpsDataList.get(gpsDataList.size() - 1).getY()), Double.parseDouble(gpsDataList.get(gpsDataList.size() - 1).getX())));
					// 执行转换操作
					LatLng endtLatLng = converter.convert();
					markerOption.position(endtLatLng);
					if (NotNull.isNotNull(gpsDataList.get(gpsDataList.size() - 1).getWeight())) {
						double gpsDataWeight = Double.parseDouble(gpsDataList.get(gpsDataList.size() - 1).getWeight());
						gpsWeightEnd = myformat.format(gpsDataWeight);
					}
					markerOption.title("设备ID:" + truckModel.getDeviceId() + "\n车牌号:" + truckModel.getCarNumber() + "\n车重:" + gpsWeightEnd + "(吨)").snippet("日期:" + gpsDataList.get(i).getDate());
					markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.end)));
				}
				markerOption.setFlat(true);
				mAMap.addMarker(markerOption);
				newbounds.include(desLatLng);//轨迹全部显示在屏幕内
			}
		}
		CameraUpdate mCameraUpdate = CameraUpdateFactory.newLatLng(new LatLng((double) (x/gpsDataList.size()),(double)(y/gpsDataList.size())));
		mAMap.animateCamera(mCameraUpdate);//第二个参数为四周留空宽度.
		mAMap.setMinZoomLevel(6f);
		mAMap.setMaxZoomLevel(13f);
		mAMap.moveCamera(CameraUpdateFactory.zoomTo(8));
		mPolylineOptions.addAll(latList);
		mPolylineOptions.colorValues(colorList);
		mAMap.addPolyline(mPolylineOptions);
	
	}

如果有类似如上图的轨迹曲线,曲线点没有依附在道路上,可以尝试用 高德的轨迹纠偏

https://lbs.amap.com/api/android-sdk/guide/draw-on-map/track-sdk  

8.在地图上显示实时位置,并用图标标记


	//添加实时位置
	private void addAddr(MarkerOptions opt, OnLineTruckBean bean, String speed) {
		if (NotNull.isNotNull(bean.getY()) && NotNull.isNotNull(bean.getX())) {
			if (addMarker != null) {
				addMarker.remove();
			}
			float zoom= mAMap.getCameraPosition().zoom;
			if(zoom <4){
				zoom=10f;
			}
			Bitmap bitmap = doAddBit(bean,speed);//图标
			LatLng gpsLatLng = new LatLng(Double.parseDouble(bean.getY()), Double.parseDouble(bean.getX()));//当前座标(x,y)
			converter.coord(gpsLatLng);
			// 执行转换操作
			LatLng gdlatLng = converter.convert();
			opt.position(gdlatLng);

		
			opt.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
			addMarker = mAMap.addMarker(opt);
			newbounds.include(gdlatLng);//轨迹全部显示在屏幕内

			CameraUpdate mCameraUpdate = CameraUpdateFactory.changeLatLng(gdlatLng);//改变位置
			mAMap.moveCamera(mCameraUpdate);//第二个参数为四周留空宽度.
			mAMap.moveCamera(CameraUpdateFactory.zoomTo(zoom));
		
		}
	}

9.在地图自定义区域 圆或者多边形

  //画圆,圆心座标(lat1,lon) 半径r3    
  Double lat1 = Double.parseDouble(lat);
                                    Double lon2 = Double.parseDouble(lon);
                                    Double r3 = Double.parseDouble(r);
                                    LatLng latLng = new LatLng(lat1,lon2);
                                    Circle myCircle=mAMap.addCircle(new CircleOptions().
                                            center(latLng).
                                            radius(r3).
                                            fillColor(Color.argb(170, 238, 89, 83)).
                                            strokeColor(Color.argb(170, 13, 130, 235)).
                                            strokeWidth(3f));
//画多边形   
List<WeiLan> wllis  =jsonToBeanList(data,WeiLan.class); //点list
                                List<LatLng>  list3=new ArrayList<>();
                                for (int i = 0; i < wllis.size(); i++) {
                                    WeiLan point = wllis.get(i);
                                    Double lat1 = Double.parseDouble(point.getLat());
                                    Double lat2 = Double.parseDouble(point.getLng());
                                    LatLng lat = new LatLng(lat1, lat2);
                                    list3.add(lat);
                                    llis.add(lat);
                                }
                                // 声明 多边形参数对象
                                PolygonOptions polygonOptions = new PolygonOptions();
                                // 添加 多边形的每个顶点(顺序添加)
                                for (int t = 0; t < list3.size(); t++) {
                                    LatLng latp = list3.get(t);
                                    polygonOptions.add(latp);
                                }
                                polygonOptions.strokeWidth(4) // 多边形的边框 深绿色:#98ED84
                                        .strokeColor(Color.argb(100, 13, 130, 235)) // 边框颜色
                                        .fillColor(Color.argb(100, 238, 89, 83));   // 多边形的填充色
                          
                                mAMap.addPolygon(polygonOptions);

 

效果图如下:

 

以上代码涉及的项目可以再github上查看:https://github.com/ctgu1988/hd_wnq-yufeng

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章