Merge branch 'dev_robotaxi-d-app-module_265_220329_2.6.5' into 'master'

Dev robotaxi d app module 265 220329 2.6.5

See merge request zhjt/AndroidApp/MoGoEagleEye!14
This commit is contained in:
pangfan
2022-04-25 06:22:39 +00:00
3265 changed files with 107610 additions and 126289 deletions

View File

@@ -1,7 +1,6 @@
# 网约车(Online Car Hailing)
## 小巴
## 出租车
## 无实现
1. mogo-och-busBus司机端Bus
2. mogo-och-bus-passengerBus乘客端BusPassenger
3. mogo-och-taxiTaxi司机端Taxi
4. mogo-och-taxi-passengerTaxi乘客端TaxiPassenger
5. mogo-och-noop空实现用于独立鹰眼打包

View File

@@ -0,0 +1,75 @@
apply plugin: 'com.android.library'
apply plugin: 'com.alibaba.arouter'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
// buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode Integer.valueOf(VERSION_CODE)
versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION")
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation rootProject.ext.dependencies.kotlinstdlibjdk7
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.arouter
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.2.1'
annotationProcessor rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.rxandroid
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.amapnavi3dmap
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.mogoutils
implementation rootProject.ext.dependencies.mogocommons
implementation rootProject.ext.dependencies.modulecommon
implementation rootProject.ext.dependencies.mogo_core_data
implementation rootProject.ext.dependencies.mogo_core_function_call
implementation rootProject.ext.dependencies.mogo_core_function_v2x
implementation rootProject.ext.dependencies.mogo_core_function_hmi
}else {
implementation project(":core:mogo-core-utils")
implementation project(":foudations:mogo-commons")
implementation project(':modules:mogo-module-common')
implementation project(':core:mogo-core-data')
implementation project(':core:mogo-core-function-call')
implementation project(':core:function-impl:mogo-core-function-v2x')
implementation project(':core:function-impl:mogo-core-function-hmi')
}
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.och
POM_ARTIFACT_ID=och-bus-passenger
VERSION_CODE=1

View File

@@ -0,0 +1,26 @@
package com.mogo.och.bus.passenger;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.mogo.och.bus.passenger.test", appContext.getPackageName());
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.och.bus.passenger">
</manifest>

View File

@@ -0,0 +1,22 @@
package com.mogo.och.bus.passenger;
import androidx.annotation.IdRes;
import androidx.fragment.app.FragmentActivity;
import com.mogo.eagle.core.function.api.base.IMoGoFunctionProvider;
/**
* 网约车抽象接口
*
* Created on 2022/3/29
*/
interface IMogoOCH extends IMoGoFunctionProvider {
/**
* 初始化网约车容器
*
* @param activity
* @param containerId 容器ID
*/
void createCoverage(FragmentActivity activity, @IdRes int containerId);
}

View File

@@ -0,0 +1,109 @@
package com.mogo.och.bus.passenger;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.elegant.utils.UiThreadHandler;
import com.mogo.eagle.core.function.call.setting.CallerMoGoUiSettingManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.map.MogoMapUIController;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.bus.passenger.ui.BusPassengerRouteFragment;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI_P;
/**
* 网约车-Bus-乘客端
*
* Created on 2022/3/29
*/
@Route(path = BusPassengerConst.PATH)
public class MogoOCHBusPassenger implements IMogoOCH, IMogoStatusChangedListener {
private static final String TAG = MogoOCHBusPassenger.class.getSimpleName();
private FragmentActivity mActivity;
private int mContainerId;
private BusPassengerRouteFragment mPassengerFragment;
@Override
public void createCoverage(FragmentActivity activity, int containerId) {
}
@Nullable
@Override
public Fragment createCoverage(@Nullable FragmentActivity activity, @Nullable Integer containerId) {
this.mActivity = activity;
this.mContainerId = containerId;
// UiThreadHandler.post(() -> stepIntoVrMode());
return null;
}
@NotNull
@Override
public String getFunctionName() {
return null;
}
@Override
public void onDestroy() {
// 若不调用finish, 设置中打开关闭UITouch,会造成och fragment 重叠
if (mActivity == null) return;
mActivity.finish();
}
@Override
public void init(Context context) {
MogoApisHandler.getInstance().getApis().getStatusManagerApi().registerStatusChangedListener("OchBus"
, StatusDescriptor.VR_MODE, this);
}
@Override
public void onStatusChanged(StatusDescriptor descriptor, boolean isTrue) {
if (descriptor == StatusDescriptor.VR_MODE) {
if (isTrue){
showFragment();
}else {
hideFragment();
}
}
}
/**
* 进入鹰眼模式,设置手势缩放地图失效
*/
private void stepIntoVrMode() {
CallerLogger.INSTANCE.d( M_TAXI_P + TAG, "进入vr模式" );
MogoMapUIController.getInstance()
.stepInVrMode( true ); // 白天模式
CallerMoGoUiSettingManager.INSTANCE.stepInDayMode();//白天模式 状态栏字体颜色变黑
}
private void showFragment() {
if (mPassengerFragment == null) {
CallerLogger.INSTANCE.d(M_TAXI_P + TAG, "准备add fragment======");
mPassengerFragment = new BusPassengerRouteFragment();
mActivity.getSupportFragmentManager().beginTransaction().add(mContainerId, mPassengerFragment).commitAllowingStateLoss();
return;
}
CallerLogger.INSTANCE.d(M_TAXI_P + TAG, "准备show fragment");
mActivity.getSupportFragmentManager().beginTransaction().show(mPassengerFragment).commitAllowingStateLoss();
}
private void hideFragment(){
if (mPassengerFragment != null){
mActivity.getSupportFragmentManager().beginTransaction().hide(mPassengerFragment).commitAllowingStateLoss();
}
}
}

View File

@@ -0,0 +1,152 @@
package com.mogo.och.bus.passenger.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import java.util.List;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.STATION_STATUS_STOPPED;
/**
* @author: wangmingjun
* @date: 2022/4/6
*/
public class BusPassengerLineStationsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<BusPassengerStation> mStations;
private static final int LINE_START_STATION_ITEM = 0;
private static final int LINE_END_STATION_ITEM = 1;
private static final int LINE_MIDDLE_STATION_ITEM = 2;
public BusPassengerLineStationsAdapter(Context context, List<BusPassengerStation> stations){
this.mContext = context;
this.mStations = stations;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == LINE_START_STATION_ITEM){
View view = LayoutInflater.from(mContext).inflate(R.layout.bus_p_stations_start_item,parent,false);
StartStationViewHolder viewHolder = new StartStationViewHolder(view);
return viewHolder;
}else if (viewType == LINE_END_STATION_ITEM) {
View view = LayoutInflater.from(mContext).inflate(R.layout.bus_p_stations_end_item,parent,false);
EndStationViewHolder viewHolder = new EndStationViewHolder(view);
return viewHolder;
}else {
View view = LayoutInflater.from(mContext).inflate(R.layout.bus_p_stations_middle_item,parent,false);
MiddleStationViewHolder viewHolder = new MiddleStationViewHolder(view);
return viewHolder;
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
BusPassengerStation station = mStations.get(position);
if (holder instanceof StartStationViewHolder){
StartStationViewHolder viewHolder = (StartStationViewHolder)holder;
viewHolder.startStationName.setText(station.getName());
if (station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving()){//到站
viewHolder.curStationBg.setVisibility(View.VISIBLE);
viewHolder.stationCircle.setVisibility(View.GONE);
viewHolder.startStationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_current_station_txt_color));
}else {
viewHolder.curStationBg.setVisibility(View.GONE);
viewHolder.stationCircle.setVisibility(View.VISIBLE);
viewHolder.startStationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_station_txt_color));
}
}else if (holder instanceof EndStationViewHolder){
EndStationViewHolder viewHolder = (EndStationViewHolder)holder;
viewHolder.endStationName.setText(station.getName());
BusPassengerStation preStation = mStations.get(position -1);
if ((preStation.getDrivingStatus() == STATION_STATUS_STOPPED && preStation.isLeaving())
|| (station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving())){//到站
viewHolder.curStationBg.setVisibility(View.VISIBLE);
viewHolder.stationCircle.setVisibility(View.GONE);
viewHolder.endStationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_current_station_txt_color));
}else {
viewHolder.curStationBg.setVisibility(View.GONE);
viewHolder.stationCircle.setVisibility(View.VISIBLE);
viewHolder.endStationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_station_txt_color));
}
}else {
MiddleStationViewHolder viewHolder = (MiddleStationViewHolder)holder;
viewHolder.middleStationName.setText(station.getName());
BusPassengerStation preStation = mStations.get(position -1);
if ((preStation.getDrivingStatus() == STATION_STATUS_STOPPED && preStation.isLeaving())
|| (station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving())) {//到站
viewHolder.curStationBg.setVisibility(View.VISIBLE);
viewHolder.middleStationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_current_station_txt_color));
}else {
viewHolder.curStationBg.setVisibility(View.GONE);
viewHolder.middleStationName.setTextColor(mContext.getResources().getColor(R.color.bus_p_station_txt_color));
}
}
}
@Override
public int getItemCount() {
return mStations.size();
}
@Override
public int getItemViewType(int position) {
//第一个要显示时间
if (position == 0){
return LINE_START_STATION_ITEM;
}else if (position == mStations.size() -1){
return LINE_END_STATION_ITEM;
}else {
return LINE_MIDDLE_STATION_ITEM;
}
}
}
class StartStationViewHolder extends RecyclerView.ViewHolder{
public TextView startStationName;
public ImageView stationCircle;
public ImageView curStationBg;
public StartStationViewHolder(@NonNull View itemView) {
super(itemView);
startStationName = itemView.findViewById(R.id.bus_p_start_station);
stationCircle = itemView.findViewById(R.id.bus_p_start_circle);
curStationBg = itemView.findViewById(R.id.bus_p_cur_start_station_tag);
}
}
class EndStationViewHolder extends RecyclerView.ViewHolder{
public TextView endStationName;
public ImageView stationCircle;
public ImageView curStationBg;
public EndStationViewHolder(@NonNull View itemView) {
super(itemView);
endStationName = itemView.findViewById(R.id.bus_p_end_station);
stationCircle = itemView.findViewById(R.id.bus_p_end_circle);
curStationBg = itemView.findViewById(R.id.bus_p_cur_end_station_tag);
}
}
class MiddleStationViewHolder extends RecyclerView.ViewHolder{
public TextView middleStationName;
public ImageView curStationBg;
public MiddleStationViewHolder(@NonNull View itemView) {
super(itemView);
middleStationName = itemView.findViewById(R.id.bus_p_middle_station);
curStationBg = itemView.findViewById(R.id.bus_p_middle_tag);
}
}

View File

@@ -0,0 +1,21 @@
package com.mogo.och.bus.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态返回参数
*/
public class BusPassengerOperationStatusResponse extends BaseData {
public Result data;
public static class Result {
private String sn; //司机屏sn
public String plateNumber; //车牌号
public int serviceStatus;//0:已收车1:已出车
public int businessType;// 车辆类型: taxi/bus
}
}

View File

@@ -0,0 +1,18 @@
package com.mogo.och.bus.passenger.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
public
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
class BusPassengerQueryLineRequest {
private String sn;
public BusPassengerQueryLineRequest(String sn) {
this.sn = sn;
}
}

View File

@@ -0,0 +1,27 @@
package com.mogo.och.bus.passenger.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* 网约车小巴路线接口请求响应结果 返回的是对应司机屏的线路信息
*
* @author tongchenfei
*/
public class BusPassengerRoutesResponse extends BaseData {
private BusPassengerRoutesResult data;
public BusPassengerRoutesResult getResult() {
return data;
}
public void setResult(BusPassengerRoutesResult data) {
this.data = data;
}
@Override
public String toString() {
return "OchBusRoutesResponse{" +
"data=" + data +
'}';
}
}

View File

@@ -0,0 +1,59 @@
package com.mogo.och.bus.passenger.bean;
import java.util.List;
/**
* 网约车小巴路线接口返回接口数据封装
*
* @author tongchenfei
*/
public class BusPassengerRoutesResult {
private List<BusPassengerStation> sites;
private int lineId;
private String name; //线路名称
private int lineType; //线路类型0:环形
private String description;
private int status;
private String runningDur; //运营时间
public List<BusPassengerStation> getSites() {
return sites;
}
public int getLineId() {
return lineId;
}
public String getName() {
return name;
}
public int getLineType() {
return lineType;
}
public String getDescription() {
return description;
}
public int getStatus() {
return status;
}
public String getRunningDur() {
return runningDur;
}
@Override
public String toString() {
return "BusPassengerRoutesResult{" +
"sites=" + sites +
", lineId=" + lineId +
", name='" + name + '\'' +
", lineType=" + lineType +
", description='" + description + '\'' +
", status=" + status +
", runningDur='" + runningDur + '\'' +
'}';
}
}

View File

