限制最小围栏范围:圆形最小半径:(50 m),矩形最小边长:(100 m × 100 m)

This commit is contained in:
yezhiqiu
2025-12-26 10:17:56 +08:00
parent efc47f5df7
commit 2bd26b81cb
9 changed files with 129 additions and 52 deletions

View File

@@ -479,10 +479,14 @@ class FencesAddActivity : BaseActivity<ActivityFencesAddBinding>(ActivityFencesA
mFencesMapCommon.refreshDistance()
}
override fun rectScaleClick() {
override fun rectScaleEndClick() {
mFencesMapCommon.refreshDistance()
}
override fun rectScalingClick() {
}
override fun rectStartDragClick() {
}

View File

@@ -786,7 +786,11 @@ open class AddAndEditFencesZoneBaseActivity :
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
}
override fun rectScaleClick() {
override fun rectScaleEndClick() {
// mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
}
override fun rectScalingClick() {
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
}
@@ -800,7 +804,7 @@ open class AddAndEditFencesZoneBaseActivity :
}
override fun circleScaleEndClick() {
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
// mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
}
override fun circleStartDragClick() {
@@ -808,7 +812,7 @@ open class AddAndEditFencesZoneBaseActivity :
}
override fun circleScalingClick() {
// mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
}
override fun circleEndDragClick() {
@@ -886,7 +890,7 @@ open class AddAndEditFencesZoneBaseActivity :
when (mFencesBean.fenceShapeType) {
ConstantInt.CircleShapeType -> {
mFencesBean.radius = Utils.roundOffToInt(distances[0].toDouble())
val r = Util.metricConvertUnits(distances[0].toFloat(), ConstantInt.Type3, 2)
val r = Util.metricConvertUnits(distances[1].toFloat(), ConstantInt.Type3, 2)
val radiusStr = Utils.roundOffToInt(r.toDouble()).toString() + mDistanceUnit
mViewBinding.fencesZoneCircleView.setShowDisDistance(radiusStr)
}
@@ -894,8 +898,8 @@ open class AddAndEditFencesZoneBaseActivity :
ConstantInt.RectangleShapeType -> {
mFencesBean.longDistance = Utils.roundOffToInt(distances[0].toDouble())
mFencesBean.shortDistance = Utils.roundOffToInt(distances[1].toDouble())
val l = Util.metricConvertUnits(distances[0].toFloat(), ConstantInt.Type3, 2)
val s = Util.metricConvertUnits(distances[1].toFloat(), ConstantInt.Type3, 2)
val l = Util.metricConvertUnits(distances[2].toFloat(), ConstantInt.Type3, 2)
val s = Util.metricConvertUnits(distances[3].toFloat(), ConstantInt.Type3, 2)
val longStr = Utils.roundOffToInt(l.toDouble()).toString() + mDistanceUnit
val shortStr = Utils.roundOffToInt(s.toDouble()).toString() + mDistanceUnit
mViewBinding.fencesZoneRectView.setShowDisDistance(longStr, shortStr)

View File

@@ -19,7 +19,7 @@ class AddNoGoZoneActivity : AddAndEditFencesZoneBaseActivity() {
fenceNameType = 6
}
super.initData()
mFencesMapCommon.setMapZoom(18f)
// mFencesMapCommon.setMapZoom(18f)
mViewBinding.apply {
noGoZoneInitData()
setFenceShape(ConstantInt.CircleShapeType)

View File

@@ -16,7 +16,7 @@ class AddSafeZoneActivity : AddAndEditFencesZoneBaseActivity() {
setTopBarTitle(R.string.txt_add_safe_zone)
mFencesBean = FencesBean()
super.initData()
mFencesMapCommon.setMapZoom(18f)
// mFencesMapCommon.setMapZoom(16f)
mViewBinding.apply {
setFenceShape(ConstantInt.CircleShapeType)
safeZoneInitData()

View File

@@ -6,7 +6,6 @@ import android.location.Location
import android.view.View
import androidx.core.view.isVisible
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.bean.FencesBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.ui.common.map.FencesAddEditMapCommon
@@ -72,28 +71,26 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
//现在围栏控件改成随地图移动,只需要执行一次
isCanExecuteCameraCallBack = false
mapOkAndDistancePointLatLng(500)
setScaleLimitDistance()
}
}
setOnCameraMoveListener {
mFencesBean.let {
resetFencesViewCentre(
LatLng(
it.latitudeCenter, it.longitudeCenter
)
)
resetFencesViewCentre(LatLng(it.latitudeCenter, it.longitudeCenter))
}
//监听地图放大缩小操作
if (isMapZoomReady && getGoogleMapZoom() != cameraPosition.zoom) {
setGoogleMapZoom(cameraPosition.zoom)
resetFencesViewSize()
setScaleLimitDistance()
}
}
setOnMapLongClickListener {
resetFencesViewCentre(it)
mapOkAndDistancePointLatLng(0)
// mapOkAndDistancePointLatLng(500)
}
}
@@ -114,7 +111,6 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
isMapZoomReady = true
restoreEditFences()
}, 500)
return
}
@@ -169,6 +165,37 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
}
}
/**
* 设置围栏最小可拖动距离
*/
private fun setScaleLimitDistance() {
mGoogleMap?.apply {
//假设取个离(100,100)x坐标100的点
var stepX: Int
var stepY: Int
//手机坐标点转换为经纬度
val centreLatLng = Point(100, 100).let {
stepX = it.x + 100
stepY = it.y
projection.fromScreenLocation(it)
}
val stepLatLng = projection.fromScreenLocation(Point(stepX, stepY))
val stepDistance = Util.measureLatLonDistance(
centreLatLng.latitude,
centreLatLng.longitude,
stepLatLng.latitude,
stepLatLng.longitude
)
//限制圆半径50m
val limitRadius = 100 / stepDistance * 50
//限制矩形边长100m
val limitSide = 100 / stepDistance * 100
LogUtil.e("setScaleLimitDistance,$stepDistance,$limitRadius,$limitSide,${cameraPosition.zoom}")
mFencesCircleView.mLimitRadius = limitRadius.toFloat()
mFencesRectView.mLimitSide = limitSide.toFloat()
}
}
private fun getLatLngAndCalDistance(): Array<String> {
// 经纬度转换为手机坐标点
// val x = mGoogleMap!!.projection.toScreenLocation(it).x
@@ -176,32 +203,26 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
return when (mFencesBean.fenceShapeType) {
ConstantInt.CircleShapeType -> {
var centrePointX = 0
var startPointX = 0
//手机坐标点转换为经纬度
val centreLatLng = mFencesCircleView.getCircleCentrePoint().let {
centrePointX = it.x
mGoogleMap!!.projection.fromScreenLocation(it)
}
val startLatLng = mFencesCircleView.getCircleLineStartPoint().let {
startPointX = it.x
mGoogleMap!!.projection.fromScreenLocation(it)
}
val endLatLng = mFencesCircleView.getCircleLineEndPoint()
.let { mGoogleMap!!.projection.fromScreenLocation(it) }
LogUtil.e("GoogleMap,setOnCameraIdleListener 监听回调")
LogUtil.e("startLatLng=$centreLatLng,endLatLng=$endLatLng")
// LogUtil.e("startLatLng=$centreLatLng,endLatLng=$endLatLng")
val distance = Util.measureLatLonDistance(
centreLatLng.latitude,
centreLatLng.longitude,
endLatLng.latitude,
endLatLng.longitude
)
// if (distance.toInt() < 50) {
// LogUtil.e("xxxxxxxxx$distance")
// mFencesCircleView.mLimitRadius = abs(centrePointX - startPointX).toFloat()
// return arrayOf("50")
// }
val distanceInt = distance.toInt()
val showDistance = getShowDistance(distanceInt)
LogUtil.e("getLatLngAndCalDistance,$distanceInt,$showDistance")
mFencesBean.apply {
latitudeCenter = centreLatLng.latitude
longitudeCenter = centreLatLng.longitude
@@ -211,8 +232,8 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
ancillaryOtherLongitude = startLatLng.longitude
}
arrayOf(
Utils.formatDecimal(distance, 2)
// distance.toInt().toString()
// Utils.formatDecimal(distance, 2)
distanceInt.toString(), showDistance.toString()
)
}
@@ -243,6 +264,10 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
rectCLatLng.latitude,
rectCLatLng.longitude
)
val widthDistance = rectWidthDistance.toInt()
val showWidthDistance = getShowDistance(widthDistance)
val heightDistance = rectHeightDistance.toInt()
val showHeightDistance = getShowDistance(heightDistance)
mFencesBean.apply {
latitudeCenter = centreLatLng.latitude
longitudeCenter = centreLatLng.longitude
@@ -257,8 +282,10 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
}
//长度和高度
arrayOf(
Utils.formatDecimal(rectWidthDistance, 2),
Utils.formatDecimal(rectHeightDistance, 2)
widthDistance.toString(),
heightDistance.toString(),
showWidthDistance.toString(),
showHeightDistance.toString()
)
}
@@ -311,21 +338,40 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
}
}
/**
* 获取ui显示的距离经过算法处理的
*/
private fun getShowDistance(distance: Int): Int {
val singleDigit = distance % 10
val integerDigit = distance / 10 * 10
return if (singleDigit > 4) integerDigit + 10
else integerDigit
}
/**
* 还原围栏
*/
private fun restoreEditFences() {
var arrayOfDistance = arrayOf("0")
setScaleLimitDistance()
mFencesBean.apply {
when (mFencesBean.fenceShapeType) {
ConstantInt.CircleShapeType -> {
restoreCircleFences()
arrayOfDistance = arrayOf("$radius")
val showDistance = getShowDistance(radius)
arrayOfDistance = arrayOf("$radius", "$showDistance")
}
ConstantInt.RectangleShapeType -> {
restoreRectFences()
arrayOfDistance = arrayOf("$longDistance", "$shortDistance")
val showWidthDistance = getShowDistance(longDistance)
val showHeightDistance = getShowDistance(shortDistance)
arrayOfDistance = arrayOf(
"$longDistance",
"$shortDistance",
"$showWidthDistance",
"$showHeightDistance"
)
}
ConstantInt.PolygonShapeType -> {

View File

@@ -14,7 +14,8 @@ interface OnCircleViewScaleClickListener {
interface OnRectViewRotateScaleClickListener {
fun rectRotateClick()
fun rectScaleClick()
fun rectScaleEndClick()
fun rectScalingClick()
fun rectStartDragClick()
fun rectEndDragClick()
}

View File

@@ -18,6 +18,7 @@ import com.abbidot.tracker.R
import com.abbidot.tracker.util.ImageUtil
import com.abbidot.tracker.util.ViewUtil
import com.qmuiteam.qmui.util.QMUIDisplayHelper
import kotlin.math.abs
/**
*Created by .yzq on 2022/1/22/022.
@@ -246,7 +247,7 @@ class FencesCircleView : View {
/**
* 设置默认的半径
*/
fun initDefaultRadius(dp: Int = 100) {
fun initDefaultRadius(dp: Int = 80) {
if (dp <= 0) return
setCircleRadius(dp)
}
@@ -339,6 +340,8 @@ class FencesCircleView : View {
if (isRefresh) invalidate()
}
private var mScalingX = 0f
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
@@ -370,12 +373,16 @@ class FencesCircleView : View {
val circleRadius = mMaxCircleRadius + transformX
//限制缩放不能太小
if (mLimitRadius == 0f && circleRadius < mLocationBitmap!!.height / 2f) {
// if (circleRadius < mLimitRadius || circleRadius < mLocationBitmap!!.height / 2f) {
return true
} else if (circleRadius < mLimitRadius) {
return true
}
mMaxCircleRadius = circleRadius
mOldX = x
mScaleClickListener?.circleScalingClick()
if (abs(x - mScalingX) > 1) {
mScalingX = x
mScaleClickListener?.circleScalingClick()
}
invalidate()
return true
} else if (isDrag) {

View File

@@ -2,7 +2,12 @@ package com.abbidot.tracker.widget
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.DashPathEffect
import android.graphics.Paint
import android.graphics.Point
import android.graphics.RectF
import android.text.TextUtils
import android.util.AttributeSet
import android.view.MotionEvent
@@ -86,6 +91,9 @@ class FencesRectView : View {
//是否需要测量防止百度地图使用会执行onMeasure/地图页面上下滑动重新布局执行onMeasure
private var isNeedMeasure = true
//限制边长
var mLimitSide = 0f
private var mRotateScaleClickListener: OnRectViewRotateScaleClickListener? = null
constructor(context: Context) : super(context) {
@@ -167,14 +175,14 @@ class FencesRectView : View {
rotate(mRotateAngle.toFloat())
startDraw(this)
restore()
// val a = getRectABCDXYPoint(FencesRectView.POINT_A)
// drawCircle(a[0], a[1], 50f, mTextPaint)
// val b = getRectABCDXYPoint(FencesRectView.POINT_B)
// drawCircle(b[0], b[1], 50f, mTextPaint)
// val c = getRectABCDXYPoint(FencesRectView.POINT_C)
// drawCircle(c[0], c[1], 50f, mTextPaint)
// val d = getRectABCDXYPoint(FencesRectView.POINT_D)
// drawCircle(d[0], d[1], 50f, mTextPaint)
// val a = getRectABCDXYPoint(FencesRectView.POINT_A)
// drawCircle(a[0], a[1], 50f, mTextPaint)
// val b = getRectABCDXYPoint(FencesRectView.POINT_B)
// drawCircle(b[0], b[1], 50f, mTextPaint)
// val c = getRectABCDXYPoint(FencesRectView.POINT_C)
// drawCircle(c[0], c[1], 50f, mTextPaint)
// val d = getRectABCDXYPoint(FencesRectView.POINT_D)
// drawCircle(d[0], d[1], 50f, mTextPaint)
}
}
@@ -296,7 +304,7 @@ class FencesRectView : View {
/**
* 设置默认长宽大小,初始化使用
*/
fun initDefaultWidthHeight(width: Int = 100, height: Int = 100) {
fun initDefaultWidthHeight(width: Int = 150, height: Int = 150) {
if (width <= 0 && height <= 0) return
mRectWidth = QMUIDisplayHelper.dpToPx(width).toFloat()
mRectHeight = QMUIDisplayHelper.dpToPx(height).toFloat()
@@ -479,12 +487,19 @@ class FencesRectView : View {
LogUtil.e("mRectWidth=$mRectWidth,mRectHeight=$mRectHeight,x - oldX=${x - mOldX},y - oldY=${y - mOldY}")
val transformX = x - mOldX
val transformY = y - mOldY
val newRectWidth = mRectWidth + transformX
val newRectHeight = mRectHeight + transformY
//限制缩放不能太小
if (mRectWidth + transformX < mLocationBitmap!!.height || mRectHeight + transformY < mLocationBitmap!!.height) {
if (mLimitSide == 0f) {
if (newRectWidth < mLocationBitmap!!.height || newRectHeight < mLocationBitmap!!.height) {
return true
}
} else if (newRectWidth < mLimitSide || newRectHeight < mLimitSide) {
return true
}
mRectWidth += transformX
mRectHeight += transformY
mRotateScaleClickListener?.rectScalingClick()
mRectWidth = newRectWidth
mRectHeight = newRectHeight
mOldX = x
mOldY = y
invalidate()
@@ -507,7 +522,7 @@ class FencesRectView : View {
isRotate = false
}
if (isScale) {
mRotateScaleClickListener?.rectScaleClick()
mRotateScaleClickListener?.rectScaleEndClick()
isScale = false
}
if (isDrag) {