重构测量工具代码,修改代码逻辑和展现形式。
增加面积,角度测量 修改地图渲染面会崩溃的问题
This commit is contained in:
parent
8578ea0afd
commit
4baa137ad6
@ -9,6 +9,7 @@ import android.util.Log
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.viewModels
|
||||
@ -20,7 +21,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.map.NIMapOptions
|
||||
import com.navinfo.collect.library.map.handler.MeasureLayerHandler
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.bean.ImportConfig
|
||||
@ -397,9 +398,124 @@ class MainActivity : BaseActivity() {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.add(R.id.console_fragment_layout, ConsoleFragment()).commit()
|
||||
}
|
||||
|
||||
initMeasuringTool()
|
||||
}
|
||||
|
||||
//根据输入的经纬度跳转坐标
|
||||
/**
|
||||
*初始化测量工具栏的点击事件
|
||||
*/
|
||||
|
||||
private fun initMeasuringTool() {
|
||||
val root = binding.mainActivityMeasuringTool.root
|
||||
root.findViewById<View>(R.id.measuring_tool_select_point)
|
||||
.setOnClickListener(measuringToolClickListener)
|
||||
root.findViewById<View>(R.id.measuring_tool_close)
|
||||
.setOnClickListener(measuringToolClickListener)
|
||||
root.findViewById<View>(R.id.measuring_tool_backspace)
|
||||
.setOnClickListener(measuringToolClickListener)
|
||||
root.findViewById<View>(R.id.measuring_tool_reset)
|
||||
.setOnClickListener(measuringToolClickListener)
|
||||
root.findViewById<View>(R.id.measuring_tool_distance)
|
||||
.setOnClickListener(measuringToolClickListener)
|
||||
root.findViewById<View>(R.id.measuring_tool_area)
|
||||
.setOnClickListener(measuringToolClickListener)
|
||||
root.findViewById<View>(R.id.measuring_tool_angle)
|
||||
.setOnClickListener(measuringToolClickListener)
|
||||
}
|
||||
|
||||
/**
|
||||
* 测量工具点击事件
|
||||
*/
|
||||
private val measuringToolClickListener = View.OnClickListener {
|
||||
when (it.id) {
|
||||
//选点
|
||||
R.id.measuring_tool_select_point -> {
|
||||
viewModel.addPointForMeasuringTool()
|
||||
}
|
||||
//关闭
|
||||
R.id.measuring_tool_close -> {
|
||||
measuringToolOff()
|
||||
}
|
||||
//上一步
|
||||
R.id.measuring_tool_backspace -> {
|
||||
viewModel.backPointForMeasuringTool()
|
||||
}
|
||||
//重绘
|
||||
R.id.measuring_tool_reset -> {
|
||||
viewModel.resetMeasuringTool()
|
||||
}
|
||||
//测距
|
||||
R.id.measuring_tool_distance -> {
|
||||
it.isSelected = true
|
||||
viewModel.setMeasuringToolType(MeasureLayerHandler.MEASURE_TYPE.DISTANCE)
|
||||
val root = binding.mainActivityMeasuringTool.root
|
||||
root.findViewById<View>(R.id.measuring_tool_area).isSelected = false
|
||||
root.findViewById<View>(R.id.measuring_tool_angle).isSelected = false
|
||||
}
|
||||
//测面积
|
||||
R.id.measuring_tool_area -> {
|
||||
it.isSelected = true
|
||||
viewModel.setMeasuringToolType(MeasureLayerHandler.MEASURE_TYPE.AREA)
|
||||
val root = binding.mainActivityMeasuringTool.root
|
||||
root.findViewById<View>(R.id.measuring_tool_distance).isSelected = false
|
||||
root.findViewById<View>(R.id.measuring_tool_angle).isSelected = false
|
||||
}
|
||||
//测角度
|
||||
R.id.measuring_tool_angle -> {
|
||||
it.isSelected = true
|
||||
viewModel.setMeasuringToolType(MeasureLayerHandler.MEASURE_TYPE.ANGLE)
|
||||
val root = binding.mainActivityMeasuringTool.root
|
||||
root.findViewById<View>(R.id.measuring_tool_distance).isSelected = false
|
||||
root.findViewById<View>(R.id.measuring_tool_area).isSelected = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始测量
|
||||
*/
|
||||
private fun measuringToolOn() {
|
||||
val root = binding.mainActivityMeasuringTool.root
|
||||
val valueView = root.findViewById<TextView>(R.id.measuring_tool_value)
|
||||
val unitView = root.findViewById<TextView>(R.id.measuring_tool_value_unit)
|
||||
val centerTextView = binding.mainActivityHomeCenterText
|
||||
//监听测距值
|
||||
mapController.measureLayerHandler.measureValueLiveData.observe(this) {
|
||||
valueView.text = it.valueString
|
||||
unitView.text = it.unit
|
||||
}
|
||||
mapController.measureLayerHandler.tempMeasureValueLiveData.observe(this)
|
||||
{
|
||||
centerTextView.text = "${it.valueString}${it.unit}"
|
||||
}
|
||||
viewModel.setMeasuringToolEnable(true)
|
||||
binding.mainActivityHomeCenter.visibility = View.VISIBLE
|
||||
binding.mainActivityHomeCenterText.visibility = View.VISIBLE
|
||||
viewModel.setMeasuringToolType(MeasureLayerHandler.MEASURE_TYPE.DISTANCE)
|
||||
root.visibility = View.VISIBLE
|
||||
root.findViewById<View>(R.id.measuring_tool_distance).isSelected = true
|
||||
root.findViewById<View>(R.id.measuring_tool_area).isSelected = false
|
||||
root.findViewById<View>(R.id.measuring_tool_angle).isSelected = false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 结束测量
|
||||
*/
|
||||
private fun measuringToolOff() {
|
||||
//监听测距值
|
||||
mapController.measureLayerHandler.measureValueLiveData.removeObservers(this)
|
||||
mapController.measureLayerHandler.tempMeasureValueLiveData.removeObservers(this)
|
||||
viewModel.setMeasuringToolEnable(false)
|
||||
binding.mainActivityHomeCenter.visibility = View.GONE
|
||||
binding.mainActivityHomeCenterText.visibility = View.GONE
|
||||
binding.mainActivityMeasuringTool.root.visibility = View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据输入的经纬度跳转坐标
|
||||
*/
|
||||
fun jumpPosition() {
|
||||
val view = this.layoutInflater.inflate(R.layout.dialog_view_edittext, null)
|
||||
val inputDialog = MaterialAlertDialogBuilder(
|
||||
@ -488,10 +604,10 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击计算
|
||||
* 点击测速
|
||||
*/
|
||||
fun onClickCalcDisance() {
|
||||
|
||||
fun onClickCalcDistance() {
|
||||
measuringToolOn()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -825,7 +941,7 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun showMainActivityBottomSheetGroup(){
|
||||
private fun showMainActivityBottomSheetGroup() {
|
||||
binding.mainActivityBottomSheetGroup.visibility = View.VISIBLE
|
||||
mapController.mMapView.setScaleBarLayer(GLViewport.Position.BOTTOM_CENTER, 128, 65)
|
||||
mapController.mMapView.vtmMap.animator().animateTo(
|
||||
@ -836,7 +952,7 @@ class MainActivity : BaseActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun hideMainActivityBottomSheetGroup(){
|
||||
private fun hideMainActivityBottomSheetGroup() {
|
||||
binding.mainActivityBottomSheetGroup.visibility = View.GONE
|
||||
mapController.mMapView.setScaleBarLayer(GLViewport.Position.BOTTOM_CENTER, 128, 5)
|
||||
mapController.mMapView.vtmMap.animator().animateTo(
|
||||
|
@ -22,16 +22,12 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.findNavController
|
||||
import com.blankj.utilcode.util.ToastUtils
|
||||
import com.blankj.utilcode.util.ViewUtils.runOnUiThread
|
||||
import com.navinfo.collect.library.data.dao.impl.TraceDataBase
|
||||
import com.navinfo.collect.library.data.entity.*
|
||||
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.ONNoteItemClickListener
|
||||
import com.navinfo.collect.library.map.handler.OnNiLocationItemListener
|
||||
import com.navinfo.collect.library.map.handler.OnQsRecordItemClickListener
|
||||
import com.navinfo.collect.library.map.handler.OnTaskLinkItemClickListener
|
||||
import com.navinfo.collect.library.map.handler.*
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.collect.library.utils.GeometryToolsKt
|
||||
import com.navinfo.omqs.Constant
|
||||
@ -59,10 +55,8 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.locationtech.jts.geom.Point
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.MapPosition
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
import org.oscim.map.Map
|
||||
import org.videolan.libvlc.LibVlcUtil
|
||||
import java.io.File
|
||||
@ -174,6 +168,17 @@ class MainViewModel @Inject constructor(
|
||||
*/
|
||||
private var bSelectPauseTrace = false
|
||||
|
||||
/**
|
||||
* 是不是开启测距
|
||||
*/
|
||||
private var bMeasuringTool = false
|
||||
|
||||
/**
|
||||
* 测量类型
|
||||
*/
|
||||
var measuringType: MeasureLayerHandler.MEASURE_TYPE =
|
||||
MeasureLayerHandler.MEASURE_TYPE.DISTANCE
|
||||
|
||||
var linkIdCache = ""
|
||||
|
||||
private var lastNiLocaion: NiLocation? = null
|
||||
@ -219,12 +224,16 @@ class MainViewModel @Inject constructor(
|
||||
object : OnGeoPointClickListener {
|
||||
override fun onMapClick(tag: String, point: GeoPoint) {
|
||||
if (tag == TAG) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
//线选择状态
|
||||
if (bSelectRoad) {
|
||||
captureLink(point)
|
||||
} else {
|
||||
captureItem(point)
|
||||
if (bMeasuringTool) {
|
||||
mapController.measureLayerHandler.addPoint(measuringType, point)
|
||||
} else {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
//线选择状态
|
||||
if (bSelectRoad) {
|
||||
captureLink(point)
|
||||
} else {
|
||||
captureItem(point)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1028,12 +1037,12 @@ class MainViewModel @Inject constructor(
|
||||
val nextNiLocation =
|
||||
mapController.markerHandle.getNILocation(currentIndexNiLocation + 1)
|
||||
if (nextNiLocation != null && niLocation != null) {
|
||||
var nilocationDisTime =
|
||||
var niLocationDisTime =
|
||||
nextNiLocation.timeStamp.toLong() - niLocation.timeStamp.toLong()
|
||||
disTime = if (nilocationDisTime < 1000) {
|
||||
disTime = if (niLocationDisTime < 1000) {
|
||||
1000
|
||||
} else {
|
||||
nilocationDisTime
|
||||
niLocationDisTime
|
||||
}
|
||||
showMarker(mapController.mMapView.context, nextNiLocation)
|
||||
currentIndexNiLocation += 1
|
||||
@ -1053,5 +1062,45 @@ class MainViewModel @Inject constructor(
|
||||
fun cancelTrace() {
|
||||
timer?.cancel()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 开启测量工具
|
||||
*/
|
||||
fun setMeasuringToolEnable(b: Boolean) {
|
||||
bMeasuringTool = b
|
||||
mapController.measureLayerHandler.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* 测量打点
|
||||
*/
|
||||
fun addPointForMeasuringTool() {
|
||||
mapController.measureLayerHandler.addPoint(measuringType)
|
||||
}
|
||||
|
||||
/**
|
||||
* 测距回退点
|
||||
*/
|
||||
fun backPointForMeasuringTool() {
|
||||
mapController.measureLayerHandler.backspacePoint()
|
||||
}
|
||||
|
||||
/**
|
||||
* 重绘
|
||||
*/
|
||||
fun resetMeasuringTool() {
|
||||
mapController.measureLayerHandler.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置测量类型 0:距离 2:面积 3:角度
|
||||
*/
|
||||
fun setMeasuringToolType(type: MeasureLayerHandler.MEASURE_TYPE) {
|
||||
if(measuringType != type) {
|
||||
measuringType = type
|
||||
mapController.measureLayerHandler.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.navinfo.omqs.ui.fragment.tasklink
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@ -38,7 +37,7 @@ class TaskLinkFragment : BaseFragment(), View.OnClickListener {
|
||||
|
||||
arguments?.let {
|
||||
val id = it.getString("TaskLinkId")
|
||||
if (id != null && id.isNotEmpty()){
|
||||
if (id != null && id.isNotEmpty()) {
|
||||
viewModel.initData(id)
|
||||
}
|
||||
}
|
||||
@ -97,11 +96,11 @@ class TaskLinkFragment : BaseFragment(), View.OnClickListener {
|
||||
/**
|
||||
* 线长度
|
||||
*/
|
||||
mapController.measureLayerHandler.lineLengthLiveData.observe(viewLifecycleOwner) {
|
||||
mapController.measureLayerHandler.measureValueLiveData.observe(viewLifecycleOwner) {
|
||||
binding.taskLinkLength.text = "${it}米"
|
||||
}
|
||||
mapController.measureLayerHandler.tempLineDistanceLiveData.observe(viewLifecycleOwner) {
|
||||
(activity as MainActivity).setHomeCenterText(it)
|
||||
mapController.measureLayerHandler.tempMeasureValueLiveData.observe(viewLifecycleOwner) {
|
||||
(activity as MainActivity).setHomeCenterText("${it.valueString}${it.unit}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +158,7 @@ class TaskLinkFragment : BaseFragment(), View.OnClickListener {
|
||||
binding.taskLinkClear -> {
|
||||
viewModel.clearLink()
|
||||
}
|
||||
binding.taskLinkBarDelete ->{
|
||||
binding.taskLinkBarDelete -> {
|
||||
viewModel.deleteData(requireContext())
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
package com.navinfo.omqs.ui.fragment.tasklink
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
@ -13,18 +10,15 @@ import com.navinfo.collect.library.data.entity.LinkInfoBean
|
||||
import com.navinfo.collect.library.data.entity.QsRecordBean
|
||||
import com.navinfo.collect.library.data.entity.TaskBean
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.map.handler.MeasureLayerHandler
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.omqs.Constant
|
||||
import com.navinfo.omqs.ui.dialog.FirstDialog
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import io.realm.Realm
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.bson.codecs.UuidCodec
|
||||
import org.bson.internal.UuidHelper
|
||||
import org.oscim.core.GeoPoint
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -136,7 +130,7 @@ class TaskLinkViewModel @Inject constructor(
|
||||
* 编辑点
|
||||
*/
|
||||
fun addPoint() {
|
||||
mapController.measureLayerHandler.drawLineOrPolygon(false)
|
||||
mapController.measureLayerHandler.addPoint(MeasureLayerHandler.MEASURE_TYPE.DISTANCE)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,7 +192,7 @@ class TaskLinkViewModel @Inject constructor(
|
||||
if (hadLinkDvoBean != null) {
|
||||
hadLinkDvoBean!!.taskId = liveDataTaskBean.value!!.id
|
||||
hadLinkDvoBean!!.length =
|
||||
mapController.measureLayerHandler.lineLengthLiveData.value!!
|
||||
mapController.measureLayerHandler.measureValueLiveData.value!!.value
|
||||
hadLinkDvoBean!!.geometry =
|
||||
GeometryTools.getLineString(mapController.measureLayerHandler.mPathLayer.points)
|
||||
hadLinkDvoBean!!.linkInfo = LinkInfoBean(
|
||||
@ -218,7 +212,7 @@ class TaskLinkViewModel @Inject constructor(
|
||||
taskId = liveDataTaskBean.value!!.id,
|
||||
linkPid = UUID.randomUUID().toString(),
|
||||
linkStatus = 3,
|
||||
length = mapController.measureLayerHandler.lineLengthLiveData.value!!,
|
||||
length = mapController.measureLayerHandler.measureValueLiveData.value!!.value,
|
||||
geometry = GeometryTools.getLineString(mapController.measureLayerHandler.mPathLayer.points),
|
||||
linkInfo = LinkInfoBean(
|
||||
kind = liveDataSelectKind.value!!.type,
|
||||
@ -256,7 +250,7 @@ class TaskLinkViewModel @Inject constructor(
|
||||
* 绘制线的时候回退点
|
||||
*/
|
||||
fun removeLinkLastPoint() {
|
||||
mapController.measureLayerHandler.drawLineBackspace()
|
||||
mapController.measureLayerHandler.backspacePoint()
|
||||
}
|
||||
|
||||
/**
|
||||
|
BIN
app/src/main/res/drawable-xxhdpi/measuring_tool_close.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/measuring_tool_close.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 836 B |
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/shape_rect_white_press_6dp_bg" android:state_selected="true"></item>
|
||||
<item android:drawable="@drawable/shape_rect_white_press_6dp_bg" android:state_pressed="true"></item>
|
||||
<item android:drawable="@drawable/shape_rect_white_6dp_bg" />
|
||||
</selector>
|
@ -7,7 +7,7 @@
|
||||
android:bottomRightRadius="6dp"
|
||||
android:topLeftRadius="6dp"
|
||||
android:topRightRadius="6dp" />
|
||||
|
||||
<stroke android:width="1dp" android:color="@color/blue"/>
|
||||
<solid android:color="#2632335e" />
|
||||
|
||||
</shape>
|
||||
|
@ -101,7 +101,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_disance,main_activity_menu"
|
||||
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:flow_horizontalGap="6dp"
|
||||
app:flow_wrapMode="aligned"
|
||||
app:layout_constraintRight_toLeftOf="@id/main_activity_right_fragment"
|
||||
@ -112,7 +112,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_disance" />
|
||||
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" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_serach"
|
||||
@ -139,9 +139,9 @@
|
||||
android:src="@drawable/icon_trace" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_calc_disance"
|
||||
android:id="@+id/main_activity_calc_distance"
|
||||
style="@style/top_right_drawer_btns_style"
|
||||
android:onClick="@{()->mainActivity.onClickCalcDisance()}"
|
||||
android:onClick="@{()->mainActivity.onClickCalcDistance()}"
|
||||
android:src="@drawable/icon_calc_disance" />
|
||||
|
||||
<ImageButton
|
||||
@ -164,6 +164,15 @@
|
||||
android:elevation="2dp"
|
||||
android:onClick="@{()->mainActivity.onClickMenu()}" />
|
||||
|
||||
<include
|
||||
android:id="@+id/main_activity_measuring_tool"
|
||||
layout="@layout/main_measuring_tool"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintRight_toRightOf="@id/main_activity_calc_distance"
|
||||
app:layout_constraintTop_toBottomOf="@id/main_activity_flow" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:layout_width="wrap_content"
|
||||
@ -333,12 +342,12 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/five"
|
||||
app:constraint_referenced_ids="main_activity_snapshot_finish,main_activity_trace_snapshot_points,main_activity_snapshot_media_flag,main_activity_snapshot_rewind,main_activity_snapshot_pause,main_activity_snapshot_next,main_activity_menu_indoor_group"
|
||||
app:constraint_referenced_ids="main_activity_snapshot_finish,main_activity_trace_snapshot_points,main_activity_snapshot_rewind,main_activity_snapshot_pause,main_activity_snapshot_next,main_activity_menu_indoor_group"
|
||||
app:flow_horizontalGap="6dp"
|
||||
app:flow_wrapMode="aligned"
|
||||
app:layout_constraintBottom_toTopOf="@id/main_activity_bottom_sheet"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/main_activity_bottom_sheet" />
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/main_activity_menu_indoor_group"
|
||||
@ -359,12 +368,12 @@
|
||||
android:onClick="@{()->mainActivity.tracePointsOnclick()}"
|
||||
android:src="@drawable/map_trace_select_point" />
|
||||
|
||||
<!-- <ImageButton
|
||||
android:id="@+id/main_activity_snapshot_media_flag"
|
||||
style="@style/top_right_drawer_btns_style"
|
||||
android:visibility="gone"
|
||||
android:onClick="@{()->mainActivity.mediaFlagOnclick()}"
|
||||
android:src="@drawable/map_trace_mediaflag" />-->
|
||||
<!-- <ImageButton
|
||||
android:id="@+id/main_activity_snapshot_media_flag"
|
||||
style="@style/top_right_drawer_btns_style"
|
||||
android:visibility="gone"
|
||||
android:onClick="@{()->mainActivity.mediaFlagOnclick()}"
|
||||
android:src="@drawable/map_trace_mediaflag" />-->
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_snapshot_rewind"
|
||||
|
@ -3,31 +3,48 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/shape_rect_white_6dp_bg"
|
||||
android:clickable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="5dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/measuring_tool_value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="24dp"
|
||||
android:background="@drawable/shape_bg_blue_bg_4_radius"
|
||||
android:textColor="@color/white" />
|
||||
android:gravity="center"
|
||||
android:minWidth="65dp"
|
||||
android:text="0"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/measuring_tool_value_unit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/blue" />
|
||||
android:text="米"
|
||||
android:textColor="@color/blue"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/measuring_tool_select_point"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingRight="6dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
@ -43,10 +60,16 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/measuring_tool_distance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:background="@drawable/selector_default_button_white_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingRight="6dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
@ -62,8 +85,12 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/measuring_tool_area"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:background="@drawable/selector_default_button_white_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
@ -81,8 +108,12 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/measuring_tool_angle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:background="@drawable/selector_default_button_white_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
@ -100,20 +131,36 @@
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/measuring_tool_backspace"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:background="@drawable/shape_rect_transparent_blue_6dp_bg"
|
||||
android:drawableLeft="@drawable/baseline_arrow_left_24"
|
||||
android:drawablePadding="-15dp"
|
||||
android:gravity="center"
|
||||
android:text="上一步"
|
||||
android:textColor="@color/blue"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@drawable/baseline_arrow_left_24"
|
||||
android:id="@+id/measuring_tool_reset"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:background="@drawable/shape_rect_transparent_blue_6dp_bg"
|
||||
android:gravity="center"
|
||||
android:text="重复"
|
||||
android:text="重绘"
|
||||
android:textColor="@color/blue"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/measuring_tool_close"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:background="@drawable/measuring_tool_close" />
|
||||
</LinearLayout>
|
@ -10,7 +10,6 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.navinfo.collect.library.R
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
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
|
||||
@ -26,29 +25,48 @@ import org.oscim.layers.marker.MarkerInterface
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
import org.oscim.layers.marker.MarkerSymbol
|
||||
import org.oscim.layers.vector.PathLayer
|
||||
import org.oscim.layers.vector.geometries.PolygonDrawable
|
||||
import org.oscim.layers.vector.geometries.Style
|
||||
import org.oscim.map.Map
|
||||
import java.math.BigDecimal
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.ceil
|
||||
|
||||
|
||||
open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView), Map.UpdateListener {
|
||||
|
||||
private var editIndex: Int = -1;//线修型的时候,用来表示是不是正在修型,修的第几个点
|
||||
private val mPathMakers: MutableList<MarkerItem> = mutableListOf()
|
||||
private var bDrawLine = false
|
||||
private val bDrawPoint = false
|
||||
private var measureType = MEASURE_TYPE.DISTANCE
|
||||
|
||||
/**
|
||||
* 测量类型
|
||||
*/
|
||||
enum class MEASURE_TYPE {
|
||||
DISTANCE,//距离
|
||||
AREA,//面积
|
||||
ANGLE,//角度
|
||||
}
|
||||
|
||||
data class MeasureValueBean(
|
||||
var value: Double = 0.00,
|
||||
var valueString: String = "0.00",
|
||||
var unit: String = ""
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* 加上虚线的总长度
|
||||
*/
|
||||
val tempLineDistanceLiveData = MutableLiveData("")
|
||||
val tempMeasureValueLiveData = MutableLiveData<MeasureValueBean>()
|
||||
|
||||
/**
|
||||
* 实际绘制的总长度
|
||||
*/
|
||||
val lineLengthLiveData = MutableLiveData(0.000)
|
||||
val measureValueLiveData = MutableLiveData<MeasureValueBean>()
|
||||
|
||||
|
||||
private val markerLayer: ItemizedLayer by lazy {
|
||||
|
||||
@ -64,35 +82,46 @@ open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
layer
|
||||
}
|
||||
|
||||
private val mAreaLayer: ItemizedLayer by lazy {
|
||||
val markerSymbol = MarkerSymbol(mPathMarkerBitmap, MarkerSymbol.HotspotPlace.CENTER)
|
||||
ItemizedLayer(mMapView.vtmMap, ArrayList(), markerSymbol, null)
|
||||
/**
|
||||
* 显示面积文字
|
||||
*/
|
||||
private var mAreaTextLayer: ItemizedLayer? = null
|
||||
|
||||
/**
|
||||
* 面积的渲染面
|
||||
*/
|
||||
private var areaPolygon: PolygonDrawable? = null
|
||||
|
||||
/**
|
||||
* 面积的渲染样式
|
||||
*/
|
||||
private val areaStyle: Style by lazy {
|
||||
Style.builder().scaleZoomLevel(20).buffer(1.0)
|
||||
.fillColor(context.resources.getColor(R.color.draw_area_color)).fillAlpha(0.5f)
|
||||
.fixed(true).build()
|
||||
}
|
||||
|
||||
//绘制线 样式
|
||||
private val lineStyle: Style by lazy {
|
||||
//新增线数据图层和线样式
|
||||
Style.builder().scaleZoomLevel(20).buffer(1.0)
|
||||
.stippleColor(context.resources.getColor(R.color.draw_line_blue1_color))
|
||||
.strokeWidth(4f)
|
||||
.fillColor(context.resources.getColor(R.color.draw_line_blue2_color))
|
||||
.fillAlpha(0.5f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color))
|
||||
.fillColor(context.resources.getColor(R.color.draw_line_red_color))
|
||||
.stippleWidth(4f).fixed(true).build()
|
||||
.stippleColor(context.resources.getColor(R.color.draw_line_blue1_color)).strokeWidth(4f)
|
||||
.fillColor(context.resources.getColor(R.color.draw_line_blue2_color)).fillAlpha(0.5f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color)).stippleWidth(4f)
|
||||
.fixed(true).build()
|
||||
}
|
||||
|
||||
private val newTempStyle: Style by lazy {
|
||||
Style.builder().stippleColor(context.resources.getColor(R.color.transparent))
|
||||
.stipple(30).stippleWidth(30f).strokeWidth(4f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color))
|
||||
.fixed(true).randomOffset(false).build()
|
||||
Style.builder().stippleColor(context.resources.getColor(R.color.transparent)).stipple(30)
|
||||
.stippleWidth(30f).strokeWidth(4f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_blue2_color)).fixed(true)
|
||||
.randomOffset(false).build()
|
||||
}
|
||||
|
||||
//线型编辑时的样式
|
||||
private val editTempStyle: Style by lazy {
|
||||
Style.builder().stippleColor(context.resources.getColor(R.color.transparent))
|
||||
.stipple(30).stippleWidth(30f).strokeWidth(8f)
|
||||
Style.builder().stippleColor(context.resources.getColor(R.color.transparent)).stipple(30)
|
||||
.stippleWidth(30f).strokeWidth(8f)
|
||||
.strokeColor(context.resources.getColor(R.color.draw_line_red_color)).fixed(true)
|
||||
.randomOffset(false).build()
|
||||
|
||||
@ -121,125 +150,115 @@ open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
)
|
||||
}
|
||||
|
||||
private var bDrawPolygon = false
|
||||
|
||||
val mPolygonLayer: NIPolygonLayer by lazy {
|
||||
val layer = NIPolygonLayer(mMapView.vtmMap, lineStyle)
|
||||
addLayer(layer, NIMapView.LAYER_GROUPS.OPERATE_LINE)
|
||||
layer
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
mMapView.vtmMap.events.bind(this)
|
||||
}
|
||||
|
||||
open fun drawLineOrPolygon(isPolygon: Boolean) {
|
||||
bDrawLine = true
|
||||
open fun addPoint(type: MEASURE_TYPE, selectPoint: GeoPoint? = null) {
|
||||
|
||||
//画面
|
||||
if (isPolygon && !mPolygonLayer.isEnabled) {
|
||||
mPolygonLayer.isEnabled = true
|
||||
} else if (!mPathLayer.isEnabled) {
|
||||
bDrawLine = true
|
||||
measureType = type
|
||||
if (!mPathLayer.isEnabled) {
|
||||
mPathLayer.isEnabled = true
|
||||
}
|
||||
if (!markerLayer.isEnabled) {
|
||||
markerLayer.isEnabled = true
|
||||
}
|
||||
//上一个点的引线
|
||||
if (!mPathLayerTemp.isEnabled) {
|
||||
mPathLayerTemp.isEnabled = true
|
||||
}
|
||||
val geoPoint = GeoPoint(
|
||||
|
||||
val geoPoint = selectPoint ?: GeoPoint(
|
||||
mMapView.vtmMap.mapPosition.latitude, mMapView.vtmMap.mapPosition.longitude
|
||||
)
|
||||
|
||||
//编辑点
|
||||
if (editIndex > -1) {
|
||||
if (mPathMakers.size > editIndex) {
|
||||
markerLayer.removeItem(editIndex)
|
||||
mPathMakers.removeAt(editIndex)
|
||||
val markerItem = MarkerItem(createUUID(), "", "", geoPoint)
|
||||
markerLayer.addItem(markerItem)
|
||||
mPathMakers.add(editIndex, markerItem)
|
||||
if (mPathLayer.points.size > 0) {
|
||||
val list: MutableList<GeoPoint> = mPathLayer.points
|
||||
if (editIndex < list.size) {
|
||||
list.removeAt(editIndex)
|
||||
val list2: MutableList<GeoPoint> = java.util.ArrayList(list)
|
||||
list2.add(editIndex, geoPoint)
|
||||
mPathLayer.setPoints(list2)
|
||||
}
|
||||
} else if (mPolygonLayer.points.size > 0) {
|
||||
val list = mPolygonLayer.points
|
||||
if (editIndex < list.size) {
|
||||
list.removeAt(editIndex)
|
||||
val list2: MutableList<GeoPoint> = java.util.ArrayList(list)
|
||||
list2.add(editIndex, geoPoint)
|
||||
mPolygonLayer.setPoints(list2)
|
||||
}
|
||||
}
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>()
|
||||
if (isPolygon && mPathMakers.size > 1) {
|
||||
list.add(mPathMakers[0].geoPoint)
|
||||
list.add(geoPoint)
|
||||
list.add(mPathMakers[mPathMakers.size - 1].geoPoint)
|
||||
} else {
|
||||
list.add(mPathMakers[mPathMakers.size - 1].geoPoint)
|
||||
list.add(geoPoint)
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
Log.e("jingo", "移除marker $editIndex")
|
||||
val marker = mPathMakers[editIndex]
|
||||
markerLayer.removeItem(marker)
|
||||
mPathMakers.removeAt(editIndex)
|
||||
val markerItem = MarkerItem(createUUID(), "", "", geoPoint)
|
||||
markerLayer.addItem(markerItem)
|
||||
mPathMakers.add(editIndex, markerItem)
|
||||
if (mPathLayer.points.size > 0) {
|
||||
val list: MutableList<GeoPoint> = mPathLayer.points
|
||||
list.removeAt(editIndex)
|
||||
val list2: MutableList<GeoPoint> = ArrayList(list)
|
||||
list2.add(editIndex, geoPoint)
|
||||
mPathLayer.setPoints(list2)
|
||||
}
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
mMapView.vtmMap.animator().animateTo(mPathLayer.points[mPathLayer.points.size - 1])
|
||||
editIndex = -1
|
||||
} else { //新增点
|
||||
if (isPolygon) {
|
||||
val points: MutableList<GeoPoint> = java.util.ArrayList(mPolygonLayer.points)
|
||||
if (points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList()
|
||||
points.add(points[0])
|
||||
if (type == MEASURE_TYPE.ANGLE && mPathLayer.points.size == 3) {
|
||||
return
|
||||
}
|
||||
val points: List<GeoPoint> = mPathLayer.points
|
||||
if (points.size > 2) {
|
||||
val list = mutableListOf<GeoPoint>()
|
||||
list.add(geoPoint)
|
||||
list.add(points[points.size - 1])
|
||||
var bCross = GeometryTools.isLineStringCrosses(points, list)
|
||||
if (bCross) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
if (measureType == MEASURE_TYPE.AREA) {
|
||||
list.clear()
|
||||
list.add(geoPoint)
|
||||
list.add(points[0])
|
||||
list.add(geoPoint)
|
||||
list.add(mPolygonLayer.points[mPolygonLayer.points.size - 1])
|
||||
val bCross = GeometryTools.isPolygonCrosses(points, list)
|
||||
bCross = GeometryTools.isLineStringCrosses(points, list)
|
||||
if (bCross) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
}
|
||||
mPolygonLayer.addPoint(geoPoint)
|
||||
} else {
|
||||
val points: List<GeoPoint> = mPathLayer.points
|
||||
if (points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList()
|
||||
list.add(geoPoint)
|
||||
list.add(points[points.size - 1])
|
||||
val bCross = GeometryTools.isLineStringCrosses(points, list)
|
||||
if (bCross) {
|
||||
Toast.makeText(mContext, "不能交叉", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
}
|
||||
mPathLayer.addPoint(geoPoint)
|
||||
if (mPathLayer.points.size > 1) {
|
||||
val distance: Double = GeometryTools.getDistance(mPathLayer.points)
|
||||
val bg = BigDecimal(distance)
|
||||
val f1 = bg.setScale(3, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
lineLengthLiveData.value = f1
|
||||
} else {
|
||||
lineLengthLiveData.value = 0.000
|
||||
}
|
||||
}
|
||||
mPathLayer.addPoint(geoPoint)
|
||||
// }
|
||||
val markerItem = MarkerItem(createUUID(), "", "", geoPoint)
|
||||
markerLayer.addItem(markerItem)
|
||||
mPathMakers.add(markerItem)
|
||||
markerLayer.update()
|
||||
}
|
||||
showAreaLayer()
|
||||
|
||||
//
|
||||
when (type) {
|
||||
MEASURE_TYPE.AREA -> {
|
||||
showAreaLayer()
|
||||
}
|
||||
MEASURE_TYPE.DISTANCE -> {
|
||||
if (mPathLayer.points.size > 1) {
|
||||
measureValueLiveData.value = calculatedDistance(mPathLayer.points)
|
||||
} else {
|
||||
measureValueLiveData.value = MeasureValueBean(unit = "米")
|
||||
}
|
||||
}
|
||||
MEASURE_TYPE.ANGLE -> {
|
||||
if (mPathLayer.points.size == 3) {
|
||||
val bean = calculatedAngle(mPathLayer.points)
|
||||
measureValueLiveData.value = bean
|
||||
} else {
|
||||
measureValueLiveData.value = MeasureValueBean(unit = "度")
|
||||
}
|
||||
}
|
||||
}
|
||||
//点击选点让地图动一下,好出发mapEvent
|
||||
if (selectPoint != null) {
|
||||
mMapView.vtmMap.animator().animateTo(selectPoint)
|
||||
}
|
||||
mPathLayer.update()
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制线回退点
|
||||
*/
|
||||
open fun drawLineBackspace() {
|
||||
open fun backspacePoint() {
|
||||
if (mPathLayer.points.size > 0) {
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>(mPathLayer.getPoints())
|
||||
val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>(mPathLayer.points)
|
||||
val point = list[mPathLayer.points.size - 1]
|
||||
list.remove(point)
|
||||
mPathLayer.setPoints(list)
|
||||
@ -250,115 +269,196 @@ open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
)
|
||||
}
|
||||
if (mPathMakers.size > 0) {
|
||||
var item: MarkerItem? = mPathMakers[mPathMakers.size - 1]
|
||||
val item: MarkerItem = mPathMakers[mPathMakers.size - 1]
|
||||
markerLayer.removeItem(item)
|
||||
mPathMakers.remove(item)
|
||||
}
|
||||
if (mPathMakers.size == 0 && mPathLayerTemp != null) {
|
||||
if (mPathMakers.size == 0) {
|
||||
mPathLayerTemp.clearPath()
|
||||
}
|
||||
editIndex = -1
|
||||
if (mPathLayerTemp != null) {
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
}
|
||||
if (mPathLayer.points.size > 1) {
|
||||
val distance: Double = GeometryTools.getDistance(mPathLayer.points)
|
||||
val bg = BigDecimal(distance)
|
||||
val f1 = bg.setScale(3, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
lineLengthLiveData.value = f1
|
||||
} else {
|
||||
lineLengthLiveData.value = 0.000
|
||||
tempLineDistanceLiveData.value = "0米"
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
when (measureType) {
|
||||
MEASURE_TYPE.AREA -> {
|
||||
showAreaLayer()
|
||||
}
|
||||
MEASURE_TYPE.DISTANCE -> {
|
||||
if (mPathLayer.points.size > 1) {
|
||||
measureValueLiveData.value = calculatedDistance(mPathLayer.points)
|
||||
} else {
|
||||
val bean = MeasureValueBean(unit = "米")
|
||||
measureValueLiveData.value = bean
|
||||
tempMeasureValueLiveData.value = bean
|
||||
}
|
||||
}
|
||||
MEASURE_TYPE.ANGLE -> {
|
||||
val bean = MeasureValueBean(unit = "度")
|
||||
measureValueLiveData.value = bean
|
||||
tempMeasureValueLiveData.value = bean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制面回退点
|
||||
*/
|
||||
open fun drawPolygonBackspace() {
|
||||
// if (mPathLayer.points.size > 0) {
|
||||
// val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>(mPathLayer.getPoints())
|
||||
// val point = list[mPathLayer.getPoints().size - 1]
|
||||
// list.remove(point)
|
||||
// mPathLayer.setPoints(list)
|
||||
// mMapView.layerManager.jumpToPosition(point.longitude, point.latitude, 0)
|
||||
// } else if (mPolygonLayer.points.size > 0) {
|
||||
// val list: MutableList<GeoPoint> = java.util.ArrayList<GeoPoint>(mPolygonLayer.points)
|
||||
// val point = list[mPolygonLayer.points.size - 1]
|
||||
// list.remove(point)
|
||||
// mPolygonLayer.setPoints(list)
|
||||
// mMapView.layerManager.jumpToPosition(point!!.longitude, point.latitude, 0)
|
||||
// }
|
||||
// if (mPathMakers.size > 0) {
|
||||
// var item: MarkerItem? = mPathMakers[mPathMakers.size - 1]
|
||||
// mMapView.layerManager.removeMarker(item, NILayerManager.MARQUEE_MARKER_LAYER)
|
||||
// mPathMakers.remove(item)
|
||||
// item = null
|
||||
// }
|
||||
// if (mPathMakers.size == 0 && mPathLayerTemp != null) {
|
||||
// mPathLayerTemp.clearPath()
|
||||
// }
|
||||
// editIndex = -1
|
||||
// if (mPathLayerTemp != null) {
|
||||
// mPathLayerTemp.setStyle(newTempStyle)
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 隐藏面积计算
|
||||
*/
|
||||
open fun hideAreaLayer() {
|
||||
mAreaLayer.removeAllItems()
|
||||
mMapView.vtmMap.layers().remove(mAreaLayer)
|
||||
}
|
||||
mAreaTextLayer?.let {
|
||||
it.removeAllItems()
|
||||
removeLayer(it)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示面积计算
|
||||
*/
|
||||
open fun showAreaLayer() {
|
||||
mAreaLayer.removeAllItems()
|
||||
mMapView.vtmMap.layers().remove(mAreaLayer)
|
||||
if (mPolygonLayer.points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = ArrayList(mPolygonLayer.points)
|
||||
val area = DistanceUtil.planarPolygonAreaMeters2(list)
|
||||
val areaString = if (area < 1000000) {
|
||||
area.toString() + "平方米"
|
||||
} else if (area < 10000000000.0) {
|
||||
val d = area / 1000000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(1, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
f1.toString() + "平方公里"
|
||||
} else {
|
||||
val d = area / 10000000000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(1, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
f1.toString() + "万平方公里"
|
||||
}
|
||||
if (mAreaTextLayer != null) {
|
||||
mAreaTextLayer!!.removeAllItems()
|
||||
removeLayer(mAreaTextLayer!!)
|
||||
}
|
||||
if (areaPolygon != null) mPathLayer.remove(areaPolygon)
|
||||
|
||||
if (mPathLayer.points.size > 2) {
|
||||
val list: MutableList<GeoPoint> = mPathLayer.points.toMutableList()
|
||||
val valueBean = calculatedArea(list)
|
||||
val textPaint = TextPaint()
|
||||
textPaint.textSize = 13 * CanvasAdapter.getScale()
|
||||
textPaint.color = Color.BLUE
|
||||
val width = ceil(textPaint.measureText(areaString).toDouble()).toInt()
|
||||
val width = ceil(
|
||||
textPaint.measureText("${valueBean.valueString}${valueBean.unit}").toDouble()
|
||||
).toInt()
|
||||
val fontMetrics = textPaint.fontMetrics
|
||||
val height = ceil((abs(fontMetrics.bottom) + abs(fontMetrics.top)).toDouble()).toInt()
|
||||
val bitmap = android.graphics.Bitmap.createBitmap(
|
||||
width, height, android.graphics.Bitmap.Config.ARGB_8888
|
||||
)
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.drawText(areaString, 0f, abs(fontMetrics.ascent), textPaint)
|
||||
// val bitmap2: Bitmap = AndroidBitmap(bitmap)
|
||||
// val markerSymbol = MarkerSymbol(bitmap2, MarkerSymbol.HotspotPlace.CENTER)
|
||||
// mAreaLayer = ItemizedLayer(mMapView.vtmMap, ArrayList(), markerSymbol, null)
|
||||
// mMapView.vtmMap.layers().add(mAreaLayer)
|
||||
canvas.drawText(
|
||||
"${valueBean.valueString}${valueBean.unit}",
|
||||
0f,
|
||||
abs(fontMetrics.ascent),
|
||||
textPaint
|
||||
)
|
||||
val bitmap2: Bitmap = AndroidBitmap(bitmap)
|
||||
val markerSymbol = MarkerSymbol(bitmap2, MarkerSymbol.HotspotPlace.CENTER)
|
||||
mAreaTextLayer = ItemizedLayer(
|
||||
mMapView.vtmMap, java.util.ArrayList(), markerSymbol, null
|
||||
)
|
||||
addLayer(mAreaTextLayer!!, NIMapView.LAYER_GROUPS.OPERATE_MARKER)
|
||||
list.add(list[0])
|
||||
val polygon = GeometryTools.createPolygon(list)
|
||||
val point = polygon.centroid
|
||||
val item = MarkerItem(areaString, "", GeoPoint(point.coordinate.y, point.coordinate.x))
|
||||
mAreaLayer.removeAllItems()
|
||||
mAreaLayer.addItem(item)
|
||||
mAreaLayer.update()
|
||||
val item = MarkerItem(
|
||||
"${valueBean.valueString}${valueBean.unit}",
|
||||
"",
|
||||
GeoPoint(point.coordinate.y, point.coordinate.x)
|
||||
)
|
||||
mAreaTextLayer!!.removeAllItems()
|
||||
mAreaTextLayer!!.addItem(item)
|
||||
mAreaTextLayer!!.update()
|
||||
areaPolygon = PolygonDrawable(polygon, areaStyle)
|
||||
mPathLayer.add(areaPolygon)
|
||||
|
||||
measureValueLiveData.postValue(valueBean)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算角度
|
||||
*/
|
||||
private fun calculatedAngle(list: MutableList<GeoPoint>): MeasureValueBean {
|
||||
val bean = MeasureValueBean(unit = "度")
|
||||
if (list.size == 3) {
|
||||
var angle = DistanceUtil.angle(
|
||||
list[0],
|
||||
list[1],
|
||||
list[2]
|
||||
)
|
||||
if (angle > 180)
|
||||
angle = 360 - angle
|
||||
val bg = BigDecimal(angle)
|
||||
val f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)
|
||||
bean.value = angle
|
||||
bean.valueString = f1.toString()
|
||||
}
|
||||
return bean
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算距离
|
||||
*/
|
||||
private fun calculatedDistance(list: MutableList<GeoPoint>): MeasureValueBean {
|
||||
val bean = MeasureValueBean(unit = "米")
|
||||
if (list.size < 2) {
|
||||
return bean
|
||||
}
|
||||
val distance: Double = GeometryTools.getDistance(list)
|
||||
bean.value = distance
|
||||
try {
|
||||
if (distance < 1000) {
|
||||
val bg = BigDecimal(distance)
|
||||
val f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)
|
||||
bean.valueString = f1.toString()
|
||||
bean.unit = "米"
|
||||
} else if (distance < 10000000) {
|
||||
|
||||
val d = distance / 1000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)
|
||||
bean.valueString = f1.toString()
|
||||
bean.unit = "公里"
|
||||
|
||||
} else {
|
||||
val d = distance / 10000000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)
|
||||
bean.valueString = f1.toString()
|
||||
bean.unit = "万公里"
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("jingo", e.toString() + "$distance")
|
||||
}
|
||||
return bean
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算面积
|
||||
*/
|
||||
private fun calculatedArea(list: MutableList<GeoPoint>): MeasureValueBean {
|
||||
val bean = MeasureValueBean(unit = "平方米")
|
||||
|
||||
val area = DistanceUtil.planarPolygonAreaMeters2(list)
|
||||
bean.value = area
|
||||
if (area == 0.0) {
|
||||
"0"
|
||||
} else if (area < 10000) {
|
||||
val bg = BigDecimal(area)
|
||||
val f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)
|
||||
bean.valueString = f1.toString()
|
||||
bean.unit = "平方米"
|
||||
} else if (area < 1000000) {
|
||||
val d = area / 10000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)
|
||||
bean.valueString = f1.toString()
|
||||
bean.unit = "万平方米"
|
||||
} else if (area < 10000000000.0) {
|
||||
val d = area / 1000000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)
|
||||
bean.valueString = f1.toString()
|
||||
bean.unit = "平方公里"
|
||||
} else {
|
||||
val d = area / 10000000000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP)
|
||||
bean.valueString = f1.toString()
|
||||
bean.unit = "万平方公里"
|
||||
}
|
||||
return bean
|
||||
}
|
||||
|
||||
/**
|
||||
@ -368,17 +468,20 @@ open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
bDrawLine = false
|
||||
editIndex = -1
|
||||
markerLayer.removeAllItems()
|
||||
markerLayer.isEnabled = false
|
||||
mPathMakers.clear()
|
||||
mPathLayer.clearPath()
|
||||
if (areaPolygon != null) {
|
||||
mPathLayer.remove(areaPolygon)
|
||||
areaPolygon = null
|
||||
}
|
||||
mPathLayer.isEnabled = false
|
||||
mPolygonLayer.clearPath()
|
||||
mPolygonLayer.isEnabled = false
|
||||
mPathLayerTemp.clearPath()
|
||||
mPathLayerTemp.isEnabled = false
|
||||
mPathLayerTemp.setStyle(newTempStyle)
|
||||
hideAreaLayer()
|
||||
lineLengthLiveData.value = 0.000
|
||||
tempLineDistanceLiveData.value = "0米"
|
||||
measureValueLiveData.value = MeasureValueBean()
|
||||
tempMeasureValueLiveData.value = MeasureValueBean()
|
||||
mMapView.vtmMap.updateMap(true)
|
||||
}
|
||||
|
||||
@ -394,27 +497,94 @@ open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
// mapPosition.setPosition(geoPoint)
|
||||
// }
|
||||
if (e === Map.POSITION_EVENT) {
|
||||
mPathLayerTemp.clearPath()
|
||||
//测角度,3个点后不渲染引导线
|
||||
|
||||
if (mPathLayer.points.size > 0) {
|
||||
if (editIndex > -1) {
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
if (editIndex == 0 || editIndex == mPathMakers.size - 1) {
|
||||
list.add(mPathMakers[editIndex].geoPoint)
|
||||
val list = mutableListOf<GeoPoint>()
|
||||
val tempList = mutableListOf<GeoPoint>()
|
||||
//编辑起点
|
||||
if (editIndex == 0) {
|
||||
//如果现在只有一个点,显示当前点要移动到的位置
|
||||
if (mPathLayer.points.size == 1) {
|
||||
list.add(mPathLayer.points[0])
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude, mapPosition.longitude
|
||||
)
|
||||
)
|
||||
} else {
|
||||
//当前有多个点,红线链接第二个点
|
||||
list.add(mPathLayer.points[1])
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude, mapPosition.longitude
|
||||
)
|
||||
)
|
||||
if (measureType == MEASURE_TYPE.AREA) {
|
||||
list.add(mPathLayer.points[mPathLayer.points.size - 1])
|
||||
}
|
||||
tempList.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude, mapPosition.longitude
|
||||
)
|
||||
)
|
||||
for (i in 1 until mPathLayer.points.size) {
|
||||
tempList.add(mPathLayer.points[i])
|
||||
}
|
||||
}
|
||||
} else if (editIndex == mPathLayer.points.size - 1) {
|
||||
//如果当前编辑的是最后一个点
|
||||
list.add(mPathLayer.points[editIndex - 1])
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude, mapPosition.longitude
|
||||
)
|
||||
)
|
||||
for (i in 0 until mPathLayer.points.size - 1) {
|
||||
tempList.add(mPathLayer.points[i])
|
||||
}
|
||||
tempList.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude, mapPosition.longitude
|
||||
)
|
||||
)
|
||||
if (measureType == MEASURE_TYPE.AREA) {
|
||||
list.add(mPathLayer.points[0])
|
||||
}
|
||||
} else {
|
||||
list.add(mPathMakers[editIndex - 1].geoPoint)
|
||||
list.add(mPathLayer.points[editIndex - 1])
|
||||
list.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude, mapPosition.longitude
|
||||
)
|
||||
)
|
||||
list.add(mPathMakers[editIndex + 1].geoPoint)
|
||||
list.add(mPathLayer.points[editIndex + 1])
|
||||
for (i in 0 until editIndex) {
|
||||
tempList.add(mPathLayer.points[i])
|
||||
}
|
||||
tempList.add(
|
||||
GeoPoint(
|
||||
mapPosition.latitude, mapPosition.longitude
|
||||
)
|
||||
)
|
||||
for (i in editIndex + 1 until mPathLayer.points.size) {
|
||||
tempList.add(mPathLayer.points[i])
|
||||
}
|
||||
}
|
||||
mPathLayerTemp.setPoints(list)
|
||||
// crossText.setText("")
|
||||
when (measureType) {
|
||||
MEASURE_TYPE.DISTANCE -> {
|
||||
tempMeasureValueLiveData.value = calculatedDistance(tempList)
|
||||
}
|
||||
MEASURE_TYPE.AREA -> {
|
||||
tempMeasureValueLiveData.value = calculatedArea(tempList)
|
||||
}
|
||||
MEASURE_TYPE.ANGLE -> {
|
||||
tempMeasureValueLiveData.value = calculatedAngle(tempList)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val list: MutableList<GeoPoint> = mutableListOf()
|
||||
list.add(mPathLayer.points[mPathLayer.points.size - 1])
|
||||
@ -424,29 +594,40 @@ open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
list.add(
|
||||
nowPoint
|
||||
)
|
||||
mPathLayerTemp.setPoints(list)
|
||||
if (mPathLayer.points.size > 0) {
|
||||
val dList = mPathLayer.points.toMutableList()
|
||||
dList.add(nowPoint)
|
||||
val distance: Double =
|
||||
GeometryTools.getDistance(dList)
|
||||
if (distance < 1000) {
|
||||
tempLineDistanceLiveData.value = "${distance.toInt()}米"
|
||||
} else {
|
||||
try {
|
||||
val d = distance / 1000.0
|
||||
val bg = BigDecimal(d)
|
||||
val f1 =
|
||||
bg.setScale(1, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
tempLineDistanceLiveData.value = "${f1}公里"
|
||||
} catch (e: Exception) {
|
||||
Log.e("jingo", e.toString() + "$distance")
|
||||
}
|
||||
when (measureType) {
|
||||
MEASURE_TYPE.DISTANCE -> {
|
||||
mPathLayerTemp.setPoints(list)
|
||||
val dList = mPathLayer.points.toMutableList()
|
||||
dList.add(nowPoint)
|
||||
tempMeasureValueLiveData.value = calculatedDistance(dList)
|
||||
}
|
||||
MEASURE_TYPE.AREA -> {
|
||||
if (mPathLayer.points.size == 1) {
|
||||
mPathLayerTemp.setPoints(list)
|
||||
} else if (mPathLayer.points.size > 1) {
|
||||
list.add(mPathLayer.points[0])
|
||||
mPathLayerTemp.setPoints(list)
|
||||
val dList = mPathLayer.points.toMutableList()
|
||||
dList.add(nowPoint)
|
||||
dList.add(mPathLayer.points[0])
|
||||
tempMeasureValueLiveData.value = calculatedArea(dList)
|
||||
} else {
|
||||
tempMeasureValueLiveData.value = MeasureValueBean(unit = "平方米")
|
||||
}
|
||||
|
||||
}
|
||||
MEASURE_TYPE.ANGLE -> {
|
||||
mPathLayerTemp.setPoints(list)
|
||||
val dList = mPathLayer.points.toMutableList()
|
||||
if(dList.size < 3) {
|
||||
dList.add(nowPoint)
|
||||
}
|
||||
tempMeasureValueLiveData.value = calculatedAngle(dList)
|
||||
}
|
||||
} else {
|
||||
tempLineDistanceLiveData.value = "0米"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tempMeasureValueLiveData.value = MeasureValueBean(unit = "平方米")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -466,13 +647,11 @@ open class MeasureLayerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
mPathMakers.add(markerItem)
|
||||
}
|
||||
if (mPathLayer.points.size > 1) {
|
||||
val distance: Double = GeometryTools.getDistance(mPathLayer.points)
|
||||
val bg = BigDecimal(distance)
|
||||
val f1 = bg.setScale(3, BigDecimal.ROUND_HALF_UP).toDouble()
|
||||
lineLengthLiveData.value = f1
|
||||
tempLineDistanceLiveData.value = "${f1}米"
|
||||
val bean = calculatedDistance(mPathLayer.points)
|
||||
measureValueLiveData.value = bean
|
||||
tempMeasureValueLiveData.value = bean
|
||||
} else {
|
||||
lineLengthLiveData.value = 0.000
|
||||
measureValueLiveData.value = MeasureValueBean(unit = "米")
|
||||
}
|
||||
mMapView.updateMap(true)
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ public class GeometryTools {
|
||||
* @return Polygon
|
||||
*/
|
||||
public static Polygon createPolygon(List<GeoPoint> geoPointList) {
|
||||
if (geoPointList != null && geoPointList.size() >= 3) {
|
||||
if (geoPointList != null && geoPointList.size() > 2) {
|
||||
Coordinate[] coordinates = new Coordinate[geoPointList.size()];
|
||||
for (int i = 0; i < geoPointList.size(); i++) {
|
||||
coordinates[i] = new Coordinate(geoPointList.get(i).getLongitude(), geoPointList.get(i).getLatitude());
|
||||
|
@ -9,5 +9,6 @@
|
||||
<color name="draw_line_blue2_color" comment="线数据样式">#4E55AF</color>
|
||||
<color name="draw_line_red_color" comment="线数据样式">#FFF6565D</color>
|
||||
<color name="default_red" comment="应用主要色调">#F03736</color>
|
||||
<color name="draw_area_color" comment="测量面积渲染颜色">#8DEF08EB</color>
|
||||
|
||||
</resources>
|
2
vtm
2
vtm
@ -1 +1 @@
|
||||
Subproject commit 4c9926d105877fce305025e8f85651ccea947c4f
|
||||
Subproject commit a8b86629c698e0fe24bac6ee1dc296f3b65b0f79
|
Loading…
x
Reference in New Issue
Block a user