@@ -0,0 +1,137 @@
package com.mogo.och.bus.passenger.bean;
/**
* 单个网约车小巴车站信息
*
* @author wangmingjun
*/
public class BusPassengerStation {
private String name;
private String description;
private String cityCode;
private double lon; //高精坐标
private double lat; //高精坐标
private int businessType; //站点类型9:taxi10:bus
private int status;
private int siteId;
private int seq;
private int drivingStatus;//行驶信息0初始值1已经过2当前站3未到站
private int ifStop = 1; // 是否需要停靠、1需要、0不需要 // TODO: 2021/10/19 原来站点里有设计是否需要停靠字段,现设计暂无,默认都需要停靠
private boolean leaving;
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setCityCode(String cityCode) {
this.cityCode = cityCode;
}
public void setLon(double lon) {
this.lon = lon;
}
public void setLat(double lat) {
this.lat = lat;
}
public void setBusinessType(int businessType) {
this.businessType = businessType;
}
public void setStatus(int status) {
this.status = status;
}
public void setSiteId(int siteId) {
this.siteId = siteId;
}
public void setSeq(int seq) {
this.seq = seq;
}
public void setDrivingStatus(int drivingStatus) {
this.drivingStatus = drivingStatus;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getCityCode() {
return cityCode;
}
public int getBusinessType() {
return businessType;
}
public int getStatus() {
return status;
}
public int getSiteId() {
return siteId;
}
public int getSeq() {
return seq;
}
public int getDrivingStatus() {
return drivingStatus;
}
public double getLon() {
return lon;
}
public double getLat() {
return lat;
}
public void setIfStop(int ifStop) {
this.ifStop = ifStop;
}
public int getIfStop() {
return ifStop;
}
public void setLeaving(boolean leaving) {
this.leaving = leaving;
}
public boolean isLeaving() {
return leaving;
}
@Override
public String toString() {
return "OchBusStation{" +
"name='" + name + '\'' +
", description='" + description + '\'' +
", cityCode='" + cityCode + '\'' +
", lon=" + lon +
", lat=" + lat +
", businessType=" + businessType +
", status=" + status +
", siteId=" + siteId +
", seq=" + seq +
", drivingStatus=" + drivingStatus +
", ifStop=" + ifStop +
", leaving=" + leaving +
'}';
}
}

View File

@@ -0,0 +1,10 @@
package com.mogo.och.bus.passenger.callback;
/**
* @author: wangmingjun
* @date: 2021/10/22
*/
public interface IBusPassegerDriverStatusCallback {
void changeOperationStatus(boolean changeStatus);
void updatePlateNumber(String plateNumber);
}

View File

@@ -0,0 +1,20 @@
package com.mogo.och.bus.passenger.callback;
/**
* Created on 2022/3/31
*
* Model->Presenter回调ADAS相关自动驾驶状态回调到达终点等等
*/
public interface IBusPassengerADASStatusCallback {
// 自动驾驶触发的已到达目的地:暂未用到
void onAutopilotArriveEnd();
// 自动驾驶可用状态
void onAutopilotEnable();
// 自动驾驶不可用状态
void onAutopilotDisable();
// 自动驾驶运行中
void onAutopilotRunning();
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.passenger.callback;
import com.amap.api.maps.model.LatLng;
import com.mogo.eagle.core.data.map.MogoLatLng;
import java.util.List;
import mogo.telematics.pad.MessagePad;
/**
* Created on 2022/3/31
*/
public interface IBusPassengerAutopilotPlanningCallback {
void routeResult(List<LatLng> models);
void routePlanningToNextStationChanged(long meters, long timeInSecond);
}

View File

@@ -0,0 +1,15 @@
package com.mogo.och.bus.passenger.callback;
import android.location.Location;
/**
* Created on 2022/3/31
*
* Model->Presenter回调状态控制器监听accOn、adas ui show、voice ui show、push ui show、v2x ui show等等
*/
public interface IBusPassengerControllerStatusCallback {
// 是否vr map模式
void onVRModeChanged(boolean isVRMode);
// 自车定位
void onCarLocationChanged(Location location);
}

View File

@@ -0,0 +1,9 @@
package com.mogo.och.bus.passenger.callback;
/**
* @author: wangmingjun
* @date: 2022/3/10
*/
public interface IBusPassengerMapViewCallback {
void onCameraChange(float bearing);
}

View File

@@ -0,0 +1,14 @@
package com.mogo.och.bus.passenger.callback;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/4/6
*/
public interface IBusPassengerRouteLineInfoCallback {
void updateLineInfo(String lineName, String lineDurTime);
void updateStationsInfo(List<BusPassengerStation> stations,int currentStationIndex,boolean isArrived);
}

View File

@@ -0,0 +1,44 @@
package com.mogo.och.bus.passenger.constant
import com.mogo.commons.debug.DebugConfig
/**
* Created on 2021/12/6
*/
class BusPassengerConst {
companion object {
private const val BASE_URL_OCH_DEV = "http://tech-dev.zhidaohulian.com"
private const val BASE_URL_OCH_QA = "https://tech-qa.zhidaohulian.com"
private const val BASE_URL_OCH_RELEASE = "https://tech.zhidaohulian.com"
@JvmStatic
fun getBaseUrl(): String {
return when (DebugConfig.getNetMode()) {
DebugConfig.NET_MODE_DEV, DebugConfig.NET_MODE_DEMO -> BASE_URL_OCH_DEV
DebugConfig.NET_MODE_QA -> BASE_URL_OCH_QA
DebugConfig.NET_MODE_RELEASE -> BASE_URL_OCH_RELEASE
else -> BASE_URL_OCH_RELEASE
}
}
// OCH arouter 路由path
const val PATH = "/och/api"
// 轮询line
const val LOOP_LINE_2S = 2 * 1000L
const val LOOP_DELAY = 100L
// 无状态
const val STATION_STATUS_IDLE = 0
// 已过站(历史站)
const val STATION_STATUS_LEAVING = 1
// 到站(当前站)
const val STATION_STATUS_STOPPED = 2
// 未到站(未到站)
const val STATION_STATUS_ARRIVING = 3
//bus平均速度
const val BUS_AVERAGE_SPEED = 25
}
}

View File

@@ -0,0 +1,414 @@
package com.mogo.och.bus.passenger.model;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.net.ConnectivityManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.amap.api.maps.model.LatLng;
import com.mogo.aicloud.services.socket.IMogoLifecycleListener;
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager;
import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.commons.debug.DebugConfig;
import com.mogo.eagle.core.data.autopilot.AutopilotStatusInfo;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotPlanningListenerManager;
import com.mogo.eagle.core.network.utils.GsonUtil;
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
import com.mogo.map.navi.IMogoCarLocationChangedListener2;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse;
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse;
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResult;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import com.mogo.och.bus.passenger.callback.IBusPassegerDriverStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerADASStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerAutopilotPlanningCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerControllerStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerRouteLineInfoCallback;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import com.mogo.och.bus.passenger.network.BusPassengerModelLoopManager;
import com.mogo.och.bus.passenger.network.BusPassengerServiceCallback;
import com.mogo.och.bus.passenger.network.BusPassengerServiceManager;
import com.mogo.och.bus.passenger.utils.BPCoordinateCalculateRouteUtil;
import com.mogo.service.intent.IMogoIntentListener;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.STATION_STATUS_STOPPED;
/**
* Created on 2022/3/31
*/
public class BusPassengerModel {
private static final String TAG = BusPassengerModel.class.getSimpleName();
private List<LatLng> mRoutePoints = new ArrayList<>();
private static final class SingletonHolder {
private static final BusPassengerModel INSTANCE = new BusPassengerModel();
}
public static BusPassengerModel getInstance() {
return SingletonHolder.INSTANCE;
}
private Context mContext;
private IBusPassengerADASStatusCallback mADASStatusCallback; //Model->Presenter自动驾驶状态相关
private IBusPassengerAutopilotPlanningCallback mAutopilotPlanningCallback; //Model->Presenter自动驾驶线路规划
private Map<String, IBusPassengerControllerStatusCallback> mControllerStatusCallbackMap = new ConcurrentHashMap<>();
private IBusPassegerDriverStatusCallback mDriverStatusCallback; //出车收车状态
private IBusPassengerRouteLineInfoCallback mRouteLineInfoCallback; // bus路线信息更新
private double mLongitude, mLatitude;
private BusPassengerModel() {
}
public void init( Context context ) {
mContext = context.getApplicationContext();
initListeners();
// TODO: 2022/3/31
queryDriverOperationStatus();
}
public void setDriverStatusCallback(IBusPassegerDriverStatusCallback callback){
this.mDriverStatusCallback = callback;
}
public void setRouteLineInfoCallback(IBusPassengerRouteLineInfoCallback callback){
this.mRouteLineInfoCallback = callback;
}
private void queryDriverOperationStatus() {
BusPassengerServiceManager.getInstance().queryDriverOperationStatus(mContext
, new BusPassengerServiceCallback<BusPassengerOperationStatusResponse>() {
@Override
public void onSuccess(BusPassengerOperationStatusResponse data) {
if (data == null || data.data == null) return;
startOrStopOrderLoop(data.data.serviceStatus == 1);
if(mDriverStatusCallback != null){
mDriverStatusCallback.changeOperationStatus(data.data.serviceStatus == 1);
mDriverStatusCallback.updatePlateNumber(data.data.plateNumber);
}
}
@Override
public void onFail(int code, String msg) {
queryDriverOperationStatus();
}
});
}
public void queryDriverSiteByCoordinate(){
BusPassengerServiceManager.getInstance().queryDriverSiteByCoordinate(mContext
, new BusPassengerServiceCallback<BusPassengerRoutesResponse>() {
@Override
public void onSuccess(BusPassengerRoutesResponse data) {
if ( data == null
|| data.getResult() == null
|| data.getResult().getSites() == null) {
return;
}
updatePassengerRouteInfo(data.getResult());
}
@Override
public void onFail(int code, String msg) {
}
});
}
private void updatePassengerRouteInfo(BusPassengerRoutesResult result) {
if (mRouteLineInfoCallback != null){
mRouteLineInfoCallback.updateLineInfo(result.getName(),result.getRunningDur());
if (result.getSites() != null){
List<BusPassengerStation> stations = result.getSites();
for (int i = 0; i< stations.size(); i++){
BusPassengerStation station = stations.get(i);
if (station.getDrivingStatus() == STATION_STATUS_STOPPED && station.isLeaving() && i+1 < stations.size()){
mRouteLineInfoCallback.updateStationsInfo(stations,i+1,false);
return;
}else if (station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving()){
startOrStopCalculateRouteInfo(false);
mRouteLineInfoCallback.updateStationsInfo(stations,i,true);
return;
}
}
}
}
}
public void release() {
releaseListeners();
startOrStopCalculateRouteInfo(false);
startOrStopOrderLoop(false);
}
public void setMoGoAutopilotPlanningListener(IBusPassengerAutopilotPlanningCallback
moGoAutopilotPlanningCallback) {
this.mAutopilotPlanningCallback = moGoAutopilotPlanningCallback;
}
public void setADASStatusCallback(IBusPassengerADASStatusCallback callback) {
this.mADASStatusCallback = callback;
}
public void setControllerStatusCallback(String tag, IBusPassengerControllerStatusCallback callback) {
if (tag == null || "".equals(tag)) return;
if (callback == null) {
mControllerStatusCallbackMap.remove(tag);
return;
}
mControllerStatusCallbackMap.put(tag,callback);
}
private void initListeners() {
MogoAiCloudSocketManager.getInstance(mContext)
.registerLifecycleListener(10010, mSocketLifeCycleLisnter);
// 2021.11.1重构自动驾驶 实现接口 IMoGoAutopilotStatusListener 注册监听 替换IMogoAdasOCHCallback接口
CallerAutoPilotStatusListenerManager.INSTANCE.addListener(TAG, mGoAutopilotStatusListener);
MogoApisHandler.getInstance()
.getApis()
.getIntentManagerApi()
.registerIntentListener( ConnectivityManager.CONNECTIVITY_ACTION, mNetWorkIntentListener );
MogoApisHandler.getInstance()
.getApis()
.getStatusManagerApi()
.registerStatusChangedListener( TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener );
// 达到起始站围栏监听
MogoApisHandler.getInstance()
.getApis()
.getRegisterCenterApi()
.registerCarLocationChangedListener( TAG, mCarLocationChangedListener2);
//2021.11.1 自动驾驶路线规划接口
CallerAutopilotPlanningListenerManager.INSTANCE.addListener(TAG,moGoAutopilotPlanningListener);
}
private void releaseListeners() {
MogoApisHandler.getInstance()
.getApis()
.getStatusManagerApi()
.unregisterStatusChangedListener(TAG, StatusDescriptor.VR_MODE, mMogoStatusChangedListener);
// 注销到达起始站围栏监听
MogoApisHandler.getInstance()
.getApis()
.getRegisterCenterApi()
.unregisterCarLocationChangedListener(TAG, mCarLocationChangedListener2);
MogoAiCloudSocketManager.getInstance(mContext)
.unregisterLifecycleListener(10010);
CallerAutoPilotStatusListenerManager.INSTANCE.removeListener(mGoAutopilotStatusListener);
CallerAutopilotPlanningListenerManager.INSTANCE.removeListener(moGoAutopilotPlanningListener);
}
//监听网络变化,避免启动机器时无网导致无法更新订单信息
private final IMogoIntentListener mNetWorkIntentListener = new IMogoIntentListener() {
@Override
public void onIntentReceived( String intentStr, Intent intent ) {
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "onIntentReceived = %s", intentStr );
if ( ConnectivityManager.CONNECTIVITY_ACTION.equals( intentStr ) ) {
if ( NetworkUtils.isConnected( mContext ) ) {
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
queryDriverOperationStatus();
}
}
}
}
};
private final IMogoStatusChangedListener mMogoStatusChangedListener = new IMogoStatusChangedListener() {
// VR mode变更回调
@Override
public void onStatusChanged(StatusDescriptor descriptor, boolean isTrue) {
if (StatusDescriptor.VR_MODE == descriptor) {
if (mControllerStatusCallbackMap.size() > 0) {
for (IBusPassengerControllerStatusCallback callback :mControllerStatusCallbackMap.values()){
callback.onVRModeChanged(isTrue);
}
}
}
}
};
private final IMogoLifecycleListener mSocketLifeCycleLisnter = new IMogoLifecycleListener() {
@Override
public void onConnectFailure() { CallerLogger.INSTANCE.e(M_BUS_P + TAG,"socket onConnectFailure"); }
@Override
public void onConnectSuccess() { CallerLogger.INSTANCE.e(M_BUS_P + TAG,"socket onConnectSuccess"); }
@Override
public void onConnectLost() { CallerLogger.INSTANCE.e(M_BUS_P + TAG,"socket onConnectLost"); }
};
// 自车定位
private final IMogoCarLocationChangedListener2 mCarLocationChangedListener2 = new IMogoCarLocationChangedListener2() {
@Override
public void onCarLocationChanged2( Location location ) {
//位置变化时通过围栏判断是否到达x点
// TODO: 2022/3/31
mLongitude = location.getLongitude();
mLatitude = location.getLatitude();
for (IBusPassengerControllerStatusCallback callback :mControllerStatusCallbackMap.values()){
callback.onCarLocationChanged(location);
}
}
};
private final IMoGoAutopilotStatusListener mGoAutopilotStatusListener = new IMoGoAutopilotStatusListener(){
@Override
public void onAutopilotGuardian(@Nullable MogoReportMsg.MogoReportMessage guardianInfo) {
}
private boolean arriveAtEnd = false; //乘客app专用字段
@Override
public void onAutopilotStatusResponse(@NotNull AutopilotStatusInfo autopilotStatusInfo) {
if (autopilotStatusInfo == null) return;
int state = autopilotStatusInfo.getState();
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "state = %s", state );
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotRunning();
// TODO: 2022/3/31
} else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) {
// TODO: 2022/3/31
if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotEnable();
} else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) {
// TODO: 2022/3/31
if (mADASStatusCallback != null) mADASStatusCallback.onAutopilotDisable();
}
}
@Override
public void onAutopilotSNRequest() {
}
@Override
public void onAutopilotArriveAtStation(@Nullable MessagePad.ArrivalNotification arrivalNotification) {
if (FunctionBuildConfig.isDemoMode
&& AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) {
arriveAtEnd = true;
}
// TODO: 2022/3/31
if (DebugConfig.isDebug()) {
// TipToast.shortTip("到达目的地");
}
if (mADASStatusCallback != null){
mADASStatusCallback.onAutopilotArriveEnd();
}
}
};
private final IMoGoAutopilotPlanningListener moGoAutopilotPlanningListener = new IMoGoAutopilotPlanningListener(){
@Override
public void onAutopilotTrajectory(@NonNull List<MessagePad.TrajectoryPoint> trajectoryInfos) {
}
@Override
public void onAutopilotRotting(@Nullable MessagePad.GlobalPathResp routeList) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "onAutopilotRotting = "
+ GsonUtil.jsonFromObject(routeList));
List<MessagePad.Location> mRoutePoints = routeList.getWayPointsList();
if (null != routeList && mRoutePoints.size() > 0){
updateRoutePoints(mRoutePoints);
}
}
};
public void dynamicCalculateRouteInfo() {
List<LatLng> lastPoints = BPCoordinateCalculateRouteUtil
.getRemainPointListByCompare(mRoutePoints,mLongitude,mLatitude);
float lastSumLength = 0;
if (lastPoints.size() == 1){ //只是最后一个点,计算当前位置和最后一个点的距离
lastSumLength = CoordinateUtils.calculateLineDistance(
lastPoints.get(0).longitude, lastPoints.get(0).latitude,
mLongitude, mLatitude);
}else {
lastSumLength = BPCoordinateCalculateRouteUtil.calculateRouteSumLength(lastPoints);
}
double lastTime = lastSumLength / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 ; //秒
if (mAutopilotPlanningCallback != null){
mAutopilotPlanningCallback.routePlanningToNextStationChanged((long)lastSumLength,(long) lastTime);
}
}
public void updateRoutePoints(List<MessagePad.Location> routePoints) {
if (mAutopilotPlanningCallback != null){
mAutopilotPlanningCallback.routeResult(
BPCoordinateCalculateRouteUtil.coordinateConverterWgsToGcjListCommon(mContext
, routePoints));
}
//转换成高德坐标系
mRoutePoints.clear();
mRoutePoints.addAll(BPCoordinateCalculateRouteUtil.coordinateConverterWgsToGcjListCommon(mContext,routePoints));
//开启实时计算剩余距离,剩余时间,预计时间
startOrStopCalculateRouteInfo(true);
}
/**
* 开始轮询计算剩余里程和时间
* @param isStart
*/
public void startOrStopCalculateRouteInfo(boolean isStart) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "startOrStopOrderLoop() " + isStart);
if (isStart) {
BusPassengerModelLoopManager.getInstance().startCalculateRouteInfoLoop();
} else {
mRoutePoints.clear();
BusPassengerModelLoopManager.getInstance().stopCalculateRouteInfLoop();
}
}
private void startOrStopOrderLoop(boolean start) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "startOrStopOrderLoop() " + start);
if (start) {
BusPassengerModelLoopManager.getInstance().startQueryDriverLineLoop();
} else {
BusPassengerModelLoopManager.getInstance().stopQueryDriverLineLoop();
}
}
}

