eagle 小地图导航 车前引导线

This commit is contained in:
lianglihui
2021-09-27 10:03:37 +08:00
parent 0fade93ff3
commit ff3f2d20e2
6 changed files with 362 additions and 156 deletions

View File

@@ -0,0 +1,34 @@
package com.mogo.eagle.core.function.smp;
import com.mogo.eagle.core.data.map.MogoLatLng;
import java.util.List;
public class RoutePathConvertUtils {
public List<MogoLatLng> routeList;
public int ROUTE_LEFT = 1;
public int ROUTE_RIGHT = 2;
public int ROUTE_STRAIGHT = 0;
public int route_direction =-1;
public void convert(){
for (int i = 0; i <routeList.size()-2 ; i++) {
MogoLatLng latLng0 = routeList.get(i);
MogoLatLng latLng1 = routeList.get(i+1);
MogoLatLng latLng2 = routeList.get(i+2);
double v1x = latLng1.lat - latLng0.lat;
double v1y = latLng1.lon - latLng0.lon;
double v2x = latLng2.lat - latLng1.lat;
double v2y = latLng2.lon - latLng2.lon;
double r = v1x* v2y - v1y*v2x;
if (r > 0.0){
route_direction = ROUTE_LEFT;
}else {
route_direction = ROUTE_RIGHT;
}
}
}
}

View File

