修改定位,修改提前看板

This commit is contained in:
squallzhjch 2023-04-28 16:03:40 +08:00
parent 3dc650a76b
commit 894732ee45
23 changed files with 435 additions and 164 deletions

View File

@ -79,16 +79,14 @@ class RealmOperateHelper() {
}
suspend fun queryLink(
linkPid: String,
): RenderEntity? {
suspend fun queryLink(linkPid: String): RenderEntity? {
var link: RenderEntity? = null
withContext(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val realmR = realm.where(RenderEntity::class.java)
.equalTo("table", "OMDB_RD_LINK")
.and()
.rawPredicate("properties['${LinkTable.linkPid}']=$linkPid")
.equalTo("properties['${LinkTable.linkPid}']", linkPid)
.findFirst()
if (realmR != null) {
link = realm.copyFromRealm(realmR)

View File

@ -6,6 +6,7 @@ import androidx.room.Room
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
import com.navinfo.omqs.Constant
import com.navinfo.omqs.OMQSApplication
import com.navinfo.omqs.db.RoomAppDatabase
@ -90,7 +91,7 @@ class GlobalModule {
@Provides
@Singleton
fun provideGson(): Gson = GsonBuilder()
// 解决解析Json时将int类型自动转换为Double的问题
// 解决解析Json时将int类型自动转换为Double的问题
.registerTypeAdapter(object : TypeToken<Map<String, Any?>>() {}.getType(), IntTypeAdapter())
.registerTypeAdapter(object : TypeToken<Map<String, Any>>() {}.getType(), IntTypeAdapter())
.registerTypeAdapter(object : TypeToken<Map<Any, Any>>() {}.getType(), IntTypeAdapter())
@ -137,6 +138,15 @@ class GlobalModule {
.build();
}
@Singleton
@Provides
fun provideTraceDatabase(context: Application): TraceDataBase {
return TraceDataBase.getDatabase(
context,
Constant.USER_DATA_PATH + "/trace.sqlite"
)
}
// /**
// * realm 注册
// */

View File

@ -1,10 +1,13 @@
package com.navinfo.omqs.ui.activity.map
import android.os.Build
import android.os.Bundle
import androidx.activity.viewModels
import androidx.annotation.RequiresApi
import androidx.core.view.WindowCompat
import androidx.databinding.DataBindingUtil
import androidx.navigation.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.map.handler.NiLocationListener
@ -32,6 +35,7 @@ class MainActivity : BaseActivity() {
@Inject
lateinit var offlineMapDownloadManager: OfflineMapDownloadManager
private val signAdapter by lazy { SignAdapter() }
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
@ -43,7 +47,7 @@ class MainActivity : BaseActivity() {
binding.mainActivityMap,
null,
Constant.MAP_PATH,
Constant.USER_DATA_PATH+"/trace.sqlite"
Constant.USER_DATA_PATH + "/trace.sqlite"
)
//关联生命周期
binding.lifecycleOwner = this
@ -56,7 +60,11 @@ class MainActivity : BaseActivity() {
//处理页面跳转
viewModel.navigation(this, it)
}
binding.mainActivitySignRecyclerview.layoutManager = LinearLayoutManager(this)
binding.mainActivitySignRecyclerview.adapter = signAdapter
viewModel.liveDataSignList.observe(this) {
signAdapter.refreshData(it)
}
}
override fun onStart() {
@ -64,15 +72,10 @@ class MainActivity : BaseActivity() {
//开启定位
mapController.locationLayerHandler.startLocation()
//启动轨迹存储
mapController.locationLayerHandler.setNiLocationListener(NiLocationListener {
//ToastUtils.showLong("定位${it.longitude}")
binding!!.viewModel!!.addSaveTrace(it)
binding!!.viewModel!!.startSaveTraceThread(this)
})
//显示轨迹图层
// mapController.layerManagerHandler.showNiLocationLayer(Constant.DATA_PATH+ SystemConstant.USER_ID+"/trace.sqlite")
mapController.layerManagerHandler.showNiLocationLayer()
// viewModel.startSaveTraceThread(this)
}
override fun onPause() {
@ -103,7 +106,7 @@ class MainActivity : BaseActivity() {
*/
fun openCamera() {
//显示轨迹图层
binding!!.viewModel!!.onClickCameraButton(this)
viewModel.onClickCameraButton(this)
}
/**

View File

@ -2,23 +2,33 @@ package com.navinfo.omqs.ui.activity.map
import android.content.Context
import android.content.DialogInterface
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.data.entity.RenderEntity
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.map.handler.NiLocationListener
import com.navinfo.collect.library.map.handler.OnQsRecordItemClickListener
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.collect.library.utils.GeometryToolsKt
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.ui.dialog.CommonDialog
import com.navinfo.omqs.ui.manager.TakePhotoManager
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ActivityContext
import dagger.hilt.android.qualifiers.ApplicationContext
import io.realm.RealmSet
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.oscim.core.GeoPoint
import org.videolan.libvlc.LibVlcUtil
import javax.inject.Inject
@ -26,15 +36,25 @@ import javax.inject.Inject
/**
* 创建Activity全局viewmode
*/
@HiltViewModel
class MainViewModel @Inject constructor(
private val mapController: NIMapController,
private val traceDataBase: TraceDataBase,
private val realmOperateHelper: RealmOperateHelper
) : ViewModel() {
val liveDataQsRecordIdList = MutableLiveData<List<String>>()
private var mCameraDialog: CommonDialog? = null
private var niLocationList: MutableList<NiLocation> = ArrayList<NiLocation>()
//地图点击捕捉到的质检数据ID列表
val liveDataQsRecordIdList = MutableLiveData<List<String>>()
//看板数据
val liveDataSignList = MutableLiveData<List<SignBean>>()
// private var niLocationList: MutableList<NiLocation> = ArrayList<NiLocation>()
var testPoint = GeoPoint(0, 0)
init {
mapController.markerHandle.setOnQsRecordItemClickListener(object :
@ -43,6 +63,93 @@ class MainViewModel @Inject constructor(
liveDataQsRecordIdList.value = list
}
})
initLocation()
viewModelScope.launch {
mapController.onMapClickFlow.collect {
testPoint = it
}
}
}
private fun initLocation() {
// mapController.locationLayerHandler.setNiLocationListener(NiLocationListener {
// addSaveTrace(it)
//
// })
//用于定位点存储到数据库
viewModelScope.launch(Dispatchers.Default) {
mapController.locationLayerHandler.niLocationFlow.collect { location ->
location.longitude = testPoint.longitude
location.latitude = testPoint.latitude
val geometry = GeometryTools.createGeometry(
GeoPoint(
location.latitude,
location.longitude
)
)
val tileX = RealmSet<Int>()
GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
val tileY = RealmSet<Int>()
GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
//遍历存储tile对应的x与y的值
tileX.forEach { x ->
tileY.forEach { y ->
location.tilex = x
location.tiley = y
}
}
Log.e("jingo", "定位点插入 ${Thread.currentThread().name}")
traceDataBase.niLocationDao.insert(location)
}
}
//用于定位点捕捉道路
viewModelScope.launch(Dispatchers.Default) {
mapController.locationLayerHandler.niLocationFlow.collect { location ->
Log.e("jingo", "定位点绑定道路 ${Thread.currentThread().name}")
location.longitude = testPoint.longitude
location.latitude = testPoint.latitude
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val linkList = realmOperateHelper.queryLink(
point = GeometryTools.createPoint(
location.longitude,
location.latitude
),
)
//看板数据
val signList = mutableListOf<SignBean>()
if (linkList.isNotEmpty()) {
val link = linkList[0]
val linkId = link.properties[RenderEntity.Companion.LinkTable.linkPid]
mapController.lineHandler.showLine(link.geometry)
linkId?.let {
var elementList = realmOperateHelper.queryLinkByLinkPid(it)
for (element in elementList) {
val distance = GeometryTools.distanceToDouble(
GeoPoint(
location.latitude, location.longitude,
),
GeometryTools.createGeoPoint(element.geometry)
)
signList.add(
SignBean(
iconId = R.drawable.icon_speed_limit,
iconText = element.name,
distance = distance.toInt(),
)
)
}
liveDataSignList.postValue(signList)
Log.e("jingo", "自动捕捉数据 共${elementList.size}")
}
}
}
}
}
//显示轨迹图层
mapController.layerManagerHandler.showNiLocationLayer()
}
/**
@ -54,6 +161,9 @@ class MainViewModel @Inject constructor(
override fun onCleared() {
super.onCleared()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mapController.lineHandler.removeLine()
}
}
//点击相机按钮
@ -96,49 +206,61 @@ class MainViewModel @Inject constructor(
})
}
fun startSaveTraceThread(context: Context) {
Thread(Runnable {
try {
while (true) {
if (niLocationList != null && niLocationList.size > 0) {
// fun startSaveTraceThread(context: Context) {
// Thread(Runnable {
// try {
// while (true) {
//
// if (niLocationList != null && niLocationList.size > 0) {
//
// var niLocation = niLocationList[0]
// val geometry = GeometryTools.createGeometry(
// GeoPoint(
// niLocation.latitude,
// niLocation.longitude
// )
// )
// val tileX = RealmSet<Int>()
// GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
// val tileY = RealmSet<Int>()
// GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
//
// //遍历存储tile对应的x与y的值
// tileX.forEach { x ->
// tileY.forEach { y ->
// niLocation.tilex = x
// niLocation.tiley = y
// }
// }
//
// TraceDataBase.getDatabase(
// context,
// Constant.USER_DATA_PATH + "/trace.sqlite"
// ).niLocationDao.insert(niLocation)
// niLocationList.remove(niLocation)
//
// Log.e("qj", "saveTrace==${niLocationList.size}")
// }
// Thread.sleep(30)
// }
// } catch (e: InterruptedException) {
// e.printStackTrace()
// Log.e("qj", "异常==${e.message}")
// }
// }).start()
// }
var niLocation = niLocationList[0]
val geometry = GeometryTools.createGeometry(GeoPoint(niLocation.latitude,niLocation.longitude))
val tileX = RealmSet<Int>()
GeometryToolsKt.getTileXByGeometry(geometry.toString(), tileX)
val tileY = RealmSet<Int>()
GeometryToolsKt.getTileYByGeometry(geometry.toString(), tileY)
//遍历存储tile对应的x与y的值
tileX.forEach { x ->
tileY.forEach { y ->
niLocation.tilex = x
niLocation.tiley = y
}
}
TraceDataBase.getDatabase(context, Constant.USER_DATA_PATH + "/trace.sqlite").niLocationDao.insert(niLocation)
niLocationList.remove(niLocation)
Log.e("qj", "saveTrace==${niLocationList.size}")
}
Thread.sleep(30)
}
} catch (e: InterruptedException) {
e.printStackTrace()
Log.e("qj", "异常==${e.message}")
}
}).start()
}
//增加轨迹存储
fun addSaveTrace(niLocation: NiLocation) {
if (niLocation != null && niLocationList != null) {
niLocationList.add(niLocation)
}
}
// //增加轨迹存储
// fun addSaveTrace(niLocation: NiLocation) {
// if (niLocation != null && niLocationList != null) {
// niLocationList.add(niLocation)
// }
// }
/**
* 处理页面调转
*/
fun navigation(activity: MainActivity, list: List<String>) {
//获取右侧fragment容器
val naviController = activity.findNavController(R.id.main_activity_right_fragment)

View File

@ -0,0 +1,28 @@
package com.navinfo.omqs.ui.activity.map
import android.view.LayoutInflater
import android.view.ViewGroup
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.AdapterSignBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
class SignAdapter : BaseRecyclerViewAdapter<SignBean>() {
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_sign
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterSignBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return BaseViewHolder(viewBinding)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as AdapterSignBinding
val item = data[position]
bd.signMainIcon.background = holder.viewBinding.root.context.getDrawable(item.iconId)
bd.signMainIcon.text = item.iconText
}
}

View File

@ -0,0 +1,8 @@
package com.navinfo.omqs.ui.activity.map
data class SignBean(
//图标ID
val iconId: Int,
val distance: Int = 0,
val iconText: String = ""
)

View File

@ -8,7 +8,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.data.entity.RenderEntity.Companion.LinkTable
import com.navinfo.collect.library.map.GeoPoint
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.db.RealmOperateHelper
@ -18,10 +17,10 @@ import io.realm.Realm
import io.realm.kotlin.where
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.oscim.core.GeoPoint
import java.util.*
import javax.inject.Inject
@RequiresApi(Build.VERSION_CODES.N)
@HiltViewModel
class EvaluationResultViewModel @Inject constructor(
private val roomAppDatabase: RoomAppDatabase,
@ -59,24 +58,24 @@ class EvaluationResultViewModel @Inject constructor(
init {
liveDataQsRecordBean.value = QsRecordBean(id = UUID.randomUUID().toString())
Log.e("jingo", "EvaluationResultViewModel 创建了 ${hashCode()}")
mapController.markerHandle.run {
setOnMapClickListener {
liveDataQsRecordBean.value!!.geometry = it.toGeometry()
addMarker(it, markerTitle)
viewModelScope.launch {
mapController.onMapClickFlow.collect {
liveDataQsRecordBean.value!!.geometry = GeometryTools.createGeometry(it).toText()
mapController.markerHandle.addMarker(it, markerTitle)
viewModelScope.launch {
captureLink(it.longitude, it.latitude)
}
}
}
}
override fun onCleared() {
super.onCleared()
Log.e("jingo", "EvaluationResultViewModel 销毁了 ${hashCode()}")
mapController.markerHandle.removeMarker(markerTitle)
mapController.markerHandle.removeOnMapClickListener()
mapController.lineHandler.removeLine()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mapController.lineHandler.removeLine()
}
}
@ -90,7 +89,7 @@ class EvaluationResultViewModel @Inject constructor(
}
val geoPoint = mapController.locationLayerHandler.getCurrentGeoPoint()
geoPoint?.let {
liveDataQsRecordBean.value!!.geometry = it.toGeometry()
liveDataQsRecordBean.value!!.geometry = GeometryTools.createGeometry(it).toText()
mapController.markerHandle.addMarker(geoPoint, markerTitle)
viewModelScope.launch {
captureLink(geoPoint.longitude, geoPoint.latitude)
@ -102,20 +101,23 @@ class EvaluationResultViewModel @Inject constructor(
* 捕捉到路
*/
private suspend fun captureLink(longitude: Double, latitude: Double) {
val linkList = realmOperateHelper.queryLink(
point = GeometryTools.createPoint(
longitude,
latitude
),
)
liveDataQsRecordBean.value?.let {
if (linkList.isNotEmpty()) {
it.linkId =
linkList[0].properties[LinkTable.linkPid] ?: ""
mapController.lineHandler.showLine(linkList[0].geometry)
} else {
it.linkId = ""
mapController.lineHandler.removeLine()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val linkList = realmOperateHelper.queryLink(
point = GeometryTools.createPoint(
longitude,
latitude
),
)
liveDataQsRecordBean.value?.let {
if (linkList.isNotEmpty()) {
it.linkId =
linkList[0].properties[LinkTable.linkPid] ?: ""
mapController.lineHandler.showLine(linkList[0].geometry)
} else {
it.linkId = ""
mapController.lineHandler.removeLine()
}
}
}
}
@ -276,23 +278,26 @@ class EvaluationResultViewModel @Inject constructor(
*/
fun initData(id: String) {
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val objects = realm.where<QsRecordBean>().equalTo("id", id).findFirst()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
val objects = realm.where<QsRecordBean>().equalTo("id", id).findFirst()
if (objects != null) {
oldBean = realm.copyFromRealm(objects)
oldBean?.let {
liveDataQsRecordBean.postValue(it.copy())
val p = GeometryTools.createGeoPoint(it.geometry)
mapController.markerHandle.addMarker(
GeoPoint(p.longitude, p.latitude),
markerTitle
)
if (it.linkId.isNotEmpty()) {
val link = realmOperateHelper.queryLink(it.linkId)
link?.let { l ->
mapController.lineHandler.showLine(l.geometry)
if (objects != null) {
oldBean = realm.copyFromRealm(objects)
oldBean?.let {
liveDataQsRecordBean.postValue(it.copy())
val p = GeometryTools.createGeoPoint(it.geometry)
mapController.markerHandle.addMarker(
GeoPoint(p.latitude, p.longitude),
markerTitle
)
if (it.linkId.isNotEmpty()) {
val link = realmOperateHelper.queryLink(it.linkId)
link?.let { l ->
mapController.lineHandler.showLine(l.geometry)
}
}
}
}

View File

@ -1,7 +1,9 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.os.Build
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.TextItemSelectBinding
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
@ -21,6 +23,7 @@ class MiddleAdapter(private var itemListener: ((Int, String) -> Unit?)? = null)
return BaseViewHolder(viewBinding)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val bd = holder.viewBinding as TextItemSelectBinding
val title = data[position]

View File

@ -0,0 +1,12 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval"
android:useLevel="false">
<stroke
android:width="1.33dp"
android:color="#DB4646" />
<size
android:width="24dp"
android:height="24dp" />
<solid android:color="@color/white" />
</shape>

View File

@ -35,6 +35,7 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/main_activity_person_center"
android:layout_width="48dp"
@ -46,6 +47,14 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_activity_sign_recyclerview"
android:layout_width="150dp"
android:layout_height="350dp"
android:layout_marginTop="10dp"
app:layout_constraintLeft_toLeftOf="@id/main_activity_person_center"
app:layout_constraintTop_toBottomOf="@id/main_activity_person_center" />
<ImageButton
android:id="@+id/main_activity_location"
android:layout_width="48dp"
@ -68,6 +77,16 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<ImageButton
android:id="@+id/main_activity_line"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="10dp"
android:onClick="@{()->mainActivity.voiceOnclick()}"
android:src="@drawable/baseline_keyboard_voice_24"
app:layout_constraintBottom_toTopOf="@id/main_activity_voice"
app:layout_constraintRight_toRightOf="@id/main_activity_voice" />
<fragment
android:id="@+id/main_activity_middle_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
@ -107,11 +126,11 @@
android:id="@+id/main_activity_camera2"
android:layout_width="48dp"
android:layout_height="48dp"
android:visibility="gone"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:onClick="@{()->mainActivity.openCamera()}"
android:src="@drawable/baseline_person_24"
android:visibility="gone"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@ -0,0 +1,20 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/bg_sign"
tools:context="com.navinfo.omqs.ui.activity.map.SignAdapter">
<TextView
android:id="@+id/sign_main_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="19dp"
android:layout_marginTop="4dp"
android:background="@drawable/icon_speed_limit"
android:gravity="center"
android:text="80"
android:textColor="#2F2F2F"
android:textSize="14.67sp" />
</RelativeLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,14 +1,14 @@
package com.navinfo.collect.library.map
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class GeoPoint(
var latitude: Double = 0.0,
var longitude: Double = 0.0
) : Parcelable {
fun toGeometry(): String {
return "POINT($longitude $latitude)"
}
}
//package com.navinfo.collect.library.map
//
//import android.os.Parcelable
//import kotlinx.parcelize.Parcelize
//
//@Parcelize
//data class GeoPoint(
// var latitude: Double = 0.0,
// var longitude: Double = 0.0
//) : Parcelable {
// fun toGeometry(): String {
// return "POINT($longitude $latitude)"
// }
//}

View File

@ -1,14 +1,20 @@
package com.navinfo.collect.library.map
import android.content.Context
import android.util.Log
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.data.handler.DataNiLocationHandler
import com.navinfo.collect.library.map.NIMapView.OnMapClickListener
import com.navinfo.collect.library.map.handler.*
import com.navinfo.collect.library.map.maphandler.MeasureLayerHandler
import com.navinfo.collect.library.map.handler.MeasureLayerHandler
import com.navinfo.collect.library.map.handler.ViewportHandler
import com.navinfo.collect.library.system.Constant
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
import org.oscim.core.GeoPoint
/**
* 地图控制器
@ -25,19 +31,35 @@ class NIMapController {
lateinit var viewportHandler: ViewportHandler
lateinit var measureLayerHandler: MeasureLayerHandler
fun init(context: AppCompatActivity, mapView: NIMapView, options: NIMapOptions? = null, mapPath: String, tracePath: String) {
val onMapClickFlow = MutableSharedFlow<GeoPoint>()
fun init(
context: AppCompatActivity,
mapView: NIMapView,
options: NIMapOptions? = null,
mapPath: String,
tracePath: String
) {
Constant.MAP_PATH = mapPath
layerManagerHandler = LayerManagerHandler(context, mapView, tracePath)
locationLayerHandler = LocationLayerHandler(context, mapView)
animationHandler = AnimationHandler(context, mapView)
markerHandle = MarkHandler(context, mapView)
lineHandler = LineHandler(context, mapView)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
lineHandler = LineHandler(context, mapView)
}
polygonHandler = PolygonHandler(context, mapView)
viewportHandler = ViewportHandler(context, mapView)
measureLayerHandler = MeasureLayerHandler(context, mapView)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
measureLayerHandler = MeasureLayerHandler(context, mapView)
}
mMapView = mapView
mMapView.setOnMapClickListener {
context.lifecycleScope.launch {
onMapClickFlow.emit(it)
}
}
mapView.setOptions(options)
mMapView.vtmMap.viewport().maxZoomLevel = Constant.MAX_ZOOM // 设置地图的最大级别
}

View File

@ -1,5 +1,6 @@
package com.navinfo.collect.library.map
import com.navinfo.collect.library.system.Constant
import org.json.JSONObject
@ -8,6 +9,7 @@ data class NIMapOptions(
val showZoomControl: Boolean = true, //是否显示zoom按钮
val zoomLevel: Double = 13.0, /// 地图比例尺初始级别
val coordinate: NICoordinate = NICoordinate(39.907375, 116.391349),
val maxZoom: Int = Constant.MAX_ZOOM
) {
companion object {
fun fromJson(json: String): NIMapOptions {

View File

@ -1,6 +1,7 @@
package com.navinfo.collect.library.map;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@ -121,7 +122,7 @@ public final class NIMapView extends RelativeLayout {
*
* @param point
*/
void onMapClick(com.navinfo.collect.library.map.GeoPoint point);
void onMapClick(GeoPoint point);
/**
* 地图内 Poi 单击事件回调函数
@ -358,6 +359,7 @@ public final class NIMapView extends RelativeLayout {
}
MapPosition mapPosition = getVtmMap().getMapPosition();
mapPosition.setZoom(options.getZoomLevel());
getVtmMap().viewport().setMaxZoomLevel(options.getMaxZoom());
mapPosition.setPosition(options.getCoordinate().getLatitude(), options.getCoordinate().getLongitude());
getVtmMap().animator().animateTo(100, mapPosition);
}
@ -819,7 +821,9 @@ public final class NIMapView extends RelativeLayout {
LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
if (layoutParams.getRules() != null) {
for (int i = 0; i < layoutParams.getRules().length; i++) {
layoutParams.removeRule(i);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
layoutParams.removeRule(i);
}
}
}
switch (position) {
@ -926,7 +930,7 @@ public final class NIMapView extends RelativeLayout {
GeoPoint geoPoint = mMap.viewport().fromScreenPoint(e.getX(), e.getY());
if (g instanceof Gesture.Tap) { // 单击事件
if (mapClickListener != null) {
mapClickListener.onMapClick(new com.navinfo.collect.library.map.GeoPoint(geoPoint.getLatitude(), geoPoint.getLongitude()));
mapClickListener.onMapClick(geoPoint);
}
} else if (g instanceof Gesture.DoubleTap) { // 双击
if (mapDoubleClickListener != null) {

View File

@ -20,11 +20,11 @@ abstract class BaseHandler(context: AppCompatActivity, mapView: NIMapView) {
mMapView.vtmMap.layers().remove(layer)
}
fun setOnMapClickListener(listener: NIMapView.OnMapClickListener) {
mMapView.setOnMapClickListener(listener)
}
fun removeOnMapClickListener() {
mMapView.setOnMapClickListener(null)
}
// fun setOnMapClickListener(listener: NIMapView.OnMapClickListener) {
// mMapView.setOnMapClickListener(listener)
// }
//
// fun removeOnMapClickListener() {
// mMapView.setOnMapClickListener(null)
// }
}

View File

@ -24,7 +24,7 @@ import java.io.File
class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView,tracePath: String) : BaseHandler(context, mapView) {
private var baseGroupLayer // 用于盛放所有基础底图的图层组,便于统一管理
: GroupLayer? = null
protected val mTracePath:String = tracePath
private val mTracePath:String = tracePath
/**
* 轨迹渲染图层

View File

@ -137,13 +137,12 @@ class LineHandler(context: AppCompatActivity, mapView: NIMapView) : BaseHandler(
fun showLine(geometry: String) {
try {
mDefaultPathLayer.clearPath()
mDefaultPathLayer.setPoints(GeometryTools.getGeoPoints(geometry))
mDefaultPathLayer.isEnabled = true
} catch (e: Exception) {
Toast.makeText(mContext, "高亮路线失败 ${e.message}", Toast.LENGTH_SHORT).show()
}
val g = GeometryTools.getGeoPoints(geometry)
mDefaultPathLayer.setPoints(g)
mDefaultPathLayer.isEnabled = true
}
fun removeLine() {

View File

@ -1,27 +1,34 @@
package com.navinfo.collect.library.map.handler
import android.content.Context
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.baidu.location.BDAbstractLocationListener
import com.baidu.location.BDLocation
import com.baidu.location.LocationClient
import com.baidu.location.LocationClientOption
import com.baidu.location.LocationClientOption.LocationMode
import com.navinfo.collect.library.data.entity.NiLocation
import com.navinfo.collect.library.map.GeoPoint
import com.navinfo.collect.library.map.NIMapView
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import org.oscim.core.GeoPoint
import org.oscim.layers.LocationLayer
class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : BaseHandler(context, mapView) {
class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
BaseHandler(context, mapView) {
private var mCurrentLocation: BDLocation? = null
private var bFirst = true
private val mLocationLayer: LocationLayer = LocationLayer(mMapView.vtmMap)
private lateinit var locationClient: LocationClient
private lateinit var niLocationListener: NiLocationListener
// private var niLocationListener: NiLocationListener by lazy{
//
// }
val niLocationFlow = MutableSharedFlow<NiLocation>(5)
init {
///添加定位图层到地图,[NIMapView.LAYER_GROUPS.NAVIGATION] 是最上层layer组
@ -47,20 +54,29 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
//更多结果信息获取说明请参照类参考中BDLocation类中的说明
//获取纬度信息
val latitude = it.latitude
// val latitude = it.latitude
//获取经度信息
val longitude = it.longitude
// val longitude = it.longitude
//获取定位精度默认值为0.0f
val radius = it.radius
// val radius = it.radius
//获取经纬度坐标类型以LocationClientOption中设置过的坐标类型为准
val coorType = it.coorType
// val coorType = it.coorType
//获取定位类型、定位错误返回码具体信息可参照类参考中BDLocation类中的说明
val errorCode = it.locType
mCurrentLocation = it
mLocationLayer.setPosition(it.latitude, it.longitude, it.radius)
Log.e("qj","location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}")
if(niLocationListener!=null){
getCurrentNiLocation()?.let { it1 -> niLocationListener.call(it1) }
// Log.e(
// "qj",
// "location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}"
// )
// if (niLocationListener != null) {
getCurrentNiLocation()?.let { it1 ->
mContext.lifecycleScope.launch {
niLocationFlow.emit(it1)
}
// }// niLocationListener.call(it1) }
}
//第一次定位成功显示当前位置
if (this.bFirst) {
@ -107,7 +123,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
locationClient.locOption = locationOption
} catch (e: Throwable) {
Toast.makeText(mContext, "定位初始化失败 $e", Toast.LENGTH_SHORT)
Log.e("qj","定位初始化失败$e")
Log.e("qj", "定位初始化失败$e")
}
}
@ -160,8 +176,8 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
//获取当前定位对象
fun getCurrentNiLocation(): NiLocation? {
if(mCurrentLocation!=null){
val niLocation:NiLocation = NiLocation()
if (mCurrentLocation != null) {
val niLocation: NiLocation = NiLocation()
niLocation.longitude = mCurrentLocation!!.longitude
niLocation.latitude = mCurrentLocation!!.latitude
niLocation.direction = mCurrentLocation!!.direction.toDouble()
@ -186,10 +202,10 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : Bas
return null
}
//设置定位回调
fun setNiLocationListener(listener: NiLocationListener){
niLocationListener = listener
}
// //设置定位回调
// fun setNiLocationListener(listener: NiLocationListener) {
// niLocationListener = listener
// }
}
/**
@ -205,7 +221,7 @@ private class MyLocationListener(callback: (BDLocation) -> Unit) : BDAbstractLoc
/**
* 实现定位回调
*/
public class NiLocationListener(callback: (NiLocation) -> Unit){
class NiLocationListener(callback: (NiLocation) -> Unit) {
val call = callback;
fun onReceiveLocation(location: NiLocation) {
call(location)

View File

@ -10,7 +10,6 @@ import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.lifecycleScope
import com.navinfo.collect.library.R
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.map.GeoPoint
import com.navinfo.collect.library.map.NIMapView
import com.navinfo.collect.library.map.cluster.ClusterMarkerItem
import com.navinfo.collect.library.map.cluster.ClusterMarkerRenderer
@ -27,6 +26,7 @@ import org.oscim.android.canvas.AndroidBitmap
import org.oscim.backend.CanvasAdapter
import org.oscim.backend.canvas.Bitmap
import org.oscim.backend.canvas.Paint
import org.oscim.core.GeoPoint
import org.oscim.layers.marker.*
import org.oscim.layers.marker.ItemizedLayer.OnItemGestureListener
import org.oscim.map.Map
@ -90,9 +90,10 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
}
)
addLayer(mDefaultMarkerLayer, NIMapView.LAYER_GROUPS.OPERATE);
//初始化之间数据图层
initQsRecordDataLayer()
addLayer(mDefaultMarkerLayer, NIMapView.LAYER_GROUPS.OPERATE);
// 设置矢量图层均在12级以上才显示
mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition ->
if (e == Map.SCALE_EVENT) {
@ -127,13 +128,13 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) :
val marker = MarkerItem(
tempTitle,
description,
org.oscim.core.GeoPoint(geoPoint.latitude, geoPoint.longitude)
geoPoint
)
mDefaultMarkerLayer.addItem(marker);
mMapView.vtmMap.updateMap(true)
} else {
marker.description = description
marker.geoPoint = org.oscim.core.GeoPoint(geoPoint.latitude, geoPoint.longitude)
marker.geoPoint = geoPoint
mDefaultMarkerLayer.removeItem(marker)
mDefaultMarkerLayer.addItem(marker)
mMapView.vtmMap.updateMap(true)

View File

@ -1,19 +1,17 @@
package com.navinfo.collect.library.map.maphandler
package com.navinfo.collect.library.map.handler
import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.os.Build
import android.text.TextPaint
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.navinfo.collect.library.R
import com.navinfo.collect.library.map.NIMapView
import com.navinfo.collect.library.map.handler.BaseHandler
import com.navinfo.collect.library.map.layers.NIPolygonLayer
import com.navinfo.collect.library.utils.DistanceUtil
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.collect.library.utils.StringUtil.Companion.createUUID
import org.oscim.android.canvas.AndroidBitmap
import org.oscim.backend.CanvasAdapter
import org.oscim.backend.canvas.Bitmap
@ -30,6 +28,7 @@ import org.oscim.layers.vector.geometries.Style
import org.oscim.map.Map
import java.math.BigDecimal
@RequiresApi(Build.VERSION_CODES.M)
open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
BaseHandler(context, mapView), Map.UpdateListener {

View File

@ -418,7 +418,7 @@ public class GeometryTools {
Geometry startGeo = createGeometry(startGeoPoint);
Geometry endGeo = createGeometry(endGeoPoint);
double d = startGeo.distance(endGeo);
return d * 100000;
return convertDistanceToDegree(d,startGeoPoint.getLatitude());
}
return 0;