Optimized heights parsing
This commit is contained in:
parent
71f012dc6b
commit
c7b22f012b
2 changed files with 68 additions and 48 deletions
|
|
@ -88,30 +88,35 @@ class KhmParser {
|
||||||
dis.use {
|
dis.use {
|
||||||
val header = readHeader(dis)
|
val header = readHeader(dis)
|
||||||
|
|
||||||
val glist: Array<Pair<Pair<Float, Float>, Int>> = Array(coords.size) { i ->
|
val glist: MutableMap<Pair<Float, Float>, Int> = mutableMapOf()
|
||||||
val x = ((coords[i].first - header.minLon) / header.lonPerValue).toInt()
|
|
||||||
val y = ((coords[i].second - header.minLat) / header.latPerValue).toInt()
|
for (coord in coords) {
|
||||||
|
val x = ((coord.first - header.minLon) / header.lonPerValue).toInt()
|
||||||
|
val y = ((coord.second - header.minLat) / header.latPerValue).toInt()
|
||||||
val offset = getOffset(header, x, y)
|
val offset = getOffset(header, x, y)
|
||||||
Pair(coords[i], offset)
|
glist.put(coord, offset)
|
||||||
}
|
|
||||||
glist.sortBy {
|
|
||||||
it.second
|
|
||||||
}
|
}
|
||||||
|
val sortedGlist = glist.toList().sortedBy { (_, v) -> v }.toMap()
|
||||||
|
val glistKeys = sortedGlist.keys.toTypedArray()
|
||||||
|
|
||||||
coords.sortBy { oit ->
|
val cutOffsets = IntArray(glist.size) {-1}
|
||||||
glist.find { it.first == oit }!!.second
|
if (inBounds(header, coords[0].first, coords[0].second)) {
|
||||||
|
val key = glistKeys[0]
|
||||||
|
cutOffsets[0] = sortedGlist.getOrDefault(key, 0)
|
||||||
}
|
}
|
||||||
|
for (i in 1 until sortedGlist.size) {
|
||||||
val cutOffsets = IntArray(glist.size)
|
if (inBounds(header, coords[i].first, coords[i].second) && cutOffsets[i-1] >= 0) {
|
||||||
cutOffsets[0] = glist[0].second
|
val prevKey = glistKeys[i-1]
|
||||||
for (i in 1 until glist.size) {
|
val key = glistKeys[i]
|
||||||
cutOffsets[i] = glist[i].second - glist[i-1].second - 2
|
cutOffsets[i] = sortedGlist.getOrDefault(key, 0) - sortedGlist.getOrDefault(prevKey, 0) - 2
|
||||||
assert(cutOffsets[i] >= 0)
|
} else break
|
||||||
}
|
}
|
||||||
|
|
||||||
return Pair(UShortArray(coords.size) { i ->
|
return Pair(UShortArray(coords.size) { i ->
|
||||||
|
if (cutOffsets[i] > 0) {
|
||||||
dis.skipBytes(cutOffsets[i])
|
dis.skipBytes(cutOffsets[i])
|
||||||
dis.readUnsignedShort().toUShort()
|
dis.readUnsignedShort().toUShort()
|
||||||
|
} else 0u
|
||||||
}, coords)
|
}, coords)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import androidx.compose.foundation.gestures.detectDragGestures
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
@ -46,12 +48,21 @@ fun MapCanvas(
|
||||||
var pointRequested by rememberSaveable { viewModel.pointRequested }
|
var pointRequested by rememberSaveable { viewModel.pointRequested }
|
||||||
var pointLat by rememberSaveable { viewModel.rememberedPointLat }
|
var pointLat by rememberSaveable { viewModel.rememberedPointLat }
|
||||||
var pointLon by rememberSaveable { viewModel.rememberedPointLon }
|
var pointLon by rememberSaveable { viewModel.rememberedPointLon }
|
||||||
|
var invokeHeightCalc by remember { mutableStateOf(false) }
|
||||||
Canvas(
|
Canvas(
|
||||||
modifier = modifier.fillMaxSize()
|
modifier = modifier.fillMaxSize()
|
||||||
.pointerInput(Unit) {
|
.pointerInput(Unit) {
|
||||||
detectDragGestures { _, distance ->
|
detectDragGestures (
|
||||||
|
onDragEnd = {
|
||||||
|
invokeHeightCalc = true
|
||||||
|
},
|
||||||
|
onDragCancel = {
|
||||||
|
invokeHeightCalc = true
|
||||||
|
}
|
||||||
|
) { _, distance ->
|
||||||
offsetX -= distance.x
|
offsetX -= distance.x
|
||||||
offsetY -= distance.y
|
offsetY -= distance.y
|
||||||
|
invokeHeightCalc = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
|
@ -186,6 +197,7 @@ fun MapCanvas(
|
||||||
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)
|
||||||
drawText(
|
drawText(
|
||||||
textMeasurer = textMeasurer,
|
textMeasurer = textMeasurer,
|
||||||
text = buildAnnotatedString { withStyle(SpanStyle(color = Color.White)) {
|
text = buildAnnotatedString { withStyle(SpanStyle(color = Color.White)) {
|
||||||
|
|
@ -193,6 +205,7 @@ fun MapCanvas(
|
||||||
} },
|
} },
|
||||||
topLeft = Offset(pointOffsetX, pointOffsetY - 32)
|
topLeft = Offset(pointOffsetX, pointOffsetY - 32)
|
||||||
)
|
)
|
||||||
|
if (invokeHeightCalc) {
|
||||||
val latPV = KhmParser.getLatPerValue()
|
val latPV = KhmParser.getLatPerValue()
|
||||||
val lonPV = KhmParser.getLonPerValue()
|
val lonPV = KhmParser.getLonPerValue()
|
||||||
val valueDistance = sqrt(latPV.pow(2) + lonPV.pow(2))
|
val valueDistance = sqrt(latPV.pow(2) + lonPV.pow(2))
|
||||||
|
|
@ -206,12 +219,13 @@ fun MapCanvas(
|
||||||
}
|
}
|
||||||
val heightPair = KhmParser.getHeightsMul(ctx, array)
|
val heightPair = KhmParser.getHeightsMul(ctx, array)
|
||||||
val heights = heightPair.first
|
val heights = heightPair.first
|
||||||
val coords = heightPair.second
|
val coords = heightPair.second.reversed()
|
||||||
for (step in 0 until coords.size) {
|
for (step in 0 until coords.size) {
|
||||||
val stepLat = coords[step].second
|
val stepLat = coords[step].second
|
||||||
val stepLon = coords[step].first
|
val stepLon = coords[step].first
|
||||||
val stepOffsetX = SphereMercator.mercateLon(stepLon.toDouble(), level, -TILE_SIZE.toDouble()).toFloat() - offsetX
|
val stepOffsetX = SphereMercator.mercateLon(stepLon.toDouble(), level, -TILE_SIZE.toDouble()).toFloat() - offsetX
|
||||||
val stepOffsetY = SphereMercator.mercateLat(stepLat.toDouble(), level, -TILE_SIZE.toDouble()).toFloat() - offsetY
|
val stepOffsetY = SphereMercator.mercateLat(stepLat.toDouble(), level, -TILE_SIZE.toDouble()).toFloat() - offsetY
|
||||||
|
if (stepOffsetX >= 0 && stepOffsetY >= 0 && stepOffsetX < size.width && stepOffsetY < size.height)
|
||||||
drawRect(
|
drawRect(
|
||||||
color = if (heights[step] > startHeight) Color.Red else Color.Green,
|
color = if (heights[step] > startHeight) Color.Red else Color.Green,
|
||||||
size = Size(8F, 8F),
|
size = Size(8F, 8F),
|
||||||
|
|
@ -219,6 +233,7 @@ fun MapCanvas(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cursor path
|
// Cursor path
|
||||||
val path = Path()
|
val path = Path()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue