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 a: GeodeticMapCoordinates,
|
||||||
override val b: GeodeticMapCoordinates,
|
override val b: GeodeticMapCoordinates,
|
||||||
) : Rectangle<Gmc> {
|
) : Rectangle<Gmc> {
|
||||||
|
override val center: GeodeticMapCoordinates
|
||||||
|
get() = GeodeticMapCoordinates.normalized(
|
||||||
|
(a.latitude + b.latitude) / 2,
|
||||||
|
(a.longitude + b.longitude) / 2
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
override fun contains(point: Gmc): Boolean =
|
override fun contains(point: Gmc): Boolean =
|
||||||
point.latitude.isBetween(a.latitude, b.latitude) && point.longitude.isBetween(a.longitude, b.longitude)
|
point.latitude.isBetween(a.latitude, b.latitude) && point.longitude.isBetween(a.longitude, b.longitude)
|
||||||
}
|
}
|
||||||
|
|
||||||
public val Rectangle<Gmc>.center: GeodeticMapCoordinates
|
|
||||||
get() = GeodeticMapCoordinates.normalized(
|
|
||||||
(a.latitude + b.latitude) / 2,
|
|
||||||
(a.longitude + b.longitude) / 2
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimum longitude
|
* Minimum longitude
|
||||||
*/
|
*/
|
||||||
|
@ -19,6 +19,8 @@ public interface Area<T : Any> {
|
|||||||
public interface Rectangle<T : Any> : Area<T> {
|
public interface Rectangle<T : Any> : Area<T> {
|
||||||
public val a: T
|
public val a: T
|
||||||
public val b: 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.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)
|
val offset = offsetTo(b, zoom)
|
||||||
return sqrt(offset.x.value * offset.x.value + offset.y.value * offset.y.value).dp
|
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 d12 = a.offsetTo(b, zoom)
|
||||||
val d01 = offsetTo(a, 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
|
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 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>
|
public fun withAttributes(modify: Attributes.() -> Attributes): Feature<T>
|
||||||
}
|
}
|
||||||
@ -136,15 +136,15 @@ public data class LineFeature<T : Any>(
|
|||||||
public val b: T,
|
public val b: T,
|
||||||
override val attributes: Attributes = Attributes.EMPTY,
|
override val attributes: Attributes = Attributes.EMPTY,
|
||||||
) : DomainFeature<T>, LineSegmentFeature<T> {
|
) : DomainFeature<T>, LineSegmentFeature<T> {
|
||||||
override fun getBoundingBox(zoom: Float): Rectangle<T> =
|
override fun getBoundingBox(zoom: Float): Rectangle<T> = space.Rectangle(a, b)
|
||||||
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) {
|
override fun contains(viewPoint: ViewPoint<T>): Boolean = with(space) {
|
||||||
viewPoint.focus in getBoundingBox(viewPoint.zoom) && viewPoint.focus.distanceToLine(
|
viewPoint.focus.distanceTo(center) <= length / 2 &&
|
||||||
a,
|
viewPoint.focus.distanceToLine(a, b, viewPoint.zoom).value <= clickRadius
|
||||||
b,
|
|
||||||
viewPoint.zoom
|
|
||||||
).value < clickRadius
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun withAttributes(modify: (Attributes) -> Attributes): Feature<T> = copy(attributes = modify(attributes))
|
override fun withAttributes(modify: (Attributes) -> Attributes): Feature<T> = copy(attributes = modify(attributes))
|
||||||
|
@ -36,4 +36,35 @@ public fun <T : Any> FeatureGroup<T>.draggableLine(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return drawLine()
|
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 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 {
|
// companion object {
|
||||||
// fun square(center: XY, height: Float, width: Float): XYRectangle = XYRectangle(
|
// fun square(center: XY, height: Float, width: Float): XYRectangle = XYRectangle(
|
||||||
// XY(center.x - width / 2, center.y + height / 2),
|
// 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>.width: Float get() = abs(a.x - b.x)
|
||||||
val Rectangle<XY>.height: Float get() = abs(a.y - b.y)
|
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>.leftTop: XY get() = XY(left, top)
|
||||||
public val Rectangle<XY>.rightBottom: XY get() = XY(right, bottom)
|
public val Rectangle<XY>.rightBottom: XY get() = XY(right, bottom)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user