Untitled
unknown
plain_text
12 days ago
31 kB
3
Indexable
class MainScreen { private lateinit var lifeCycleOwner: LifecycleOwner private val blueOutlineSymbol by lazy { SimpleLineSymbol(SimpleLineSymbolStyle.Solid, color = com.arcgismaps.Color.fromRgba(0, 0, 255, 255), 2f) } private val pointSymbol by lazy { SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Circle, color = com.arcgismaps.Color.fromRgba(255, 0, 0, 200), 15f).apply { // outline = blueOutlineSymbol } } private val lineSymbol by lazy { SimpleLineSymbol(SimpleLineSymbolStyle.Solid, color = com.arcgismaps.Color.fromRgba(0, 0, 0, 255), 3f) } private val polygonSymbol by lazy { SimpleFillSymbol(SimpleFillSymbolStyle.Solid, color = com.arcgismaps.Color.fromRgba(100, 0, 255, 100), blueOutlineSymbol) } private val graphicsOverlay by lazy { GraphicsOverlay() } private val graphicsStack = mutableListOf<List<Graphic>>() private val linePoints = mutableListOf<Point>() private val polygonPoints = mutableListOf<Point>() private val isMeasuring = mutableStateOf(false) private val showActionBar = mutableStateOf(false) var distance:Double = 0.0 var area:Double = 0.0 var originalArea: Double = 0.0 var originalDistanceUnit: String = "Meter" var originalAreaUnit: String = "Acre" var distanceText:MutableState<String> = mutableStateOf("0.0") var areaText:MutableState<String> = mutableStateOf("0.0") // var distanceTextState: MutableLiveData<String> = MutableLiveData() // commented by Ramya @SuppressLint("SuspiciousIndentation") @Composable fun MainScreenComposable() { val context = LocalContext.current val coroutineScope = rememberCoroutineScope() ArcGISEnvironment.applicationContext = context.applicationContext val mapType: MutableState<BasemapStyle> = remember { mutableStateOf(BasemapStyle.ArcGISTopographic) } lifeCycleOwner = LocalLifecycleOwner.current // Observe changes to the switchState LiveData // distanceTextState.observe( // lifeCycleOwner // ) { value -> // distanceTextState.value = value // } val locationDisplay = rememberLocationDisplay().apply { setAutoPanMode(LocationDisplayAutoPanMode.Recenter) } val map = remember(mapType.value) { ArcGISMap(mapType.value).apply { initialViewpoint = Viewpoint( latitude = 13.0236, longitude = 80.1780, scale = 72000.0 ) } } var cumulativeDistance by remember { mutableStateOf(0.0) } // var distanceText by remember { mutableStateOf(" ") } // var distance:Double =0.0 // var distance by remember { mutableStateOf(0.0) } // var area by remember { mutableStateOf(0.0) } // var distanceText by remember { mutableStateOf(" 0.0 Metre") } // var areaText by remember { mutableStateOf(" 0.0 Acre") } // Added state for area text var requestPermissions by remember { mutableStateOf(false) } var selectedGeometryType by remember { mutableStateOf("Distance") } var selectedUnit by remember { mutableStateOf("Meter") } var pointsDrawn by remember { mutableStateOf(false) } var isCalloutVisible by remember { mutableStateOf(true) } 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" } if (requestPermissions) { RequestPermissions( onPermissionGranted = { coroutineScope.launch { locationDisplay.setAutoPanMode(LocationDisplayAutoPanMode.Navigation) locationDisplay.dataSource.start() } } ) } Box(modifier = Modifier.fillMaxSize()) { val mapViewProxy = MapViewProxy() var calloutLocation by remember { mutableStateOf<Point?>(null) } MapView( modifier = Modifier.fillMaxSize(), mapViewProxy = mapViewProxy, arcGISMap = map, graphicsOverlays = listOf(graphicsOverlay), locationDisplay = locationDisplay, onSingleTapConfirmed = { screenCoordinate -> if (isMeasuring.value) { val mapPoint: Point? = mapViewProxy.screenToLocationOrNull(screenCoordinate.screenCoordinate) if (mapPoint != null) { pointsDrawn = true val mapPointNotNull: Point = mapPoint val mapPointProjected: Point? = GeometryEngine.projectOrNull( mapPointNotNull, SpatialReference.wgs84() ) val latitude = mapPointProjected?.y val longitude = mapPointProjected?.x calloutLocation = mapPointProjected Toast.makeText( context, "Map tapped at: Latitude: $latitude, Longitude: $longitude", Toast.LENGTH_SHORT ).show() val relatedGraphics = mutableListOf<Graphic>() 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 ) area = areaValue areaText.value = formatMeasurementValue(areaValue, selectedUnit) // Update area text } else { val distanceValue = GeometryEngine.lengthGeodetic( polyline, getLinearUnit(selectedUnit), GeodeticCurveType.Geodesic ) distance = distanceValue distanceText.value = formatMeasurementValue(distanceValue, selectedUnit) // Update area text // distanceTextState.postValue(distanceValue.toString()) } } } "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() distance = cumulativeDistance distanceText.value = formatMeasurementValue(cumulativeDistance, selectedUnit) // distanceTextState.value = distanceText.value TextSymbol().apply { text = distanceText.value 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") { "${areaText.value} ${originalAreaUnit}" } else { "${distanceText.value} ${originalDistanceUnit}" // distanceText.value } ) } } } ImageButtonWithSpinner(mapType, context) IconButton( onClick = { if (checkPermissions(context)) { coroutineScope.launch { locationDisplay.setAutoPanMode(LocationDisplayAutoPanMode.Navigation) locationDisplay.dataSource.start() } } else { requestPermissions = true } }, modifier = Modifier .align(Alignment.CenterEnd) .padding(end = 16.dp, top = 200.dp) ) { Image( painter = painterResource(R.mipmap.ic_location), contentDescription = "My Location" ) } IconButton( onClick = { showActionBar.value = true isMeasuring.value = true }, modifier = Modifier .align(Alignment.CenterEnd) .padding(end = 16.dp, top = 40.dp) ) { Image( painter = painterResource(R.mipmap.ic_measure), contentDescription = "Measure" ) } 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.value = " " // Reset distance text // distanceTextState.value = " " areaText.value = " " // Reset area text cumulativeDistance = 0.0 // Reset cumulative distance }, pointsDrawn = pointsDrawn ) } // Call setupMapClickListener here setupMapClickListener() } } 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 { var measureVal:String = String.format("%.2f", value) var mutablemeasureVal = mutableStateOf(measureVal) return mutablemeasureVal.value // return "$value $unit" } private fun clearGraphics() { graphicsOverlay.graphics.clear() graphicsStack.clear() // linePoints.clear() // polygonPoints.clear() } private fun undoLastGraphic() { if (graphicsStack.isNotEmpty()) { val lastGraphics = graphicsStack.removeAt(graphicsStack.size - 1) lastGraphics.forEach { graphic -> graphicsOverlay.graphics.remove(graphic) } } } @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 ) { var expanded by remember { mutableStateOf(false) } val units = if (selectedGeometryType == "Distance") distanceUnits else areaUnits Box( modifier = Modifier .fillMaxWidth() .padding(8.dp) .background(color = Color.DarkGray) ) { Row( modifier = Modifier.align(Alignment.CenterStart), verticalAlignment = Alignment.CenterVertically ) { IconButton(onClick = { onShowActionBarChange(false) onClearGraphics() isMeasuring.value = false }) { Image( painter = painterResource(R.mipmap.ic_backbutton), contentDescription = "Back" ) } } Row( modifier = Modifier.align(Alignment.CenterEnd), verticalAlignment = Alignment.CenterVertically ) { if (pointsDrawn) { IconButton(onClick = { undoLastGraphic() }) { Image( painter = painterResource(R.mipmap.ic_undo), contentDescription = "Undo" ) } IconButton(onClick = { onClearGraphics() linePoints.clear() polygonPoints.clear() }) { Image( painter = painterResource(R.mipmap.ic_delete), contentDescription = "Delete" ) } } IconButton(onClick = { expanded = true }) { Image( painter = painterResource(R.mipmap.ic_selection), contentDescription = "Settings" ) } DropdownMenu( expanded = expanded, onDismissRequest = { expanded = false }, modifier = Modifier.width(150.dp), ) { Column(modifier = Modifier.padding(1.dp)) { Text(text = "Select Geometry Type", color = Color.Blue) Row(verticalAlignment = Alignment.CenterVertically) { Checkbox( checked = selectedGeometryType == "Distance", onCheckedChange = { if (it) onGeometryTypeChange("Distance") } ) Text(text = "Distance") } Row(verticalAlignment = Alignment.CenterVertically) { Checkbox( checked = selectedGeometryType == "Area", onCheckedChange = { if (it) onGeometryTypeChange("Area") } ) Text(text = "Area") } 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(unit) } } } ) Text(text = unit, modifier = Modifier.padding(4.dp)) } } } } } } } private fun updateDistanceUnits(unit: String) { distance = when (unit) { "Meter" -> { if (originalDistanceUnit.equals("Kilometre")){ convertFromKiloMeterToMeter(distance) } else if (originalDistanceUnit.equals("Foot")){ convertFromFootToMeter(distance) } else { convertFromYardToMeter(distance) } } "Kilometre" -> { if (originalDistanceUnit.equals("Meter")){ convertFromMeterToKiloMeter(distance) } else if (originalDistanceUnit.equals("Foot")){ convertFromFootToKiloMeter(distance) } else { convertFromYardToKiloMeter(distance) } } "Foot" -> { if (originalDistanceUnit.equals("Meter")){ convertFromMeterToFeet(distance) } else if (originalDistanceUnit.equals("Kilometre")){ convertFromKilometerMeterToFeet(distance) } else { convertFromYardToFeet(distance) } } "Yard" -> { if (originalDistanceUnit.equals("Meter")){ convertFromMeterToYards(distance) } else if (originalDistanceUnit.equals("Kilometre")){ convertFromKilometerMeterToYards(distance) } else { convertFromFootToYard(distance) } } else -> distance } originalDistanceUnit = unit // distanceTextState.value = "%.2f" .format(distance) distanceText.value = "%.2f" .format(distance) } private fun convertFromMeterToKiloMeter(distance: Double):Double{ return distance / 1000 } private fun convertFromMeterToFeet(distance: Double): Double { return distance * 3.28084 } private fun convertFromMeterToYards(distance: Double): Double { return distance * 1.09361 } private fun convertFromKiloMeterToMeter(distance: Double):Double{ return distance * 1000 } private fun convertFromKilometerMeterToYards(distance: Double): Double { return convertFromKiloMeterToMeter(distance) * 1.09361 } private fun convertFromKilometerMeterToFeet(distance: Double): Double { return convertFromKiloMeterToMeter(distance) * 3.28084 } private fun convertFromFootToMeter(distance: Double): Double { return distance / 3.28084 } private fun convertFromFootToKiloMeter(distance: Double): Double { return convertFromFootToMeter(distance) / 1000 } private fun convertFromFootToYard(distance: Double): Double { return convertFromFootToMeter(distance) * 1.09361 } private fun convertFromYardToMeter(distance: Double): Double { return distance / 1.09361 } private fun convertFromYardToKiloMeter(distance: Double): Double { return convertFromYardToMeter(distance) / 1000 } private fun convertFromYardToFeet(distance: Double): Double { return convertFromYardToMeter(distance) * 3.28084 } private fun updateAreaUnits(unit: String) { area = when (unit) { "Acre" -> { if (originalAreaUnit.equals("Hectare")){ convertHectareToAcre(area) } else if (originalAreaUnit.equals("Square Meter")){ convertSquareMeterToAcre(area) } else if (originalAreaUnit.equals("Square Kilometer")){ convertSquareKilometerToAcre(area) } else{ convertSquareFootToAcre(area) } } "Hectare" -> { if (originalAreaUnit.equals("Acre")){ convertAcreToHectare(area) } else if (originalAreaUnit.equals("Square Meter")){ convertSquareMeterToHectare(area) } else if (originalAreaUnit.equals("Square Kilometer")){ convertSquareKilometerToHectare(area) } else{ convertSquareFootToHectare(area) } } "Square Meter" -> { if (originalAreaUnit.equals("Acre")){ convertAcreToSquareMeter(area) } else if (originalAreaUnit.equals("Square Meter")){ convertHectareToSquareMeter(area) } else if (originalAreaUnit.equals("Square Kilometer")){ convertSquareKilometerToSquareMeter(area) } else{ convertSquareFootToSquareMeter(area) } } "Square Kilometer" -> { if (originalAreaUnit.equals("Acre")){ convertAcreToSquareKilometer(area) } else if (originalAreaUnit.equals("Square Meter")){ convertHectareToSquareKilometer(area) } else if (originalAreaUnit.equals("Square Kilometer")){ convertSquareMeterToSquareKilometer(area) } else{ convertSquareFootToSquareKilometer(area) } } "Square Foot" -> { if (originalAreaUnit.equals("Acre")){ convertAcreToSquareFoot(area) } else if (originalAreaUnit.equals("Square Meter")){ convertHectareToSquareFoot(area) } else if (originalAreaUnit.equals("Square Kilometer")){ convertSquareMeterToSquareFoot(area) } else{ convertSquareKilometerToSquareFoot(area) } } else -> { area } } originalAreaUnit = unit // updateAreaText("$area $unit") areaText.value = "%.2f" .format(area) } private fun convertAcreToHectare(area: Double):Double{ return area * 0.404686 } private fun convertAcreToSquareMeter(area: Double):Double{ return area * 4046.86 // return convertAcreToSquareMeter(area) * 0.0001 } private fun convertAcreToSquareKilometer(area: Double):Double{ // return area * 0.004046 return convertAcreToSquareMeter(area) / 1_000_000 } private fun convertAcreToSquareFoot(area: Double):Double{ return area * 43560.038507 // return convertAcreToSquareMeter(area) * 10.7639 } private fun convertHectareToAcre(area: Double):Double{ return area * 2.471055 // return convertHectareToSquareMeter(area) * 0.000247105 } private fun convertHectareToSquareMeter(area: Double):Double{ return area * 10000.008840 // return area * 10_000 } private fun convertHectareToSquareKilometer(area: Double):Double{ // return area * 0.01 return convertHectareToSquareMeter(area) / 1_000_000 } private fun convertHectareToSquareFoot(area: Double):Double{ // return area * 107639.199320 return convertHectareToSquareMeter(area) * 10.7639 } private fun convertSquareMeterToAcre(area: Double): Double { return area * 0.000247105 } private fun convertSquareMeterToHectare(area: Double): Double { return area * 0.0001 } private fun convertSquareMeterToSquareKilometer(area: Double): Double { return area * 1e-6 } private fun convertSquareMeterToSquareFoot(area: Double): Double { return area * 10.7639 } private fun convertSquareKilometerToAcre(area: Double): Double { // return area * 247.105 return convertSquareKilometerToSquareMeter(area) * 0.000247105 } private fun convertSquareKilometerToHectare(area: Double): Double { // return area * 100.00008840000052146 return convertSquareKilometerToSquareMeter(area) * 0.0001 } private fun convertSquareKilometerToSquareMeter(area: Double): Double { return area * 1000000.8840000052005 } private fun convertSquareKilometerToSquareFoot(area: Double): Double { // return area * 10763919.932006586343 return convertSquareKilometerToSquareMeter(area) * 10.7639 } private fun convertSquareFootToAcre(area: Double): Double { // return area * 2.2957e-5 return convertSquareFootToSquareMeter(area) * 0.000247105 } private fun convertSquareFootToHectare(area: Double): Double { // return area * 9.2903e-6 return convertSquareFootToSquareMeter(area) * 0.0001 } private fun convertSquareFootToSquareMeter(area: Double): Double { return area * 0.092903 } private fun convertSquareFootToSquareKilometer(area: Double): Double { // return area * 9.2903e-8 return convertSquareFootToSquareMeter(area) / 1_000_000 }
Editor is loading...
Leave a Comment