由于大疆所给予的最新示例代码(uxsdk)中只包括mapbox以及谷歌地图,导致国内无法正常使用,所以需要进行集成,且由于大疆官方给出的集成示例代码为MSDK5.9,比较落后,所以需要使用最新代码进行地图集成。
第一步下载示例代码:

下载后进行解压:

第二步打开并运行示例代码:
用Android studio打开其中的Android_sdk_v5_as,sample和uxsdk均已集成进as中

测试并运行示例代码:

第三步添加高德地图相关库和配置:
在uxsdk的gradle中添加高德地图相关依赖:

在dependence中添加高德地图相关库

第四步添加高德地图相关代码:

package dji.v5.ux.mapkit.amap.annotations;
import androidx.annotation.ColorInt;
import com.amap.api.maps.model.Circle;
import com.amap.api.maps.model.LatLng;
import dji.v5.ux.mapkit.amap.utils.AMapUtils;
import dji.v5.ux.mapkit.core.models.DJILatLng;
import dji.v5.ux.mapkit.core.models.annotations.DJICircle;
/**
* Created by joeyang on 6/12/17.
*/
public class ACircle implements DJICircle {
private Circle mCircle;
public ACircle(Circle circle) {
mCircle = circle;
}
@Override
public void remove() {
mCircle.remove();
}
@Override
public void setVisible(boolean visible) {
mCircle.setVisible(visible);
}
@Override
public boolean isVisible() {
return mCircle.isVisible();
}
@Override
public void setCenter(DJILatLng center) {
mCircle.setCenter(AMapUtils.fromDJILatLng(center));
}
@Override
public DJILatLng getCenter() {
LatLng center = mCircle.getCenter();
return AMapUtils.fromLatLng(center);
}
@Override
public void setRadius(double radius) {
mCircle.setRadius(radius);
}
@Override
public double getRadius() {
return mCircle.getRadius();
}
@Override
public void setFillColor(@ColorInt int color) {
mCircle.setFillColor(color);
}
@Override
public int getFillColor() {
return mCircle.getFillColor();
}
@Override
public void setStrokeColor(@ColorInt int color) {
mCircle.setStrokeColor(color);
}
@Override
public int getStrokeColor() {
return mCircle.getStrokeColor();
}
@Override
public void setZIndex(float zIndex) {
mCircle.setZIndex(zIndex);
}
@Override
public float getZIndex() {
return mCircle.getZIndex();
}
@Override
public void setCircle(DJILatLng center, Double radius) {
mCircle.setCenter(AMapUtils.fromDJILatLng(center));
mCircle.setRadius(radius);
}
@Override
public void setStrokeWidth(float strokeWidth) {
mCircle.setStrokeWidth(strokeWidth);
}
@Override
public float getStrokeWidth() {
return mCircle.getStrokeWidth();
}
}
package dji.v5.ux.mapkit.amap.annotations;
import com.amap.api.maps.model.Circle;
import java.util.List;
import dji.v5.ux.mapkit.core.models.DJILatLng;
import dji.v5.ux.mapkit.core.models.annotations.DJIGroupCircle;
import dji.v5.ux.mapkit.core.models.annotations.DJIGroupCircleOptions;
/**
* Created by dickensdai 10/9/18
* 高德地图的groupCircle代理类
*/
public class AGroupCircle implements DJIGroupCircle {
/**
* 用一个list来保存所有添加的circle
*/
private List<Circle> circles;
public AGroupCircle(List<Circle> circles) {
this.circles = circles;
}
@Override
public void remove() {
for (Circle circle : circles) {
circle.remove();
}
}
@Override
public void setVisible(boolean visible) {
for (Circle circle : circles) {
circle.setVisible(visible);
}
}
@Override
public boolean isVisible() {
return circles.get(0).isVisible();
}
@Override
public void setZIndex(float zIndex) {
for (Circle circle : circles) {
circle.setZIndex(zIndex);
}
}
@Override
public float getZIndex() {
return circles.get(0).getZIndex();
}
@Override
public void setFillColor(int color) {
for (Circle circle : circles) {
circle.remove();
}
}
@Override
public void setStrokeColor(int color) {
for (Circle circle : circles) {
circle.setStrokeColor(color);
}
}
@Override
public void setCircles(List<DJILatLng> centers, List<Double> radius) {
return;
}
@Override
public DJIGroupCircleOptions getOptions() {
return null;
}
}
package dji.v5.ux.mapkit.amap.annotations;
import com.amap.api.maps.model.Marker;
import dji.v5.ux.mapkit.amap.map.AMapDelegate;
import dji.v5.ux.mapkit.amap.utils.AMapUtils;
import dji.v5.ux.mapkit.core.models.DJIBitmapDescriptor;
import dji.v5.ux.mapkit.core.models.DJILatLng;
import dji.v5.ux.mapkit.core.models.annotations.DJIMarker;
/**
* Created by joeyang on 5/30/17.
*/
public class AMarker extends DJIMarker {
private Marker mMarker;
private AMapDelegate aMap;
public AMarker(Marker marker, AMapDelegate aMap) {
this.mMarker = marker;
this.aMap = aMap;
}
@Override
public void setPosition(DJILatLng latLng) {
setPositionCache(latLng);
mMarker.setPosition(AMapUtils.fromDJILatLng(latLng));
}
/**
* 设置水平旋转角度
* @param rotate 旋转角度,顺时针为正;高德地图以逆时针为正,所以实现中要取负
*/
@Override
public void setRotation(float rotate) {
setRotationCache(–rotate);
mMarker.setRotateAngle(–rotate);
}
@Override
public void setIcon(DJIBitmapDescriptor icon) {
mMarker.setIcon(AMapUtils.fromDJIBitmapDescriptor(icon));
}
@Override
public void setAnchor(float u, float v) {
mMarker.setAnchor(u, v);
}
@Override
public void setTitle(String title) {
mMarker.setTitle(title);
}
@Override
public void setVisible(boolean visible) {
mMarker.setVisible(visible);
}
@Override
public String getTitle() {
return mMarker.getTitle();
}
@Override
public boolean isVisible() {
return mMarker.isVisible();
}
@Override
public void showInfoWindow() {
mMarker.showInfoWindow();
}
@Override
public void hideInfoWindow() {
mMarker.hideInfoWindow();
}
@Override
public boolean isInfoWindowShown() {
return mMarker.isInfoWindowShown();
}
@Override
public void remove() {
mMarker.remove();
aMap.onMarkerRemove(mMarker);
}
@Override
public void setDraggable(boolean b) {
mMarker.setDraggable(b);
}
@Override
public boolean isDraggable() {
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AMarker aMarker = (AMarker) o;
return mMarker != null ? mMarker.equals(aMarker.mMarker) : aMarker.mMarker == null;
}
@Override
public int hashCode() {
return mMarker != null ? mMarker.hashCode() : 0;
}
}
package dji.v5.ux.mapkit.amap.annotations;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Polygon;
import java.util.ArrayList;
import java.util.List;
import dji.v5.ux.mapkit.amap.utils.AMapUtils;
import dji.v5.ux.mapkit.core.models.DJILatLng;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolygon;
/**
* Created by joeyang on 6/16/17.
*/
public class APolygon implements DJIPolygon {
private Polygon mPolygon;
public APolygon(@NonNull Polygon mPolygon) {
this.mPolygon = mPolygon;
}
@Override
public void remove() {
mPolygon.remove();
}
@Override
public boolean isVisible() {
return mPolygon.isVisible();
}
@Override
public void setVisible(boolean visible) {
mPolygon.setVisible(visible);
}
@Override
public void setPoints(List<DJILatLng> points) {
List<LatLng> aPoints = new ArrayList<>(points.size());
for (DJILatLng latLng : points) {
aPoints.add(AMapUtils.fromDJILatLng(latLng));
}
mPolygon.setPoints(aPoints);
}
@Override
public List<DJILatLng> getPoints() {
List<DJILatLng> djiPoints = new ArrayList<>(mPolygon.getPoints().size());
for (LatLng latLng : mPolygon.getPoints()) {
djiPoints.add(AMapUtils.fromLatLng(latLng));
}
return djiPoints;
}
@Override
public void setFillColor(@ColorInt int color) {
mPolygon.setFillColor(color);
}
@Override
public int getFillColor() {
return mPolygon.getFillColor();
}
@Override
public void setStrokeColor(@ColorInt int color) {
mPolygon.setStrokeColor(color);
}
@Override
public int getStrokeColor() {
return mPolygon.getStrokeColor();
}
@Override
public void setStrokeWidth(float strokeWidth) {
mPolygon.setStrokeWidth(strokeWidth);
}
@Override
public float getStrokeWidth() {
return mPolygon.getStrokeWidth();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
APolygon aPolygon = (APolygon) o;
return mPolygon.equals(aPolygon.mPolygon);
}
@Override
public int hashCode() {
return mPolygon.hashCode();
}
}
package dji.v5.ux.mapkit.amap.annotations;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Polyline;
import java.util.ArrayList;
import java.util.List;
import dji.v5.ux.mapkit.amap.utils.AMapUtils;
import dji.v5.ux.mapkit.core.models.DJILatLng;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolyline;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolylineOptions;
/**
* Created by joeyang on 6/11/17.
*/
public class APolyline implements DJIPolyline {
private Polyline mPolyline;
private DJIPolylineOptions mDJIPolylineOptions;
public APolyline(@NonNull Polyline polyline) {
this.mPolyline = polyline;
}
public APolyline(Polyline polyline, DJIPolylineOptions options) {
mPolyline = polyline;
mDJIPolylineOptions = options;
}
@Override
public void remove() {
mPolyline.remove();
}
@Override
public void setWidth(float width) {
mPolyline.setWidth(width);
}
@Override
public float getWidth() {
return mPolyline.getWidth();
}
@Override
public void setPoints(List<DJILatLng> points) {
List<LatLng> aPoints = new ArrayList<>(points.size());
for (DJILatLng latLng : points) {
aPoints.add(AMapUtils.fromDJILatLng(latLng));
}
mPolyline.setPoints(aPoints);
}
@Override
public List<DJILatLng> getPoints() {
List<DJILatLng> djiPoints = new ArrayList<>(mPolyline.getPoints().size());
for (LatLng latLng : mPolyline.getPoints()) {
djiPoints.add(AMapUtils.fromLatLng(latLng));
}
return djiPoints;
}
@Override
public void setZIndex(float zIndex) {
mPolyline.setZIndex(zIndex);
}
@Override
public float getZIndex() {
return mPolyline.getZIndex();
}
@Override
public void setColor(@ColorInt int color) {
mPolyline.setColor(color);
}
@ColorInt
@Override
public int getColor() {
return mPolyline.getColor();
}
public DJIPolylineOptions getOptions() {
return mDJIPolylineOptions;
}
public void setOptions(DJIPolylineOptions options) {
mDJIPolylineOptions = options;
mPolyline.setOptions(AMapUtils.fromDJIPolylineOptions(options));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
APolyline aPolyline = (APolyline) o;
return mPolyline.equals(aPolyline.mPolyline);
}
@Override
public int hashCode() {
return mPolyline.hashCode();
}
}
package dji.v5.ux.mapkit.amap.map;
import android.graphics.Bitmap;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.Circle;
import com.amap.api.maps.model.CircleOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polygon;
import com.amap.api.maps.model.Polyline;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import dji.v5.ux.mapkit.amap.annotations.ACircle;
import dji.v5.ux.mapkit.amap.annotations.AGroupCircle;
import dji.v5.ux.mapkit.amap.annotations.AMarker;
import dji.v5.ux.mapkit.amap.annotations.APolygon;
import dji.v5.ux.mapkit.amap.annotations.APolyline;
import dji.v5.ux.mapkit.amap.utils.AMapUtils;
import dji.v5.ux.mapkit.core.callback.MapScreenShotListener;
import dji.v5.ux.mapkit.core.callback.OnMapTypeLoadedListener;
import dji.v5.ux.mapkit.core.camera.DJICameraUpdate;
import dji.v5.ux.mapkit.core.maps.DJIBaseMap;
import dji.v5.ux.mapkit.core.maps.DJIMap;
import dji.v5.ux.mapkit.core.maps.DJIProjection;
import dji.v5.ux.mapkit.core.maps.DJIUiSettings;
import dji.v5.ux.mapkit.core.models.DJIBitmapDescriptor;
import dji.v5.ux.mapkit.core.models.DJICameraPosition;
import dji.v5.ux.mapkit.core.models.DJILatLng;
import dji.v5.ux.mapkit.core.models.annotations.DJICircle;
import dji.v5.ux.mapkit.core.models.annotations.DJICircleOptions;
import dji.v5.ux.mapkit.core.models.annotations.DJIGroupCircle;
import dji.v5.ux.mapkit.core.models.annotations.DJIGroupCircleOptions;
import dji.v5.ux.mapkit.core.models.annotations.DJIMarker;
import dji.v5.ux.mapkit.core.models.annotations.DJIMarkerOptions;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolygon;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolygonOptions;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolyline;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolylineOptions;
/**
* Created by joeyang on 5/29/17.
* 高德地图的代理类
*/
public class AMapDelegate extends DJIBaseMap implements AMap.OnMarkerClickListener,
AMap.OnMapClickListener,
AMap.OnInfoWindowClickListener,
AMap.OnMarkerDragListener,
AMap.OnMapLongClickListener, AMap.OnCameraChangeListener {
// private static final String TAG = AMapDelegate.class.getSimpleName();
private AMap mMap;
private Map<Marker, AMarker> markerMap;
public AMapDelegate(AMap map) {
mMap = map;
mMap.setOnMarkerClickListener(this);
mMap.setOnMapClickListener(this);
mMap.setOnInfoWindowClickListener(this);
mMap.setOnCameraChangeListener(this);
mMap.setOnMarkerDragListener(this);
markerMap = new HashMap<>();
}
@NonNull
@Override
public DJIMarker addMarker(DJIMarkerOptions markerOptions) {
DJILatLng latLng = markerOptions.getPosition();
if (latLng == null) {
throw new IllegalArgumentException("DJIMarkerOptions parameter must have position set");
}
MarkerOptions options = new MarkerOptions();
DJILatLng position = markerOptions.getPosition();
DJIBitmapDescriptor icon = markerOptions.getIcon();
options.draggable(markerOptions.getDraggable())
.position(AMapUtils.fromDJILatLng(position))
.anchor(markerOptions.getAnchorU(), markerOptions.getAnchorV())
.rotateAngle(–markerOptions.getRotation())
.zIndex(markerOptions.getZIndex())
.visible(markerOptions.getVisible())
.title(markerOptions.getTitle())
.infoWindowEnable(markerOptions.isInfoWindowEnable())
.setFlat(markerOptions.isFlat());
if (icon != null) {
options.icon(AMapUtils.fromDJIBitmapDescriptor(icon));
}
Marker marker = mMap.addMarker(options);
AMarker aMarker = new AMarker(marker, this);
aMarker.setPositionCache(markerOptions.getPosition());
markerMap.put(marker, aMarker);
return aMarker;
}
@Override
public Object getMap() {
return mMap;
}
@Override
public DJICameraPosition getCameraPosition() {
CameraPosition p = mMap.getCameraPosition();
return AMapUtils.fromCameraPosition(p);
// return DJICameraPosition.from(p.target.latitude, p.target.longitude,
// p.zoom, p.tilt, p.bearing);
}
@Override
public void animateCamera(DJICameraUpdate cameraUpdate) {
// CameraUpdate update = cameraUpdate.toACameraUpdate();
// mMap.animateCamera(update, 100, null);
CameraUpdate update = AMapUtils.fromDJICameraUpdate(cameraUpdate);
mMap.animateCamera(update);
}
@Override
public void moveCamera(DJICameraUpdate cameraUpdate) {
// CameraUpdate update = cameraUpdate.toACameraUpdate();
// mMap.moveCamera(update);
CameraUpdate update = AMapUtils.fromDJICameraUpdate(cameraUpdate);
mMap.moveCamera(update);
}
@Override
public void setInfoWindowAdapter(final InfoWindowAdapter adapter) {
mMap.setInfoWindowAdapter(new AMap.InfoWindowAdapter() {
@Override
public View getInfoWindow(Marker marker) {
return adapter.getInfoWindow(new AMarker(marker, AMapDelegate.this));
}
@Override
public View getInfoContents(Marker marker) {
return adapter.getInfoContents(new AMarker(marker, AMapDelegate.this));
}
});
}
@NonNull
@Override
public DJIPolyline addPolyline(DJIPolylineOptions options) {
Polyline polyline = mMap.addPolyline(AMapUtils.fromDJIPolylineOptions(options));
return new APolyline(polyline, options);
}
@NonNull
@Override
public DJIPolygon addPolygon(DJIPolygonOptions options) {
Polygon polygon = mMap.addPolygon(AMapUtils.fromDJIPolygonOptions(options));
return new APolygon(polygon);
}
@Nullable
@Override
public DJICircle addSingleCircle(DJICircleOptions options) {
if (options.getRadius() <= 0) {
return null;
}
CircleOptions circleOptions = new CircleOptions();
DJILatLng center = options.getCenter();
circleOptions.center(AMapUtils.fromDJILatLng(center))
.radius(options.getRadius())
.strokeWidth(options.getStrokeWidth())
.strokeColor(options.getStrokeColor())
.fillColor(options.getFillColor());
Circle circle = mMap.addCircle(circleOptions);
return new ACircle(circle);
}
@Nullable
@Override
public DJICircle addMarkerCircle(DJICircleOptions options) {
//TODO 高德安卓api未提供相应方法,暂时只在js中有该方法。
return null;
}
@Nullable
@Override
public DJIGroupCircle addGroupCircle(DJIGroupCircleOptions options) {
if (options.getRadius().size() != options.getCenters().size() || options.getRadius().size() == 0) {
return null;
}
int size = options.getCenters().size();
List<Circle> circles = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
CircleOptions circleOptions = new CircleOptions();
DJILatLng center = options.getCenters().get(i);
Double radius = options.getRadius().get(i);
circleOptions.center(AMapUtils.fromDJILatLng(center))
.radius(radius)
.strokeWidth(options.getStrokeWidth())
.strokeColor(options.getStrokeColor())
.fillColor(options.getFillColor());
Circle circle = mMap.addCircle(circleOptions);
circles.add(circle);
}
return new AGroupCircle(circles);
}
@Override
public void setMapType(int type) {
switch (type) {
case DJIMap.MAP_TYPE_NORMAL:
mMap.setMapType(AMap.MAP_TYPE_NORMAL);
break;
case DJIMap.MAP_TYPE_SATELLITE:
mMap.setMapType(AMap.MAP_TYPE_NIGHT);
break;
case DJIMap.MAP_TYPE_HYBRID:
mMap.setMapType(AMap.MAP_TYPE_SATELLITE);
break;
default:
mMap.setMapType(AMap.MAP_TYPE_NORMAL);
}
}
@Override
public void setMapType(MapType type, OnMapTypeLoadedListener listener) {
setMapType(type);
listener.onMapTypeLoaded();
}
@Override
public void setMapType(MapType type) {
switch (type) {
case NORMAL:
mMap.setMapType(AMap.MAP_TYPE_NORMAL);
break;
case SATELLITE:
mMap.setMapType(AMap.MAP_TYPE_NIGHT);
break;
case HYBRID:
mMap.setMapType(AMap.MAP_TYPE_SATELLITE);
break;
default:
mMap.setMapType(AMap.MAP_TYPE_NORMAL);
}
}
@Override
public DJIUiSettings getUiSettings() {
return new AUiSettings(mMap.getUiSettings());
}
/**********************************************************************************************/
@Override
public boolean onMarkerClick(Marker marker) {
if (markerMap.containsKey(marker)) {
onMarkerClick(markerMap.get(marker));
}
return true;
}
@Override
public void onMapClick(LatLng latLng) {
DJILatLng djiLatLng = AMapUtils.fromLatLng(latLng);
onMapClick(djiLatLng);
}
@Override
public void onInfoWindowClick(Marker marker) {
if (markerMap.containsKey(marker)) {
onInfoWindowClick(markerMap.get(marker));
}
}
@Override
public void onMarkerDragStart(Marker marker) {
if (markerMap.containsKey(marker)) {
onMarkerDragStart(markerMap.get(marker));
}
}
@Override
public void onMarkerDrag(Marker marker) {
if (markerMap.containsKey(marker)) {
DJIMarker djiMarker = markerMap.get(marker);
LatLng latLng = marker.getPosition();
DJILatLng djiLatLng = AMapUtils.fromLatLng(latLng);
djiMarker.setPosition(djiLatLng);
onMarkerDrag(djiMarker);
}
}
@Override
public void onMarkerDragEnd(Marker marker) {
if (markerMap.containsKey(marker)) {
DJIMarker djiMarker = markerMap.get(marker);
LatLng latLng = marker.getPosition();
DJILatLng djiLatLng = AMapUtils.fromLatLng(latLng);
djiMarker.setPosition(djiLatLng);
onMarkerDragEnd(djiMarker);
}
}
@Override
public void snapshot(final MapScreenShotListener callback) {
mMap.getMapScreenShot(new AMap.OnMapScreenShotListener() {
@Override
public void onMapScreenShot(Bitmap bitmap) {
callback.onMapScreenShot(bitmap);
}
@Override
public void onMapScreenShot(Bitmap bitmap, int i) {
//do something
}
});
}
@Override
public DJIProjection getProjection() {
return new AProjection(mMap.getProjection());
}
@Override
public void clear() {
mMap.clear();
}
public void onMarkerRemove(Marker marker) {
if (markerMap.containsKey(marker)) {
markerMap.remove(marker);
}
}
@Override
public void onMapLongClick(LatLng latLng) {
DJILatLng djiLatLng = AMapUtils.fromLatLng(latLng);
onMapLongClick(djiLatLng);
}
@Override
public void onCameraChange(CameraPosition cameraPosition) {
DJICameraPosition p = AMapUtils.fromCameraPosition(cameraPosition);
AMapDelegate.this.onCameraChange(p);
}
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
DJICameraPosition p = AMapUtils.fromCameraPosition(cameraPosition);
AMapDelegate.this.onCameraChangeFinish(p);
}
}
package dji.v5.ux.mapkit.amap.map;
import android.content.Context;
import androidx.annotation.NonNull;
import com.amap.api.maps.TextureMapView;
import dji.v5.ux.mapkit.core.Mapkit;
import dji.v5.ux.mapkit.core.maps.DJIMapView;
import dji.v5.ux.mapkit.core.maps.DJIMapViewInternal;
/**
* Created by joeyang on 5/30/17.
*/
public class AMapView extends TextureMapView implements DJIMapViewInternal {
public AMapView(Context context) {
super(context);
}
@Override
public void onStart() {
//do something
}
@Override
public void onStop() {
//do something
}
@Override
public void getDJIMapAsync(@NonNull final DJIMapView.OnDJIMapReadyCallback callback) {
AMapDelegate amap = new AMapDelegate(getMap());
int mapType = Mapkit.getMapType();
amap.setMapType(mapType);
callback.onDJIMapReady(amap);
}
}
package dji.v5.ux.mapkit.amap.map;
import android.graphics.Point;
import com.amap.api.maps.Projection;
import com.amap.api.maps.model.LatLng;
import dji.v5.ux.mapkit.amap.utils.AMapUtils;
import dji.v5.ux.mapkit.core.maps.DJIProjection;
import dji.v5.ux.mapkit.core.models.DJILatLng;
/**
* Created by joeyang on 6/12/17.
*/
public class AProjection implements DJIProjection {
Projection mProjection;
public AProjection(Projection projection) {
mProjection = projection;
}
@Override
public DJILatLng fromScreenLocation(Point point) {
DJILatLng result = null;
LatLng latLng = mProjection.fromScreenLocation(point);
if (latLng != null) {
// result = new DJILatLng(latLng);
result = AMapUtils.fromLatLng(latLng);
}
return result;
}
@Override
public Point toScreenLocation(DJILatLng location) {
LatLng latLng = AMapUtils.fromDJILatLng(location);
return mProjection.toScreenLocation(latLng);
}
}
package dji.v5.ux.mapkit.amap.map;
import com.amap.api.maps.UiSettings;
import dji.v5.ux.mapkit.core.maps.DJIUiSettings;
/**
* Created by joeyang on 6/8/17.
*/
public class AUiSettings implements DJIUiSettings {
UiSettings mUiSettings;
public AUiSettings(UiSettings uiSettings) {
mUiSettings = uiSettings;
}
@Override
public void setZoomControlsEnabled(boolean enabled) {
mUiSettings.setZoomControlsEnabled(enabled);
}
@Override
public void setScrollGesturesEnabled(boolean enabled) {
mUiSettings.setScrollGesturesEnabled(enabled);
}
@Override
public void setCompassEnabled(boolean enabled) {
mUiSettings.setCompassEnabled(enabled);
}
@Override
public void setMapToolbarEnabled(boolean enabled) {
//do something
}
@Override
public void setMyLocationButtonEnabled(boolean enabled) {
mUiSettings.setMyLocationButtonEnabled(enabled);
}
@Override
public void setRotateGesturesEnabled(boolean enabled) {
mUiSettings.setRotateGesturesEnabled(enabled);
}
@Override
public void setTiltGesturesEnabled(boolean enabled) {
mUiSettings.setTiltGesturesEnabled(enabled);
}
@Override
public void setZoomGesturesEnabled(boolean enabled) {
mUiSettings.setZoomGesturesEnabled(enabled);
}
}
package dji.v5.ux.mapkit.amap.place;
import android.content.Context;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import java.util.ArrayList;
import java.util.List;
import dji.v5.ux.mapkit.core.models.DJILatLng;
import dji.v5.ux.mapkit.core.places.DJIPlacesClient;
import dji.v5.ux.mapkit.core.places.DJIPoiItem;
import dji.v5.ux.mapkit.core.places.DJIPoiSearchQuery;
import dji.v5.ux.mapkit.core.places.DJIRegeocodeResult;
import dji.v5.ux.mapkit.core.places.IInternalPlacesClient;
import dji.v5.ux.mapkit.core.utils.DJIGpsUtils;
/**
* Created by joeyang on 10/10/17.
*/
public class AMapPlaceDelegate implements IInternalPlacesClient, PoiSearch.OnPoiSearchListener {
private static final int AMAP_SEARCH_SUCCESS_CODE = 1000;
private Context context;
private PoiSearch poiSearch;
private PoiSearch.Query query;
private DJIPlacesClient.OnPoiSearchListener onPoiSearchListener;
private DJIPlacesClient.OnRegeocodeSearchListener onRegeocodeSearchListener;
public AMapPlaceDelegate(Context context) {
this.context = context;
query = new PoiSearch.Query("", "", "");
query.setPageSize(10);
poiSearch = new PoiSearch(context, query);
}
@Override
public void setPoiSearchQuery(DJIPoiSearchQuery poiSearchQuery) {
query = new PoiSearch.Query(poiSearchQuery.keyWord(), "");
poiSearch.setQuery(query);
}
@Override
public void setOnRegeocodeSearchListener(DJIPlacesClient.OnRegeocodeSearchListener onRegeocodeSearchListener) {
this.onRegeocodeSearchListener = onRegeocodeSearchListener;
}
@Override
public void setOnPoiSearchListener(DJIPlacesClient.OnPoiSearchListener onPoiSearchListener) {
this.onPoiSearchListener = onPoiSearchListener;
}
@Override
public void searchPOIAsyn(DJILatLng latLng) {
searchPOIAsyn(latLng, POI_RADIUS);
}
@Override
public void searchPOIAsyn(DJILatLng latLng, int radius) {
DJILatLng gcjLatLng = DJIGpsUtils.wgs2gcjInChina(latLng);
poiSearch.setOnPoiSearchListener(this);
poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(gcjLatLng.getLatitude(), gcjLatLng.getLongitude()), radius));
poiSearch.searchPOIAsyn();
}
@Override
public void onPoiSearched(PoiResult poiResult, int i) {
if (i == AMAP_SEARCH_SUCCESS_CODE) {
List<PoiItem> pois = poiResult.getPois();
List<DJIPoiItem> poiList = new ArrayList<>(pois.size());
for (PoiItem poiItem : pois) {
LatLonPoint latLonPoint = poiItem.getLatLonPoint();
DJILatLng wgsLatLng = DJIGpsUtils.gcj2wgsInChina(new DJILatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude()));
DJIPoiItem item = new DJIPoiItem(poiItem.getTitle(), poiItem.getSnippet(), wgsLatLng);
poiList.add(item);
}
if (onPoiSearchListener != null) {
onPoiSearchListener.onPoiSearched(poiList);
}
} else {
if (onPoiSearchListener != null) {
onPoiSearchListener.onPoiSearchFailed();
}
}
}
@Override
public void onPoiItemSearched(PoiItem poiItem, int i) {
// no code
}
@Override
public void regeocodeSearchAsyn(DJILatLng latLng) {
//第一个参数表示一个Latlng,第二参数表示范围多少米,第三个参数表示是火系坐标系还是GPS原生坐标系
RegeocodeQuery querys = new RegeocodeQuery(new LatLonPoint(latLng.getLatitude(), latLng.getLongitude()), POI_RADIUS, GeocodeSearch.AMAP);
GeocodeSearch geoCoderSearch = new GeocodeSearch(this.context);
geoCoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
@Override
public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int resultId) {
if (resultId == 1000) {
RegeocodeAddress regeocodeAddress = regeocodeResult.getRegeocodeAddress();
DJIRegeocodeResult result = new DJIRegeocodeResult();
result.setCountry("中国");
result.setRegion(regeocodeAddress.getProvince());
result.setCity(regeocodeAddress.getCity());
result.setDistrict(regeocodeAddress.getDistrict());
result.setStreet(regeocodeAddress.getTownship());
result.setSubStreet(regeocodeAddress.getStreetNumber() != null ? regeocodeAddress.getStreetNumber().getStreet() : null);
result.setAddress(regeocodeAddress.getFormatAddress());
if (onRegeocodeSearchListener != null) {
onRegeocodeSearchListener.onSearched(result);
}
} else {
if (onRegeocodeSearchListener != null) {
onRegeocodeSearchListener.onSearched(null);
}
}
}
@Override
public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
//do something
}
});
geoCoderSearch.getFromLocationAsyn(querys);
}
}
package dji.v5.ux.mapkit.amap.provider;
import static com.dji.flysafe.mapkit.core.core.Mapkit.MapProviderConstant.AMAP_PROVIDER;
import android.content.Context;
import android.os.RemoteException;
import androidx.annotation.NonNull;
import com.amap.api.maps.MapsInitializer;
import dji.v5.ux.mapkit.amap.map.AMapView;
import dji.v5.ux.mapkit.amap.place.AMapPlaceDelegate;
import dji.v5.ux.mapkit.core.Mapkit;
import dji.v5.ux.mapkit.core.MapkitOptions;
import dji.v5.ux.mapkit.core.exceptions.MapkitInitializerException;
import dji.v5.ux.mapkit.core.maps.DJIMapViewInternal;
import dji.v5.ux.mapkit.core.places.IInternalPlacesClient;
import dji.v5.ux.mapkit.core.providers.MapProvider;
public class AMapProvider extends MapProvider {
public AMapProvider() {
providerType = AMAP_PROVIDER;
}
@Override
protected DJIMapViewInternal requestMapView(@NonNull Context context,
@NonNull MapkitOptions mapkitOptions) {
DJIMapViewInternal mapView = null;
Mapkit.mapType(mapkitOptions.getMapType());
Mapkit.mapProvider(Mapkit.MapProviderConstant.INVALID_PROVIDER);
mapView = new AMapView(context);
try {
MapsInitializer.initialize(context);
} catch (RemoteException e) {
throw new MapkitInitializerException(Mapkit.MapProviderConstant.INVALID_PROVIDER);
}
return mapView;
}
@Override
protected IInternalPlacesClient requestGeocodingClient(Context context, MapkitOptions mapkitOptions) {
IInternalPlacesClient client = null;
Mapkit.geocodingProvider(getProviderType());
client = new AMapPlaceDelegate(context);
return client;
}
}
package dji.v5.ux.mapkit.amap.utils;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
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.PolygonOptions;
import com.amap.api.maps.model.PolylineOptions;
import java.util.ArrayList;
import java.util.List;
import dji.v5.ux.mapkit.core.camera.DJICameraUpdate;
import dji.v5.ux.mapkit.core.camera.DJICameraUpdateFactory;
import dji.v5.ux.mapkit.core.models.DJIBitmapDescriptor;
import dji.v5.ux.mapkit.core.models.DJICameraPosition;
import dji.v5.ux.mapkit.core.models.DJILatLng;
import dji.v5.ux.mapkit.core.models.DJILatLngBounds;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolygonOptions;
import dji.v5.ux.mapkit.core.models.annotations.DJIPolylineOptions;
import dji.v5.ux.mapkit.core.utils.DJIGpsUtils;
/**
* Created by joeyang on 2/10/18.
*/
public class AMapUtils {
private AMapUtils(){}
public static final LatLng fromDJILatLng(DJILatLng latLng) {
DJILatLng gcjLatLng = DJIGpsUtils.wgs2gcjInChina(latLng);
return new LatLng(gcjLatLng.getLatitude(), gcjLatLng.getLongitude());
}
public static final DJILatLng fromLatLng(LatLng latLng) {
DJILatLng ll = new DJILatLng(latLng.latitude, latLng.longitude);
DJILatLng transformed = DJIGpsUtils.gcj2wgsInChina(ll);
return transformed;
}
public static final CameraUpdate fromDJICameraUpdate(DJICameraUpdate cameraUpdate) {
CameraUpdate u = CameraUpdateFactory.newLatLng(new LatLng(0.0, 0.0));
if (cameraUpdate instanceof DJICameraUpdateFactory.CameraBoundsUpdate) {
final DJICameraUpdateFactory.CameraBoundsUpdate boundsUpdate
= (DJICameraUpdateFactory.CameraBoundsUpdate) cameraUpdate;
int width = boundsUpdate.getWidth();
int height = boundsUpdate.getHeight();
int padding = boundsUpdate.getPadding();
int paddingLeft = boundsUpdate.getPaddingLeft();
int paddingRight = boundsUpdate.getPaddingRight();
int paddingBottom = boundsUpdate.getPaddingBottom();
int paddingTop = boundsUpdate.getPaddingTop();
LatLngBounds.Builder builder = new LatLngBounds.Builder();
DJILatLngBounds bounds = boundsUpdate.getBounds();
DJILatLng northeast = bounds.getNortheast();
DJILatLng southwest = bounds.getSouthwest();
builder.include(fromDJILatLng(northeast))
.include(fromDJILatLng(southwest));
if (width == 0 || height == 0) {
u = CameraUpdateFactory.newLatLngBoundsRect(builder.build(),
padding + paddingLeft,
padding + paddingRight,
padding + paddingTop,
padding + paddingBottom);
} else {
u = CameraUpdateFactory.newLatLngBounds(builder.build(), width, height, padding);
}
} else if (cameraUpdate instanceof DJICameraUpdateFactory.CameraPositionUpdate) {
final DJICameraUpdateFactory.CameraPositionUpdate positionUpdate
= (DJICameraUpdateFactory.CameraPositionUpdate) cameraUpdate;
CameraPosition p;
LatLng target = fromDJILatLng(positionUpdate.getTarget());
p = new CameraPosition.Builder().target(target)
.zoom(positionUpdate.getZoom())
.tilt(positionUpdate.getTilt())
.bearing(positionUpdate.getBearing())
.build();
u = CameraUpdateFactory.newCameraPosition(p);
}
return u;
}
public static final DJICameraPosition fromCameraPosition(CameraPosition cameraPosition) {
DJICameraPosition.Builder builder = new DJICameraPosition.Builder();
LatLng target = cameraPosition.target;
builder.target(fromLatLng(target))
.zoom(cameraPosition.zoom)
.tilt(cameraPosition.tilt)
.bearing(cameraPosition.bearing);
return builder.build();
}
public static final BitmapDescriptor fromDJIBitmapDescriptor(DJIBitmapDescriptor descriptor) {
BitmapDescriptor bitmapDescriptor;
String path = descriptor.getPath();
switch (descriptor.getType()) {
case BITMAP:
bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(descriptor.getBitmap());
break;
case PATH_ABSOLUTE:
bitmapDescriptor = BitmapDescriptorFactory.fromPath(path);
break;
case PATH_ASSET:
bitmapDescriptor = BitmapDescriptorFactory.fromAsset(path);
break;
case PATH_FILEINPUT:
bitmapDescriptor = BitmapDescriptorFactory.fromFile(path);
break;
case RESOURCE_ID:
bitmapDescriptor = BitmapDescriptorFactory.fromResource(descriptor.getResourceId());
break;
case VIEW:
bitmapDescriptor = BitmapDescriptorFactory.fromView(descriptor.getView());
break;
default:
throw new AssertionError();
}
return bitmapDescriptor;
}
public static final PolygonOptions fromDJIPolygonOptions(DJIPolygonOptions options) {
PolygonOptions result = new PolygonOptions();
List<LatLng> points = new ArrayList<>();
for (DJILatLng point : options.getPoints()) {
points.add(fromDJILatLng(point));
}
result.strokeWidth(options.getStrokeWidth())
.zIndex(options.getZIndex())
.strokeColor(options.getStrokeColor())
.fillColor(options.getFillColor())
.visible(options.isVisible())
.addAll(points);
return result;
}
public static final PolylineOptions fromDJIPolylineOptions(DJIPolylineOptions options) {
PolylineOptions result = new PolylineOptions();
List<LatLng> points = new ArrayList<>();
List<DJILatLng> originPoints = options.getPoints();
// 暂弃用此航点抽稀算法 缩放级别较大时,航迹绘不连贯,弯弯曲曲, 并且高德之外的地图都没有用
// List<DJILatLng> compressPoints = originPoints;
// // 若首尾两个点坐标相同,使用道格拉斯算法会有问题,需要排除这种情况
// if (!originPoints.isEmpty() && !originPoints.get(0).equals(originPoints.get(originPoints.size() – 1))) {
// compressPoints = DouglasUtils.compress(originPoints, 0.5);
// }
for (DJILatLng point : originPoints) {
points.add(fromDJILatLng(point));
}
result.width(options.getWidth())
.zIndex(options.getZIndex())
.color(options.getColor())
.visible(options.isVisible())
.geodesic(options.isGeodesic())
.addAll(points);
// 高德地图不能设置虚线间隔和长短, 只能选择dot类型:圆形或方形, 这里默认选择方形
if (options.isDashed()) {
result.setDottedLine(true).setDottedLineType(PolylineOptions.DOTTEDLINE_TYPE_SQUARE);
}
if (options.isEnableTexture() && options.getBitmapDescriptor() != null){
result.setUseTexture(true);
BitmapDescriptor bitmapDescriptor = fromDJIBitmapDescriptor(options.getBitmapDescriptor());
result.setCustomTexture(bitmapDescriptor);
}
return result;
}
}
第五步添加高德地图启动项:
在Mapwight中添加高德地图启动代码:

public void initAMap(@Nullable final OnMapReadyListener listener) {
mapView = new AMapProvider().dispatchMapViewRequest(getContext(), null);
addView((ViewGroup) mapView, 0);
mapView.getDJIMapAsync(map -> {
MapWidget.this.map = map;
postInit(listener);
flyZoneHelper.initializeMap(map);
});
}
第六步在使用高德地图部分的fragment中替换地图初始化代码

private fun createMapView(savedInstanceState: Bundle?) {
// 初始化高德地图
binding?.mapWidget?.initAMap(object : MapWidget.OnMapReadyListener {
override fun onMapReady(map: DJIMap) { // 注意:这里去掉了问号
// 设置地图类型(DJIMap 通用方法)
map.setMapType(DJIMap.MapType.NORMAL)
// 如果需要设置高德特有属性,需要获取原生 AMap 对象
// 例如:如果 DJIMap 提供了 getAMap() 方法
// val aMap = (map as? AMapWrapper)?.aMap
// aMap?.uiSettings?.isZoomControlsEnabled = false
}
})
binding?.mapWidget?.onCreate(savedInstanceState)
}
别忘了添加高德的key
<meta–data
android:name="com.amap.api.v2.apikey"
android:value="YOUR KEY"/>
</application>
运行结果