@@ -1,13 +1,13 @@
package com.mogo.eagle.core.function.smp;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.location.Location;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.view.View;
import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
@@ -15,24 +15,31 @@ import androidx.annotation.Nullable;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CustomMapStyleOptions;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewOptions;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.map.MogoLatLng;
import com.mogo.eagle.core.function.smp.animation.DirectionRotateAnimation;
import com.mogo.eagle.core.function.smp.utils.MapAssetStyleUtils;
import com.mogo.eagle.core.function.smp.view.ISmallMapDirectionView;
import com.mogo.eagle.core.widget.RoundLayout;
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.utils.logger.Logger;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import ch.hsr.geohash.GeoHash;
/**
* 小地图的方向View
*
@@ -44,16 +51,20 @@ public class SmallMapDirectionView
implements IMogoCarLocationChangedListener2, ISmallMapDirectionView {
//小地图名称
public static final String MODULE_NAME = "SmallMapDirectionView";
public static final String MODULE_NAME = "SmallMap";
private ImageView mIvMapBorder;
private DirectionRotateAnimation mRotateAnimation;
private int lastAngle = 0;
private AMapNaviView mAMapNaviView;
private RoundLayout rlSmallMapBorder;
private TextureMapView mAMapNaviView;
private AMap mAMap;
private AMapNavi mAMapNavi;
private int zoomLevel = 15;
private Marker mCarMarker;
private Marker mStartMarker;
private Marker mEndMarker;
private int zoomLevel = 13;
private List<LatLng> mCoordinatesLatLng = new ArrayList<>();
private List<MogoLatLng> mCoordinatesLatLngCurrent = new ArrayList<>();
private Polyline mPolyline;
private CameraUpdate mCameraUpdate;
public SmallMapDirectionView(Context context) {
this(context, null);
@@ -73,13 +84,11 @@ public class SmallMapDirectionView
}
private void initView(Context context) {
mRotateAnimation = new DirectionRotateAnimation(context, null);
View smpView = LayoutInflater.from(context).inflate(R.layout.module_small_map_view, this);
LayoutInflater.from(context).inflate(R.layout.module_small_map_view, this);
mAMapNaviView = findViewById(R.id.aMapNaviView);
mAMapNaviView.onCreate(null);
mIvMapBorder = findViewById(R.id.ivMapBorder);
mAMapNaviView = (TextureMapView)smpView.findViewById(R.id.aMapNaviView);
rlSmallMapBorder = findViewById(R.id.rlSmallMapBorder);
rlSmallMapBorder.addView(mAMapNaviView);
initAMapView();
@@ -112,10 +121,7 @@ public class SmallMapDirectionView
}
private void initAMapView() {
// 车头朝上
mAMapNaviView.setNaviMode(AMapNaviView.CAR_UP_MODE);
// 设置电子眼所在路线的可见性
mAMapNaviView.setRouteOverlayVisible(false);
mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel);
mAMap = mAMapNaviView.getMap();
// 关闭地图文字标注
mAMap.showMapText(false);
@@ -123,25 +129,15 @@ public class SmallMapDirectionView
mAMap.setMapType(AMap.MAP_TYPE_NIGHT);
// 关闭显示实时路况图层aMap是地图控制器对象。
mAMap.setTrafficEnabled(false);
mAMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
if (cameraPosition != null) {
//Log.w("onCameraChange", "cameraPosition=" + cameraPosition.bearing);
changeAngle((int) cameraPosition.bearing);
}
}
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
}
});
mAMapNavi = AMapNavi.getInstance(getContext());
//使用外部GPS数据
mAMapNavi.setIsUseExtraGPSData(true);
// 设置 锚点 图标
mCarMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_my_location_logo))
.anchor(0.5f, 0.5f));
mStartMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_start)));
mEndMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.module_small_map_view_dir_end)));
new Thread(() -> {
try {
@@ -157,8 +153,7 @@ public class SmallMapDirectionView
);
//设置希望展示的地图缩放级别
CameraUpdate cameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel);
mAMap.moveCamera(cameraUpdate);
mAMap.moveCamera(mCameraUpdate);
}).start();
// 设置地图的样式
@@ -167,71 +162,12 @@ public class SmallMapDirectionView
uiSettings.setAllGesturesEnabled(false);// 所有手势
uiSettings.setMyLocationButtonEnabled(false); // 显示默认的定位按钮
uiSettings.setLogoBottomMargin(-150); //设置Logo下边界距离屏幕底部的边距,设置为负值即可
// 导航地图
AMapNaviViewOptions options = mAMapNaviView.getViewOptions();
//设置导航界面UI是否显示。
if (options != null) {
// 设置是否开启自动黑夜模式切换默认为false不自动切换
options.setAutoNaviViewNightMode(false);
// 设置6秒后是否自动锁车
options.setAutoLockCar(true);
// 设置路线上的摄像头气泡是否显示
options.setCameraBubbleShow(false);
// 设置路线相关的配置属性,如:路线的路况颜色,路线上是否显示摄像头气泡等。
// options.setRouteOverlayOptions( MapStyleUtils.getRouteOverlayOptions() );
// 设置自车的图片对象
options.setCarBitmap(BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.module_small_map_view_my_location_logo));
// 设置罗盘位图对象
options.setFourCornersBitmap(BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.icon_module_small_map_four_corners));
// 设置指南针图标否在导航界面显示默认显示。true显示false隐藏。
options.setCompassEnabled(false);
//设置路况光柱条是否显示(只适用于驾车导航,需要联网)。
options.setTrafficBarEnabled(false);
// 设置[实时交通图层开关按钮]是否显示(只适用于驾车导航,需要联网)。
options.setTrafficLayerEnabled(false);
// 设置导航界面是否显示路线全览按钮。
options.setRouteListButtonShow(false);
// 设置屏幕是否常亮,默认开启
options.setScreenAlwaysBright(false);
// 设置交通播报是否打开(只适用于驾车导航,需要联网)。
options.setTrafficInfoUpdateEnabled(false);
// 设置摄像头播报是否打开(只适用于驾车导航)。
options.setCameraInfoUpdateEnabled(false);
// 设置菜单按钮是否在导航界面显示。
options.setSettingMenuEnabled(false);
// 设置是否绘制显示交通路况的线路(彩虹线),拥堵-红色,畅通-绿色,缓慢-黄色,未知-蓝色。默认不绘制彩虹线。
options.setTrafficLine(false);
// 设置是否绘制牵引线(当前位置到目的地的指引线)。默认不绘制牵引线。
options.setLeaderLineEnabled(-1);
// 设置导航界面UI是否显示。
options.setLayoutVisible(false);
// 设置是否自动画路
options.setAutoDrawRoute(false);
// 设置是否显示路口放大图(实景图)
options.setRealCrossDisplayShow(false);
// 设置是否显示路口放大图(路口模型图)
options.setModeCrossDisplayShow(false);
// 设置是否显示道路信息view
options.setLaneInfoShow(false);
// 设置是否自动改变缩放等级
options.setAutoChangeZoom(false);
// 设置是否自动全览模式,即在算路成功后自动进入全览模式
options.setAutoDisplayOverview(false);
// 设置路线转向箭头隐藏和显示
options.setNaviArrowVisible(false);
// 通过路线是否自动置灰,仅支持驾车导航
options.setAfterRouteAutoGray(false);
options.setZoom(((int) 10));
//options.setPointToCenter(0.7D, 0.5D);
// 2D模式
options.setTilt(0);
// 黑夜模式
options.setNaviNight(true);
mAMapNaviView.setViewOptions(options);
}
mAMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
@Override
public void onMapLoaded() {
mAMapNaviView.getMap().setPointToCenter(mAMapNaviView.getWidth()/2, mAMapNaviView.getHeight()/2);
}
});
}
@@ -242,58 +178,106 @@ public class SmallMapDirectionView
@Override
public void onCarLocationChanged2(Location latLng) {
//Logger.d(MODULE_NAME, "onCarLocationChanged2 latLng:" + latLng);
if (mAMapNavi != null) {
NumberFormat nf = NumberFormat.getNumberInstance();
// 保留两位小数
nf.setMaximumFractionDigits(6);
// 如果不需要四舍五入可以使用RoundingMode.DOWN
nf.setRoundingMode(RoundingMode.UP);
try {
latLng.setLatitude(Double.valueOf(nf.format(latLng.getLatitude())));
latLng.setLongitude(Double.valueOf(nf.format(latLng.getLongitude())));
} catch (NumberFormatException e) {
e.printStackTrace();
latLng.setLatitude(latLng.getLatitude());
latLng.setLongitude(latLng.getLongitude());
Logger.d(MODULE_NAME, "onCarLocationChanged2 latLng:" + latLng);
LatLng currentLatLng = new LatLng(latLng.getLatitude(), latLng.getLongitude());
if (mCarMarker != null) {
mCarMarker.setRotateAngle(360 - latLng.getBearing());
mCarMarker.setPosition(currentLatLng);
mCarMarker.setToTop();
}
if (mCoordinatesLatLng.size() > 1) {
mCoordinatesLatLngCurrent.clear();
for (LatLng lng : mCoordinatesLatLng) {
MogoLatLng mogoLatLng = new MogoLatLng(lng.latitude, lng.longitude);
mCoordinatesLatLngCurrent.add(mogoLatLng);
}
mAMapNavi.setExtraGPSData(2, latLng);
// 结束位置
LatLng endLatLng = mCoordinatesLatLng.get(mCoordinatesLatLng.size() - 1);
// 与结束位置进行 GeoHash 0-12
// GeoHash endGeoHash = GeoHash.withCharacterPrecision(endLatLng.latitude, endLatLng.longitude, 7);
// GeoHash currentGeoHash = GeoHash.withCharacterPrecision(currentLatLng.latitude, currentLatLng.longitude, 7);
// Log.d(MODULE_NAME, "currentGeoHash=" + currentGeoHash);
// Log.d(MODULE_NAME, "endGeoHash=" + endGeoHash);
float calculateDistance = CoordinateUtils.calculateLineDistance(
endLatLng.latitude, endLatLng.longitude,
currentLatLng.latitude, currentLatLng.longitude
);
Log.d(MODULE_NAME, "calculateDistance=" + calculateDistance);
if (calculateDistance <= 20) {
clearPolyline();
} else {
drawablePolyline(mCoordinatesLatLngCurrent);
}
} else {
//设置希望展示的地图缩放级别
mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, zoomLevel));
}
}
@Override
public void onCarLocationChanged(MogoLatLng latLng) {
//Logger.d(MODULE_NAME, "onCarLocationChanged latLng:" + latLng);
Logger.d(MODULE_NAME, "onCarLocationChanged latLng:" + latLng);
}
@Override
public void drawablePolyline(List<MogoLatLng> coordinates) {
clearPolyline();
mCoordinatesLatLng.clear();
for (MogoLatLng coordinate : coordinates) {
mCoordinatesLatLng.add(new LatLng(coordinate.getLat(), coordinate.getLon()));
}
if (mAMap != null) {
if (mCoordinatesLatLng.size() > 2) {
// 设置开始结束Marker位置
mStartMarker.setPosition(mCoordinatesLatLng.get(0));
mEndMarker.setPosition(mCoordinatesLatLng.get(mCoordinatesLatLng.size() - 1));
mStartMarker.setVisible(true);
mEndMarker.setVisible(true);
//存放所有点的经纬度
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
for (int i = 0; i < mCoordinatesLatLng.size(); i++) {
//把所有点都include进去LatLng类型
boundsBuilder.include(mCoordinatesLatLng.get(i));
}
//第二个参数为四周留空宽度
mAMap.animateCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(), 65, 65, 65, 65));
// 绘制线
mPolyline = mAMap.addPolyline(
new PolylineOptions()
.addAll(mCoordinatesLatLng)
.color(Color.argb(255, 31, 127, 255))
.width(5));
} else {
//设置希望展示的地图缩放级别
mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mCoordinatesLatLng.get(0), zoomLevel));
}
}
}
@Override
public void clearPolyline() {
mCoordinatesLatLng.clear();
if (mPolyline != null) {
mPolyline.remove();
}
if (mStartMarker != null) {
mStartMarker.setVisible(false);
}
if (mEndMarker != null) {
mEndMarker.setVisible(false);
}
}
/**
* 修改角度
*
* @param angle 角度 0 - 359度旋转,相对于自身中心位置
*/
public void changeAngle(int angle) {
int tempAngle = 360 - angle;
mRotateAnimation.setFromDegrees(lastAngle);
mRotateAnimation.setToDegrees(tempAngle);
//设置线性插值,可以解决旋转一圈后卡顿问题
mRotateAnimation.setInterpolator(new LinearInterpolator());
//设置旋转一圈时间
mRotateAnimation.setDuration(300);
//控件动画结束时是否保持动画最后的状态
mRotateAnimation.setFillAfter(true);
mIvMapBorder.startAnimation(mRotateAnimation);
// 刷新最后一次角度
lastAngle = tempAngle;
}
}

View File

@@ -20,14 +20,15 @@
app:roundLayoutRadius="360dp">
<!--TODO Hook方案在Pad上有问题,优先 效果,后面在看如何解决-->
<com.amap.api.navi.AMapNaviView
android:id="@+id/aMapNaviView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- <com.amap.api.maps.TextureMapView
<!-- <com.amap.api.navi.AMapNaviView-->
<!-- android:id="@+id/aMapNaviView"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent" />-->
<com.amap.api.maps.TextureMapView
android:id="@+id/aMapNaviView"
android:layout_width="match_parent"
android:layout_height="match_parent" />-->
android:layout_height="match_parent" />
</com.mogo.eagle.core.widget.RoundLayout>
<ImageView