|
zfeqiloimkq64023080053.gif
) j' R6 U4 `7 ~. S7 \ j点击上方蓝色字体,关注我们% s0 W1 n4 J: L& X
- U- f1 F7 W' F* G$ h
, L/ [# T) ]6 H; V0 H }第三篇文章准备单独拿出来写,因为在大疆为人机的所有功能中,航线规划的功能最为复杂,也相当的繁琐,这里需要说仔细一点,可能会将代码进行多步分解。$ N/ Y4 T" g" q0 T9 j0 P
1$ H5 C# l3 P9 Y) |7 G/ v! ~
航线规划
( ~/ s4 G' g J7 G6 A7 [航线打点
7 t4 @" k6 g$ n4 t5 u9 I3 v/ k8 [5 @3 @& c
在地图中手动选择点位选择完成航线打点;若打点位置错了可进行点位删除。/ D9 x4 @( {( K# F) D& ~
f4yxtknukf364023080153.png
/ p' g; }: D8 ~
( z; @2 d" I8 b1 y1 Q航点设置 8 d ]& q7 j5 r5 @! O$ y
3 n/ W) n( I; Z. V ?可对航线点位进行设置,如飞行高度,速度(慢速:3m/s;中速: 7m/s;高速:10 m/s)、任务结束后操作及航向,点击[设置]按钮完成设置。' ~9 c* I9 f6 }; D8 n8 z' F( v) K
f5aqrpgtkfy64023080253.png
- w2 [% z5 f" W% s
设置完成后会显示总距离及飞行总时间。% K# l/ M7 }1 r3 C6 `
qi5ptv2qcta64023080353.png
- r3 f6 T6 ^ R: S( |/ q
1 d: k. Y/ y- F
航线上传# W; ?5 N, s$ ?; {* u
+ T0 w+ t5 A; o* G" m2 A点击[上传]按钮,进行航线上传。可以进入本地存储中选择航线文件进行上传,航线文件为 .kml结尾。* ^; n5 @. P: O+ O; {9 q
ti2wlwnhxu164023080453.png
/ F4 u$ U2 ?& y4 w: _; y3 P8 f7 M2 s" F
航线执行
8 E+ W8 s8 Z2 A# V z% m# Q! C/ u/ p) h9 T( |2 z7 h
点击 [开始]按钮,则可对航线进行执行。若中途需要暂停也可点击[暂停]安装进行暂停操作。
w1 }5 V6 \9 X* @( G5 a
vjgcenr4gaz64023080554.png
% m; [, h% E; Q3 E6 h1 u& q. k9 Z: R
5 V% c* E+ ?: B7 p- Z$ z+ l" a航线管理7 T! L7 X' I- E2 g0 X( o
- O4 X2 Y5 ~* ^" _& K y' S按钮即可进入航线管理界面。
3 m" [& C8 C. x2 w N1 z5 `* X/ q3 p9 G+ ^6 e
xa44estxv5y64023080654.png
7 ]& y* J k# W) ^6 b$ c
) b( A+ W" Z" k( @- K. F: O获取航线 . u& b S* [; Z# q3 N4 j5 U8 S
0 N& b$ a) H" l# D点击[获取]按钮,即可将航线信息展示到地图界面中。, h% l7 i/ [4 a( |* f5 C
0 |6 I% A8 m4 w
0 v! x& |* |+ I8 ]$ `- m7 Q3 J
21 r2 q; D/ c/ D% x6 c( x
主要功能代码8 Z) o: w2 C; ^. O
创建activity_setting_route.xml及SettingRouteActivity文件。
8 F `1 }6 H2 B: @; {! ]% o- x$ K; Y5 Z5 q& o6 u( w4 q8 P g
2 ?8 b0 w6 l! u" P% w
activity_setting_route.xml6 \ C1 ]9 Z; e$ M! u
2 W( w G, Z3 { g" Y! KLinearlayout xmlns:android="http://schemas.android.com/apk/res/android", l( Q% |$ o1 }. ?9 D! P6 P4 O. l
xmlns:app="http://schemas.android.com/apk/res-auto"
! v: Z7 G# \# P# D: V% @ xmlns:tools="http://schemas.android.com/tools"
3 }+ p2 K& h7 |6 J* L6 c' E android:layout_width="match_parent"
* v9 H) B3 r; A! m k; j+ O* h j android:layout_height="match_parent"
6 b* t, S/ q' D' o: S( p" \ android:orientation="vertical"- H$ i7 T7 n1 f D" D: O
tools:context=".ui.SettingRouteActivity">
' W# G& z; K2 G2 k; J" m8 m( `+ p include
% U+ y7 k+ y: ^4 H android:id="@+id/layout_route"! Z/ w; e9 n8 M1 I9 F
layout="@layout/activity_toolbar">include>1 T9 B" C+ @% y) _7 L
RelativeLayout
' I) M9 @$ l9 i! ^- ]+ n) q android:layout_width="match_parent"
( r8 u: c+ h; I1 f1 e android:layout_height="match_parent">
* v. x0 q% E( m* `" `9 p0 L U com.amap.api.maps.MapView
# I( I5 L/ f3 u android:id="@+id/map"7 l( K- y0 e' C- R- w0 y
android:layout_width="match_parent". F( {* [. h; H, s) L( R5 v
android:layout_height="match_parent" />
! g9 u3 Z4 s/ `2 [ c* O LinearLayout5 Y. I2 P E- @, i6 D1 t1 W
android:layout_width="wrap_content"& K5 `- C3 L, v
android:layout_height="wrap_content"
& `2 A& m$ a& {/ O( O android:layout_alignParentTop="true"( [( ?# @& d# v9 l( D
android:layout_centerInParent="true"
. ^- `/ g5 }* q) b0 V& e, l! A4 X7 m android:layout_marginTop="5dp">$ q7 u" ]5 b* ?' T, {
Button
+ S2 R* w# l" j# M y2 \, P android:id="@+id/btn_delete"
' k1 a8 b; V: [! q" N0 l android:layout_width="60dp"3 V2 ~- G- x5 q+ }+ f7 r! L
android:layout_height="30dp", t1 M* X3 R2 W
android:visibility="gone"
. ]8 F' Z# N: s3 G% _" P: ~ android:text="删除"
7 W) n9 {8 ?2 g5 @' e7 d android:textColor="@color/white" _& v' g, j8 W
android:background="@drawable/button_task_background">Button>2 F9 D* G' i. ^, J: j! G% @
Button% ?+ {% _7 { W7 S
android:id="@+id/btn_finish"
3 D9 J5 K0 I) l! S$ e) }( V6 @ android:layout_width="60dp"9 D) s8 t) Y# |" v4 U
android:layout_height="30dp"
^5 ?% F# ]/ p5 f- \0 n android:visibility="gone"* P4 f7 w* N8 Q: M8 J, e
android:textColor="@color/white"8 u9 N* m7 \# h1 y3 i
android:background="@drawable/button_task_background"
4 W! f' ^# E: [. I& r android:text="完成">Button>
. u( i7 T! U5 g9 q Button: Z; m0 S6 R( P* ^' y% b. Y" y
android:id="@+id/btn_setting"
X0 M& Q) @0 O android:layout_width="60dp"
9 [- \' U9 R5 r& r, s* s1 d android:layout_height="30dp"
3 J: V* c1 I. a android:visibility="gone"/ O/ I& g, z2 a1 _6 E8 u5 y
android:textColor="@color/white"( a- ?; Y% e m' B
android:background="@drawable/button_task_background"4 q' [0 ~! H3 H4 N( i
android:text="设置">Button>
( j7 V$ @" F6 y& n5 w% s Button
( T/ z0 g, b4 Z/ e" M( D$ R& L5 R android:id="@+id/btn_upload"
8 v, ~! ^- u7 U android:layout_width="60dp"
) ^$ g+ S% h2 c8 J9 j android:layout_height="30dp"
, B3 D, y( Y8 r0 a android:visibility="gone"
. R6 u! H# M$ O) T# T" ?' ^ android:textColor="@color/white"
8 V1 d e3 h5 a% V2 u android:background="@drawable/button_task_background"3 P/ A4 U* |4 H
android:text="上传">Button>
% S4 Q2 ]6 p" L% z: K: k Button
& f' W: |) R, p0 R* v2 N0 z android:id="@+id/btn_start") Z6 ~ u4 ` o7 v. R
android:layout_width="60dp"% s/ o- R( D& v$ i% |! b1 {
android:layout_height="30dp". X+ p1 s8 B/ o# R" O
android:visibility="gone"; W2 Q. s O. Z y( j# a
android:textColor="@color/white"
$ H7 M$ t$ ~# Z8 ?3 F) H5 ]+ {0 Z android:background="@drawable/button_task_background"9 Z! ~. m- T: L+ ~! H8 u( o
android:text="开始">Button>3 G, t! n6 ~5 b% F4 t) B
Button
2 u; \* |4 _5 X1 @6 l1 } android:id="@+id/btn_stop"
5 R% ^* ~( O$ O4 s" g- R5 g: A android:layout_width="60dp"6 G) O/ v: I6 v# i5 k
android:layout_height="30dp"
- e. s# U8 c9 v9 u( M android:visibility="gone"# p! E5 M3 F) F; b; ~# \- Z3 s
android:textColor="@color/white"4 K0 t2 o. N- q9 c. W( q
android:background="@drawable/button_task_background"
f- v) p5 A; o4 a$ R! Y U1 e7 E android:text="暂停">Button>, j3 X/ x7 ^- W/ l0 t# l4 N o
LinearLayout>( i# ^3 o0 U* R7 s" S
LinearLayout' P' C0 u+ c9 ^8 ?* P
android:id="@+id/ll_information"
% |4 E7 q- P3 w. w# X- I; t! U3 M android:layout_width="wrap_content"5 W) o; I" P* i& {8 k, E& u
android:layout_height="wrap_content"1 ~* e) L: ^- `2 \6 R8 s
android:layout_alignParentBottom="true"
' `- h+ i1 d6 }) _, a6 k8 T! Y; q1 E android:layout_centerInParent="true"
+ r' M/ i; |) G8 C `9 @ android:layout_marginBottom="5dp"
+ N. z5 M4 S/ @6 N! @) C9 m android:padding="10dp"
/ [" ?5 t7 u( m' X" v android:visibility="gone"
1 v# W: f8 x6 l: s' @; L! l android:background="@color/color_nav_Item_unselected">
5 J5 A' ^7 x* C! U) H/ b TextView
- J6 n/ m; G$ \3 H7 e8 e. z android:id="@+id/tv_height"4 F$ z. Q3 V. q4 Z# Q& e3 |( U
android:layout_width="wrap_content"
8 C) T" q* h* i9 i( `; H android:layout_height="wrap_content"5 i; j' I3 J( W) N% f0 g; v
android:text="高度:"
* }# d; @' k: P. W( O android:textColor="@color/white"& ^) \3 Y0 M& `( {' C1 D
>TextView>
0 X/ c8 ?# o& L TextView( |1 p: J9 \5 h
android:id="@+id/tv_speed"
- ~/ R) d3 w4 Y/ q' a1 [ android:layout_width="wrap_content"
! o5 C. O# R6 T android:layout_height="wrap_content"
& z: w& m; r5 Y+ f* z7 Y! h1 @. S android:text="速度:"
1 `- e/ X, b' O9 J' ~: g android:textColor="@color/white"
8 `" E, Z: u6 R2 K* \6 m0 K$ N android:layout_marginLeft="10dp", S0 W; L m5 ]+ X9 \
>TextView>
; P# @6 r* F G TextView2 b5 q- r, U/ C
android:id="@+id/tv_count", d) ?: l. U, ~9 I$ p! _
android:layout_width="wrap_content"
+ c- W2 T8 b; g0 s7 ~: U android:layout_height="wrap_content"/ n% _* c9 Z' @5 b3 y' \' M2 \
android:text="航点数:"9 X, g* p, ]; O, n. J( q" Q
android:textColor="@color/white"
9 H/ o( k/ W: S& Y" n& V2 D6 Q android:layout_marginLeft="10dp"
* k8 c# J0 C5 } r6 D' b >TextView>
. |" ^' o$ D3 A+ I/ k. N K! T8 o. r. @ TextView1 e. {6 j6 f! \- B" _" K
android:id="@+id/tv_distance"
7 Q3 a4 u4 H3 K; r! W; q android:layout_width="wrap_content"
# T3 L! x5 ~; {) d- h) y android:layout_height="wrap_content"! _+ z0 O, ^% r6 s; n U
android:text="总距离:"% Z" E. X* ^+ y' m% F/ x8 e2 [$ ]% d
android:textColor="@color/white"1 L+ A3 I- D6 y
android:layout_marginLeft="10dp" {% L6 |& D/ d' |
>TextView>
2 p, H5 g$ ^# m TextView
" ]* @7 X- c( K: P: F android:id="@+id/tv_time"' `+ ?/ H$ \1 X0 ~8 b$ n
android:layout_width="wrap_content"
; I- W0 X- Y. Q: H- _" l android:layout_height="wrap_content"
. k: i* M# `, x s. a7 ?1 f android:text="总时间:"
+ z1 N1 I9 q- q3 Y. x" U android:textColor="@color/white"% M& f, U- R* J& q7 q
android:layout_marginLeft="10dp"$ N# j2 b. H1 \! `) |
>TextView>
7 K- p$ [# Y. t7 f1 ]4 r LinearLayout>' N: R8 [. |4 \8 w, X h
RelativeLayout>1 n& O$ W( `4 w; u0 l# A! r
LinearLayout>
4 \% L, P4 M: _9 z4 @# g& X1 i% JSettingRouteActivity
# r4 c9 U, C; P2 q1 w7 b e2 z2 R2 {( | t8 q) g. V" B
public class SettingRouteActivity extends BaseActivity implements AMap.OnMarkerClickListener, View.OnClickListener, AMap.OnMapClickListener, LocationSource, AMapLocationListener, AMap.InfoWindowAdapter {& K4 l8 J& ]# }% b' D$ ~, P
@BindView(R.id.layout_route)
/ h9 P9 T2 Q3 s& N View mViewLayoutToolbar;( ~: }- }0 {4 G6 r9 _
@BindView(R.id.ll_route)
9 w4 ~* z) D5 H% k LinearLayout mLinearLayout;7 r6 V/ r; |3 p% \: v
@BindView(R.id.tv_toolbar_title). c! W+ {. R4 d- O3 j
TextView mTextViewToolbarTitle;
# P3 w) h7 O( g/ d) j7 f7 N // @BindView(R.id.map)) M- S1 j2 ~5 L/ D" Z
// MapView mMapView;& ?) X# i: F9 g! N# b' U I
@BindView(R.id.btn_delete)2 Q# B# V6 p8 F& Y
Button mButtonDelete;
6 m5 j0 x# J$ j @BindView(R.id.btn_finish)* j# N" {& r' [+ a! [/ v5 L3 ~
Button mButtonFinish;/ u! c* }2 m0 l2 b
@BindView(R.id.btn_setting)
, o* y: W2 |! Q: m, J; _5 r* U/ p Button mButtonSetting;
3 N6 s1 f/ @# {$ O* d# }; }4 _; T @BindView(R.id.btn_upload)
" H" ]( u( H% O6 g/ \) m6 U, U3 P Button mButtonUpload;
( Y2 v' h$ @0 d @BindView(R.id.btn_start)
, ^1 K2 B, v/ _' M3 L8 N1 p3 w Button mButtonStart;3 e4 }) E8 _8 f; [( E
@BindView(R.id.btn_stop)
; d. b# M! Q7 U3 ? Button mButtonStop;
; {/ \; y- y; K2 i5 A" H @BindView(R.id.ll_information)
8 R+ d: s0 S. B! V* I+ V LinearLayout mLinearLayoutInformation;6 x( i8 v3 o3 w% Z9 ]5 V$ T
@BindView(R.id.tv_height)' m/ f* H/ T( o& h8 P
TextView mTextViewHeight;
& `2 Q- o5 G& A, m/ a m7 v+ D @BindView(R.id.tv_speed)
$ L! l5 E& ?! I" q+ h5 M8 e TextView mTextViewSpeed;
4 m% g- J, A- H1 [7 @( [ @BindView(R.id.tv_count)
( X9 ] u8 t% Z0 j8 r3 b TextView mTextViewCount;0 ]- \. ] o+ K* t5 _. R: U
@BindView(R.id.tv_distance)
' b; g3 R0 h% M' [: I# ~! g TextView mTextViewDistance;5 ~) ]3 N7 |' `6 `2 t V
@BindView(R.id.tv_time)
. r8 J }" j. V% u! y3 Y: J TextView mTextViewTime;& a/ n S! i3 ]. ~2 C7 a9 Q6 u# P
private MapView mMapView;
4 W. a0 |3 X$ j$ c8 q private OnLocationChangedListener mListener;
. S% A* U n' T" C0 J. w# h private AMapLocationClient mlocationClient;
- Q1 \; h4 t8 G% @' ~" ~7 y private AMapLocationClientOption mLocationOption;
1 ~! m& i Y( ^- |! p5 d0 A5 \ private double D_latitude, D_longitude;: e; \9 t. Z2 b, D6 D
private UiSettings mUiSettings;
" _+ g, }. d: a3 i6 }, p2 K* ~# `2 s/ j private AMap aMap;
% T0 ^1 B" n+ v private Marker droneMarker = null;
1 q; y3 j6 }2 g3 }6 t5 U3 w private float altitude = 100.0f;
; T8 i0 n: r) X+ J) O private float mSpeed = 10.0f;) w! y# b7 `8 U; y: ~7 w7 b
private boolean isAdd = false;
5 u7 V8 I* f% ?. z9 u2 W% B* l& t private final Map[I] mMarkers = new ConcurrentHashMap[I]();" G$ o" U2 i# c! b, x5 \& ~- O
private Marker mClickMarker;' C v+ z; \$ A: r# A
private List waypointList = new ArrayList();: s- Q3 w$ r& @4 T9 Y# K
private List mLatLng = new ArrayList();/ Q I4 }7 q! B% _: _/ ]9 B
private List mPointInfo = new ArrayList();% b( z" Z5 T# @ H
public static WaypointMission.Builder waypointMissionBuilder;) e! d: h N, |) s- v/ o
private FlightController mFlightController;' Y. b. l2 ~) t3 _, Y- Q
private WaypointMissionOperator instance;3 j6 n1 d; P4 u1 h8 X" q2 S
private WaypointMissionFinishedAction mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;& S# w1 _$ Q3 R( H/ q- c
private WaypointMissionHeadingMode mHeadingMode = WaypointMissionHeadingMode.AUTO;
- ^, a! P9 E1 m0 g2 a private SQLiteHelper mSQLiteHelper;
1 ?9 c- V* T" u v+ \" Q private String FinishedAction, HeadingMode;+ P+ L- D# ?; Q! @# P
//自定义窗体5 V5 U2 U a8 e# v t7 c' `
View infoWindow = null;( L, X7 c9 @0 i$ t
int speed_RG_id = 0;( E6 i r7 d+ ^. X7 d8 j
int actionAfterFinished_RG_id = 0;
, V6 i2 ^# f5 d+ K' @3 i" O int heading_RG_id = 0;4 l, d6 A6 A0 ?, h& ?: @
//kim! D; z f- M! J a) A
static ReadKml readKml = new ReadKml();
" z$ M3 U# O6 Q! e private static List sampleList = readKml.getCoordinateList();
* W' w! [6 i9 J! I2 x @Override
% P8 G/ Q8 D3 G W public void initViews() {
9 h. ~) X3 i s5 C1 k: }- [- q$ R mLinearLayout.setVisibility(View.VISIBLE);* \. h2 q: x: Z W3 e! I; U
mTextViewToolbarTitle.setText("航线规划");4 Q. I: h" F/ u, n
IntentFilter filter = new IntentFilter();0 K. K, \" F' C% O: M" z
filter.addAction(ReceiverApplication.FLAG_CONNECTION_CHANGE);! v" z; U+ F1 q
registerReceiver(mReceiver, filter);
Q' F5 m4 L5 Y7 c3 F7 | mMapView = findViewById(R.id.map);$ L0 S% ^4 F: P8 i
mMapView.onCreate(InstanceState);
$ t" z$ _8 g. W- s initMapView();
/ E U6 E2 ^! f2 {. ?) { addListener();
2 z6 I. `5 R& m! h, L4 E t: D% V onProductConnectionChange();
5 d, f1 `9 q0 Z- P; [* [* ` }! @$ s A9 _) ^5 o! c
@Override* c" m0 `& R8 R3 h x
protected void onResume() {/ [! W2 O3 b: M% V7 H8 \- ^
super.onResume();
8 g% X2 l. Q p3 {: g# m# q initFlightController();
5 ~* t6 @8 k9 ]% l+ z" U/ E; L mMapView.onResume();
6 t/ d# {- J1 N' S% T, Q% R" ` }
9 `' ?5 M( d$ ~0 I( q7 e ]/ z /*** A' K" V1 f( N8 |% z
* 方法必须重写
4 f3 j! Z% D" `3 Y* `7 J, R */) c9 w- w' g/ U" V/ U* _
@Override9 J3 q; n. w. H, w. y
protected void onSaveInstanceState(Bundle outState) {
) N- C, e% X5 @ super.onSaveInstanceState(outState);
$ @$ J+ H h; i/ \ L mMapView.onSaveInstanceState(outState);; H! m( }5 x% ^2 ]0 }* @3 \
}1 w+ i" j+ a) A- a9 w3 e0 \* n! f
@Override
+ N7 {8 B# y/ ]! X# h protected void onPause() {
h2 z9 {7 V& ^" ?* O6 Y super.onPause();
% D- k7 V# c! r9 f3 w mMapView.onPause();
& ~* S8 w+ Y1 K& ~- z7 x deactivate();
- _+ M! E! P* u9 K V3 N- G) H }
. H2 @0 U: u' W' Q& Z @Override! v8 K2 M' Y: [# C6 Q
protected void onDestroy() {3 K% ^; O6 v. S8 L! o0 `; F
super.onDestroy();
. O `# |' n& T4 {! R W unregisterReceiver(mReceiver);
" U% U$ m' E* y) f6 e" t removeListener();
5 U, e1 I1 U: s; t- ?7 I$ p mMapView.onDestroy();# p# s& u/ @8 k1 _/ z, v; {
if (null != mlocationClient) {& \ o; K: P: R: D6 M
mlocationClient.onDestroy();9 o T" k) Q3 O" }+ C
}
1 y, \" g- n' e' A9 N4 d+ u }
7 ?% v+ b ]3 D0 d$ t: ~ @Override
2 \1 A- X5 K/ Z public void initDatas() {
4 ~& j2 U5 s& p5 U& i }4 F% m) h0 j5 ?. [* i. x3 }0 N
@Override) A; Q( d/ @2 E' g3 t/ j: ]5 j
protected void requestData() {) C" \; A! t0 Z1 q; Z& L
}0 p1 A h5 c4 H
private void initMapView() {
/ {! `0 a! r& w* z5 t. @ if (aMap == null) {
7 m& K2 P. e% g2 K5 G W4 l3 D aMap = mMapView.getMap();$ b( @( c6 q4 ?0 n5 j2 H
mUiSettings = aMap.getUiSettings();& q" I* u8 N# T) N7 B% M9 T
mUiSettings.setMyLocationButtonEnabled(true);
4 R$ w) t& N3 T% z$ n+ k2 U8 @ mUiSettings.setScaleControlsEnabled(true);) p& l% E. a B) A& ^5 n' ^* d3 e
aMap.setOnMapClickListener(this);// add the listener for click for amap object
: E: P: ]1 x2 V% k aMap.setLocationSource(this);
; ]9 c; J+ P$ x ^+ [ aMap.setMyLocationEnabled(true);" L1 H' a. L0 D1 |' J( E2 }
aMap.setInfoWindowAdapter(this);
# T0 |, k) C: W& R6 b+ k v aMap.setOnMarkerClickListener(this);; f/ p# o" R4 M4 E% f
setupLocationStyle();
1 J0 {1 F. \4 d; T& L }) R" [; M8 b a1 w; p+ v* ^
}
$ z# Z! n3 z5 y& ?( k9 h private void setupLocationStyle() {
5 D4 b# [( x7 }( [$ @( A/ G // 自定义系统定位蓝点
: t( B8 o; ]. n* h MyLocationStyle myLocationStyle = new MyLocationStyle();
9 o1 V7 }' ~" h6 e7 _2 W+ ` // 自定义定位蓝点图标! _3 y, T( L% x! g$ t* C O- W
myLocationStyle.myLocationIcon(BitmapDescriptorFactory.9 k9 p7 S$ x+ ~" _+ n
fromResource(R.mipmap.icv_gps_point_36dp));$ e9 L( L, v ~& o1 h; [5 S
// 自定义精度范围的圆形边框颜色
9 { i/ z9 O' G7 e myLocationStyle.strokeColor(Color.parseColor("#00000000"));
) o1 p* g* c! e6 [. | //自定义精度范围的圆形边框宽度
. q3 J4 z; N' e2 Y& J- N myLocationStyle.strokeWidth(5);! @2 W! a3 `! @% Y3 ^6 ^: b
// 设置圆形的填充颜色' P8 ^% v, D8 z2 V' @
myLocationStyle.radiusFillColor(Color.parseColor("#00000000"));
5 e4 M) {1 P. q; Y7 `. p // 将自定义的 myLocationStyle 对象添加到地图上0 L4 e& Q8 a6 j; [& |. X7 V- P9 U
aMap.setMyLocationStyle(myLocationStyle);# o8 n* F$ t2 U9 q
}
! R8 K3 ^( u! V$ r" J @OnClick({R.id.img_kml_input, R.id.img_setting_route, R.id.img_start_fly, R.id.btn_delete,
: @. y/ ]- [& I d R.id.img_setting_clear, R.id.btn_finish, R.id.btn_setting, R.id.btn_upload,
& V8 G! p0 n' ?0 f6 x1 `% W R.id.btn_start, R.id.btn_stop, R.id.img_back})
: `/ K; o2 z! n& g( V1 P7 \! G @Override7 q3 I' ]6 b7 W, x+ P% [( d) I
public void onClick(View v) {
& j1 Z, D& F% N4 c1 j switch (v.getId()) {$ j$ i4 K! u7 x' \
case R.id.img_back:# q1 o. W/ A+ N9 k$ W7 l
SettingRouteActivity.this.finish();
0 `! ~/ ]0 M8 T8 m; V# M break;; ]+ |! h: ~, V) d) k" b
case R.id.img_kml_input:0 c# N& e" G8 Q' L1 x+ l
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
5 a" V. g F2 S y' {7 h% \ intent.setType("*/*");//设置类型,我这里是任意类型,任意后缀的可以这样写。3 |7 T6 Y9 s! e# q- t; f, A( ^9 `4 e
intent.addCategory(Intent.CATEGORY_OPENABLE);& V2 d( x O8 d9 K7 o2 u- C) W" h
startActivityForResult(intent, MyStatic.REQUEST_CODE_FILE);
9 k& |9 ?9 w; B* j break;
0 Z6 m* d n8 A- H4 w+ t case R.id.img_setting_route:
9 I" O0 H8 x, ~3 J. }1 _ enableDisableAdd();
0 [$ _5 D% B9 j4 n3 J2 x0 c break;1 L$ R8 z! R- i- ^: \4 M
case R.id.img_setting_clear:; a+ i/ I/ l0 u
runOnUiThread(new Runnable() {0 t: n* F7 a8 E- _) C
@Override
- ~ b. j T+ G public void run() {! x+ F$ Q1 @& R9 R
aMap.clear();
9 P1 _; m% `- x4 F( h" z mMarkers.clear();2 p2 W9 n/ Y) }& E1 I
mPointInfo.clear();
$ ]' X4 N" i# T mLinearLayoutInformation.setVisibility(View.GONE);
* q6 ]# K! E) n9 ^, R mButtonFinish.setVisibility(View.GONE);
: v @9 d( t0 ?; V2 @ mButtonSetting.setVisibility(View.GONE);3 p1 ^& s, V1 j
mButtonUpload.setVisibility(View.GONE);
, P! G6 \+ |1 U, l9 P2 ?% O mButtonStart.setVisibility(View.GONE);$ O' Z/ i8 X9 U. X$ v
mButtonStop.setVisibility(View.GONE);$ G3 u j i) z4 W* d. j
}: E8 W9 X! ~! J! n# u7 o
});
4 W0 ]$ O) e! N( g waypointList.clear();
6 t; T, X3 T, @' A; a. a. h waypointMissionBuilder.waypointList(waypointList);
/ m* @- t9 y) h, c h break;7 w& y0 p$ H. M) I0 y
case R.id.img_start_fly:% s6 j) y: A, z" ]$ I H
atyAction(WaypointActivity.class, MyStatic.REQUEST_CODE_ID);- P/ x4 e' P) W
break;2 _! W6 ?* z( Q# k
case R.id.btn_delete:
' E1 U' }, ]2 T' {) {# t( I" B runOnUiThread(new Runnable() {
/ q2 l5 [6 n/ n/ ^4 Z( D& t q& {5 [* t$ ^ @Override k1 W/ Z7 U: \: ?( c- T
public void run() {
6 t8 ~" t4 r! I9 V5 q* L( C aMap.clear();) r, b$ r$ ~$ x+ I+ b1 U. H m
}
4 z) Q! H: C% C9 V6 P! U* X });
# `. `" P( e$ Z7 I' U6 h. n for (int i = 0; i if (mMarkers.get(i).getTitle().equals(mClickMarker.getTitle())) {
$ \, H- F. b; e" A) a' F6 Q8 R/ \% M for (int j = i; j 1; j++) {
% W+ L$ z5 f- K3 G5 E mMarkers.put(j, mMarkers.get(j + 1));
' z" y# f" O9 K; Q! j0 a% m; t, ^% t } K! R4 e8 _) n' l
mMarkers.remove(mMarkers.size() - 1);1 R8 a0 a8 J6 |
}. G. q6 J# }. \# X/ K& F# l
}
1 c/ H+ z4 |* g for (int i = 0; i "航点" + (i + 1));
- O0 h. ~3 |% R+ a9 f }5 f& Y$ [: X$ Y7 R4 S
updateMarkWaypoint();+ D. p* Z0 A B- \9 r
break;
/ F1 Q8 p* B( y. K7 ` case R.id.btn_finish:
, y5 o6 A9 x+ r& i MyLog.d("航点数:" + waypointMissionBuilder.getWaypointCount());: S$ k- n/ @. Q' W. ]3 z' P% ?/ Q
MyLog.d("总距离:" + waypointMissionBuilder.calculateTotalDistance());
2 h5 P5 t5 }3 F, ] MyLog.d("总时间:" + waypointMissionBuilder.calculateTotalTime());
# P! _( D& a% U$ ^! U; Y$ [ isAdd = false;
" P: ], P: j+ q9 M6 L mButtonFinish.setVisibility(View.GONE);8 E a) p" A r0 a5 R! Y! n
mButtonSetting.setVisibility(View.VISIBLE);( [- W/ m1 |' L8 W' t$ g) P$ g# m2 T
mButtonUpload.setVisibility(View.VISIBLE);
8 t9 B; K/ G1 Y+ \ showSettingDialog();
/ M6 q! l+ s7 W; f0 A5 j break;* U$ g$ T. ]: Z
case R.id.btn_setting:) m7 ^+ e$ q" ?1 L$ n
showSettingDialog();) o. K3 p0 _8 F& x8 p' C% t2 z; B
break;
% |) h1 O' i# d case R.id.btn_upload:
9 y, I5 P4 k4 ^: g& K uploadWayPointMission();) A' J: d! N6 o% i# t) z
break;
t, V% i* M# K9 ?1 V- O$ T* Q case R.id.btn_start:
$ B- k' f: ~! `9 c/ D( I( K startWaypointMission();) c* ~# M: t5 p
break;* n* c7 I3 i9 \9 N
case R.id.btn_stop:- z+ U k9 t# M5 T
stopWaypointMission();4 X) k$ W; [. ]' W. [
break;
( }" R. {2 h5 S* }3 _) x0 X" V }9 `8 H8 h8 t3 E
}
, W9 |* M8 `$ f: c, u private void enableDisableAdd() {
1 [2 W! `+ P/ ]3 l if (isAdd == false) {
3 J. u- h1 D, w7 V3 g isAdd = true;
; y5 p, j0 q# g mButtonFinish.setVisibility(View.VISIBLE);
. P% E% E% ?+ _6 |3 j; z } else {
9 B7 D+ a# g* o1 K; B) p& } isAdd = false;; m3 H6 i7 X. M a
}( r0 H7 a6 K" g6 B# ], \+ Q0 ]7 O6 M
}! r# x' U( _( r
private void initFlightController() {8 b0 M1 y; D9 a
BaseProduct product = ReceiverApplication.getProductInstance();' }$ p. ^2 a! T+ K3 i
if (product != null && product.isConnected()) {
+ X% r6 V: T0 k7 |4 H if (product instanceof Aircraft) {
" M% j; x% w2 J) _2 p% T0 V& a r mFlightController = ((Aircraft) product).getFlightController();3 c/ C. L2 s$ V) b7 q5 B
}' ]+ W9 u$ @8 E7 e: a; \8 i! ^
}: f I, A; C, u9 s- p0 @
if (mFlightController != null) {
4 h$ w" Q4 q- D' H, R7 ~ mFlightController.setStateCallback(
$ l+ p0 p6 R* d l( d7 G* k new FlightControllerState.Callback() {8 B/ r2 m) P2 d
@Override# V* o+ t# ~$ R4 s! j$ U
public void onUpdate(FlightControllerState, Y# Z% y4 ]( G& t2 b
djiFlightControllerCurrentState) {) K/ f7 b/ K% M& Z/ N* ~/ l% N$ d, ]9 A
if (djiFlightControllerCurrentState.getAircraftLocation().getLatitude() != 0.0 && djiFlightControllerCurrentState.getAircraftLocation().getLongitude() != 0.0) {( ^- u0 I7 ~" K8 X" p
D_latitude = djiFlightControllerCurrentState.getAircraftLocation().getLatitude();
% s- } k* o. |8 w _0 J. k# }, T D_longitude = djiFlightControllerCurrentState.getAircraftLocation().getLongitude();& b0 t* ?( K" ^" q
}
" f# z' U( d+ L6 G# R H0 r updateDroneLocation();
7 I6 b( t! ^' Q, h# g2 f) ^' ^ }; }$ [) z; }3 G1 z
});
+ R, E/ _) V- i) M% v: m; |, X }4 W( M! t" S3 P4 k9 F, z. s, V
}( Q$ c5 F; R3 q0 M. s
private void updateDroneLocation() {
% K( O v! h* s E9 D, r8 a! p LatLng pos = new LatLng(D_latitude, D_longitude);4 O. b0 w$ a% c( ~
//Create MarkerOptions object. O- C8 l2 i1 g
final MarkerOptions markerOptions = new MarkerOptions();7 s l' _# v) X& p
markerOptions.position(pos); Y7 D# r5 b: @
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_aircraft_write_36dp));
4 S: O3 b: x. @/ b9 B; z runOnUiThread(new Runnable() {
+ d) N3 K" d9 A& V @Override* h) r2 H+ E6 F! Y/ q4 L+ r
public void run() {
1 o) w' s: O' U, `0 R if (droneMarker != null) {; T3 S$ B& Q% }6 m' }
droneMarker.remove();1 p& x4 W; \ y: O3 C9 ~' D+ \
}
$ o* w- F9 m8 \: t6 L; g if (checkGpsCoordination(D_latitude, D_longitude)) {
6 }. T9 V$ a0 a' T! J9 H; P* o" y droneMarker = aMap.addMarker(markerOptions);
6 r; t' \6 u+ q1 ^& e }+ Y- Y, s% g6 l0 D9 ~; E g
}( V* G2 B3 w) q6 b6 _4 o
});
0 V& a+ G( {* R# y! I }% C5 V4 |7 Z& @5 f+ g& z# `5 P
public static boolean checkGpsCoordination(double latitude, double longitude) {' P; c5 q8 @' A
return (latitude > -90 && latitude 90 && longitude > -180 && longitude 180) && (latitude != 0f && longitude != 0f);
# C: @8 c" [' ]/ Z7 e4 Y) C }
" y* {2 H$ [9 H protected BroadcastReceiver mReceiver = new BroadcastReceiver() {8 h$ x3 o- M7 _9 i; r
@Override/ \8 x! a3 S- y7 z7 _
public void onReceive(Context context, Intent intent) {0 _6 U& B; R2 r L; C# k5 c
onProductConnectionChange();# W2 j3 C4 T! ^( A. ~. C" E( o; V
}
3 ]# b- ]& p2 w' z" @1 L7 k- U };( T1 r3 I N, I7 S' J/ Y5 F
private void onProductConnectionChange() {
9 V4 `5 O9 b. r- z* C( ~+ E initFlightController();+ @3 Z f# c* k2 z6 e9 n( x
}
) d5 [3 [- i8 }; d7 a$ ] private void addListener() {! k1 s: t! I3 S# p2 K2 D+ X
if (getWaypointMissionOperator() != null) {
1 M! N; V+ P( N8 B8 G# x& q getWaypointMissionOperator().addListener(eventNotificationListener);
9 {: h$ @) M# z' x* w8 O" ^ }
+ t6 r3 ]: z" k- W9 G }
; J4 ?% K: `$ ]6 r% E( A9 @ private void removeListener() {* H# M) ?$ d$ b$ q0 E- a7 L
if (getWaypointMissionOperator() != null) {) B4 w3 O5 K& s
getWaypointMissionOperator().removeListener(eventNotificationListener);
, ^+ u4 C$ V/ b( h }1 k! o% S2 R, M' b* r
}) ~* K I& {& i1 Q7 x) u& f
private WaypointMissionOperatorListener eventNotificationListener = new WaypointMissionOperatorListener() {
& U6 ~, i6 N# `/ j9 G7 a6 q& M7 @ @Override& [+ W( S% \$ e: K( d& B- Z
public void onDownloadUpdate(WaypointMissionDownloadEvent downloadEvent) {
/ ~9 `% O( Z: G5 Z }$ m$ x' D; e5 O% e2 w( ^
@Override J% v/ H% B5 A
public void onUploadUpdate(WaypointMissionUploadEvent uploadEvent) {
7 K, P. g/ t/ P# O# a7 g }
# l* S3 `$ @; C# R& f" n @Override
& N6 J2 x4 q7 r! A4 L. _ public void onExecutionUpdate(WaypointMissionExecutionEvent executionEvent) {
0 K% y: u1 ?' y" w' c" M9 P0 [. k" @ }
* e& e; F) ], k* ? @Override' u' U+ K" R+ }6 T! r& A/ r
public void onExecutionStart() {. B* ], J% u9 J, Z. m+ w
}* Y1 {; Q' O# t' ]; V
@Override& Q0 _7 K8 l- g J/ o7 j
public void onExecutionFinish(@Nullable final DJIError error) {3 S, b1 {* w1 m* U: R7 w' c6 g
showToasts("Execution finished: " + (error == null ? "Success!" : error.getDescription()));% ~$ p7 W% { p# T0 t/ c5 o& a8 q
}3 ?8 p3 h" z o1 k4 u* ~) X0 s
};
2 U0 Y# `* @1 |# o: M9 I) I) _ public WaypointMissionOperator getWaypointMissionOperator() {* l3 v, _4 d' C- l8 w& ^& u/ c9 l1 D
if (instance == null) {
- n; ~% c- v& G6 D, |7 r instance = DJISDKManager.getInstance().getMissionControl().getWaypointMissionOperator();
+ H9 l. \; x9 y. Q/ a4 d }' Z0 M9 Y/ F/ J/ N; F) I* v
return instance;
: d/ h; J# k Z1 n% ~- F0 A }
; U# p0 x& l' ^ @Override+ S: I9 f% ]' u4 S9 u
public void onMapClick(LatLng point) {
$ I G- ~, j" F8 V o# S& P5 X0 s3 q if (isAdd == true) {9 c8 v; y2 P# X5 \) E
markWaypoint(point);0 Q" P! r3 c- i8 g# [( e* O
Waypoint mWaypoint = new Waypoint(point.latitude, point.longitude, altitude);
4 T% ~# W9 w. p# r+ B- f //Add Waypoints to Waypoint arraylist;& X2 e! c' |5 q. ~% u! ~) V9 K
if (waypointMissionBuilder != null) {3 g! d) T" ], a: |3 s
waypointList.add(mWaypoint);8 A2 z& q" M0 O1 x$ ]. F$ g: E P
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());5 h2 L' L" |4 r
} else {
$ @# @1 i; C- U. t- |( O) z waypointMissionBuilder = new WaypointMission.Builder();
" g3 A/ I' U6 L3 x+ D waypointList.add(mWaypoint);4 C5 A+ M: Y2 B: w, z- U# `
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());9 m$ f! C3 [ g; b
}0 x8 F* O2 u1 S$ ?' d5 H
mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());/ c) ~+ x- H$ H' |
mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");
( P& e! F( P# a7 W mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");" l# ]! \% T; z
} else {
0 B; }# x6 o' \ if (mClickMarker != null && mClickMarker.isInfoWindowShown()) {0 _1 c8 a; L4 X: n$ U: V/ ~7 y; w
mClickMarker.hideInfoWindow();4 p5 Y+ d: G: `5 G; h5 S/ \
mButtonDelete.setVisibility(View.GONE);
( Z; ^1 \8 t v+ V# l& d( Y- G }7 z3 s8 F; V$ t C5 q
// showToasts("当前未开启增加点模式");) v* A+ C m0 K2 G, l I/ t4 @
}
; S) ]0 {0 U* l! n' b }
+ A3 [; S, g1 t8 o- M* Y4 F private void markWaypoint(LatLng point) {+ z- J2 E: \' {) c) D0 {- T) Y
MarkerOptions markerOptions = new MarkerOptions();# W: V" R* j% f3 x$ m
markerOptions.position(point);* i+ O+ i" @4 n& J& X2 x9 }5 P0 u
mPointInfo.add(new PointInfo(point.latitude, point.longitude));
4 Z! D' r8 I% ~3 y markerOptions.title("航点" + (mMarkers.size() + 1));
1 r. e& T7 ] h3 d9 F, i5 p6 Z9 h markerOptions.snippet("事件:");* { R6 h& Q) g; l
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
' D5 n+ ?. p2 v4 q: L% y markerOptions.infoWindowEnable(true);6 h6 o% M; B8 K* w ^8 H+ y
Marker marker = aMap.addMarker(markerOptions);) [7 i( V) z* P1 z. c, e5 O
mMarkers.put(mMarkers.size(), marker);
( o+ X6 ^1 S4 @ marker.showInfoWindow();' X5 c5 i3 w) J9 w B
if (mMarkers.size() > 0) {
" U, a8 H- q) t- D mLatLng.clear();
: ^0 F, x, q' M7 ~ PolylineOptions PolylineOptions = new PolylineOptions();
1 V" V% R1 A: F" E7 G for (int i = 0; i 10);
8 u. R0 W6 {- G) C2 V- j5 R" \2 K PolylineOptions.color(Color.argb(255, 1, 1, 1));
: r& O( ]$ K- m, F" u) V4 ` aMap.addPolyline(PolylineOptions);7 i2 P4 g1 s0 ^
}* m! m) U$ j7 g
}
% C3 D0 g5 F% e( }; e. e3 k7 q8 c private void updateMarkWaypoint() {
5 p& @, Q8 N! ?5 _9 j* M mLatLng.clear();
& a* S/ |0 A/ b$ q9 E+ j# {+ n waypointList.clear();
+ T8 b+ M; {8 c mPointInfo.clear();
1 h! F" u6 ?/ \5 A4 X waypointMissionBuilder.waypointList(waypointList);0 A! `% T" s% x) Q; H! X* o
for (int i = 0; i new PointInfo(mMarkers.get(i).getPosition().latitude, mMarkers.get(i).getPosition().longitude));
" ]( P& i/ @, T; _) }3 l MarkerOptions markerOptions = new MarkerOptions();7 r7 ]5 S8 j* S4 q5 o
Waypoint mWaypoint = new Waypoint(mMarkers.get(i).getPosition().latitude, mMarkers.get(i).getPosition().longitude, altitude);3 `- x W3 ]" ^! H$ Q: _/ p
waypointList.add(mWaypoint);
" J' _% T) v+ \6 g markerOptions.position(mMarkers.get(i).getPosition());" x3 }/ C& b. q: Q. w
markerOptions.title(mMarkers.get(i).getTitle());2 G/ L+ Y& D5 h& i0 ]8 v( p+ v0 h
markerOptions.snippet(mMarkers.get(i).getSnippet());9 K9 k" f8 J, ]* {9 d
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
) ]: x% i i5 ?! A! w5 B& K aMap.addMarker(markerOptions);
1 r+ W2 c# _8 n- p: }1 D- j mLatLng.add(mMarkers.get(i).getPosition());
# G& d# f3 a' t0 J. _/ X0 S# b5 a# ^; `# V }+ O! `2 [/ e5 Y- a% |& x' i1 r4 K$ G
if (mMarkers.size() > 0) {$ Q& E! p0 ^9 b5 W0 l3 _# c
PolylineOptions PolylineOptions = new PolylineOptions();
w( r, \5 Y) w$ T0 M PolylineOptions.addAll(mLatLng);
& o$ D/ j8 F) t9 ?2 ` PolylineOptions.width(10);
: z( V% k" N# q! K/ B PolylineOptions.color(Color.argb(255, 1, 1, 1));0 y0 x4 H7 N8 O& i) k
aMap.addPolyline(PolylineOptions);0 a3 i- L2 i: H6 }( }+ }6 o
}3 h) w- K# a5 g& b* ]
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());, L+ L) t' M) v5 T5 c7 I$ c
mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());: `" h3 p0 v* x5 Z0 K$ w
mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");! |( ?( o' H( F
mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");
: e$ }6 ~* E1 K* N: @+ v MyLog.d("航点数:" + waypointMissionBuilder.getWaypointCount());: ]9 M' m4 @9 d8 j
MyLog.d("总距离:" + waypointMissionBuilder.calculateTotalDistance());6 F: s7 W. E1 o. f$ ` k8 u' e
MyLog.d("总时间:" + waypointMissionBuilder.calculateTotalTime());
0 @# ^& m& m# d9 d- Q mButtonDelete.setVisibility(View.GONE);
4 y/ I9 i. `( i5 h }" q9 j3 J* T( J: k: T3 \& u! K' f
% i; ]# i" ?$ m/ n) ?6 H& q! D# z% ^3 `* h
/**
1 N2 a$ O" u6 i/ _! D/ V * 定位成功后回调函数
& U# t( W8 ~* @* W1 V */0 _- z, H! i( t
@Override7 R1 @; _3 ^3 \: T9 t- v- r
public void onLocationChanged(AMapLocation amapLocation) {
+ b- M$ k' Z% W4 ^8 {3 @ if (mListener != null && amapLocation != null) {
3 e7 i0 J3 [- ]1 X/ v m" F2 y. w if (amapLocation != null
6 J$ d) g2 g9 E/ @9 v && amapLocation.getErrorCode() == 0) {
- r. P L/ {; e6 i D_latitude = amapLocation.getLatitude(); //获取纬度1 o! _+ o7 d8 j& j' O. g5 |$ D( t
D_longitude = amapLocation.getLongitude(); //获取经度
' K5 I n0 @* B; }: B mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
# u8 F* _3 s8 i/ w9 F9 w9 k aMap.moveCamera(CameraUpdateFactory.zoomTo(18));+ W$ f; a [: i$ m0 N
} else {
5 e" W7 X8 u7 }: v6 c3 l) w String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
+ @- [& G3 Q0 @: f: X9 ~ e Log.e("AmapErr", errText);
4 [# j7 x6 \+ D$ } }) Z0 z! K4 v3 d+ ]- ?0 x S
}
2 |0 W% H7 U1 E0 G4 Q# v }9 N( o0 F! b7 d; `% a
@Override
8 b( I5 a8 s1 N; n public void activate(OnLocationChangedListener listener) {0 j* n% H W( k2 M' v* K
mListener = listener;, o+ E% m8 v# y
if (mlocationClient == null) {4 _3 y2 `: Y3 T) t9 {
try {' L- t0 u/ `$ l) b& J& u* Q O
mlocationClient = new AMapLocationClient(this);, U, [( S# |0 M
} catch (Exception e) {
; ~4 i% G( R: H3 d4 Q) Q- u e.printStackTrace();: I0 d% E6 H3 R6 a6 ?
}" {! \3 i6 G4 k- T2 g
mLocationOption = new AMapLocationClientOption();/ Q% x$ b D+ I; x% T
//设置定位监听
7 y1 E6 ]/ N& X5 d4 t8 c mlocationClient.setLocationListener(this);
( J5 G$ c' I$ M) r6 R* V //设置为高精度定位模式& U2 D: Y7 b5 t, ]( l+ Z
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);9 J# n2 {! ]- D6 G, c6 [) }7 w% i
//设置定位参数; L0 C8 }6 {+ [" I6 a
mLocationOption.setOnceLocation(true);6 C. V% {: H! K' i% o
mlocationClient.setLocationOption(mLocationOption);6 s% W. k0 I. g
// 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,* w8 G; W/ ] v
// 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求 |. b$ L d/ l9 Y
// 在定位结束后,在合适的生命周期调用onDestroy()方法/ g) L' g a+ {
// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
! K% |* d8 l: x8 H" T( z mlocationClient.startLocation();
1 j1 Y! U( z$ L/ V: v, B }
' Q+ Y) _3 z) V/ K7 a: }2 G }
) h$ H" p0 r" C2 t) C @Override( {' ]: P* s! g0 U; @9 R" o
public void deactivate() {1 V$ `9 T% v: H5 ^" ]
mListener = null;
- m# d n G! f, `; B if (mlocationClient != null) {
5 b" v# T5 V; M" j# |2 r c mlocationClient.stopLocation();
! H" k' N4 e8 I/ E- z4 @ mlocationClient.onDestroy();
8 R6 x, j4 |( f6 f }7 A: c) m5 i( P! A* e
mlocationClient = null;
: K" z) y0 B( F1 {/ S }" E9 N3 _: }3 W- y0 s6 _
@Override
. B% [# J- z) \5 ~: C3 x public View getInfoWindow(Marker marker) {
1 d- F( b3 T0 g6 T/ g g; P* _ if (infoWindow == null) {$ Z8 v% p8 S! D# Y8 {
infoWindow = LayoutInflater.from(this).inflate(R.layout.amap_info_window, null);
1 U+ Z; V, q& q+ S W }
! r) a# U7 b( z' X2 v render(marker, infoWindow);
3 I3 h- ^8 O3 ] return infoWindow;
3 r/ G, t3 n3 c* Q2 R2 Q }
4 V* Q \; Y4 Y1 R" a /**3 u9 O" q$ {0 y) X% `
* 自定义infoWindow窗口7 z( C( ?. ]: H |; E
*/
, M; P) A; a: ? private void render(Marker marker, View infoWindow) {
8 o# f8 u# m1 q. v1 H+ h TextView title = infoWindow.findViewById(R.id.info_window_title);! c1 X* O* j$ T! Z; c
TextView content = infoWindow.findViewById(R.id.info_window_content);+ s3 v* ]- c: W2 V
title.setText(marker.getTitle());& ~" k3 @2 V5 J
content.setText(marker.getSnippet());
5 f& Y8 A9 V* ]3 j9 i }3 F, M0 u0 P) P0 ^) f# l/ _
4 _' _1 L0 Z) u: G; @. e
@Override5 K! k' R3 c+ w
public View getInfoContents(Marker marker) {* J" f6 D& Y N% H, ]6 d2 j
return null;
3 z7 b/ E9 M. T4 [ }
/ }; U+ E/ |& u @Override! |; t8 _# n: ^* p0 f/ k; E
public boolean onMarkerClick(Marker marker) {
1 v( @- v+ ~5 c) c) D3 v' Q marker.showInfoWindow();- q! A! t+ s& F4 V, g# V" S$ P7 r7 D5 m
mClickMarker = marker; C- ~9 B/ M# a+ M0 r- F- @
mButtonDelete.setVisibility(View.VISIBLE);9 B9 E8 ~& I1 T) }; ^* L
// aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(marker.getPosition(),18,0,0)));
" A1 G, `3 t! f4 D) z) w return true;
: w3 \7 n( B1 P* b1 V' X }7 N! X# T) V, j1 M+ G
private void showSettingDialog() {
( p' @/ o, ?4 h; @6 K: z LinearLayout wayPointSettings = (LinearLayout) getLayoutInflater().inflate(R.layout.dialog_waypointsetting, null);. G- r* V* r: ~6 L: I* o- B
final TextView wpAltitude_TV = (TextView) wayPointSettings.findViewById(R.id.altitude);
' _3 K* j# b4 B5 z" ? RadioGroup speed_RG = (RadioGroup) wayPointSettings.findViewById(R.id.speed);
; C6 V2 r& G. e8 e RadioGroup actionAfterFinished_RG = (RadioGroup) wayPointSettings.findViewById(R.id.actionAfterFinished);% J+ e7 U# c0 y* J- j4 @. r
RadioGroup heading_RG = (RadioGroup) wayPointSettings.findViewById(R.id.heading);% R8 f; ^2 f x t/ J
wpAltitude_TV.setText(Math.round(altitude) + "");& d; V6 Q( {' t1 _; H
if (speed_RG_id != 0) {
: }8 ^3 w: V+ e7 |* S4 P RadioButton radioButton = (RadioButton) speed_RG.findViewById(speed_RG_id);8 L' Q% V2 q/ M2 I
radioButton.setChecked(true);
; x! c; P/ S0 k6 x }* ^+ t5 g/ J4 H9 ^
if (actionAfterFinished_RG_id != 0) {
0 X' R9 h9 d' `" D+ q0 t3 K; P" m RadioButton radioButton = (RadioButton) actionAfterFinished_RG.findViewById(actionAfterFinished_RG_id);. k' U+ t6 K- V. m9 k
radioButton.setChecked(true);
6 T2 a% Y0 w. b1 d8 G }
5 R6 C! n3 s* C/ H3 U1 y if (heading_RG_id != 0) {
# [, h5 P3 v% b" X) `7 K RadioButton radioButton = (RadioButton) heading_RG.findViewById(heading_RG_id);; H$ H( J, r; N, K, q/ ^) I
radioButton.setChecked(true);
, M0 B9 A3 ]( i }
2 p7 e1 N5 y k4 C' U) V1 V speed_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
4 U' J5 M6 K) ~; A" J9 m1 r @Override
0 n8 X$ q3 O1 r# K$ ]* N7 B public void onCheckedChanged(RadioGroup group, int checkedId) {, K" }( v+ |' ? u% n
if (checkedId == R.id.lowSpeed) {! D! o- N. e; {
mSpeed = 3.0f;. E, b- G# M" }
} else if (checkedId == R.id.MidSpeed) {
9 P6 t$ T9 j1 d( d D9 Q mSpeed = 5.0f;
0 h9 e$ c7 v2 c5 T } else if (checkedId == R.id.HighSpeed) {
+ Q3 [7 |: D8 y% P; O4 O' a mSpeed = 10.0f;
9 a3 W% p4 }; t k7 ^8 [1 ]2 L7 _8 j }+ V3 V) I& q$ }8 I* h
speed_RG_id = checkedId;. B* D! C9 c, {/ D) J, u. W% F1 O
}
; @; B$ f/ k- m });
' @; k1 q% @% U actionAfterFinished_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {4 B- e) G" \, h. \2 u5 @
@Override
7 b& r9 K( n; ` public void onCheckedChanged(RadioGroup group, int checkedId) {, H e- P1 M# r+ B
MyLog.d("选择动作完成");
6 r- t2 b( N$ o8 _1 L if (checkedId == R.id.finishNone) {" M. J! _, M, P: \, M. G
mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;6 J8 L" {0 K9 ]( c3 H; [2 H
FinishedAction = "0";
5 f. e6 ^1 q9 L& ?6 g } else if (checkedId == R.id.finishGoHome) {0 N4 b5 T- ^+ S! H: D+ @
mFinishedAction = WaypointMissionFinishedAction.GO_HOME;
. ~: q ~# A% c FinishedAction = "1";) {7 E6 ]$ `( M' L* Y; t* a, ]
} else if (checkedId == R.id.finishAutoLanding) {
6 B: F6 n0 f* ?+ v mFinishedAction = WaypointMissionFinishedAction.AUTO_LAND;7 Z: I q! \$ U: n% W/ G4 w
FinishedAction = "2";: b$ J- U- g2 g2 w
} else if (checkedId == R.id.finishToFirst) {
; A" e1 G7 T5 T2 [ mFinishedAction = WaypointMissionFinishedAction.GO_FIRST_WAYPOINT;
) o2 w6 C- N, `$ Q6 H9 m& O FinishedAction = "3";; D, @8 U8 j# X7 ?
}
! s% Y+ ]! Q2 b actionAfterFinished_RG_id = checkedId;
8 l0 D$ K( f7 q1 F: _ G8 ^5 O }
' @* \: }' h! z3 R# l3 A7 F });
% ?6 D, S$ u7 { z/ h; G( h4 C: t! l. z heading_RG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {3 z U( |& S' d6 M8 W5 _
@Override( f' _9 M- i9 @
public void onCheckedChanged(RadioGroup group, int checkedId) {
% L P& I' K. p7 O9 [4 _" a MyLog.d("选择标题");+ i, |# p' e2 M& l+ {6 M9 ]
if (checkedId == R.id.headingNext) {# y6 U6 s/ n, H# \) }& p6 a L
mHeadingMode = WaypointMissionHeadingMode.AUTO;+ o5 ~6 C. _8 b' F `/ v ~' {
HeadingMode = "0";- y ^- |& M& A+ H9 P
} else if (checkedId == R.id.headingInitDirec) {& m8 k( K5 ?9 d
mHeadingMode = WaypointMissionHeadingMode.USING_INITIAL_DIRECTION;
2 ~. T7 L- h, `# C5 E- o$ \5 L HeadingMode = "1";: ^' ?" V$ o0 O% L: c. m: x( ^
} else if (checkedId == R.id.headingRC) {
9 m1 M6 N$ o( L/ i, _ mHeadingMode = WaypointMissionHeadingMode.CONTROL_BY_REMOTE_CONTROLLER;
+ ]# ~; V* r" u/ o: I8 Q1 c HeadingMode = "2";
- E7 b5 l0 ?# d4 ]2 p } else if (checkedId == R.id.headingWP) {* E" D, `' e6 [: ]
mHeadingMode = WaypointMissionHeadingMode.USING_WAYPOINT_HEADING;$ t& r& Z9 I6 S2 a$ d. x
HeadingMode = "3";
/ y8 n9 p0 K# B0 w' D0 S }$ X5 a, p$ U- H
heading_RG_id = checkedId;+ T. P$ [, F, g- m$ C) ]3 S
}+ W, X' q8 z* f6 ?1 }; B& V
});
& }& S/ M' G- ^1 l5 R( Z. b. ~ new AlertDialog.Builder(this)
) m2 R! r, s) ]! w) W0 ^$ N .setTitle("航点设置")0 [. v# a+ i5 F
.setView(wayPointSettings)) {# ~$ R0 @: q! Y/ h
.setNeutralButton("设置", new DialogInterface.OnClickListener() {
, \& f" e9 g, [4 ~- D public void onClick(DialogInterface dialog, int id) {
' w$ l) S7 s8 B$ _7 ? String altitudeString = wpAltitude_TV.getText().toString();
5 a, K: ^* i7 V9 @$ n I altitude = Integer.parseInt(nulltoIntegerDefalt(altitudeString));2 [6 B; Y2 }# D* i1 G3 o( m
MyLog.e("altitude " + altitude);) y: u! s- S X3 l8 C1 N
MyLog.e("speed " + mSpeed);
+ E5 C# W1 c& F$ ~) z1 r, }* H MyLog.e("mFinishedAction " + mFinishedAction);
. h: D. N. H) ]* ^8 d# M: O T MyLog.e("mHeadingMode " + mHeadingMode);
0 ~5 j0 D5 b& Y configWayPointMission();
1 c) f$ P) m) Y' Y3 U. k6 ~ }
6 I2 N$ ?9 Y$ T, g& {0 _3 Q- P })8 ^4 H' H% x+ q- L K/ a# D' W
.setCancelable(false)
+ M% Z6 w' k! O* }6 A% D .create()1 V; o* ^! j: @( p \
.show();
# W5 r5 O8 c$ B/ E" L, A2 T }
4 M) @ e6 J; ]. [: c* y String nulltoIntegerDefalt(String value) {; a& W: i& K0 f2 o" U q9 Z% x
if (!isIntValue(value))9 A: y) W8 u0 N
value = "0";
1 h/ l9 a- z7 S# r return value;8 ^3 i3 V2 j& [' [- j$ a; j
}
5 h h( ^ M! C" u {9 S! I' H* p boolean isIntValue(String val) {, D8 w3 V$ \2 |5 ^9 i
try {- q3 q7 F7 z/ y y8 o0 H# i
val = val.replace(" ", "");
2 n0 i# R V& }7 H Integer.parseInt(val);/ A1 ~- |0 v1 y: ]) F
} catch (Exception e) {
9 u1 Z* j' o% I2 x* b return false;6 l' }4 Q6 K" l3 k) P) P7 h/ r
}
$ F- [1 W, ]" }. T7 |- w3 i3 } return true;
9 M5 e# Y- v2 E, X }
* T9 F8 i% D! R; p private void configWayPointMission() {1 ^: }: \& ]8 s' w8 d
if (waypointMissionBuilder == null) {
# z& }+ _# h2 _- z# u( N waypointMissionBuilder = new WaypointMission.Builder().finishedAction(mFinishedAction)& G b, e" i, J
.headingMode(mHeadingMode)6 \% T# b* q; L6 J' h+ r8 _& P" @
.autoFlightSpeed(mSpeed)) j& L5 M: W& a
.maxFlightSpeed(mSpeed)
* Y" {8 M; E6 O .flightPathMode(WaypointMissionFlightPathMode.NORMAL);. J X% b% l% B1 C1 \4 ?
} else {4 U4 t; _" @% U4 W7 B
waypointMissionBuilder.finishedAction(mFinishedAction)
+ z, U7 C# B- K4 a .headingMode(mHeadingMode); u9 `) }; d0 B: ~1 ?2 Z
.autoFlightSpeed(mSpeed); r/ j! V- a7 ^& l8 Q7 f
.maxFlightSpeed(mSpeed)
, v3 T/ Y1 b2 @ f" U! s .flightPathMode(WaypointMissionFlightPathMode.NORMAL);9 B4 O4 w% g2 k
}
* l3 Q/ T! R- M7 t if (waypointMissionBuilder.getWaypointList().size() > 0) {) o/ Q6 u% o# h& ?
for (int i = 0; i if (error == null) {9 W F7 S ] V; [' |# A
if (mLinearLayoutInformation.getVisibility() == View.GONE) {
4 u" B8 M5 d% S9 t# M mLinearLayoutInformation.setVisibility(View.VISIBLE);
) t8 \4 C' B" m" N }
# n9 O. F4 X6 W% ^/ f' P6 h mTextViewHeight.setText("高度:" + altitude + "m");0 R0 r' a3 m; ~3 e/ G: U- P% T0 c
mTextViewSpeed.setText("速度:" + mSpeed + "m/s");
3 C% R4 u& P3 {% t& |6 [( [7 X mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());
: o( }% g# N- Q* a4 | mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");: U! J& F% B0 L
mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");
" B8 H6 y A% f6 s MyLog.d("航点数:" + waypointMissionBuilder.getWaypointCount());
|& B/ p6 v- E MyLog.d("总距离:" + waypointMissionBuilder.calculateTotalDistance());! ]* K# g3 h5 b& x5 l% ?! Y
MyLog.d("总时间:" + waypointMissionBuilder.calculateTotalTime());& I: l; B: d5 ^# j& ~3 t/ ^
showToasts("航路点配置成功");
4 O" G% ]4 G, H } else {
" R2 y) e) X" q% D# L# T showToasts("航路点配置失败 " + error.getDescription());- j; D' o( ]& g+ y6 j
}
. C# C7 T% N6 p1 c8 H }* o$ ]/ a9 S& o' h# S+ C
private void uploadWayPointMission() {* ~. Q+ z5 X z1 {; l8 V- \
getWaypointMissionOperator().uploadMission(new CommonCallbacks.CompletionCallback() {
% \- ~" z5 R- m @Override( ?& P& ~7 V2 `0 _
public void onResult(DJIError error) {
$ U( G5 @0 f) q$ T if (error == null) {* r* }7 v5 \7 J# b, ]+ i: o
runOnUiThread(new Runnable() {
) j( x5 }+ [1 B. I) u3 M @Override
4 b! y# n; D Y5 Q public void run() {
2 }$ p4 L/ ^: y4 ? u mButtonSetting.setVisibility(View.GONE);7 K$ Z# V; N% [. z; a0 s
mButtonUpload.setVisibility(View.GONE);
! h' d; K3 U1 \ mButtonStart.setVisibility(View.VISIBLE);
6 |! p6 q5 t; I8 T" _2 R mButtonStop.setVisibility(View.VISIBLE);; l; X/ X' F3 D! ]: P
}
" u( H5 K8 E$ w, j });! \8 M1 N2 x& H' e$ X. b2 }
showToasts("任务上传成功!");
3 S5 Z- F V0 n9 c$ y6 S) v mSQLiteHelper = new SQLiteHelper(SettingRouteActivity.this);" r7 h! `$ X" u3 ^6 }, ?. K
MyLog.d("航点值:" + GsonUtil.GsonString(mPointInfo));
^$ [5 p& }+ S& ^: t# l3 J( `/ E mSQLiteHelper.doInsert(GsonUtil.GsonString(mPointInfo), altitude, mSpeed, HeadingMode, FinishedAction,, U B' _% E* h
waypointMissionBuilder.getWaypointCount(), Math.round(waypointMissionBuilder.calculateTotalDistance()),
! p* q, K1 g3 D0 K' } Math.round(waypointMissionBuilder.calculateTotalTime()), DateUtils.getCurrentDate());' w1 p1 |8 y1 |4 c
mSQLiteHelper.close();5 y; o) @- y* ^2 E& b* q5 A
} else {
/ p' }, Q: c( t/ T8 a0 h7 e showToasts("任务上传失败, error: " + error.getDescription() + " retrying...");
+ ]# h) z4 _: h+ D! G5 D" H& n getWaypointMissionOperator().retryUploadMission(null);$ L3 h1 ?; q% v
}5 E- e4 U) \8 J8 D! h& t* o
}/ I- J7 y4 h# E) F
});
) Y' T$ F+ U, t5 a O }
% l# [& o" {9 ~ private void startWaypointMission() {
+ L* |! @" x; u" T) D6 V+ C& p getWaypointMissionOperator().startMission(new CommonCallbacks.CompletionCallback() {
8 c; w& }& y) V R @Override4 \ a1 e! P( a- _2 o
public void onResult(DJIError error) {
6 _0 e: c: r5 z [4 A showToasts("任务开始: " + (error == null ? "成功" : "失败:" + error.getDescription()));
; a1 j6 k- |! D0 \$ n }
, B7 W: `) S. a# b+ f; V1 ? });
/ ?" a' \# |8 b7 R+ p' z( D6 N }/ @. \+ A% O, H, f
private void stopWaypointMission() {
$ u( ^, H# j6 [* x5 U getWaypointMissionOperator().stopMission(new CommonCallbacks.CompletionCallback() {+ k$ n) c. R0 p- O- V" V. v% Q
@Override
( ]+ X& k( p% M# j! q a# A public void onResult(DJIError error) {
- ^0 @8 v9 Y* A( A showToasts("任务暂停: " + (error == null ? "成功" : "失败" + error.getDescription()));
+ U, m3 R* M0 V. _+ I! {0 c }9 U: X, G# |% w+ w- ]7 y. U
});
" l0 v7 H- n) j$ J2 c2 ^- ?( ]+ ~ }
$ e x" [- n7 E! o" Y/ n @Override5 ], T9 F( d3 `/ N6 k8 l- l
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
% a# L" o: P5 P& B7 U switch (requestCode) {$ S8 s1 ^: m3 d/ ^
case 101:8 v* y+ \6 S& B
int Id = data.getExtras().getInt("id");
1 D# B5 p! R4 y' e; t' G8 `' i% C MyLog.d("返回的ID:" + Id);/ i+ G: {& s; K5 G" U Z
if (Id > -1) {+ X1 C0 G. |- J% d/ W" F1 `' \
refreshMapPoint(Id);
8 O; ?. X6 A& a4 e2 X }! M. u# j+ ]! y. O! J# Q
break;
& q8 _- X! e, k# H case 102:
8 W4 e4 ~, N( x! _ if (data.getData() != null) {
. T$ i7 Y' j( S/ l( \3 M$ ^& \: g Uri uri = data.getData();//得到uri,后面就是将uri转化成file的过程。
8 _+ }- {, }' Y; N ] String img_path = uri.getPath();" [( x4 j8 q4 \( a& v+ b1 @
try {& g. Y" o' B: [
if (!TextUtils.isEmpty(img_path)) {
n0 Y) l9 [1 l" W5 b readKml.parseKml(img_path);: ?' M, J3 w3 i4 O- f7 G$ d. a+ e
addSampleMarker();) Z. A5 `) _+ F. X' ~6 q8 n
}+ f4 @# c( P& Z# x+ D
} catch (Exception e) {
" ?& H1 j3 e. k2 }8 a e.printStackTrace();
" d3 I8 n6 e, J+ v5 T3 {5 s% {% b( f0 ] }+ `: a. q1 o/ d0 i- t9 T. [
}
! f6 `! I$ Z9 y8 A1 K break;; d) |, \7 X5 b1 y5 j2 g; X0 }; z5 {
default:
# i: j; R } p% w+ V+ w break;
4 R$ H7 \! J4 ~( {7 } }7 d1 `2 b0 `" R& D5 G9 L) c1 |
}
& V7 O/ P" L! \5 \ private void refreshMapPoint(int id) {
& m& L) C2 Y9 m6 Y& ` aMap.clear();8 c! R, k' k5 |4 E' ~6 @
mMarkers.clear();
, c" |5 I6 d3 u# w/ r mPointInfo.clear();4 u; C( _ q3 @1 A
mLinearLayoutInformation.setVisibility(View.GONE);
: U+ t# T0 Y6 a2 n o! m* m mButtonFinish.setVisibility(View.GONE);9 q, A, ^" x# O2 {9 b
mButtonSetting.setVisibility(View.GONE);
# r' F" m0 k, x mButtonUpload.setVisibility(View.GONE);
$ }: Q- G5 S3 I9 n mButtonStart.setVisibility(View.GONE);
5 O( D J1 \, B0 X- G mButtonStop.setVisibility(View.GONE);
& E1 \$ o6 L/ ]7 C+ h waypointList.clear();
8 V; ? @$ g0 d0 [3 N E mSQLiteHelper = new SQLiteHelper(SettingRouteActivity.this);
% q9 C% J3 T( ]/ ^ Cursor c = mSQLiteHelper.doSelectWaypoint(id);' Z# H# c1 o& a! Y9 \8 T! ?
if (c != null) {; n, D5 e0 Y" c/ Z. s# w. Q
if (c.moveToNext()) {
' `" w/ w; ~# ~ MyLog.d("航点:" + "{'pointInfo':" + c.getString(1) + "}");
. e, a& P( b' W% q: n7 I/ _% V k% J mPointInfo.addAll(GsonUtil.GsonToBean("{'pointInfo':" + c.getString(1) + "}", Root.class).getPointInfo());, x$ s2 z8 y4 u- M$ k3 s! G
altitude = c.getFloat(2);) L& @5 J# j$ j, b4 p- i6 C, t% Y4 f
mSpeed = c.getFloat(3);
1 D3 y0 Q( \; n; u" B/ I! I8 K2 k switch (c.getString(4)) {" ^( C S+ L1 j; \5 K. I _$ W
case "0":
$ A7 R8 F+ s( K2 T* n4 o mHeadingMode = WaypointMissionHeadingMode.AUTO;$ Y1 f6 {. Z1 T3 v5 u1 Z {
break;
, q7 }7 _! I/ G5 J case "1":, V1 w6 `" p* A! U) r
mHeadingMode = WaypointMissionHeadingMode.USING_INITIAL_DIRECTION;
! `& Z% m) X: N: E6 m! J" F/ z5 o break;' z2 V$ q' l, y& L" P( t
case "2":
; b- h: X h2 F6 x/ H4 _2 l mHeadingMode = WaypointMissionHeadingMode.CONTROL_BY_REMOTE_CONTROLLER; {8 f' D7 c8 F2 N7 }2 p
break;9 L6 Q! F; f3 F, H: A; y
case "3":
* d6 f3 V' l! a! E" S mHeadingMode = WaypointMissionHeadingMode.USING_WAYPOINT_HEADING;5 K7 P. V3 m, P- g( Y) V, b
break;' c& b0 r& c: m" {& m! Q: e, N
case "4":; p4 J! U) C5 K% H( R
mHeadingMode = WaypointMissionHeadingMode.TOWARD_POINT_OF_INTEREST;; r% S; K& t- {6 W& |
break;
7 v' v4 a" v) T; p8 t; [ }3 K _$ J9 [, K- v1 o" N8 T: X
switch (c.getString(5)) {/ ^& H! X- {/ v: y" a0 H
case "0":
: D: v5 r0 Z. d7 I3 p& T mFinishedAction = WaypointMissionFinishedAction.NO_ACTION;
1 m2 \8 _4 L v/ D5 X5 r1 G( ?9 ] break;( Z/ b& o$ d3 { o
case "1":
$ U I$ h. u. k- g: C& d+ K; v; ]/ o mFinishedAction = WaypointMissionFinishedAction.GO_HOME;
k N6 b+ V# m" m$ } break;
7 K$ o, h; q$ J$ m' X case "2":
3 N, O; ~: B6 N) W mFinishedAction = WaypointMissionFinishedAction.AUTO_LAND;3 O1 V$ a% }2 ~" U! j
break;2 g% K8 h8 L! L3 E
case "3":5 q' L' c3 t* u6 \( j4 g
mFinishedAction = WaypointMissionFinishedAction.GO_FIRST_WAYPOINT;
" \( F6 _9 W& p1 ^0 j break;2 k9 V- t8 a( s# C& }8 ?1 Z- o
case "4":
; \5 q2 w1 Y" z1 F( @# `4 @ mFinishedAction = WaypointMissionFinishedAction.CONTINUE_UNTIL_END;' d- U% a/ S# q1 W8 \: e0 K
break;* K' Y( ]; S# d, x" F9 \3 A3 F
}
& {! t/ V/ C8 Z" ]' b0 \ }, [* R6 e: ^4 u" O* P# X% a8 \
}
& y8 j( j, N0 r2 y& S* z9 X# } for (int i = 0; i new LatLng(mPointInfo.get(i).getLatitude(), mPointInfo.get(i).getLongitude()));
9 z# |9 }9 A d Waypoint mWaypoint = new Waypoint(mPointInfo.get(i).getLatitude(), mPointInfo.get(i).getLongitude(), altitude);
+ G+ }. n3 ?8 |) v9 ^+ ]8 z# W7 Q if (waypointMissionBuilder != null) {! G* O8 @$ O5 a E# [3 I
waypointList.add(mWaypoint);! L) Q6 E1 s! Y6 @
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());. m) d1 u( A9 c' a5 @
} else {$ ]3 O/ y) J% q5 L' `
waypointMissionBuilder = new WaypointMission.Builder();
+ P& ~% @( k) c; I/ B+ f; G9 ]! I waypointList.add(mWaypoint);
# u+ ?. R$ F1 b R waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
; }6 @7 d' A/ C/ S }
' C; g9 I( z; m4 ? g: |4 b# t! E: ~ { }
I5 [' i# e! w- z; @& X( D; F# G2 X aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(mPointInfo.get(0).getLatitude(), mPointInfo.get(0).getLongitude()), 18, 0, 0)));! {* G' I' b% ]8 [: ~9 m
ResultconfigWayPointMission();
; Y' Q- ~: m) z2 F" q+ B& F getWaypointMissionOperator().uploadMission(new CommonCallbacks.CompletionCallback() {+ o( ]" `* Q* J# E" B
@Override: C: y: j- s+ j& E* g
public void onResult(DJIError djiError) {8 K1 D2 F; f/ ?7 @' M# t3 T
if (djiError == null) {
9 |6 k4 ^$ l! K+ M% r& P" m$ } showToasts("获取任务成功!");
0 Z8 X6 L- w# _3 _$ Q2 H% M }" H* N, S, w9 Q1 [
}0 b! _1 q. X9 j- ?* s b2 `
});: T$ w+ v- u, W# a( A: u9 [
}
. T) x2 V" {# n( R: N+ L private void showWaypoint(LatLng point) {
6 `1 k# G$ J3 x" f* E6 y MarkerOptions markerOptions = new MarkerOptions();
5 P+ Q! x: c+ @& Y4 {+ M$ B$ G* Q! Q markerOptions.position(point);4 F) {* k! r9 G
markerOptions.title("航点" + (mMarkers.size() + 1));
" {7 I0 B, \8 F markerOptions.snippet("事件:");
|9 J" v3 B) q6 G+ y+ a4 I markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));; H$ {" G F6 @5 I" e
markerOptions.infoWindowEnable(true);
2 Z& x+ b$ E7 Z) [- C Marker marker = aMap.addMarker(markerOptions);$ `( V- O* q& r" D/ R3 u
mMarkers.put(mMarkers.size(), marker);
3 A* r4 H* S% o- D0 T* @4 n. K marker.showInfoWindow();* y' u9 W- S5 x. p& h
if (mMarkers.size() > 0) {
! Y' Y* }/ }, M1 |8 | mLatLng.clear();8 a4 A& p. |- `0 p. m7 g1 h
PolylineOptions PolylineOptions = new PolylineOptions();) b3 ~; \8 t; d
for (int i = 0; i 10);
: o! z' g6 L) f PolylineOptions.color(Color.argb(255, 1, 1, 1));
8 q- A* G# N9 o2 e6 `+ G aMap.addPolyline(PolylineOptions); O8 p* g ?/ S1 z
}9 `! ~8 o. a5 p- x" T p
}1 T$ Y ^* a* n7 ]/ A
private void ResultconfigWayPointMission() {: D# Z% j# C4 e% y' \% R0 i
if (waypointMissionBuilder == null) {% N# E x( |2 I R( p- s' ] F
waypointMissionBuilder = new WaypointMission.Builder().finishedAction(mFinishedAction)
- s9 v3 J. g/ n" Z0 A" p/ l .headingMode(mHeadingMode). c }0 `/ k2 H y* Z/ W. M
.autoFlightSpeed(mSpeed)
6 \! R* \+ S! R2 J- o7 ^6 ` .maxFlightSpeed(mSpeed)
. J* e, }7 K6 o8 |+ Y .flightPathMode(WaypointMissionFlightPathMode.NORMAL);
2 K5 _) w' n; d% \' K( E8 ]# P } else {
3 E2 o e7 l% P$ g- r6 U. M) z% t waypointMissionBuilder.finishedAction(mFinishedAction)+ |7 u3 q5 {, e+ V: n$ U4 j
.headingMode(mHeadingMode)
2 i' @+ X! i. A" R+ `9 n4 d .autoFlightSpeed(mSpeed)! T" W* u4 K3 M: S
.maxFlightSpeed(mSpeed)) S7 }. i& `2 f; T" }3 s8 I- r
.flightPathMode(WaypointMissionFlightPathMode.NORMAL);7 d4 |! x+ K" |( Z! Y: k
}
& S$ ` i2 x$ H& C0 k6 k6 e if (waypointMissionBuilder.getWaypointList().size() > 0) {. h+ d8 a1 w3 z6 X: J+ j
for (int i = 0; i if (error == null) {
3 M* e$ m1 \- [ A* Z6 u if (mLinearLayoutInformation.getVisibility() == View.GONE) {
$ v- y; r. g. I$ B k( U mLinearLayoutInformation.setVisibility(View.VISIBLE);
5 Q1 C1 M2 f+ q2 q8 K }
/ B, S1 o6 K5 x4 Y3 |$ X3 H9 `% v% u mButtonStart.setVisibility(View.VISIBLE);
9 e, A S3 L! v0 o mButtonStop.setVisibility(View.VISIBLE); u5 \2 R3 ~6 {( C' a8 g
mTextViewHeight.setText("高度:" + altitude + "m");
! d9 o5 l, b& ~2 l' C. Z- t& ^3 e mTextViewSpeed.setText("速度:" + mSpeed + "m/s");
# G7 S1 K s' W2 u6 X! E9 A mTextViewCount.setText("航点数:" + waypointMissionBuilder.getWaypointCount());
# Z1 p$ N' D* p" t) t3 c mTextViewDistance.setText("总距离:" + Math.round(waypointMissionBuilder.calculateTotalDistance()) + "m");/ {: y" H4 `" @8 d; `" p: [( O- e
mTextViewTime.setText("总时间:" + Math.round(waypointMissionBuilder.calculateTotalTime()) + "min");
0 [$ S# j6 a) W& `# m4 b }$ A$ [+ u* ]% o& ~" Y
}
: D+ ~$ ]: y, z+ e# L private void addSampleMarker() {$ C, W5 Y% K, g8 L4 y$ K9 p1 e: C+ q
if (ReadKml.addSampleSuccess) {
. v/ N1 a1 m/ d# \7 U" _- u. b aMap.clear();6 B5 K- A" p; Y7 n- o7 J+ O
mMarkers.clear();/ O$ d, n- w/ _. `
mPointInfo.clear();! O7 {# }4 ?. u) v; D1 j& f% [! E% r- t
waypointList.clear();
" Q/ V! ^; {4 G9 q if (mLinearLayoutInformation.getVisibility() == View.VISIBLE) {
T9 y5 v# v5 W# A mLinearLayoutInformation.setVisibility(View.GONE);
3 j# k; k0 \$ w* b; Y }: j0 J- o1 O- p/ M: r8 z
mButtonFinish.setVisibility(View.GONE);
! _2 B V. n' |$ D( z* S mButtonSetting.setVisibility(View.GONE);
% Z! ]4 E! o9 C- S mButtonUpload.setVisibility(View.GONE);9 E- O; n f& H! p* E
mButtonStart.setVisibility(View.GONE);
8 B) b! D' e/ o4 ` mButtonStop.setVisibility(View.GONE);
3 B* h/ V/ |- ^( O- H8 u for (int i = 0; i new LatLng(sampleList.get(i).getX(), sampleList.get(i).getY()));( L; Z0 R8 n c
Waypoint mWaypoint = new Waypoint(sampleList.get(i).getX(), sampleList.get(i).getY(), altitude);. W9 R/ y" h, s. A4 h
//Add Waypoints to Waypoint arraylist;" P8 i. w, |* l$ u. \
if (waypointMissionBuilder != null) {
. d$ u* [" E1 l' M waypointList.add(mWaypoint);
5 t) f& r" o% u- Z2 l* ~ waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
; O% d. M1 _' q( D1 ~ } else {: C0 Q$ V" h: s# Q3 |" }
waypointMissionBuilder = new WaypointMission.Builder();. j6 e2 p: u* T6 p$ X# a
waypointList.add(mWaypoint);( F& o2 k, P4 g6 @& e. a& w/ @
waypointMissionBuilder.waypointList(waypointList).waypointCount(waypointList.size());
3 b, T4 L( T8 [4 C }. R: M& p6 A9 R V! r: }
}/ |8 x- I; c8 v X) j5 c, K
aMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(sampleList.get(0).getX(), sampleList.get(0).getY()), 18, 0, 0)));- t3 a: m& c( [; a
showSettingDialog();( ?. L. f/ _; E. a
mButtonSetting.setVisibility(View.VISIBLE);
) Z0 p& [* \; S- y mButtonUpload.setVisibility(View.VISIBLE);
' W; Y/ G! l4 b } else {7 }0 j/ }" O8 C
Log.d("MainActivity", "addSampleSuccess is false or aMap is null");
7 Y! n" V7 ?+ W2 o- S. y" W }
/ j" _! b$ j: ^/ n! L, j" h }$ X& Y- s1 n3 o/ W
- ~. i5 `) {% W; I8 P0 J# b( R" R
3
7 X; E) g1 }8 W. l航线管理8 \' r# ?: m1 f6 o; H
创建activity_waypoint.xml和WaypointActivity文件。
0 @8 D: l' H1 D8 I: O1 \5 A, h
3 J) O. u0 \" O5 g: t# M/ U _activity_waypoint.xml
v) q; p: ?& t
2 t8 k! [0 U1 ]; QLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
( X: o8 \+ ]9 M# O% @+ r xmlns:app="http://schemas.android.com/apk/res-auto"5 `) B% F6 c4 u. w) [; j) p) L% k5 z
xmlns:tools="http://schemas.android.com/tools"" k$ [$ D2 u$ i& d. e7 `; G, _
android:layout_width="match_parent"+ X1 \2 ]3 O: s
android:layout_height="match_parent", D% Z* z' r9 S
tools:context=".ui.WaypointActivity"0 A2 S4 D- ~, Y. R. y; t# c
android:orientation="vertical"+ X( b E+ J: @$ i4 ~# Y, y
android:background="@drawable/shape_corner_eight">
8 H' ?% m- Z' y2 R include
4 x6 Q- m) l6 f v2 z+ c8 b8 X android:id="@+id/layout_waypoint"5 e/ }3 a% M( r
layout="@layout/activity_toolbar">include>& B8 w) l) n _$ e$ g" c/ I7 O
View
1 f6 f+ d5 C g- t ^7 H6 w6 h l/ N% z android:layout_width="match_parent"
& C# F- O, P X8 G9 { android:layout_height="1dp"
# h/ G3 {+ S: ]1 o$ u0 ]7 j* P android:background="#5B6782"# n0 T# U& o3 M7 g e" z" V
android:layout_marginTop="1dp"* Y) t( R1 l9 a X! a3 u `5 ^
android:layout_marginRight="20dp", w8 @! [/ I2 r! y: I
android:layout_marginLeft="20dp". t) i% a7 i( V$ m+ \
>View>
9 [% w$ u. c) ?6 l4 q& ^4 r androidx.recyclerview.widget.RecyclerView3 t0 C: E, z; G! L% s
android:id="@+id/rv_waypoint"
N d: P- o) U9 u android:layout_width="match_parent"
5 c; V' @& i2 W. P android:layout_height="match_parent"
% G/ G/ w( {. v# o! c android:layout_marginRight="20dp"
7 o9 }$ I, v }) j1 P android:layout_marginLeft="20dp">androidx.recyclerview.widget.RecyclerView>+ M0 x& L- o; N& ?
LinearLayout>; L; I; g9 ]( U+ G+ a; K3 m3 w: F
WaypointActivity
& S. J8 P9 `$ Q' g$ X& }
7 ]- `4 q" L c3 n2 \0 f@Layout(R.layout.activity_waypoint)) d$ }& ]2 E* g
public class WaypointActivity extends BaseActivity implements View.OnClickListener {( I/ `% h1 ]4 G7 S1 M+ f
@BindView(R.id.layout_waypoint)- b3 _9 q9 l f% n
View mViewLayoutToolbar;
( S3 \2 Y: R% g5 a+ e1 G @BindView(R.id.ll_waypoint)1 n6 b) g; \0 S' i; F0 f2 L
LinearLayout mLinearLayout;; i( U7 ^* ~0 K) `
@BindView(R.id.tv_toolbar_title)
1 Z4 y0 A: J+ M TextView mTextViewToolbarTitle;
2 {3 V" b5 y5 s) W9 j9 X2 c* U @BindView(R.id.rv_waypoint)
3 b, L) J+ r! k6 ~1 h) @9 Z3 y RecyclerView mRecyclerView;3 t! B7 ~( _# |
private SQLiteHelper mSQLiteHelper;% t$ Q* ^( G' E8 @6 o
private List mWaypointInfo = new ArrayList();9 r/ K) j3 V0 ^" ~( }. l2 E
private WaypointAdapter mWaypointAdapter;
$ w+ x5 d: g4 Y" M: P$ G private List[I] mWaypointId = new ArrayList();% e" W9 c6 g7 b/ V% ]4 X; C0 {
private String StrId = "";, d1 K0 i$ t" f2 k# x3 E9 g# @
@Override5 K/ ]7 q, W- R7 E" ^
public void initViews() {
7 _ O7 H/ k0 K% ], H& J3 \ mLinearLayout.setVisibility(View.VISIBLE);3 f" w) K4 n8 g
mTextViewToolbarTitle.setText("航线管理");
; d: A: x8 z7 i6 p8 Y MyStatic.isChoose = false;
+ ^6 a6 V9 X) l8 W1 S6 Z. k0 D( Z }5 F a4 k- Y2 U
@Override- _. o" u* h6 u1 H2 J5 x
public void initDatas() {
# r S7 E# P7 [3 I! ~& ], x9 s mSQLiteHelper = new SQLiteHelper(WaypointActivity.this);0 C( N- e; i/ Y: W9 N; b
Cursor c = mSQLiteHelper.doSelect();4 v, j6 Y0 `" M, |8 _
if (c!=null){
9 K; b1 }: J) O' M5 B3 t' I while (c.moveToNext()){2 d8 v) x! n8 G6 Q$ d
mWaypointInfo.add(new WaypointInfo(c.getInt(0),c.getString(1),c.getFloat(2),c.getFloat(3),
! I* o$ E$ b8 x& m8 N( n c.getString(4),c.getString(5),c.getString(6),c.getInt(7),c.getInt(8),5 q9 B0 L/ Y, q4 k9 V9 f
c.getInt(9),c.getString(10)));' L5 G5 ]: A2 l! B r6 `. ?- _: T
}
$ `5 X0 F3 x4 ~4 t3 V }
; n0 ]4 K" T) f: S c.close();
& D) `* Z4 q6 u mSQLiteHelper.close();
- p& u/ I) x# N% l mWaypointAdapter = new WaypointAdapter(R.layout.item_waypoint);
3 v1 o. c0 Y8 b" p mWaypointAdapter.setNewData(mWaypointInfo);
3 L3 _1 h% F: K _% W initRv(mRecyclerView,mWaypointAdapter);
1 j+ L- ^4 i5 W' l! x- v0 n7 a% [ mWaypointAdapter.setOnItemchildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {4 L% j% }( b( f/ ^ Z1 P
@Override5 Z! D. i) ?1 b
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {7 C5 U h' p' c3 ]; G
Intent intent = new Intent();
$ z2 E0 v* j& Y. e w6 k" B intent.putExtra("id", mWaypointInfo.get(position).getId());9 m5 p* {9 o ]( [
setResult(RESULT_OK, intent);% l( L: B* Q% G( [, f) E
finish();
. @ D5 X: T* F" P# v' X }
+ I+ I- U* C# V% J$ p! \7 r });; O5 j, n, |/ I8 M6 b
mWaypointAdapter.setOnCheckboxCheckedListener(new WaypointAdapter.OnCheckboxCheckedListener() {
9 m; u, K; C9 `. ?1 j @Override
# o" h4 z* c: c, M+ @. P public void OnCheckboxChecked(boolean isCheck, int position) {2 W4 N, @4 m& U1 \! \
if (isCheck){5 S, i7 a$ E% U! B/ H
mWaypointId.add(position);* _3 {9 K! N. v) G! O) _/ E; H
}else {
: e& T8 B) Z1 T8 T+ W if (mWaypointId.contains(position)){ E, O% T+ l c9 `# v
mWaypointId.remove(position);1 d$ v9 |% Y5 c+ t" {! P3 J
}
: X/ x) `7 J4 e3 m( [) K }6 t, J! ]$ d3 e
}
/ T k0 Z5 ]+ g/ i: v% M! W });
$ g# ?, @5 A2 g/ p9 M8 { }
" I& M6 m& ]" j# t; _ @Override$ B) k1 l5 u/ x" a
protected void requestData() {
9 A. L$ R8 H. |+ r( i }3 D# j+ o* h+ U) e! X
@OnClick({R.id.img_way_choose,R.id.img_way_delete,R.id.img_back})4 a( X' t+ O" O& Q ^9 e
@Override
; a6 p% v0 u+ [/ E1 g public void onClick(View v) {0 j, N: ~; |2 Z# X% c$ f H6 p) N
switch (v.getId()){# P% E7 k! D8 d/ S9 [
case R.id.img_way_choose:
6 M2 x% y# @5 r: }) J6 j `$ ` if (MyStatic.isChoose){1 {/ C7 I6 S2 i: `2 N9 [
MyStatic.isChoose = false;
1 e% e0 H0 _# U }else {
; h8 m2 A' f: j MyStatic.isChoose = true; T8 f! [, p0 ]# L% r' k
}; |3 A2 |- K- d$ Y% ?
if (mWaypointAdapter!=null){! H/ ?- o* k. G' ~1 a! B
mWaypointAdapter.notifyDataSetChanged();
; K( G: z* g% X2 q6 W% x }
: v9 L1 r. m) |6 ] break;# {# j# j9 ?) h. }( m8 z
case R.id.img_way_delete:7 _& f( R) F; R7 b, @
if (mWaypointId.size() > 0){
' H& u- d" W- W @" @ for (int i = 0; i ",";& p! ^2 Q6 k" j/ G2 p1 ]
}
: f2 \5 C4 t8 J; @) W) x+ @ if (!TextUtils.isEmpty(StrId)){
+ s! ^) p& f! z. w. G: ]5 c StrId = StrId.substring(0,StrId.length()-1);
- R4 f( q2 y) G, f" p mSQLiteHelper = new SQLiteHelper(WaypointActivity.this);& E. D8 ~: m5 b( k$ P$ A. V
mSQLiteHelper.doDelete(StrId);
( I9 Q# j) d' R, T# } mSQLiteHelper.close();
9 K$ v! |+ `! i3 y2 ^ ^ for (int j = 0; j if (mWaypointAdapter!=null){: I, W- Q1 u/ N7 B4 A
mWaypointId.clear();
, c( Q* b! g+ {4 i5 [/ h MyStatic.isChoose = false;
# S/ u9 g n* t" c. _ N mWaypointAdapter.setNewData(mWaypointInfo);
; y$ V+ x" l; D$ Y- a: G }
+ l% e- I- g9 u Q, k& h! Q6 S }% f2 t( v( k8 ~7 N
}else {, o3 ~8 }- z0 M' r
showToasts("请先选择删除的航线!");% }- I3 M, Q4 m0 J
}
* T5 R1 D9 ^) h0 U0 ~7 J, t7 d break;
1 R/ E" @& ~ J& V. x- A$ w case R.id.img_back:7 O3 {% H4 M% ~% d6 K" l
Intent intent = new Intent();8 F( M% ^; u5 p3 N% U# N
intent.putExtra("id", -1);
6 u. h, e) v$ c2 z3 U1 G0 O6 ` setResult(RESULT_OK, intent);
. n* y4 @! }+ Q' ?! t/ @9 c9 ` finish();5 N" `9 k" G5 M
break;
3 z2 h; \4 z* s: i" G; H$ r }
+ f& b& L" \: l% j* ^ }
; A5 L$ k4 K+ \以上代码仅供参考,如果想了解更多的大疆无人机二次开发过程可以私信我,源代码因为涉及到商业使用不能给大家共享,有什么问题我可以帮你解决。# k, `) T0 `8 \- w8 a) j! ^
i3rsowcj2fd64023080754.png
) b9 Z7 E/ H1 K; X7 u7 b
往期推荐毕业设计So Easy:基于C++实现网络扫描器 U u X' s0 k4 o
详解CAN总线:CAN节点硬件构成方案
( e6 e- D$ v& R5 dLabVIEW串口通信
% p3 e& [$ Z1 Q3 s5 YLabVIEW感兴趣区域分析(实战篇—1)
, i: h5 c( u* D$ e/ \Python Qt GUI设计:信号与槽的使用方法(基础篇—7)* M$ ^9 m( u- A* h
和12岁小同志搞创客开发:如何使用继电器?
/ P- U1 Y! R! M( a' f7 `# sPCB天线无线模组如何布局摆放?' U* R9 I1 n) _( L9 \2 m
芯片内部长啥样?牛人用1500张照片,一层一层放给你看!
& E" w- @, f: m! Q8 i4 a7 x移柯L620模组使用MQTT协议连接移动OneNet云平台) x9 q7 ^" M* R
" N. G6 w% ?. M/ S6 m; Y) `
osqlvujdnmp64023080854.jpg
, X7 g; d1 ~) b! U: M( p
0c5axrrvgz264023080954.gif
7 S6 E) X" b- C* ?" l, a" R
点击阅读原文,更精彩~ |
|