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 e8a995d8..7d0d249e 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 @@ -21,6 +22,7 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.tabs.TabLayout import com.navinfo.collect.library.map.NIMapController +import com.navinfo.collect.library.map.handler.MeasureLayerHandler import com.navinfo.omqs.Constant import com.navinfo.omqs.R import com.navinfo.omqs.bean.ImportConfig @@ -447,10 +449,12 @@ class MainActivity : BaseActivity() { Toast.makeText(this, "输入格式不正确", Toast.LENGTH_SHORT).show() } } + dialog.dismiss() } inputDialog.show() } + override fun onStart() { super.onStart() @@ -508,10 +512,10 @@ class MainActivity : BaseActivity() { } /** - * 点击计算 + * 点击测速 */ - fun onClickCalcDisance() { - + fun onClickCalcDistance() { + measuringToolOn() } /** 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 ca889bfa..84761c47 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.collect.library.utils.RealmDBParamUtils @@ -60,10 +56,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 @@ -175,6 +169,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 @@ -220,12 +225,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) + } } } } @@ -586,7 +595,6 @@ class MainViewModel @Inject constructor( * 点击我的位置,回到我的位置 */ fun onClickLocationButton() { - mapController.markerHandle.removeMarker("location") mapController.locationLayerHandler.animateToCurrentPosition() } @@ -1032,12 +1040,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 @@ -1058,6 +1066,46 @@ class MainViewModel @Inject constructor( 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() + } + } + fun click2Dor3D(){ viewModelScope.launch(Dispatchers.IO) { Log.e( 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..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 @@ -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) { - binding.taskLinkLength.text = "${it}米" + mapController.measureLayerHandler.measureValueLiveData.observe(viewLifecycleOwner) { + binding.taskLinkLength.text = "${it.valueString}${it.unit}" } - mapController.measureLayerHandler.tempLineDistanceLiveData.observe(viewLifecycleOwner) { - (activity as MainActivity).setHomeCenterText(it) + mapController.measureLayerHandler.tempMeasureValueLiveData.observe(viewLifecycleOwner) { + (activity as MainActivity).setHomeCenterText("${it.valueString}${it.unit}") } } @@ -111,6 +110,7 @@ class TaskLinkFragment : BaseFragment(), View.OnClickListener { * 显示地图准星 */ activity?.let { + (activity as MainActivity).measuringToolOff() (activity as MainActivity).setHomeCenterVisibility(View.VISIBLE) } } @@ -159,7 +159,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..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 @@ -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() } /** @@ -302,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/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 00000000..cf4775f5 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/measuring_tool_close.png differ 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 @@ + \ 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" /> - + 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" /> + + app:layout_constraintStart_toStartOf="parent" /> - + + android:orientation="horizontal" + android:padding="5dp"> + android:gravity="center" + android:minWidth="65dp" + android:text="0" + android:textColor="@color/white" + android:textSize="14sp" /> + android:text="米" + android:textColor="@color/blue" + android:textSize="12sp" /> + android:orientation="vertical" + android:paddingLeft="6dp" + android:paddingRight="6dp"> + android:orientation="vertical" + android:paddingLeft="6dp" + android:paddingRight="6dp"> @@ -81,8 +108,12 @@ @@ -100,20 +131,36 @@ + + \ 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 = 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() /** * 实际绘制的总长度 */ - val lineLengthLiveData = MutableLiveData(0.000) + val measureValueLiveData = MutableLiveData() + 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 = mPathLayer.points - if (editIndex < list.size) { - list.removeAt(editIndex) - val list2: MutableList = 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 = java.util.ArrayList(list) - list2.add(editIndex, geoPoint) - mPolygonLayer.setPoints(list2) - } - } - mPathLayerTemp.setStyle(newTempStyle) - val list: MutableList = java.util.ArrayList() - 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 = mPathLayer.points + list.removeAt(editIndex) + val list2: MutableList = 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 = java.util.ArrayList(mPolygonLayer.points) - if (points.size > 2) { - val list: MutableList = java.util.ArrayList() - points.add(points[0]) + if (type == MEASURE_TYPE.ANGLE && mPathLayer.points.size == 3) { + return + } + val points: List = mPathLayer.points + if (points.size > 2) { + val list = mutableListOf() + 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 = mPathLayer.points - if (points.size > 2) { - val list: MutableList = 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 = java.util.ArrayList(mPathLayer.getPoints()) + val list: MutableList = java.util.ArrayList(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 = java.util.ArrayList(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 = java.util.ArrayList(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 = 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 = 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): 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): 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): 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 = mutableListOf() - if (editIndex == 0 || editIndex == mPathMakers.size - 1) { - list.add(mPathMakers[editIndex].geoPoint) + val list = mutableListOf() + val tempList = mutableListOf() + //编辑起点 + 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 = 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/map/source/OMDBReferenceDataSource.java b/collect-library/src/main/java/com/navinfo/collect/library/map/source/OMDBReferenceDataSource.java index 3784e991..c1cd5783 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 @@ -57,7 +57,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 34c81ada..e604c0a3 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 @@ -55,7 +55,6 @@ public class OMDBTileDataSource implements ITileDataSource { } List 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() + "条数据 主"); 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 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 @@ #4E55AF #FFF6565D #F03736 + #8DEF08EB \ No newline at end of file