Changed multiple heights parsing
This commit is contained in:
parent
470535cac8
commit
71f012dc6b
2 changed files with 50 additions and 6 deletions
|
|
@ -2,10 +2,12 @@ package com.mirenkov.ktheightmap
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import java.io.DataInput
|
||||||
import java.io.DataInputStream
|
import java.io.DataInputStream
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
import kotlin.math.sign
|
||||||
|
|
||||||
private data class HeightInfo(
|
private data class HeightInfo(
|
||||||
val minLon: Float,
|
val minLon: Float,
|
||||||
|
|
@ -20,6 +22,7 @@ class KhmParser {
|
||||||
companion object {
|
companion object {
|
||||||
private var header: HeightInfo? = null
|
private var header: HeightInfo? = null
|
||||||
const val HEIGHT_FILE: String = "height.khm"
|
const val HEIGHT_FILE: String = "height.khm"
|
||||||
|
|
||||||
fun load(filePath: String, ctx: Context) {
|
fun load(filePath: String, ctx: Context) {
|
||||||
if (ctx.getFileStreamPath(HEIGHT_FILE).exists()) {
|
if (ctx.getFileStreamPath(HEIGHT_FILE).exists()) {
|
||||||
return
|
return
|
||||||
|
|
@ -77,6 +80,42 @@ class KhmParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalUnsignedTypes::class)
|
||||||
|
fun getHeightsMul(ctx: Context, coords: Array<Pair<Float, Float>>): Pair<UShortArray, Array<Pair<Float, Float>>> {
|
||||||
|
if (coords.isEmpty()) return Pair(ushortArrayOf(), coords)
|
||||||
|
val dis = DataInputStream(ctx.openFileInput(HEIGHT_FILE))
|
||||||
|
dis.use {
|
||||||
|
val header = readHeader(dis)
|
||||||
|
|
||||||
|
val glist: Array<Pair<Pair<Float, Float>, Int>> = Array(coords.size) { i ->
|
||||||
|
val x = ((coords[i].first - header.minLon) / header.lonPerValue).toInt()
|
||||||
|
val y = ((coords[i].second - header.minLat) / header.latPerValue).toInt()
|
||||||
|
val offset = getOffset(header, x, y)
|
||||||
|
Pair(coords[i], offset)
|
||||||
|
}
|
||||||
|
glist.sortBy {
|
||||||
|
it.second
|
||||||
|
}
|
||||||
|
|
||||||
|
coords.sortBy { oit ->
|
||||||
|
glist.find { it.first == oit }!!.second
|
||||||
|
}
|
||||||
|
|
||||||
|
val cutOffsets = IntArray(glist.size)
|
||||||
|
cutOffsets[0] = glist[0].second
|
||||||
|
for (i in 1 until glist.size) {
|
||||||
|
cutOffsets[i] = glist[i].second - glist[i-1].second - 2
|
||||||
|
assert(cutOffsets[i] >= 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pair(UShortArray(coords.size) { i ->
|
||||||
|
dis.skipBytes(cutOffsets[i])
|
||||||
|
dis.readUnsignedShort().toUShort()
|
||||||
|
}, coords)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getLonPerValue(): Float {
|
fun getLonPerValue(): Float {
|
||||||
return header?.lonPerValue ?: 0F
|
return header?.lonPerValue ?: 0F
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,11 @@ 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.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.ceil
|
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
@OptIn(ExperimentalUnsignedTypes::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun MapCanvas(
|
fun MapCanvas(
|
||||||
viewModel: TileViewModel,
|
viewModel: TileViewModel,
|
||||||
|
|
@ -200,15 +200,20 @@ fun MapCanvas(
|
||||||
val lonDiff = lon - pointLon
|
val lonDiff = lon - pointLon
|
||||||
val distance = sqrt((latDiff).pow(2) + (lonDiff).pow(2))
|
val distance = sqrt((latDiff).pow(2) + (lonDiff).pow(2))
|
||||||
val valuesCount = floor(distance / valueDistance).toInt()
|
val valuesCount = floor(distance / valueDistance).toInt()
|
||||||
for (step in 0 .. valuesCount) {
|
val array: Array<Pair<Float, Float>> = Array(valuesCount) { step ->
|
||||||
val interCoef = 1F - step.toFloat() / valuesCount
|
val interCoef = 1F - step.toFloat() / valuesCount
|
||||||
val stepLat = lat - latDiff * interCoef
|
Pair(lon - lonDiff * interCoef, lat - latDiff * interCoef)
|
||||||
val stepLon = lon - lonDiff * interCoef
|
}
|
||||||
|
val heightPair = KhmParser.getHeightsMul(ctx, array)
|
||||||
|
val heights = heightPair.first
|
||||||
|
val coords = heightPair.second
|
||||||
|
for (step in 0 until coords.size) {
|
||||||
|
val stepLat = coords[step].second
|
||||||
|
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
|
||||||
val height = KhmParser.getHeight(stepLon, stepLat, ctx)
|
|
||||||
drawRect(
|
drawRect(
|
||||||
color = if (height > startHeight) Color.Red else Color.Green,
|
color = if (heights[step] > startHeight) Color.Red else Color.Green,
|
||||||
size = Size(8F, 8F),
|
size = Size(8F, 8F),
|
||||||
topLeft = Offset(stepOffsetX - 4, stepOffsetY - 4)
|
topLeft = Offset(stepOffsetX - 4, stepOffsetY - 4)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue