限制最小围栏范围:圆形最小半径:(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

@@ -30,7 +30,7 @@ android {
targetSdkVersion 35 targetSdkVersion 35
versionCode 2101 versionCode 2101
// versionName "2.1.1" // versionName "2.1.1"
versionName "2.1.1-Beta12" versionName "2.1.1-Beta13"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,6 @@ import android.location.Location
import android.view.View import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.bean.FencesBean import com.abbidot.tracker.bean.FencesBean
import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.ui.common.map.FencesAddEditMapCommon import com.abbidot.tracker.ui.common.map.FencesAddEditMapCommon
@@ -72,28 +71,26 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
//现在围栏控件改成随地图移动,只需要执行一次 //现在围栏控件改成随地图移动,只需要执行一次
isCanExecuteCameraCallBack = false isCanExecuteCameraCallBack = false
mapOkAndDistancePointLatLng(500) mapOkAndDistancePointLatLng(500)
setScaleLimitDistance()
} }
} }
setOnCameraMoveListener { setOnCameraMoveListener {
mFencesBean.let { mFencesBean.let {
resetFencesViewCentre( resetFencesViewCentre(LatLng(it.latitudeCenter, it.longitudeCenter))
LatLng(
it.latitudeCenter, it.longitudeCenter
)
)
} }
//监听地图放大缩小操作 //监听地图放大缩小操作
if (isMapZoomReady && getGoogleMapZoom() != cameraPosition.zoom) { if (isMapZoomReady && getGoogleMapZoom() != cameraPosition.zoom) {
setGoogleMapZoom(cameraPosition.zoom) setGoogleMapZoom(cameraPosition.zoom)
resetFencesViewSize() resetFencesViewSize()
setScaleLimitDistance()
} }
} }
setOnMapLongClickListener { setOnMapLongClickListener {
resetFencesViewCentre(it) resetFencesViewCentre(it)
mapOkAndDistancePointLatLng(0) // mapOkAndDistancePointLatLng(500)
} }
} }
@@ -114,7 +111,6 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
isMapZoomReady = true isMapZoomReady = true
restoreEditFences() restoreEditFences()
}, 500) }, 500)
return 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> { private fun getLatLngAndCalDistance(): Array<String> {
// 经纬度转换为手机坐标点 // 经纬度转换为手机坐标点
// val x = mGoogleMap!!.projection.toScreenLocation(it).x // val x = mGoogleMap!!.projection.toScreenLocation(it).x
@@ -176,32 +203,26 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
return when (mFencesBean.fenceShapeType) { return when (mFencesBean.fenceShapeType) {
ConstantInt.CircleShapeType -> { ConstantInt.CircleShapeType -> {
var centrePointX = 0
var startPointX = 0
//手机坐标点转换为经纬度 //手机坐标点转换为经纬度
val centreLatLng = mFencesCircleView.getCircleCentrePoint().let { val centreLatLng = mFencesCircleView.getCircleCentrePoint().let {
centrePointX = it.x
mGoogleMap!!.projection.fromScreenLocation(it) mGoogleMap!!.projection.fromScreenLocation(it)
} }
val startLatLng = mFencesCircleView.getCircleLineStartPoint().let { val startLatLng = mFencesCircleView.getCircleLineStartPoint().let {
startPointX = it.x
mGoogleMap!!.projection.fromScreenLocation(it) mGoogleMap!!.projection.fromScreenLocation(it)
} }
val endLatLng = mFencesCircleView.getCircleLineEndPoint() val endLatLng = mFencesCircleView.getCircleLineEndPoint()
.let { mGoogleMap!!.projection.fromScreenLocation(it) } .let { mGoogleMap!!.projection.fromScreenLocation(it) }
LogUtil.e("GoogleMap,setOnCameraIdleListener 监听回调") LogUtil.e("GoogleMap,setOnCameraIdleListener 监听回调")
LogUtil.e("startLatLng=$centreLatLng,endLatLng=$endLatLng") // LogUtil.e("startLatLng=$centreLatLng,endLatLng=$endLatLng")
val distance = Util.measureLatLonDistance( val distance = Util.measureLatLonDistance(
centreLatLng.latitude, centreLatLng.latitude,
centreLatLng.longitude, centreLatLng.longitude,
endLatLng.latitude, endLatLng.latitude,
endLatLng.longitude endLatLng.longitude
) )
// if (distance.toInt() < 50) { val distanceInt = distance.toInt()
// LogUtil.e("xxxxxxxxx$distance") val showDistance = getShowDistance(distanceInt)
// mFencesCircleView.mLimitRadius = abs(centrePointX - startPointX).toFloat() LogUtil.e("getLatLngAndCalDistance,$distanceInt,$showDistance")
// return arrayOf("50")
// }
mFencesBean.apply { mFencesBean.apply {
latitudeCenter = centreLatLng.latitude latitudeCenter = centreLatLng.latitude
longitudeCenter = centreLatLng.longitude longitudeCenter = centreLatLng.longitude
@@ -211,8 +232,8 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
ancillaryOtherLongitude = startLatLng.longitude ancillaryOtherLongitude = startLatLng.longitude
} }
arrayOf( arrayOf(
Utils.formatDecimal(distance, 2) // Utils.formatDecimal(distance, 2)
// distance.toInt().toString() distanceInt.toString(), showDistance.toString()
) )
} }
@@ -243,6 +264,10 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
rectCLatLng.latitude, rectCLatLng.latitude,
rectCLatLng.longitude rectCLatLng.longitude
) )
val widthDistance = rectWidthDistance.toInt()
val showWidthDistance = getShowDistance(widthDistance)
val heightDistance = rectHeightDistance.toInt()
val showHeightDistance = getShowDistance(heightDistance)
mFencesBean.apply { mFencesBean.apply {
latitudeCenter = centreLatLng.latitude latitudeCenter = centreLatLng.latitude
longitudeCenter = centreLatLng.longitude longitudeCenter = centreLatLng.longitude
@@ -257,8 +282,10 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() {
} }
//长度和高度 //长度和高度
arrayOf( arrayOf(
Utils.formatDecimal(rectWidthDistance, 2), widthDistance.toString(),
Utils.formatDecimal(rectHeightDistance, 2) 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() { private fun restoreEditFences() {
var arrayOfDistance = arrayOf("0") var arrayOfDistance = arrayOf("0")
setScaleLimitDistance()
mFencesBean.apply { mFencesBean.apply {
when (mFencesBean.fenceShapeType) { when (mFencesBean.fenceShapeType) {
ConstantInt.CircleShapeType -> { ConstantInt.CircleShapeType -> {
restoreCircleFences() restoreCircleFences()
arrayOfDistance = arrayOf("$radius") val showDistance = getShowDistance(radius)
arrayOfDistance = arrayOf("$radius", "$showDistance")
} }
ConstantInt.RectangleShapeType -> { ConstantInt.RectangleShapeType -> {
restoreRectFences() restoreRectFences()
arrayOfDistance = arrayOf("$longDistance", "$shortDistance") val showWidthDistance = getShowDistance(longDistance)
val showHeightDistance = getShowDistance(shortDistance)
arrayOfDistance = arrayOf(
"$longDistance",
"$shortDistance",
"$showWidthDistance",
"$showHeightDistance"
)
} }
ConstantInt.PolygonShapeType -> { ConstantInt.PolygonShapeType -> {

View File

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

View File

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

View File

@@ -2,7 +2,12 @@ package com.abbidot.tracker.widget
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context 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.text.TextUtils
import android.util.AttributeSet import android.util.AttributeSet
import android.view.MotionEvent import android.view.MotionEvent
@@ -86,6 +91,9 @@ class FencesRectView : View {
//是否需要测量防止百度地图使用会执行onMeasure/地图页面上下滑动重新布局执行onMeasure //是否需要测量防止百度地图使用会执行onMeasure/地图页面上下滑动重新布局执行onMeasure
private var isNeedMeasure = true private var isNeedMeasure = true
//限制边长
var mLimitSide = 0f
private var mRotateScaleClickListener: OnRectViewRotateScaleClickListener? = null private var mRotateScaleClickListener: OnRectViewRotateScaleClickListener? = null
constructor(context: Context) : super(context) { constructor(context: Context) : super(context) {
@@ -167,14 +175,14 @@ class FencesRectView : View {
rotate(mRotateAngle.toFloat()) rotate(mRotateAngle.toFloat())
startDraw(this) startDraw(this)
restore() restore()
// val a = getRectABCDXYPoint(FencesRectView.POINT_A) // val a = getRectABCDXYPoint(FencesRectView.POINT_A)
// drawCircle(a[0], a[1], 50f, mTextPaint) // drawCircle(a[0], a[1], 50f, mTextPaint)
// val b = getRectABCDXYPoint(FencesRectView.POINT_B) // val b = getRectABCDXYPoint(FencesRectView.POINT_B)
// drawCircle(b[0], b[1], 50f, mTextPaint) // drawCircle(b[0], b[1], 50f, mTextPaint)
// val c = getRectABCDXYPoint(FencesRectView.POINT_C) // val c = getRectABCDXYPoint(FencesRectView.POINT_C)
// drawCircle(c[0], c[1], 50f, mTextPaint) // drawCircle(c[0], c[1], 50f, mTextPaint)
// val d = getRectABCDXYPoint(FencesRectView.POINT_D) // val d = getRectABCDXYPoint(FencesRectView.POINT_D)
// drawCircle(d[0], d[1], 50f, mTextPaint) // 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 if (width <= 0 && height <= 0) return
mRectWidth = QMUIDisplayHelper.dpToPx(width).toFloat() mRectWidth = QMUIDisplayHelper.dpToPx(width).toFloat()
mRectHeight = QMUIDisplayHelper.dpToPx(height).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}") LogUtil.e("mRectWidth=$mRectWidth,mRectHeight=$mRectHeight,x - oldX=${x - mOldX},y - oldY=${y - mOldY}")
val transformX = x - mOldX val transformX = x - mOldX
val transformY = y - mOldY 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 return true
} }
mRectWidth += transformX mRotateScaleClickListener?.rectScalingClick()
mRectHeight += transformY mRectWidth = newRectWidth
mRectHeight = newRectHeight
mOldX = x mOldX = x
mOldY = y mOldY = y
invalidate() invalidate()
@@ -507,7 +522,7 @@ class FencesRectView : View {
isRotate = false isRotate = false
} }
if (isScale) { if (isScale) {
mRotateScaleClickListener?.rectScaleClick() mRotateScaleClickListener?.rectScaleEndClick()
isScale = false isScale = false
} }
if (isDrag) { if (isDrag) {