|

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