安卓高德地图开发(四)——自定义线路规划(根据地点的经纬度规划线路)

来源:互联网 发布:软件企业认定多久 编辑:程序博客网 时间:2024/06/12 01:26


一、原理


在高德地图使用的时候,我们在给定起点和终点的时候就可以规划出线路,但是有时候我们需要车按指定的站点进行运行和线路规划,那么,此时的话就必须自己去重新来规

划这个线路,原理也很简单,就是获取到你要经过的那些地方的经纬度(经纬度一定要是准确的经纬度,这里在获取的时候可以通过地理编码去获取),在获取到经纬度之后把数

据传递到线路规划的方法里面,这样就可以完成线路的自定义规划!


二、获取要经过的站点经纬度


1:布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="#FFF"    android:orientation="vertical" >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp" >        <Button            android:id="@+id/button1"            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:text="中兴产业园" />        <Button            android:id="@+id/button2"            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:text="大雁塔" />        <Button            android:id="@+id/button3"            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:text="旺座现代城" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp" >        <Button            android:id="@+id/button4"            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:text="亚美大厦" />        <Button            android:id="@+id/button5"            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:text="吉祥村" />        <Button            android:id="@+id/button6"            android:layout_width="0dp"            android:layout_height="fill_parent"            android:layout_weight="1"            android:text="陕西历史博物馆" />    </LinearLayout>    <com.amap.api.maps.MapView        android:id="@+id/map"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>

2:java文件

package com.amap.map3d.demo.geocoder;import android.app.Activity;import android.app.ProgressDialog;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import com.amap.api.maps.AMap;import com.amap.api.maps.CameraUpdateFactory;import com.amap.api.maps.MapView;import com.amap.api.maps.model.BitmapDescriptorFactory;import com.amap.api.maps.model.Marker;import com.amap.api.maps.model.MarkerOptions;import com.amap.api.services.core.LatLonPoint;import com.amap.api.services.geocoder.GeocodeAddress;import com.amap.api.services.geocoder.GeocodeQuery;import com.amap.api.services.geocoder.GeocodeResult;import com.amap.api.services.geocoder.GeocodeSearch;import com.amap.api.services.geocoder.GeocodeSearch.OnGeocodeSearchListener;import com.amap.api.services.geocoder.RegeocodeQuery;import com.amap.api.services.geocoder.RegeocodeResult;import com.amap.map3d.demo.util.AMapUtil;import com.amap.map3d.demo.util.ToastUtil;import com.amap.map3d.demo.R;/** * 地理编码与逆地理编码功能介绍 */public class GeocoderActivity extends Activity implements OnGeocodeSearchListener, OnClickListener {private ProgressDialog progDialog = null;private GeocodeSearch geocoderSearch;private String addressName;private AMap aMap;private MapView mapView;private LatLonPoint latLonPoint = new LatLonPoint(39.90865, 116.39751);private Marker geoMarker;private Marker regeoMarker;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.geocoder_activity);/* * 设置离线地图存储目录,在下载离线地图或初始化地图设置; 使用过程中可自行设置, 若自行设置了离线地图存储的路径, * 则需要在离线地图下载和使用地图页面都进行路径设置 */// Demo中为了其他界面可以使用下载的离线地图,使用默认位置存储,屏蔽了自定义设置// MapsInitializer.sdcardDir =OffLineMapUtils.getSdCacheDir(this);mapView = (MapView) findViewById(R.id.map);mapView.onCreate(savedInstanceState);// 此方法必须重写}/** * 方法必须重写 */@Overrideprotected void onResume() {super.onResume();mapView.onResume();}/** * 方法必须重写 */@Overrideprotected void onPause() {super.onPause();mapView.onPause();}/** * 方法必须重写 */@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);mapView.onSaveInstanceState(outState);}/** * 方法必须重写 */@Overrideprotected void onDestroy() {super.onDestroy();mapView.onDestroy();}/** * 显示进度条对话框 */public void showDialog() {progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);progDialog.setIndeterminate(false);progDialog.setCancelable(true);progDialog.setMessage("正在获取地址");progDialog.show();}/** * 隐藏进度条对话框 */public void dismissDialog() {if (progDialog != null) {progDialog.dismiss();}}/** * 响应地理编码 */public void getLatlon(final String name) {showDialog();GeocodeQuery query = new GeocodeQuery(name, "010");// 第一个参数表示地址,第二个参数表示查询城市,中文或者中文全拼,citycode、adcode,geocoderSearch.getFromLocationNameAsyn(query);// 设置同步地理编码请求}/** * 响应逆地理编码 */public void getAddress(final LatLonPoint latLonPoint) {showDialog();RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP);// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求}/** * 地理编码查询回调 */@Overridepublic void onGeocodeSearched(GeocodeResult result, int rCode) {dismissDialog();if (rCode == 0) {if (result != null && result.getGeocodeAddressList() != null && result.getGeocodeAddressList().size() > 0) {GeocodeAddress address = result.getGeocodeAddressList().get(0);aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(AMapUtil.convertToLatLng(address.getLatLonPoint()), 15));geoMarker.setPosition(AMapUtil.convertToLatLng(address.getLatLonPoint()));addressName = "经纬度值:" + address.getLatLonPoint() + "\n位置描述:" + address.getFormatAddress();ToastUtil.show(GeocoderActivity.this, addressName);} else {ToastUtil.show(GeocoderActivity.this, R.string.no_result);}} else if (rCode == 27) {ToastUtil.show(GeocoderActivity.this, R.string.error_network);} else if (rCode == 32) {ToastUtil.show(GeocoderActivity.this, R.string.error_key);} else {ToastUtil.show(GeocoderActivity.this, getString(R.string.error_other) + rCode);}}/** * 逆地理编码回调 */@Overridepublic void onRegeocodeSearched(RegeocodeResult result, int rCode) {dismissDialog();if (rCode == 0) {if (result != null && result.getRegeocodeAddress() != null && result.getRegeocodeAddress().getFormatAddress() != null) {addressName = result.getRegeocodeAddress().getFormatAddress() + "附近";aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(AMapUtil.convertToLatLng(latLonPoint), 15));regeoMarker.setPosition(AMapUtil.convertToLatLng(latLonPoint));ToastUtil.show(GeocoderActivity.this, addressName);} else {ToastUtil.show(GeocoderActivity.this, R.string.no_result);}} else if (rCode == 27) {ToastUtil.show(GeocoderActivity.this, R.string.error_network);} else if (rCode == 32) {ToastUtil.show(GeocoderActivity.this, R.string.error_key);} else {ToastUtil.show(GeocoderActivity.this, getString(R.string.error_other) + rCode);}}@Overridepublic void onClick(View v) {switch (v.getId()) {/** * 响应地理编码按钮 */case R.id.geoButton:getLatlon("方恒国际中心");break;/** * 响应逆地理编码按钮 */case R.id.regeoButton:getAddress(latLonPoint);break;default:break;}}}


通过以上的方法可以以此获取到各自的经纬度的值:


private LatLonPoint lat_one = new LatLonPoint(34.215748, 108.891869);private LatLonPoint lat_two = new LatLonPoint(34.233685, 108.900635);private LatLonPoint lat_three = new LatLonPoint(34.225311, 108.930992);private LatLonPoint lat_four = new LatLonPoint(34.224136, 108.955284);// 旺座现代城:34.215748,108.891869// 亚美大厦:34.233685,108.900635// 吉祥村:34.225311,108.930992// 陕西历史博物馆:34.224136,108.955284

同时还要拿到起点和终点的经纬度:


private LatLonPoint startPoint = new LatLonPoint(34.185642, 108.881905);private LatLonPoint endPoint = new LatLonPoint(34.214397, 108.963448);


三、线路规划


