Commit 3bac7e4c authored by p x's avatar p x
Browse files

增加驾车路径规划

parent 8a1780fa
......@@ -70,7 +70,8 @@
android:exported="false" /> <!-- <uses-library -->
<activity
android:name=".MainActivity"
android:exported="true">
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......
......@@ -3,6 +3,8 @@ package com.sd.mapmultiengine
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
......@@ -76,10 +78,37 @@ class MainActivity : AppCompatActivity() {
}
}
// binding.sp.onItemSelectedListener=object :AdapterView.OnItemSelectedListener{
// override fun onItemSelected(
// parent: AdapterView<*>?,
// view: View?,
// position: Int,
// id: Long
// ) {
// var str=parent?.adapter?.getItem(position)
// println("-------sp str = ${str}")
// if (str?.equals("四维")==true){
//
// }else if (str?.equals("高德")==true){
//
// }
// }
//
// override fun onNothingSelected(parent: AdapterView<*>?) {
//
// }
// }
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
println("----------MainActivity.onNewIntent")
}
fun initMap() {
MSDKInitializer.initializeMap(this, MAP_TYPE.MINE, object : OnSdkInitCb {
fun initMap(type: MAP_TYPE = MAP_TYPE.MINE) {
MSDKInitializer.initializeMap(this, type, object : OnSdkInitCb {
override fun onInitSuccess() {
println("--------onMapInitSuccess")
}
......@@ -91,4 +120,6 @@ class MainActivity : AppCompatActivity() {
}
}
\ No newline at end of file
......@@ -145,7 +145,7 @@ class TextMainActivity : AppCompatActivity() {
fun initMap() {
MSDKInitializer.initializeMap(this, MAP_TYPE.AMAP, object : OnSdkInitCb {
MSDKInitializer.initializeMap(this, MAP_TYPE.MINE, object : OnSdkInitCb {
override fun onInitSuccess() {
println("--------onMapInitSuccess}")
}
......
package com.sd.mapmultiengine.ui
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.amap.api.services.route.BusRouteResult
import com.amap.api.services.route.DriveRouteResult
import com.amap.api.services.route.RideRouteResult
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.minedata.minenavi.map.Route
import com.minedata.minenavi.map.RouteOptions
import com.minedata.minenavi.mapdal.LatLng
import com.minedata.minenavi.mapdal.PoiFavorite
import com.minedata.minenavi.navi.ArrowInfo
import com.minedata.minenavi.navi.BusRoute
import com.minedata.minenavi.navi.GuidanceText
import com.minedata.minenavi.navi.MineNaviListener
import com.minedata.minenavi.navi.NaviProgressData
import com.minedata.minenavi.navi.NaviSession
import com.minedata.minenavi.navi.NaviSessionData
import com.minedata.minenavi.navi.RouteBase
import com.minedata.minenavi.navi.RouteBriefQuerier
import com.minedata.minenavi.navi.RouteCollection
import com.minedata.minenavi.navi.RoutePlan
import com.minedata.minenavi.navi.RouterErrorInfo
import com.minedata.minenavi.navi.SmoothNaviData
import com.minedata.minenavi.navi.TmcSections
import com.minedata.minenavi.util.Tools
import com.sd.maplibrary.MAP_TYPE
import com.sd.maplibrary.MSDKInitializer
import com.sd.maplibrary.bean.DriverRouteBean
import com.sd.maplibrary.bean.MSLatLng
import com.sd.maplibrary.core.MSRoutePlans
......@@ -8,12 +37,16 @@ import com.sd.maplibrary.core.MSRoutePlans.OnDriveRoute
import com.sd.maplibrary.core.MapReadyView
import com.sd.maplibrary.ui.MapMultiView.OnMapReadyLis
import com.sd.mapmultiengine.databinding.ActivityTdriveRouteBinding
import overlay.DrivingRouteOverlay
import com.amap.api.services.core.LatLonPoint as ALatLonPoint
class TDriveRouteActivity : TBaseActivity() {
class TDriveRouteActivity : AppCompatActivity() {
private lateinit var binding: ActivityTdriveRouteBinding
var mapReadView: MapReadyView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTdriveRouteBinding.inflate(layoutInflater)
......@@ -22,9 +55,11 @@ class TDriveRouteActivity : TBaseActivity() {
binding.mapMultiView.addMapRenderCallback(object : OnMapReadyLis {
override fun onMapReady(mapReadyView: MapReadyView) {
this@TDriveRouteActivity.mapReadView = mapReadyView
}
})
//初始化并设置监听
MSRoutePlans.addPlanLis(this, onDriveRoute)
//开始规划
......@@ -32,20 +67,282 @@ class TDriveRouteActivity : TBaseActivity() {
// if (mapReadView == null)
// return@setOnClickListener
// 起点坐标 116.3215,39.8919
val startPoint = MSLatLng(116.490682,39.806898)
// 终点坐标116.3793,39.8643
val endPoint = MSLatLng(116.379311, 39.864311)
// 终点名称
val endName = ""
val startPoint = MSLatLng(39.806898, 116.490682)
//// 终点坐标116.3793,39.8643
val endPoint = MSLatLng(39.864311, 116.379311)
//// 终点名称
val endName = "沈阳火车站"
MSRoutePlans.drivingPathPlanning(startPoint, endPoint, endName)
// testDriverPlan()
// testDriverPlanaMAP()
}
}
private var onDriveRoute = object : OnDriveRoute {
override fun onDriverRoute(driverRouteBean: DriverRouteBean) {
when (MSDKInitializer.getMapType()) {
MAP_TYPE.MINE -> {
// mapReadView?.mMineMap?.removeOverlay(mRoute)
var routeBase = driverRouteBean.routeCollection?.routes?.get(0)
val options = RouteOptions()
.routeBase(routeBase)
.colorType(Route.RouteColorType.enrouteTi)
// .colorType(Route.RouteColorType.none)
.styleClass("DEFAULT")
var mRoute = mapReadView?.mMineMap?.addRoute(options)
setRouteOverlayStyle(mRoute, false)
}
MAP_TYPE.AMAP -> {
mapReadView?.aMap?.clear()
var drivePath = driverRouteBean.driveRouteResult?.paths?.get(0);
if (drivePath == null) {
return
}
var mDriveRouteResult = driverRouteBean.driveRouteResult
var drivingRouteOverlay = DrivingRouteOverlay(
this@TDriveRouteActivity, mapReadView?.aMap!!, drivePath,
mDriveRouteResult?.getStartPos(),
mDriveRouteResult?.getTargetPos(), null
)
drivingRouteOverlay.setNodeIconVisibility(false) //设置节点marker是否显示
drivingRouteOverlay.setIsColorfulline(true) //是否用颜色展示交通拥堵情况,默认true
drivingRouteOverlay.removeFromMap()
drivingRouteOverlay.addToMap()
drivingRouteOverlay.zoomToSpan()
}
}
}
}
private fun setRouteOverlayStyle(route: Route?, isSmallMapRoute: Boolean) {
var routeStyle = "DEFAULT"
if (isSmallMapRoute) {
routeStyle += ",small-map"
}
route?.selectStyleClass(routeStyle)
}
lateinit var mNaviSession: NaviSession
private fun testDriverPlan() {
mNaviSession = NaviSession.getInstance()
mNaviSession.enableSound(true)
// mNaviSession.setDataPreference(DataPreference.preferOnline)
mNaviSession.addMineNaviListener(mineNaviListener)
// 起点名称
val startName = ""
var mStartPoint = Tools.latLngToPoint(LatLng(41.8194611, 123.4358811))
// 终点名称
val endName = "北京奥利匹克公园"
var mEndPoint = Tools.latLngToPoint(LatLng(39.9923712, 116.392522))
val newstartPoint = PoiFavorite(mStartPoint, startName)
val newendPoint = PoiFavorite(mEndPoint, endName)
val wayPoints = ArrayList<PoiFavorite>()
val routePlan = RoutePlan()
// 设置算路偏好
routePlan.setRoutePreference(RoutePlan.RoutePreference.none)
// crp 算路
routePlan.setRouteServerType(RoutePlan.RouteServiceType.crp)
mNaviSession.calculateDriveRoute(
newstartPoint,
wayPoints,
newendPoint,
routePlan,
NaviSession.RouteMethod.multipleResult
)
}
var mineNaviListener = object : MineNaviListener {
override fun onCalculateRouteSuccess(p0: RouteCollection?) {
var a = 0
println("---算路成功")
}
override fun onCalculateBusSuccess(p0: List<BusRoute?>?) {
}
override fun onCalculateRouteFailed(p0: RouterErrorInfo?) {
var b = 0
println("---算路失败 p0?.errCode = ${p0?.errCode}")
}
override fun onCalculateVrpSuccess(p0: List<PoiFavorite?>?) {
}
override fun onArriveDestination() {
}
override fun onWayPointArrived(p0: Int) {
}
override fun onNewArrow(p0: ArrowInfo?) {
}
override fun onDeleteArrow() {
}
override fun onNewRouteTaken() {
}
override fun onRouteRemoved() {
}
override fun onNeedsReroute() {
}
override fun onRerouteCancelled() {
}
override fun onRerouteComplete(p0: RouteBase?) {
}
override fun onRerouteFailed(p0: RouterErrorInfo?) {
}
override fun onRerouteStarted() {
}
override fun onRouteCancelled() {
}
override fun onRouteStarted() {
}
override fun onRouting() {
}
override fun onNaviBegin() {
}
override fun onNaviEnded() {
}
override fun onSimNaviBegin() {
}
override fun onSimNaviEnd() {
}
override fun onTracking(p0: NaviSessionData?) {
}
override fun onSmoothTracking(p0: SmoothNaviData?) {
}
override fun onDataUpdated(p0: NaviProgressData?) {
}
override fun onTextChanged(p0: GuidanceText?) {
}
override fun onDistanceChanged(p0: Int) {
}
override fun onTiBarUpdated(p0: TmcSections?) {
}
override fun onRouteTmcUpdated(p0: RouteBase?) {
}
override fun onRouteTeUpdated(p0: RouteBase?) {
}
override fun onRouteBriefRequestSucceeded(p0: RouteBriefQuerier.RouteBrief?) {
}
override fun onRouteBriefRequestFailed(p0: Int, p1: String?) {
}
override fun onRouteBriefRequestCancelled() {
}
};
private var mStartPoint = ALatLonPoint(39.942295, 116.335891) //起点,39.942295,116.335891
private var mEndPoint = ALatLonPoint(39.995576, 116.481288) //终点,39.995576,116.481288
private fun testDriverPlanaMAP() {
var mRouteSearch = RouteSearch(this)
mRouteSearch.setRouteSearchListener(ppp);
val fromAndTo = RouteSearch.FromAndTo(
mStartPoint, mEndPoint
)
val query = DriveRouteQuery(
fromAndTo, RouteSearch.DrivingDefault, null,
null, ""
) // 第一个参数表示路径规划的起点和终点,第二个参数表示驾车模式,第三个参数表示途经点,第四个参数表示避让区域,第五个参数表示避让道路
mRouteSearch.calculateDriveRouteAsyn(query) // 异步路径规划驾车模式查询
}
private var ppp = object : OnRouteSearchListener {
override fun onBusRouteSearched(
p0: BusRouteResult?,
p1: Int
) {
}
override fun onDriveRouteSearched(
p0: DriveRouteResult?,
p1: Int
) {
println(" ---高德成功")
}
override fun onWalkRouteSearched(
p0: WalkRouteResult?,
p1: Int
) {
}
override fun onRideRouteSearched(
p0: RideRouteResult?,
p1: Int
) {
}
}
......
......@@ -7,6 +7,21 @@
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="right"
android:visibility="gone">
<Spinner
android:id="@+id/sp"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:entries="@array/maptypes"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/demo_list"
android:layout_width="match_parent"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.TDriveRouteActivity">
<Button
android:id="@+id/starplan"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始规划"/>
<Button
android:id="@+id/starplan"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始规划" />
<com.sd.maplibrary.ui.MapMultiView
android:id="@+id/mapMultiView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:map_type="MINE" />
android:layout_height="match_parent" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="maptypes">
<item>四维</item>
<item>高德</item>
</string-array>
</resources>
\ No newline at end of file
......@@ -140,6 +140,7 @@ object MSRoutePlans {
override fun onCalculateRouteSuccess(data: RouteCollection) {
// 路线规划成功
driverRouteBean.routeCollection = data
onDriveRoute?.onDriverRoute(driverRouteBean)
}
override fun onCalculateRouteFailed(data: RouterErrorInfo) {
......@@ -163,6 +164,7 @@ object MSRoutePlans {
errorCode: Int
) {
driverRouteBean.driveRouteResult = result
onDriveRoute?.onDriverRoute(driverRouteBean)
}
override fun onWalkRouteSearched(
......
/**
*
*/
package com.sd.maplibrary.utils.amp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.text.Html;
import android.text.Spanned;
import android.widget.EditText;
import com.amap.api.maps.model.LatLng;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.BusPath;
import com.amap.api.services.route.BusStep;
import com.amap.api.services.route.RouteBusLineItem;
import com.amap.api.services.route.RouteRailwayItem;
import com.sd.maplibrary.R;
public class AMapUtil {
/**
* 判断edittext是否null
*/
public static String checkEditText(EditText editText) {
if (editText != null && editText.getText() != null
&& !(editText.getText().toString().trim().equals(""))) {
return editText.getText().toString().trim();
} else {
return "";
}
}
public static Spanned stringToSpan(String src) {
return src == null ? null : Html.fromHtml(src.replace("\n", "<br />"));
}
public static String colorFont(String src, String color) {
StringBuffer strBuf = new StringBuffer();
strBuf.append("<font color=").append(color).append(">").append(src)
.append("</font>");
return strBuf.toString();
}
public static String makeHtmlNewLine() {
return "<br />";
}
public static String makeHtmlSpace(int number) {
final String space = "&nbsp;";
StringBuilder result = new StringBuilder();
for (int i = 0; i < number; i++) {
result.append(space);
}
return result.toString();
}
public static String getFriendlyLength(int lenMeter) {
if (lenMeter > 10000) // 10 km
{
int dis = lenMeter / 1000;
return dis + ChString.Kilometer;
}
if (lenMeter > 1000) {
float dis = (float) lenMeter / 1000;
DecimalFormat fnum = new DecimalFormat("##0.0");
String dstr = fnum.format(dis);
return dstr + ChString.Kilometer;
}
if (lenMeter > 100) {
int dis = lenMeter / 50 * 50;
return dis + ChString.Meter;
}
int dis = lenMeter / 10 * 10;
if (dis == 0) {
dis = 10;
}
return dis + ChString.Meter;
}
public static boolean IsEmptyOrNullString(String s) {
return (s == null) || (s.trim().length() == 0);
}
/**
* 把LatLng对象转化为LatLonPoint对象
*/
public static LatLonPoint convertToLatLonPoint(LatLng latlon) {
return new LatLonPoint(latlon.latitude, latlon.longitude);
}
/**
* 把LatLonPoint对象转化为LatLon对象
*/
public static LatLng convertToLatLng(LatLonPoint latLonPoint) {
return new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude());
}
/**
* 把集合体的LatLonPoint转化为集合体的LatLng
*/
public static ArrayList<LatLng> convertArrList(List<LatLonPoint> shapes) {
ArrayList<LatLng> lineShapes = new ArrayList<LatLng>();
for (LatLonPoint point : shapes) {
LatLng latLngTemp = AMapUtil.convertToLatLng(point);
lineShapes.add(latLngTemp);
}
return lineShapes;
}
/**
* long类型时间格式化
*/
public static String convertToTime(long time) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(time);
return df.format(date);
}
public static final String HtmlBlack = "#000000";
public static final String HtmlGray = "#808080";
public static String getFriendlyTime(int second) {
if (second > 3600) {
int hour = second / 3600;
int miniate = (second % 3600) / 60;
return hour + "小时" + miniate + "分钟";
}
if (second >= 60) {
int miniate = second / 60;
return miniate + "分钟";
}
return second + "秒";
}
//路径规划方向指示和图片对应
public static int getDriveActionID(String actionName) {
if (actionName == null || actionName.equals("")) {
return R.drawable.dir3;
}
if ("左转".equals(actionName)) {
return R.drawable.dir2;
}
if ("右转".equals(actionName)) {
return R.drawable.dir1;
}
if ("向左前方行驶".equals(actionName) || "靠左".equals(actionName)) {
return R.drawable.dir6;
}
if ("向右前方行驶".equals(actionName) || "靠右".equals(actionName)) {
return R.drawable.dir5;
}
if ("向左后方行驶".equals(actionName) || "左转调头".equals(actionName)) {
return R.drawable.dir7;
}
if ("向右后方行驶".equals(actionName)) {
return R.drawable.dir8;
}
if ("直行".equals(actionName)) {
return R.drawable.dir3;
}
if ("减速行驶".equals(actionName)) {
return R.drawable.dir4;
}
return R.drawable.dir3;
}
public static int getWalkActionID(String actionName) {
if (actionName == null || actionName.equals("")) {
return R.drawable.dir13;
}
if ("左转".equals(actionName)) {
return R.drawable.dir2;
}
if ("右转".equals(actionName)) {
return R.drawable.dir1;
}
if ("向左前方".equals(actionName) || "靠左".equals(actionName) || actionName.contains("向左前方")) {
return R.drawable.dir6;
}
if ("向右前方".equals(actionName) || "靠右".equals(actionName) || actionName.contains("向右前方")) {
return R.drawable.dir5;
}
if ("向左后方".equals(actionName)|| actionName.contains("向左后方")) {
return R.drawable.dir7;
}
if ("向右后方".equals(actionName)|| actionName.contains("向右后方")) {
return R.drawable.dir8;
}
if ("直行".equals(actionName)) {
return R.drawable.dir3;
}
if ("通过人行横道".equals(actionName)) {
return R.drawable.dir9;
}
if ("通过过街天桥".equals(actionName)) {
return R.drawable.dir11;
}
if ("通过地下通道".equals(actionName)) {
return R.drawable.dir10;
}
return R.drawable.dir13;
}
public static String getBusPathTitle(BusPath busPath) {
if (busPath == null) {
return String.valueOf("");
}
List<BusStep> busSetps = busPath.getSteps();
if (busSetps == null) {
return String.valueOf("");
}
StringBuffer sb = new StringBuffer();
for (BusStep busStep : busSetps) {
StringBuffer title = new StringBuffer();
if (busStep.getBusLines().size() > 0) {
for (RouteBusLineItem busline : busStep.getBusLines()) {
if (busline == null) {
continue;
}
String buslineName = getSimpleBusLineName(busline.getBusLineName());
title.append(buslineName);
title.append(" / ");
}
// RouteBusLineItem busline = busStep.getBusLines().get(0);
sb.append(title.substring(0, title.length() - 3));
sb.append(" > ");
}
if (busStep.getRailway() != null) {
RouteRailwayItem railway = busStep.getRailway();
sb.append(railway.getTrip()+"("+railway.getDeparturestop().getName()
+" - "+railway.getArrivalstop().getName()+")");
sb.append(" > ");
}
}
return sb.substring(0, sb.length() - 3);
}
public static String getBusPathDes(BusPath busPath) {
if (busPath == null) {
return String.valueOf("");
}
long second = busPath.getDuration();
String time = getFriendlyTime((int) second);
float subDistance = busPath.getDistance();
String subDis = getFriendlyLength((int) subDistance);
float walkDistance = busPath.getWalkDistance();
String walkDis = getFriendlyLength((int) walkDistance);
return String.valueOf(time + " | " + subDis + " | 步行" + walkDis);
}
public static String getSimpleBusLineName(String busLineName) {
if (busLineName == null) {
return String.valueOf("");
}
return busLineName.replaceAll("\\(.*?\\)", "");
}
}
package com.sd.maplibrary.utils.amp;
public class ChString {
public static final String Kilometer = "\u516c\u91cc";// "公里";
public static final String Meter = "\u7c73";// "米";
public static final String ByFoot = "\u6b65\u884c";// "步行";
public static final String To = "\u53bb\u5f80";// "去往";
public static final String Station = "\u8f66\u7ad9";// "车站";
public static final String TargetPlace = "\u76ee\u7684\u5730";// "目的地";
public static final String StartPlace = "\u51fa\u53d1\u5730";// "出发地";
public static final String About = "\u5927\u7ea6";// "大约";
public static final String Direction = "\u65b9\u5411";// "方向";
public static final String GetOn = "\u4e0a\u8f66";// "上车";
public static final String GetOff = "\u4e0b\u8f66";// "下车";
public static final String Zhan = "\u7ad9";// "站";
public static final String cross = "\u4ea4\u53c9\u8def\u53e3"; // 交叉路口
public static final String type = "\u7c7b\u522b"; // 类别
public static final String address = "\u5730\u5740"; // 地址
public static final String PrevStep = "\u4e0a\u4e00\u6b65";
public static final String NextStep = "\u4e0b\u4e00\u6b65";
public static final String Gong = "\u516c\u4ea4";
public static final String ByBus = "\u4e58\u8f66";
public static final String Arrive = "\u5230\u8FBE";// 到达
}
package overlay;
/**
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Bitmap;
import com.amap.api.maps.model.LatLng;
import com.amap.api.services.core.LatLonPoint;
class AMapServicesUtil {
public static int BUFFER_SIZE = 2048;
public static byte[] inputStreamToByte(InputStream in) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[BUFFER_SIZE];
int count = -1;
while ((count = in.read(data, 0, BUFFER_SIZE)) != -1)
outStream.write(data, 0, count);
data = null;
return outStream.toByteArray();
}
public static LatLonPoint convertToLatLonPoint(LatLng latlon) {
return new LatLonPoint(latlon.latitude, latlon.longitude);
}
public static LatLng convertToLatLng(LatLonPoint latLonPoint) {
return new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude());
}
public static ArrayList<LatLng> convertArrList(List<LatLonPoint> shapes) {
ArrayList<LatLng> lineShapes = new ArrayList<LatLng>();
for (LatLonPoint point : shapes) {
LatLng latLngTemp = AMapServicesUtil.convertToLatLng(point);
lineShapes.add(latLngTemp);
}
return lineShapes;
}
public static Bitmap zoomBitmap(Bitmap bitmap, float res) {
if (bitmap == null) {
return null;
}
int width, height;
width = (int) (bitmap.getWidth() * res);
height = (int) (bitmap.getHeight() * res);
Bitmap newbmp = Bitmap.createScaledBitmap(bitmap, width, height, true);
return newbmp;
}
}
package overlay;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Color;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.busline.BusLineItem;
import com.amap.api.services.busline.BusStationItem;
import com.amap.api.services.core.LatLonPoint;
import com.sd.maplibrary.R;
/**
* 公交线路图层类。在高德地图API里,如果要显示公交线路,可以用此类来创建公交线路图层。如不满足需求,也可以自己创建自定义的公交线路图层。
*
* @since V2.1.0
*/
public class BusLineOverlay {
private BusLineItem mBusLineItem;
private AMap mAMap;
private ArrayList<Marker> mBusStationMarks = new ArrayList<Marker>();
private Polyline mBusLinePolyline;
private List<BusStationItem> mBusStations;
private BitmapDescriptor startBit, endBit, busBit;
private Context mContext;
/**
* 通过此构造函数创建公交线路图层。
*
* @param context 当前activity。
* @param amap 地图对象。
* @param busLineItem 公交线路。详见搜索服务模块的公交线路和公交站点包(com.amap.api.services.busline)中的类 <strong><a href="../../../../../../Search/com/amap/api/services/busline/BusStationItem.html" title="com.amap.api.services.busline中的类">BusStationItem</a></strong>。
* @since V2.1.0
*/
public BusLineOverlay(Context context, AMap amap, BusLineItem busLineItem) {
mContext = context;
mBusLineItem = busLineItem;
this.mAMap = amap;
mBusStations = mBusLineItem.getBusStations();
}
/**
* 添加公交线路到地图中。
*
* @since V2.1.0
*/
public void addToMap() {
try {
List<LatLonPoint> pointList = mBusLineItem.getDirectionsCoordinates();
List<LatLng> listPolyline = AMapServicesUtil.convertArrList(pointList);
mBusLinePolyline = mAMap.addPolyline(new PolylineOptions()
.addAll(listPolyline).color(getBusColor())
.width(getBuslineWidth()));
if (mBusStations.size() < 1) {
return;
}
for (int i = 1; i < mBusStations.size() - 1; i++) {
Marker marker = mAMap.addMarker(getMarkerOptions(i));
mBusStationMarks.add(marker);
}
Marker markerStart = mAMap.addMarker(getMarkerOptions(0));
mBusStationMarks.add(markerStart);
Marker markerEnd = mAMap
.addMarker(getMarkerOptions(mBusStations.size() - 1));
mBusStationMarks.add(markerEnd);
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 去掉BusLineOverlay上所有的Marker。
*
* @since V2.1.0
*/
public void removeFromMap() {
if (mBusLinePolyline != null) {
mBusLinePolyline.remove();
}
try {
for (Marker mark : mBusStationMarks) {
mark.remove();
}
destroyBit();
} catch (Throwable e) {
e.printStackTrace();
}
}
private void destroyBit() {
if (startBit != null) {
startBit.recycle();
startBit = null;
}
if (endBit != null) {
endBit.recycle();
endBit = null;
}
if (busBit != null) {
busBit.recycle();
busBit = null;
}
}
/**
* 移动镜头到当前的视角。
*
* @since V2.1.0
*/
public void zoomToSpan() {
if (mAMap == null)
return;
try {
List<LatLonPoint> coordin = mBusLineItem.getDirectionsCoordinates();
if (coordin != null && coordin.size() > 0) {
LatLngBounds bounds = getLatLngBounds(coordin);
mAMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 5));
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private LatLngBounds getLatLngBounds(List<LatLonPoint> coordin) {
LatLngBounds.Builder b = LatLngBounds.builder();
for (int i = 0; i < coordin.size(); i++) {
b.include(new LatLng(coordin.get(i).getLatitude(), coordin.get(i)
.getLongitude()));
}
return b.build();
}
private MarkerOptions getMarkerOptions(int index) {
MarkerOptions options = new MarkerOptions()
.position(
new LatLng(mBusStations.get(index).getLatLonPoint()
.getLatitude(), mBusStations.get(index)
.getLatLonPoint().getLongitude()))
.title(getTitle(index)).snippet(getSnippet(index));
if (index == 0) {
options.icon(getStartBitmapDescriptor());
} else if (index == mBusStations.size() - 1) {
options.icon(getEndBitmapDescriptor());
} else {
options.anchor(0.5f, 0.5f);
options.icon(getBusBitmapDescriptor());
}
return options;
}
protected BitmapDescriptor getStartBitmapDescriptor() {
startBit = BitmapDescriptorFactory.fromResource(R.drawable.amap_start);
return startBit;
}
protected BitmapDescriptor getEndBitmapDescriptor() {
endBit = BitmapDescriptorFactory.fromResource(R.drawable.amap_end);
return endBit;
}
protected BitmapDescriptor getBusBitmapDescriptor() {
busBit = BitmapDescriptorFactory.fromResource(R.drawable.amap_bus);
return busBit;
}
/**
* 返回第index的Marker的标题。
*
* @param index 第几个Marker。
* @return marker的标题。
* @since V2.1.0
*/
protected String getTitle(int index) {
return mBusStations.get(index).getBusStationName();
}
/**
* 返回第index的Marker的详情。
*
* @param index 第几个Marker。
* @return marker的详情。
* @since V2.1.0
*/
protected String getSnippet(int index) {
return "";
}
/**
* 从marker中得到公交站点在list的位置。
*
* @param marker 一个标记的对象。
* @return 返回该marker对应的公交站点在list的位置。
* @since V2.1.0
*/
public int getBusStationIndex(Marker marker) {
for (int i = 0; i < mBusStationMarks.size(); i++) {
if (mBusStationMarks.get(i).equals(marker)) {
return i;
}
}
return -1;
}
/**
* 返回第index的公交站点的信息。
*
* @param index 第几个公交站点。
* @return 公交站点的信息。详见搜索服务模块的公交线路和公交站点包(com.amap.api.services.busline)中的类 <strong><a href="../../../../../../Search/com/amap/api/services/busline/BusStationItem.html" title="com.amap.api.services.busline中的类">BusStationItem</a></strong>。
* @since V2.1.0
*/
public BusStationItem getBusStationItem(int index) {
if (index < 0 || index >= mBusStations.size()) {
return null;
}
return mBusStations.get(index);
}
protected int getBusColor() {
return Color.parseColor("#537edc");
}
protected float getBuslineWidth() {
return 18f;
}
}
package overlay;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import com.amap.api.maps.AMap;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.busline.BusStationItem;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.BusPath;
import com.amap.api.services.route.BusStep;
import com.amap.api.services.route.Doorway;
import com.amap.api.services.route.RailwayStationItem;
import com.amap.api.services.route.RouteBusLineItem;
import com.amap.api.services.route.RouteBusWalkItem;
import com.amap.api.services.route.RouteRailwayItem;
import com.amap.api.services.route.TaxiItem;
import com.amap.api.services.route.WalkStep;
import com.sd.maplibrary.utils.amp.AMapUtil;
/**
* 公交路线图层类。在高德地图API里,如果需要显示公交路线,可以用此类来创建公交路线图层。如不满足需求,也可以自己创建自定义的公交路线图层。
* @since V2.1.0
*/
public class BusRouteOverlay extends RouteOverlay {
private BusPath busPath;
private LatLng latLng;
/**
* 通过此构造函数创建公交路线图层。
* @param context 当前activity。
* @param amap 地图对象。
* @param path 公交路径规划的一个路段。详见搜索服务模块的路径查询包(com.amap.api.services.route)中的类<strong> <a href="../../../../../../Search/com/amap/api/services/route/BusPath.html" title="com.amap.api.services.route中的类">BusPath</a></strong>。
* @param start 起点坐标。详见搜索服务模块的核心基础包(com.amap.api.services.core)中的类 <strong><a href="../../../../../../Search/com/amap/api/services/core/LatLonPoint.html" title="com.amap.api.services.core中的类">LatLonPoint</a></strong>。
* @param end 终点坐标。详见搜索服务模块的核心基础包(com.amap.api.services.core)中的类 <strong><a href="../../../../../../Search/com/amap/api/services/core/LatLonPoint.html" title="com.amap.api.services.core中的类">LatLonPoint</a></strong>。
* @since V2.1.0
*/
public BusRouteOverlay(Context context, AMap amap, BusPath path,
LatLonPoint start, LatLonPoint end) {
super(context);
this.busPath = path;
startPoint = AMapUtil.convertToLatLng(start);
endPoint = AMapUtil.convertToLatLng(end);
mAMap = amap;
}
/**
* 添加公交路线到地图上。
* @since V2.1.0
*/
public void addToMap() {
/**
* 绘制节点和线<br>
* 细节情况较多<br>
* 两个step之间,用step和step1区分<br>
* 1.一个step内可能有步行和公交,然后有可能他们之间连接有断开<br>
* 2.step的公交和step1的步行,有可能连接有断开<br>
* 3.step和step1之间是公交换乘,且没有步行,需要把step的终点和step1的起点连起来<br>
* 4.公交最后一站和终点间有步行,加入步行线路,还会有一些步行marker<br>
* 5.公交最后一站和终点间无步行,之间连起来<br>
*/
try {
List<BusStep> busSteps = busPath.getSteps();
for (int i = 0; i < busSteps.size(); i++) {
BusStep busStep = busSteps.get(i);
if (i < busSteps.size() - 1) {
BusStep busStep1 = busSteps.get(i + 1);// 取得当前下一个BusStep对象
// 假如步行和公交之间连接有断开,就把步行最后一个经纬度点和公交第一个经纬度点连接起来,避免断线问题
if (busStep.getWalk() != null
&& busStep.getBusLine() != null) {
checkWalkToBusline(busStep);
}
// 假如公交和步行之间连接有断开,就把上一公交经纬度点和下一步行第一个经纬度点连接起来,避免断线问题
if (busStep.getBusLine() != null
&& busStep1.getWalk() != null
&& busStep1.getWalk().getSteps().size() > 0) {
checkBusLineToNextWalk(busStep, busStep1);
}
// 假如两个公交换乘中间没有步行,就把上一公交经纬度点和下一步公交第一个经纬度点连接起来,避免断线问题
if (busStep.getBusLine() != null
&& busStep1.getWalk() == null
&& busStep1.getBusLine() != null) {
checkBusEndToNextBusStart(busStep, busStep1);
}
// 和上面的很类似
if (busStep.getBusLine() != null
&& busStep1.getWalk() == null
&& busStep1.getBusLine() != null) {
checkBusToNextBusNoWalk(busStep, busStep1);
}
if (busStep.getBusLine() != null
&& busStep1.getRailway() != null ) {
checkBusLineToNextRailway(busStep, busStep1);
}
if (busStep1.getWalk() != null &&
busStep1.getWalk().getSteps().size() > 0 &&
busStep.getRailway() != null) {
checkRailwayToNextWalk(busStep, busStep1);
}
if ( busStep1.getRailway() != null &&
busStep.getRailway() != null) {
checkRailwayToNextRailway(busStep, busStep1);
}
if (busStep.getRailway() != null &&
busStep1.getTaxi() != null ){
checkRailwayToNextTaxi(busStep, busStep1);
}
}
if (busStep.getWalk() != null
&& busStep.getWalk().getSteps().size() > 0) {
addWalkSteps(busStep);
} else {
if (busStep.getBusLine() == null && busStep.getRailway() == null && busStep.getTaxi() == null) {
addWalkPolyline(latLng, endPoint);
}
}
if (busStep.getBusLine() != null) {
RouteBusLineItem routeBusLineItem = busStep.getBusLine();
addBusLineSteps(routeBusLineItem);
addBusStationMarkers(routeBusLineItem);
if (i == busSteps.size() - 1) {
addWalkPolyline(AMapUtil.convertToLatLng(getLastBuslinePoint(busStep)), endPoint);
}
}
if (busStep.getRailway() != null) {
addRailwayStep(busStep.getRailway());
addRailwayMarkers(busStep.getRailway());
if (i == busSteps.size() - 1) {
addWalkPolyline(AMapUtil.convertToLatLng(busStep.getRailway().getArrivalstop().getLocation()), endPoint);
}
}
if (busStep.getTaxi() != null) {
addTaxiStep(busStep.getTaxi());
addTaxiMarkers(busStep.getTaxi());
}
}
addStartAndEndMarker();
} catch (Throwable e) {
e.printStackTrace();
}
}
private void checkRailwayToNextTaxi(BusStep busStep, BusStep busStep1) {
LatLonPoint railwayLastPoint = busStep.getRailway().getArrivalstop().getLocation();
LatLonPoint taxiFirstPoint = busStep1.getTaxi().getOrigin();
if (!railwayLastPoint.equals(taxiFirstPoint)) {
addWalkPolyLineByLatLonPoints(railwayLastPoint, taxiFirstPoint);
}
}
private void checkRailwayToNextRailway(BusStep busStep, BusStep busStep1) {
LatLonPoint railwayLastPoint = busStep.getRailway().getArrivalstop().getLocation();
LatLonPoint railwayFirstPoint = busStep1.getRailway().getDeparturestop().getLocation();
if (!railwayLastPoint.equals(railwayFirstPoint)) {
addWalkPolyLineByLatLonPoints(railwayLastPoint, railwayFirstPoint);
}
}
private void checkBusLineToNextRailway(BusStep busStep, BusStep busStep1) {
LatLonPoint busLastPoint = getLastBuslinePoint(busStep);
LatLonPoint railwayFirstPoint = busStep1.getRailway().getDeparturestop().getLocation();
if (!busLastPoint.equals(railwayFirstPoint)) {
addWalkPolyLineByLatLonPoints(busLastPoint, railwayFirstPoint);
}
}
private void checkRailwayToNextWalk(BusStep busStep, BusStep busStep1) {
LatLonPoint railwayLastPoint = busStep.getRailway().getArrivalstop().getLocation();
LatLonPoint walkFirstPoint = getFirstWalkPoint(busStep1);
if (!railwayLastPoint.equals(walkFirstPoint)) {
addWalkPolyLineByLatLonPoints(railwayLastPoint, walkFirstPoint);
}
}
private void addRailwayStep(RouteRailwayItem railway) {
List<LatLng> railwaylistpoint = new ArrayList<LatLng>();
List<RailwayStationItem> railwayStationItems = new ArrayList<RailwayStationItem>();
railwayStationItems.add(railway.getDeparturestop());
railwayStationItems.addAll(railway.getViastops());
railwayStationItems.add(railway.getArrivalstop());
for (int i = 0; i < railwayStationItems.size(); i++) {
railwaylistpoint.add(AMapUtil.convertToLatLng(railwayStationItems.get(i).getLocation()));
}
addRailwayPolyline(railwaylistpoint);
}
private void addTaxiStep(TaxiItem taxi){
addPolyLine(new PolylineOptions().width(getRouteWidth())
.color(getBusColor())
.add(AMapUtil.convertToLatLng(taxi.getOrigin()))
.add(AMapUtil.convertToLatLng(taxi.getDestination())));
}
/**
* @param busStep
*/
private void addWalkSteps(BusStep busStep) {
RouteBusWalkItem routeBusWalkItem = busStep.getWalk();
List<WalkStep> walkSteps = routeBusWalkItem.getSteps();
for (int j = 0; j < walkSteps.size(); j++) {
WalkStep walkStep = walkSteps.get(j);
if (j == 0) {
LatLng latLng = AMapUtil.convertToLatLng(walkStep
.getPolyline().get(0));
String road = walkStep.getRoad();// 道路名字
String instruction = getWalkSnippet(walkSteps);// 步行导航信息
addWalkStationMarkers(latLng, road, instruction);
}
List<LatLng> listWalkPolyline = AMapUtil
.convertArrList(walkStep.getPolyline());
this.latLng = listWalkPolyline.get(listWalkPolyline.size() - 1);
addWalkPolyline(listWalkPolyline);
// 假如步行前一段的终点和下的起点有断开,断画直线连接起来,避免断线问题
if (j < walkSteps.size() - 1) {
LatLng lastLatLng = listWalkPolyline.get(listWalkPolyline
.size() - 1);
LatLng firstlatLatLng = AMapUtil
.convertToLatLng(walkSteps.get(j + 1).getPolyline()
.get(0));
if (!(lastLatLng.equals(firstlatLatLng))) {
addWalkPolyline(lastLatLng, firstlatLatLng);
}
}
}
}
/**
* 添加一系列的bus PolyLine
*
* @param routeBusLineItem
*/
private void addBusLineSteps(RouteBusLineItem routeBusLineItem) {
addBusLineSteps(routeBusLineItem.getPolyline());
}
private void addBusLineSteps(List<LatLonPoint> listPoints) {
if (listPoints.size() < 1) {
return;
}
addPolyLine(new PolylineOptions().width(getRouteWidth())
.color(getBusColor())
.addAll(AMapUtil.convertArrList(listPoints)));
}
/**
* @param latLng
* marker
* @param title
* @param snippet
*/
private void addWalkStationMarkers(LatLng latLng, String title,
String snippet) {
addStationMarker(new MarkerOptions().position(latLng).title(title)
.snippet(snippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
.icon(getWalkBitmapDescriptor()));
}
/**
* @param routeBusLineItem
*/
private void addBusStationMarkers(RouteBusLineItem routeBusLineItem) {
BusStationItem startBusStation = routeBusLineItem
.getDepartureBusStation();
LatLng position = AMapUtil.convertToLatLng(startBusStation
.getLatLonPoint());
String title = routeBusLineItem.getBusLineName();
String snippet = getBusSnippet(routeBusLineItem);
addStationMarker(new MarkerOptions().position(position).title(title)
.snippet(snippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
.icon(getBusBitmapDescriptor()));
}
private void addTaxiMarkers(TaxiItem taxiItem) {
LatLng position = AMapUtil.convertToLatLng(taxiItem
.getOrigin());
String title = taxiItem.getmSname()+"打车";
String snippet = "到终点";
addStationMarker(new MarkerOptions().position(position).title(title)
.snippet(snippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
.icon(getDriveBitmapDescriptor()));
}
private void addRailwayMarkers(RouteRailwayItem railway) {
LatLng Departureposition = AMapUtil.convertToLatLng(railway
.getDeparturestop().getLocation());
String Departuretitle = railway.getDeparturestop().getName()+"上车";
String Departuresnippet = railway.getName();
addStationMarker(new MarkerOptions().position(Departureposition).title(Departuretitle)
.snippet(Departuresnippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
.icon(getBusBitmapDescriptor()));
LatLng Arrivalposition = AMapUtil.convertToLatLng(railway
.getArrivalstop().getLocation());
String Arrivaltitle = railway.getArrivalstop().getName()+"下车";
String Arrivalsnippet = railway.getName();
addStationMarker(new MarkerOptions().position(Arrivalposition).title(Arrivaltitle)
.snippet(Arrivalsnippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
.icon(getBusBitmapDescriptor()));
}
/**
* 如果换乘没有步行 检查bus最后一点和下一个step的bus起点是否一致
*
* @param busStep
* @param busStep1
*/
private void checkBusToNextBusNoWalk(BusStep busStep, BusStep busStep1) {
LatLng endbusLatLng = AMapUtil
.convertToLatLng(getLastBuslinePoint(busStep));
LatLng startbusLatLng = AMapUtil
.convertToLatLng(getFirstBuslinePoint(busStep1));
if (startbusLatLng.latitude - endbusLatLng.latitude > 0.0001
|| startbusLatLng.longitude - endbusLatLng.longitude > 0.0001) {
drawLineArrow(endbusLatLng, startbusLatLng);// 断线用带箭头的直线连?
}
}
/**
*
* checkBusToNextBusNoWalk 和这个类似
*
* @param busStep
* @param busStep1
*/
private void checkBusEndToNextBusStart(BusStep busStep, BusStep busStep1) {
LatLonPoint busLastPoint = getLastBuslinePoint(busStep);
LatLng endbusLatLng = AMapUtil.convertToLatLng(busLastPoint);
LatLonPoint busFirstPoint = getFirstBuslinePoint(busStep1);
LatLng startbusLatLng = AMapUtil.convertToLatLng(busFirstPoint);
if (!endbusLatLng.equals(startbusLatLng)) {
drawLineArrow(endbusLatLng, startbusLatLng);//
}
}
/**
* 检查bus最后一步和下一各step的步行起点是否一致
*
* @param busStep
* @param busStep1
*/
private void checkBusLineToNextWalk(BusStep busStep, BusStep busStep1) {
LatLonPoint busLastPoint = getLastBuslinePoint(busStep);
LatLonPoint walkFirstPoint = getFirstWalkPoint(busStep1);
if (!busLastPoint.equals(walkFirstPoint)) {
addWalkPolyLineByLatLonPoints(busLastPoint, walkFirstPoint);
}
}
/**
* 检查 步行最后一点 和 bus的起点 是否一致
*
* @param busStep
*/
private void checkWalkToBusline(BusStep busStep) {
LatLonPoint walkLastPoint = getLastWalkPoint(busStep);
LatLonPoint buslineFirstPoint = getFirstBuslinePoint(busStep);
if (!walkLastPoint.equals(buslineFirstPoint)) {
addWalkPolyLineByLatLonPoints(walkLastPoint, buslineFirstPoint);
}
}
/**
* @param busStep1
* @return
*/
private LatLonPoint getFirstWalkPoint(BusStep busStep1) {
return busStep1.getWalk().getSteps().get(0).getPolyline().get(0);
}
/**
*
*/
private void addWalkPolyLineByLatLonPoints(LatLonPoint pointFrom,
LatLonPoint pointTo) {
LatLng latLngFrom = AMapUtil.convertToLatLng(pointFrom);
LatLng latLngTo = AMapUtil.convertToLatLng(pointTo);
addWalkPolyline(latLngFrom, latLngTo);
}
/**
* @param latLngFrom
* @param latLngTo
* @return
*/
private void addWalkPolyline(LatLng latLngFrom, LatLng latLngTo) {
addPolyLine(new PolylineOptions().add(latLngFrom, latLngTo)
.width(getRouteWidth()).color(getWalkColor()).setDottedLine(true));
}
/**
* @param listWalkPolyline
*/
private void addWalkPolyline(List<LatLng> listWalkPolyline) {
addPolyLine(new PolylineOptions().addAll(listWalkPolyline)
.color(getWalkColor()).width(getRouteWidth()).setDottedLine(true));
}
private void addRailwayPolyline(List<LatLng> listPolyline) {
addPolyLine(new PolylineOptions().addAll(listPolyline)
.color(getDriveColor()).width(getRouteWidth()));
}
private String getWalkSnippet(List<WalkStep> walkSteps) {
float disNum = 0;
for (WalkStep step : walkSteps) {
disNum += step.getDistance();
}
return "\u6B65\u884C" + disNum + "\u7C73";
}
public void drawLineArrow(LatLng latLngFrom, LatLng latLngTo) {
addPolyLine(new PolylineOptions().add(latLngFrom, latLngTo).width(3)
.color(getBusColor()).width(getRouteWidth()));// 绘制直线
}
private String getBusSnippet(RouteBusLineItem routeBusLineItem) {
return "("
+ routeBusLineItem.getDepartureBusStation().getBusStationName()
+ "-->"
+ routeBusLineItem.getArrivalBusStation().getBusStationName()
+ ") \u7ECF\u8FC7" + (routeBusLineItem.getPassStationNum() + 1)
+ "\u7AD9";
}
/**
* @param busStep
* @return
*/
private LatLonPoint getLastWalkPoint(BusStep busStep) {
List<WalkStep> walkSteps = busStep.getWalk().getSteps();
WalkStep walkStep = walkSteps.get(walkSteps.size() - 1);
List<LatLonPoint> lonPoints = walkStep.getPolyline();
return lonPoints.get(lonPoints.size() - 1);
}
private LatLonPoint getExitPoint(BusStep busStep) {
Doorway doorway = busStep.getExit();
if (doorway == null) {
return null;
}
return doorway.getLatLonPoint();
}
private LatLonPoint getLastBuslinePoint(BusStep busStep) {
List<LatLonPoint> lonPoints = busStep.getBusLine().getPolyline();
return lonPoints.get(lonPoints.size() - 1);
}
private LatLonPoint getEntrancePoint(BusStep busStep) {
Doorway doorway = busStep.getEntrance();
if (doorway == null) {
return null;
}
return doorway.getLatLonPoint();
}
private LatLonPoint getFirstBuslinePoint(BusStep busStep) {
return busStep.getBusLine().getPolyline().get(0);
}
}
package overlay;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Color;
import com.amap.api.maps.AMap;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveStep;
import com.amap.api.services.route.TMC;
import com.sd.maplibrary.R;
import com.sd.maplibrary.utils.amp.AMapUtil;
/**
* 导航路线图层类。
*/
public class DrivingRouteOverlay extends RouteOverlay{
private DrivePath drivePath;
private List<LatLonPoint> throughPointList;
private List<Marker> throughPointMarkerList = new ArrayList<Marker>();
private boolean throughPointMarkerVisible = true;
private List<TMC> tmcs;
private PolylineOptions mPolylineOptions;
private PolylineOptions mPolylineOptionscolor;
private Context mContext;
private boolean isColorfulline = true;
private float mWidth = 25;
private List<LatLng> mLatLngsOfPath;
public void setIsColorfulline(boolean iscolorfulline) {
this.isColorfulline = iscolorfulline;
}
/**
* 根据给定的参数,构造一个导航路线图层类对象。
*
* @param amap 地图对象。
* @param path 导航路线规划方案。
* @param context 当前的activity对象。
*/
public DrivingRouteOverlay(Context context, AMap amap, DrivePath path,
LatLonPoint start, LatLonPoint end, List<LatLonPoint> throughPointList) {
super(context);
mContext = context;
mAMap = amap;
this.drivePath = path;
startPoint = AMapUtil.convertToLatLng(start);
endPoint = AMapUtil.convertToLatLng(end);
this.throughPointList = throughPointList;
}
public float getRouteWidth() {
return mWidth;
}
/**
* 设置路线宽度
*
* @param mWidth 路线宽度,取值范围:大于0
*/
public void setRouteWidth(float mWidth) {
this.mWidth = mWidth;
}
/**
* 添加驾车路线添加到地图上显示。
*/
public void addToMap() {
initPolylineOptions();
try {
if (mAMap == null) {
return;
}
if (mWidth == 0 || drivePath == null) {
return;
}
mLatLngsOfPath = new ArrayList<LatLng>();
tmcs = new ArrayList<TMC>();
List<DriveStep> drivePaths = drivePath.getSteps();
for (DriveStep step : drivePaths) {
List<LatLonPoint> latlonPoints = step.getPolyline();
List<TMC> tmclist = step.getTMCs();
tmcs.addAll(tmclist);
addDrivingStationMarkers(step, convertToLatLng(latlonPoints.get(0)));
for (LatLonPoint latlonpoint : latlonPoints) {
mPolylineOptions.add(convertToLatLng(latlonpoint));
mLatLngsOfPath.add(convertToLatLng(latlonpoint));
}
}
if (startMarker != null) {
startMarker.remove();
startMarker = null;
}
if (endMarker != null) {
endMarker.remove();
endMarker = null;
}
addStartAndEndMarker();
addThroughPointMarker();
if (isColorfulline && tmcs.size()>0 ) {
colorWayUpdate(tmcs);
showcolorPolyline();
}else {
showPolyline();
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 初始化线段属性
*/
private void initPolylineOptions() {
mPolylineOptions = null;
mPolylineOptions = new PolylineOptions();
mPolylineOptions
.color(getDriveColor())
.setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.custtexture))
.width(getRouteWidth());
}
private void showPolyline() {
addPolyLine(mPolylineOptions);
}
private void showcolorPolyline() {
addPolyLine(mPolylineOptionscolor);
}
/**
* 根据不同的路段拥堵情况展示不同的颜色
*
* @param tmcSection
*/
private void colorWayUpdate(List<TMC> tmcSection) {
if (mAMap == null) {
return;
}
if (tmcSection == null || tmcSection.size() <= 0) {
return;
}
TMC segmentTrafficStatus;
mPolylineOptionscolor = null;
mPolylineOptionscolor = new PolylineOptions();
mPolylineOptionscolor.width(getRouteWidth());
List<Integer> colorList = new ArrayList<Integer>();
mPolylineOptionscolor.add(AMapUtil.convertToLatLng(tmcSection.get(0).getPolyline().get(0)));
colorList.add(getDriveColor());
for (int i = 0; i < tmcSection.size(); i++) {
segmentTrafficStatus = tmcSection.get(i);
int color = getcolor(segmentTrafficStatus.getStatus());
List<LatLonPoint> mployline = segmentTrafficStatus.getPolyline();
for (int j = 1; j < mployline.size(); j++) {
mPolylineOptionscolor.add(AMapUtil.convertToLatLng(mployline.get(j)));
colorList.add(color);
}
}
colorList.add(getDriveColor());
mPolylineOptionscolor.colorValues(colorList);
}
private int getcolor(String status) {
if (status.equals("畅通")) {
return Color.GREEN;
} else if (status.equals("缓行")) {
return Color.YELLOW;
} else if (status.equals("拥堵")) {
return Color.RED;
} else if (status.equals("严重拥堵")) {
return Color.parseColor("#990033");
} else {
return Color.parseColor("#537edc");
}
}
public LatLng convertToLatLng(LatLonPoint point) {
return new LatLng(point.getLatitude(),point.getLongitude());
}
/**
* @param driveStep
* @param latLng
*/
private void addDrivingStationMarkers(DriveStep driveStep, LatLng latLng) {
addStationMarker(new MarkerOptions()
.position(latLng)
.title("\u65B9\u5411:" + driveStep.getAction()
+ "\n\u9053\u8DEF:" + driveStep.getRoad())
.snippet(driveStep.getInstruction()).visible(nodeIconVisible)
.anchor(0.5f, 0.5f).icon(getDriveBitmapDescriptor()));
}
@Override
protected LatLngBounds getLatLngBounds() {
LatLngBounds.Builder b = LatLngBounds.builder();
b.include(new LatLng(startPoint.latitude, startPoint.longitude));
b.include(new LatLng(endPoint.latitude, endPoint.longitude));
if (this.throughPointList != null && this.throughPointList.size() > 0) {
for (int i = 0; i < this.throughPointList.size(); i++) {
b.include(new LatLng(
this.throughPointList.get(i).getLatitude(),
this.throughPointList.get(i).getLongitude()));
}
}
return b.build();
}
public void setThroughPointIconVisibility(boolean visible) {
try {
throughPointMarkerVisible = visible;
if (this.throughPointMarkerList != null
&& this.throughPointMarkerList.size() > 0) {
for (int i = 0; i < this.throughPointMarkerList.size(); i++) {
this.throughPointMarkerList.get(i).setVisible(visible);
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void addThroughPointMarker() {
if (this.throughPointList != null && this.throughPointList.size() > 0) {
LatLonPoint latLonPoint = null;
for (int i = 0; i < this.throughPointList.size(); i++) {
latLonPoint = this.throughPointList.get(i);
if (latLonPoint != null) {
throughPointMarkerList.add(mAMap
.addMarker((new MarkerOptions())
.position(
new LatLng(latLonPoint
.getLatitude(), latLonPoint
.getLongitude()))
.visible(throughPointMarkerVisible)
.icon(getThroughPointBitDes())
.title("\u9014\u7ECF\u70B9")));
}
}
}
}
private BitmapDescriptor getThroughPointBitDes() {
return BitmapDescriptorFactory.fromResource(R.drawable.amap_through);
}
/**
* 获取两点间距离
*
* @param start
* @param end
* @return
*/
public static int calculateDistance(LatLng start, LatLng end) {
double x1 = start.longitude;
double y1 = start.latitude;
double x2 = end.longitude;
double y2 = end.latitude;
return calculateDistance(x1, y1, x2, y2);
}
public static int calculateDistance(double x1, double y1, double x2, double y2) {
final double NF_pi = 0.01745329251994329; // 弧度 PI/180
x1 *= NF_pi;
y1 *= NF_pi;
x2 *= NF_pi;
y2 *= NF_pi;
double sinx1 = Math.sin(x1);
double siny1 = Math.sin(y1);
double cosx1 = Math.cos(x1);
double cosy1 = Math.cos(y1);
double sinx2 = Math.sin(x2);
double siny2 = Math.sin(y2);
double cosx2 = Math.cos(x2);
double cosy2 = Math.cos(y2);
double[] v1 = new double[3];
v1[0] = cosy1 * cosx1 - cosy2 * cosx2;
v1[1] = cosy1 * sinx1 - cosy2 * sinx2;
v1[2] = siny1 - siny2;
double dist = Math.sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
return (int) (Math.asin(dist / 2) * 12742001.5798544);
}
//获取指定两点之间固定距离点
public static LatLng getPointForDis(LatLng sPt, LatLng ePt, double dis) {
double lSegLength = calculateDistance(sPt, ePt);
double preResult = dis / lSegLength;
return new LatLng((ePt.latitude - sPt.latitude) * preResult + sPt.latitude, (ePt.longitude - sPt.longitude) * preResult + sPt.longitude);
}
/**
* 去掉DriveLineOverlay上的线段和标记。
*/
@Override
public void removeFromMap() {
try {
super.removeFromMap();
if (this.throughPointMarkerList != null
&& this.throughPointMarkerList.size() > 0) {
for (int i = 0; i < this.throughPointMarkerList.size(); i++) {
this.throughPointMarkerList.get(i).remove();
}
this.throughPointMarkerList.clear();
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package overlay;
import android.content.Context;
import android.graphics.Color;
import com.amap.api.maps.AMap;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.DrivePlanPath;
import com.amap.api.services.route.DrivePlanStep;
import com.amap.api.services.route.DriveRoutePlanResult;
import com.amap.api.services.route.TMC;
import com.amap.api.services.route.TimeInfo;
import com.amap.api.services.route.TimeInfosElement;
import com.sd.maplibrary.utils.amp.AMapUtil;
import java.util.ArrayList;
import java.util.List;
public class DrivingRoutePlanOverlay extends RouteOverlay{
private Context mContext;
DriveRoutePlanResult driveRoutePlanResult;
private boolean isColorfulline = true;
private float mWidth = 25;
private List<LatLng> mLatLngsOfPath;
private int selectIndex = 0;
private PolylineOptions mPolylineOptions;
private PolylineOptions mPolylineOptionscolor;
public DrivingRoutePlanOverlay(Context context, AMap amap, DriveRoutePlanResult result, int index) {
super(context);
mContext = context;
mAMap = amap;
driveRoutePlanResult = result;
selectIndex = index;
if (result != null) {
startPoint = AMapUtil.convertToLatLng(result.getStartPos());
endPoint = AMapUtil.convertToLatLng(result.getTargetPos());
}
}
public void setIsColorfulline(boolean iscolorfulline) {
this.isColorfulline = iscolorfulline;
}
/**
* 添加驾车路线添加到地图上显示。
*/
public void addToMap() {
initPolylineOptions();
try {
if (mAMap == null) {
return;
}
if (mWidth == 0 || driveRoutePlanResult == null) {
return;
}
if (driveRoutePlanResult.getTimeInfos() == null || driveRoutePlanResult.getPaths() == null) {
return;
}
mLatLngsOfPath = new ArrayList<LatLng>();
List<TMC> tmcs = new ArrayList<TMC>();
List<TimeInfo> timeInfos = driveRoutePlanResult.getTimeInfos();
if (selectIndex >= 0 && selectIndex < timeInfos.size()) {
tmcs = timeInfos.get(selectIndex).getElements().get(0).getTMCs();
}
int pathIndex = timeInfos.get(selectIndex).getElements().get(0).getPathindex();
if (pathIndex < 0 || pathIndex > driveRoutePlanResult.getPaths().size()) {
return;
}
DrivePlanPath drivePlanPath = driveRoutePlanResult.getPaths().get(pathIndex);
List<DrivePlanStep> drivePaths = drivePlanPath.getSteps();
for (DrivePlanStep step : drivePaths) {
List<LatLonPoint> latlonPoints = step.getPolyline();
//List<TMC> tmclist = step.getTMCs();
//tmcs.addAll(tmclist);
for (LatLonPoint latlonpoint : latlonPoints) {
mPolylineOptions.add(convertToLatLng(latlonpoint));
mLatLngsOfPath.add(convertToLatLng(latlonpoint));
}
}
if (startMarker != null) {
startMarker.remove();
startMarker = null;
}
if (endMarker != null) {
endMarker.remove();
endMarker = null;
}
addStartAndEndMarker();
if (isColorfulline && tmcs.size()>0 ) {
colorWayUpdate(tmcs);
showcolorPolyline();
}else {
showPolyline();
}
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 初始化线段属性
*/
private void initPolylineOptions() {
mPolylineOptions = null;
mPolylineOptions = new PolylineOptions();
mPolylineOptions.color(getDriveColor()).width(getRouteWidth());
}
private void showPolyline() {
addPolyLine(mPolylineOptions);
}
private void showcolorPolyline() {
addPolyLine(mPolylineOptionscolor);
}
/**
* 根据不同的路段拥堵情况展示不同的颜色
*
* @param tmcSection
*/
private void colorWayUpdate(List<TMC> tmcSection) {
if (mAMap == null) {
return;
}
if (tmcSection == null || tmcSection.size() <= 0) {
return;
}
TMC segmentTrafficStatus;
mPolylineOptionscolor = null;
mPolylineOptionscolor = new PolylineOptions();
mPolylineOptionscolor.width(getRouteWidth());
List<Integer> colorList = new ArrayList<Integer>();
mPolylineOptionscolor.add(AMapUtil.convertToLatLng(tmcSection.get(0).getPolyline().get(0)));
colorList.add(getDriveColor());
for (int i = 0; i < tmcSection.size(); i++) {
segmentTrafficStatus = tmcSection.get(i);
int color = getcolor(segmentTrafficStatus.getStatus());
List<LatLonPoint> mployline = segmentTrafficStatus.getPolyline();
for (int j = 1; j < mployline.size(); j++) {
mPolylineOptionscolor.add(AMapUtil.convertToLatLng(mployline.get(j)));
colorList.add(color);
}
}
colorList.add(getDriveColor());
mPolylineOptionscolor.colorValues(colorList);
}
private int getcolor(String status) {
if (status.equals("畅通")) {
return Color.GREEN;
} else if (status.equals("缓行")) {
return Color.YELLOW;
} else if (status.equals("拥堵")) {
return Color.RED;
} else if (status.equals("严重拥堵")) {
return Color.parseColor("#990033");
} else {
return Color.parseColor("#537edc");
}
}
public LatLng convertToLatLng(LatLonPoint point) {
return new LatLng(point.getLatitude(),point.getLongitude());
}
}
package overlay;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.TextView;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.Gradient;
import com.amap.api.maps.model.HeatMapLayerOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.WeightedLatLng;
import com.sd.maplibrary.R;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
public class HoneycombHeatMapActivity extends Activity {
private MapView mMapView ;
private AMap mMap;
private TextView heatItemTv = null;
private com.amap.api.maps.model.HeatMapLayer heatMapLayer = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_heatmap_overlay);
mMapView = findViewById(R.id.mapview);
mMapView.onCreate(savedInstanceState);
heatItemTv = findViewById(R.id.heat_item_tv);
mMap = mMapView.getMap();
mMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
@Override
public void onMapLoaded() {
testHeatMapOverlay();
}
});
}
private void testHeatMapOverlay() {
// 因为数据都在青岛附近,将地图中心点移动到青岛
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(36.673927,119.996751), 8.5f));
String heatMapStr = new String(readFileContentsFromAssets(this, "heatmap/heatmap_honey.data"));
String[] heatMapStrs = heatMapStr.split("\n");
WeightedLatLng[] weightlatlngs = new WeightedLatLng[heatMapStrs.length];
int index = 0;
for (String str : heatMapStrs) {
String[] dataItem = str.split(",");
if (dataItem != null && dataItem.length == 3) {
weightlatlngs[index] = new WeightedLatLng(new LatLng(Double.parseDouble(dataItem[1]), Double.parseDouble(dataItem[0])), Double.parseDouble(dataItem[2]));
} else {
android.util.Log.e("mapcore","read file failed");
}
index++;
}
int[] colors = {
Color.parseColor("#ecda9a"),
Color.parseColor("#efc47e"),
Color.parseColor("#f3ad6a"),
Color.parseColor("#f7945d"),
Color.parseColor("#f97b57"),
Color.parseColor("#f66356"),
Color.parseColor("#ee4d5a")};
float[] startPoints = new float[colors.length];
for(int i =0 ;i < startPoints.length; i ++) {
startPoints[i] = i * 1.0f / startPoints.length ;
}
HeatMapLayerOptions heatMapLayerOptions = new HeatMapLayerOptions();
// 带权重的经纬度
heatMapLayerOptions.weightedData(Arrays.asList(weightlatlngs));
// 指定颜色和颜色变化索引
Gradient gradient = new Gradient(colors, startPoints);
heatMapLayerOptions.gradient(gradient);
// 大小和间隔
heatMapLayerOptions.size(6000);
heatMapLayerOptions.gap(300);
// 最大最小缩放级别
heatMapLayerOptions.minZoom(5);
heatMapLayerOptions.maxZoom(19);
// 整个覆盖物的透明度
heatMapLayerOptions.opacity(0.85f);
// 热力图类型为蜂窝
heatMapLayerOptions.type(HeatMapLayerOptions.TYPE_HEXAGON);
// 控制在底图文字的上面,默认底图文字级别是0
heatMapLayerOptions.zIndex(1);
heatMapLayer = mMap.addHeatMapLayer(heatMapLayerOptions);
// 获取指定位置的热力情况
mMap.setOnMapClickListener(new AMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
if (heatMapLayer != null && mMap != null && latLng != null) {
com.amap.api.maps.model.HeatMapItem item = heatMapLayer.getHeatMapItem(latLng);
if (item != null) {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("热力中心:").append(item.getCenter()).append("\n");
stringBuffer.append("热力值:").append(item.getIntensity()).append("\n");
String indexes = "";
for(Integer integer : item.getIndexes()) {
indexes += integer + ",";
}
stringBuffer.append("热力索引:").append(indexes).append("\n");
stringBuffer.append("数据数量:").append(item.getIndexes().length);
updateHeatItemTv(stringBuffer.toString());
} else {
updateHeatItemTv("未找到热力信息");
}
}
}
});
}
private void updateHeatItemTv(final String text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if(heatItemTv != null && text != null) {
heatItemTv.setText(text);
}
}
});
}
public static byte[] readFileContentsFromAssets(Context context, String assetsPath) {
AssetManager assetManager = context.getAssets();
InputStream is = null;
try {
String path = assetsPath;
is = assetManager.open(path);
int count = is.available();
if (count == 0) {
return null;
}
byte[] bufferByte = new byte[count];
// 已经成功读取的字节的个数
int readCount = 0;
while (readCount < count) {
readCount += is.read(bufferByte, readCount, count - readCount);
}
is.close();
return bufferByte;
} catch (IOException e) {
return null;
} catch (OutOfMemoryError e) {
return null;
}
}
@Override
protected void onResume() {
super.onResume();
if (mMapView != null) {
mMapView.onResume();
}
}
@Override
protected void onPause() {
if (mMapView != null) {
mMapView.onPause();
}
super.onPause();
}
@Override
protected void onDestroy() {
if (mMapView != null) {
mMapView.onDestroy();
}
super.onDestroy();
}
}
package overlay;
import java.util.ArrayList;
import java.util.List;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.services.core.PoiItem;
/**
* Poi图层类。在高德地图API里,如果要显示Poi,可以用此类来创建Poi图层。如不满足需求,也可以自己创建自定义的Poi图层。
* @since V2.1.0
*/
public class PoiOverlay {
private List<PoiItem> mPois;
private AMap mAMap;
private ArrayList<Marker> mPoiMarks = new ArrayList<Marker>();
/**
* 通过此构造函数创建Poi图层。
* @param amap 地图对象。
* @param pois 要在地图上添加的poi。列表中的poi对象详见搜索服务模块的基础核心包(com.amap.api.services.core)中的类<strong> <a href="../../../../../../Search/com/amap/api/services/core/PoiItem.html" title="com.amap.api.services.core中的类">PoiItem</a></strong>。
* @since V2.1.0
*/
public PoiOverlay(AMap amap, List<PoiItem> pois) {
mAMap = amap;
mPois = pois;
}
/**
* 添加Marker到地图中。
* @since V2.1.0
*/
public void addToMap() {
try{
for (int i = 0; i < mPois.size(); i++) {
Marker marker = mAMap.addMarker(getMarkerOptions(i));
marker.setObject(i);
mPoiMarks.add(marker);
}
}catch(Throwable e){
e.printStackTrace();
}
}
/**
* 去掉PoiOverlay上所有的Marker。
* @since V2.1.0
*/
public void removeFromMap() {
for (Marker mark : mPoiMarks) {
mark.remove();
}
}
/**
* 移动镜头到当前的视角。
* @since V2.1.0
*/
public void zoomToSpan() {
try{
if (mPois != null && mPois.size() > 0) {
if (mAMap == null)
return;
if(mPois.size()==1){
mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mPois.get(0).getLatLonPoint().getLatitude(),
mPois.get(0).getLatLonPoint().getLongitude()), 18f));
}else{
LatLngBounds bounds = getLatLngBounds();
mAMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 5));
}
}
}catch(Throwable e){
e.printStackTrace();
}
}
private LatLngBounds getLatLngBounds() {
LatLngBounds.Builder b = LatLngBounds.builder();
for (int i = 0; i < mPois.size(); i++) {
b.include(new LatLng(mPois.get(i).getLatLonPoint().getLatitude(),
mPois.get(i).getLatLonPoint().getLongitude()));
}
return b.build();
}
private MarkerOptions getMarkerOptions(int index) {
return new MarkerOptions()
.position(
new LatLng(mPois.get(index).getLatLonPoint()
.getLatitude(), mPois.get(index)
.getLatLonPoint().getLongitude()))
.title(getTitle(index)).snippet(getSnippet(index))
.icon(getBitmapDescriptor(index));
}
/**
* 给第几个Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
* @param index 第几个Marker。
* @return 更换的Marker图片。
* @since V2.1.0
*/
protected BitmapDescriptor getBitmapDescriptor(int index) {
return null;
}
/**
* 返回第index的Marker的标题。
* @param index 第几个Marker。
* @return marker的标题。
* @since V2.1.0
*/
protected String getTitle(int index) {
return mPois.get(index).getTitle();
}
/**
* 返回第index的Marker的详情。
* @param index 第几个Marker。
* @return marker的详情。
* @since V2.1.0
*/
protected String getSnippet(int index) {
return mPois.get(index).getSnippet();
}
/**
* 从marker中得到poi在list的位置。
* @param marker 一个标记的对象。
* @return 返回该marker对应的poi在list的位置。
* @since V2.1.0
*/
public int getPoiIndex(Marker marker) {
for (int i = 0; i < mPoiMarks.size(); i++) {
if (mPoiMarks.get(i).equals(marker)) {
return i;
}
}
return -1;
}
/**
* 返回第index的poi的信息。
* @param index 第几个poi。
* @return poi的信息。poi对象详见搜索服务模块的基础核心包(com.amap.api.services.core)中的类 <strong><a href="../../../../../../Search/com/amap/api/services/core/PoiItem.html" title="com.amap.api.services.core中的类">PoiItem</a></strong>。
* @since V2.1.0
*/
public PoiItem getPoiItem(int index) {
if (index < 0 || index >= mPois.size()) {
return null;
}
return mPois.get(index);
}
}
package overlay;
import java.util.List;
import android.content.Context;
import com.amap.api.maps.AMap;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.RidePath;
import com.amap.api.services.route.RideStep;
import com.sd.maplibrary.R;
import com.sd.maplibrary.utils.amp.AMapUtil;
/**
* 骑行路线图层类。在高德地图API里,如果要显示步行路线规划,可以用此类来创建骑行路线图层。如不满足需求,也可以自己创建自定义的骑行路线图层。
* @since V3.5.0
*/
public class RideRouteOverlay extends RouteOverlay {
private PolylineOptions mPolylineOptions;
private BitmapDescriptor walkStationDescriptor= null;
private RidePath ridePath;
/**
* 通过此构造函数创建骑行路线图层。
* @param context 当前activity。
* @param amap 地图对象。
* @param path 骑行路线规划的一个方案。详见搜索服务模块的路径查询包(com.amap.api.services.route)中的类 <strong><a href="../../../../../../Search/com/amap/api/services/route/WalkStep.html" title="com.amap.api.services.route中的类">WalkStep</a></strong>。
* @param start 起点。详见搜索服务模块的核心基础包(com.amap.api.services.core)中的类<strong><a href="../../../../../../Search/com/amap/api/services/core/LatLonPoint.html" title="com.amap.api.services.core中的类">LatLonPoint</a></strong>。
* @param end 终点。详见搜索服务模块的核心基础包(com.amap.api.services.core)中的类<strong><a href="../../../../../../Search/com/amap/api/services/core/LatLonPoint.html" title="com.amap.api.services.core中的类">LatLonPoint</a></strong>。
* @since V3.5.0
*/
public RideRouteOverlay(Context context, AMap amap, RidePath path,
LatLonPoint start, LatLonPoint end) {
super(context);
this.mAMap = amap;
this.ridePath = path;
startPoint = AMapUtil.convertToLatLng(start);
endPoint = AMapUtil.convertToLatLng(end);
}
/**
* 添加骑行路线到地图中。
* @since V3.5.0
*/
public void addToMap() {
initPolylineOptions();
try {
List<RideStep> ridePaths = ridePath.getSteps();
for (int i = 0; i < ridePaths.size(); i++) {
RideStep rideStep = ridePaths.get(i);
LatLng latLng = AMapUtil.convertToLatLng(rideStep
.getPolyline().get(0));
addRideStationMarkers(rideStep, latLng);
addRidePolyLines(rideStep);
}
addStartAndEndMarker();
showPolyline();
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* @param rideStep
*/
private void addRidePolyLines(RideStep rideStep) {
mPolylineOptions.addAll(AMapUtil.convertArrList(rideStep.getPolyline()));
}
/**
* @param rideStep
* @param position
*/
private void addRideStationMarkers(RideStep rideStep, LatLng position) {
addStationMarker(new MarkerOptions()
.position(position)
.title("\u65B9\u5411:" + rideStep.getAction()
+ "\n\u9053\u8DEF:" + rideStep.getRoad())
.snippet(rideStep.getInstruction()).visible(nodeIconVisible)
.anchor(0.5f, 0.5f).icon(walkStationDescriptor));
}
/**
* 初始化线段属性
*/
private void initPolylineOptions() {
if(walkStationDescriptor == null) {
walkStationDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.amap_ride);
}
mPolylineOptions = null;
mPolylineOptions = new PolylineOptions();
mPolylineOptions.color(getDriveColor()).width(getRouteWidth());
}
private void showPolyline() {
addPolyLine(mPolylineOptions);
}
}
package overlay;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.sd.maplibrary.R;
public class RouteOverlay {
protected List<Marker> stationMarkers = new ArrayList<Marker>();
protected List<Polyline> allPolyLines = new ArrayList<Polyline>();
protected Marker startMarker;
protected Marker endMarker;
protected LatLng startPoint;
protected LatLng endPoint;
protected AMap mAMap;
private Context mContext;
private Bitmap startBit, endBit, busBit, walkBit, driveBit;
protected boolean nodeIconVisible = true;
public RouteOverlay(Context context) {
mContext = context;
}
/**
* 去掉BusRouteOverlay上所有的Marker。
* @since V2.1.0
*/
public void removeFromMap() {
if (startMarker != null) {
startMarker.remove();
}
if (endMarker != null) {
endMarker.remove();
}
for (Marker marker : stationMarkers) {
marker.remove();
}
for (Polyline line : allPolyLines) {
line.remove();
}
destroyBit();
}
private void destroyBit() {
if (startBit != null) {
startBit.recycle();
startBit = null;
}
if (endBit != null) {
endBit.recycle();
endBit = null;
}
if (busBit != null) {
busBit.recycle();
busBit = null;
}
if (walkBit != null) {
walkBit.recycle();
walkBit = null;
}
if (driveBit != null) {
driveBit.recycle();
driveBit = null;
}
}
/**
* 给起点Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
* @return 更换的Marker图片。
* @since V2.1.0
*/
protected BitmapDescriptor getStartBitmapDescriptor() {
return BitmapDescriptorFactory.fromResource(R.drawable.amap_start);
}
/**
* 给终点Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
* @return 更换的Marker图片。
* @since V2.1.0
*/
protected BitmapDescriptor getEndBitmapDescriptor() {
return BitmapDescriptorFactory.fromResource(R.drawable.amap_end);
}
/**
* 给公交Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
* @return 更换的Marker图片。
* @since V2.1.0
*/
protected BitmapDescriptor getBusBitmapDescriptor() {
return BitmapDescriptorFactory.fromResource(R.drawable.amap_bus);
}
/**
* 给步行Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。
* @return 更换的Marker图片。
* @since V2.1.0
*/
protected BitmapDescriptor getWalkBitmapDescriptor() {
return BitmapDescriptorFactory.fromResource(R.drawable.amap_man);
}
protected BitmapDescriptor getDriveBitmapDescriptor() {
return BitmapDescriptorFactory.fromResource(R.drawable.amap_car);
}
protected void addStartAndEndMarker() {
startMarker = mAMap.addMarker((new MarkerOptions())
.position(startPoint).icon(getStartBitmapDescriptor())
.title("\u8D77\u70B9"));
// startMarker.showInfoWindow();
endMarker = mAMap.addMarker((new MarkerOptions()).position(endPoint)
.icon(getEndBitmapDescriptor()).title("\u7EC8\u70B9"));
// mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(startPoint,
// getShowRouteZoom()));
}
/**
* 移动镜头到当前的视角。
* @since V2.1.0
*/
public void zoomToSpan() {
if (startPoint != null) {
if (mAMap == null) {
return;
}
try {
LatLngBounds bounds = getLatLngBounds();
mAMap.animateCamera(CameraUpdateFactory
.newLatLngBounds(bounds, 100));
} catch (Throwable e) {
e.printStackTrace();
}
}
}
protected LatLngBounds getLatLngBounds() {
LatLngBounds.Builder b = LatLngBounds.builder();
b.include(new LatLng(startPoint.latitude, startPoint.longitude));
b.include(new LatLng(endPoint.latitude, endPoint.longitude));
return b.build();
}
/**
* 路段节点图标控制显示接口。
* @param visible true为显示节点图标,false为不显示。
* @since V2.3.1
*/
public void setNodeIconVisibility(boolean visible) {
try {
nodeIconVisible = visible;
if (this.stationMarkers != null && this.stationMarkers.size() > 0) {
for (int i = 0; i < this.stationMarkers.size(); i++) {
this.stationMarkers.get(i).setVisible(visible);
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
protected void addStationMarker(MarkerOptions options) {
if(options == null) {
return;
}
Marker marker = mAMap.addMarker(options);
if(marker != null) {
stationMarkers.add(marker);
}
}
protected void addPolyLine(PolylineOptions options) {
if(options == null) {
return;
}
Polyline polyline = mAMap.addPolyline(options);
if(polyline != null) {
allPolyLines.add(polyline);
}
}
protected float getRouteWidth() {
return 18f;
}
protected int getWalkColor() {
return Color.parseColor("#6db74d");
}
/**
* 自定义路线颜色。
* return 自定义路线颜色。
* @since V2.2.1
*/
protected int getBusColor() {
return Color.parseColor("#537edc");
}
protected int getDriveColor() {
return Color.parseColor("#537edc");
}
// protected int getShowRouteZoom() {
// return 15;
// }
}
package overlay;
import java.util.ArrayList;
import java.util.List;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.maps.model.LatLngBounds.Builder;
public class TraceOverlay {
private Polyline mPolyline;
private PolylineOptions mOption;
private AMap mAMap;
private List<LatLng> mTracedList = new ArrayList<LatLng>();
public static final int TRACE_STATUS_PROCESSING = 1;
public static final int TRACE_STATUS_FINISH = 2;
public static final int TRACE_STATUS_FAILURE = 3;
public static final int TRACE_STATUS_PREPARE = 4;
private int mTraceStatus = TRACE_STATUS_PREPARE;
private int mDistance;
private int mWaitTime;
public TraceOverlay(AMap amap, List<LatLng> lines) {
this.mAMap = amap;
options();
mOption.addAll(lines);
mPolyline = amap.addPolyline(mOption);
}
public TraceOverlay(AMap amap) {
this.mAMap = amap;
options();
}
public void add(List<LatLng> segments) {
if (segments == null || segments.size() == 0) {
return;
}
mTracedList.addAll(segments);
options();
if (mPolyline == null) {
mPolyline = mAMap.addPolyline(mOption);
}
mPolyline.setPoints(mTracedList);
}
public void remove() {
if (mPolyline != null) {
mPolyline.remove();
}
}
public void setProperCamera(List<LatLng> lists) {
Builder builder = LatLngBounds.builder();
if (lists == null || lists.size() == 0) {
return;
}
for (LatLng latlng : lists) {
builder.include(latlng);
}
try {
LatLngBounds bounds = builder.build();
mAMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 20));
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
public void zoopToSpan() {
List<LatLng> lists = mOption.getPoints();
setProperCamera(lists);
}
private PolylineOptions options() {
if (mOption == null) {
mOption = new PolylineOptions();
mOption.setCustomTexture(BitmapDescriptorFactory
.fromAsset("tracelinetexture.png"));
mOption.width(40);
}
return mOption;
}
public int getTraceStatus() {
return mTraceStatus;
}
public void setTraceStatus(int mTraceStatus) {
this.mTraceStatus = mTraceStatus;
}
public int getDistance() {
return mDistance;
}
public void setDistance(int mDistance) {
this.mDistance = mDistance;
}
public int getWaitTime() {
return mWaitTime;
}
public void setWaitTime(int mWaitTime) {
this.mWaitTime = mWaitTime;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment