From 4baa137ad602b8fc927db608bfad0cd9159fe590 Mon Sep 17 00:00:00 2001 From: squallzhjch <zhangjingchao@navinfo.com> Date: Thu, 10 Aug 2023 11:18:14 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=B5=8B=E9=87=8F?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=80=BB=E8=BE=91=E5=92=8C=E5=B1=95=E7=8E=B0?= =?UTF-8?q?=E5=BD=A2=E5=BC=8F=E3=80=82=20=E5=A2=9E=E5=8A=A0=E9=9D=A2?= =?UTF-8?q?=E7=A7=AF=EF=BC=8C=E8=A7=92=E5=BA=A6=E6=B5=8B=E9=87=8F=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9C=B0=E5=9B=BE=E6=B8=B2=E6=9F=93=E9=9D=A2?= =?UTF-8?q?=E4=BC=9A=E5=B4=A9=E6=BA=83=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../omqs/ui/activity/map/MainActivity.kt | 130 +++- .../omqs/ui/activity/map/MainViewModel.kt | 81 ++- .../ui/fragment/tasklink/TaskLinkFragment.kt | 11 +- .../ui/fragment/tasklink/TaskLinkViewModel.kt | 16 +- .../baseline_cancel_24.xml | 0 .../drawable-xxhdpi/measuring_tool_close.png | Bin 0 -> 836 bytes .../selector_default_button_white_bg.xml | 1 + .../shape_rect_transparent_blue_6dp_bg.xml | 2 +- app/src/main/res/layout/activity_main.xml | 35 +- .../main/res/layout/main_measuring_tool.xml | 71 +- .../map/handler/MeasureLayerHandler.kt | 611 +++++++++++------- .../collect/library/utils/GeometryTools.java | 2 +- .../src/main/res/values/colors.xml | 1 + vtm | 2 +- 14 files changed, 679 insertions(+), 284 deletions(-) rename app/src/main/res/{drawable => drawable-v24}/baseline_cancel_24.xml (100%) create mode 100644 app/src/main/res/drawable-xxhdpi/measuring_tool_close.png 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 7457dbf9..ff151fcd 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 @@ -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( 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 58602999..3aace3e8 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 @@ -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() + } + } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt index 579382bb..269f04e3 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt @@ -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()) } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt index a6e7d636..4d85f53a 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt @@ -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() } /** diff --git a/app/src/main/res/drawable/baseline_cancel_24.xml b/app/src/main/res/drawable-v24/baseline_cancel_24.xml similarity index 100% rename from app/src/main/res/drawable/baseline_cancel_24.xml rename to app/src/main/res/drawable-v24/baseline_cancel_24.xml diff --git a/app/src/main/res/drawable-xxhdpi/measuring_tool_close.png b/app/src/main/res/drawable-xxhdpi/measuring_tool_close.png new file mode 100644 index 0000000000000000000000000000000000000000..cf4775f5bbbe526cdf63679a62a1df1747f9dc4b GIT binary patch literal 836 zcmV-K1H1f*P)<h;3K|Lk000e1NJLTq001Tc001Tk1^@s6s6FYf00001b5ch_0Itp) z=>Px%{z*hZR9Hvtmd{I6Q546&=UkN}b((R~TC}JcGsubvTDS-;Ehx$gs$JM7Xji*d zE!#*4MN#+{NDvgXh>U&^v>4q)MvfX4hN4fMAEG$pyC?1&jX^T+(+MQzZQnijeBSq* z^F5ESK_A+nTquJ1txQp|qGEm(@O!@4WB*by6%N!NgwCd%^w+rGMBzZ>5DAhKso^1; zSnE;-H}Bb}O7wdGDUf^FNesWXNMP=l>Ok}w33q}d<s=7dEaL2)KM<(jSqkX^unWM1 z2u@9=;<43|gsP&~nYa^PD*eVu4mPhAW8PaUW)4>eB1Z|Tn?PX^8FRJUIz2P|X{AKf zm38gJ)CHgfKx|&)WI7#p3J&JMRqZ}ZkY~iIR>U2LD;J%ap|^R-yz+$ubyo#+kBQ4f z+&*M8r=8jFqc%{!6<fMASP^MZieCX_`ej0E-8PjT`mppqR299!#CHfp0^R2%OB;dD z8C$3|gPFi^MYIWu9|IJI$e7l;Wol-qKU7(Fg&AD{DO0`$${bH5z9sxXtqaTqhbkkD zO#H+vtJb4J`YwTP5vg(!-76WKot%sR^b56aFb}RGx|f+>g0LMB4G;^^Tb`UfGJ=u0 zwLldFEH|yun*_QI(^Dd@XgOfYx>l(5f_c-o*i-ibDmPHftVGM07JWW{ApAo5^0DQY z=cbQ3h?LT%r(E66%sn952FL_lePNlESo5tJ%=i>Q4;M|kchh1|c>}@fsTo{A#$8t* z`<n@`MCunTxBDvV+QIaQL1hAoNe1Wgr!QwE)J>#nMC&mD&e*K4d`Q1wSloRbL|kGV zeSxwqfAT5MgqeGYxK>PA$-QK`_&q*fVBTK>_(AT=WK~D^))(RV@3JztPEQYfv}rVJ zu-qC_?*Iw{5<_;r&1Uz7w?vvDY|6S-Yu!JYiZ>J#EL0xZ!DXrskRS6}ok*v@Oxh$c zXM(}{{mPXWAQ^CygH1MZ){5C&R>(6&Fu!UR6)P&{R{_80i#_(=DE12`E;BZiGpgPI O0000<MNUMnLSTXqVR;t- literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/selector_default_button_white_bg.xml b/app/src/main/res/drawable/selector_default_button_white_bg.xml index f79bccd6..2be24bac 100644 --- a/app/src/main/res/drawable/selector_default_button_white_bg.xml +++ b/app/src/main/res/drawable/selector_default_button_white_bg.xml @@ -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> \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_rect_transparent_blue_6dp_bg.xml b/app/src/main/res/drawable/shape_rect_transparent_blue_6dp_bg.xml index 3be9fc1b..98969c28 100644 --- a/app/src/main/res/drawable/shape_rect_transparent_blue_6dp_bg.xml +++ b/app/src/main/res/drawable/shape_rect_transparent_blue_6dp_bg.xml @@ -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> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 84a4c048..ce96f6c6 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -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" diff --git a/app/src/main/res/layout/main_measuring_tool.xml b/app/src/main/res/layout/main_measuring_tool.xml index 38140f92..11ba6072 100644 --- a/app/src/main/res/layout/main_measuring_tool.xml +++ b/app/src/main/res/layout/main_measuring_tool.xml @@ -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> \ No newline at end of file diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MeasureLayerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MeasureLayerHandler.kt index 289e58b5..c5bbe32b 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MeasureLayerHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MeasureLayerHandler.kt @@ -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) } 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 12372b32..02d1e1ff 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 @@ -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()); diff --git a/collect-library/src/main/res/values/colors.xml b/collect-library/src/main/res/values/colors.xml index 45cbc411..66069c05 100644 --- a/collect-library/src/main/res/values/colors.xml +++ b/collect-library/src/main/res/values/colors.xml @@ -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> \ No newline at end of file diff --git a/vtm b/vtm index 4c9926d1..a8b86629 160000 --- a/vtm +++ b/vtm @@ -1 +1 @@ -Subproject commit 4c9926d105877fce305025e8f85651ccea947c4f +Subproject commit a8b86629c698e0fe24bac6ee1dc296f3b65b0f79 From 54b30d5db5ac08b0384e82c86921c68c087c6d61 Mon Sep 17 00:00:00 2001 From: squallzhjch <zhangjingchao@navinfo.com> Date: Thu, 10 Aug 2023 14:02:52 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E9=87=8F?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=9A=84=E8=81=94=E5=8A=A8=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=20=E4=BF=AE=E6=94=B9=E5=B4=A9=E6=BA=83bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/navinfo/omqs/ui/activity/map/MainActivity.kt | 2 +- .../navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt | 3 ++- .../omqs/ui/fragment/tasklink/TaskLinkViewModel.kt | 8 +++++--- .../library/map/source/OMDBReferenceDataSource.java | 1 - .../collect/library/map/source/OMDBTileDataSource.java | 3 --- 5 files changed, 8 insertions(+), 9 deletions(-) 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 25bd04f2..f3564217 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 @@ -503,7 +503,7 @@ class MainActivity : BaseActivity() { /** * 结束测量 */ - private fun measuringToolOff() { + fun measuringToolOff() { //监听测距值 mapController.measureLayerHandler.measureValueLiveData.removeObservers(this) mapController.measureLayerHandler.tempMeasureValueLiveData.removeObservers(this) diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt index 269f04e3..52ae10b9 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkFragment.kt @@ -97,7 +97,7 @@ class TaskLinkFragment : BaseFragment(), View.OnClickListener { * 线长度 */ mapController.measureLayerHandler.measureValueLiveData.observe(viewLifecycleOwner) { - binding.taskLinkLength.text = "${it}米" + binding.taskLinkLength.text = "${it.valueString}${it.unit}" } mapController.measureLayerHandler.tempMeasureValueLiveData.observe(viewLifecycleOwner) { (activity as MainActivity).setHomeCenterText("${it.valueString}${it.unit}") @@ -110,6 +110,7 @@ class TaskLinkFragment : BaseFragment(), View.OnClickListener { * 显示地图准星 */ activity?.let { + (activity as MainActivity).measuringToolOff() (activity as MainActivity).setHomeCenterVisibility(View.VISIBLE) } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt index 4d85f53a..2f33032a 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/tasklink/TaskLinkViewModel.kt @@ -296,9 +296,11 @@ class TaskLinkViewModel @Inject constructor( if (task != null) { liveDataTaskBean.postValue(realm.copyFromRealm(task)) } - hadLinkDvoBean = realm.copyFromRealm(objects) - withContext(Dispatchers.Main) { - mapController.measureLayerHandler.initPathLine(hadLinkDvoBean?.geometry!!) + if(objects != null) { + hadLinkDvoBean = realm.copyFromRealm(objects) + withContext(Dispatchers.Main) { + mapController.measureLayerHandler.initPathLine(hadLinkDvoBean?.geometry!!) + } } } } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java index 6b8d6c64..2380c259 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java @@ -51,7 +51,6 @@ public class OMDBReferenceDataSource implements ITileDataSource { if (!listResult.isEmpty()) { mThreadLocalDecoders.get().decode(tile.zoomLevel, tile, mapDataSink, listResult); } - Log.e("jingo",listResult.size() + "条数据"); mapDataSink.completed(QueryResult.SUCCESS); // Log.d("RealmDBTileDataSource", "tile:"+tile.getBoundingBox().toString()); } else { diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java index 0a37ab79..62a43907 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBTileDataSource.java @@ -50,12 +50,9 @@ public class OMDBTileDataSource implements ITileDataSource { } List<RenderEntity> listResult = realmQuery/*.distinct("id")*/.findAll(); if (!listResult.isEmpty()) { - Log.e("qj", "查询数据==" + listResult.size() + "==地图级别" + tile.zoomLevel); mThreadLocalDecoders.get().decode(tile.zoomLevel, tile, mapDataSink, listResult); } - Log.e("jingo",listResult.size() + "条数据 主"); mapDataSink.completed(QueryResult.SUCCESS); -// Log.d("RealmDBTileDataSource", "tile:"+tile.getBoundingBox().toString()); } else { mapDataSink.completed(QueryResult.SUCCESS); }