View File

@@ -0,0 +1,79 @@
package com.mogo.och.bus.passenger.network;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.och.bus.passenger.model.BusPassengerModel;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.LOOP_DELAY;
import static com.mogo.och.bus.passenger.constant.BusPassengerConst.LOOP_LINE_2S;
/**
* Created on 2021/11/22
*
* 管理轮询逻辑(订单轮询、新单轮询、新单抢单结果轮询等等)
*/
public class BusPassengerModelLoopManager {
private static final String TAG = BusPassengerModelLoopManager.class.getSimpleName();
private Disposable mCalculateRouteDisposable; //每隔2s计算一次剩余里程和时间
private static final class SingletonHolder {
private static final BusPassengerModelLoopManager INSTANCE = new BusPassengerModelLoopManager();
}
public static BusPassengerModelLoopManager getInstance() {
return SingletonHolder.INSTANCE;
}
private Disposable mHeartbeatDisposable; //心跳轮询
public void startQueryDriverLineLoop() {
if (mHeartbeatDisposable != null && !mHeartbeatDisposable.isDisposed()) {
return;
}
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "startQueryDriverLineLoop()");
mHeartbeatDisposable = Observable.interval(LOOP_DELAY,
LOOP_LINE_2S, TimeUnit.MILLISECONDS)
.map((aLong -> aLong + 1))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> BusPassengerModel.getInstance().queryDriverSiteByCoordinate());
}
public void stopQueryDriverLineLoop() {
if (mHeartbeatDisposable != null) {
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "stopQueryDriverLineLoop()");
mHeartbeatDisposable.dispose();
mHeartbeatDisposable = null;
}
}
public void startCalculateRouteInfoLoop() {
if (mCalculateRouteDisposable != null && !mCalculateRouteDisposable.isDisposed()) {
return;
}
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "startCalculateRouteInfoLoop()");
mCalculateRouteDisposable = Observable.interval(LOOP_DELAY,
LOOP_LINE_2S, TimeUnit.MILLISECONDS)
.map((aLong -> aLong + 1))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> BusPassengerModel.getInstance().dynamicCalculateRouteInfo());
}
public void stopCalculateRouteInfLoop() {
if (mCalculateRouteDisposable != null) {
CallerLogger.INSTANCE.i(M_BUS_P + TAG, "stopCalculateRouteInfLoop()");
mCalculateRouteDisposable.dispose();
mCalculateRouteDisposable = null;
}
}
}

View File

@@ -0,0 +1,38 @@
package com.mogo.och.bus.passenger.network;
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse;
import com.mogo.och.bus.passenger.bean.BusPassengerQueryLineRequest;
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* Created on 2022/3/31
*
* Bus乘客端接口定义
*/
interface BusPassengerServiceApi {
/**
* 查询bus司机端绑定路线
* @return 接口返回数据
*/
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/line/v2/driver/bus/passenger/lineDataWithDriver/query" )
Observable<BusPassengerRoutesResponse> queryDriverSiteByCoordinate(@Header("appId") String appId, @Header("ticket") String ticket, @Body BusPassengerQueryLineRequest request);
/**
* 查询司机端出车/收车状态
* @param sn
* @return
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@GET("/autopilot-car-hailing/car/v2/driver/bus/passenger/takeOrderStatus/query")
Observable<BusPassengerOperationStatusResponse> queryDriverOperationStatus(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
}

View File

@@ -0,0 +1,15 @@
package com.mogo.och.bus.passenger.network;
/**
* Created on 2022/3/31
*/
public interface BusPassengerServiceCallback<T> {
void onSuccess(T data);
void onFail(int code, String msg);
default void onError() {
}
}

View File

@@ -0,0 +1,118 @@
package com.mogo.och.bus.passenger.network;
import android.content.Context;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager;
import com.mogo.eagle.core.network.MoGoRetrofitFactory;
import com.mogo.eagle.core.network.RequestOptions;
import com.mogo.eagle.core.network.SubscribeImpl;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.och.bus.passenger.bean.BusPassengerOperationStatusResponse;
import com.mogo.och.bus.passenger.bean.BusPassengerQueryLineRequest;
import com.mogo.och.bus.passenger.bean.BusPassengerRoutesResponse;
import com.mogo.och.bus.passenger.constant.BusPassengerConst;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
/**
* Created on 2022/3/31
*/
public class BusPassengerServiceManager {
private static final String TAG = BusPassengerServiceManager.class.getSimpleName();
private static final class SingletonHolder {
private static final BusPassengerServiceManager INSTANCE = new BusPassengerServiceManager();
}
public static BusPassengerServiceManager getInstance() {
return SingletonHolder.INSTANCE;
}
private BusPassengerServiceApi mBusPassengerServiceApi;
private BusPassengerServiceManager() {
if (mBusPassengerServiceApi == null){
mBusPassengerServiceApi = MoGoRetrofitFactory.getInstance(
BusPassengerConst.getBaseUrl()).create(BusPassengerServiceApi.class);
}
}
/**
* 获取Bus司机端的sn
* @return
*/
private String getDriverAppSn(){
return CallerTelematicManager.INSTANCE.getServerToken();
// return "X2020211111NG0XNFK";
}
/**
* 查询绑定行驶的小巴车路线
* @param context
* @param callback
*/
public void queryDriverSiteByCoordinate(Context context
,BusPassengerServiceCallback<BusPassengerRoutesResponse> callback){
mBusPassengerServiceApi.queryDriverSiteByCoordinate(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
,MoGoAiCloudClientConfig.getInstance().getToken()
,new BusPassengerQueryLineRequest(getDriverAppSn()))
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() )
.subscribe(getSubscribeImpl(context,callback,"queryDriverSiteByCoordinate"));
}
/**
* 查询司机端出车收车状态,以及车牌号
* @param context
* @param callback
*/
public void queryDriverOperationStatus(Context context, BusPassengerServiceCallback<BusPassengerOperationStatusResponse> callback){
mBusPassengerServiceApi.queryDriverOperationStatus(MoGoAiCloudClientConfig.getInstance().getServiceAppId()
,MoGoAiCloudClientConfig.getInstance().getToken()
,getDriverAppSn())
.subscribeOn( Schedulers.io() )
.observeOn( AndroidSchedulers.mainThread() )
.subscribe(getSubscribeImpl(context,callback,"queryDriverOperationStatus"));
}
private <T extends BaseData> SubscribeImpl getSubscribeImpl(
Context context, BusPassengerServiceCallback<T> callback, String apiName) {
return new SubscribeImpl<T>(RequestOptions.create(context)) {
@Override
public void onSuccess(T o) {
super.onSuccess(o);
CallerLogger.INSTANCE.e(M_BUS_P + TAG,apiName +
": onSuccess() " + o.msg);
if (callback != null) {
callback.onSuccess(o);
}
}
@Override
public void onError(Throwable e) {
super.onError(e);
CallerLogger.INSTANCE.e(M_BUS_P + TAG,apiName +
": onError() " + e.getMessage());
if (callback != null) {
callback.onError();
}
}
@Override
public void onError(String message, int code) {
super.onError(message, code);
CallerLogger.INSTANCE.e(M_BUS_P + TAG,String.format(apiName +
": onError() code = %d; message = %s;", code, message));
if (callback != null) {
callback.onFail(code, message);
}
}
};
}
}

View File

@@ -0,0 +1,147 @@
package com.mogo.och.bus.passenger.presenter;
import android.location.Location;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import com.amap.api.maps.model.LatLng;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import com.mogo.och.bus.passenger.callback.IBusPassegerDriverStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerADASStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerAutopilotPlanningCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerControllerStatusCallback;
import com.mogo.och.bus.passenger.callback.IBusPassengerRouteLineInfoCallback;
import com.mogo.och.bus.passenger.model.BusPassengerModel;
import com.mogo.och.bus.passenger.ui.BusPassengerRouteFragment;
import java.util.List;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
/**
* Created on 2022/3/31
*/
public class BaseBusPassengerPresenter extends Presenter<BusPassengerRouteFragment> implements
IBusPassengerADASStatusCallback, IBusPassengerControllerStatusCallback, IBusPassegerDriverStatusCallback, IBusPassengerRouteLineInfoCallback, IBusPassengerAutopilotPlanningCallback {
private static final String TAG = BaseBusPassengerPresenter.class.getSimpleName();
public BaseBusPassengerPresenter(BusPassengerRouteFragment view) {
super(view);
BusPassengerModel.getInstance().init(AbsMogoApplication.getApp());
initListeners();
}
@Override
public void onCreate( @NonNull LifecycleOwner owner ) {
super.onCreate( owner );
CallerLogger.INSTANCE.d( M_BUS_P + TAG, "Bus乘客端Presenter onCreate()" );
}
@Override
public void onDestroy( @NonNull LifecycleOwner owner ) {
super.onDestroy( owner );
releaseListeners();
BusPassengerModel.getInstance().release();
}
private void initListeners() {
BusPassengerModel.getInstance().setADASStatusCallback(this);
BusPassengerModel.getInstance().setControllerStatusCallback(TAG, this);
BusPassengerModel.getInstance().setDriverStatusCallback(this);
BusPassengerModel.getInstance().setRouteLineInfoCallback(this);
BusPassengerModel.getInstance().setMoGoAutopilotPlanningListener(this);
}
private void releaseListeners() {
BusPassengerModel.getInstance().setADASStatusCallback(null);
BusPassengerModel.getInstance().setControllerStatusCallback(TAG, null);
BusPassengerModel.getInstance().setDriverStatusCallback(null);
BusPassengerModel.getInstance().setRouteLineInfoCallback(null);
BusPassengerModel.getInstance().setMoGoAutopilotPlanningListener(null);
}
private void runOnUIThread( Runnable executor ) {
if ( executor == null ) {
return;
}
if ( Looper.myLooper() != Looper.getMainLooper() ) {
UiThreadHandler.post( executor );
} else {
executor.run();
}
}
@Override
public void onAutopilotArriveEnd() {
}
@Override
public void onAutopilotEnable() {
runOnUIThread(() -> mView.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE));
}
@Override
public void onAutopilotDisable() {
runOnUIThread(() -> mView.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE));
}
@Override
public void onAutopilotRunning() {
runOnUIThread(() -> mView.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING));
}
@Override
public void onVRModeChanged(boolean isVRMode) {
}
@Override
public void onCarLocationChanged(Location location) {
if (location != null){
runOnUIThread(() -> mView.onCarLocationChanged(location));
}
}
@Override
public void changeOperationStatus(boolean changeStatus) {
runOnUIThread(() -> mView.changeOperationStatus(changeStatus));
}
@Override
public void updatePlateNumber(String plateNumber) {
runOnUIThread(() -> mView.updatePlateNum(plateNumber));
}
@Override
public void updateLineInfo(String lineName, String lineDurTime) {
runOnUIThread(() -> mView.updateLineInfo(lineName, lineDurTime));
}
@Override
public void updateStationsInfo(List<BusPassengerStation> stations,int currentStationIndex,boolean isArrived) {
runOnUIThread(() -> mView.updateStationsInfo(stations,currentStationIndex, isArrived));
}
@Override
public void routeResult(List<LatLng> models) {
runOnUIThread(() -> mView.routeResult(models));
}
@Override
public void routePlanningToNextStationChanged(long meters, long timeInSecond) {
runOnUIThread(() -> mView.updateRoutePlanningToNextStation(meters, timeInSecond));
}
}

View File

