Untitled
unknown
plain_text
9 months ago
13 kB
16
Indexable
var distance:Double = 0.0
var area:Double = 0.0
var originalArea: Double = 0.0
var distanceText by remember { mutableStateOf(" ") }
var areaText by remember { mutableStateOf(" ") }
val distanceUnits = mutableListOf("Meter", "Kilometre", "Foot", "Yard")
val areaUnits = listOf("Acre", "Hectare", "Square Meter", "Square Kilometer", "Square Foot")
if (selectedGeometryType == "Area" && selectedUnit !in areaUnits) {
selectedUnit = "Acre"
}
when (selectedGeometryType) {
"Area" -> {
val pointGraphic = Graphic(mapPoint, pointSymbol)
graphicsOverlay.graphics.add(pointGraphic)
relatedGraphics.add(pointGraphic)
polygonPoints.add(mapPointNotNull)
if (polygonPoints.size > 1) {
val polyline = Polyline(polygonPoints)
val lineGraphic = Graphic(polyline, lineSymbol)
graphicsOverlay.graphics.add(lineGraphic)
relatedGraphics.add(lineGraphic)
// Remove previous text symbols
graphicsOverlay.graphics.removeAll { it.symbol is TextSymbol }
if (polygonPoints.size > 2) {
val polygon = Polygon(polygonPoints)
val polygonGraphic = Graphic(polygon, polygonSymbol)
graphicsOverlay.graphics.add(polygonGraphic)
relatedGraphics.add(polygonGraphic)
val areaValue = GeometryEngine.areaGeodetic(
polygon,
getAreaUnit(selectedUnit),
GeodeticCurveType.Geodesic
)
areaText = formatMeasurementValue(areaValue, selectedUnit) // Update area text
} else {
val distanceValue = GeometryEngine.lengthGeodetic(
polyline,
getLinearUnit(selectedUnit),
GeodeticCurveType.Geodesic
)
distanceText = formatMeasurementValue(distanceValue, selectedUnit) // Update area text
}
}
}
"Distance" -> {
val pointGraphic = Graphic(mapPointNotNull, pointSymbol)
graphicsOverlay.graphics.add(pointGraphic)
relatedGraphics.add(pointGraphic)
linePoints.add(mapPointNotNull)
if (linePoints.size > 1) {
val polyline = Polyline(linePoints)
val lineGraphic = Graphic(polyline, lineSymbol)
graphicsOverlay.graphics.add(lineGraphic)
relatedGraphics.add(lineGraphic)
val distanceValue = GeometryEngine.lengthGeodetic(
polyline,
getLinearUnit(selectedUnit),
GeodeticCurveType.Geodesic
)
cumulativeDistance += distanceValue
}
// Remove previous text symbols
graphicsOverlay.graphics.removeAll { it.symbol is TextSymbol }
// Only add the text symbol at the last point
if (linePoints.size > 1) {
linePoints.last()
distanceText = formatMeasurementValue(cumulativeDistance, selectedUnit)
TextSymbol().apply {
text = distanceText as String
color = com.arcgismaps.Color.fromRgba(0, 0, 0, 255) // Black color
size = 15f
}
}
}
}
graphicsStack.add(relatedGraphics)
{
calloutLocation?.let { location ->
Callout(location = location, offset = Offset(0f, -50f)) {
Text(
text = if (selectedGeometryType == "Area") {
"$area $originalAreaUnit"
} else {
// "$distanceText $originalDistanceUnit"
"$distance $originalDistanceUnit"
}
)
}
}
if (showActionBar.value) {
CustomTopBar(
selectedGeometryType = selectedGeometryType,
onGeometryTypeChange = { selectedGeometryType = it },
selectedUnit = selectedUnit,
// onUnitChange = { selectedUnit = it },
onUnitChange = { unit ->
selectedUnit = unit
if (selectedGeometryType == "Distance") {
updateDistanceUnits(unit)
} else if (selectedGeometryType == "Area") {
updateAreaUnits(originalArea, unit)
}
},
distanceUnits = distanceUnits,
areaUnits = areaUnits,
onShowActionBarChange = { showActionBar.value = it },
onClearGraphics = {
clearGraphics()
linePoints.clear()
polygonPoints.clear()
calloutLocation = null // Reset callout location
distanceText = " " // Reset distance text
areaText = " " // Reset area text
cumulativeDistance = 0.0 // Reset cumulative distance
},
pointsDrawn = pointsDrawn
)
}
private fun getAreaUnit(unit: String): AreaUnit? {
return when (unit) {
"Square Meter" -> AreaUnit.squareMeters
"Square Kilometer" -> AreaUnit.squareKilometers
"Acre" -> AreaUnit(AreaUnitId.Acres)
"Hectare" -> AreaUnit(AreaUnitId.Hectares)
"Square Foot" -> AreaUnit.squareFeet
else -> null
}
}
private fun getLinearUnit(unit: String): LinearUnit? {
return when (unit) {
"Meter" -> LinearUnit.meters
"Kilometre" -> LinearUnit.kilometers
"Foot" -> LinearUnit.feet
"Yard" -> LinearUnit(LinearUnitId.Yards)
else -> null
}
}
private fun formatMeasurementValue(value: Double, unit: String): String {
// return String.format("%.2f %s", value, unit)
return "$value $unit"
}
@Composable
fun CustomTopBar(
selectedGeometryType: String,
onGeometryTypeChange: (String) -> Unit,
selectedUnit: String,
onUnitChange: (String) -> Unit,
distanceUnits: List<String>,
areaUnits: List<String>,
onShowActionBarChange: (Boolean) -> Unit,
onClearGraphics: () -> Unit,
pointsDrawn: Boolean
)Text(text = "Select Unit", color = Color.Blue)
units.forEach { unit ->
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = selectedUnit == unit,
onCheckedChange = {
if (it) {
onUnitChange(unit)
if (selectedGeometryType == "Distance") {
updateDistanceUnits(unit)
} else if (selectedGeometryType == "Area") {
updateAreaUnits(originalArea, unit)
}
}
}
)
Text(text = unit, modifier = Modifier.padding(4.dp))
}
}
}
}
}
}
}
private fun updateDistanceUnits(unit: String) {
val baseDistance = convertDistanceToBaseUnit(distance, originalDistanceUnit)
distance = when (unit) {
"Meter" -> convertToMeters(baseDistance)
"Kilometre" -> convertToKilometres(baseDistance)
"Foot" -> convertToFeet(baseDistance)
"Yard" -> convertToYards(baseDistance)
else -> baseDistance
}
originalDistanceUnit = unit
// Log.d(" tag", "updateDistanceUnits: " + originalDistanceUnit.toString())
}
private fun convertDistanceToBaseUnit(distance: Double, originalDistanceUnit: String): Double {
return when (originalDistanceUnit) {
"Meter" -> distance
"Kilometre" -> distance / 1000
"Foot" -> distance / 3.28084
"Yard" -> distance / 1.09361
else -> distance
}
}
private fun convertToMeters(distance: Double): Double {
return distance
}
private fun convertToKilometres(distance: Double): Double {
return distance / 1000
}
private fun convertToFeet(distance: Double): Double {
return distance * 3.28084
}
private fun convertToYards(distance: Double): Double {
return distance * 1.09361
}
private fun updateAreaUnits(value: Double, unit: String) {
val baseArea = convertAreaToBaseUnit(value, originalAreaUnit)
area = when (unit) {
"Acre" -> convertToAcres(baseArea)
"Hectare" -> convertToHectares(baseArea)
"Square Meter" -> convertToSquareMeters(baseArea)
"Square Kilometer" -> convertToSquareKilometers(baseArea)
"Square Foot" -> convertToSquareFeet(baseArea)
else -> baseArea
}
originalAreaUnit = unit
// updateAreaText("$area $unit")
}
private fun convertAreaToBaseUnit(value: Double, originalAreaUnit: String): Double {
return when (originalAreaUnit) {
"Square Meter" -> value
"Square Kilometer" -> value * 1_000_000
"Square Foot" -> value / 10.7639
"Acre" -> value / 0.000247105
"Hectare" -> value / 0.0001
else -> value
}
}
private fun convertToSquareMeters(area: Double): Double {
return area
}
private fun convertToSquareKilometers(area: Double): Double {
return area / 1_000_000
}
private fun convertToSquareFeet(area: Double): Double {
return area * 10.7639
}
private fun convertToHectares(area: Double): Double {
return area * 0.0001
}
private fun convertToAcres(area: Double): Double {
return area * 0.000247105
}
Editor is loading...
Leave a Comment