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