@@ -0,0 +1,359 @@
package com.mogo.och.bus.passenger.ui;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.LinearLayout;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.utils.DimenUtil;
/**
* @author: wangmingjun
* @date: 2022/1/21
* 边框阴影
*/
public class BusBorderShadowLayout extends LinearLayout {
private static final String TAG = "ShadowLayout";
//默认阴影半径
public static final float SHADOW_DEFAULT_RADIUS = DimenUtil.INSTANCE.dp2px(5);
//阴影最大偏移量
public static final float SHADOW_MAX_OFFSET = DimenUtil.INSTANCE.dp2px(20);
//阴影最大模糊半径
public static final float SHADOW_MAX_BLUR = DimenUtil.INSTANCE.dp2px(20);
//默认模糊半径
public static final float SHADOW_DEFAULT_BLUR_RADIUS = DimenUtil.INSTANCE.dp2px(5);
//阴影颜色
private int shadowColor = Color.parseColor("#333333");
//阴影类型,0:默认为单边 1:单边 2:邻边 3:四边所有
private int shadowType;
//阴影半径
private float shadowRadius = 0f;
//模糊度半径
private float blurRadius = SHADOW_DEFAULT_BLUR_RADIUS ;
//水平位移
private float xOffset = DimenUtil.INSTANCE.dp2px(10);
//竖直方向位移
private float yOffset = DimenUtil.INSTANCE.dp2px(0);
//背景色
private int bgColor = Color.WHITE;
//是否有点击效果
private boolean hasEffect = false ;
int left =0 ,right =0,top = 0,bottom = 0 ;
//代理方式
private IShadow shadow = new BusBorderShadowLayout.ShadowConfig(this);
private float mWidthMode;
private float mHeightMode;
private Paint mPaint = new Paint();
private Paint locationPaint = new Paint();
public BusBorderShadowLayout(Context context) {
super(context,null);
}
public BusBorderShadowLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public BusBorderShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowLayout);
shadowColor = typedArray.getColor(R.styleable.ShadowLayout_shadowColor, Color.BLUE);
blurRadius = typedArray.getDimension(R.styleable.ShadowLayout_blurRadius, SHADOW_DEFAULT_BLUR_RADIUS);
shadowRadius = typedArray.getDimension(R.styleable.ShadowLayout_shadowRadius,0);
hasEffect = typedArray.getBoolean(R.styleable.ShadowLayout_hasEffect, false);
xOffset = typedArray.getDimension(R.styleable.ShadowLayout_xOffset,DimenUtil.INSTANCE.dp2px(10));
yOffset = typedArray.getDimension(R.styleable.ShadowLayout_yOffset,DimenUtil.INSTANCE.dp2px(10));
bgColor = typedArray.getColor(R.styleable.ShadowLayout_bgColor,Color.WHITE);
typedArray.recycle();
if (shadowRadius<0){
shadowRadius = -shadowRadius;
}
if (blurRadius < 0) {
blurRadius = -blurRadius;
}
blurRadius = Math.min(SHADOW_MAX_BLUR,blurRadius);
if (Math.abs(xOffset)> SHADOW_MAX_OFFSET){
xOffset = xOffset/Math.abs(xOffset) * SHADOW_MAX_OFFSET;
}
if (Math.abs(yOffset) > SHADOW_MAX_OFFSET){
yOffset = yOffset/Math.abs(yOffset) * SHADOW_MAX_OFFSET;
}
init();
}
private void init(){
setBackgroundColor(Color.parseColor("#00ffffff"));
if (xOffset>0){
//水平偏移量为正数右侧有阴影阴影长度为blurRadius+|xOffset|
right = (int)(blurRadius + Math.abs(xOffset));
}else if (xOffset==0){
//水平偏移为0,水平间距为blurRadius
left = (int)blurRadius;
right = (int)blurRadius;
}else {
//水平偏移为负数,左侧有阴影阴影长度为blurRadius+|xOffset|
left = (int)(blurRadius + Math.abs(xOffset));
}
if (yOffset>0){
//竖直偏移量为正数底部有阴影阴影长度为blurRadius+|yOffset|
bottom = (int)(blurRadius + Math.abs(yOffset));
}else if (yOffset==0){
//竖直偏移量为0竖直间距为blurRadius
top = (int)blurRadius;
bottom = (int)blurRadius;
}else {
//竖直偏移量为负数顶部有阴影阴影长度为blurRadius+|yOffset|
top = (int)(blurRadius + Math.abs(yOffset));
}
setPadding(left,top,right,bottom);
}
/**
* 获取阴影设置
* @return 返回阴影设置配置
*/
public IShadow getShadowConfig(){
return shadow;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed,l,t,r,b);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
}
@Override
protected void onDraw(Canvas canvas) {
drawBackground(canvas);//放在super前是后景相反是前景前景会覆盖子布局
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
//绘制背景色(在子view底部)
private void drawBackground(Canvas canvas){
mWidthMode = getMeasuredWidth();
mHeightMode = getMeasuredHeight();
float startX = 0;
float startY = 0;
float endX = 0;
float endY = 0;
if (xOffset==0){
startX = right;
endX = mWidthMode-blurRadius;
}else {
startX = right+blurRadius;
endX = mWidthMode-left-blurRadius;
}
if (yOffset==0){
startY = bottom;
endY = mHeightMode-blurRadius;
}else {
startY = bottom+blurRadius;
endY = mHeightMode-top-blurRadius;
}
// mPaint.setShadowLayer(blurRadius,0,0,shadowColor);
if (blurRadius>0){
mPaint.setMaskFilter(new BlurMaskFilter(blurRadius,BlurMaskFilter.Blur.NORMAL));
}
mPaint.setColor(shadowColor);
mPaint.setAntiAlias(true);
RectF shadowRect = new RectF(startX,startY,endX,endY);
RectF locationRectF = new RectF(left,top,mWidthMode-right,mHeightMode-bottom);
if (shadowRadius==0){
//不是圆角
canvas.drawRect(shadowRect,mPaint);
}else {
//圆角角度为shadowRadius
canvas.drawRoundRect(shadowRect,shadowRadius,shadowRadius,mPaint);
}
locationPaint.setColor(bgColor);
locationPaint.setAntiAlias(true);
if (shadowRadius==0){
//不是圆角
canvas.drawRect(locationRectF,locationPaint);
}else {
//圆角角度为shadowRadius
canvas.drawRoundRect(locationRectF,shadowRadius,shadowRadius,locationPaint);
}
}
/**
* 阴影配置
*/
class ShadowConfig implements IShadow {
//代理
private BusBorderShadowLayout shadow;
private ShadowConfig(BusBorderShadowLayout shadow) {
this.shadow = shadow;
}
@Override
public IShadow setShadowRadius(float radius) {
return setShadowRadius(TypedValue.COMPLEX_UNIT_DIP,radius);
}
@Override
public IShadow setShadowRadius(int unit, float radius) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
shadow.shadowRadius = Math.abs(TypedValue.applyDimension(unit,radius,r.getDisplayMetrics()));
return this;
}
@Override
public IShadow setShadowColor(int color) {
shadow.shadowColor = color;
return this;
}
@Override
public IShadow setShadowColorRes(int colorRes) {
shadow.shadowColor = shadow.getResources().getColor(colorRes);
return this;
}
@Override
public IShadow setBlurRadius(float radius) {
return setBlurRadius(TypedValue.COMPLEX_UNIT_DIP,radius);
}
@Override
public IShadow setBlurRadius(int unit, float radius) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
shadow.blurRadius = Math.min(SHADOW_MAX_BLUR,Math.abs(TypedValue.applyDimension(unit,radius,r.getDisplayMetrics())));
return this;
}
@Override
public IShadow setXOffset(float offset) {
return setXOffset(TypedValue.COMPLEX_UNIT_DIP,offset);
}
@Override
public IShadow setXOffset(int unit, float offset) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
float x = TypedValue.applyDimension(unit,offset,r.getDisplayMetrics());
if (Math.abs(x)> SHADOW_MAX_OFFSET){
x = x/Math.abs(x) * SHADOW_MAX_OFFSET;
}
shadow.xOffset = x;
return this;
}
@Override
public IShadow setYOffset(float offset) {
return setYOffset(TypedValue.COMPLEX_UNIT_DIP,offset);
}
@Override
public IShadow setYOffset(int unit, float offset) {
Context c = getContext();
Resources r;
if (c == null) {
r = Resources.getSystem();
} else {
r = c.getResources();
}
float y = TypedValue.applyDimension(unit,offset,r.getDisplayMetrics());
if (Math.abs(y)> SHADOW_MAX_OFFSET){
y = y/Math.abs(y) * SHADOW_MAX_OFFSET;
}
shadow.yOffset = y;
return this;
}
@Override
public void commit() {
shadow.init();
shadow.requestLayout();
shadow.postInvalidate();
}
}
}

View File

@@ -0,0 +1,142 @@
package com.mogo.och.bus.passenger.ui;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.mogo.commons.mvp.IView;
import com.mogo.commons.mvp.MvpFragment;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.call.map.CallerSmpManager;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.utils.BPDateTimeUtil;
/**
* Created on 2022/3/31
* <p>
* Bus乘客端基础Fragment
*/
public abstract class BusPassengerBaseFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> {
private static final String TAG = BusPassengerBaseFragment.class.getSimpleName();
private TextView mCurrentArriveStation;
private TextView mCurrentArriveStationTitle;
private TextView mCurrentArriveTip;
private ImageView mAutopilotIv;
private FrameLayout flContainer;
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
private int mPrevAPStatus = -1;
@Override
protected int getLayoutId() {
return R.layout.bus_p_base_fragment;
}
@Override
public String getTagName() {
return TAG;
}
@Override
protected void initViews() {
//隐藏小地图
CallerSmpManager.INSTANCE.hidePanel();
mCurrentArriveStation = findViewById(R.id.bus_p_cur_station_name);
mCurrentArriveStationTitle = findViewById(R.id.bus_p_cur_station_title);
mCurrentArriveTip = findViewById(R.id.bus_p_cur_station_tip);
mAutopilotIv = findViewById(R.id.bus_p_autopilot_iv);
showRouteFragment();
}
@Override
protected void initViews(Bundle savedInstanceState) {
super.initViews(savedInstanceState);
}
/**
* 获取站点面板view在{@link #initViews()}时候添加到container中
*
* @return 站点面板view
*/
public abstract int getStationPanelViewId();
/**
* 显示线路信息
*/
public void showRouteFragment() {
flContainer = findViewById(R.id.bus_p_route_panel);
LayoutInflater.from(getContext()).inflate(getStationPanelViewId(), flContainer);
}
public void updateArrivedStation(String station,int currentIndex,boolean isArrived){
if (null == station){
mCurrentArriveStation.setText("----");
}else {
mCurrentArriveStation.setText(station);
if (currentIndex == 0){
mCurrentArriveStationTitle.setText(getResources().getString(R.string.bus_p_cur_station_title_init));
mCurrentArriveTip.setText(getResources().getString(R.string.bus_p_cur_station_arrived_tip_init));
return;
}
if (isArrived){
mCurrentArriveStationTitle.setText(getResources().getString(R.string.bus_p_cur_station_title));
mCurrentArriveTip.setText(getResources().getString(R.string.bus_p_cur_station_arrived_tip));
}else {
mCurrentArriveStationTitle.setText(getResources().getString(R.string.bus_p_cur_next_station_title));
}
}
}
public void updateRoutePlanningToNextStation(long meters, long timeInSecond){
String dis = "0";
String disUnit = "公里";
if (meters > 0){
if (meters / 1000 < 1){
disUnit = "";
dis = String.valueOf(Math.round(meters));
}else {
disUnit = "公里";
dis = BPDateTimeUtil.formatLong((double)meters / 1000);
}
}
String strHtml2 = "<font color=\"#2D3E5F\">距离 </font>" + "<b><font color=\"#0043FF\">" + dis + "</font></b>" + "<font color=\"#2D3E5F\"> "+disUnit+"</font>"
+ "<font color=\"#2D3E5F\"> &nbsp 剩余 </font>" + "<b><font color=\"#0043FF\">" + (int)Math.ceil((double)timeInSecond/ 60f) + "</font></b>" + "<font color=\"#2D3E5F\"> 分钟</font>";
mCurrentArriveTip.setText(Html.fromHtml(strHtml2));
}
public void onAutopilotStatusChanged(int status) {
getActivity().runOnUiThread(() -> {
// 3. 其他过程直接更新
if (mPrevAPStatus != status){
AutopilotStatusChanged(status);
}
mPrevAPStatus = status;
});
}
public void AutopilotStatusChanged(int status) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == status) {
mAutopilotIv.setImageResource(R.drawable.bus_p_auto_nor);
} else if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE == status){
mAutopilotIv.setImageResource(R.drawable.bus_p_un_auto_nor);
} else {
mAutopilotIv.setImageResource(R.drawable.bus_p_un_auto_nor);
}
}
}

View File

@@ -0,0 +1,352 @@
package com.mogo.och.bus.passenger.ui;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
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.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.CustomMapStyleOptions;
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.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.map.listener.IMoGoMapLocationListener;
import com.mogo.eagle.core.function.call.map.CallerMapLocationListenerManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.callback.IBusPassengerMapViewCallback;
import com.mogo.och.bus.passenger.utils.BusPassengerMapAssetStyleUtil;
import java.util.ArrayList;
import java.util.List;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
/**
* 乘客屏小地图
*/
public class BusPassengerMapDirectionView
extends RelativeLayout
implements IMoGoMapLocationListener, IBusPassengerMapDirectionView, AMap.OnCameraChangeListener {
//小地图名称
public static final String TAG = "TPMapDirectionView";
private TextureMapView mAMapNaviView;
private AMap mAMap;
private Marker mCarMarker;
private Marker mStartMarker;
private Marker mEndMarker;
private int mCurrentIndex = -1;
private int zoomLevel = 13;
private List<LatLng> mCoordinatesLatLng = new ArrayList<>();
private List<LatLng> mLinePointsLatLng = new ArrayList<>();
private Polyline mPolyline;
private CameraUpdate mCameraUpdate;
private Context mContext;
private List<Integer> colorList = new ArrayList<>();
private List<Marker> mLineMarkers = new ArrayList<>();
private IBusPassengerMapViewCallback mIBusPassengerMapViewCallback;
public BusPassengerMapDirectionView(Context context) {
this(context, null);
}
public BusPassengerMapDirectionView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BusPassengerMapDirectionView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
try {
initView(context);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setTaxiPassengerMapViewCallback(IBusPassengerMapViewCallback iBusPassengerMapViewCallback) {
this.mIBusPassengerMapViewCallback = iBusPassengerMapViewCallback;
}
private void initView(Context context) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "initView");
mContext = context;
View smpView = LayoutInflater.from(context).inflate(R.layout.bus_p_map_view, this);
mAMapNaviView = (TextureMapView) smpView.findViewById(R.id.bus_p_line_amap_view);
initAMapView();
// 注册定位监听
CallerMapLocationListenerManager.INSTANCE.addListener(TAG, this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// 注册定位监听
CallerMapLocationListenerManager.INSTANCE.removeListener(TAG);
}
private void initAMapView() {
// mCameraUpdate = CameraUpdateFactory.zoomTo(zoomLevel);
mAMap = mAMapNaviView.getMap();
// 设置导航地图模式aMap是地图控制器对象。
mAMap.setMapType(AMap.MAP_TYPE_NIGHT);
// 关闭显示实时路况图层aMap是地图控制器对象。
mAMap.setTrafficEnabled(false);
// 设置 锚点 图标
mCarMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_car))
.anchor(0.5f, 0.5f));
mStartMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_view_dir_way_point)));
mEndMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_view_dir_end_point)));
// 加载自定义样式
CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions()
.setEnable(true)
.setStyleData(BusPassengerMapAssetStyleUtil.getAssetsStyle(getContext(), "map_style.data"))
.setStyleExtraData(BusPassengerMapAssetStyleUtil.getAssetsExtraStyle(getContext(), "map_style_extra.data"));
// 设置自定义样式
mAMap.setCustomMapStyle(customMapStyleOptions);
//设置希望展示的地图缩放级别
// mAMap.moveCamera(mCameraUpdate);
// 设置地图的样式
UiSettings uiSettings = mAMap.getUiSettings();
uiSettings.setZoomControlsEnabled(false);// 地图缩放级别的交换按钮
uiSettings.setAllGesturesEnabled(false);// 所有手势
uiSettings.setMyLocationButtonEnabled(false); // 显示默认的定位按钮
uiSettings.setLogoBottomMargin(-150); //设置Logo下边界距离屏幕底部的边距,设置为负值即可
mAMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
@Override
public void onMapLoaded() {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "smp---onMapLoaded");
// 加载自定义样式
CustomMapStyleOptions customMapStyleOptions = new CustomMapStyleOptions()
.setEnable(true)
.setStyleData(BusPassengerMapAssetStyleUtil.getAssetsStyle(getContext(), "map_style.data"))
.setStyleExtraData(BusPassengerMapAssetStyleUtil.getAssetsExtraStyle(getContext(), "map_style_extra.data"));
// 设置自定义样式
mAMap.setCustomMapStyle(customMapStyleOptions);
mAMapNaviView.getMap().setPointToCenter(mAMapNaviView.getWidth() / 2, mAMapNaviView.getHeight() / 2);
}
});
//设置地图状态的监听接口
mAMap.setOnCameraChangeListener(this);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
@Override
public void onLocationChanged(@Nullable MogoLocation location, int from) {
if (location == null) {
return;
}
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "onCarLocationChanged2 :" + location.getLatitude() + ":" + location.getLongitude());
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
//更新车辆位置
if (mCarMarker != null) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "location.getBearing() = " + location.getBearing());
mCarMarker.setRotateAngle(360 - location.getBearing());
mCarMarker.setPosition(currentLatLng);
mCarMarker.setToTop();
}
if (mLinePointsLatLng.size() > 1){
//圈定地图显示范围
//存放经纬度
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
for (int i = 0; i < mLinePointsLatLng.size(); i++) {
boundsBuilder.include(mLinePointsLatLng.get(i));
}
boundsBuilder.include(currentLatLng);
//第二个参数为四周留空宽度
mAMap.animateCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(),100,100,100,100));
}else {
//设置希望展示的地图缩放级别
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(mCarMarker.getPosition()).tilt(0).bearing(location.getBearing()).zoom(zoomLevel).build();
mAMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
@Override
public void drawablePolyline() {
clearPolyline();
if (mAMap != null) {
addRouteColorList();
if (mCoordinatesLatLng.size() > 2) {
// 设置开始结束Marker位置
LatLng startLatLng = mCoordinatesLatLng.get(0);
LatLng endLatLng = mCoordinatesLatLng.get(mCoordinatesLatLng.size() - 1);
mStartMarker.setPosition(startLatLng);
mEndMarker.setPosition(endLatLng);
mStartMarker.setVisible(true);
mEndMarker.setVisible(true);
//设置线段纹理
PolylineOptions polylineOptions = new PolylineOptions();
polylineOptions.addAll(mCoordinatesLatLng);
polylineOptions.colorValues(colorList);
polylineOptions.useGradient(true);
polylineOptions.width(10); //线段宽度
polylineOptions.lineCapType(PolylineOptions.LineCapType.LineCapRound);
// 绘制线
mPolyline = mAMap.addPolyline(polylineOptions);
}
}
}
/**
* 添加画线颜色值
*/
private void addRouteColorList() {
for (int i = 0; i < mCoordinatesLatLng.size(); i++) {
colorList.add(Color.argb(255, 70, 147, 253));//路线颜色
}
}
@Override
public void clearPolyline() {
if (mPolyline != null) {
mPolyline.remove();
}
if (mStartMarker != null) {
mStartMarker.setVisible(false);
}
if (mEndMarker != null) {
mEndMarker.setVisible(false);
}
}
public void clearCoordinatesLatLng(){
mCoordinatesLatLng.clear();
}
public void onCreateView(Bundle savedInstanceState) {
if (mAMapNaviView != null) {
mAMapNaviView.onCreate(savedInstanceState);
}
}
public void onResume() {
if (mAMapNaviView != null) {
mAMapNaviView.onResume();
}
}
public void onPause() {
if (mAMapNaviView != null) {
mAMapNaviView.onPause();
}
mCurrentIndex = -1;
}
public void onDestroy() {
if (mAMapNaviView != null) {
mAMapNaviView.onDestroy();
}
mCurrentIndex = -1;
}
public void setCoordinatesLatLng(List<LatLng> latLngs) {
mCoordinatesLatLng.clear();
mCoordinatesLatLng.addAll(latLngs);
}
public void clearLineMarkers(){
for (int i =0; i< mLineMarkers.size();i++){
mLineMarkers.get(i).setVisible(false);
}
mLineMarkers.clear();
}
public void setLineMarkersAndDraw(List<LatLng> lineineLatLngs){
clearLineMarkers();
for (int i = 0; i < lineineLatLngs.size(); i++) {
Marker mWayPointMarker = mAMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_p_map_view_dir_way_point)));
mLineMarkers.add(mWayPointMarker);
}
if (mCoordinatesLatLng.size() == 0) {
for (int i = 0; i < mLineMarkers.size(); i++) {
mLineMarkers.get(i).setPosition(lineineLatLngs.get(i));
mLineMarkers.get(i).setVisible(true);
}
mCurrentIndex = -1;
}
}
public void setLinePointMarkerAndDraw(List<LatLng> routeLineLatLngs, int currentIndex) {
mLinePointsLatLng.clear();
mLinePointsLatLng.addAll(routeLineLatLngs);
if (mCoordinatesLatLng.size() > 0 && mCurrentIndex != currentIndex) {
if (mAMap != null && mLineMarkers.size() > 0) {
mCurrentIndex = currentIndex;
for (int i = 0; i < mLineMarkers.size(); i++) {
if (i != currentIndex && i + 1 != currentIndex) {
mLineMarkers.get(i).setPosition(mLinePointsLatLng.get(i));
mLineMarkers.get(i).setVisible(true);
} else {
mLineMarkers.get(i).setVisible(false);
}
}
}
}
}
@Override
public void onCameraChange(CameraPosition cameraPosition) {
mIBusPassengerMapViewCallback.onCameraChange(cameraPosition.bearing);
}
@Override
public void onCameraChangeFinish(CameraPosition cameraPosition) {
}
}

