合并策略上报
This commit is contained in:
@@ -35,8 +35,7 @@ class StrategyShareProvider : IProvider {
|
||||
// if(!DebugConfig.isLauncher()) {
|
||||
apis.registerCenterApi.registerMogoLocationListener(MogoServicePaths.PATH_STRATEGY_SHARE) {
|
||||
// Logger.d(S_TAG,"定位发生变化,准备记录速度: ${it.speed}")
|
||||
blockStrategy.recordSpeed(it.speed * 3.6F)
|
||||
blockStrategy.recordLocation(it.latitude, it.longitude)
|
||||
blockStrategy.recordSpeed(it.speed * 3.6F, it.latitude, it.longitude)
|
||||
}
|
||||
|
||||
apis.adasControllerApi.addAdasDataCallback {
|
||||
|
||||
@@ -17,9 +17,12 @@ import com.mogo.service.share.TanluUploadParams
|
||||
import com.mogo.utils.logger.Logger
|
||||
import com.mogo.utils.network.RequestOptions
|
||||
import com.mogo.utils.network.utils.GsonUtil
|
||||
import com.mogo.utils.storage.SharedPrefsMgr
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
/**
|
||||
@@ -35,6 +38,21 @@ private const val TAG = "BlockUploadStrategy"
|
||||
|
||||
private const val DISTANCE_RECORD_TIME = 3 * 60 * 1000L
|
||||
|
||||
private const val MORNING_PEAK_START_MINUTE = 7 * 60 + 30
|
||||
private const val MORNING_PEAK_STOP_MINUTE = 9 * 60 + 30
|
||||
|
||||
private const val NIGHT_PEAK_START_MINUTE = 17 * 60 + 30
|
||||
private const val NIGHT_PEAK_STOP_MINUTE = 19 * 60 + 30
|
||||
|
||||
private const val DISTANCE_MORNING_PEAK_COUNT = "DISTANCE_MORNING_PEAK_COUNT"
|
||||
private const val DISTANCE_NIGHT_PEAK_COUNT = "DISTANCE_NIGHT_PEAK_COUNT"
|
||||
private const val DISTANCE_NORMAL_COUNT = "DISTANCE_NORMAL_COUNT"
|
||||
|
||||
|
||||
private const val SPEED_MORNING_PEAK_COUNT = "SPEED_MORNING_PEAK_COUNT"
|
||||
private const val SPEED_NIGHT_PEAK_COUNT = "SPEED_NIGHT_PEAK_COUNT"
|
||||
private const val SPEED_NORMAL_COUNT = "SPEED _NORMAL_COUNT"
|
||||
|
||||
/**
|
||||
* 用于计算拥堵策略
|
||||
*/
|
||||
@@ -61,9 +79,17 @@ class BlockStrategy(private val context: Context, private val apis: IMogoService
|
||||
* 停车标志为累加超过[STOP_FLAG_THRESHOLD]判定为停车,不是拥堵,舍弃掉整个两分钟数据,不进行上报,
|
||||
* 否则上报服务端,返回是否抓取视频
|
||||
*
|
||||
* * 距离策略上报
|
||||
*
|
||||
* 1. 过去3分钟,行驶距离<1km,大于30m
|
||||
* 2. 前车距离<5m,获取不到前车距离时,默认此项满足
|
||||
* 3. 当前车速<40km/h
|
||||
*
|
||||
* 满足上述条件,自动上报拥堵
|
||||
*
|
||||
* @param speed 当前速度,单位需要是Km/h
|
||||
*/
|
||||
fun recordSpeed(speed: Float) {
|
||||
fun recordSpeed(speed: Float, lat: Double, lon: Double) {
|
||||
currentSpeed = speed.toInt()
|
||||
val current = SystemClock.uptimeMillis()
|
||||
if (startRecordTime == 0L) {
|
||||
@@ -82,7 +108,27 @@ class BlockStrategy(private val context: Context, private val apis: IMogoService
|
||||
stopFlag = 0
|
||||
}
|
||||
|
||||
if (current - startRecordTime >= SPEED_RECORD_TIME_INTERVAL) {
|
||||
if (lastLat == 0.0) {
|
||||
// 定位初始化,只判断一个就行了
|
||||
lastLon = lon
|
||||
lastLat = lat
|
||||
} else {
|
||||
// 记录行进距离
|
||||
tripDistance += com.mogo.module.service.Utils.calculateLineDistance(lastLon, lastLat, lon, lat).toInt()
|
||||
lastLon = lon
|
||||
lastLat = lat
|
||||
}
|
||||
|
||||
if (current - startRecordTime >= DISTANCE_RECORD_TIME) {
|
||||
|
||||
var blockFromSpeed = false
|
||||
var blockFromDistance = false
|
||||
|
||||
var latLonFromSpeed: MogoLatLng? = null
|
||||
var latLonFromDistance: MogoLatLng? = null
|
||||
|
||||
val p = TanluUploadParams(IMogoTanluProvider.TYPE_BLOCK, IMogoTanluProvider.UPLOAD_FROM_STRATEGY_BLOCK_AUTO)
|
||||
|
||||
// 到达时间限制,上报速度,数据清空
|
||||
if (stopFlag < STOP_FLAG_THRESHOLD) {
|
||||
// 停车标志位小于阈值,判定不是停车,计算平均值,进行上报
|
||||
@@ -92,12 +138,85 @@ class BlockStrategy(private val context: Context, private val apis: IMogoService
|
||||
}
|
||||
val ave = sum / speedCacheList.size
|
||||
Logger.d(TAG, "平均速度为: $ave")
|
||||
blockFromSpeed = true
|
||||
// 上报平均速度
|
||||
uploadAverageSpeed(ave)
|
||||
val location = ServiceApisManager.serviceApis.mapServiceApi.getSingletonLocationClient(context).lastKnowLocation
|
||||
latLonFromSpeed = MogoLatLng(location.latitude, location.longitude)
|
||||
} else {
|
||||
Logger.d(TAG, "判定为停车,不进行上报")
|
||||
}
|
||||
|
||||
// 超过阈值,准备判断是否拥堵
|
||||
if (tripDistance in 100..1000 && isClose() && currentSpeed < 40) {
|
||||
Logger.d(TAG, "根据距离,判定为拥堵,准备上报, tripDistance: $tripDistance, frontDistance: $frontDistance, currentSpeed: $currentSpeed")
|
||||
latLonFromDistance = MogoLatLng(lat, lon)
|
||||
blockFromDistance = true
|
||||
} else {
|
||||
Logger.d(TAG, "根据距离,没有判定为拥堵, tripDistance: $tripDistance, frontDistance: $frontDistance, currentSpeed: $currentSpeed")
|
||||
}
|
||||
tripDistance = 0
|
||||
lastLat = 0.0
|
||||
lastLon = 0.0
|
||||
startRecordTime = 0
|
||||
|
||||
if (blockFromDistance || blockFromSpeed) {
|
||||
Logger.d(TAG, "判定拥堵,准备上报 blockFromDistance: $blockFromDistance, blockFromSpeed: $blockFromSpeed")
|
||||
if (isMorningPeak()) {
|
||||
val distanceMorningCount = SharedPrefsMgr.getInstance(context).getInt(DISTANCE_MORNING_PEAK_COUNT, 0)
|
||||
val speedMorningCount = SharedPrefsMgr.getInstance(context).getInt(SPEED_MORNING_PEAK_COUNT, 0)
|
||||
if (blockFromDistance && distanceMorningCount < 2) {
|
||||
Logger.d(TAG, "按距离策略上报早高峰")
|
||||
SharedPrefsMgr.getInstance(context).putInt(DISTANCE_MORNING_PEAK_COUNT, distanceMorningCount + 1)
|
||||
p.location = latLonFromDistance
|
||||
apis.analyticsApi.track("v2x_share_autoUpload", mapOf("type" to 1))
|
||||
apis.tanluApi.uploadRoadCondition(p)
|
||||
return
|
||||
}
|
||||
if (blockFromSpeed && speedMorningCount < 2) {
|
||||
Logger.d(TAG, "按速度策略上报早高峰")
|
||||
SharedPrefsMgr.getInstance(context).putInt(SPEED_MORNING_PEAK_COUNT, speedMorningCount + 1)
|
||||
p.location = latLonFromSpeed
|
||||
apis.tanluApi.uploadRoadCondition(p)
|
||||
return
|
||||
}
|
||||
} else if (isNightPeak()) {
|
||||
val distanceNightCount = SharedPrefsMgr.getInstance(context).getInt(DISTANCE_NIGHT_PEAK_COUNT, 0)
|
||||
val speedNightCount = SharedPrefsMgr.getInstance(context).getInt(SPEED_NIGHT_PEAK_COUNT, 0)
|
||||
if (blockFromDistance && distanceNightCount < 3) {
|
||||
Logger.d(TAG, "按距离策略上报晚高峰")
|
||||
SharedPrefsMgr.getInstance(context).putInt(DISTANCE_NIGHT_PEAK_COUNT, distanceNightCount + 1)
|
||||
p.location = latLonFromDistance
|
||||
apis.analyticsApi.track("v2x_share_autoUpload", mapOf("type" to 1))
|
||||
apis.tanluApi.uploadRoadCondition(p)
|
||||
return
|
||||
}
|
||||
if (blockFromSpeed && speedNightCount < 3) {
|
||||
Logger.d(TAG, "按速度策略上报晚高峰")
|
||||
SharedPrefsMgr.getInstance(context).putInt(SPEED_NIGHT_PEAK_COUNT, speedNightCount + 1)
|
||||
p.location = latLonFromSpeed
|
||||
apis.tanluApi.uploadRoadCondition(p)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
val distanceNormalCount = SharedPrefsMgr.getInstance(context).getInt(DISTANCE_NORMAL_COUNT, 0)
|
||||
val speedNormalCount = SharedPrefsMgr.getInstance(context).getInt(SPEED_NORMAL_COUNT, 0)
|
||||
if (blockFromDistance && distanceNormalCount < 5) {
|
||||
Logger.d(TAG, "按距离策略上报一般时段")
|
||||
SharedPrefsMgr.getInstance(context).putInt(DISTANCE_NORMAL_COUNT, distanceNormalCount + 1)
|
||||
p.location = latLonFromDistance
|
||||
apis.analyticsApi.track("v2x_share_autoUpload", mapOf("type" to 1))
|
||||
apis.tanluApi.uploadRoadCondition(p)
|
||||
return
|
||||
}
|
||||
if (blockFromSpeed && speedNormalCount < 5) {
|
||||
Logger.d(TAG, "按速度策略上报早高峰")
|
||||
SharedPrefsMgr.getInstance(context).putInt(SPEED_NORMAL_COUNT, speedNormalCount + 1)
|
||||
p.location = latLonFromSpeed
|
||||
apis.tanluApi.uploadRoadCondition(p)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,82 +228,37 @@ class BlockStrategy(private val context: Context, private val apis: IMogoService
|
||||
*/
|
||||
private var tripDistance: Int = 0
|
||||
|
||||
/**
|
||||
* 距离策略上报
|
||||
*
|
||||
* 1. 过去3分钟,行驶距离<1km,大于30m
|
||||
* 2. 前车距离<5m,获取不到前车距离时,默认此项满足
|
||||
* 3. 当前车速<40km/h
|
||||
*
|
||||
* 满足上述条件,自动上报拥堵
|
||||
*/
|
||||
fun recordLocation(lat: Double, lon: Double) {
|
||||
if (lastLat == 0.0) {
|
||||
// 定位初始化,只判断一个就行了
|
||||
lastLon = lon
|
||||
lastLat = lat
|
||||
} else {
|
||||
// 记录行进距离
|
||||
tripDistance += com.mogo.module.service.Utils.calculateLineDistance(lastLon, lastLat, lon, lat).toInt()
|
||||
lastLon = lon
|
||||
lastLat = lat
|
||||
val current = SystemClock.uptimeMillis()
|
||||
if (startRecordDistanceTime == 0L) {
|
||||
startRecordDistanceTime = current
|
||||
}
|
||||
|
||||
if (current - startRecordDistanceTime >= DISTANCE_RECORD_TIME) {
|
||||
// 超过阈值,准备判断是否拥堵
|
||||
startRecordDistanceTime = 0L
|
||||
if (tripDistance in 100..1000 && isClose() && currentSpeed < 40) {
|
||||
Logger.d(TAG, "根据距离,判定为拥堵,准备上报, tripDistance: $tripDistance, frontDistance: $frontDistance, currentSpeed: $currentSpeed")
|
||||
val p = TanluUploadParams(IMogoTanluProvider.TYPE_BLOCK, IMogoTanluProvider.UPLOAD_FROM_STRATEGY_BLOCK_AUTO)
|
||||
val latLon = MogoLatLng(lat, lon)
|
||||
p.location = latLon
|
||||
// 疑似拥堵埋点上报
|
||||
apis.analyticsApi.track("v2x_share_autoUpload", mapOf("type" to 1))
|
||||
apis.tanluApi.uploadRoadCondition(p)
|
||||
} else {
|
||||
Logger.d(TAG, "根据距离,没有判定为拥堵, tripDistance: $tripDistance, frontDistance: $frontDistance, currentSpeed: $currentSpeed")
|
||||
}
|
||||
tripDistance = 0
|
||||
lastLat = 0.0
|
||||
lastLon = 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 没有有效前车距离或者前车距离小于5m
|
||||
*/
|
||||
private fun isClose(): Boolean {
|
||||
val r = (frontDistance in 1..4) || (frontDistance == -1)
|
||||
Logger.d(TAG,"r: $r")
|
||||
Logger.d(TAG, "r: $r")
|
||||
return r
|
||||
}
|
||||
|
||||
private fun uploadAverageSpeed(average: Float) {
|
||||
val params = ArrayMap<String, Any>()
|
||||
params["speed"] = average.toInt()
|
||||
val body = RequestBody.create(MediaType.parse("Content-type:application/json;charset=UTF-8"), GsonUtil.jsonFromObject(params))
|
||||
apis.networkApi.create(ShareApiService::class.java, HttpConstant.getNetHost()).sendAverageSpeedForBlockStrategy(body, Utils.getSn()).subscribeOn(Schedulers.io()).subscribe(object : SubscribeImpl<AverateSpeedResponse>(RequestOptions.create(context)) {
|
||||
override fun onSuccess(response: AverateSpeedResponse?) {
|
||||
super.onSuccess(response)
|
||||
response?.let {
|
||||
Logger.d(TAG, "收到服务端返回结果: $it")
|
||||
// 收到服务端回调,视情况进行视频上报
|
||||
if (it.result.upload) {
|
||||
val p = TanluUploadParams(it.result.poiType, IMogoTanluProvider.UPLOAD_FROM_STRATEGY_BLOCK_AUTO)
|
||||
val location = ServiceApisManager.serviceApis.mapServiceApi.getSingletonLocationClient(context).lastKnowLocation
|
||||
val latLon = MogoLatLng(location.latitude, location.longitude)
|
||||
p.location = latLon
|
||||
apis.tanluApi.uploadRoadCondition(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
// private fun uploadAverageSpeed(average: Float) {
|
||||
// val params = ArrayMap<String, Any>()
|
||||
// params["speed"] = average.toInt()
|
||||
// val body = RequestBody.create(MediaType.parse("Content-type:application/json;charset=UTF-8"), GsonUtil.jsonFromObject(params))
|
||||
// apis.networkApi.create(ShareApiService::class.java, HttpConstant.getNetHost()).sendAverageSpeedForBlockStrategy(body, Utils.getSn()).subscribeOn(Schedulers.io()).subscribe(object : SubscribeImpl<AverateSpeedResponse>(RequestOptions.create(context)) {
|
||||
// override fun onSuccess(response: AverateSpeedResponse?) {
|
||||
// super.onSuccess(response)
|
||||
// response?.let {
|
||||
// Logger.d(TAG, "收到服务端返回结果: $it")
|
||||
// // 收到服务端回调,视情况进行视频上报
|
||||
// if (it.result.upload) {
|
||||
// val p = TanluUploadParams(it.result.poiType, IMogoTanluProvider.UPLOAD_FROM_STRATEGY_BLOCK_AUTO)
|
||||
// val location = ServiceApisManager.serviceApis.mapServiceApi.getSingletonLocationClient(context).lastKnowLocation
|
||||
// val latLon = MogoLatLng(location.latitude, location.longitude)
|
||||
// p.location = latLon
|
||||
// apis.tanluApi.uploadRoadCondition(p)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// })
|
||||
// }
|
||||
|
||||
companion object {
|
||||
const val MSG_FRONT_DISTANCE_CHECK = 1001
|
||||
@@ -207,4 +281,22 @@ class BlockStrategy(private val context: Context, private val apis: IMogoService
|
||||
frontDistance = distance
|
||||
handler.sendEmptyMessageDelayed(MSG_FRONT_DISTANCE_CHECK, FRONT_DISTANCE_CHECK_DELAY)
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是早高峰
|
||||
*/
|
||||
private fun isMorningPeak(): Boolean {
|
||||
val hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
|
||||
val minute = Calendar.getInstance().get(Calendar.MINUTE) + hour * 60
|
||||
return minute in MORNING_PEAK_START_MINUTE..MORNING_PEAK_STOP_MINUTE
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否在晚高峰
|
||||
*/
|
||||
private fun isNightPeak(): Boolean {
|
||||
val hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
|
||||
val minute = Calendar.getInstance().get(Calendar.MINUTE) + hour * 60
|
||||
return minute in NIGHT_PEAK_START_MINUTE..NIGHT_PEAK_STOP_MINUTE
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user