Untitled
unknown
plain_text
9 months ago
31 kB
6
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 = formatMeasurementValue(areaValue, selectedUnit) // Update area text
} else {
val distanceValue = GeometryEngine.lengthGeodetic(
polyline,
getLinearUnit(selectedUnit),
GeodeticCurveType.Geodesic
)
distance = distanceValue
distanceText = 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 = 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): MutableState<String> {
var measureVal:String = String.format("%.2f", value)
var mutablemeasureVal = mutableStateOf(measureVal)
return mutablemeasureVal
// 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(originalArea, 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(value: Double, 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