View File

@@ -0,0 +1,285 @@
package com.mogo.och.bus.passenger.ui;
import android.location.Location;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.amap.api.maps.model.LatLng;
import com.mogo.eagle.core.data.app.AppConfigInfo;
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.bus.passenger.R;
import com.mogo.och.bus.passenger.adapter.BusPassengerLineStationsAdapter;
import com.mogo.och.bus.passenger.bean.BusPassengerStation;
import com.mogo.och.bus.passenger.callback.IBusPassengerMapViewCallback;
import com.mogo.och.bus.passenger.presenter.BaseBusPassengerPresenter;
import com.mogo.och.bus.passenger.utils.BPCoordinateCalculateRouteUtil;
import com.mogo.och.bus.passenger.utils.BPRouteDataTestUtils;
import java.util.ArrayList;
import java.util.List;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
/**
* @author: wangmingjun
* @date: 2022/4/12
*/
public class BusPassengerRouteFragment extends
BusPassengerBaseFragment<BusPassengerRouteFragment, BaseBusPassengerPresenter> implements IBusPassengerMapViewCallback {
private final String TAG = "BusPassengerRouteFragment";
private BusPassengerTrafficLightView mTrafficLightView;
private List<BusPassengerStation> mStationsList = new ArrayList<>();
private List<LatLng> mLinePointsList = new ArrayList<>();
private TextView mSpeedTv;
private ConstraintLayout mNoLineInfoView;
private TextView mCarPlateNum;
private TextView mLineName;
private TextView mOperationTime;
private ConstraintLayout mRouteInfoView;
private RecyclerView mStationsListRv;
private BusPassengerMapDirectionView mMapDirectionView;
private ImageView mMapArrowIcon;
private RotateAnimation rotateAnimation;
private float lastBearing = 0;
private BusPassengerLineStationsAdapter mAdapter;
@Override
public int getStationPanelViewId() {
return R.layout.bus_p_route_fragment;
}
@NonNull
@Override
protected BaseBusPassengerPresenter createPresenter() {
return new BaseBusPassengerPresenter(this);
}
@Override
protected void initViews() {
super.initViews();
mTrafficLightView = findViewById(R.id.bus_p_traffic_light_view);
CallerHmiManager.INSTANCE.setProxyTrafficLightView(mTrafficLightView);
mSpeedTv = findViewById(R.id.bus_p_speed_tv);
mNoLineInfoView =findViewById(R.id.bus_p_no_order_data_view);
mCarPlateNum = findViewById(R.id.bus_p_driver_num_plate_tv);
mLineName = findViewById(R.id.bus_p_line_name_tv);
mOperationTime = findViewById(R.id.line_operation_time_tv);
mRouteInfoView = findViewById(R.id.bus_p_line_cl);
mStationsListRv = findViewById(R.id.bus_p_line_stations_rl);
LinearLayoutManager manager = new LinearLayoutManager(getContext());
mStationsListRv.setLayoutManager(manager);
mAdapter = new BusPassengerLineStationsAdapter(getContext(), mStationsList);
mStationsListRv.setAdapter(mAdapter);
mMapArrowIcon = findViewById(R.id.bus_p_arrow_nor);
//测试
mSpeedTv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
BPRouteDataTestUtils.converToRouteData();
UiThreadHandler.postDelayed(new Runnable() {
@Override
public void run() {
updateWayPointList(mStationsList,1);
}
},1000);
return false;
}
});
}
@Override
protected void initViews(Bundle savedInstanceState) {
super.initViews(savedInstanceState);
mMapDirectionView = findViewById(R.id.bus_p_line_map_view);
mMapDirectionView.onCreateView(savedInstanceState);
mMapDirectionView.setTaxiPassengerMapViewCallback(this);
}
@Override
public void onResume() {
super.onResume();
if (mMapDirectionView != null) {
mMapDirectionView.onResume();
}
}
@Override
public void onPause() {
super.onPause();
if (mMapDirectionView != null) {
mMapDirectionView.onPause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mMapDirectionView != null) {
mMapDirectionView.onDestroy();
}
}
public void routeResult(List<LatLng> latLngList) {
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "routeResult:" + latLngList.size());
if (latLngList.size() > 0) {
drawablePolyline(latLngList);
} else {
clearPolyline();
}
}
/**
* 绘制
*
* @param coordinates
*/
private void drawablePolyline(List<LatLng> coordinates) {
if (mMapDirectionView != null) {
mMapDirectionView.setCoordinatesLatLng(coordinates);
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
mMapDirectionView.drawablePolyline();
}
});
}
}
public void clearPolyline() {
if (mMapDirectionView != null) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
mMapDirectionView.clearPolyline();
}
});
}
}
public void setLineMarkers(List<LatLng> list) {
if (mMapDirectionView != null) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
mMapDirectionView.setLineMarkersAndDraw(list);
}
});
}
}
public void changeOperationStatus(boolean status) {
if (status) {
mNoLineInfoView.setVisibility(View.GONE);
mRouteInfoView.setVisibility(View.VISIBLE);
} else {
mNoLineInfoView.setVisibility(View.VISIBLE);
mRouteInfoView.setVisibility(View.GONE);
}
}
public void updatePlateNum(String plateNum){
if ("".equals(plateNum) || null == plateNum) {
mCarPlateNum.setText("-- --");
}else {
mCarPlateNum.setText((plateNum));
}
}
public void updateLineInfo(String lineName, String lineDurTime) {
mLineName.setText(lineName);
mOperationTime.setText(lineDurTime);
}
/**
*
* @param stations
* @param currentStationIndex
* @param isArrived 是否到站并离开true 到达当前站 currentStationIndex 未离开, false 正在前往此站 currentStationIndex
*/
public void updateStationsInfo(List<BusPassengerStation> stations, int currentStationIndex,boolean isArrived) {
updateArrivedStation(stations.get(currentStationIndex).getName(),currentStationIndex,isArrived);
mStationsList.clear();
mStationsList.addAll(stations);
mAdapter.notifyDataSetChanged();
if (currentStationIndex == 0 && isArrived){ //到达始发站且并未出发, 恢复站点marker 清楚路径 清空路径点
clearPolyline();
if (mMapDirectionView != null) mMapDirectionView.clearCoordinatesLatLng();
}
if (stations.size() > 0){
updateWayPointList(stations,currentStationIndex);
}
}
private void updateWayPointList(List<BusPassengerStation> stations,int currentStationIndex) {
mLinePointsList.clear();
for (int i = 0; i< stations.size(); i++) {//站点集合
LatLng latLng = BPCoordinateCalculateRouteUtil.coordinateConverterWgsToGcj(getContext()
,stations.get(i).getLon(),stations.get(i).getLat());// lat,lon
mLinePointsList.add(latLng);
}
setLineMarkers(mLinePointsList);
if (mMapDirectionView != null) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
mMapDirectionView.setLinePointMarkerAndDraw(mLinePointsList,currentStationIndex);
}
});
}
}
@Override
public void onCameraChange(float bearing) {
startIvCompass(bearing);
}
/**
* 设置指南针旋转
*
* @param bearing
*/
private void startIvCompass(float bearing) {
bearing = 360 - bearing;
CallerLogger.INSTANCE.d(M_BUS_P + TAG, "startIvCompass: " + bearing);
rotateAnimation = new RotateAnimation(lastBearing, bearing, Animation.RELATIVE_TO_SELF
, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setFillAfter(true);
mMapArrowIcon.startAnimation(rotateAnimation);
lastBearing = bearing;
}
public void onCarLocationChanged(Location location) {
updateSpeedView(location.getSpeed());
}
public void updateSpeedView(float speed){
int speedKM = (int) (Math.abs(speed) * 3.6F);
mSpeedTv.setText(String.valueOf(speedKM));
}
}

View File

@@ -0,0 +1,157 @@
package com.mogo.och.bus.passenger.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.TextView;
import com.mogo.eagle.core.function.api.hmi.view.IViewTrafficLight;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.bus.passenger.R;
import org.jetbrains.annotations.Nullable;
/**
* bus乘客端红绿灯view
*
* Created on 2022/3/14
*/
public class BusPassengerTrafficLightView extends IViewTrafficLight {
private ImageView mLightIconIV;
private TextView mLightTimeTV;
private int mCurrentLightId;
public BusPassengerTrafficLightView(@Nullable Context context) {
this(context, null, 0);
}
public BusPassengerTrafficLightView(@Nullable Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BusPassengerTrafficLightView(@Nullable Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.bus_p_traffic_light_view, this, true);
mLightIconIV = findViewById(R.id.bus_p_traffic_light_iv);
mLightTimeTV = findViewById(R.id.bus_p_traffic_light_time_tv);
}
/**
* 展示红绿灯预警
*
* @param checkLightId 0-都是默认1-红2-黄3-绿
*/
@Override
public void showWarningTrafficLight(int checkLightId) {
super.showWarningTrafficLight(checkLightId);
mCurrentLightId = checkLightId;
updateTrafficLightIcon(checkLightId);
}
/**
* 关闭红绿灯预警展示,并重制灯态
*/
@Override
public void disableWarningTrafficLight() {
super.disableWarningTrafficLight();
UiThreadHandler.post(() -> {
mCurrentLightId = 0;
BusPassengerTrafficLightView.this.setVisibility(GONE);
});
}
/**
* @param redNum 红灯倒计时
* @param yellowNum 黄灯倒计时
* @param greenNum 绿灯倒计时
*/
@Override
public void changeCountdownTrafficLightNum(int redNum, int yellowNum, int greenNum) {
super.changeCountdownTrafficLightNum(redNum, yellowNum, greenNum);
switch (mCurrentLightId) {
case 1:
changeCountdownRed(redNum);
break;
case 2:
changeCountdownYellow(yellowNum);
break;
case 3:
changeCountdownGreen(greenNum);
break;
default:
UiThreadHandler.post(() -> {
mLightTimeTV.setText("");
});
break;
}
}
@Override
public void changeCountdownRed(int redNum) {
super.changeCountdownRed(redNum);
UiThreadHandler.post(() -> {
if (redNum > 0) {
mLightTimeTV.setText(String.valueOf(redNum));
} else {
mLightTimeTV.setText("");
}
});
}
@Override
public void changeCountdownGreen(int greenNum) {
super.changeCountdownGreen(greenNum);
UiThreadHandler.post(() -> {
if (greenNum > 0) {
mLightTimeTV.setText(String.valueOf(greenNum));
} else {
mLightTimeTV.setText("");
}
});
}
@Override
public void changeCountdownYellow(int yellowNum) {
super.changeCountdownYellow(yellowNum);
UiThreadHandler.post(() -> {
if (yellowNum > 0) {
mLightTimeTV.setText(String.valueOf(yellowNum));
} else {
mLightTimeTV.setText("");
}
});
}
/**
* 更新红绿灯icon
*
* @param lightId 0-都是默认1-红2-黄3-绿
*/
private void updateTrafficLightIcon(int lightId) {
UiThreadHandler.post(() -> {
switch (lightId) {
case 1:
mLightIconIV.setBackgroundResource(R.drawable.bus_p_light_red_nor);
BusPassengerTrafficLightView.this.setVisibility(VISIBLE);
break;
case 2:
mLightIconIV.setBackgroundResource(R.drawable.bus_p_light_yellow_nor);
BusPassengerTrafficLightView.this.setVisibility(VISIBLE);
break;
case 3:
mLightIconIV.setBackgroundResource(R.drawable.bus_p_light_green_nor);
BusPassengerTrafficLightView.this.setVisibility(VISIBLE);
break;
default:
BusPassengerTrafficLightView.this.setVisibility(GONE);
break;
}
});
}
}

View File

@@ -0,0 +1,18 @@
package com.mogo.och.bus.passenger.ui;
/**
* @author xiaoyuzhou
* @date 2021/6/24 11:33 上午
*/
public interface IBusPassengerMapDirectionView {
/**
* 绘制路径线
*/
void drawablePolyline();
/**
* 清除路径线
*/
void clearPolyline();
}

View File

@@ -0,0 +1,65 @@
package com.mogo.och.bus.passenger.ui
import androidx.annotation.ColorRes
/**
* @author: wangmingjun
* @date: 2022/1/21
*/
interface IShadow {
//设置阴影半径
fun setShadowRadius(radius:Float):IShadow
//添加单位设置
fun setShadowRadius(unit:Int,radius: Float):IShadow
//设置应用颜色
fun setShadowColor(color:Int):IShadow
//设置阴影颜色资源文件id
fun setShadowColorRes(@ColorRes color: Int):IShadow
/**
* 设置模糊半径
* @param radius
*/
fun setBlurRadius(radius:Float):IShadow
/**
*
* @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
* @param radius 模糊半径
*/
fun setBlurRadius(unit:Int,radius:Float):IShadow
/**
* 设置水平方向的偏移量
* @param offset x轴偏移
*/
fun setXOffset(offset:Float):IShadow
/**
* 设置x方向的偏移量,设置单位
* @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
* @param offset x轴偏移
*/
fun setXOffset(unit:Int,offset:Float):IShadow
/**
* 设置竖直方向的偏移量
* @param offset y轴偏移
*/
fun setYOffset(offset:Float):IShadow
/**
* 设置竖直方向的偏移量,带单位
* @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
* @param offset y轴偏移
*/
fun setYOffset(unit:Int,offset:Float):IShadow
/**
* 更新绘制
*/
fun commit();
}

View File

@@ -0,0 +1,103 @@
package com.mogo.och.bus.passenger.utils;
import android.content.Context;
import com.amap.api.maps.CoordinateConverter;
import com.amap.api.maps.model.LatLng;
import com.mogo.cloud.commons.utils.CoordinateUtils;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import java.util.ArrayList;
import java.util.List;
import mogo.telematics.pad.MessagePad;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS_P;
/**
* @author: wangmingjun
* @date: 2022/3/28
*/
public class BPCoordinateCalculateRouteUtil {
public static float calculateRouteSumLength(List<LatLng> points){
if (null == points || points.size() == 0) return 0;
float sumLength = 0;
//计算全路径总距离
for (int i = 0;i + 1< points.size();i++){
double preLat = points.get(i).latitude;
double preLon = points.get(i).longitude;
double laLat = points.get(i+1).latitude;
double laLon = points.get(i+1).longitude;
float length = CoordinateUtils.calculateLineDistance(laLon,laLat,preLon,preLat);
sumLength += length;
}
return sumLength;
}
public static List<LatLng> coordinateConverterWgsToGcjListCommon(Context mContext, List<MessagePad.Location> models) {
//转成MogoLatLng集合
List<LatLng> list = new ArrayList<>();
for (MessagePad.Location m : models) {
LatLng mogoLatLng = coordinateConverterWgsToGcj(mContext, m);
list.add(mogoLatLng);
}
return list;
}
public static LatLng coordinateConverterWgsToGcj(Context mContext, double lon, double lat) {
CoordinateConverter mCoordinateConverter = new CoordinateConverter(mContext);
mCoordinateConverter.from(CoordinateConverter.CoordType.GPS);
mCoordinateConverter.coord(new LatLng(lat,lon));
LatLng latLng = mCoordinateConverter.convert();
return latLng;
}
public static LatLng coordinateConverterWgsToGcj(Context mContext, MessagePad.Location mogoLatLng) {
CoordinateConverter mCoordinateConverter = new CoordinateConverter(mContext);
mCoordinateConverter.from(CoordinateConverter.CoordType.GPS);
mCoordinateConverter.coord(new LatLng(mogoLatLng.getLatitude(), mogoLatLng.getLongitude()));
LatLng latLng = mCoordinateConverter.convert();
return latLng;
}
/**
* 简单粗暴 直接比较 todo 需要优化
* @param mRoutePoints
* @param realLon
* @param realLat
* @return
*/
public static List<LatLng> getRemainPointListByCompare(List<LatLng> mRoutePoints,double realLon,double realLat) {
List<LatLng> latePoints = new ArrayList<>();
int currentIndex = 0; //记录疑似点
if (mRoutePoints.size() > 0){
//基础点
LatLng baseLatLng = mRoutePoints.get(0);
float baseDiffDis = CoordinateUtils.calculateLineDistance(realLon,realLat
,baseLatLng.longitude,baseLatLng.latitude);// lon,lat, prelon, prelat
for (int i= 1; i < mRoutePoints.size(); i++){
LatLng latLng = mRoutePoints.get(i);
float diff = CoordinateUtils.calculateLineDistance(realLon,realLat
,latLng.longitude,latLng.latitude);
if (baseDiffDis > diff){
// Logger.d(M_TAXI + "calculateRouteSumLength", "点:"+i+"-------先记录点----- ");
baseDiffDis = diff;
currentIndex = i;
}
}
Logger.d(M_BUS_P + "calculateRouteSumLength", "点:"+currentIndex+"-------是最近的点------ ");
if (currentIndex == mRoutePoints.size()-1){
latePoints.add(mRoutePoints.get(currentIndex));
}else {
latePoints.addAll(mRoutePoints.subList(currentIndex,mRoutePoints.size()-1));
}
return latePoints;
}
return latePoints;
}
}

View File

