Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS

 Conflicts:
	vtm
This commit is contained in:
squallzhjch
2023-08-10 11:18:40 +08:00
32 changed files with 996 additions and 270 deletions

View File

@@ -5,42 +5,45 @@
"code": 1012,
"name": "检查点",
"zoomMin": 16,
"zoomMax": 22
"zoomMax": 19
},
"2001": {
"table": "OMDB_RD_LINK",
"code": 2001,
"name": "道路线",
"zoomMin": 16,
"zoomMax": 22
"zoomMax": 17
},
"2002": {
"table": "OMDB_RD_LINK_FUNCTION_CLASS",
"code": 2002,
"name": "道路功能等级",
"zoomMin": 16,
"zoomMax": 22
"zoomMax": 19
},
"2008": {
"table": "OMDB_RD_LINK_KIND",
"code": 2008,
"name": "道路种别",
"zoomMin": 16,
"zoomMax": 22
"zoomMax": 19,
"checkLinkId": false
},
"2010": {
"table": "OMDB_LINK_DIRECT",
"code": 2010,
"name": "道路方向",
"zoomMin": 16,
"zoomMax": 22
"zoomMax": 19,
"checkLinkId": false
},
"2011": {
"table": "OMDB_LINK_NAME",
"code": 2011,
"name": "道路名",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 19,
"checkLinkId": false,
"transformer": [
{
"k": "geometry",
@@ -54,8 +57,9 @@
"table": "OMDB_LANE_MARK_BOUNDARYTYPE",
"code": 2013,
"name": "车道边界类型",
"zoomMin": 19,
"zoomMax": 22,
"zoomMin": 18,
"zoomMax": 21,
"checkLinkId": false,
"transformer": [
{
"k": "geometry",
@@ -70,21 +74,21 @@
"code": 2019,
"name": "常规线限速",
"zoomMin": 16,
"zoomMax": 22
"zoomMax": 19
},
"2020": {
"table": "OMDB_LINK_SPEEDLIMIT_COND",
"code": 2020,
"name": "条件线限速",
"zoomMin": 16,
"zoomMax": 22
"zoomMax": 19
},
"2021": {
"table": "OMDB_LINK_SPEEDLIMIT_VAR",
"code": 2021,
"name": "可变线限速",
"zoomMin": 16,
"zoomMax": 22
"zoomMax": 19
},
"2022": {
"table": "OMDB_CON_ACCESS",
@@ -110,20 +114,31 @@
"table": "OMDB_RDBOUND_BOUNDARYTYPE",
"code": 2083,
"name": "道路边界类型",
"zoomMin": 19,
"zoomMax": 22
"zoomMin": 18,
"zoomMax": 21,
"checkLinkId": false
},
"2201":{
"table": "OMDB_BRIDGE",
"code": 2201,
"name": "桥"
"name": "桥",
"zoomMin": 16,
"zoomMax": 21,
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateS2EReferencePoint(bridgeType,OMDB_BRIDGE)"
}
]
},
"2202":{
"table": "OMDB_TUNNEL",
"code": 2202,
"name": "隧道",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 21,
"transformer": [
{
"k": "geometry",
@@ -134,11 +149,11 @@
]
},
"4001": {
"table": "OMDB_INTERSECTION",
"code": 4001,
"name": "路口",
"table": "OMDB_INTERSECTION",
"code": 4001,
"name": "路口",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 19,
"transformer": [
{
"k": "geometry",
@@ -147,13 +162,13 @@
"vlib": "generateIntersectionReference()"
}
]
},
},
"4002": {
"table": "OMDB_SPEEDLIMIT",
"code": 4002,
"name": "常规点限速",
"table": "OMDB_SPEEDLIMIT",
"code": 4002,
"name": "常规点限速",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 19,
"transformer": [
{
"k": "maxSpeed",
@@ -168,13 +183,13 @@
"vlib": "translateRight()"
}
]
},
},
"4003":{
"table": "OMDB_SPEEDLIMIT_COND",
"code": 4003,
"name": "条件点限速",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 19,
"transformer": [
{
"k": "maxSpeed",
@@ -189,7 +204,7 @@
"code": 4004,
"name": "可变点限速",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 19,
"transformer": [
{
"k": "location",
@@ -216,7 +231,7 @@
"code": 4006,
"name": "普通交限",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 21,
"transformer": [
{
"k": "geometry",
@@ -255,7 +270,7 @@
"code": 4010,
"name": "电子眼",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 21,
"transformer": [
{
"k": "geometry",
@@ -273,7 +288,7 @@
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateDirectReferenceLine()"
"vlib": "generateDirectReferenceLine(3)"
},
{
"k": "geometry",
@@ -288,7 +303,7 @@
"code": 4022,
"name": "交通灯",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 21,
"transformer": [
]
},
@@ -297,7 +312,7 @@
"code": 4601,
"name": "车信",
"zoomMin": 16,
"zoomMax": 22,
"zoomMax": 19,
"transformer": [
{
"k": "geometry",
@@ -319,12 +334,12 @@
}
]
},
"5001":{
"table": "OMDB_LANE_LINK_LG",
"code": 5001,
"name": "车道中心线",
"zoomMin": 19,
"zoomMax": 22,
"5001":{
"table": "OMDB_LANE_LINK_LG",
"code": 5001,
"name": "车道中心线",
"zoomMin": 18,
"zoomMax": 21,
"transformer": [
{
"k": "geometry",
@@ -333,42 +348,11 @@
"vlib": "generateAddWidthLine()"
}
]
},
},
"5002":{
"table": "OMDB_AREA",
"code": 5002,
"name": "面测试"
},
"3005":{
"table": "OMDB_TRAFFIC_SIGN",
"code": 3005,
"name": "交通标牌",
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "normalizationTrafficSignHeight()"
},{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "generateDirectReferenceLine('', 0.2)"
}
]
},
"3006":{
"table": "OMDB_POLE",
"code": 3006,
"name": "杆状物",
"transformer": [
{
"k": "geometry",
"v": "~",
"klib": "geometry",
"vlib": "normalizationPoleHeight()"
}
]
}
}
}

View File

@@ -121,6 +121,7 @@ class TableInfo {
val code: Int = 0
val zoomMin: Int = 16
val zoomMax: Int = 21
val checkLinkId: Boolean = true//是否需要校验linkid
val name: String = ""
var checked : Boolean = true
var transformer: MutableList<Transform> = mutableListOf()

View File

@@ -11,6 +11,7 @@ import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.navinfo.collect.library.data.entity.ReferenceEntity
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.ImportConfig
import com.navinfo.omqs.hilt.OMDBDataBaseHiltFactory
@@ -101,10 +102,13 @@ class ImportOMDBHelper @AssistedInject constructor(
FIELD_TYPE_NULL -> rowMap[columnName] = ""
FIELD_TYPE_INTEGER -> rowMap[columnName] =
getInt(columnIndex)
FIELD_TYPE_FLOAT -> rowMap[columnName] =
getFloat(columnIndex)
FIELD_TYPE_BLOB -> rowMap[columnName] =
String(getBlob(columnIndex), Charsets.UTF_8)
else -> rowMap[columnName] = getString(columnIndex)
}
}
@@ -123,99 +127,132 @@ class ImportOMDBHelper @AssistedInject constructor(
* @param omdbZipFile omdb数据抽取生成的Zip文件
* @param configFile 对应的配置文件
* */
suspend fun importOmdbZipFile(omdbZipFile: File, taskId: Int): Flow<String> = withContext(Dispatchers.IO) {
val unZipFolder = File(omdbZipFile.parentFile, "result")
flow {
if (unZipFolder.exists()) {
unZipFolder.deleteRecursively()
}
unZipFolder.mkdirs()
// 开始解压zip文件
val unZipFiles = ZipUtils.unzipFile(omdbZipFile, unZipFolder)
// 将listResult数据插入到Realm数据库中
val realm = Realm.getDefaultInstance()
realm.beginTransaction()
try {
// 遍历解压后的文件,读取该数据返回
for ((index, currentEntry) in importConfig.tableMap.entries.withIndex()) {
val currentConfig = currentEntry.value
val txtFile = unZipFiles.find {
it.name == currentConfig.table
}
suspend fun importOmdbZipFile(omdbZipFile: File, task: TaskBean): Flow<String> =
withContext(Dispatchers.IO) {
val unZipFolder = File(omdbZipFile.parentFile, "result")
flow {
if (unZipFolder.exists()) {
unZipFolder.deleteRecursively()
}
unZipFolder.mkdirs()
// 开始解压zip文件
val unZipFiles = ZipUtils.unzipFile(omdbZipFile, unZipFolder)
// 将listResult数据插入到Realm数据库中
val realm = Realm.getDefaultInstance()
realm.beginTransaction()
try {
// 遍历解压后的文件,读取该数据返回
for ((index, currentEntry) in importConfig.tableMap.entries.withIndex()) {
val currentConfig = currentEntry.value
val txtFile = unZipFiles.find {
it.name == currentConfig.table
}
val listResult = mutableListOf<RenderEntity>()
currentConfig?.let {
val list = FileIOUtils.readFile2List(txtFile, "UTF-8")
Log.d("ImportOMDBHelper", "开始解析:${txtFile?.name}")
if (list != null) {
// 将list数据转换为map
for ((index, line) in list.withIndex()) {
if (line == null || line.trim() == "") {
continue
}
Log.d("ImportOMDBHelper", "解析第:${index+1}")
val map = gson.fromJson<Map<String, Any>>(line, object:TypeToken<Map<String, Any>>(){}.getType())
.toMutableMap()
map["qi_table"] = currentConfig.table
map["qi_name"] = currentConfig.name
map["qi_code"] =
if (currentConfig.code == 0) currentConfig.code else currentEntry.key
map["qi_code"] = if (currentConfig.code == 0) currentConfig.code else currentEntry.key
map["qi_zoomMin"] = currentConfig.zoomMin
map["qi_zoomMax"] = currentConfig.zoomMax
// 先查询这个mesh下有没有数据如果有则跳过即可
// val meshEntity = Realm.getDefaultInstance().where(RenderEntity::class.java).equalTo("properties['mesh']", map["mesh"].toString()).findFirst()
val renderEntity = RenderEntity()
renderEntity.code = map["qi_code"].toString().toInt()
renderEntity.name = map["qi_name"].toString()
renderEntity.table = map["qi_table"].toString()
renderEntity.taskId = taskId
renderEntity.zoomMin = map["qi_zoomMin"].toString().toInt()
renderEntity.zoomMax = map["qi_zoomMax"].toString().toInt()
// 其他数据插入到Properties中
renderEntity.geometry = map["geometry"].toString()
for ((key, value) in map) {
when (value) {
is String -> renderEntity.properties.put(key, value)
is Int -> renderEntity.properties.put(
key,
value.toInt().toString()
)
is Double -> renderEntity.properties.put(
key,
value.toDouble().toString()
)
else -> renderEntity.properties.put(key, value.toString())
val listResult = mutableListOf<RenderEntity>()
currentConfig?.let {
val list = FileIOUtils.readFile2List(txtFile, "UTF-8")
Log.d("ImportOMDBHelper", "开始解析:${txtFile?.name}")
if (list != null) {
// 将list数据转换为map
for ((index, line) in list.withIndex()) {
if (line == null || line.trim() == "") {
continue
}
}
listResult.add(renderEntity)
// 对renderEntity做预处理后再保存
val resultEntity = importConfig.transformProperties(renderEntity)
if (resultEntity != null) {
realm.insert(renderEntity)
Log.d("ImportOMDBHelper", "解析第:${index + 1}")
val map = gson.fromJson<Map<String, Any>>(
line,
object : TypeToken<Map<String, Any>>() {}.getType()
)
.toMutableMap()
map["qi_table"] = currentConfig.table
map["qi_name"] = currentConfig.name
map["qi_code"] =
if (currentConfig.code == 0) currentConfig.code else currentEntry.key
map["qi_code"] =
if (currentConfig.code == 0) currentConfig.code else currentEntry.key
map["qi_zoomMin"] = currentConfig.zoomMin
map["qi_zoomMax"] = currentConfig.zoomMax
// 先查询这个mesh下有没有数据如果有则跳过即可
// val meshEntity = Realm.getDefaultInstance().where(RenderEntity::class.java).equalTo("properties['mesh']", map["mesh"].toString()).findFirst()
val renderEntity = RenderEntity()
renderEntity.code = map["qi_code"].toString().toInt()
renderEntity.name = map["qi_name"].toString()
renderEntity.table = map["qi_table"].toString()
renderEntity.taskId = task.id
renderEntity.zoomMin = map["qi_zoomMin"].toString().toInt()
renderEntity.zoomMax = map["qi_zoomMax"].toString().toInt()
// 其他数据插入到Properties中
renderEntity.geometry = map["geometry"].toString()
for ((key, value) in map) {
when (value) {
is String -> renderEntity.properties[key] = value
is Int -> renderEntity.properties[key] = value.toInt().toString()
is Double -> renderEntity.properties[key] = value.toDouble().toString()
else -> renderEntity.properties[key] = value.toString()
}
}
//如果要素不包括linkPid需要从其他字段获得
if(!renderEntity.properties.containsKey("linkPid")){
//交限从进入线获取
if(renderEntity.properties.containsKey("linkIn")){
renderEntity.properties["linkPid"]= renderEntity.properties["linkIn"]
}
}
//遍历判断只显示与任务Link相关的任务数据
if (currentConfig.checkLinkId && renderEntity.properties.containsKey("linkPid")) {
var currentLinkPid = renderEntity.properties["linkPid"]
task.hadLinkDvoList.forEach {
if (it.linkPid == currentLinkPid) {
renderEntity.enable = 1
Log.e("qj", "${renderEntity.name}==包括任务link")
return@forEach
}
}
} else {
renderEntity.enable = 2
Log.e("qj", "${renderEntity.name}==不包括任务linkPid")
}
listResult.add(renderEntity)
// 对renderEntity做预处理后再保存
val resultEntity = importConfig.transformProperties(renderEntity)
if (resultEntity != null) {
realm.insert(renderEntity)
}
}
}
}
// 1个文件发送一次flow流
emit("${index + 1}/${importConfig.tableMap.size}")
// 如果当前解析的是OMDB_RD_LINK数据将其缓存在预处理类中以便后续处理其他要素时使用
if (currentConfig.table == "OMDB_RD_LINK") {
importConfig.preProcess.cacheRdLink =
listResult.associateBy { it.properties["linkPid"] }
}
}
// 1个文件发送一次flow流
emit("${index + 1}/${importConfig.tableMap.size}")
// 如果当前解析的是OMDB_RD_LINK数据将其缓存在预处理类中以便后续处理其他要素时使用
if (currentConfig.table == "OMDB_RD_LINK") {
importConfig.preProcess.cacheRdLink =
listResult.associateBy { it.properties["linkPid"] }
}
realm.commitTransaction()
realm.close()
} catch (e: Exception) {
realm.cancelTransaction()
throw e
}
realm.commitTransaction()
realm.close()
} catch (e: Exception) {
realm.cancelTransaction()
throw e
emit("finish")
}
emit("finish")
}
}
// 获取指定数据表的列名
fun getColumns(db: SQLiteDatabase, tableName: String): List<String> {

View File

@@ -21,20 +21,26 @@ class ImportPreProcess {
val defaultTranslateDistance = 3.0
fun checkCircleRoad(renderEntity: RenderEntity): Boolean {
val linkInId = renderEntity.properties["linkIn"]
val linkOutId = renderEntity.properties["linkOut"]
val linkInId = renderEntity.properties["linkIn"]
val linkOutId = renderEntity.properties["linkOut"]
// 根据linkIn和linkOut获取对应的link数据
val linkInEntity = cacheRdLink[linkInId]
val linkOutEntity = cacheRdLink[linkOutId]
Log.d("checkCircleRoad", "LinkInEntity: ${linkInId}- ${linkInEntity?.properties?.get("snodePid")}LinkOutEntity: ${linkOutId}- ${linkOutEntity?.properties?.get("enodePid")}")
Log.d(
"checkCircleRoad",
"LinkInEntity: ${linkInId}- ${linkInEntity?.properties?.get("snodePid")}LinkOutEntity: ${linkOutId}- ${
linkOutEntity?.properties?.get("enodePid")
}"
)
// 查询linkIn的sNode和linkOut的eNode是否相同如果相同认为数据是环形路口返回false
if (linkInEntity!=null&&linkOutEntity!=null) {
if (linkInEntity.properties["snodePid"] == linkOutEntity.properties["enodePid"] || linkInEntity.properties["enodePid"] == linkOutEntity.properties["snodePid"] || linkInEntity.properties["snodePid"] == linkOutEntity.properties["snodePid"]|| linkInEntity.properties["enodePid"] == linkOutEntity.properties["enodePid"]) {
if (linkInEntity != null && linkOutEntity != null) {
if (linkInEntity.properties["snodePid"] == linkOutEntity.properties["enodePid"] || linkInEntity.properties["enodePid"] == linkOutEntity.properties["snodePid"] || linkInEntity.properties["snodePid"] == linkOutEntity.properties["snodePid"] || linkInEntity.properties["enodePid"] == linkOutEntity.properties["enodePid"]) {
return false
}
}
return true
}
/**
* 计算指定数据指定方向的坐标
* @param direction 判断当前数据是否为逆向给定的应该是一个a=b的表达式a为对应的properties的keyb为对应的值
@@ -47,17 +53,20 @@ class ImportPreProcess {
var isReverse = false // 是否为逆向
if (direction.isNotEmpty()) {
val paramDirections = direction.split("=")
if (paramDirections.size>=2 && renderEntity.properties[paramDirections[0].trim()] == paramDirections[1].trim()) {
if (paramDirections.size >= 2 && renderEntity.properties[paramDirections[0].trim()] == paramDirections[1].trim()) {
isReverse = true;
}
}
if (Geometry.TYPENAME_POINT == geometry?.geometryType) { // angle为与正北方向的顺时针夹角
var angle = if(renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get("angle")?.toDouble()!!
var angle =
if (renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get(
"angle"
)?.toDouble()!!
// if (isReverse) {
// angle += 180
// }
// angle角度为与正北方向的顺时针夹角将其转换为与X轴正方向的逆时针夹角即为正东方向的夹角
angle=(450-angle)%360
angle = (450 - angle) % 360
radian = Math.toRadians(angle)
} else if (Geometry.TYPENAME_LINESTRING == geometry?.geometryType) {
var coordinates = geometry.coordinates
@@ -72,8 +81,14 @@ class ImportPreProcess {
}
// 计算偏移距离
val dx: Double = GeometryTools.convertDistanceToDegree(defaultTranslateDistance, geometry?.coordinate?.y!!) * Math.cos(radian)
val dy: Double = GeometryTools.convertDistanceToDegree(defaultTranslateDistance, geometry?.coordinate?.y!!) * Math.sin(radian)
val dx: Double = GeometryTools.convertDistanceToDegree(
defaultTranslateDistance,
geometry?.coordinate?.y!!
) * Math.cos(radian)
val dy: Double = GeometryTools.convertDistanceToDegree(
defaultTranslateDistance,
geometry?.coordinate?.y!!
) * Math.sin(radian)
// 计算偏移后的点
val coord =
@@ -81,11 +96,13 @@ class ImportPreProcess {
// 记录偏移后的点位或线数据,如果数据为线时,记录的偏移后数据为倒数第二个点右移后,方向与线的最后两个点平行同向的单位向量
if (Geometry.TYPENAME_POINT == geometry?.geometryType) {
val geometryTranslate: Geometry = GeometryTools.createGeometry(doubleArrayOf(coord.x, coord.y))
val geometryTranslate: Geometry =
GeometryTools.createGeometry(doubleArrayOf(coord.x, coord.y))
renderEntity.geometry = geometryTranslate.toString()
} else {
val coorEnd = Coordinate(coord.x+dx, coord.y+dy)
val geometryTranslate: Geometry = GeometryTools.createLineString(arrayOf(coord, coorEnd))
val coorEnd = Coordinate(coord.x + dx, coord.y + dy)
val geometryTranslate: Geometry =
GeometryTools.createLineString(arrayOf(coord, coorEnd))
renderEntity.geometry = geometryTranslate.toString()
}
}
@@ -99,19 +116,22 @@ class ImportPreProcess {
var isReverse = false // 是否为逆向
if (direction.isNotEmpty()) {
val paramDirections = direction.split("=")
if (paramDirections.size>=2 && renderEntity.properties[paramDirections[0].trim()] == paramDirections[1].trim()) {
if (paramDirections.size >= 2 && renderEntity.properties[paramDirections[0].trim()] == paramDirections[1].trim()) {
isReverse = true;
}
}
var radian = 0.0 // geometry的角度如果是点获取angle如果是线获取最后两个点的方向
var point = Coordinate(geometry?.coordinate)
if (Geometry.TYPENAME_POINT == geometry?.geometryType) {
var angle = if(renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get("angle")?.toDouble()!!
var angle =
if (renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get(
"angle"
)?.toDouble()!!
// if (isReverse) {
// angle += 180
// }
// angle角度为与正北方向的顺时针夹角将其转换为与X轴正方向的逆时针夹角即为正东方向的夹角
angle=(450-angle)%360
angle = (450 - angle) % 360
radian = Math.toRadians(angle)
} else if (Geometry.TYPENAME_LINESTRING == geometry?.geometryType) {
var coordinates = geometry.coordinates
@@ -126,15 +146,22 @@ class ImportPreProcess {
}
// 计算偏移距离
val dx: Double = GeometryTools.convertDistanceToDegree(defaultTranslateDistance, geometry?.coordinate?.y!!) * Math.cos(radian)
val dy: Double = GeometryTools.convertDistanceToDegree(defaultTranslateDistance, geometry?.coordinate?.y!!) * Math.sin(radian)
val dx: Double = GeometryTools.convertDistanceToDegree(
defaultTranslateDistance,
geometry?.coordinate?.y!!
) * Math.cos(radian)
val dy: Double = GeometryTools.convertDistanceToDegree(
defaultTranslateDistance,
geometry?.coordinate?.y!!
) * Math.sin(radian)
// 计算偏移后的点
val coord =
Coordinate(point.getX() - dx, point.getY() - dy)
// 将这个点记录在数据中
val geometryTranslate: Geometry = GeometryTools.createGeometry(doubleArrayOf(coord.x, coord.y))
val geometryTranslate: Geometry =
GeometryTools.createGeometry(doubleArrayOf(coord.x, coord.y))
renderEntity.geometry = geometryTranslate.toString()
}
@@ -146,13 +173,17 @@ class ImportPreProcess {
val translateGeometry = renderEntity.wkt
val startGeometry = GeometryTools.createGeometry(renderEntity.properties["geometry"])
var pointEnd = translateGeometry!!.coordinates[translateGeometry.numPoints-1] // 获取这个geometry对应的结束点坐标
var pointStart = startGeometry!!.coordinates[startGeometry.numPoints-1] // 获取这个geometry对应的结束点坐标
var pointEnd =
translateGeometry!!.coordinates[translateGeometry.numPoints - 1] // 获取这个geometry对应的结束点坐标
var pointStart =
startGeometry!!.coordinates[startGeometry.numPoints - 1] // 获取这个geometry对应的结束点坐标
if (translateGeometry.geometryType == Geometry.TYPENAME_LINESTRING) { // 如果是线数据,则取倒数第二个点作为偏移的起止点
pointEnd = translateGeometry!!.coordinates[translateGeometry.numPoints-2] // 获取这个geometry对应的结束点坐标
pointEnd =
translateGeometry!!.coordinates[translateGeometry.numPoints - 2] // 获取这个geometry对应的结束点坐标
}
if (startGeometry.geometryType == Geometry.TYPENAME_LINESTRING) { // 如果是线数据,则取倒数第二个点作为偏移的起止点
pointStart = startGeometry!!.coordinates[startGeometry.numPoints-2] // 获取这个geometry对应的结束点坐标
pointStart =
startGeometry!!.coordinates[startGeometry.numPoints - 2] // 获取这个geometry对应的结束点坐标
}
// 将这个起终点的线记录在数据中
@@ -163,60 +194,91 @@ class ImportPreProcess {
startEndReference.zoomMin = renderEntity.zoomMin
startEndReference.zoomMax = renderEntity.zoomMax
startEndReference.taskId = renderEntity.taskId
startEndReference.enable = renderEntity.enable
// 起终点坐标组成的线
startEndReference.geometry = GeometryTools.createLineString(arrayOf<Coordinate>(pointStart, pointEnd)).toString()
startEndReference.geometry =
GeometryTools.createLineString(arrayOf<Coordinate>(pointStart, pointEnd)).toString()
startEndReference.properties["qi_table"] = renderEntity.table
startEndReference.properties["type"] = "s_2_e"
Realm.getDefaultInstance().insert(startEndReference)
}
fun generateS2EReferencePoint(renderEntity: RenderEntity) {
fun generateS2EReferencePoint(
renderEntity: RenderEntity,
proKey: String = "",
table: String = ""
) {
val geometry = GeometryTools.createGeometry(renderEntity.properties["geometry"])
val pointEnd = geometry!!.coordinates[geometry.numPoints-1] // 获取这个geometry对应的结束点坐标
val pointEnd = geometry!!.coordinates[geometry.numPoints - 1] // 获取这个geometry对应的结束点坐标
val pointStart = geometry!!.coordinates[0] // 获取这个geometry对应的起点
// 将这个起终点的线记录在数据中
val startReference = ReferenceEntity()
startReference.renderEntityId = renderEntity.id
startReference.name = "${renderEntity.name}参考线"
startReference.name = "${renderEntity.name}参考"
startReference.table = renderEntity.table
startReference.zoomMin = renderEntity.zoomMin
startReference.zoomMax = renderEntity.zoomMax
startReference.taskId = renderEntity.taskId
startReference.enable = renderEntity.enable
// 起点坐标
startReference.geometry = GeometryTools.createGeometry(GeoPoint(pointStart.y,pointStart.x)).toString()
startReference.geometry =
GeometryTools.createGeometry(GeoPoint(pointStart.y, pointStart.x)).toString()
startReference.properties = renderEntity.properties
startReference.properties["qi_table"] = renderEntity.table
startReference.properties["type"] = "s_2_p"
Log.e("qj","generateS2EReferencePoint===$table===$proKey")
if (renderEntity.table == table) {
Log.e("qj","generateS2EReferencePoint===开始")
if (renderEntity.properties.containsKey(proKey)) {
startReference.properties["type"] = "s_2_p_${renderEntity.properties[proKey]}"
Log.e("qj","generateS2EReferencePoint===s_2_p_${renderEntity.properties[proKey]}")
}
} else {
startReference.properties["type"] = "s_2_p"
}
Realm.getDefaultInstance().insert(startReference)
val endReference = ReferenceEntity()
endReference.renderEntityId = renderEntity.id
endReference.name = "${renderEntity.name}参考线"
endReference.name = "${renderEntity.name}参考"
endReference.table = renderEntity.table
endReference.zoomMin = renderEntity.zoomMin
endReference.zoomMax = renderEntity.zoomMax
endReference.taskId = renderEntity.taskId
endReference.enable = renderEntity.enable
// 终点坐标
endReference.geometry = GeometryTools.createGeometry(GeoPoint(pointEnd.y,pointEnd.x)).toString()
endReference.geometry =
GeometryTools.createGeometry(GeoPoint(pointEnd.y, pointEnd.x)).toString()
endReference.properties = renderEntity.properties
endReference.properties["qi_table"] = renderEntity.table
endReference.properties["type"] = "e_2_p"
if (renderEntity.table == table) {
if (renderEntity.properties.containsKey(proKey)) {
endReference.properties["type"] = "e_2_p_${renderEntity.properties[proKey]}"
}
} else {
endReference.properties["type"] = "e_2_p"
}
Realm.getDefaultInstance().insert(endReference)
}
/**
* 生成与对应方向相同的方向线,用以绘制方向箭头
* */
fun generateDirectReferenceLine(renderEntity: RenderEntity, direction: String = "", distance: String = "") {
fun generateDirectReferenceLine(
renderEntity: RenderEntity,
direction: String = "",
distance: String = ""
) {
// 根据数据或angle计算方向对应的角度和偏移量
val geometry = renderEntity.wkt
var isReverse = false // 是否为逆向
if (direction.isNotEmpty()) {
val paramDirections = direction.split("=")
if (paramDirections.size>=2 && renderEntity.properties[paramDirections[0].trim()] == paramDirections[1].trim()) {
if (paramDirections.size >= 2 && renderEntity.properties[paramDirections[0].trim()] == paramDirections[1].trim()) {
isReverse = true
}
}
@@ -225,9 +287,12 @@ class ImportPreProcess {
if (Geometry.TYPENAME_POINT == geometry?.geometryType) {
val point = Coordinate(geometry?.coordinate)
pointStartArray.add(point)
var angle = if(renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get("angle")?.toDouble()!!
var angle =
if (renderEntity?.properties?.get("angle") == null) 0.0 else renderEntity?.properties?.get(
"angle"
)?.toDouble()!!
// angle角度为与正北方向的顺时针夹角将其转换为与X轴正方向的逆时针夹角即为正东方向的夹角
angle=(450-angle)%360
angle = (450 - angle) % 360
radian = Math.toRadians(angle)
} else if (Geometry.TYPENAME_LINESTRING == geometry?.geometryType) {
var coordinates = geometry.coordinates
@@ -243,7 +308,7 @@ class ImportPreProcess {
// 记录下面数据的每一个点位
pointStartArray.addAll(geometry.coordinates)
// 获取当前的面数据对应的方向信息
var angle = if(renderEntity?.properties?.get("angle") == null) {
var angle = if (renderEntity?.properties?.get("angle") == null) {
if (renderEntity?.properties?.get("heading") == null) {
0.0
} else {
@@ -251,16 +316,28 @@ class ImportPreProcess {
}
} else renderEntity?.properties?.get("angle")?.toDouble()!!
angle=(450-angle)%360
angle = (450 - angle) % 360
radian = Math.toRadians(angle)
}
// 计算偏移距离
var dx: Double = GeometryTools.convertDistanceToDegree(defaultTranslateDistance, geometry?.coordinate?.y!!) * Math.cos(radian)
var dy: Double = GeometryTools.convertDistanceToDegree(defaultTranslateDistance, geometry?.coordinate?.y!!) * Math.sin(radian)
var dx: Double = GeometryTools.convertDistanceToDegree(
defaultTranslateDistance,
geometry?.coordinate?.y!!
) * Math.cos(radian)
var dy: Double = GeometryTools.convertDistanceToDegree(
defaultTranslateDistance,
geometry?.coordinate?.y!!
) * Math.sin(radian)
if (distance.isNotEmpty()) {
dx = GeometryTools.convertDistanceToDegree(distance.toDouble(), geometry?.coordinate?.y!!) * Math.cos(radian)
dy = GeometryTools.convertDistanceToDegree(distance.toDouble(), geometry?.coordinate?.y!!) * Math.sin(radian)
dx = GeometryTools.convertDistanceToDegree(
distance.toDouble(),
geometry?.coordinate?.y!!
) * Math.cos(radian)
dy = GeometryTools.convertDistanceToDegree(
distance.toDouble(),
geometry?.coordinate?.y!!
) * Math.sin(radian)
}
for (pointStart in pointStartArray) {
@@ -273,8 +350,10 @@ class ImportPreProcess {
angleReference.zoomMin = renderEntity.zoomMin
angleReference.zoomMax = renderEntity.zoomMax
angleReference.taskId = renderEntity.taskId
angleReference.enable = renderEntity.enable
// 与原有方向指向平行的线
angleReference.geometry = WKTWriter(3).write(GeometryTools.createLineString(arrayOf(pointStart, coorEnd)))
angleReference.geometry =
WKTWriter(3).write(GeometryTools.createLineString(arrayOf(pointStart, coorEnd)))
angleReference.properties["qi_table"] = renderEntity.table
angleReference.properties["type"] = "angle"
Realm.getDefaultInstance().insert(angleReference)
@@ -284,10 +363,10 @@ class ImportPreProcess {
fun addAngleFromGeometry(renderEntity: RenderEntity): String {
if (!renderEntity.properties.containsKey("angle")) {
if (renderEntity.wkt!=null) {
if (renderEntity.wkt != null) {
val geometry = renderEntity.wkt
var angle: String = "90"
if (geometry?.numPoints!!>=2) {
if (geometry?.numPoints!! >= 2) {
val p1: Coordinate = geometry?.coordinates?.get(geometry.coordinates.size - 2)!!
val p2: Coordinate = geometry?.coordinates?.get(geometry.coordinates.size - 1)!!
// 弧度转角度
@@ -307,16 +386,18 @@ class ImportPreProcess {
* 解析车道边线数据二级属性
* */
fun unpackingLaneBoundary(renderEntity: RenderEntity) {
var shape:JSONObject = JSONObject(mapOf(
"lateralOffset" to 0,
"markType" to 1,
"markColor" to 0,
"markMaterial" to 1,
"markSeqNum" to 1,
"markWidth" to 10,
"markingCount" to 1
))
if (renderEntity.code == 2013&&!renderEntity.properties["shapeList"].isNullOrEmpty()&&renderEntity.properties["shapeList"]!="null") {
var shape: JSONObject = JSONObject(
mapOf(
"lateralOffset" to 0,
"markType" to 1,
"markColor" to 0,
"markMaterial" to 1,
"markSeqNum" to 1,
"markWidth" to 10,
"markingCount" to 1
)
)
if (renderEntity.code == 2013 && !renderEntity.properties["shapeList"].isNullOrEmpty() && renderEntity.properties["shapeList"] != "null") {
// 解析shapeList将数组中的属性放会properties
val shapeList = JSONArray(renderEntity.properties["shapeList"])
for (i in 0 until shapeList.length()) {
@@ -336,9 +417,12 @@ class ImportPreProcess {
* */
fun unpackingLaneInfo(renderEntity: RenderEntity) {
if (renderEntity.code == 4601) {
if (!renderEntity.properties["laneinfoGroup"].isNullOrEmpty()&&renderEntity.properties["laneinfoGroup"]!="null") {
if (!renderEntity.properties["laneinfoGroup"].isNullOrEmpty() && renderEntity.properties["laneinfoGroup"] != "null") {
// 解析laneinfoGroup将数组中的属性放会properties
val laneinfoGroup = JSONArray(renderEntity.properties["laneinfoGroup"].toString().replace("{", "[").replace("}", "]"))
val laneinfoGroup = JSONArray(
renderEntity.properties["laneinfoGroup"].toString().replace("{", "[")
.replace("}", "]")
)
// 分别获取两个数组中的数据,取第一个作为主数据,另外两个作为辅助渲染数据
val laneInfoDirectArray = JSONArray(laneinfoGroup[0].toString())
val laneInfoTypeArray = JSONArray(laneinfoGroup[1].toString())
@@ -352,9 +436,12 @@ class ImportPreProcess {
// 与原数据使用相同的geometry
referenceEntity.geometry = renderEntity.geometry.toString()
referenceEntity.properties["qi_table"] = renderEntity.table
referenceEntity.properties["currentDirect"] = laneInfoDirectArray[i].toString().split(",").distinct().joinToString("_")
referenceEntity.properties["currentType"] = laneInfoTypeArray[i].toString().split(",").distinct().joinToString("_")
referenceEntity.properties["symbol"] = "assets:omdb/4601/bus/1301_"+referenceEntity.properties["currentDirect"]+".svg"
referenceEntity.properties["currentDirect"] =
laneInfoDirectArray[i].toString().split(",").distinct().joinToString("_")
referenceEntity.properties["currentType"] =
laneInfoTypeArray[i].toString().split(",").distinct().joinToString("_")
referenceEntity.properties["symbol"] =
"assets:omdb/4601/bus/1301_" + referenceEntity.properties["currentDirect"] + ".svg"
Log.d("unpackingLaneInfo", referenceEntity.properties["symbol"].toString())
Realm.getDefaultInstance().insert(referenceEntity)
}
@@ -368,25 +455,27 @@ class ImportPreProcess {
* */
fun generateRoadName(renderEntity: RenderEntity) {
// LinkName的真正名称数据是保存在properties的shapeList中的因此需要解析shapeList数据
var shape :JSONObject? = null
var shape: JSONObject? = null
if (renderEntity.properties.containsKey("shapeList")) {
val shapeListJsonArray: JSONArray = JSONArray(renderEntity.properties["shapeList"])
for (i in 0 until shapeListJsonArray.length()) {
val shapeJSONObject = shapeListJsonArray.getJSONObject(i)
if (shapeJSONObject["nameClass"]==1) {
if (shapeJSONObject["nameClass"] == 1) {
if (shape == null) {
shape = shapeJSONObject
}
// 获取第一官方名
//("名称分类"NAME_CLASS =“1 官方名”且名称序号SEQ_NUM 最小者)
if (shapeJSONObject["seqNum"].toString().toInt()< shape!!["seqNum"].toString().toInt()) {
if (shapeJSONObject["seqNum"].toString().toInt() < shape!!["seqNum"].toString()
.toInt()
) {
shape = shapeJSONObject
}
}
}
}
// 获取最小的shape值将其记录增加记录在properties的name属性下
if(shape!=null) {
if (shape != null) {
renderEntity.properties["name"] = shape["name"].toString()
} else {
renderEntity.properties["name"] = ""
@@ -398,9 +487,10 @@ class ImportPreProcess {
* */
fun generateElectronName(renderEntity: RenderEntity) {
// 解析电子眼的kind将其转换为渲染的简要名称
var shape :JSONObject? = null
var shape: JSONObject? = null
if (renderEntity.properties.containsKey("kind")) {
renderEntity.properties["name"] = code2NameMap.electronEyeKindMap[renderEntity.properties["kind"].toString().toInt()]
renderEntity.properties["name"] =
code2NameMap.electronEyeKindMap[renderEntity.properties["kind"].toString().toInt()]
} else {
renderEntity.properties["name"] = ""
}
@@ -421,6 +511,7 @@ class ImportPreProcess {
angleReference.zoomMin = renderEntity.zoomMin
angleReference.zoomMax = renderEntity.zoomMax
angleReference.taskId = renderEntity.taskId
angleReference.enable = renderEntity.enable
Realm.getDefaultInstance().insert(angleReference)
}
@@ -441,14 +532,29 @@ class ImportPreProcess {
intersectionReference.zoomMin = renderEntity.zoomMin
intersectionReference.zoomMax = renderEntity.zoomMax
intersectionReference.taskId = renderEntity.taskId
intersectionReference.enable = renderEntity.enable
// 与原有方向指向平行的线
intersectionReference.geometry = GeometryTools.createGeometry(nodeJSONObject["geometry"].toString()).toString()
intersectionReference.geometry =
GeometryTools.createGeometry(nodeJSONObject["geometry"].toString()).toString()
intersectionReference.properties["qi_table"] = renderEntity.table
intersectionReference.properties["type"] = "node"
Realm.getDefaultInstance().insert(intersectionReference)
}
}
}
/**
* 生成默认路口数据的参考数据
* */
fun generateIntersectionDynamic(renderEntity: RenderEntity) {
// 路口数据的其他点位是保存在nodeList对应的数组下
if (renderEntity.properties.containsKey("type")) {
if (renderEntity.properties["type"] == "0") {
renderEntity.properties["typesrc"] = "assets:symbols/dot_blue_dark.svg"
} else {
renderEntity.properties["typesrc"] = "assets:symbols/volcano.svg"
}
}
}
/**
* 处理杆状物的高程数据
@@ -456,14 +562,14 @@ class ImportPreProcess {
fun normalizationPoleHeight(renderEntity: RenderEntity) {
// 获取杆状物的高程数据
val geometry = renderEntity.wkt
if (geometry!=null) {
var minHeight=Double.MAX_VALUE
var maxHeight=Double.MIN_VALUE
if (geometry != null) {
var minHeight = Double.MAX_VALUE
var maxHeight = Double.MIN_VALUE
for (coordinate in geometry.coordinates) {
if (coordinate.z<minHeight) {
if (coordinate.z < minHeight) {
minHeight = coordinate.z
}
if (coordinate.z>maxHeight) {
if (coordinate.z > maxHeight) {
maxHeight = coordinate.z
}
}
@@ -475,7 +581,8 @@ class ImportPreProcess {
coordinate.z = 40.0
}
}
renderEntity.geometry = WKTWriter(3).write(GeometryTools.createLineString(geometry.coordinates))
renderEntity.geometry =
WKTWriter(3).write(GeometryTools.createLineString(geometry.coordinates))
}
}
@@ -485,24 +592,25 @@ class ImportPreProcess {
fun normalizationTrafficSignHeight(renderEntity: RenderEntity) {
// 获取交通标牌的高程数据
val geometry = renderEntity.wkt
if (geometry!=null) {
if (geometry != null) {
// 获取所有的高程信息,计算高程的中位数,方便对高程做定制化处理
var midHeight=0.0
var midHeight = 0.0
var countHeight = 0.0
for (coordinate in geometry.coordinates) {
countHeight+=coordinate.z
countHeight += coordinate.z
}
midHeight = countHeight/geometry.coordinates.size
midHeight = countHeight / geometry.coordinates.size
// 对高程数据做特殊处理
for (coordinate in geometry.coordinates) {
if (coordinate.z>=midHeight) {
if (coordinate.z >= midHeight) {
coordinate.z = 40.0
} else {
coordinate.z = 30.0
}
}
renderEntity.geometry = WKTWriter(3).write(GeometryTools.getPolygonGeometry(geometry.coordinates))
renderEntity.geometry =
WKTWriter(3).write(GeometryTools.getPolygonGeometry(geometry.coordinates))
}
}
}

View File

@@ -133,6 +133,24 @@ class RealmOperateHelper() {
return link
}
suspend fun queryLinkToMutableRenderEntityList(linkPid: String): MutableList<RenderEntity>? {
val resultList = mutableListOf<RenderEntity>()
val realm = Realm.getDefaultInstance()
val realmR = realm.where(RenderEntity::class.java)
.equalTo("properties['${LinkTable.linkPid}']", linkPid)
.findAll()
val dataList = realm.copyFromRealm(realmR)
dataList.forEach {
resultList.add(it)
}
return resultList
}
/**
* 根据当前点位查询匹配的除Link外的其他要素数据
* @param point 点位经纬度信息

View File

@@ -77,7 +77,7 @@ class TaskDownloadScope(
downloadJob = launch() {
FileManager.checkOMDBFileInfo(taskBean)
if (taskBean.status == FileDownloadStatus.IMPORT) {
importData(taskId = taskBean.id)
importData(task = taskBean)
} else {
download()
}
@@ -108,7 +108,7 @@ class TaskDownloadScope(
if (status != FileDownloadStatus.LOADING && status != FileDownloadStatus.IMPORTING) {
val realm = Realm.getDefaultInstance()
realm.executeTransaction {
it.copyToRealmOrUpdate(taskBean)
it.insertOrUpdate(taskBean)
}
}
}
@@ -127,7 +127,7 @@ class TaskDownloadScope(
/**
* 导入数据
*/
private suspend fun importData(file: File? = null, taskId: Int? = 0) {
private suspend fun importData(file: File? = null, task: TaskBean? = null) {
try {
Log.e("jingo", "importData SSS")
change(FileDownloadStatus.IMPORTING)
@@ -138,8 +138,8 @@ class TaskDownloadScope(
downloadManager.context,
fileNew
)
if (taskId != null) {
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, taskId).collect {
if (task != null) {
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task).collect {
Log.e("jingo", "数据安装 $it")
if (it == "finish") {
change(FileDownloadStatus.DONE)
@@ -187,7 +187,7 @@ class TaskDownloadScope(
startPosition = 0
}
if (fileTemp.length() > 0 && taskBean.fileSize > 0 && fileTemp.length() == taskBean.fileSize) {
importData(fileTemp, taskBean.id)
importData(fileTemp, taskBean)
return
}
@@ -228,7 +228,7 @@ class TaskDownloadScope(
randomAccessFile?.close()
inputStream = null
randomAccessFile = null
importData(taskId = taskBean.id)
importData(task = taskBean)
} else {
change(FileDownloadStatus.PAUSE)
}

View File

@@ -522,7 +522,7 @@ class MainActivity : BaseActivity() {
this
).setTitle("坐标定位").setView(view)
val editText = view.findViewById<EditText>(R.id.dialog_edittext)
editText.hint = "请输入经纬度例如:\n116.1234567,39.1234567\n116.1234567 39.1234567"
editText.hint = "请输入经纬度例如116.1234567,39.1234567"
inputDialog.setNegativeButton("取消") { dialog, _ ->
dialog.dismiss()
}
@@ -621,7 +621,7 @@ class MainActivity : BaseActivity() {
* 点击搜索
*/
fun onClickSearch() {
jumpPosition()
}
/**

View File

@@ -15,7 +15,6 @@ import com.blankj.utilcode.util.UriUtils
import com.github.k1rakishou.fsaf.FileChooser
import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks
import com.github.k1rakishou.fsaf.callback.FileChooserCallback
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
@@ -23,10 +22,8 @@ import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding
import com.navinfo.omqs.db.ImportOMDBHelper
import com.navinfo.omqs.hilt.ImportOMDBHiltFactory
import com.navinfo.omqs.tools.CoroutineUtils
import com.navinfo.omqs.ui.activity.map.MainActivity
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.activity.scan.QrCodeActivity
import com.navinfo.omqs.ui.fragment.console.ConsoleFragment
import com.permissionx.guolindev.PermissionX
import dagger.hilt.android.AndroidEntryPoint
import org.oscim.core.GeoPoint
@@ -126,7 +123,8 @@ class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit?
//116.25017070328308 40.061730653134696
// 定位到指定位置
niMapController.mMapView.vtmMap.animator()
.animateTo(GeoPoint( 40.055878135289966, 116.3011588289057 ))
// .animateTo(GeoPoint( 40.05108004733645, 116.29187746293708 ))
.animateTo(GeoPoint( 39.91975038055932,116.35447089476969 ))
}
// R.id.personal_center_menu_task_list -> {
// findNavController().navigate(R.id.TaskManagerFragment)

View File

@@ -162,11 +162,17 @@ class PersonalCenterViewModel @Inject constructor(
/**
* 导入OMDB数据
* */
fun importOMDBData(importOMDBHelper: ImportOMDBHelper,taskId:Int?=0) {
fun importOMDBData(importOMDBHelper: ImportOMDBHelper, task: TaskBean? =null) {
viewModelScope.launch(Dispatchers.IO) {
Log.d("OMQSApplication", "开始导入数据")
if (taskId != null) {
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, taskId).collect {
if (task != null) {
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, task).collect {
Log.d("importOMDBData", it)
}
} else {
val newTask = TaskBean()
newTask.id = 9999
importOMDBHelper.importOmdbZipFile(importOMDBHelper.omdbFile, newTask).collect {
Log.d("importOMDBData", it)
}
}

View File

@@ -421,8 +421,21 @@ class TaskViewModel @Inject constructor(
r.copyToRealmOrUpdate(hadLinkDvoBean)
r.copyToRealmOrUpdate(currentSelectTaskBean!!)
}
//根据Link数据查询对应数据上要素对要素进行显示重置
l.properties["linkPid"]?.let {
realmOperateHelper.queryLinkToMutableRenderEntityList(it)
?.forEach { renderEntity ->
if(renderEntity.enable!=1){
renderEntity.enable = 1
realm.executeTransaction { r ->
r.copyToRealmOrUpdate(renderEntity)
}
}
}
}
liveDataTaskLinks.postValue(currentSelectTaskBean!!.hadLinkDvoList)
mapController.lineHandler.addTaskLink(hadLinkDvoBean)
mapController.mMapView.vtmMap.updateMap(true)
}
}
}
@@ -461,7 +474,23 @@ class TaskViewModel @Inject constructor(
) { dialog, _ ->
dialog.dismiss()
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
//重置数据为隐藏
if(hadLinkDvoBean.linkStatus==2){
realmOperateHelper.queryLinkToMutableRenderEntityList(hadLinkDvoBean.linkPid)
?.forEach { renderEntity ->
if(renderEntity.enable==1){
renderEntity.enable = 0
realm.executeTransaction { r ->
r.copyToRealmOrUpdate(renderEntity)
}
}
}
mapController.mMapView.vtmMap.updateMap(true)
}
realm.executeTransaction {
for (link in currentSelectTaskBean!!.hadLinkDvoList) {
if (link.linkPid == hadLinkDvoBean.linkPid) {

View File

@@ -11,7 +11,7 @@
android:layout_margin="8dp"
android:background="@drawable/shape_rect_white_2dp_bg"
android:hint="请备注无需作业原因"
android:lines="5"
android:lines="4"
android:textSize="13dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -38,7 +38,7 @@
<item
android:id="@+id/personal_center_menu_version"
android:icon="@drawable/ic_baseline_layers_24"
android:title="版本ONE_QE_V1.5.0_20230728_A" />
android:title="版本ONE_23QE4_V1.1.0_20230804_A" />
</group>
<group android:checkableBehavior="single">
<item android:title="小标题">

View File

@@ -0,0 +1,97 @@
package com.navinfo.omqs;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class ParallelRectangleAlgorithm {
public static List<Point> getParallelRectanglePoints(List<Point> polygon) {
// Step 1: Get the first two points of the polygon to form a line
List<Point> line = new ArrayList<>();
line.add(polygon.get(0));
line.add(polygon.get(1));
// Step 2: Find the points on the opposite side or farther away from the line
List<Point> farPoints = new ArrayList<>();
for (int i = 2; i < polygon.size(); i++) {
Point point = polygon.get(i);
int side = getSide(line.get(0), line.get(1), point);
double distance = getDistance(line.get(0), line.get(1), point);
if (side != 0 && side != Math.signum(distance)) {
farPoints.add(point);
}
}
// Step 3: Find the perpendicular lines to the first line passing through the farthest points
List<Point> perpendicularLines = new ArrayList<>();
for (Point farPoint : farPoints) {
double dx = line.get(1).getY() - line.get(0).getY();
double dy = line.get(0).getX() - line.get(1).getX();
double magnitude = Math.sqrt(dx * dx + dy * dy);
dx /= magnitude;
dy /= magnitude;
double distance = Math.abs((farPoint.getX() - line.get(0).getX()) * dx + (farPoint.getY() - line.get(0).getY()) * dy);
Point perpendicularLine = new Point(farPoint.getX() + distance * dx, farPoint.getY() + distance * dy);
perpendicularLines.add(perpendicularLine);
}
// Step 4: Find the intersection points of the perpendicular lines
List<Point> intersectionPoints = new ArrayList<>();
for (int i = 0; i < perpendicularLines.size(); i++) {
for (int j = i + 1; j < perpendicularLines.size(); j++) {
Point intersectionPoint = getIntersectionPoint(line.get(0), perpendicularLines.get(i), line.get(1), perpendicularLines.get(j));
intersectionPoints.add(intersectionPoint);
}
}
return intersectionPoints;
}
private static int getSide(Point p1, Point p2, Point point) {
return Integer.signum((int) Math.signum((p2.getX() - p1.getX()) * (point.getY() - p1.getY()) - (p2.getY() - p1.getY()) * (point.getX() - p1.getX())));
}
private static double getDistance(Point p1, Point p2, Point point) {
return ((p2.getX() - p1.getX()) * (point.getY() - p1.getY()) - (p2.getY() - p1.getY()) * (point.getX() - p1.getX())) / Math.sqrt((p2.getX() - p1.getX()) * (p2.getX() - p1.getX()) + (p2.getY() - p1.getY()) * (p2.getY() - p1.getY()));
}
private static Point getIntersectionPoint(Point p1, Point p2, Point p3, Point p4) {
double x1 = p1.getX();
double y1 = p1.getY();
double x2 = p2.getX();
double y2 = p2.getY();
double x3 = p3.getX();
double y3 = p3.getY();
double x4 = p4.getX();
double y4 = p4.getY();
double x = ((x2 - x1) * (x3 * y4 - x4 * y3) - (x4 - x3) * (x1 * y2 - x2 * y1)) / ((x2 - x1) * (y3 - y4) - (x4 - x3) * (y1 - y2));
double y = ((y3 - y4) * (x1 * y2 - x2 * y1) - (y1 - y2) * (x3 * y4 - x4 * y3)) / ((x2 - x1) * (y3 - y4) - (x4 - x3) * (y1 - y2));
return new Point(x, y);
}
@Test
public void test() {
List<Point> polygon = new ArrayList<>();
polygon.add(new Point(0, 0));
polygon.add(new Point(2, 0));
polygon.add(new Point(2, 1));
polygon.add(new Point(1, 1));
polygon.add(new Point(1, 2));
polygon.add(new Point(0, 2));
List<Point> result = getParallelRectanglePoints(polygon);
for (Point point : result) {
System.out.println(point);
}
}
}
class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
@Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}