package cn.flightfeather.supervision.business.location
|
|
import cn.flightfeather.supervision.common.utils.ExcelUtil
|
import cn.flightfeather.supervision.domain.ds1.entity.Scense
|
import cn.flightfeather.supervision.domain.ds1.mapper.ScenseMapper
|
import org.springframework.stereotype.Component
|
import tk.mybatis.mapper.entity.Example
|
import kotlin.math.PI
|
|
/**
|
* 路段周边查询
|
*/
|
@Component
|
class LocationRoadNearby(private val scenseMapper: ScenseMapper) {
|
|
private val utilFile = UtilFile()
|
|
data class BasePlace(
|
val name: String,
|
val sP: Pair<Double, Double>,
|
val eP: Pair<Double, Double>,
|
)
|
|
private fun searchOne(basePlace: BasePlace, distance: Double) {
|
val range = rangeRestriction(basePlace, distance)
|
getSceneFromDb(range).forEach { utilFile.parseRow(it) }
|
}
|
|
/**
|
* 搜寻参考路段给定半径内的点位
|
* @param basePlace 参考点位信息
|
* @param distance 搜索半径
|
*/
|
fun search(basePlace: BasePlace, distance: Double) {
|
utilFile.reset()
|
searchOne(basePlace, distance)
|
utilFile.outPutToFile()
|
}
|
|
fun searchList(pList: List<BasePlace>, distance: Double) {
|
utilFile.reset()
|
pList.forEach {
|
val range = rangeRestriction(it, distance)
|
val sceneList = getSceneFromDb(range)
|
if (sceneList.isEmpty()) {
|
utilFile.addRow(listOf(it.name))
|
}
|
sceneList.forEachIndexed { index, s->
|
utilFile.parseRow(s)
|
if (index == 0) {
|
utilFile.updateLastRow(0, ExcelUtil.MyCell(it.name, sceneList.size))
|
}
|
}
|
utilFile.index = 1
|
}
|
utilFile.outPutToFile(distance)
|
}
|
|
/**
|
* 根据圆心和半径查询范围内监测点(当前简化操作,改为以直径为边长的正方形范围)
|
* @param center 圆心
|
* @param radius 半径(单位:米)
|
* @return 场景列表
|
*/
|
fun searchByRadius(center: Pair<Double, Double>, radius: Double): List<Scense> {
|
// 求经度的最小值
|
val minLng = CoordinateUtil.getPointByLen(center, radius, PI * 1.5).first
|
// 求经度的最大值
|
val maxLng = CoordinateUtil.getPointByLen(center, radius, PI * 0.5).first
|
// 求纬度的最小值
|
val minLat = CoordinateUtil.getPointByLen(center, radius, PI).second
|
// 求纬度的最大值
|
val maxLat = CoordinateUtil.getPointByLen(center, radius, .0).second
|
|
val list = listOf(minLng, maxLng, minLat, maxLat)
|
return getSceneFromDb(list)
|
}
|
|
/**
|
* 范围限定
|
* 根据路段的始末点坐标和查询半径,计算最大可能的范围矩形,得出经纬度的最大最小值
|
*/
|
private fun rangeRestriction(basePlace: BasePlace, distance: Double): List<Double> {
|
// 求经度的最小值
|
val p1 = if (basePlace.sP.first < basePlace.eP.first) basePlace.sP else basePlace.eP
|
val minLng = CoordinateUtil.getPointByLen(p1, distance, PI * 1.5).first
|
// 求经度的最大值
|
val p2 = if (basePlace.sP.first > basePlace.eP.first) basePlace.sP else basePlace.eP
|
val maxLng = CoordinateUtil.getPointByLen(p2, distance, PI * 0.5).first
|
// 求纬度的最小值
|
val p3 = if (basePlace.sP.second < basePlace.eP.second) basePlace.sP else basePlace.eP
|
val minLat = CoordinateUtil.getPointByLen(p3, distance, PI).second
|
// 求纬度的最大值
|
val p4 = if (basePlace.sP.second > basePlace.eP.second) basePlace.sP else basePlace.eP
|
val maxLat = CoordinateUtil.getPointByLen(p4, distance, .0).second
|
|
return listOf(minLng, maxLng, minLat, maxLat)
|
}
|
|
/**
|
* 根据限定矩形范围从数据库获取符合条件的点位
|
*/
|
private fun getSceneFromDb(range: List<Double>): List<Scense> {
|
return scenseMapper.selectByExample(Example(Scense::class.java).apply {
|
createCriteria().andGreaterThanOrEqualTo("longitude", range[0])
|
.andLessThanOrEqualTo("longitude", range[1])
|
.andGreaterThanOrEqualTo("latitude", range[2])
|
.andLessThanOrEqualTo("latitude", range[3])
|
and(createCriteria().orNotEqualTo("extension1", "0")
|
.orIsNull("extension1"))
|
})
|
}
|
}
|