diff --git a/maps-kt-compose/src/commonMain/kotlin/center/sciprog/maps/compose/GmcRectangle.kt b/maps-kt-compose/src/commonMain/kotlin/center/sciprog/maps/compose/GmcRectangle.kt index 5401340..a151db9 100644 --- a/maps-kt-compose/src/commonMain/kotlin/center/sciprog/maps/compose/GmcRectangle.kt +++ b/maps-kt-compose/src/commonMain/kotlin/center/sciprog/maps/compose/GmcRectangle.kt @@ -18,17 +18,17 @@ internal data class GmcRectangle( override val a: GeodeticMapCoordinates, override val b: GeodeticMapCoordinates, ) : Rectangle { + 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) } -public val Rectangle.center: GeodeticMapCoordinates - get() = GeodeticMapCoordinates.normalized( - (a.latitude + b.latitude) / 2, - (a.longitude + b.longitude) / 2 - ) - /** * Minimum longitude */ diff --git a/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/CoordinateSpace.kt b/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/CoordinateSpace.kt index 1775008..800b097 100644 --- a/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/CoordinateSpace.kt +++ b/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/CoordinateSpace.kt @@ -19,6 +19,8 @@ public interface Area { public interface Rectangle : Area { public val a: T public val b: T + + public val center: T } /** @@ -64,12 +66,12 @@ public interface CoordinateSpace { 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 diff --git a/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/Feature.kt b/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/Feature.kt index 372c992..5fc9bb4 100644 --- a/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/Feature.kt +++ b/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/Feature.kt @@ -29,7 +29,7 @@ public interface Feature { public val attributes: Attributes - public fun getBoundingBox(zoom: Float): Rectangle? + public fun getBoundingBox(zoom: Float = Float.MAX_VALUE): Rectangle? public fun withAttributes(modify: Attributes.() -> Attributes): Feature } @@ -136,15 +136,15 @@ public data class LineFeature( public val b: T, override val attributes: Attributes = Attributes.EMPTY, ) : DomainFeature, LineSegmentFeature { - override fun getBoundingBox(zoom: Float): Rectangle = - space.Rectangle(a, b) + override fun getBoundingBox(zoom: Float): Rectangle = 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): 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 = copy(attributes = modify(attributes)) diff --git a/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/compositeFeatures.kt b/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/compositeFeatures.kt index 8177114..a608a5d 100644 --- a/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/compositeFeatures.kt +++ b/maps-kt-features/src/commonMain/kotlin/center/sciprog/maps/features/compositeFeatures.kt @@ -36,4 +36,35 @@ public fun FeatureGroup.draggableLine( } return drawLine() +} + +public fun FeatureGroup.draggableMultiLine( + points: List>>, + id: String? = null, +): FeatureRef> { + var polygonId: FeatureRef>? = null + + fun drawLines(): FeatureRef> { + 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() } \ No newline at end of file diff --git a/maps-kt-scheme/src/commonMain/kotlin/center/sciprog/maps/scheme/XY.kt b/maps-kt-scheme/src/commonMain/kotlin/center/sciprog/maps/scheme/XY.kt index dd43640..298d60a 100644 --- a/maps-kt-scheme/src/commonMain/kotlin/center/sciprog/maps/scheme/XY.kt +++ b/maps-kt-scheme/src/commonMain/kotlin/center/sciprog/maps/scheme/XY.kt @@ -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.left get() = min(a.x, b.x) val Rectangle.width: Float get() = abs(a.x - b.x) val Rectangle.height: Float get() = abs(a.y - b.y) -val Rectangle.center get() = XY((a.x + b.x) / 2, (a.y + b.y) / 2) - public val Rectangle.leftTop: XY get() = XY(left, top) public val Rectangle.rightBottom: XY get() = XY(right, bottom)