Fix line clickability region
This commit is contained in:
parent
7623e5f622
commit
8f489ea0f9
@ -18,17 +18,17 @@ internal data class GmcRectangle(
|
||||
override val a: GeodeticMapCoordinates,
|
||||
override val b: GeodeticMapCoordinates,
|
||||
) : Rectangle<Gmc> {
|
||||
|
||||
override fun contains(point: Gmc): Boolean =
|
||||
point.latitude.isBetween(a.latitude, b.latitude) && point.longitude.isBetween(a.longitude, b.longitude)
|
||||
}
|
||||
|
||||
public val Rectangle<Gmc>.center: GeodeticMapCoordinates
|
||||
override val center: GeodeticMapCoordinates
|
||||
get() = GeodeticMapCoordinates.normalized(
|
||||
(a.latitude + b.latitude) / 2,
|
||||
(a.longitude + b.longitude) / 2
|
||||
)
|
||||
|
||||
|
||||
override fun contains(point: Gmc): Boolean =
|
||||
point.latitude.isBetween(a.latitude, b.latitude) && point.longitude.isBetween(a.longitude, b.longitude)
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum longitude
|
||||
*/
|
||||
|
@ -19,6 +19,8 @@ public interface Area<T : Any> {
|
||||
public interface Rectangle<T : Any> : Area<T> {
|
||||
public val a: T
|
||||
public val b: T
|
||||
|
||||
public val center: T
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,12 +66,12 @@ public interface CoordinateSpace<T : Any> {
|
||||
|
||||
public fun T.offsetTo(b: T, zoom: Float): DpOffset
|
||||
|
||||
public fun T.distanceTo(b: T, zoom: Float): Dp {
|
||||
public fun T.distanceTo(b: T, zoom: Float = Float.MAX_VALUE): Dp {
|
||||
val offset = offsetTo(b, zoom)
|
||||
return sqrt(offset.x.value * offset.x.value + offset.y.value * offset.y.value).dp
|
||||
}
|
||||
|
||||
public fun T.distanceToLine(a: T, b: T, zoom: Float): Dp {
|
||||
public fun T.distanceToLine(a: T, b: T, zoom: Float = Float.MAX_VALUE): Dp {
|
||||
val d12 = a.offsetTo(b, zoom)
|
||||
val d01 = offsetTo(a, zoom)
|
||||
val distanceVale = abs(d12.x.value * d01.y.value - d12.y.value * d01.x.value) / a.distanceTo(b, zoom).value
|
||||
|
@ -29,7 +29,7 @@ public interface Feature<T : Any> {
|
||||
|
||||
public val attributes: Attributes
|
||||
|
||||
public fun getBoundingBox(zoom: Float): Rectangle<T>?
|
||||
public fun getBoundingBox(zoom: Float = Float.MAX_VALUE): Rectangle<T>?
|
||||
|
||||
public fun withAttributes(modify: Attributes.() -> Attributes): Feature<T>
|
||||
}
|
||||
@ -136,15 +136,15 @@ public data class LineFeature<T : Any>(
|
||||
public val b: T,
|
||||
override val attributes: Attributes = Attributes.EMPTY,
|
||||
) : DomainFeature<T>, LineSegmentFeature<T> {
|
||||
override fun getBoundingBox(zoom: Float): Rectangle<T> =
|
||||
space.Rectangle(a, b)
|
||||
override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(a, b)
|
||||
|
||||
val center: T by lazy { getBoundingBox().center }
|
||||
|
||||
val length: Dp by lazy { with(space) { a.distanceTo(b) } }
|
||||
|
||||
override fun contains(viewPoint: ViewPoint<T>): Boolean = with(space) {
|
||||
viewPoint.focus in getBoundingBox(viewPoint.zoom) && viewPoint.focus.distanceToLine(
|
||||
a,
|
||||
b,
|
||||
viewPoint.zoom
|
||||
).value < clickRadius
|
||||
viewPoint.focus.distanceTo(center) <= length / 2 &&
|
||||
viewPoint.focus.distanceToLine(a, b, viewPoint.zoom).value <= clickRadius
|
||||
}
|
||||
|
||||
override fun withAttributes(modify: (Attributes) -> Attributes): Feature<T> = copy(attributes = modify(attributes))
|
||||
|
@ -37,3 +37,34 @@ public fun <T : Any> FeatureGroup<T>.draggableLine(
|
||||
|
||||
return drawLine()
|
||||
}
|
||||
|
||||
public fun <T : Any> FeatureGroup<T>.draggableMultiLine(
|
||||
points: List<FeatureRef<T, MarkerFeature<T>>>,
|
||||
id: String? = null,
|
||||
): FeatureRef<T, MultiLineFeature<T>> {
|
||||
var polygonId: FeatureRef<T, MultiLineFeature<T>>? = null
|
||||
|
||||
fun drawLines(): FeatureRef<T, MultiLineFeature<T>> {
|
||||
val currentId = feature(
|
||||
polygonId?.id ?: id,
|
||||
MultiLineFeature(
|
||||
space,
|
||||
points.map { it.resolve().center },
|
||||
Attributes {
|
||||
ZAttribute(-10f)
|
||||
polygonId?.attributes?.let { from(it) }
|
||||
}
|
||||
)
|
||||
)
|
||||
polygonId = currentId
|
||||
return currentId
|
||||
}
|
||||
|
||||
points.forEach {
|
||||
it.draggable { _, _ ->
|
||||
drawLines()
|
||||
}
|
||||
}
|
||||
|
||||
return drawLines()
|
||||
}
|
@ -18,6 +18,8 @@ internal data class XYRectangle(
|
||||
|
||||
override fun contains(point: XY): Boolean = point.x in a.x..b.x && point.y in a.y..b.y
|
||||
|
||||
override val center get() = XY((a.x + b.x) / 2, (a.y + b.y) / 2)
|
||||
|
||||
// companion object {
|
||||
// fun square(center: XY, height: Float, width: Float): XYRectangle = XYRectangle(
|
||||
// XY(center.x - width / 2, center.y + height / 2),
|
||||
@ -35,8 +37,6 @@ val Rectangle<XY>.left get() = min(a.x, b.x)
|
||||
val Rectangle<XY>.width: Float get() = abs(a.x - b.x)
|
||||
val Rectangle<XY>.height: Float get() = abs(a.y - b.y)
|
||||
|
||||
val Rectangle<XY>.center get() = XY((a.x + b.x) / 2, (a.y + b.y) / 2)
|
||||
|
||||
public val Rectangle<XY>.leftTop: XY get() = XY(left, top)
|
||||
public val Rectangle<XY>.rightBottom: XY get() = XY(right, bottom)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user