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