@@ -0,0 +1,109 @@
package com.mogo.och.bus.passenger.utils;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Calendar;
/**
* @author: wangmingjun
* @date: 2021/8/20
*/
public class BPDateTimeUtil {
public static final String TAXI_HH_mm = "HH:mm";
public static final String TAXI_MM_dd = "MM-dd";
public static final String TAXI_MM_dd_HH_mm = "MM-dd HH:mm";
public static final String TAXI_yyyy_MM_dd = "yyyy-MM-dd";
public static final String TAXI_yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm";
public static String formatCalendarToString(Calendar calendar, String format){
if (calendar == null) return "";
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
return dateFormat.format(calendar.getTime());
}catch (Exception e){
e.printStackTrace();
}
return "";
}
public static boolean compareDateIsCurrentDay(Calendar targetCalendar){
Calendar currentCale = DateTimeUtils.getCurrentDateTime();
String currentDay = formatCalendarToString(currentCale, TAXI_yyyy_MM_dd);
if (currentDay.equals(formatCalendarToString(targetCalendar, TAXI_yyyy_MM_dd))){
return true;
}else {
return false;
}
}
public static Calendar formatLongToCalendar(long time){
Calendar calendar = null;
try {
calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
}catch (Exception e){
e.printStackTrace();
}
return calendar;
}
public static String formatLongToString(long time, String format){
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
return dateFormat.format(time);
}catch (Exception e){
e.printStackTrace();
}
return "";
}
public static String getYMDTime(long time){//格式为 2021.8.21
try {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
int month = calendar.get(Calendar.MONTH) + 1;
return calendar.get(Calendar.YEAR)+"."+month+"."+ calendar.get(Calendar.DAY_OF_MONTH);
}catch (Exception e){
e.printStackTrace();
}
return "";
}
/**
*
* @param seconds 60
* @return 1 时
*/
public static String secondsToHourStr(long seconds){//秒数转成相应的 小时分钟数
if (seconds >= 3600){
int hours = (int)seconds/3600;
return String.valueOf(hours);
}
return "";
}
/**
*
* @param seconds 60
* @return 1 时
*/
public static String secondsToMinuteStr(long seconds){//秒数转成相应的 小时分钟数
int minute = (int)(seconds % 3600)/60;
return String.valueOf(minute);
}
/**
* 有小数两位, 没有小数保留整数
* @param d
* @return
*/
public static String formatLong(double d) {
BigDecimal bg = new BigDecimal(d).setScale(1, RoundingMode.HALF_UP);
double num = bg.doubleValue();
if (Math.ceil(num) - num == 0) {
return String.valueOf((long) num);
}
return String.valueOf(num);
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,61 @@
package com.mogo.och.bus.passenger.utils;
import android.content.Context;
import java.io.IOException;
import java.io.InputStream;
/**
* @author donghongyu
* @date 12/18/20 5:37 PM
*/
public class BusPassengerMapAssetStyleUtil {
public static byte[] getAssetsStyle(Context context,String fileName) {
byte[] buffer1 = null;
InputStream is1 = null;
try {
is1 = context.getResources().getAssets().open(fileName); //eg. small_map_style.data
int lenght1 = is1.available();
buffer1 = new byte[lenght1];
is1.read(buffer1);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is1 != null) {
is1.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return buffer1;
}
public static byte[] getAssetsExtraStyle(Context context, String fileName) {
byte[] buffer1 = null;
InputStream is1 = null;
try {
is1 = context.getResources().getAssets().open(fileName); //eg. small_map_style_extra.data
int lenght1 = is1.available();
buffer1 = new byte[lenght1];
is1.read(buffer1);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is1 != null) {
is1.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return buffer1;
}
}

View File

@@ -0,0 +1,13 @@
package com.mogo.och.bus.passenger.utils
import android.content.res.Resources
/**
* @author: wangmingjun
* @date: 2022/1/21
*/
object DimenUtil{
fun dp2px(value:Float):Float{
return (0.5f + value * Resources.getSystem().displayMetrics.density)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bus_p_end_station_circle_borner_color" />
<corners android:radius="@dimen/bus_p_station_circle_radius_size" />
</shape>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="@dimen/bus_p_station_tag_width_height"
android:height="@dimen/bus_p_station_tag_width_height">
<shape android:shape="rectangle">
<corners android:radius="@dimen/bus_p_station_tag_radius_size"/>
<gradient
android:angle="90"
android:endColor="@color/bus_p_end_tag_bg_color1"
android:startColor="@color/bus_p_end_tag_bg_color2"
android:type="linear" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bus_p_start_station_circle_borner_color" />
<corners android:radius="@dimen/bus_p_station_circle_radius_size" />
</shape>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="@dimen/bus_p_station_tag_width_height"
android:height="@dimen/bus_p_station_tag_width_height">
<shape android:shape="rectangle">
<corners android:radius="@dimen/bus_p_station_tag_radius_size"/>
<gradient
android:angle="90"
android:endColor="@color/bus_p_start_tag_bg_color1"
android:startColor="@color/bus_p_start_tag_bg_color2"
android:type="linear" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/bus_p_traffic_light_bg_color"/>
<corners android:radius="@dimen/bus_p_route_traffic_light_view_corner"/>
<stroke android:color="@color/bus_p_traffic_light_bg_stroke"
android:width="@dimen/bus_p_traffic_light_bg_stroke_width"/>
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient
android:angle="180"
android:endColor="#B6CCF5"
android:startColor="#CDDBF6"
android:type="linear" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="#F2F7FF"
android:startColor="#E6ECF9"
android:type="linear" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mogo.eagle.core.function.hmi.ui.widget.SteeringWheelView
android:id="@+id/steering_wheel"
android:layout_width="@dimen/dp_300"
android:layout_height="@dimen/dp_300"
android:layout_marginLeft="@dimen/dp_90"
android:layout_marginTop="@dimen/dp_112"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/bus_p_autopilot_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/bus_p_curent_station_panel_margin"
android:layout_marginTop="@dimen/dp_112"
android:scaleType="fitXY"
android:layout_gravity="center_horizontal"
android:src="@drawable/bus_p_un_auto_nor"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<androidx.cardview.widget.CardView
android:id="@+id/iv_bg"
android:layout_width="@dimen/bus_p_curent_station_panel_width"
android:layout_height="@dimen/bus_p_curent_station_panel_height"
android:layout_marginLeft="@dimen/bus_p_curent_station_panel_margin"
android:layout_marginBottom="@dimen/bus_p_curent_station_panel_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:alpha="0.99"
app:cardElevation="@dimen/dp_5"
app:cardBackgroundColor="@color/bus_p_panel_cur_station_panel_color"
app:cardCornerRadius="20px"/>
<TextView
android:id="@+id/bus_p_cur_station_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_27"
android:layout_marginTop="@dimen/dp_50"
android:elevation="@dimen/dp_10"
android:text="@string/bus_p_cur_station_title"
android:textStyle="bold"
android:textColor="@color/bus_p_panel_cur_txt_color"
android:textSize="@dimen/bus_p_curent_station_txt_size"
app:layout_constraintLeft_toLeftOf="@+id/iv_bg"
app:layout_constraintTop_toTopOf="@+id/iv_bg" />
<TextView
android:id="@+id/bus_p_cur_station_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10"
android:textColor="@color/bus_p_panel_cur_station_txt_color"
android:textSize="@dimen/bus_p_curent_station_txt_size1"
android:textStyle="bold"
android:text="-- --"
android:elevation="@dimen/dp_10"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_cur_station_title"
app:layout_constraintTop_toBottomOf="@+id/bus_p_cur_station_title" />
<TextView
android:id="@+id/bus_p_cur_station_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_20"
android:text="@string/bus_p_cur_station_arrived_tip"
android:elevation="@dimen/dp_10"
android:textStyle="bold"
android:textColor="@color/bus_p_panel_cur_station_tips_color"
android:textSize="@dimen/bus_p_curent_station_tip_size1"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_cur_station_name"
app:layout_constraintTop_toBottomOf="@+id/bus_p_cur_station_name" />
<FrameLayout
android:id="@+id/bus_p_route_panel"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/dp_40"
android:layout_marginBottom="@dimen/dp_48"
android:src="@drawable/bus_p_mogo_nor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/bus_p_route_panel"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent">
<com.amap.api.maps.TextureMapView
android:id="@+id/bus_p_line_amap_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/bus_p_no_order_data_view">
<ImageView
android:id="@+id/no_order_data_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/bus_p_no_order_data"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/no_order_data_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/bus_p_no_data_color"
android:textSize="@dimen/bus_p_no_data_size"
android:layout_marginTop="50px"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/no_order_data_iv"
android:text="@string/bus_p_no_data"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
<com.mogo.och.bus.passenger.ui.BusBorderShadowLayout
android:id="@+id/edge_view"
android:layout_width="716px"
android:layout_height="match_parent"
app:shadowColor="@color/bus_p_route_view_left_edge_shadow"
app:xOffset="0px"
app:yOffset="0px"
app:bgColor="@android:color/transparent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/bus_p_route_info_panel_width"
android:layout_height="match_parent"
android:background="@android:color/transparent" />
</com.mogo.och.bus.passenger.ui.BusBorderShadowLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/bus_p_route_info_panel_width"
android:layout_height="match_parent"
android:background="@drawable/bus_p_route_bg"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/bus_p_speed_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/bus_p_route_info_margin_left"
android:layout_marginTop="@dimen/bus_p_route_info_margin_top"
android:includeFontPadding="false"
android:letterSpacing="-0.05"
android:text="0"
android:textColor="@color/bus_p_speed_txt_color"
android:textSize="@dimen/bus_p_speed_txt_size"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bus_p_unit_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_10"
android:layout_marginRight="@dimen/bus_p_route_info_margin_right"
android:layout_marginBottom="@dimen/dp_20"
android:includeFontPadding="false"
android:textStyle="bold"
android:text="@string/bus_p_speed_unit_txt"
android:textColor="@color/bus_p_speed_txt_color"
android:textSize="@dimen/bus_p_speed_unit_txt_size"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_speed_tv"
app:layout_constraintLeft_toRightOf="@+id/bus_p_speed_tv" />
<com.mogo.och.bus.passenger.ui.BusPassengerTrafficLightView
android:id="@+id/bus_p_traffic_light_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/bus_p_route_info_margin_right"
android:visibility="gone"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_unit_tv"/>
<View
android:id="@+id/dividing_line_1"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_route_line_dividing_view_height"
android:background="@drawable/bus_p_dividing_line_bg"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/bus_p_speed_tv" />
<include
layout="@layout/bus_p_no_data_common_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/bus_p_line_map_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dividing_line_1" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bus_p_line_cl"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bus_p_line_map_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/dividing_line_1">
<TextView
android:id="@+id/bus_p_driver_num_plate_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/bus_p_route_info_margin_left"
android:layout_marginTop="@dimen/bus_p_driver_number_plate_margin_top"
android:text="----"
android:textColor="@color/bus_p_driver_number_plate_color"
android:textSize="@dimen/bus_p_driver_number_plate_size"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bus_p_line_name_tv"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginRight="@dimen/dp_20"
android:maxLines="1"
android:ellipsize="end"
android:text="----"
android:textColor="@color/bus_p_line_name_color"
android:textSize="@dimen/bus_p_driver_number_plate_size"
android:textStyle="bold"
app:layout_constraintLeft_toRightOf="@+id/bus_p_driver_num_plate_tv"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_driver_num_plate_tv"
app:layout_goneMarginLeft="0px" />
<TextView
android:id="@+id/line_operation_time_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/bus_p_line_operation_time_margin_top"
android:text="-- --"
android:textColor="@color/bus_p_line_operation_time_color"
android:textSize="@dimen/bus_p_line_operation_time_size"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_driver_num_plate_tv"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/dividing_line_2"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_route_line_dividing_view_height"
android:layout_marginTop="@dimen/bus_p_route_dividing_line2_margin_top"
android:background="@drawable/bus_p_dividing_line_bg"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/bus_p_line_stations_rl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/bus_p_driver_number_plate_margin_top"
android:paddingLeft="@dimen/bus_p_route_info_margin_left"
android:paddingRight="@dimen/bus_p_route_info_margin_right"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_driver_num_plate_tv"
app:layout_constraintTop_toBottomOf="@+id/dividing_line_2" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.mogo.och.bus.passenger.ui.BusPassengerMapDirectionView
android:id="@+id/bus_p_line_map_view"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_route_line_map_view_height"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<ImageView
android:id="@+id/bus_p_arrow_nor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/dp_20"
android:layout_marginBottom="@dimen/dp_370"
android:src="@drawable/bus_p_arrow_nor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_station_item_height"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:layout_width="@dimen/bus_p_station_tag_line_width"
android:layout_height="@dimen/bus_p_station_tag_line_height"
android:background="@color/bus_p_tag_line_color"
android:layout_marginLeft="@dimen/dp_7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/bus_p_end_station"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="--"
android:textSize="@dimen/bus_p_station_txt_size"
android:textStyle="bold"
android:includeFontPadding = "false"
android:textColor="@color/bus_p_station_txt_color"
android:layout_marginLeft="@dimen/dp_45"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_end_tag"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_end_tag"/>
<ImageView
android:id="@+id/bus_p_end_circle"
android:layout_width="@dimen/bus_p_station_circle_width_height"
android:layout_height="@dimen/bus_p_station_circle_width_height"
android:background="@drawable/bg_bus_p_end_station_circle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_end_station"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_end_station"/>
<ImageView
android:id="@+id/bus_p_cur_end_station_tag"
android:layout_width="@dimen/bus_p_cur_station_circle_width"
android:layout_height="wrap_content"
android:background="@drawable/bg_bus_p_arrived_station"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_end_station"/>
<ImageView
android:id="@+id/bus_p_end_tag"
android:layout_width="@dimen/bus_p_station_tag_width_height"
android:layout_height="@dimen/bus_p_station_tag_width_height"
android:background="@drawable/bg_bus_p_end_tag_bg"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:layout_width="@dimen/bus_p_station_tag_width_height"
android:layout_height="@dimen/bus_p_station_tag_width_height"
android:textSize="@dimen/bus_p_station_tag_txt_size"
android:textColor="@color/bus_p_end_tag_txt_color"
android:text="@string/bus_p_end_station_txt_tag"
android:includeFontPadding="false"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_end_tag"
app:layout_constraintRight_toRightOf="@+id/bus_p_end_tag"
app:layout_constraintTop_toTopOf="@+id/bus_p_end_tag"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_end_tag"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_station_item_middle_height"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:layout_width="@dimen/bus_p_station_tag_line_width"
android:layout_height="@dimen/bus_p_station_tag_line_height"
android:background="@color/bus_p_tag_line_color"
android:layout_marginLeft="@dimen/dp_7"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<ImageView
android:layout_width="@dimen/bus_p_station_tag_line_width"
android:layout_height="@dimen/bus_p_station_tag_line_height"
android:background="@color/bus_p_tag_line_color"
android:layout_marginLeft="@dimen/dp_7"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/bus_p_middle_station"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="--"
android:textSize="@dimen/bus_p_station_txt_size"
android:textStyle="bold"
android:includeFontPadding = "false"
android:textColor="@color/bus_p_current_station_txt_color"
android:layout_marginLeft="@dimen/dp_45"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<ImageView
android:id="@+id/bus_p_middle_tag"
android:layout_width="@dimen/bus_p_cur_station_circle_width"
android:layout_height="wrap_content"
android:background="@drawable/bg_bus_p_arrived_station"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/bus_p_station_item_height"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:layout_width="@dimen/bus_p_station_tag_line_width"
android:layout_height="@dimen/bus_p_station_tag_line_height"
android:background="@color/bus_p_tag_line_color"
android:layout_marginLeft="@dimen/dp_7"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/bus_p_start_station"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="--"
android:textSize="@dimen/bus_p_station_txt_size"
android:textStyle="bold"
android:includeFontPadding = "false"
android:textColor="@color/bus_p_station_txt_color"
android:layout_marginLeft="@dimen/dp_45"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_start_tag"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_start_tag"/>
<ImageView
android:id="@+id/bus_p_start_circle"
android:layout_width="@dimen/bus_p_station_circle_width_height"
android:layout_height="@dimen/bus_p_station_circle_width_height"
android:background="@drawable/bg_bus_p_start_station_circle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_start_station"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_start_station"/>
<ImageView
android:id="@+id/bus_p_cur_start_station_tag"
android:layout_width="@dimen/bus_p_cur_station_circle_width"
android:layout_height="wrap_content"
android:background="@drawable/bg_bus_p_arrived_station"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_start_station"/>
<ImageView
android:id="@+id/bus_p_start_tag"
android:layout_width="@dimen/bus_p_station_tag_width_height"
android:layout_height="@dimen/bus_p_station_tag_width_height"
android:background="@drawable/bg_bus_p_start_tag_bg"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/bus_p_start_station"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_start_station"/>
<TextView
android:layout_width="@dimen/bus_p_station_tag_width_height"
android:layout_height="@dimen/bus_p_station_tag_width_height"
android:textSize="@dimen/bus_p_station_tag_txt_size"
android:textColor="@color/bus_p_end_tag_txt_color"
android:text="@string/bus_p_start_station_txt_tag"
android:includeFontPadding="false"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="@+id/bus_p_start_tag"
app:layout_constraintRight_toRightOf="@+id/bus_p_start_tag"
app:layout_constraintTop_toTopOf="@+id/bus_p_start_tag"
app:layout_constraintBottom_toBottomOf="@+id/bus_p_start_tag"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/bus_p_route_traffic_light_view_width"
android:layout_height="@dimen/bus_p_route_traffic_light_view_height"
android:visibility="visible">
<ImageView
android:layout_width="@dimen/bus_p_traffic_light_bg_width"
android:layout_height="@dimen/bus_p_traffic_light_bg_height"
android:background="@drawable/bg_bus_p_traffic_light_background"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/bus_p_traffic_light_iv"
android:layout_width="@dimen/bus_p_traffic_light_icon_size"
android:layout_height="@dimen/bus_p_traffic_light_icon_size"
android:layout_marginTop="@dimen/dp_8"
android:scaleType="fitXY"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/bus_p_traffic_light_time_tv"
android:layout_width="@dimen/bus_p_traffic_light_time_view_width"
android:layout_height="match_parent"
android:textSize="@dimen/bus_p_traffic_light_time_size"
android:textStyle="bold"
android:textColor="@color/bus_p_traffic_txt_color"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:gravity="center" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="bus_p_route_info_panel_width">700px</dimen>
<dimen name="bus_p_route_info_margin_right">40px</dimen>
<dimen name="bus_p_route_info_margin_left">40px</dimen>
<dimen name="bus_p_route_info_margin_bottom">40px</dimen>
<dimen name="bus_p_route_info_margin_top">110px</dimen>
<dimen name="bus_p_route_line_info_height">224px</dimen>
<dimen name="bus_p_route_line_map_view_height">510px</dimen>
<dimen name="bus_p_route_line_dividing_view_height">3px</dimen>
<dimen name="bus_p_route_traffic_light_view_width">158px</dimen>
<dimen name="bus_p_route_traffic_light_view_height">90px</dimen>
<dimen name="bus_p_route_traffic_light_view_corner">45px</dimen>
<dimen name="bus_p_traffic_light_bg_width">158px</dimen>
<dimen name="bus_p_traffic_light_bg_height">90px</dimen>
<dimen name="bus_p_traffic_light_time_size">45px</dimen>
<dimen name="bus_p_traffic_light_time_view_width">90px</dimen>
<dimen name="bus_p_traffic_light_icon_size">90px</dimen>
<dimen name="bus_p_traffic_light_bg_stroke_width">3px</dimen>
<dimen name="bus_p_route_dividing_line2_margin_top">224px</dimen>
<dimen name="bus_p_driver_number_plate_margin_top">50px</dimen>
<dimen name="bus_p_driver_number_plate_margin_bottom">50px</dimen>
<dimen name="bus_p_driver_number_plate_size">44px</dimen>
<dimen name="bus_p_line_operation_time_margin_top">130px</dimen>
<dimen name="bus_p_line_operation_time_size">38px</dimen>
<dimen name="bus_p_no_data_size">36px</dimen>
<dimen name="bus_p_speed_txt_size">110px</dimen>
<dimen name="bus_p_speed_unit_txt_size">42px</dimen>
<dimen name="bus_p_station_circle_borner_size">4px</dimen>
<dimen name="bus_p_station_circle_radius_size">10px</dimen>
<dimen name="bus_p_station_circle_width_height">20px</dimen>
<dimen name="bus_p_station_tag_width_height">60px</dimen>
<dimen name="bus_p_station_tag_radius_size">30px</dimen>
<dimen name="bus_p_cur_station_circle_width">20px</dimen>
<dimen name="bus_p_cur_station_circle_height">50px</dimen>
<dimen name="bus_p_mid_station_circle_cor">6px</dimen>
<dimen name="bus_p_station_txt_size">50px</dimen>
<dimen name="bus_p_station_tag_txt_size">36px</dimen>
<dimen name="bus_p_station_item_height">80px</dimen>
<dimen name="bus_p_station_item_middle_height">100px</dimen>
<dimen name="bus_p_station_tag_line_height">50px</dimen>
<dimen name="bus_p_station_tag_line_width">6px</dimen>
<dimen name="bus_p_curent_station_panel_width">638px</dimen>
<dimen name="bus_p_curent_station_panel_height">316px</dimen>
<dimen name="bus_p_curent_station_panel_margin">50px</dimen>
<dimen name="bus_p_curent_station_txt_size">44px</dimen>
<dimen name="bus_p_curent_station_txt_size1">55px</dimen>
<dimen name="bus_p_curent_station_tip_size1">40px</dimen>
</resources>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--阴影布局 -->
<declare-styleable name="ShadowLayout">
<!-- 阴影颜色-->
<attr name="shadowColor" format="color"/>
<!-- 圆角大小默认无圆角0-->
<attr name="shadowRadius" format="dimension"/>
<!-- 模糊半径 -->
<attr name="blurRadius" format="dimension" />
<!-- 是否有点击效果-->
<attr name="hasEffect" format="boolean"/>
<attr name="bgColor" format="color"/>
<!-- 水平位移-->
<attr name="xOffset" format="dimension"/>
<!--竖直位移 -->
<attr name="yOffset" format="dimension"/>
</declare-styleable>
</resources>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="bus_p_speed_txt_color">#2D3E5F</color>
<color name="bus_p_traffic_light_bg_color">#CCE9EFFC</color>
<color name="bus_p_traffic_light_bg_stroke">#C7D2E1</color>
<color name="bus_p_driver_number_plate_color">#2D3E5F</color>
<color name="bus_p_line_name_color">#0043FF</color>
<color name="bus_p_line_operation_time_color">#2D3E5F</color>
<color name="bus_p_no_data_color">#596A8A</color>
<color name="bus_p_station_circle_color">#D8E5F8</color>
<color name="bus_p_start_station_circle_borner_color">#FFB327</color>
<color name="bus_p_station_txt_color">#2D3E5F</color>
<color name="bus_p_current_station_txt_color">#0043FF</color>
<color name="bus_p_middle_station_circle_color2">#276AFE</color>
<color name="bus_p_middle_station_circle_color1">#0043FF</color>
<color name="bus_p_end_station_circle_borner_color">#276AFE</color>
<color name="bus_p_start_tag_bg_color1">#FFC125</color>
<color name="bus_p_start_tag_bg_color2">#FF8131</color>
<color name="bus_p_end_tag_bg_color1">#31BFF2</color>
<color name="bus_p_end_tag_bg_color2">#3257E9</color>
<color name="bus_p_end_tag_txt_color">#FFFFFF</color>
<color name="bus_p_tag_line_color">#CDDBF6</color>
<color name="bus_p_panel_cur_txt_color">#2D3E5F</color>
<color name="bus_p_panel_cur_station_txt_color">#0043FF</color>
<color name="bus_p_panel_cur_station_tips_color">#2D3E5F</color>
<color name="bus_p_panel_cur_station_panel_color">#E6E9EFFC</color>
<color name="bus_p_route_view_left_edge_shadow">#33394C63</color>
<color name="bus_p_traffic_txt_color">#2D3E5F</color>
</resources>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="bus_p_route_info_panel_width">700px</dimen>
<dimen name="bus_p_auto_icon_margin_top">40px</dimen>
<dimen name="bus_p_route_info_margin_right">40px</dimen>
<dimen name="bus_p_route_info_margin_left">40px</dimen>
<dimen name="bus_p_route_info_margin_bottom">40px</dimen>
<dimen name="bus_p_route_info_margin_top">110px</dimen>
<dimen name="bus_p_route_line_info_height">224px</dimen>
<dimen name="bus_p_route_line_map_view_height">510px</dimen>
<dimen name="bus_p_route_line_dividing_view_height">3px</dimen>
<dimen name="bus_p_route_traffic_light_view_width">158px</dimen>
<dimen name="bus_p_route_traffic_light_view_height">90px</dimen>
<dimen name="bus_p_route_traffic_light_view_corner">45px</dimen>
<dimen name="bus_p_traffic_light_bg_width">158px</dimen>
<dimen name="bus_p_traffic_light_bg_height">90px</dimen>
<dimen name="bus_p_traffic_light_time_size">45px</dimen>
<dimen name="bus_p_traffic_light_time_view_width">90px</dimen>
<dimen name="bus_p_traffic_light_icon_size">90px</dimen>
<dimen name="bus_p_traffic_light_bg_stroke_width">3px</dimen>
<dimen name="bus_p_route_dividing_line2_margin_top">224px</dimen>
<dimen name="bus_p_driver_number_plate_margin_top">50px</dimen>
<dimen name="bus_p_driver_number_plate_margin_bottom">50px</dimen>
<dimen name="bus_p_driver_number_plate_size">44px</dimen>
<dimen name="bus_p_line_operation_time_margin_top">130px</dimen>
<dimen name="bus_p_line_operation_time_size">38px</dimen>
<dimen name="bus_p_no_data_size">36px</dimen>
<dimen name="bus_p_speed_txt_size">110px</dimen>
<dimen name="bus_p_speed_unit_txt_size">42px</dimen>
<dimen name="bus_p_station_circle_borner_size">4px</dimen>
<dimen name="bus_p_station_circle_radius_size">10px</dimen>
<dimen name="bus_p_station_circle_width_height">20px</dimen>
<dimen name="bus_p_station_tag_width_height">60px</dimen>
<dimen name="bus_p_station_tag_radius_size">30px</dimen>
<dimen name="bus_p_cur_station_circle_width">20px</dimen>
<dimen name="bus_p_cur_station_circle_height">50px</dimen>
<dimen name="bus_p_mid_station_circle_cor">6px</dimen>
<dimen name="bus_p_station_txt_size">50px</dimen>
<dimen name="bus_p_station_tag_txt_size">36px</dimen>
<dimen name="bus_p_station_item_height">80px</dimen>
<dimen name="bus_p_station_item_middle_height">100px</dimen>
<dimen name="bus_p_station_tag_line_height">50px</dimen>
<dimen name="bus_p_station_tag_line_width">6px</dimen>
<dimen name="bus_p_curent_station_panel_width">638px</dimen>
<dimen name="bus_p_curent_station_panel_height">316px</dimen>
<dimen name="bus_p_curent_station_panel_margin">50px</dimen>
<dimen name="bus_p_curent_station_txt_size">44px</dimen>
<dimen name="bus_p_curent_station_txt_size1">55px</dimen>
<dimen name="bus_p_curent_station_tip_size1">40px</dimen>
</resources>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="bus_p_speed_unit_txt">KM/H</string>
<string name="bus_p_no_data">您已收车</string>
<string name="bus_p_start_station_txt_tag"></string>
<string name="bus_p_end_station_txt_tag"></string>
<string name="bus_p_cur_station_title">到达站:</string>
<string name="bus_p_cur_next_station_title">下一站:</string>
<string name="bus_p_cur_station_title_init">始发站:</string>
<string name="bus_p_cur_station_arrived_tip">请携带好随身物品下车。</string>
<string name="bus_p_cur_station_arrived_tip_init">欢迎乘坐蘑菇车联无人驾驶车。</string>
</resources>

View File

@@ -0,0 +1,17 @@
package com.mogo.och.bus.passenger;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

View File

@@ -3,7 +3,7 @@
<application>
<!--这里是为了测试增加的广播-->
<receiver android:name=".receiver.TestOchBusBroadcastReceiver">
<receiver android:name=".receiver.TestBusBroadcastReceiver">
<intent-filter>
<action android:name="com.bus.test_control" />

View File

@@ -0,0 +1,115 @@
package com.mogo.och.bus;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.map.MogoMapUIController;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.bus.constant.BusConst;
import com.mogo.och.bus.fragment.BusFragment;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* 网约车小巴业务实现入口
*
* @author tongchenfei
*/
@Route(path = BusConst.PATH)
public class BusProvider implements IMogoOCH {
private static final String TAG = "BusProvider";
private BusFragment busFragment;
private int containerId;
private FragmentActivity activity;
/**
* 进入鹰眼模式,设置手势缩放地图失效
*/
private void stepIntoVrMode(){
CallerLogger.INSTANCE.d( M_BUS + TAG, "进入vr模式" );
MogoMapUIController.getInstance()
.stepInVrMode(false);
}
@Override
public void init(Context context) {
MogoApisHandler.getInstance().getApis().getStatusManagerApi().registerStatusChangedListener("OchBus"
, StatusDescriptor.VR_MODE, statusChangedListener);
}
private void showFragment() {
if (busFragment == null) {
CallerLogger.INSTANCE.d(TAG, "准备add fragment======");
busFragment = new BusFragment();
activity.getSupportFragmentManager().beginTransaction().add(containerId, busFragment).commitAllowingStateLoss();
return;
}
CallerLogger.INSTANCE.d(TAG, "准备show fragment");
activity.getSupportFragmentManager().beginTransaction().show(busFragment).commitAllowingStateLoss();
}
private void hideFragment() {
if (busFragment != null) {
CallerLogger.INSTANCE.d(TAG, "准备hide fragment");
activity.getSupportFragmentManager().beginTransaction().hide(busFragment).commitAllowingStateLoss();
}
}
private final IMogoStatusChangedListener statusChangedListener = (descriptor, isTrue) -> {
if (descriptor == StatusDescriptor.VR_MODE) {
// 进入vr模式默认显示网约车小巴fragment
if (isTrue) {
showFragment();
} else {
hideFragment();
}
} else if (MogoApisHandler.getInstance().getApis().getStatusManagerApi().isVrMode()) {
// topView进行展示时推出网约车界面但是不隐藏整个fragment
if (busFragment != null && isTrue) {
busFragment.hideOchBus();
}
}
};
@Override
public void createCoverage(FragmentActivity activity, int containerId) {
}
@NotNull
@Override
public String getFunctionName() {
return null;
}
@Nullable
@Override
public Fragment createCoverage(@Nullable FragmentActivity fragmentActivity, @Nullable Integer integer) {
this.containerId = integer;
this.activity = fragmentActivity;
// UiThreadHandler.postDelayed(this::stepIntoVrMode, 5_000L );
return null;
}
@Override
public void onDestroy() {
//若不调用finish, 设置中打开关闭UITouch,会造成och fragment 重叠
if (activity == null) return;
activity.finish();
}
}

View File

@@ -1,116 +0,0 @@
package com.mogo.och.bus;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.module.common.MogoApisHandler;
import com.mogo.och.bus.constant.OchBusConst;
import com.mogo.och.bus.fragment.OchBusFragment;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* 网约车小巴业务实现入口
*
* @author tongchenfei
*/
@Route(path = OchBusConst.PATH)
public class OchBusProvider implements IMogoOCH {
private static final String TAG = "OchBusProvider";
private OchBusFragment busFragment;
private int containerId;
private FragmentActivity activity;
/**
* 进入鹰眼模式,设置手势缩放地图失效
*/
private void stepIntoVrMode(){
Logger.d( TAG, "进入vr模式" );
MogoApisHandler.getInstance()
.getApis()
.getMapServiceApi()
.getMapUIController()
.openVrMode(false);
}
@Override
public void init(Context context) {
MogoApisHandler.getInstance().getApis().getStatusManagerApi().registerStatusChangedListener("OchBus"
, StatusDescriptor.VR_MODE, statusChangedListener);
MogoApisHandler.getInstance().getApis().getStatusManagerApi().registerStatusChangedListener("OchBus"
, StatusDescriptor.TOP_VIEW, statusChangedListener);
}
private void showFragment() {
if (busFragment == null) {
Logger.d(TAG, "准备add fragment======");
busFragment = new OchBusFragment();
activity.getSupportFragmentManager().beginTransaction().add(containerId, busFragment).commitAllowingStateLoss();
return;
}
Logger.d(TAG, "准备show fragment");
activity.getSupportFragmentManager().beginTransaction().show(busFragment).commitAllowingStateLoss();
}
private void hideFragment() {
if (busFragment != null) {
Logger.d(TAG, "准备hide fragment");
activity.getSupportFragmentManager().beginTransaction().hide(busFragment).commitAllowingStateLoss();
}
}
private final IMogoStatusChangedListener statusChangedListener = (descriptor, isTrue) -> {
if (descriptor == StatusDescriptor.VR_MODE) {
// 进入vr模式默认显示网约车小巴fragment
if (isTrue) {
showFragment();
} else {
hideFragment();
}
} else if (MogoApisHandler.getInstance().getApis().getStatusManagerApi().isVrMode()
&& descriptor == StatusDescriptor.TOP_VIEW) {
// topView进行展示时推出网约车界面但是不隐藏整个fragment
if (busFragment != null && isTrue) {
busFragment.hideOchBus();
}
}
};
@Override
public void createCoverage(FragmentActivity activity, int containerId) {
}
@NotNull
@Override
public String getFunctionName() {
return null;
}
@Nullable
@Override
public Fragment createCoverage(@Nullable FragmentActivity fragmentActivity, @Nullable Integer integer) {
this.containerId = integer;
this.activity = fragmentActivity;
UiThreadHandler.postDelayed(this::stepIntoVrMode, 5_000L );
return null;
}
@Override
public void onDestroy() {
}
}

View File

@@ -1,127 +0,0 @@
package com.mogo.och.bus.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.mogo.och.bus.R;
import com.mogo.och.bus.bean.OchBusStation;
import com.mogo.och.bus.constant.OchBusConst;
import com.mogo.och.bus.view.VerticalDashLineView;
import java.util.ArrayList;
import java.util.List;
/**
* Station Panel 中的车站列表adapter
*
* @author tongchenfei
*/
public class OchBusStationAdapter extends RecyclerView.Adapter<OchBusStationAdapter.ViewHolder> {
private final Context context;
private final List<OchBusStation> stationList = new ArrayList<>();
private int currentStation;
public OchBusStationAdapter(Context context) {
this.context = context;
}
public void refreshStationList(List<OchBusStation> stationList) {
this.stationList.clear();
this.stationList.addAll(stationList);
for (int i = 0; i < stationList.size(); i++) {
OchBusStation station = stationList.get(i);
if (station.getDrivingStatus() == OchBusConst.STATION_STATUS_ARRIVING || station.getDrivingStatus() == OchBusConst.STATION_STATUS_STOPPED ) {
currentStation = i;
break;
}
}
notifyDataSetChanged();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_och_bus_station, parent, false));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
// Logger.d("OchBusStationAdapter", "position: " + position + " currPos: " + currentStation + " station: " + stationList.get(position));
holder.tvStationName.setText(stationList.get(position).getName());
if (position == currentStation) {
if (currentStation == 0) {
// 在起始点
holder.tvStationName.setTextColor(context.getResources().getColor(R.color.bus_arrived_station_name_text_color));
holder.ivIcon.setImageResource(R.drawable.bus_icon_arrived_station);
holder.vDashBottom.setColor(context.getResources().getColor(R.color.bus_not_arrive_dash_color));
} else {
holder.tvStationName.setTextColor(context.getResources().getColor(R.color.bus_current_station_name_text_color));
holder.ivIcon.setImageResource(R.drawable.bus_icon_arriving_station);
holder.vDashTop.setGradient(context.getResources().getColor(R.color.bus_arriving_start_dash_color), context.getResources().getColor(R.color.bus_arriving_end_dash_color));
holder.vDashBottom.setColor(context.getResources().getColor(R.color.bus_not_arrive_dash_color));
}
} else if (position < currentStation) {
// 驶过
holder.tvStationName.setTextColor(context.getResources().getColor(R.color.bus_arrived_station_name_text_color));
holder.ivIcon.setImageResource(R.drawable.bus_icon_arrived_station);
if (position == currentStation - 1) {
holder.vDashBottom.setGradient(context.getResources().getColor(R.color.bus_leaving_start_dash_color), context.getResources().getColor(R.color.bus_leaving_end_dash_color));
holder.vDashTop.setColor(context.getResources().getColor(R.color.bus_arrived_dash_color));
} else {
holder.vDashTop.setColor(context.getResources().getColor(R.color.bus_arrived_dash_color));
holder.vDashBottom.setColor(context.getResources().getColor(R.color.bus_arrived_dash_color));
}
} else {
holder.tvStationName.setTextColor(context.getResources().getColor(R.color.bus_not_arrive_station_name_text_color));
holder.ivIcon.setImageResource(R.drawable.bus_icon_not_arrive_station);
holder.vDashTop.setColor(context.getResources().getColor(R.color.bus_not_arrive_dash_color));
holder.vDashBottom.setColor(context.getResources().getColor(R.color.bus_not_arrive_dash_color));
}
if (position == 0) {
holder.tvStationNotice.setText("起点");
holder.tvStationNotice.setVisibility(View.VISIBLE);
holder.vDashTop.setVisibility(View.GONE);
holder.vDashBottom.setVisibility(View.VISIBLE);
} else if (position == getItemCount() - 1) {
holder.tvStationNotice.setText("终点");
holder.tvStationNotice.setVisibility(View.VISIBLE);
holder.vDashTop.setVisibility(View.VISIBLE);
holder.vDashBottom.setVisibility(View.GONE);
} else {
holder.tvStationNotice.setVisibility(View.GONE);
holder.vDashTop.setVisibility(View.VISIBLE);
holder.vDashBottom.setVisibility(View.VISIBLE);
}
}
@Override
public int getItemCount() {
return stationList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView ivIcon;
TextView tvStationName;
TextView tvStationNotice;
VerticalDashLineView vDashBottom, vDashTop;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ivIcon = itemView.findViewById(R.id.module_mogo_och_bus_station_icon);
tvStationName = itemView.findViewById(R.id.module_mogo_och_bus_station_name);
tvStationNotice = itemView.findViewById(R.id.module_mogo_och_bus_station_notice);
vDashTop = itemView.findViewById(R.id.module_mogo_och_bus_station_top_dash);
vDashBottom = itemView.findViewById(R.id.module_mogo_och_bus_station_bottom_dash);
}
}
}

View File

@@ -0,0 +1,43 @@
package com.mogo.och.bus.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.commons.network.Utils;
public
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态请求参数
*/
class BusOperationStatusRequest {
private String sn;
private double lat;
private double lon;
public BusOperationStatusRequest(double lon, double lat) {
this.sn = MoGoAiCloudClientConfig.getInstance().getSn();
this.lat = lat;
this.lon = lon;
}
public void setLat(double lat) {
this.lat = lat;
}
public void setLon(double lon) {
this.lon = lon;
}
public String getSn() {
return sn;
}
public double getLat() {
return lat;
}
public double getLon() {
return lon;
}
}

View File

@@ -0,0 +1,20 @@
package com.mogo.och.bus.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态返回参数
*/
public class BusOperationStatusResponse extends BaseData {
public Result data;
public static class Result {
public int serviceStatus;//0:已收车1:已出车
}
}

View File

@@ -0,0 +1,86 @@
package com.mogo.och.bus.bean;
/**
* @author congtaowang
* @since 2021/3/23
* <p>
* 小巴订单
*/
public class BusOrderBean {
/**
* orderNo number
* passengerPhone string 下单用户电话
* startStationId integer 开始站点
* startStationName string
* endStationId integer 结束站点
* endStationName string
*/
private String orderNo;
private String passengerPhone;
private int startStationId;//乘客上车点
private String startStationName;
private String endStationName;
private int endStationId;//乘客下车点
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public void setPassengerPhone(String passengerPhone) {
this.passengerPhone = passengerPhone;
}
public void setStartStationId(int startStationId) {
this.startStationId = startStationId;
}
public void setStartStationName(String startStationName) {
this.startStationName = startStationName;
}
public void setEndStationName(String endStationName) {
this.endStationName = endStationName;
}
public void setEndStationId(int endStationId) {
this.endStationId = endStationId;
}
public String getOrderNo() {
return orderNo;
}
public String getPassengerPhone() {
return passengerPhone;
}
public int getStartStationId() {
return startStationId;
}
public String getStartStationName() {
return startStationName;
}
public String getEndStationName() {
return endStationName;
}
public int getEndStationId() {
return endStationId;
}
@Override
public String toString() {
return "BusOrderBean{" +
"orderNo=" + orderNo +
", passengerPhone='" + passengerPhone + '\'' +
", startStationId=" + startStationId +
", startStationName='" + startStationName + '\'' +
", endStationName='" + endStationName + '\'' +
", endStationId=" + endStationId +
'}';
}
}

View File

@@ -0,0 +1,23 @@
package com.mogo.och.bus.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2021/10/19
*/
public class BusOrdersResponse extends BaseData {
public Result data;
public static class Result{
public List<BusOrderBean> orders;
}
@Override
public String toString() {
return "BusOrdersResponse{" +
"data=" + data +
'}';
}
}

View File

@@ -0,0 +1,63 @@
package com.mogo.och.bus.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
public
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
class BusQueryLineStationsRequest {
private String sn;
private double lat;
private double lon;
private boolean markDrivingStatus; // 默认falsetrue:是否需要返回站点的行驶状态对应返回的drivingStatus
// 0 - 关闭、1 - 启动
// public String status;
public BusQueryLineStationsRequest(double lon, double lat, boolean markDrivingStatus) {
this.sn = MoGoAiCloudClientConfig.getInstance().getSn();
this.lat = lat;
this.lon = lon;
this.markDrivingStatus = markDrivingStatus;
}
public boolean isMarkDrivingStatus() {
return markDrivingStatus;
}
public void setMarkDrivingStatus(boolean markDrivingStatus) {
this.markDrivingStatus = markDrivingStatus;
}
public void setLat(double lat) {
this.lat = lat;
}
public void setLon(double lon) {
this.lon = lon;
}
public String getSn() {
return sn;
}
public double getLat() {
return lat;
}
public double getLon() {
return lon;
}
// public BusOperationStatusRequest shutdown() {
// status = "0";
// return this;
// }
//
// public BusOperationStatusRequest launch() {
// status = "1";
// return this;
// }
}

View File

@@ -0,0 +1,18 @@
package com.mogo.och.bus.bean;
import com.mogo.cloud.passport.MoGoAiCloudClientConfig;
import com.mogo.commons.network.Utils;
/**
* @author: wangmingjun
* @date: 2021/10/18
*/
public class BusResetDrivingLineRequest {
public String sn;
public int lineId; //切换到的线路id
public BusResetDrivingLineRequest(int lineId) {
sn = MoGoAiCloudClientConfig.getInstance().getSn();
this.lineId = lineId;
}
}

View File

@@ -0,0 +1,27 @@
package com.mogo.och.bus.bean;
import com.mogo.eagle.core.data.BaseData;
/**
* 网约车小巴路线接口请求响应结果
*
* @author tongchenfei
*/
public class BusRoutesResponse extends BaseData {
private BusRoutesResult data;
public BusRoutesResult getResult() {
return data;
}
public void setResult(BusRoutesResult data) {
this.data = data;
}
@Override
public String toString() {
return "BusRoutesResponse{" +
"data=" + data +
'}';
}
}

Some files were not shown because too many files have changed in this diff Show More