Files
icegps-geotools/android/src/main/java/com/icegps/geotools/DisplaySlopeResult.kt
2025-11-26 18:58:15 +08:00

144 lines
4.5 KiB
Kotlin

package com.icegps.geotools
import android.util.Log
import com.icegps.math.geometry.Vector2D
import com.icegps.geotools.ktx.toMapboxPoint
import com.mapbox.geojson.Feature
import com.mapbox.geojson.FeatureCollection
import com.mapbox.geojson.Polygon
import com.mapbox.maps.MapView
import com.mapbox.maps.Style
import com.mapbox.maps.extension.style.expressions.generated.Expression
import com.mapbox.maps.extension.style.layers.addLayer
import com.mapbox.maps.extension.style.layers.generated.FillLayer
import com.mapbox.maps.extension.style.layers.generated.LineLayer
import com.mapbox.maps.extension.style.sources.addSource
import com.mapbox.maps.extension.style.sources.generated.geoJsonSource
/**
* @author tabidachinokaze
* @date 2025/11/26
*/
/**
* 绘制斜坡设计结果
*/
fun MapView.displaySlopeResult(
originalGrid: GridModel,
slopeResult: SlopeResult,
sourceId: String = "slope-result",
layerId: String = "slope-layer",
palette: (Double?) -> String,
showDesignHeight: Boolean
) {
val elevationList = mutableListOf<Double>()
mapboxMap.getStyle { style ->
val features = mutableListOf<Feature>()
val designGrid = slopeResult.designSurface
// 对比测试,将绘制到原来图形的左边
// val minX = originalGrid.minX * 2 - originalGrid.maxX
val minX = originalGrid.minX
val maxY = originalGrid.maxY
val cellSize = originalGrid.cellSize
for (r in 0 until originalGrid.rows) {
for (c in 0 until originalGrid.cols) {
val originalElev = originalGrid.getValue(r, c) ?: continue
val designElev = designGrid.getValue(r, c) ?: continue
elevationList.add(designElev)
// 计算填挖高度
val heightDiff = designElev - originalElev
// 计算栅格边界
val x0 = minX + c * cellSize
val y0 = maxY - r * cellSize
val x1 = x0 + cellSize
val y1 = y0 - cellSize
// 1. 创建多边形要素(背景色)
val ring = listOf(
Vector2D(x0, y0),
Vector2D(x1, y0),
Vector2D(x1, y1),
Vector2D(x0, y1),
Vector2D(x0, y0)
).map { it.toMapboxPoint() }
val poly = Polygon.fromLngLats(listOf(ring))
val feature = Feature.fromGeometry(poly)
if (showDesignHeight) {
// 显示设计高度,测试坡向是否正确,和高度是否计算正确
feature.addStringProperty("color", palette(designElev))
} else {
// 显示高差
feature.addStringProperty("color", palette(heightDiff))
}
// 显示原始高度
// feature.addStringProperty("color", palette(originalElev))
features.add(feature)
}
}
Log.d("displayGridWithDirectionArrows", "对比区域的土方量计算: ${elevationList.sum()}, 平均值:${elevationList.average()}")
// 设置图层
setupEarthworkLayer(style, sourceId, layerId, features)
}
}
/**
* 完整的土方工程图层设置 - 修正版
*/
private fun setupEarthworkLayer(
style: Style,
sourceId: String,
layerId: String,
features: List<Feature>,
) {
// 创建数据源
val source = geoJsonSource(sourceId) {
featureCollection(FeatureCollection.fromFeatures(features))
}
// 清理旧图层
try {
style.removeStyleLayer(layerId)
} catch (_: Exception) {
}
try {
style.removeStyleLayer("$layerId-arrow")
} catch (_: Exception) {
}
try {
style.removeStyleLayer("$layerId-outline")
} catch (_: Exception) {
}
try {
style.removeStyleLayer("$layerId-text")
} catch (_: Exception) {
}
if (style.styleSourceExists(sourceId)) {
style.removeStyleSource(sourceId)
}
// 添加数据源
style.addSource(source)
// 主填充图层
val fillLayer = FillLayer(layerId, sourceId).apply {
fillColor(Expression.toColor(Expression.get("color")))
fillOpacity(0.7)
}
style.addLayer(fillLayer)
// 边框图层
val outlineLayer = LineLayer("$layerId-outline", sourceId).apply {
lineColor("#333333")
lineWidth(1.0)
lineOpacity(0.5)
}
style.addLayer(outlineLayer)
}