diff --git a/app/build.gradle b/app/build.gradle index b02d1782..826f37ee 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,7 +77,6 @@ android { } - dependencies { api project(':collect-library') implementation project(path: ':vtm-android') diff --git a/app/src/main/java/com/navinfo/omqs/bean/Route.kt b/app/src/main/java/com/navinfo/omqs/bean/Route.kt new file mode 100644 index 00000000..e57ec794 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/bean/Route.kt @@ -0,0 +1,24 @@ +package com.navinfo.omqs.bean + +import com.navinfo.collect.library.utils.GeometryTools +import com.navinfo.collect.library.utils.GeometryToolsKt +import org.locationtech.jts.geom.Geometry +import org.oscim.core.GeoPoint + +data class Route( + val linkId: String, + var sNode: String = "", + var eNode: String = "", + var direct: Int = 0, + var name: String = "", + var length: Double = 0.0, +) { + var pointList: MutableList = mutableListOf() + get() { + return field + } + set(value) { + length = GeometryTools.getDistance(value) + field = value + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt index 3fab9a26..db33d350 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt @@ -279,11 +279,8 @@ class MainActivity : BaseActivity() { viewModel.liveDataRoadName.observe(this) { if (it != null) { binding.mainActivityRoadName.text = it.properties["name"] - if (binding.mainActivityRoadName.visibility != View.VISIBLE) binding.mainActivityRoadName.visibility = - View.VISIBLE } else { - if (binding.mainActivityRoadName.visibility != View.GONE) binding.mainActivityRoadName.visibility = - View.GONE + binding.mainActivityRoadName.text = " " } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt index 74a6e62c..89378a1f 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt @@ -4,6 +4,7 @@ import android.app.Activity import android.content.Context import android.content.DialogInterface import android.content.SharedPreferences +import android.graphics.Color import android.graphics.drawable.AnimationDrawable import android.graphics.drawable.BitmapDrawable import android.os.Build @@ -29,34 +30,37 @@ import com.navinfo.collect.library.garminvirbxe.HostBean import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.OnGeoPointClickListener import com.navinfo.collect.library.map.handler.* +import com.navinfo.collect.library.utils.DistanceUtil import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryToolsKt import com.navinfo.collect.library.utils.MapParamUtils import com.navinfo.omqs.Constant import com.navinfo.omqs.R -import com.navinfo.omqs.bean.ImportConfig -import com.navinfo.omqs.bean.QRCodeBean -import com.navinfo.omqs.bean.SignBean -import com.navinfo.omqs.bean.TraceVideoBean +import com.navinfo.omqs.bean.* import com.navinfo.omqs.db.RealmOperateHelper import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetworkService +import com.navinfo.omqs.tools.FileManager import com.navinfo.omqs.ui.dialog.CommonDialog import com.navinfo.omqs.ui.manager.TakePhotoManager import com.navinfo.omqs.ui.other.BaseToast -import com.navinfo.omqs.util.SignUtil -import com.navinfo.omqs.util.DateTimeUtil -import com.navinfo.omqs.util.ShareUtil -import com.navinfo.omqs.util.SoundMeter -import com.navinfo.omqs.util.SpeakMode +import com.navinfo.omqs.util.* import dagger.hilt.android.lifecycle.HiltViewModel import io.realm.Realm import io.realm.RealmConfiguration import io.realm.RealmSet import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.withContext +import org.locationtech.jts.algorithm.distance.DistanceToPoint +import org.locationtech.jts.algorithm.distance.PointPairDistance +import org.locationtech.jts.geom.Coordinate import org.locationtech.jts.geom.Geometry import org.oscim.core.GeoPoint import org.oscim.core.MapPosition @@ -86,6 +90,9 @@ class MainViewModel @Inject constructor( private var mCameraDialog: CommonDialog? = null + //路径计算 + val liveDataPlanningPathStatus = MutableLiveData() + //地图点击捕捉到的质检数据ID列表 val liveDataQsRecordIdList = MutableLiveData>() @@ -210,16 +217,22 @@ class MainViewModel @Inject constructor( private var currentMapZoomLevel: Int = 0 + //导航信息 + private var naviEngine: NaviEngine = NaviEngine() + + // 定义一个互斥锁 + private val naviMutex = Mutex() + + init { + mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition -> when (e) { Map.SCALE_EVENT, Map.MOVE_EVENT, Map.ROTATE_EVENT -> liveDataCenterPoint.value = mapPosition } - if (mapController.mMapView.vtmMap.mapPosition.zoomLevel >= 16) { - } currentMapZoomLevel = mapController.mMapView.vtmMap.mapPosition.zoomLevel }) @@ -307,9 +320,46 @@ class MainViewModel @Inject constructor( Constant.currentSelectTaskConfig = RealmConfiguration.Builder().directory(Constant.currentSelectTaskFolder).name("OMQS.realm").encryptionKey(Constant.PASSWORD).allowQueriesOnUiThread(true).schemaVersion(2).build() MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig) socketServer = SocketServer(mapController, traceDataBase, sharedPreferences) + +// viewModelScope.launch(Dispatchers.Default) { +// naviTestFlow().collect { +// naviMutex.lock() +// if (naviEngine.geometry != null) { +// //定义垂线 +// val pointPairDistance = PointPairDistance() +// val coordinate = Coordinate(it.longitude, it.latitude) +// DistanceToPoint.computeDistance( +// naviEngine.geometry, +// coordinate, +// pointPairDistance +// ) +// if (pointPairDistance.getCoordinate(0) !== null) { +// val line = GeometryTools.createLineString( +// mutableListOf( +// it, +// GeoPoint( +// pointPairDistance.getCoordinate(0).y, +// pointPairDistance.getCoordinate(0).x +// ) +// ) +// ) +// mapController.lineHandler.showLine(line.toText()) +// } +// } +// naviMutex.unlock() +// } +// } } + fun naviTestFlow(): Flow = flow { + + while (true) { + emit(mapController.mMapView.vtmMap.mapPosition.geoPoint) + delay(1000) + } + } + /** * 获取当前任务 */ @@ -319,6 +369,146 @@ class MainViewModel @Inject constructor( val res = realm.where(TaskBean::class.java).equalTo("id", id).findFirst() if (res != null) { currentTaskBean = realm.copyFromRealm(res) + planningPath(currentTaskBean!!) + } + realm.close() + } + + + private fun planningPath(taskBean: TaskBean) { + if (taskBean.status == FileManager.Companion.FileDownloadStatus.DONE) { +// Toast.makeText(context, "正在计算导航路径", Toast.LENGTH_SHORT).show() + viewModelScope.launch(Dispatchers.Default) { + naviMutex.lock() + naviEngine = NaviEngine() + val pathList = mutableListOf() + val realm = Realm.getDefaultInstance() + for (link in taskBean.hadLinkDvoList) { + //测线不参与导航 + if (link.linkStatus == 3) { + continue + } + val route = Route( + linkId = link.linkPid, + ) + route.pointList = GeometryTools.getGeoPoints(link.geometry) + //查询每条link的snode,enode + val res1 = realm.where(RenderEntity::class.java) + .equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).and() + .equalTo("properties['linkPid']", link.linkPid).findFirst() + res1?.let { + + val snodePid = it.properties["snodePid"] + if (snodePid != null) { + route.sNode = snodePid + } + val enodePid = it.properties["enodePid"] + if (enodePid != null) { + route.eNode = enodePid + } + } + //查询每条link的方向 + val res2 = realm.where(RenderEntity::class.java) + .equalTo("table", DataCodeEnum.OMDB_LINK_DIRECT.name).and() + .equalTo("properties['linkPid']", link.linkPid).findFirst() + res2?.let { + val direct = it.properties["direct"] + if (direct != null) { + route.direct = direct.toInt() + } + } + //查询每条link的名称 + val res3 = realm.where(RenderEntity::class.java) + .equalTo("table", DataCodeEnum.OMDB_LINK_NAME.name).and() + .equalTo("properties['linkPid']", link.linkPid).findFirst() + res3?.let { + route.name = "${it.properties["name"]}" + } + pathList.add(route) + } + //用来存储最终的导航路径 + val newRouteList = mutableListOf() + //比对路径排序用的 + val tempRouteList = pathList.toMutableList() + //先找到一根有方向的link,确定起终点 + var routeStart: Route? = null + for (i in tempRouteList.indices) { + val route = pathList[i] + //只要时单方向的就行 + if (route.direct == 2 || route.direct == 3) { + routeStart = route + tempRouteList.removeAt(i) + break + } + } + if (routeStart != null) { + var sNode = "" + var eNode = "" + //如果snode,enode是顺方向,geometry 不动,否则反转 + if (routeStart.direct == 3) { + routeStart.pointList.reverse() + sNode = routeStart.eNode + eNode = routeStart.sNode + } else { + sNode = routeStart.sNode + eNode = routeStart.eNode + } + newRouteList.add(routeStart) + var bBreak = true + while (bBreak) { + //先找其实link的后续link + var bHasNext = false + for (route in tempRouteList) { + //如果是link 的e 对下个link的s,方向不用动,否则下个link的geometry反转 + if (route.sNode != "" && eNode == route.sNode) { + newRouteList.add(route) + tempRouteList.remove(route) + eNode = route.eNode + bHasNext = true + break + } else if (route.eNode != "" && eNode == route.eNode) { + route.pointList.reverse() + newRouteList.add(route) + tempRouteList.remove(route) + eNode = route.sNode + bHasNext = true + break + } + } + //先找其实link的起始link + var bHasLast = false + for (route in tempRouteList) { + //如果是link 的s 对上个link的e,方向不用动,否则下个link的geometry反转 + if (route.eNode != "" && sNode == route.eNode) { + newRouteList.add(0, route) + tempRouteList.remove(route) + sNode = route.sNode + bHasLast = true + break + } else if (route.sNode != "" && sNode == route.sNode) { + route.pointList.reverse() + newRouteList.add(0, route) + tempRouteList.remove(route) + sNode = route.eNode + bHasLast = true + break + } + } + if (tempRouteList.size == 0) { + bBreak = false + } else { + if (!bHasLast && !bHasNext) { + bBreak = false + //TODO 处理错误,路径不完整 + } + } + } + } + naviEngine.routeList = newRouteList + naviMutex.unlock() + } + } else { +// Toast.makeText(context, "数据未安装,无法计算导航路径", Toast.LENGTH_SHORT).show() } realm.close() } @@ -615,7 +805,7 @@ class MainViewModel @Inject constructor( val realm = realmOperateHelper.getSelectTaskRealmInstance() - val entity = + val entityList = realmOperateHelper.getSelectTaskRealmTools(RenderEntity::class.java, true) .and() .equalTo("table", DataCodeEnum.OMDB_RESTRICTION.name) @@ -623,23 +813,32 @@ class MainViewModel @Inject constructor( .equalTo( "properties['linkIn']", it ).findFirst() - if (entity != null) { - val outLink = entity.properties["linkOut"] - val linkOutEntity = - realmOperateHelper.getSelectTaskRealmTools(RenderEntity::class.java, true) - .and() - .equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).and() - .equalTo( - "properties['${RenderEntity.Companion.LinkTable.linkPid}']", - outLink - ).findFirst() - if (linkOutEntity != null) { - mapController.lineHandler.linksLayer.addLine( - linkOutEntity.geometry, 0x7DFF0000 - ) + if (entityList.isNotEmpty()) { + val outList = entityList.distinct() + for (i in outList.indices) { + val outLink = outList[i].properties["linkOut"] + val linkOutEntity = + realmOperateHelper.getSelectTaskRealmTools( + RenderEntity::class.java, + true + ) + .equalTo("table", DataCodeEnum.OMDB_RD_LINK.name).and() + .equalTo( + "properties['${RenderEntity.Companion.LinkTable.linkPid}']", + outLink + ).findFirst() + if (linkOutEntity != null) { + mapController.lineHandler.linksLayer.addLine( + linkOutEntity.geometry, 0x7DFF0000 + ) + } } + mapController.lineHandler.linksLayer.addLine( + link.geometry, + Color.BLUE + ) + realm.close() } - realm.close() } liveDataTopSignList.postValue(topSignList.distinctBy { it.name } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/signMoreInfo/LaneBoundaryAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/signMoreInfo/LaneBoundaryAdapter.kt index 59f8bddc..19f8b18d 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/signMoreInfo/LaneBoundaryAdapter.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/signMoreInfo/LaneBoundaryAdapter.kt @@ -37,6 +37,7 @@ class LaneBoundaryAdapter : RecyclerView.Adapter() { fun bind(pos: Int, laneBoundaryItem: LaneBoundaryItem) { viewBinding.contactName.text = laneBoundaryItem.title if (laneBoundaryItem.itemList != null) { + viewBinding.infos.removeAllViews() for (item in laneBoundaryItem.itemList) { var view = LayoutInflater.from(viewBinding.root.context) .inflate(R.layout.adapter_two_item, null, false) diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt index af5cdd91..c5bb218f 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklist/TaskViewModel.kt @@ -11,15 +11,14 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.navinfo.collect.library.data.dao.impl.TraceDataBase -import com.navinfo.collect.library.data.entity.HadLinkDvoBean -import com.navinfo.collect.library.data.entity.NiLocation -import com.navinfo.collect.library.data.entity.QsRecordBean -import com.navinfo.collect.library.data.entity.TaskBean +import com.navinfo.collect.library.data.entity.* +import com.navinfo.collect.library.enums.DataCodeEnum import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.OnGeoPointClickListener import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.MapParamUtils import com.navinfo.omqs.Constant +import com.navinfo.omqs.bean.Route import com.navinfo.omqs.db.RealmOperateHelper import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetworkService @@ -149,7 +148,7 @@ class TaskViewModel @Inject constructor( } } } - }else { + } else { viewModelScope.launch(Dispatchers.IO) { val links = realmOperateHelper.queryLink( point = point, @@ -186,7 +185,7 @@ class TaskViewModel @Inject constructor( /** * 获取任务列表 */ - fun loadNetTaskList(context: Context){ + fun loadNetTaskList(context: Context) { viewModelScope.launch(Dispatchers.IO) { when (val result = networkService.getTaskList(Constant.USER_ID)) { is NetResult.Success -> { @@ -243,12 +242,12 @@ class TaskViewModel @Inject constructor( } is NetResult.Loading -> {} + else -> {} } } } - /** * 获取任务列表 */ @@ -286,7 +285,7 @@ class TaskViewModel @Inject constructor( * 设置当前选择的任务,并高亮当前任务的所有link */ - fun setSelectTaskBean(taskBean: TaskBean) { + fun setSelectTaskBean( taskBean: TaskBean) { sharedPreferences.edit().putInt(Constant.SELECT_TASK_ID, taskBean.id).apply() @@ -300,9 +299,10 @@ class TaskViewModel @Inject constructor( MapParamUtils.setTaskConfig(Constant.currentSelectTaskConfig) mapController.layerManagerHandler.updateOMDBVectorTileLayer() mapController.mMapView.updateMap(true) - } + + private fun showTaskLinks(taskBean: TaskBean) { mapController.lineHandler.removeAllTaskLine() diff --git a/app/src/main/java/com/navinfo/omqs/util/NaviEngine.kt b/app/src/main/java/com/navinfo/omqs/util/NaviEngine.kt new file mode 100644 index 00000000..863ed36c --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/util/NaviEngine.kt @@ -0,0 +1,25 @@ +package com.navinfo.omqs.util + +import com.navinfo.collect.library.utils.GeometryTools +import com.navinfo.omqs.bean.Route +import org.locationtech.jts.geom.LineString +import org.oscim.core.GeoPoint + +class NaviEngine { + var geometry: LineString? = null + var routeList = mutableListOf() + get() { + return field + } + set(value) { + val list = mutableListOf() + list.addAll(value[0].pointList) + for (i in 1 until value.size) { + val list2 = value[i].pointList + list2.removeAt(0) + list.addAll(list2) + } + geometry = GeometryTools.createLineString(list) + field = value + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/util/SignUtil.kt b/app/src/main/java/com/navinfo/omqs/util/SignUtil.kt index ec6b6c94..cbda1321 100644 --- a/app/src/main/java/com/navinfo/omqs/util/SignUtil.kt +++ b/app/src/main/java/com/navinfo/omqs/util/SignUtil.kt @@ -563,15 +563,57 @@ class SignUtil { try { val linkList = renderEntity.properties["tollinfoList"] if (linkList != null && linkList != "" && linkList != "null") { - val itemList = mutableListOf() + val jsonArray = JSONArray(linkList) for (i in 0 until jsonArray.length()) { val arrayObject: JSONObject = jsonArray[i] as JSONObject - - // itemList.add(TwoItemAdapterItem("方向", direct)) - + val itemList = mutableListOf() try { + itemList.add( + TwoItemAdapterItem("通道号码", "${arrayObject.optString("pid")}") + ) val stringBuffer = StringBuffer() + + stringBuffer.setLength(0) + val passageType = arrayObject.getInt("passageType") + for (i in 1 downTo 0) { + val bit = (passageType shr i) and 1 + if (bit == 1) { + when (i) { + 0 -> stringBuffer.append("称重车道 ") + 1 -> stringBuffer.append("绿色通道 ") + } + } + } + itemList.add( + TwoItemAdapterItem("通道类型", stringBuffer.toString()) + ) + + + stringBuffer.setLength(0) + val payMethod = arrayObject.getInt("payMethod") + for (i in 8 downTo 0) { + val bit = (payMethod shr i) and 1 + if (bit == 1) { + when (i) { + 0 -> stringBuffer.append("ETC ") + 1 -> stringBuffer.append("现金 ") + 2 -> stringBuffer.append("银行卡(借记卡) ") + 3 -> stringBuffer.append("信用卡 ") + 4 -> stringBuffer.append("IC卡 ") + 5 -> stringBuffer.append("预付卡 ") + 6 -> stringBuffer.append("微信 ") + 7 -> stringBuffer.append("支付宝 ") + 8 -> stringBuffer.append("其他APP ") + + } + } + } + itemList.add( + TwoItemAdapterItem("收费方式", stringBuffer.toString()) + ) + + stringBuffer.setLength(0) val cardType = arrayObject.getInt("cardType") for (i in 2 downTo 0) { val bit = (cardType shr i) and 1 @@ -586,34 +628,18 @@ class SignUtil { itemList.add( TwoItemAdapterItem("领卡方式", stringBuffer.toString()) ) - } catch (e: Exception) { - Log.e("jingo", "领卡方式 报错 ${e.message}") - } - try { - val stringBuffer = StringBuffer() - val passageType = arrayObject.getInt("passageType") - for (i in 2 downTo 0) { - val bit = (passageType shr i) and 1 - if (bit == 1) { - when (i) { - 0 -> stringBuffer.append("ETC ") - 1 -> stringBuffer.append("人工 ") - 2 -> stringBuffer.append("自助 ") - } - } - } - itemList.add( - TwoItemAdapterItem("领卡方式", stringBuffer.toString()) + + val seqNum = arrayObject.getInt("seqNum") + list.add( + LaneBoundaryItem( + "车道$seqNum", null, itemList + ) ) } catch (e: Exception) { Log.e("jingo", "领卡方式 报错 ${e.message}") } } - list.add( - LaneBoundaryItem( - "车道信息", null, itemList - ) - ) + } } catch (e: Exception) { @@ -642,9 +668,9 @@ class SignUtil { try { val linkList = renderEntity.properties["linkList"] if (linkList != null && linkList != "" && linkList != "null") { - val itemList = mutableListOf() val jsonArray = JSONArray(linkList) for (i in 0 until jsonArray.length()) { + val itemList = mutableListOf() val arrayObject: JSONObject = jsonArray[i] as JSONObject val direct = when (arrayObject.getInt("direct")) { 2 -> "顺方向" @@ -652,6 +678,7 @@ class SignUtil { else -> "" } itemList.add(TwoItemAdapterItem("方向", direct)) + val featureType = when (arrayObject.getInt("featureType")) { 1 -> "LINK" 2 -> "LINK PA" diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 17a22bdf..81439ebf 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -102,7 +102,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginRight="@dimen/top_right_drawer_btns_mr" - app:constraint_referenced_ids="main_activity_note,main_activity_task_line,main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_calc_distance,main_activity_menu" + app:constraint_referenced_ids="main_activity_add_new,main_activity_task_line,main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_calc_distance,main_activity_menu" app:flow_horizontalGap="6dp" app:flow_wrapMode="aligned" app:layout_constraintRight_toLeftOf="@id/main_activity_right_fragment" @@ -113,7 +113,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="invisible" - app:constraint_referenced_ids="main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_note,main_activity_task_line,main_activity_calc_distance" /> + app:constraint_referenced_ids="main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_add_new,main_activity_task_line,main_activity_calc_distance" /> + android:onClick="@{()->mainActivity.voiceOnclick()}" + android:src="@drawable/icon_add_data" /> @@ -291,11 +290,11 @@ app:layout_constraintRight_toRightOf="@id/main_activity_map_update" /> @@ -305,8 +304,8 @@ android:layout_marginBottom="12dp" android:onClick="@{()->mainActivity.voiceOnclick()}" android:src="@drawable/icon_add_voice" - app:layout_constraintBottom_toTopOf="@id/main_activity_add_new" - app:layout_constraintRight_toRightOf="@id/main_activity_add_new" /> + app:layout_constraintBottom_toTopOf="@id/main_activity_note" + app:layout_constraintRight_toRightOf="@id/main_activity_note" /> + app:constraint_referenced_ids="main_activity_close_line,main_activity_select_line,main_activity_voice,main_activity_note" /> + app:constraint_referenced_ids="main_activity_close_line,main_activity_select_line,main_activity_voice,main_activity_note,main_activity_map_update,main_activity_zoom_in,main_activity_zoom_out,main_activity_geometry,main_activity_location" /> mContext.lifecycleScope.launch { @@ -212,6 +215,7 @@ private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLoc val call = callback; override fun onReceiveLocation(location: BDLocation) { call(location) + Log.e("jingo", "定位结果:速度=" + location.speed +" 方向=" + location.direction) } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java b/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java index 02d1e1ff..4ac644d2 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/utils/GeometryTools.java @@ -1,7 +1,12 @@ package com.navinfo.collect.library.utils; import android.graphics.Point; +import android.os.Build; import android.util.Log; + +import org.jetbrains.annotations.NotNull; +import org.locationtech.jts.algorithm.distance.DistanceToPoint; +import org.locationtech.jts.algorithm.distance.PointPairDistance; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; @@ -14,6 +19,7 @@ import org.locationtech.jts.io.WKTReader; import org.locationtech.jts.operation.linemerge.LineMerger; import org.oscim.core.GeoPoint; import org.oscim.map.Map; + import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; @@ -416,7 +422,7 @@ public class GeometryTools { Geometry startGeo = createGeometry(startGeoPoint); Geometry endGeo = createGeometry(endGeoPoint); double d = startGeo.distance(endGeo); - return convertDistanceToDegree(d,startGeoPoint.getLatitude()); + return convertDistanceToDegree(d, startGeoPoint.getLatitude()); } return 0; @@ -589,6 +595,21 @@ public class GeometryTools { return list; } + public static List getGeoPoints(Geometry geometry) { + List list = null; + if (geometry != null) { + Coordinate[] coordinates = geometry.getCoordinates(); + if (coordinates != null && coordinates.length > 0) { + list = new ArrayList(); + for (Coordinate coor : coordinates) { + list.add(new GeoPoint(coor.y, coor.x)); + } + } + } + return list; + } + + public static Coordinate[] getCoordinates(String str) { Coordinate[] coordinates = null; if (Check.isEmpty(str)) @@ -1294,6 +1315,8 @@ public class GeometryTools { } + + public enum SNAP_TYPE { /** * 像素 @@ -1327,7 +1350,7 @@ public class GeometryTools { } public static boolean isCheckError(double lon, double lat) { - if(lon==0||lat==0){ + if (lon == 0 || lat == 0) { return true; } @@ -1377,8 +1400,10 @@ public class GeometryTools { static class Check { public static boolean isEmpty(String str) { - if (str == null || str.isEmpty()) { - return true; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { + if (str == null || str.isEmpty()) { + return true; + } } return false; } @@ -1446,7 +1471,7 @@ public class GeometryTools { switch (unit) { case SNAP_PIXEL: org.oscim.core.Point p = new org.oscim.core.Point(); - fMap.viewport().toScreenPoint(gp,false, p); + fMap.viewport().toScreenPoint(gp, false, p); GeoPoint gPLq = fMap.viewport().fromScreenPoint((float) p.x, (float) p.y); org.oscim.core.Point pL = new org.oscim.core.Point((p.x - distance), (p.y - distance)); @@ -1521,6 +1546,7 @@ public class GeometryTools { /** * 计算距离 + * * @param list * @return */ @@ -1573,10 +1599,68 @@ public class GeometryTools { * @return 对应的地理坐标系中的距离(单位:度) */ private static final double EARTH_RADIUS = 6371000.0; + public static double convertDistanceToDegree(double distance, double latitude) { double radianDistance = distance / EARTH_RADIUS; double radianLatitude = Math.toRadians(latitude); + double radianDegree = 2 * Math.asin(Math.sin(radianDistance / 2) / Math.cos(radianLatitude)); return Math.toDegrees(radianDegree); } + + /** + * 经纬度转墨卡托 + */ + public static Coordinate geoPointToMercator(GeoPoint point) { + Coordinate coordinate = new Coordinate(); + + double x = point.getLongitude() * 20037508.34 / 180; + double y = Math.log(Math.tan((90 + point.getLatitude()) * Math.PI / 360)) / (Math.PI / 180); + + y = y * 20037508.34 / 180; + + coordinate.x = x; + coordinate.y = y; + + return coordinate; + } + + /** + * 墨卡托转经纬度 + */ + public static GeoPoint mercatorToGeoPoint(Coordinate coordinate) { + GeoPoint point = null; + double x = coordinate.x / 20037508.34 * 180; + double y = coordinate.y / 20037508.34 * 180; + + y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2); + + point = new GeoPoint(y, x); + return point; + } + + public static List pointToLineDistance(GeoPoint point, List pointList) { + + Coordinate coordinate = geoPointToMercator(point); + Coordinate[] cs = new Coordinate[pointList.size()]; + + for (int i = 0; i < pointList.size(); i++) { + Coordinate c = geoPointToMercator(pointList.get(i)); + cs[i] = c; + } + GeometryFactory factory = new GeometryFactory(); + LineString lineString = factory.createLineString(cs); + PointPairDistance pointPairDistance = new PointPairDistance(); + DistanceToPoint.computeDistance( + lineString, + coordinate, + pointPairDistance + ); + + List newPoints = new ArrayList(); + for (int i = 0; i < pointPairDistance.getCoordinates().length; i++) { + newPoints.add(mercatorToGeoPoint(pointPairDistance.getCoordinate(i))); + } + return newPoints; + } } diff --git a/vtm b/vtm index 3031b706..3ea6a7c9 160000 --- a/vtm +++ b/vtm @@ -1 +1 @@ -Subproject commit 3031b70699d5d886834d75cc098466daa8cef118 +Subproject commit 3ea6a7c90627e6e8ea10b3896004d9082167a7ff