distance to point measurer

This commit is contained in:
Alexey 2025-09-30 14:15:09 +03:00
commit 004b498ee9

View file

@ -18,6 +18,7 @@ import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ParagraphStyle import androidx.compose.ui.text.ParagraphStyle
import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
@ -25,11 +26,27 @@ import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle import androidx.compose.ui.text.withStyle
import kotlin.math.abs
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
import kotlin.math.floor import kotlin.math.floor
import kotlin.math.max
import kotlin.math.min
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.sqrt import kotlin.math.sqrt
fun distanceString(targetMeters: Int): AnnotatedString {
return buildAnnotatedString {
withStyle(ParagraphStyle(textAlign = TextAlign.Center)) {
withStyle(SpanStyle(color = Color.White)) {
val text = if (targetMeters >= 100000)
"${targetMeters / 1000}km"
else
"${targetMeters}m"
append(text)
}
}
}
}
@OptIn(ExperimentalUnsignedTypes::class) @OptIn(ExperimentalUnsignedTypes::class)
@Composable @Composable
fun MapCanvas( fun MapCanvas(
@ -189,6 +206,7 @@ fun MapCanvas(
} }
} }
} }
// Placed point and line to center // Placed point and line to center
if (pointLat != 0F) { if (pointLat != 0F) {
val pointOffsetX = SphereMercator.mercateLon(pointLon.toDouble(), level, -TILE_SIZE.toDouble()).toFloat() - offsetX val pointOffsetX = SphereMercator.mercateLon(pointLon.toDouble(), level, -TILE_SIZE.toDouble()).toFloat() - offsetX
@ -203,6 +221,8 @@ fun MapCanvas(
start = Offset(pointOffsetX, pointOffsetY), start = Offset(pointOffsetX, pointOffsetY),
end = Offset(halvedX, halvedY) end = Offset(halvedX, halvedY)
) )
val startHeight = KhmParser.getHeight(pointLon, pointLat, ctx) val startHeight = KhmParser.getHeight(pointLon, pointLat, ctx)
if (pointOffsetX >= 0 && pointOffsetY >= 0 && pointOffsetX < size.width && pointOffsetY < size.height) if (pointOffsetX >= 0 && pointOffsetY >= 0 && pointOffsetX < size.width && pointOffsetY < size.height)
drawText( drawText(
@ -241,6 +261,17 @@ fun MapCanvas(
) )
} }
} }
val lineLength = sqrt((pointOffsetX - halvedX).pow(2) + (pointOffsetY - halvedY).pow(2))
val lineMeters = (lineLength * SphereMercator.scaledMetersPerPixel(level + 1)).toInt()
drawText(
textMeasurer = textMeasurer,
text = distanceString(lineMeters),
size = Size(160F, 48F),
topLeft = Offset(
halvedX,
halvedY - 80F
)
)
} }
// Cursor path // Cursor path
@ -316,17 +347,7 @@ fun MapCanvas(
// Distance measurer text // Distance measurer text
drawText( drawText(
textMeasurer = textMeasurer, textMeasurer = textMeasurer,
text = buildAnnotatedString { text = distanceString(targetMeters),
withStyle(ParagraphStyle(textAlign = TextAlign.Center)) {
withStyle(SpanStyle(color = Color.White)) {
val text = if (targetMeters >= 100000)
"${targetMeters / 1000}km"
else
"${targetMeters}m"
append(text)
}
}
},
topLeft = Offset(targetPixels.toFloat() * 2F, measurerHeight), topLeft = Offset(targetPixels.toFloat() * 2F, measurerHeight),
size = Size(targetPixels.toFloat() * 2F, 48F) size = Size(targetPixels.toFloat() * 2F, 48F)
) )