Format coordinates in a variety of common notations.
Use case
The coordinate formatter can format a map location in WGS84 in a number of common coordinate notations. Parsing one of these formats to a location is also supported. Formats include decimal degrees; degrees, minutes, seconds; Universal Transverse Mercator (UTM), and United States National Grid (USNG).
How to use the sample
Tap on the map to see a marker with the tapped location's coordinate formatted in 4 different ways. You can also put a coordinate string in any of these formats in the text field. Hit Enter and the coordinate string will be parsed to a map location which the marker will move to.
How it works
- Get or create a map
Point
with a spatial reference. - Use one of the static "to" methods on
CoordinateFormatter
such asCoordinateFormatter.toLatitudeLongitudeOrNull(point = newLocation, format = LatitudeLongitudeFormat.DecimalDegrees, decimalPlaces = 4)
to get the formatted string. - To go from a formatted string to a
Point
, use one of the "from" static methods likeCoordinateFormatter.fromUtmOrNull(coordinates = coordinateNotation, utmConversionMode = UtmConversionMode.LatitudeBandIndicators, spatialReference = null)
.
Relevant API
- CoordinateFormatter
- CoordinateFormatter.LatitudeLongitudeFormat
- CoordinateFormatter.UtmConversionMode
Additional information
This sample uses the GeoView-Compose Toolkit module to be able to implement a composable MapView.
Tags
convert, coordinate, decimal degrees, degree minutes seconds, format, geoview-compose, latitude, longitude, toolkit, USNG, UTM
Sample Code
/* Copyright 2023 Esri * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.esri.arcgismaps.sample.showcoordinatesinmultipleformats.components import android.app.Application import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.AndroidViewModel import com.arcgismaps.Color import com.arcgismaps.geometry.CoordinateFormatter import com.arcgismaps.geometry.LatitudeLongitudeFormat import com.arcgismaps.geometry.Point import com.arcgismaps.geometry.SpatialReference import com.arcgismaps.geometry.UtmConversionMode import com.arcgismaps.mapping.symbology.SimpleMarkerSymbol import com.arcgismaps.mapping.symbology.SimpleMarkerSymbolStyle import com.arcgismaps.mapping.view.Graphic import com.esri.arcgismaps.sample.sampleslib.components.MessageDialogViewModel class MapViewModel(application: Application) : AndroidViewModel(application) { var decimalDegrees by mutableStateOf("") private set var degreesMinutesSeconds by mutableStateOf("") private set var utm by mutableStateOf("") private set var usng by mutableStateOf("") private set // create a ViewModel to handle dialog interactions val messageDialogVM: MessageDialogViewModel = MessageDialogViewModel() // set up a graphic to indicate where the coordinates relate to, with an initial location val initialPoint = Point(0.0, 0.0, SpatialReference.wgs84()) val coordinateLocationGraphic = Graphic( geometry = initialPoint, symbol = SimpleMarkerSymbol( style = SimpleMarkerSymbolStyle.Cross, color = Color.fromRgba(255, 255, 0, 255), size = 20f ) ) /** * Uses CoordinateFormatter to update the UI with coordinate notation strings based on the * given [newLocation] point to convert to coordinate notations */ fun toCoordinateNotationFromPoint(newLocation: Point) { coordinateLocationGraphic.geometry = newLocation // use CoordinateFormatter to convert to Latitude Longitude, formatted as Decimal Degrees decimalDegrees = CoordinateFormatter.toLatitudeLongitudeOrNull( point = newLocation, format = LatitudeLongitudeFormat.DecimalDegrees, decimalPlaces = 4 ) ?: return messageDialogVM.showMessageDialog("Failed to convert from point DD coordinate") // use CoordinateFormatter to convert to Latitude Longitude, formatted as Degrees, Minutes, Seconds degreesMinutesSeconds = CoordinateFormatter.toLatitudeLongitudeOrNull( point = newLocation, format = LatitudeLongitudeFormat.DegreesMinutesSeconds, decimalPlaces = 4 ) ?: return messageDialogVM.showMessageDialog("Failed to convert from point DMS coordinate") // use CoordinateFormatter to convert to Universal Transverse Mercator, using latitudinal bands indicator utm = CoordinateFormatter.toUtmOrNull( point = newLocation, utmConversionMode = UtmConversionMode.LatitudeBandIndicators, addSpaces = true ) ?: return messageDialogVM.showMessageDialog("Failed to convert from point UTM coordinate") // use CoordinateFormatter to convert to United States National Grid (USNG) usng = CoordinateFormatter.toUsngOrNull( point = newLocation, precision = 4, addSpaces = true, ) ?: return messageDialogVM.showMessageDialog("Failed to convert from point USNG coordinate") } /** * Uses CoordinateFormatter to update the graphic in the map from the given [coordinateNotation] * string entered by the user. Also calls corresponding method to update all the remaining * [coordinateNotation] strings using the notation [notationType]. */ fun fromCoordinateNotationToPoint(notationType: NotationType, coordinateNotation: String) { // ignore empty input coordinate notation strings, do not update UI if (coordinateNotation.isEmpty()) return val convertedPoint: Point = when (notationType) { NotationType.DMS, NotationType.DD -> { // use CoordinateFormatter to parse Latitude Longitude - different numeric notations (Decimal Degrees; // Degrees, Minutes, Seconds; Degrees, Decimal Minutes) can all be passed to this same method CoordinateFormatter.fromLatitudeLongitudeOrNull( coordinates = coordinateNotation, spatialReference = null ) ?: return messageDialogVM.showMessageDialog("Failed to convert DMS/DD coordinate to point") } NotationType.UTM -> { // use CoordinateFormatter to parse UTM coordinates CoordinateFormatter.fromUtmOrNull( coordinates = coordinateNotation, utmConversionMode = UtmConversionMode.LatitudeBandIndicators, spatialReference = null ) ?: return messageDialogVM.showMessageDialog("Failed to convert UTM coordinate to point") } NotationType.USNG -> { // use CoordinateFormatter to parse US National Grid coordinates CoordinateFormatter.fromUsngOrNull( coordinates = coordinateNotation, spatialReference = null ) ?: return messageDialogVM.showMessageDialog("Failed to convert USNG coordinate to point") } } // update the location shown in the map toCoordinateNotationFromPoint(convertedPoint) } /** * Coordinate notations supported by this sample */ enum class NotationType { DMS, DD, UTM, USNG } /** * Set's [decimalDegrees] entered in the text field to the [inputString] */ fun setDecimalDegreesCoordinate(inputString: String) { decimalDegrees = inputString } /** * Set's [degreesMinutesSeconds] entered in the text field to the [inputString] */ fun degreesMinutesSecondsCoordinate(inputString: String) { degreesMinutesSeconds = inputString } /** * Set's [utm] entered in the text field to the [inputString] */ fun setUTMCoordinate(inputString: String) { utm = inputString } /** * Set's [usng] entered in the text field to the [inputString] */ fun setUSNGDegreesCoordinate(inputString: String) { usng = inputString } }