Amap【高德】/Google-開發,無人機航跡規劃演示
阿新 • • 發佈:2019-01-26
ps:又到了週五,才有時間來寫點部落格記錄下,這篇文章的所描述的內容是我2017年後 做的一個功能,也是我們的產品經理結合 航跡規劃 以及我們所提供的 能做到的一些地圖開發結合,做的一個自創性的 開發吧。其實開始做的時候挺不自信的,因為第一,地圖sdk 並不是非常瞭解,再說,裡面有好多效果和功能 ,主要是一個動態修改航點和航線這個效果,在評估的時候,著實讓我覺得頭疼。而且領導還說專案很急,讓我一週把航跡規劃和電子圍欄的開發 做完,我和ios 當初可是評估後給了 3個星期的工作日的。他要我們一週搞完,心裡挺虛的。
本身博主就是個菜雞,畢業才半年,雖說在公司實習到現在有一年了,但是畢竟改變不了菜的現實。沒辦法,頂頭幹吧。在開發中,越搞越happay ,常常加班到11點,覺得蠻有意思的,顯然不是純粹的使用地圖的簡單功能來完成開發的,而是有點難度的。聽意外的,4個工作日,就把航跡規劃和電子圍欄 搞完了。滿有成就感的。
在地圖上增加點 必須在onMapClick 中操作,在onMapClick 獲取最基本的Latlng 資料,並繪製 航線。
add PolyLine
這是基本的 新增資料 在地圖上顯示,下面就讓他來動起來吧。
監聽回撥:
繼續 上一個 程式碼中的方法
繼續上一個程式碼的方法
基本 的重點都講完了,下面是我完整的 java 檔案
博主以前是學文科的,廢話有點多,不要見怪。整個效果展示的比較長,但是呢,gif 又只能上傳2M 的圖,無奈只能一個一個截取了。fps 設定的也有點低,沒辦法,gif 2M 實在太小。將就看吧。
1.
2.
3.
一:這次只展示 航跡規劃這一個專案,電子圍欄,我已經在之前文章中寫過了。
二:本次功能要點我做個簡單的闡述。
①.要分清楚 你需要建立幾個集合 分別是:lList<Latlng>,List<Marker>,List<PolyLine>,代表的分別是,座標點,標記點,航線。
②.在UI 給的圖片上 繪製 標號,技術好的應該都會,我下面會把程式碼貼出來
③.就是吧Marker的.draggable(true),前提 先吧拖拽功能開啟。才可以操作
④重點是這個 線拖拽的問題,分別位2種情況
1)例如圖一 在沒有2 出現的情況下只有一種情況,拖拽 marker 1 將 線一拖動,
2)例如2 在拖拽2的時候會牽扯到 2根線,2根線要同步重新整理。
3)額外說的一個,我的電子圍欄中 更復雜一點,比如第一個點生成。 邏輯都和這個一樣,但是在最後一根線的時候,他要圍城一個圍欄,在沒圍成之前,拖拽marker 1的時候 只有一根線,拖拽2 會有2根,拖拽最後一個Marker 也只有一根,但是一旦確認 圍欄 形成,最後一個Marker會和第一個Marker 產生一條線,這時候在拖拽 1和最後一個marker 就需要聯動,所有的點都是 2根線 在動。這個 就從程式碼上沒什麼技術含量,但是邏輯上 需要思考好多。這次就不說這個,我下面會把程式碼貼出來。
開始貼程式碼了。
重點的幾個說完 就直接把所有的貼出來。
private ArrayList<LatLng> mPfLatLngList = new ArrayList<>(); // latlng的數量比marker的數量多一,因為當前位置座標也記錄下來了 private ArrayList<PathPlanBean> uploadList = new ArrayList<>(); //上傳航跡規劃列表的集合 private ArrayList<Marker> mPfMarkerList = new ArrayList<>(); private ArrayList<Polyline> mPfPolylineList = new ArrayList<>(); /** * Marker地圖點選監聽事件 * * @param latLng */ @Override public void onMapClick(LatLng latLng) { LatLng curLatlng = latLng; // 航跡規劃 if (isOpenFlightRoutePlan && mPfMarkerList.size() < 50 && isWayPointMode_state == GduConfig.FpClose) { LatLng lastLatlng; if (!mPfLatLngList.isEmpty()) { // 這裡判斷不為空,是保證已經 有飛機的座標點 已經新增 if (AMapUtils.calculateLineDistance(currentphoneLatlng, curLatlng) > fp_validityRange) { txhToast.show(getString(R.string.Label_Map_FlightRoute_flightpoit_invalidation)); } else { int tagNum = mPfLatLngList.size();//Marker 數_標 mPfMarkerList.add(mapMarkerTool.addPfMarker(curLatlng, tagNum)); mPfLatLngList.add(curLatlng); mIv_Fp_state.setImageResource(R.drawable.bg_map_fp_go); if (tagNum == 1) { LatLng droneLat = mPfLatLngList.get(0); mPfPolylineList.add(mapMarkerTool.addPolyDottedLine(droneLat, curLatlng)); mPfFlightDisList.add(calculateFlightDist(droneLat, curLatlng)); } else if (tagNum > 1) { lastLatlng = mPfLatLngList.get(mPfLatLngList.size() - 2); mPfPolylineList.add(mapMarkerTool.addPolyDottedLine(lastLatlng, curLatlng)); mPfFlightDisList.add(calculateFlightDist(lastLatlng, curLatlng)); } setEraserState(true);//有Marker增加時候 } } } else if (isOpenFlightRoutePlan && mPfMarkerList.size() == 50 && isWayPointMode_state == GduConfig.FpClose) { txhToast.show(getString(R.string.Label_Map_FlightRoute_flightpoit_overflow)); } else if (isOpenFlightRoutePlan && mPfMarkerList.size() < 50 && isWayPointMode_state == GduConfig.FpGo) { // 即當開始航跡規劃,在點選地圖,無響應,不增加點 }
在地圖上增加點 必須在onMapClick 中操作,在onMapClick 獲取最基本的Latlng 資料,並繪製 航線。
add Marker
/**
* <p>根據經緯度往地圖上新增marker</p>
* <p>[航跡規劃]</p>
*
* @param lagLng 當前點選的 下的座標
* @param markerNum 計數
* @return
*/
public Marker addPfMarker(LatLng lagLng, int markerNum) {
MarkerOptions options= options = new MarkerOptions().draggable(true);
options.anchor(0.5f, 1f)
.position(lagLng)
.icon(BitmapDescriptorFactory.fromBitmap(getBitMap(markerNum)));
return aMap.addMarker(options);
}
add PolyLine
/**
* <p>繪製兩點之間線段</p>
* <p>虛線</p>
*
* @param beginlatLng 起點
* @param endLatLng 終點
* @return
*/
public Polyline addPolyDottedLine(LatLng beginlatLng, LatLng endLatLng) {
PolylineOptions options = new PolylineOptions();
options.add(beginlatLng, endLatLng)
.width(10)
.color(Color.rgb(255, 121, 24))
.setDottedLine(true);// 虛線
return aMap.addPolyline(options);
}
計算距離:
/**
* <p>計算總的飛行距離</p>
*
* @param beginlatLng
* @param endLatLng
*/
private float calculateFlightDist(LatLng beginlatLng, LatLng endLatLng) {
float onceDist = AMapUtils.calculateLineDistance(beginlatLng, endLatLng);
AllFlightDist += onceDist;
DecimalFormat df = new DecimalFormat("##.#");
mTv_flightdis.setText(df.format(AllFlightDist) + StringUtils.getUnit());
return Float.parseFloat(df.format(AllFlightDist));
}
這是基本的 新增資料 在地圖上顯示,下面就讓他來動起來吧。
設定監聽。
private void initGuideMap(AMap aMap) {
// 設定marker可拖拽事件監聽器
aMap.setOnMarkerDragListener(this);
// 設定顯示marker資訊監聽,要想顯示資訊必須註冊
// aMap.setInfoWindowAdapter(this);
aMap.setOnMarkerClickListener(this);
// aMap.setOnInfoWindowClickListener(this);
// 初始化Marker配置
options = new MarkerOptions().draggable(true);
}
監聽回撥:
/**
* <p>Marker 拖拽開始監聽</p>
* <li>增加振盪器</li>
* <li>獲取當前Marker 的起始座標並儲存</li>
* <li>作用:當不滿足條件的時候,就可以使用起點座標</li>
*
* @param marker
*/
private LatLng curMarkerPosition;
@Override
public void onMarkerDragStart(Marker marker) {
Vibrator vibrator = (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE);
vibrator.vibrate(150);
if (isPfMode == GduConfig.FpMode) {
for (int i = 0; i < mPfMarkerList.size(); i++) {
if (marker.equals(mPfMarkerList.get(i))) {
curMarkerPosition = mPfLatLngList.get(i + 1);
}
}
} else if (isPfMode == GduConfig.ErMode) {
for (int i = 0; i < mErMarkerList.size(); i++) {
if (marker.equals(mErMarkerList.get(i))) {
curMarkerPosition = mErLatLngList.get(i);
}
}
}
}
/**
* <p>拖拽過程中的監聽</p>
*
* @param marker
*/
@Override
public void onMarkerDrag(Marker marker) {
drawTrackLine(marker);// 正常的Marker監聽中
}
/**
* <p>拖拽完成後的監聽</p>
* <li>當狀態為:航跡規劃進行中/電子圍欄已啟動 ,拖動點回歸原點</li>
* <li>拖拽完成後檢查是否超過2000的判定</li>
*
* @param marker
*/
@Override
public void onMarkerDragEnd(Marker marker) {
// 模式開啟,飛機在執行 指令操作,所有的點都不能生效
if (isWayPointMode_state == GduConfig.FpGo || isWayPointMode_state == GduConfig.FpGoOn || isElectronicRail_state == GduConfig.ErStart) {
BackDraggablePoint(marker);// 當前是:航跡規劃狀態/電子圍欄狀態
return;
}
if (isPfMode == GduConfig.FpMode && AMapUtils.calculateLineDistance(mPfLatLngList.get(0), marker.getPosition()) > fp_validityRange) {
txhToast.show(context.getString(R.string.Label_Map_FlightRoute_flightpoit_invalidation));
BackDraggablePoint(marker);// 就是超過2000米 的判斷
}
}
繼續 上一個 程式碼中的方法
/**
* <p>畫航線</p>
* <li>第一:分航跡規劃模式和圍欄模式</li>
* <li>第二:圍欄模式分:圍欄模式已經啟動 -實線情況,圍欄模式未啟動 -虛線情況</li>
* <li>第三:圍欄模式拖拽:分幾個特殊點 ① 起點 ②中間點 ③ 終點 </li>
* <li>第四:圍欄模式拖拽:沒啟動圍欄模式前,是沒有最後一根線的,也就是說 5個點四根線 可拖拽的效果也是要分情況的 </li>
* <li>不僅在拖拽的時候要實況改變預設航線,</li>
* <li>還要在拖拽結束的時候判斷是否滿足航線規劃的要求</li>
* <li>滿足就按照使用者的定義的來,不滿足就要回到起始點</li>
*/
private void drawTrackLine(Marker marker) {
if (isPfMode == GduConfig.FpMode) { // 航跡規劃
boolean isExceed = AMapUtils.calculateLineDistance(mPfLatLngList.get(0), marker.getPosition()) > fp_validityRange;
outofrangeCircle(isExceed);
for (int i = 0; i < mPfMarkerList.size(); i++) {
if (marker.equals(mPfMarkerList.get(i))) {
mPfLatLngList.set(i + 1, marker.getPosition()); // 第一個點是無人機的點,所以要 +1 ;
mPfPolylineList.get(i).remove();
mPfPolylineList.set(i,
addPolyDottedLine(mPfLatLngList.get(i), //虛線
mPfLatLngList.get(i + 1)));
if (i < mPfMarkerList.size() - 1) {
mPfPolylineList.get(i + 1).remove();
mPfPolylineList.set(i + 1,
addPolyDottedLine(mPfLatLngList.get(i + 1),//虛線
mPfLatLngList.get(i + 2)));
}
updateFlightDisEvent(i, marker);//實況更新飛行距離的事件
return;
}
}
} else if (isPfMode == GduConfig.ErMode) { // 電子圍欄
for (int i = 0; i < mErMarkerList.size(); i++) {
if (marker.equals(mErMarkerList.get(i))) {
if (mErMarkerList.size() > 1) {
mErLatLngList.set(i, marker.getPosition());// 沒有無人機的點,所以就按照第0點來
// 一根線 (點的後面那根)
if (isElectronicRail_state == GduConfig.ErStart) { // 已經開啟電子圍欄模式
if (i == mErMarkerList.size() - 1) { // 【特殊點】移動的是最後一個點就是【起點】,手動新增的 Polyline
mErPolylineList.get(i).remove();
mErPolylineList.set(i,
addPolySolidLine(mErLatLngList.get(i),//實線
mErLatLngList.get(0)));
} else { // 移動的不是最後一個點
mErPolylineList.get(i).remove();
mErPolylineList.set(i,
addPolySolidLine(mErLatLngList.get(i),//實線
mErLatLngList.get(i + 1)));
}
} else { // 沒有開啟電子圍欄
if (i < mErPolylineList.size()) {
mErPolylineList.get(i).remove();
mErPolylineList.set(i,
addPolyDottedLine(mErLatLngList.get(i),//虛線
mErLatLngList.get(i + 1)));
}
}
// 二根線 (點的後前面那根)
if (isElectronicRail_state == GduConfig.ErStart) { // 已經開啟電子圍欄模式
if (i == 0) { //【特殊點】 移動終點
mErPolylineList.get(mErPolylineList.size() - 1).remove();
mErPolylineList.set(mErPolylineList.size() - 1,
addPolySolidLine(mErLatLngList.get(i), //實線
mErLatLngList.get(mErLatLngList.size() - 1)));
} else {
mErPolylineList.get(i - 1).remove();
mErPolylineList.set(i - 1,
addPolySolidLine(mErLatLngList.get(i),//實線
mErLatLngList.get(i - 1)));
}
} else {
if (i > 0) {
mErPolylineList.get(i - 1).remove();
mErPolylineList.set(i - 1,
addPolyDottedLine(mErLatLngList.get(i),//虛線
mErLatLngList.get(i - 1)));
}
}
return;
}
}
}
}
}
繼續上一個程式碼的方法
/**
* <p>回到拖拽的起點</p>
* <li>當不滿足要求的時候,就會回到起始點</li>
*
* @param marker
*/
private void BackDraggablePoint(Marker marker) {
marker.setPosition(curMarkerPosition);
drawTrackLine(marker);// 不滿足要求
}
然後就是 有效域的判定
我其實是事先做了2個 有效域 的圓形,根據 地圖的 距離計算,當大於2000 就隱藏第一個圓形 顯示下一個圓形,如果第二個沒有
就新建,如果存在就 顯示,
boolean isExceed = AMapUtils.calculateLineDistance(mPfLatLngList.get(0), marker.getPosition()) > 2000;
有效域
circle = aMap.addCircle(new CircleOptions()
.center(latLng)
.radius(fp_validityRange)
.fillColor(Color.argb(26, 0, 120, 255)) // 填充域顏色
.strokeColor(Color.argb(102, 0, 160, 233))// 邊框顏色
.strokeWidth(2));
警告域 /**
* <p>是否超出有效域,超出2000 有效域變色</p>
* <p>是超出範圍的圈/p>
*/
public void outofrangeCircle(boolean isExceed) {
if (warning_circle == null) {
warning_circle = aMap.addCircle(new CircleOptions()
.center(currentphoneLatlng)
.radius(fp_validityRange)
.fillColor(Color.argb(26, 255, 199, 65)) // 填充域顏色
.strokeColor(Color.argb(102, 255, 199, 65))// 邊框顏色
.strokeWidth(2));
}
if (isExceed) {
warning_circle.setVisible(true);
normal_circle.setVisible(false);
} else {
normal_circle.setVisible(true);
warning_circle.setVisible(false);
}
}
基本 的重點都講完了,下面是我完整的 java 檔案
GuideMapFragment.java
package com.gdu.mvp_view.flightRouteplan;
import android.app.Fragment;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.Circle;
import com.amap.api.maps.model.CircleOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.Polyline;
import com.gdu._enum.ConnStateEnum;
import com.gdu.beans.PathPlanBean;
import com.gdu.config.GduConfig;
import com.gdu.config.GlobalVariable;
import com.gdu.config.UavStaticVar;
import com.gdu.event.PfMostDisEvent;
import com.gdu.mvp_view.application.GduApplication;
import com.gdu.mvp_view.flightRouteplan.helper.GPSTranslateGuide;
import com.gdu.mvp_view.flightRouteplan.helper.UpDroneCurLocation;
import com.gdu.phonedrone.R;
import com.gdu.socket.GduFrame;
import com.gdu.socket.GduMapComm;
import com.gdu.socket.GduSocketConfig;
import com.gdu.socket.SocketCallBack;
import com.gdu.util.AnimationUtils;
import com.gdu.util.BBLog;
import com.gdu.util.DialogUtils;
import com.gdu.util.SPUtils;
import com.gdu.util.StringUtils;
import com.gdu.util.ToastFactory;
import com.gdu.util.YhLog;
import com.gdu.util.dialog.BlackGeneralDialog;
import com.gdu.util.dialog.GeneralDialog;
import com.gdu.views.AngelaTXHToast;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import de.greenrobot.event.EventBus;
/**
* Created by shangbeibei on 2017/4/20.
* <p>航跡規劃--高德地圖</p>
*/
public class GuideMapFragment extends Fragment implements
AMap.OnMapLoadedListener
, View.OnClickListener
, LocationSource // 回撥監聽
, AMapLocationListener //定外監聽
, AMap.OnMapClickListener {
// init GuideMapFragment mapview
private AMap aMap;
// init MapUtils
private GuideMapMarkerTool mapMarkerTool;
// init 定位樣式,定位藍點
private MyLocationStyle myLocationStyle;
//宣告AMapLocationClient類物件
public AMapLocationClient mLocationClient = null;
//宣告mLocationOption物件
public AMapLocationClientOption mLocationOption = null;
//重要的地圖工具,有 比例尺,有logo位置 有 縮放按鈕, 指南針。滑動手勢,縮放手勢
private UiSettings mUiSettings;
private OnLocationChangedListener mListener;//定位成功回撥
// 定位當前手機的位置
private LatLng currentphoneLatlng;
// 有效域 圓
private Circle circle;
// 無效域 圓
private Circle warning_circle;
// 航跡規劃 【有效域範圍】半徑
public static int fp_validityRange = 2000;
// init GuideMapFragment view
private static GuideMapFragment guideMapFragment;
private View view;
// 高德地圖
private TextureMapView mMapView;
// 地圖控制檯
private RelativeLayout mRl_MapControlPanel;
// 清除航線規劃
private ImageView mIv_fp_cleanroutePlan;
// 電子圍欄
private ImageView mIv_electronicRail_on2off;
// 航跡規劃的開關
private ImageView mIv_flightPlan_on2off;
// 隱藏控制檯 iocn
private ImageView mIv_hide_controlpanel;
// 顯示控制檯 icon
private ImageView mIv_show_controlpanel;
// 地圖定位回撥
private ImageView mIv_fp_maplocation;
// 航跡規劃的狀態
private ImageView mIv_Fp_state;
// 電子圍欄的狀態
private ImageView mIv_Er_state;
// 地圖樣式切換 button
private ImageView mIv_switch_mapstyle;
// 地圖切換 樣式 的layout 選項框
private LinearLayout mll_switch_maplayout;
// (熱區域)點選地圖樣式,普通地圖
private LinearLayout mll_click_mapstyle_normal;
// (熱區域)點選地圖樣式,衛星地圖
private LinearLayout mll_click_mapstyle_satellite;
// 點選後,普通地圖樣式被選擇的background 變化
private LinearLayout mll_bg_maptype_normal;
// 點選後,衛星地圖樣式被選擇的background 變化
private LinearLayout mll_bg_maptype_satellite;
// 點選後,普通地圖 Text 文字 顏色變化
private TextView mTv_mapstyle_normal;
//點選後,衛星地圖 Text 文字 顏色變化
private TextView mTv_mapstyle_satellite;
// 飛行距離 layout (顯示/隱藏)
private LinearLayout mll_flight_distance;
// 飛行距離 Values 的顯示
private TextView mTv_flightdis;
//init Tools
//更新無人機當前位置
private UpDroneCurLocation updronelocation;
//實時控制頁面下滑提示
private AngelaTXHToast txhToast;
// init list (航跡規劃)
private ArrayList<LatLng> mPfLatLngList = new ArrayList<>(); // latlng的數量比marker的數量多一,因為當前位置座標也記錄下來了
private ArrayList<PathPlanBean> uploadList = new ArrayList<>(); //上傳航跡規劃列表的集合
private ArrayList<Marker> mPfMarkerList = new ArrayList<>();
private ArrayList<Polyline> mPfPolylineList = new ArrayList<>();
private ArrayList<Float> mPfFlightDisList = new ArrayList<>();
private ArrayList<Polyline> mReceivePolylineList = new ArrayList<>();
// private ArrayList<TSMWayPoint> tswayPoints = new ArrayList<>();
// private ArrayList<TSMFlightFencePoint> fencePoints = new ArrayList<>();
// init list (電子圍欄)
private ArrayList<LatLng> mErLatLngList = new ArrayList<>();
private ArrayList<Marker> mErMarkerList = new ArrayList<>();
private ArrayList<Polyline> mErPolylineList = new ArrayList<>();
// init data
// 是否可以收到飛機的下發航點,表示飛機gps 沒有問題。
private boolean ishasReceiveLatlng;
// 是否開啟航跡規劃
private boolean isOpenFlightRoutePlan = false;
// 是否處於航跡規劃進行的狀態中(正在按照規劃飛行)
public static int isWayPointMode_state;
// 是否開啟電子圍欄
private boolean isOpenElectronicRail = false;
// 是否處於電子圍欄 狀態中(已經上傳點,開始飛行)
public static int isElectronicRail_state;
//飛行距離的總規劃長度
private double AllFlightDist;
private double preLat;
private double prelon;
private GduMapComm gduMapComm;
private final int UPLOAD_PATH_OK = 2;
private final int UPLOAD_PATH_FAILE = 3;
private final int ROUTE_PLANE_DOING = 4;
private final int ROUTE_PLANE_PAUSE = 5;
private final int ROUTE_PLANE_COMPLETE = 6;
private final int ROUTE_PLANE_FAILE = 7;
private final int START_ROUTE = 8;
private final int NO_ROUTE = 9;
private final int IN_WALL = 10;
private final int OUT_WALL = 11;
private final int CLEAR_WALL = 12;
private final int EXIT_WALL = 13;
private final int INVADITE_WALL = 14;
private boolean isRoutePlane;
private Timer timer;
private boolean timeUP;
private DialogUtils dialogUtils;
public static synchronized GuideMapFragment getInstance() {
if (guideMapFragment == null) {
guideMapFragment = new GuideMapFragment();
}
return guideMapFragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_guide_map_layout, null);
initFindView();
initAmap(savedInstanceState);
initAmapListener();
initTools();
initListener();
gduMapComm = new GduMapComm(GduApplication.getSingleApp().gduCommunication.getGduSocket());
return view;
}
/**
* @author yuhao
* <p/>
* 初始化飛機的位置
*/
private void initPlanePosotion() {
GlobalVariable.GPS_Lat = 40.043519f;
GlobalVariable.GPS_Lon = 116.291275f; //TODO測試無人機座標為定值
YhLog.LogE("GlobalVariable.latitude=" + GlobalVariable.GPS_Lat);
YhLog.LogE("GlobalVariable.longitude=" + GlobalVariable.GPS_Lon);
LatLng latLng1 = GPSTranslateGuide.transform2Mars(GlobalVariable.GPS_Lat, GlobalVariable.GPS_Lon); //大地座標轉火星座標
currentphoneLatlng = new LatLng(GlobalVariable.GPS_Lat, GlobalVariable.GPS_Lon);
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng1, 20));
updronelocation.refreshDroneLocation(latLng1);// 更新無人機 Marker 位置
// 儲存當前 手機定位 並增加到 mPfLatLngList
addDroneLocation();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_switch_map_icon://地圖樣式切換
//TODO測試需要把切換按鈕改成確認航跡起飛的按鈕
sureFly();
// showMapTypeWindow();
break;
case R.id.ll_mapstyle_normal_layout://normal 點選
switchMapStyle(view);
break;
case R.id.ll_mapstyle_satellite_layout://satellite 點選
switchMapStyle(view);
break;
case R.id.iv_flightplan_on2off://航跡規劃開啟/關閉
initFlightPlanEvent();
break;
case R.id.iv_electronic_rail://電子圍欄 開啟/關閉
initElectronicRail();
break;
case R.id.iv_flightplan_clean_route://清除航跡規劃
CleanflightplanRoute();
break;
case R.id.iv_mapview_location://定位
if (currentphoneLatlng != null) {
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentphoneLatlng, 16));//V2.0
} else {
txhToast.show(getString(R.string.Label_Map_FlightRoute_unrecive_plan));
}
break;
case R.id.iv_map_right_menu_hide://隱藏地圖控制檯
initControlPanelAnimation(false);
break;
case R.id.iv_map_right_menu_show://顯示地圖控制檯
initControlPanelAnimation(true);
break;
case R.id.iv_flightplan_state://航跡規劃狀態
initFpState_on2off();
break;
case R.id.iv_ElectronicRail_state://電子圍欄狀態
initErState_on2off();
break;
}
}
/**
* <p>開始,電子圍欄事件</p>
*/
private void initElectronicRail() {
// if (WifiConnConfig.IS_LINK_DRONE == WifiConnConfig.ConnType.Conn_Sucess && ishasReceiveLatlng) {// 測試關閉
if (true && currentphoneLatlng != null) {
if (!isOpenElectronicRail) {
isOpenElectronicRail = true;
//開啟電子圍欄
mapMarkerTool.isPfMode(GduConfig.ErMode);
mIv_Er_state.setVisibility(View.VISIBLE);
mIv_Er_state.setImageResource(R.drawable.icon_map_er_start_gray);
mIv_electronicRail_on2off.setImageResource(R.drawable.bg_map_electronic_on);
txhToast.show(getString(R.string.Label_Map_ElectronicRail_Event_on));
//航跡規劃需要禁掉
mIv_flightPlan_on2off.setImageResource(R.drawable.icon_path_planning_no);
mIv_flightPlan_on2off.setEnabled(false);
} else if (isOpenElectronicRail) {
isOpenElectronicRail = false;
mapMarkerTool.isPfMode(GduConfig.NoMode);
mapMarkerTool.cleanPolygonCover();// 清除圍欄Cover
mIv_Er_state.setVisibility(View.GONE);
mIv_electronicRail_on2off.setImageResource(R.drawable.bg_map_electronic_off);
txhToast.show(getString(R.string.Label_Map_ElectronicRail_Event_off));
//航跡規劃需要開啟
mIv_flightPlan_on2off.setImageResource(R.drawable.bg_map_fp_off);
mIv_flightPlan_on2off.setEnabled(true);
// 地圖可以再次新增Marker
isElectronicRail_state = GduConfig.ErClose;
ClearMap();//再次點選電子圍欄 -清除
}
} else if (currentphoneLatlng != null) {
if (GlobalVariable.connStateEnum == ConnStateEnum.Conn_None)
txhToast.show(getString(R.string.DeviceNoConn));
else if (GlobalVariable.connStateEnum == ConnStateEnum.Conn_MoreOne)
txhToast.show(getString(R.string.Label_ConnMore));
} else if (currentphoneLatlng == null) {
txhToast.show(getString(R.string.Label_Map_FlightRoute_unrecive_plan));
}
}
/**
* <p>連線最後一根線,擴展出來一個不規則矩形</p>
*/
private void connLastLine() {
//先清除 虛線 換成 實體線
for (int i = mErPolylineList.size() - 1; i > -1; i--) {
mErPolylineList.get(i).remove();
mErPolylineList.remove(i);
}
//在增加實體線
for (int i = 1; i <= mErLatLngList.size(); i++) {
if (i == mErLatLngList.size()) {
mErPolylineList.add(mapMarkerTool.addPolySolidLine(mErLatLngList.get(mErLatLngList.size() - 1), mErLatLngList.get(0)));
} else {
mErPolylineList.add(mapMarkerTool.addPolySolidLine(mErLatLngList.get(i - 1), mErLatLngList.get(i)));
}
}
}
/**
* <p>開始,航跡規劃事件</p>
*/
private void initFlightPlanEvent() {
// boolean isflyhint = SPUtils.getBoolean(getActivity(), SPUtils.ISFlyHint);
// if (WifiConnConfig.IS_LINK_DRONE == WifiConnConfig.ConnType.Conn_Sucess && ishasReceiveLatlng) {// 測試關閉
if (true && currentphoneLatlng != null) {
if (!isOpenFlightRoutePlan) {
// if (!isflyhint) openRoutePlanDialog();
isOpenFlightRoutePlan = true;
//開啟航跡規劃
mapMarkerTool.isPfMode(GduConfig.FpMode);
mIv_Fp_state.setVisibility(View.VISIBLE);
mIv_Fp_state.setImageResource(R.drawable.icon_map_fp_go_gray);
mIv_flightPlan_on2off.setImageResource(R.drawable.bg_map_fp_on);
txhToast.show(getString(R.string.Label_Map_FlightRoute_Event_on));
// 電子圍欄需要禁掉
mIv_electronicRail_on2off.setImageResource(R.drawable.icon_fence_no);
mIv_electronicRail_on2off.setEnabled(false);
// 開啟航跡規劃,繪製航跡規劃的範圍
initDrawCircle(true);
//向MapTool 傳遞引數
mapMarkerTool.setParameter(currentphoneLatlng, warning_circle, circle);
//開啟航跡規劃,顯示距離Layout
mll_flight_distance.setVisibility(View.VISIBLE);
} else if (isOpenFlightRoutePlan) {
isOpenFlightRoutePlan = false;
// 關閉航跡規劃
mapMarkerTool.isPfMode(GduConfig.NoMode);
mIv_Fp_state.setVisibility(View.GONE);
mIv_flightPlan_on2off.setImageResource(R.drawable.bg_map_fp_off);
txhToast.show(getString(R.string.Label_Map_FlightRoute_Event_off));
// 電子圍欄需要開啟
mIv_electronicRail_on2off.setImageResource(R.drawable.bg_map_electronic_off);
mIv_electronicRail_on2off.setEnabled(true);
// 隱藏航跡規劃 有效域
initDrawCircle(false);
//開啟航跡規劃,顯示距離Layout
mll_flight_distance.setVisibility(View.GONE);
// 地圖可以再次新增Marker
isWayPointMode_state = GduConfig.FpClose;
ClearMap(); //再次點選航跡規劃 -清除
gduMapComm.controlPathPlan((byte) 0x00, goOnRoute); //停止航跡規劃
gduMapComm.controlPathPlan((byte) 0x04, goOnRoute);
uploadList.clear();
}
} else if (currentphoneLatlng != null) {
if (GlobalVariable.connStateEnum == ConnStateEnum.Conn_None)
txhToast.show(getString(R.string.DeviceNoConn));
else if (GlobalVariable.connStateEnum == ConnStateEnum.Conn_MoreOne)
txhToast.show(getString(R.string.Label_ConnMore));
} else if (currentphoneLatlng == null) {
txhToast.show(getString(R.string.Label_Map_FlightRoute_unrecive_plan));
}
}
/**
* Marker地圖點選監聽事件
*
* @param latLng
*/
@Override
public void onMapClick(LatLng latLng) {
LatLng curLatlng = latLng;
// 航跡規劃
if (isOpenFlightRoutePlan && mPfMarkerList.size() < 50 && isWayPointMode_state == GduConfig.FpClose) {
LatLng lastLatlng;
if (!mPfLatLngList.isEmpty()) { // 這裡判斷不為空,是保證已經 有飛機的座標點 已經新增
if (AMapUtils.calculateLineDistance(currentphoneLatlng, curLatlng) > fp_validityRange) {
txhToast.show(getString(R.string.Label_Map_FlightRoute_flightpoit_invalidation));
} else {
int tagNum = mPfLatLngList.size();//Marker 數_標
mPfMarkerList.add(mapMarkerTool.addPfMarker(curLatlng, tagNum));
mPfLatLngList.add(curLatlng);
mIv_Fp_state.setImageResource(R.drawable.bg_map_fp_go);
if (tagNum == 1) {
LatLng droneLat = mPfLatLngList.get(0);
mPfPolylineList.add(mapMarkerTool.addPolyDottedLine(droneLat, curLatlng));
mPfFlightDisList.add(calculateFlightDist(droneLat, curLatlng));
} else if (tagNum > 1) {
lastLatlng = mPfLatLngList.get(mPfLatLngList.size() - 2);
mPfPolylineList.add(mapMarkerTool.addPolyDottedLine(lastLatlng, curLatlng));
mPfFlightDisList.add(calculateFlightDist(lastLatlng, curLatlng));
}
setEraserState(true);//有Marker增加時候
}
}
} else if (isOpenFlightRoutePlan && mPfMarkerList.size() == 50 && isWayPointMode_state == GduConfig.FpClose) {
txhToast.show(getString(R.string.Label_Map_FlightRoute_flightpoit_overflow));
} else if (isOpenFlightRoutePlan && mPfMarkerList.size() < 50 && isWayPointMode_state == GduConfig.FpGo) {
// 即當開始航跡規劃,在點選地圖,無響應,不增加點
}
// 電子圍欄
if (isOpenElectronicRail && mErMarkerList.size() < 6 && isElectronicRail_state == GduConfig.ErClose) {
LatLng lastLatlng;
mErMarkerList.add(mapMarkerTool.addErMarker(curLatlng));
mErLatLngList.add(curLatlng);
int tagNum = mErLatLngList.size();//Marker 數_標
if (tagNum > 2) {
mIv_Er_state.setImageResource(R.drawable.bg_map_er_start);
}
if (tagNum > 1) {
lastLatlng = mErLatLngList.get(mErLatLngList.size() - 2);
BBLog.LogE("Point_畫線", "-------[" + tagNum + "]點");
mErPolylineList.add(mapMarkerTool.addPolyDottedLine(lastLatlng, curLatlng));
}
setEraserState(true);//有Marker增加時候
} else if (isOpenElectronicRail && mErMarkerList.size() == 6 && isElectronicRail_state == GduConfig.ErClose) {
txhToast.show(getString(R.string.Label_Map_FlightRoute_flightpoit_overflow));
} else if (isOpenElectronicRail && mErMarkerList.size() < 6 && isElectronicRail_state == GduConfig.ErStart) {
// 即當開始電子圍欄,在點選地圖,無響應,不增加點
}
}
/**
* <p>電子圍欄狀態—開/關</p>
*/
private void initErState_on2off() {
if (isElectronicRail_state == GduConfig.ErClose) {
boolean isContainsPoint = mapMarkerTool.isPolygonContainsPoint(mErLatLngList, mPfLatLngList.get(0));
if (mErMarkerList.size() > 2 && isContainsPoint) {
connLastLine();
setEraserState(false);
upElectronicFencePoint();
isElectronicRail_state = GduConfig.ErStart;
mIv_Er_state.setImageResource(R.drawable.bg_map_er_cancel);
mapMarkerTool.drawpolygonCover();
} else if (!isContainsPoint) {
txhToast.show(getString(R.string.Label_Map_FlightRoute_electronicRail_invalidation));
}
} else if (isElectronicRail_state == GduConfig.ErStart) {
initElectronicRail();
}
}
/**
* <p>航跡規劃狀態—開/關</p>
*/
private void initFpState_on2off() {
if (isWayPointMode_state == GduConfig.FpClose) {
if (mPfMarkerList.size() != 0) {
setFlightHei();
}
} else if (isWayPointMode_state == GduConfig.FpGo) {
mIv_Fp_state.setImageResource(R.drawable.bg_map_fp_go_on);
isWayPointMode_state = GduConfig.FpGoOn;
gduMapComm.controlPathPlan((byte) 0x02, goOnRoute);
} else if (isWayPointMode_state == GduConfig.FpGoOn) {
mIv_Fp_state.setImageResource(R.drawable.bg_map_fp_pause);
isWayPointMode_state = GduConfig.FpGo;
gduMapComm.controlPathPlan((byte) 0x03, goOnRoute);
}
}
/**
* <p>獲取 </p>
* <p>上傳飛行航跡點 </p>
*/
private void upFlightPathPoint() {
//TODO
for (int i = 1; i < mPfLatLngList.size(); i++) {
PathPlanBean pathPlanBean = new PathPlanBean();
LatLng latLng = GPSTranslateGuide.gcj2wgs(mPfLatLngList.get(i).longitude, mPfLatLngList.get(i).latitude);//火星座標轉大地座標
pathPlanBean.longitude = (int) (latLng.longitude * 10000000);
pathPlanBean.latitude = (int) (latLng.latitude * 10000000);
uploadList.add(pathPlanBean);
}
isRoutePlane = true;
GduApplication.getSingleApp().gduCommunication.addCycleACKCB(GduSocketConfig.CycleACK_pathPlan, sateRoutePlane);
// if (GlobalVariableTest.updatePlanPoints==0||GlobalVariableTest.updatePlanPoints==99){ //航點數量為0或99才能上傳航點
//TODO 必須GPS有星時才能上傳航跡
// if (GlobalVariable.satellite_drone>0&&GlobalVariable.satellite_drone!=98){ //必須GPS有星時才能上傳航跡
//
// }
uploadPath();
// }else{
// gduMapComm.controlPathPlan((byte) 0x04, new SocketCallBack() { //否則先清除航點再上傳
// @Override
// public void callBack(byte code, GduFrame bean) {
// if (code==0){
// uploadPath();
// }
// }
// });
// }
// uploadList.clear();
}
/**
* @author yuhao
* 上傳航跡規劃
*/
private void uploadPath() {
gduMapComm.updatePlanPath(uploadList, new SocketCallBack() { //上傳航跡規劃
@Override
public void callBack(byte code, GduFrame bean) {
if (code == 0) {
YhLog.LogE("航跡上傳成功");
handler.sendEmptyMessage(UPLOAD_PATH_OK);
// handler.postDelayed(new Runnable() { //上傳後等待3.5s判斷飛機收到的航點是否與傳送的一致
// @Override
// public void run() {
// if (GlobalVariableTest.updatePlanPoints == mPfLatLngList.size()) {
// handler.sendEmptyMessage(UPLOAD_PATH_OK);
// } else {
// handler.sendEmptyMessage(UPLOAD_PATH_FAILE);
// }
// }
// }, 3500);
} else {
YhLog.LogE("航跡上傳失敗");
handler.sendEmptyMessage(UPLOAD_PATH_FAILE);
}
}
});
}
int index = 0;
private boolean isShowPlane;
private TimerTask markPointRunner = new TimerTask() {
@Override
public void run() {
// if (isShowPlane){
YhLog.LogE("GlobalVariable.GPS_Lat=" + GlobalVariable.GPS_Lat + " " + "GlobalVariable.GPS_Lon" + GlobalVariable.GPS_Lon);
if (GlobalVariable.GPS_Lat < 90 && GlobalVariable.GPS_Lon < 180) {
LatLng latLng = new LatLng(GlobalVariable.GPS_Lat, GlobalVariable.GPS_Lon);
handler.obtainMessage(0, latLng).sendToTarget();
// }
}
}
};
/**
* <p>獲取 </p>
* <p>上傳電子圍欄 </p>
*/
private void upElectronicFencePoint() {
//TODO
for (int i = 0; i < mErLatLngList.size(); i++) {
PathPlanBean pathPlanBean = new PathPlanBean();
LatLng latLng = GPSTranslateGuide.gcj2wgs(mErLatLngList.get(i).longitude, mErLatLngList.get(i).latitude);//火星座標轉大地座標
pathPlanBean.longitude = (int) (latLng.longitude * 10000000);
pathPlanBean.latitude = (int) (latLng.latitude * 10000000);
// pathPlanBean.longitude = (int) (mErLatLngList.get(i).longitude * 10000000);
// pathPlanBean.latitude = (int) (mErLatLngList.get(i).latitude * 10000000);
// pathPlanBean.longitude = (int) (latLng.longitude * 10000000);
// pathPlanBean.latitude = (int) (latLng.latitude * 10000000);
// YhLog.LogE("pathPlanBean.longitude="+pathPlanBean.longitude);
// YhLog.LogE("pathPlanBean.latitude="+pathPlanBean.latitude);
uploadList.add(pathPlanBean);
}
// PathPlanBean pathPlanBean = new PathPlanBean();
// pathPlanBean.longitude = 1162969390;
// pathPlanBean.latitude = 400431079;
// uploadList.add(pathPlanBean);
//
// PathPlanBean pathPlanBean1 = new PathPlanBean();
// pathPlanBean1.longitude = 1162987400;
// pathPlanBean1.latitude = 400437560;
// uploadList.add(pathPlanBean1);
//
// PathPlanBean pathPlanBean2 = new PathPlanBean();
// pathPlanBean2.longitude = 1162969610;
// pathPlanBean2.latitude = 400442200;
// uploadList.add(pathPlanBean2);
isRoutePlane = false;
// GduApplication.getSingleApp().gduCommunication.addCycleACKCB(GduSocketConfig.CycleAck_wall,stateWall); //監聽圍欄狀態
// gduMapComm.clearWallPoint(new SocketCallBack() {
// @Override
// public void callBack(byte code, GduFrame bean) {
// if (code==0){
gduMapComm.updateWallPoints(uploadList, new SocketCallBack() { //清理電子圍藍成功後再上傳電子圍欄
@Override
public void callBack(byte code, GduFrame bean) {
YhLog.LogE("code==" + code);
if (code == 0) {
handler.sendEmptyMessage(UPLOAD_PATH_OK); //上傳電子圍欄成功 餘浩
// uploadList.clear();
} else {
handler.sendEmptyMessage(UPLOAD_PATH_FAILE);
}
}
});
// }
// }
// });
// uploadList.clear();
}
/**
* <p>上傳航點前的飛行高度</p>
* <p>設定飛行高度</p>
*/
private void setFlightHei() {
final BlackGeneralDialog dialog = new BlackGeneralDialog(getActivity(), R.style.NormalDialog) {
@Override
public void positiveOnClick() {
isWayPointMode_state = GduConfig.FpGo;
setLastMarkerIcon();
setEraserState(false);
upFlightPathPoint();
mIv_Fp_state.setImageResource(R.drawable.bg_map_fp_pause);
mll_flight_distance.setVisibility(View.GONE);
}
@Override
public void negativeOnClick() {
}
};
dialog.setTitleText(R.string.Label_Map_FlightRoute_setting_flightheight);
dialog.setContentText(R.string.Label_Map_FlightRoute_plan_keepCurrentHeight_fly);
dialog.setShowSeekBar(true);
dialog.show();
}
/**
* <p>繪製航跡規劃有效區域</p>
* currentphoneLatlng (當前手機定位點)作為有效域的 中心
* PS: 換算方法 argb
* int alpha = (color & 0xff000000) >>> 24;
* int red = (color & 0x00ff0000) >> 16;
* int green = (color & 0x0000ff00) >> 8;
* int blue = (color & 0x000000ff);
*
* @param isopen(開啟,關閉)
*/
private void initDrawCircle(boolean isopen) {
if (isopen) {
LatLng latLng = GPSTranslateGuide.transform2Mars(currentphoneLatlng.latitude, currentphoneLatlng.longitude); //大地座標轉火星座標
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18));
if (circle != null) {
circle.setVisible(true);
} else {
circle = aMap.addCircle(new CircleOptions()
.center(latLng)
.radius(fp_validityRange)
.fillColor(Color.argb(26, 0, 120, 255)) // 填充域顏色
.strokeColor(Color.argb(102, 0, 160, 233))// 邊框顏色
.strokeWidth(2));
}
} else {
circle.setVisible(false);
}
}
/**
* <p>初始化(隱藏/顯示) 控制檯動畫</p>
*/
private void initControlPanelAnimation(boolean isShow) {
AnimationUtils.mapRightDisappearAnima(isShow, mRl_MapControlPanel, mIv_hide_controlpanel, mIv_show_controlpanel);
}
/**
* <p>清除航跡規劃航點和航線</p>
* <p>或者清除預設電子圍欄</p>
*/
private void CleanflightplanRoute() {
if (isWayPointMode_state == GduConfig.FpClose) {
GeneralDialog dialog = new GeneralDialog(getActivity(), R.style.NormalDialog) {
@Override
public void positiveOnClick() {
ClearMap();// 清楚航跡規劃
}
@Override
public void negativeOnClick() {
}
};
dialog.setOnlycontent();
dialog.setContentText(isOpenFlightRoutePlan ? R.string.Label_Map_FlightRoute_delete_wayPlan : R.string.Label_Map_FlightRoute_delete_electronicRail);
dialog.show();
} else if (isWayPointMode_state == GduConfig.FpGo || isWayPointMode_state == GduConfig.FpGoOn) {
txhToast.show(getString(R.string.Label_Map_FlightRoute_noClean_WayPoint));
}
}
/**
* <p>清除地圖Marker 點</p>
*/
private void ClearMap() {
// 清除航跡規劃 LatLng 和 Marker 和 PolyLine
if (mPfFlightDisList != null && !mPfLatLngList.isEmpty() && mPfLatLngList.size() != 1) {
for (int i = mPfMarkerList.size() - 1; i > -1; i--) {
mPfMarkerList.get(i).remove();
mPfMarkerList.remove(i);
}
for (int i = mPfLatLngList.size() - 1; i > 0; i--) {
mPfLatLngList.remove(i);
}
for (int i = mPfPolylineList.size() - 1; i > -1; i--) {
mPfPolylineList.get(i).remove();
mPfPolylineList.remove(i);
}
if (UavStaticVar.isDisplayFlightTrack && mReceivePolylineList != null) {
for (int i = mReceivePolylineList.size() - 1; i > -1; i--) {
mReceivePolylineList.get(i).remove();
mReceivePolylineList.remove(i);
}
}
mIv_Fp_state.setImageResource(R.drawable.icon_map_fp_go_gray);
// 飛行距離
AllFlightDist = 0;
if (mPfFlightDisList != null)
mPfFlightDisList = null;
mTv_flightdis.setText(0 + StringUtils.getUnit());
}
// 清除電子圍欄 LatLng 和 Marker 和 PolyLine
if (!mErLatLngList.isEmpty() && mErLatLngList.size() != 1) {
for (int i = mErLatLngList.size() - 1; i > -1; i--) {
mErLatLngList.remove(i);
}
for (int i = mErMarkerList.size() - 1; i > -1; i--) {
mErMarkerList.get(i).remove();
mErMarkerList.remove(i);
}
for (int i = mErPolylineList.size() - 1; i > -1; i--) {
mErPolylineList.get(i).remove();
mErPolylineList.remove(i);
}
mIv_Er_state.setImageResource(R.drawable.icon_map_er_start_gray);
gduMapComm.clearWallPoint(new SocketCallBack() {
@Override
public void callBack(byte code, GduFrame bean) {
if (code == 0) {
YhLog.LogE("清除電子圍欄==" + bean.frame_content[0]);
}
}
});
uploadList.clear();
}
setEraserState(false);// 清除航跡後
}
/**
* <p>設定當前的飛機 狀態</p>
* <p>設定橡皮擦狀態</p>
*
* @param isopen
*/
private void setEraserState(boolean isopen) {
mIv_fp_cleanroutePlan.setEnabled(isopen ? true : false);
mIv_fp_cleanroutePlan.setImageResource(isopen ? R.drawable.bg_map_fp_clean : R.drawable.icon_cleanmap_no);
}
/**
* <p>設定最後一個Marker 的Icon 圖</p>
* <p>將帶數字的Icon 替換 終點標誌</p>
*/
private void setLastMarkerIcon() {
mPfMarkerList.get(mPfMarkerList.size() - 1).remove();
// mPfMarkerList.add(mapMarkerTool.updateFlagMarker(mPfLatLngList.get(mPfLatLngList.size() - 1)));
mPfMarkerList.add(mapMarkerTool.addEndMarker(mPfLatLngList.get(mPfLatLngList.size() - 1)));
}
/**
* <p>開啟航跡規劃後的一個提示資訊</p>
*/
private void openRoutePlanDialog() {
}
/**
* <p>切換地圖樣式</p>
*
* @param view
*/
private void switchMapStyle(View view) {
if (view.getId() == R.id.ll_mapstyle_normal_layout) {
aMap.setMapType(AMap.MAP_TYPE_NORMAL);
SPUtils.put(getActivity(), SPUtils.MAPTYPE, 1);
mMapView.invalidate();
} else {
aMap.setMapType(AMap.MAP_TYPE_SATELLITE);
SPUtils.put(getActivity(), SPUtils.MAPTYPE, 2);
mMapView.invalidate();
}
mll_switch_maplayout.setVisibility(View.GONE);
}
/**
* <p>顯示地圖型別的Layout</p>
*/
private void showMapTypeWindow() {
if (mll_switch_maplayout.getVisibility() == View.GONE) {
mll_switch_maplayout.setVisibility(View.VISIBLE);
} else {
mll_switch_maplayout.setVisibility(View.GONE);
}
//預設地圖背景
if (AMap.MAP_TYPE_NORMAL == aMap.getMapType()) {
mll_bg_maptype_normal.setBackgroundResource(R.color.pf_color_ffa030);
mll_bg_maptype_satellite.setBackgroundResource(R.color.Transparent);
mTv_mapstyle_normal.setTextColor(getResources().getColor(R.color.pf_color_ffa030));
mTv_mapstyle_satellite.setTextColor(getResources().getColor(R.color.pf_color_ffffff));
} else {
mll_bg_maptype_normal.setBackgroundResource(R.color.Transparent);
mll_bg_maptype_satellite.setBackgroundResource(R.color.pf_color_ffa030);
mTv_mapstyle_normal.setTextColor(getResources().getColor(R.color.pf_color_ffffff));
mTv_mapstyle_satellite.setTextColor(getResources().getColor(R.color.pf_color_ffa030));
}
}
/**
* <p>計算總的飛行距離</p>
*
* @param beginlatLng
* @param endLatLng
*/
private float calculateFlightDist(LatLng beginlatLng, LatLng endLatLng) {
float onceDist = AMapUtils.calculateLineDistance(beginlatLng, endLatLng);
AllFlightDist += onceDist;
DecimalFormat df = new DecimalFormat("##.#");
mTv_flightdis.setText(df.format(AllFlightDist) + StringUtils.getUnit());
return Float.parseFloat(df.format(AllFlightDist));
}
// 載入地圖必要資料
private void initAmap(Bundle savedInstanceState) {
mMapView.onCreate(savedInstanceState);
if (aMap == null) aMap = mMapView.getMap();
myLocationStyle = new MyLocationStyle();// 初始化定位藍點樣式類
initMyLocationStyle();
initUiSettings();
aMap.setMapType(AMap.MAP_TYPE_NORMAL);
}
/**
* <p>初始化定位藍點樣式類</p>
*/
private void initMyLocationStyle() {
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);// 定位一次,且將視角移動到地圖中心點
// myLocationStyle.interval(2000);//設定連續定位模式下的定位間隔,只在連續定位模式下生效,單次定位模式下不會生效。單位為毫秒。
myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.bluepoint));// 設定小藍點的圖示
myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0)); //設定定位藍點精度圓圈的邊框顏色的方法。
myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));//設定定位藍點精度圓圈的填充顏色的方法。
myLocationStyle.strokeWidth(0); //設定定位藍點精度圈的邊框寬度的方法。
aMap.setMyLocationStyle(myLocationStyle);
}
private void initUiSettings() {
mUiSettings = aMap.getUiSettings(); // 地圖工具
mUiSettings.setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_LEFT);// logo 位置
mUiSettings.setScaleControlsEnabled(true);// 預設比例尺
mUiSettings.setZoomControlsEnabled(false);// 預設縮放按鈕
mUiSettings.setCompassEnabled(false);// 預設指南針
mUiSettings.setScrollGesturesEnabled(true);// 預設滑動手勢
mUiSettings.setZoomGesturesEnabled(true);// 預設縮放手勢
mUiSettings.setMyLocationButtonEnabled(false);// 設定預設定位按鈕是否顯示
}
/**
* 地圖的監聽事件 集合 都採用匿名內部類
*/
private void initAmapListener() {
aMap.setOnMapLoadedListener(this);// 地圖載入監聽
aMap.setLocationSource(this);// 設定定位監聽 // 先設定定位監聽 ,在設定其他屬性, 衛星,模式
aMap.setOnMapClickListener(this); // 設定點選地圖事件監聽
aMap.setMyLocationEnabled(true); // 設定為true表示啟動顯示定位藍點,false表示隱藏定位藍點並不進行定位,預設是false。
aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
// 初始化載入地圖型別
int i = SPUtils.getInt(getActivity(), SPUtils.MAPTYPE);
if (!UavStaticVar.SetMapStyle && i == 0) {
aMap.setMapType(AMap.MAP_TYPE_NORMAL); // 設定預設地圖為衛星
UavStaticVar.SetMapStyle = false;
} else {
if (i == 1) {
aMap.setMapType(AMap.MAP_TYPE_NORMAL); // 設定預設地圖為普通地圖
} else if (i == 2) {
aMap.setMapType(AMap.MAP_TYPE_SATELLITE); // 設定預設地圖為衛星
}
}
}
public void initListener() {
mIv_switch_mapstyle.setOnClickListener(this);
mIv_fp_maplocation.setOnClickListener(this);
mIv_switch_mapstyle.setOnClickListener(this);
mll_click_mapstyle_normal.setOnClickListener(this);
mll_click_mapstyle_satellite.setOnClickListener(this);
mIv_hide_controlpanel.setOnClickListener(this);
mIv_show_controlpanel.setOnClickListener(this);
mIv_fp_cleanroutePlan.setOnClickListener(this);
mIv_electronicRail_on2off.setOnClickListener(this);
mIv_flightPlan_on2off.setOnClickListener(this);
mIv_fp_maplocation.setOnClickListener(this);
mIv_Fp_state.setOnClickListener(this);
mIv_Er_state.setOnClickListener(this);
}
/**
* <p>初始化非地圖API 的工具類</p>
*/
private void initTools() {
// 控制欄提示Toast
txhToast = AngelaTXHToast.getInstance(getActivity());
mapMarkerTool = new GuideMapMarkerTool(getActivity(), txhToast, aMap, mPfMarkerList, mPfLatLngList, mPfPolylineList, mPfFlightDisList, mTv_flightdis, mErMarkerList, mErLatLngList, mErPolylineList);
updronelocation = new UpDroneCurLocation(handler, aMap, mMapView, mapMarkerTool, mReceivePolylineList);
// 初始化 ,航跡清除功能 為不可點選
setEraserState(false);//初始化
// 初始化 ,無人機Marker 位置
if (GlobalVariable.GPS_Lat != -1 && GlobalVariable.GPS_Lon != -1) {
LatLng gpslatLng = GPSTranslateGuide.AmapTransform(GlobalVariable.GPS_Lat, GlobalVariable.GPS_Lon);
mapMarkerTool.addPlaneMarker(gpslatLng, null);//初始化
// mapMarkerTool.addPlaneMarker(new LatLng(GlobalVariable.latitude,GlobalVariable.longitude), null);//初始化
}
}
public void initFindView() {
//init map
mMapView = ((TextureMapView) view.findViewById(R.id.Ttmv_guide_mapview));
// init layout
mRl_MapControlPanel = ((RelativeLayout) view.findViewById(R.id.rl_map_Control_panel));
// init ControlPanel view
mIv_hide_controlpanel = ((ImageView) view.findViewById(R.id.iv_map_right_menu_hide));
mIv_show_controlpanel = ((ImageView) view.findViewById(R.id.iv_map_right_menu_show));
mIv_fp_cleanroutePlan = ((ImageView) view.findViewById(R.id.iv_flightplan_clean_route));
mIv_electronicRail_on2off = ((ImageView) view.findViewById(R.id.iv_electronic_rail));
mIv_flightPlan_on2off = ((ImageView) view.findViewById(R.id.iv_flightplan_on2off));
mIv_fp_maplocation = ((ImageView) view.findViewById(R.id.iv_mapview_location));
mIv_Fp_state = ((ImageView) view.findViewById(R.id.iv_flightplan_state));
mIv_Er_state = ((ImageView) view.findViewById(R.id.iv_ElectronicRail_state));
// init switch mapstyle
mIv_switch_mapstyle = ((ImageView) view.findViewById(R.id.iv_switch_map_icon));
mll_switch_maplayout = ((LinearLayout) view.findViewById(R.id.ll_switch_map_layout));
mll_click_mapstyle_normal = ((LinearLayout) view.findViewById(R.id.ll_mapstyle_normal_layout));
mll_click_mapstyle_satellite = ((LinearLayout) view.findViewById(R.id.ll_mapstyle_satellite_layout));
mll_bg_maptype_normal = ((LinearLayout) view.findViewById(R.id.ll_mapstyle_normal));
mll_bg_maptype_satellite = ((LinearLayout) view.findViewById(R.id.ll_mapstyle_satellite));
mTv_mapstyle_normal = ((TextView) view.findViewById(R.id.tv_mapstyle_normal_text));
mTv_mapstyle_satellite = ((TextView) view.findViewById(R.id.tv_mapstyle_satellite_text));
//init flight distance
mll_flight_distance = ((LinearLayout) view.findViewById(R.id.ll_map_flight_dis));
mTv_flightdis = ((TextView) view.findViewById(R.id.tv_map_flight_distance));
dialogUtils = new DialogUtils(getActivity());
showFlyPosition();
}
/**
* @author 餘浩
* 實時重新整理飛機的位置
*/
private void showFlyPosition() {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// YhLog.LogE("GlobalVariable.GPS_Lat=" + GlobalVariable.GPS_Lat + " " + "GlobalVariable.GPS_Lon" + GlobalVariable.GPS_Lon);
if (GlobalVariable.GPS_Lat < 90 && Glob