«

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

时间:2024-3-2 18:21     作者:韩俊     分类: Android



一、原理


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

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

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


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


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;

    @Override
    protected 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);// 此方法必须重写
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 方法必须重写
     */
    @Override
    protected 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);// 设置同步逆地理编码请求
    }

    /**
     * 地理编码查询回调
     */
    @Override
    public 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);
        }
    }

    /**
     * 逆地理编码回调
     */
    @Override
    public 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);
        }
    }

    @Override
    public 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.955284

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

    @Override
    protected 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);// 设置同步逆地理编码请求
    }

    /**
     * 地理编码查询回调
     */
    @Override
    public 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);
        }
    }

    /**
     * 逆地理编码回调
     */
    @Override
    public 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);
        }
    }

    @Override
    public void onInfoWindowClick(Marker marker) {
    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        if (marker.isInfoWindowShown()) {
            marker.hideInfoWindow();
        } else {
            marker.showInfoWindow();
        }
        return false;
    }

    @Override
    public void onMapClick(LatLng latng) {
    }

    @Override
    public View getInfoContents(Marker marker) {
        return null;
    }

    @Override
    public 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);// 异步路径规划驾车模式查询
    }

    @Override
    public void onPoiItemDetailSearched(PoiItemDetail arg0, int arg1) {

    }

    /**
     * POI搜索结果回调
     */
    @Override
    public void onPoiSearched(PoiResult result, int rCode) {
    }

    /**
     * 驾车结果回调
     */
    @Override
    public 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);
        }
    }

    /**
     * 公交路线查询回调
     */
    @Override
    public void onBusRouteSearched(BusRouteResult result, int rCode) {
    }

    /**
     * 步行路线结果回调
     */
    @Override
    public 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 "";
        }

    }

    @Override
    public void initWidget() {
        titleTv = (TextView) findViewById(R.id.titleText);
        titleTv.setText("班车线路");
    }

    @Override
    public void widgetClick(View v) {
        // TODO Auto-generated method stub

    }

}


说明:

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

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

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



四、运行效果





五、有什么问题可以加


QQ群:261742462

标签: android

热门推荐