package com.bm.futuretechcity;import java.util.ArrayList;import java.util.List;import android.app.ProgressDialog;import android.content.Context;import android.os.Bundle;import android.os.Environment;import android.view.View;import android.view.View.OnClickListener;import android.widget.ArrayAdapter;import android.widget.TextView;import com.amap.api.maps.AMap;import com.amap.api.maps.AMap.InfoWindowAdapter;import com.amap.api.maps.AMap.OnInfoWindowClickListener;import com.amap.api.maps.AMap.OnMapClickListener;import com.amap.api.maps.AMap.OnMarkerClickListener;import com.amap.api.maps.MapView;import com.amap.api.maps.MapsInitializer;import com.amap.api.maps.model.LatLng;import com.amap.api.maps.model.Marker;import com.amap.api.maps.overlay.DrivingRouteOverlay;import com.amap.api.services.core.LatLonPoint;import com.amap.api.services.geocoder.GeocodeAddress;import com.amap.api.services.geocoder.GeocodeQuery;import com.amap.api.services.geocoder.GeocodeResult;import com.amap.api.services.geocoder.GeocodeSearch;import com.amap.api.services.geocoder.GeocodeSearch.OnGeocodeSearchListener;import com.amap.api.services.geocoder.RegeocodeQuery;import com.amap.api.services.geocoder.RegeocodeResult;import com.amap.api.services.poisearch.PoiItemDetail;import com.amap.api.services.poisearch.PoiResult;import com.amap.api.services.poisearch.PoiSearch.OnPoiSearchListener;import com.amap.api.services.route.BusRouteResult;import com.amap.api.services.route.DrivePath;import com.amap.api.services.route.DriveRouteResult;import com.amap.api.services.route.RouteSearch;import com.amap.api.services.route.RouteSearch.DriveRouteQuery;import com.amap.api.services.route.RouteSearch.OnRouteSearchListener;import com.amap.api.services.route.WalkRouteResult;import com.bm.futuretechcity.adapter.ShowBanCheLineAdapter;import com.bm.futuretechcity.base.BaseActivity;import com.bm.futuretechcity.bean.ShowBanCheMessage;import com.bm.futuretechcity.utils.ToastUtil;import com.bm.futuretechcity.view.HorizontalListView;/** * 班车线路 *  * @author wangxuan *  */public class TraBanCheLineActivity extends BaseActivity implements OnGeocodeSearchListener, OnClickListener, OnMarkerClickListener,OnMapClickListener, OnInfoWindowClickListener, InfoWindowAdapter, OnPoiSearchListener, OnRouteSearchListener {private ProgressDialog progDialog = null;private GeocodeSearch geocoderSearch;private String addressName;private AMap aMap;private MapView mapView;private int drivingMode = RouteSearch.DrivingDefault;// 驾车默认模式private DriveRouteResult driveRouteResult;// 驾车模式查询结果private int routeType = 1;// 1代表公交模式,2代表驾车模式,3代表步行模式private LatLonPoint startPoint = new LatLonPoint(34.185642, 108.881905);private LatLonPoint endPoint = new LatLonPoint(34.214397, 108.963448);private LatLonPoint lat_one = new LatLonPoint(34.215748, 108.891869);private LatLonPoint lat_two = new LatLonPoint(34.233685, 108.900635);private LatLonPoint lat_three = new LatLonPoint(34.225311, 108.930992);private LatLonPoint lat_four = new LatLonPoint(34.224136, 108.955284);// 旺座现代城:34.215748,108.891869// 亚美大厦:34.233685,108.900635// 吉祥村:34.225311,108.930992// 陕西历史博物馆:34.224136,108.955284private String[] station_name = new String[] { "中兴产业园", "旺座现代城", "亚美大厦", "吉祥村", "陕西历史博物馆", "大雁塔" };private List<LatLonPoint> list_latLatLonPoints = new ArrayList<LatLonPoint>();private RouteSearch routeSearch;public ArrayAdapter<String> aAdapter;private LatLonPoint start_msg;private LatLonPoint end_msg;private HorizontalListView show_station_name;private List<ShowBanCheMessage> list_showBanCheMessages = new ArrayList<ShowBanCheMessage>();/** * 页面标题 */private TextView titleTv;@Overrideprotected void onCreate(Bundle bundle) {super.onCreate(bundle);setContentView(R.layout.activity_tra_ban_che_line);initWidget();show_station_name = (HorizontalListView) this.findViewById(R.id.show_station_name);ShowBanCheMessage showBanCheMessage;for(int i=0;i<station_name.length;i++){showBanCheMessage = new ShowBanCheMessage();showBanCheMessage.setStation_name(station_name[i]);list_showBanCheMessages.add(showBanCheMessage);}ShowBanCheLineAdapter showStationNameAdapter = new ShowBanCheLineAdapter(TraBanCheLineActivity.this, list_showBanCheMessages);show_station_name.setAdapter(showStationNameAdapter);geocoderSearch = new GeocodeSearch(this);geocoderSearch.setOnGeocodeSearchListener(this);list_latLatLonPoints.add(lat_one);list_latLatLonPoints.add(lat_two);list_latLatLonPoints.add(lat_three);list_latLatLonPoints.add(lat_four);/* * 设置离线地图存储目录,在下载离线地图或初始化地图设置; 使用过程中可自行设置, 若自行设置了离线地图存储的路径, * 则需要在离线地图下载和使用地图页面都进行路径设置 */// Demo中为了其他界面可以使用下载的离线地图,使用默认位置存储,屏蔽了自定义设置MapsInitializer.sdcardDir = getSdCacheDir(this);mapView = (MapView) findViewById(R.id.map);mapView.onCreate(bundle);// 此方法必须重写init();searchRouteResult(startPoint, endPoint);}/** * 初始化AMap对象 */private void init() {if (aMap == null) {aMap = mapView.getMap();registerListener();}routeSearch = new RouteSearch(this);routeSearch.setRouteSearchListener(this);}/** * 响应地理编码 */public void getLatlon(final String name) {GeocodeQuery query = new GeocodeQuery(name, "029");// 第一个参数表示地址,第二个参数表示查询城市,中文或者中文全拼,citycode、adcode,geocoderSearch.getFromLocationNameAsyn(query);// 设置同步地理编码请求}/** * 响应逆地理编码 */public void getAddress(final LatLonPoint latLonPoint) {RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP);// 第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系geocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求}/** * 地理编码查询回调 */@Overridepublic void onGeocodeSearched(GeocodeResult result, int rCode) {if (rCode == 0) {if (result != null && result.getGeocodeAddressList() != null && result.getGeocodeAddressList().size() > 0) {GeocodeAddress address = result.getGeocodeAddressList().get(0);address.getLatLonPoint();// if (flag == 0) {// start_msg = address.getLatLonPoint();// System.out.println("========start_msg======:"+start_msg);// } else {// end_msg = address.getLatLonPoint();// System.out.println("=======end_msg=======:"+end_msg);// }//// if (start_msg != null && end_msg != null) {// searchRouteResult(start_msg, end_msg);// }addressName = "经纬度值:" + address.getLatLonPoint() + "\n位置描述:" + address.getFormatAddress();ToastUtil.show(TraBanCheLineActivity.this, start_msg + "," + end_msg);} else {ToastUtil.show(TraBanCheLineActivity.this, R.string.no_result);}} else if (rCode == 27) {ToastUtil.show(TraBanCheLineActivity.this, R.string.error_network);} else if (rCode == 32) {ToastUtil.show(TraBanCheLineActivity.this, R.string.error_key);} else {ToastUtil.show(TraBanCheLineActivity.this, getString(R.string.error_other) + rCode);}}/** * 逆地理编码回调 */@Overridepublic void onRegeocodeSearched(RegeocodeResult result, int rCode) {if (rCode == 0) {if (result != null && result.getRegeocodeAddress() != null && result.getRegeocodeAddress().getFormatAddress() != null) {addressName = result.getRegeocodeAddress().getFormatAddress() + "附近";ToastUtil.show(TraBanCheLineActivity.this, addressName);} else {ToastUtil.show(TraBanCheLineActivity.this, R.string.no_result);}} else if (rCode == 27) {ToastUtil.show(TraBanCheLineActivity.this, R.string.error_network);} else if (rCode == 32) {ToastUtil.show(TraBanCheLineActivity.this, R.string.error_key);} else {ToastUtil.show(TraBanCheLineActivity.this, getString(R.string.error_other) + rCode);}}@Overridepublic void onInfoWindowClick(Marker marker) {}@Overridepublic boolean onMarkerClick(Marker marker) {if (marker.isInfoWindowShown()) {marker.hideInfoWindow();} else {marker.showInfoWindow();}return false;}@Overridepublic void onMapClick(LatLng latng) {}@Overridepublic View getInfoContents(Marker marker) {return null;}@Overridepublic View getInfoWindow(Marker marker) {return null;}/** * 注册监听 */private void registerListener() {aMap.setOnMapClickListener(TraBanCheLineActivity.this);aMap.setOnMarkerClickListener(TraBanCheLineActivity.this);aMap.setOnInfoWindowClickListener(TraBanCheLineActivity.this);aMap.setInfoWindowAdapter(TraBanCheLineActivity.this);}/** * 显示进度框 */private void showProgressDialog() {if (progDialog == null)progDialog = new ProgressDialog(this);progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);progDialog.setIndeterminate(false);progDialog.setCancelable(true);progDialog.setMessage("正在搜索");progDialog.show();}/** * 隐藏进度框 */private void dissmissProgressDialog() {if (progDialog != null) {progDialog.dismiss();}}/** * 开始搜索路径规划方案 */public void searchRouteResult(LatLonPoint startPoint, LatLonPoint endPoint) {showProgressDialog();final RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(startPoint, endPoint);// 驾车路径规划// 第一个参数表示路径规划的起点和终点,第二个参数表示驾车模式,第三个参数表示途经点,第四个参数表示避让区域,第五个参数表示避让道路DriveRouteQuery query = new DriveRouteQuery(fromAndTo, drivingMode, list_latLatLonPoints, null, "");routeSearch.calculateDriveRouteAsyn(query);// 异步路径规划驾车模式查询}@Overridepublic void onPoiItemDetailSearched(PoiItemDetail arg0, int arg1) {}/** * POI搜索结果回调 */@Overridepublic void onPoiSearched(PoiResult result, int rCode) {}/** * 驾车结果回调 */@Overridepublic void onDriveRouteSearched(DriveRouteResult result, int rCode) {dissmissProgressDialog();if (rCode == 0) {if (result != null && result.getPaths() != null && result.getPaths().size() > 0) {driveRouteResult = result;DrivePath drivePath = driveRouteResult.getPaths().get(0);aMap.clear();// 清理地图上的所有覆盖物DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(this, aMap, drivePath, driveRouteResult.getStartPos(),driveRouteResult.getTargetPos());drivingRouteOverlay.removeFromMap();drivingRouteOverlay.addToMap();drivingRouteOverlay.zoomToSpan();} else {ToastUtil.show(TraBanCheLineActivity.this, R.string.no_result);}} else if (rCode == 27) {ToastUtil.show(TraBanCheLineActivity.this, R.string.error_network);} else if (rCode == 32) {ToastUtil.show(TraBanCheLineActivity.this, R.string.error_key);} else {ToastUtil.show(TraBanCheLineActivity.this, getString(R.string.error_other) + rCode);}}/** * 公交路线查询回调 */@Overridepublic void onBusRouteSearched(BusRouteResult result, int rCode) {}/** * 步行路线结果回调 */@Overridepublic void onWalkRouteSearched(WalkRouteResult result, int rCode) {}public String getSdCacheDir(Context context) {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {java.io.File fExternalStorageDirectory = Environment.getExternalStorageDirectory();java.io.File autonaviDir = new java.io.File(fExternalStorageDirectory, "amapsdk");boolean result = false;if (!autonaviDir.exists()) {result = autonaviDir.mkdir();}java.io.File minimapDir = new java.io.File(autonaviDir, "offlineMap");if (!minimapDir.exists()) {result = minimapDir.mkdir();}return minimapDir.toString() + "/";} else {return "";}}@Overridepublic void initWidget() {titleTv = (TextView) findViewById(R.id.titleText);titleTv.setText("班车线路");}@Overridepublic void widgetClick(View v) {// TODO Auto-generated method stub}}


说明:

// 第一个参数表示路径规划的起点和终点,第二个参数表示驾车模式,第三个参数表示途经点,第四个参数表示避让区域,第五个参数表示避让道路

DriveRouteQuery query = new DriveRouteQuery(fromAndTo, drivingMode, list_latLatLonPoints, null, "");

这里的list_latLatLonPoints就是第三个经过的站点的经纬度数据集合,只要把这个传递进去就可以按指定的路线进行规划了!



四、运行效果





五、有什么问题可以加


 QQ群:261742462

0 0