合并策略上报

This commit is contained in:
tongchenfei
2020-12-21 17:56:36 +08:00
parent 9f8dff8d4b
commit aa4710c58a
2 changed files with 164 additions and 73 deletions

View File

@@ -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 {

View File

@@ -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
}
}