說明:
最近碰到一個需求,需要在高德地圖上選擇航點,然後連線,最後形成一個路線圖,把點的信息,用json文件的格式存儲起來
效果圖:
1.先集成高德地圖 app目錄下的builder文件,直接添加高德地圖的引用
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:26.0.0-alpha1'
testImplementation 'junit:junit:4.12'
//3d地圖 和導航
implementation 'com.amap.api:navi-3dmap:latest.integration'
//定位
implementation 'com.amap.api:location:latest.integration'
//搜索
implementation 'com.amap.api:search:latest.integration'
}
2.源碼下載地址:https://github.com/wrs13634194612/MapDrawLine
3.清單文件:注意就是申請一下權限,然後添加高德的appkey,需要自己去官網申請,如何申請,請看我上篇博客,然後再添加高德的定位服務,就可以了
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.administrator.testz">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--聲明後臺定位權限-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="f0c2f455c7c34a768eb0d2" />
<!-- 定位需要的服務 使用2.0的定位需要加上這個 -->
<service android:name="com.amap.api.location.APSService"/>
<activity android:name="com.amap.api.maps.offlinemap.OfflineMapActivity"
android:screenOrientation="portrait" />
</application>
</manifest>
4.主界面:
package com.example.administrator.testz;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMap.OnCameraChangeListener;
import com.amap.api.maps.AMap.OnMapClickListener;
import com.amap.api.maps.AMap.OnMapLongClickListener;
import com.amap.api.maps.AMap.OnMapTouchListener;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.maps.model.VisibleRegion;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.Polyline;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by wrs on 22/11/2019,上午 10:59
* projectName: MapWay
* packageName: task.pdioms.ufi.com.mapway
*/
public class MainActivity extends FragmentActivity implements View.OnClickListener, OnMapClickListener {
private MapView mapView;
private AMap aMap;
private double droneLocationLat = 181, droneLocationLng = 181;
private boolean isAdd = false;
private final Map<Integer, Marker> mMarkers = new ConcurrentHashMap<Integer, Marker>();
private Marker droneMarker = null;
private Button locate, add, clear;
private Polyline polyline;
ArrayList<LatLng> latLngList = new ArrayList<LatLng>();
LatLng[] latLngs_cross_minus_180 = {
new LatLng(36.777358, 117.114289, false),
new LatLng(34.859492, 113.582008, false),
new LatLng(31.990562, 117.115108, false)
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.map);
locate = (Button) findViewById(R.id.locate);
add = (Button) findViewById(R.id.add);
clear = (Button) findViewById(R.id.clear);
locate.setOnClickListener(this);
add.setOnClickListener(this);
clear.setOnClickListener(this);
mapView.onCreate(savedInstanceState);
initMapView();
//跨越180°的線
addBeyond180Polylines();
}
private void addBeyond180Polylines() {
/* latLngList.clear();
for (LatLng latLng : latLngs_cross_minus_180) {
latLngList.add(latLng);
}
aMap.addPolyline((new PolylineOptions())
.addAll(latLngList)
.width(5)
.setDottedLine(false)
.color(Color.RED)
);*/
}
private void initMapView() {
if (aMap == null) {
aMap = mapView.getMap();
aMap.setOnMapClickListener(this);// add the listener for click for amap object
}
// LatLng shenzhen = new LatLng(22.5362, 113.9454);
LatLng shenzhen = new LatLng(30.2781, 120.1238);
aMap.addMarker(new MarkerOptions().position(shenzhen).title("Marker in Shenzhen"));
aMap.moveCamera(CameraUpdateFactory.newLatLng(shenzhen));
}
@Override
public void onMapClick(final LatLng point) {
if (isAdd == true) {
Log.e("TAG", "onMapClick:" + point);
markWaypoint(point);
// latLngList.clear();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
latLngList.add(point);
Log.e("TAG", "start_thread: " + latLngList.toString());
aMap.addPolyline((new PolylineOptions())
.addAll(latLngList)
.width(10)
.setDottedLine(false)
.color(Color.BLACK)
);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
} else {
setResultToToast("Cannot Add Waypoint");
}
}
// Update the drone location based on states from MCU.
private void updateDroneLocation() {
LatLng pos = new LatLng(droneLocationLat, droneLocationLng);
//Create MarkerOptions object
final MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(pos);
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.smile_face_check));
runOnUiThread(new Runnable() {
@Override
public void run() {
if (droneMarker != null) {
droneMarker.remove();
}
if (checkGpsCoordination(droneLocationLat, droneLocationLng)) {
droneMarker = aMap.addMarker(markerOptions);
}
}
});
}
private void cameraUpdate() {
LatLng pos = new LatLng(droneLocationLat, droneLocationLng);
float zoomlevel = (float) 18.0;
CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(pos, zoomlevel);
aMap.moveCamera(cu);
}
public static boolean checkGpsCoordination(double latitude, double longitude) {
return (latitude > -90 && latitude < 90 && longitude > -180 && longitude < 180) && (latitude != 0f && longitude != 0f);
}
private void setResultToToast(final String string) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, string, Toast.LENGTH_SHORT).show();
}
});
}
private void markWaypoint(LatLng point) {
//Create MarkerOptions object
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(point);
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.rb_news_normal));
//markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
Marker marker = aMap.addMarker(markerOptions);
mMarkers.put(mMarkers.size(), marker);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.locate: {
updateDroneLocation();
cameraUpdate(); // Locate the drone's place
break;
}
case R.id.add: {
enableDisableAdd();
break;
}
case R.id.clear: {
runOnUiThread(new Runnable() {
@Override
public void run() {
aMap.clear();
latLngList.clear();
}
});
updateDroneLocation();
break;
}
}
}
private void enableDisableAdd() {
if (isAdd == false) {
isAdd = true;
add.setText("Exit");
} else {
isAdd = false;
add.setText("Add");
}
}
}
5.佈局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/locate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Locate"
android:layout_weight="1"/>
<Button
android:id="@+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add"
android:layout_weight="1"/>
<Button
android:id="@+id/clear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear"
android:layout_weight="1"/>
</LinearLayout>
<com.amap.api.maps.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
6.代碼說明,核心代碼說一下吧
6.1監聽地圖,點擊的標記點的經緯度,設置marker
監聽方法是:
implements OnMapClickListener
重寫方法,具體的監聽內容在如下方法:
public void onMapClick(final LatLng point) {}
然後就是對監聽到的點,進行添加marker操作:
private void markWaypoint(LatLng point) {
//Create MarkerOptions object
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(point);
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.rb_news_normal));
//markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
Marker marker = aMap.addMarker(markerOptions);
mMarkers.put(mMarkers.size(), marker);
}
6.2 把剛纔點擊的點,用一個list集合存起來,然後,用線條把這些點連接起來就可以了,這裏用了一個線程
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
latLngList.add(point);
Log.e("TAG", "start_thread: " + latLngList.toString());
aMap.addPolyline((new PolylineOptions())
.addAll(latLngList)
.width(10)
.setDottedLine(false)
.color(Color.BLACK)
);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
end