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 callout 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 return and the coordinate string will be parsed to a map location which the callout will move to.
How it works
- Get or create a map point
AGSPoint
with a spatial reference. - To get the formatted string, use one of the static methods below.
class AGSCoordinateFormatter.latitudeLongitudeString(from:format:decimalPlaces:)
class AGSCoordinateFormatter.utmString(from:conversionMode:addSpaces:)
class AGSCoordinateFormatter.usngString(from:precision:addSpaces:)
- To get an
AGSPoint
from a formatted string, use one of the static methods below.class AGSCoordinateFormatter.point(fromLatitudeLongitudeString:spatialReference:)
class AGSCoordinateFormatter.point(fromUTMString:spatialReference:conversionMode:)
class AGSCoordinateFormatter.point(fromUSNGString:spatialReference:)
Relevant API
- AGSCoordinateFormatter
- AGSLatitudeLongitudeFormat
- AGSUTMConversionMode
Tags
convert, coordinate, decimal degrees, degree minutes seconds, format, latitude, longitude, USNG, UTM
Sample Code
// Copyright 2018 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.
import UIKit
import ArcGIS
class FormatCoordinatesTableViewController: UITableViewController {
@IBOutlet private var latLongDDTextField: UITextField?
@IBOutlet private var latLongDMSTextField: UITextField?
@IBOutlet private var utmTextField: UITextField?
@IBOutlet private var usngTextField: UITextField?
var changeHandler: ((AGSPoint) -> Void)?
var point: AGSPoint? {
didSet {
updateCoordinateFieldsForPoint()
}
}
override func viewDidLoad() {
super.viewDidLoad()
updateCoordinateFieldsForPoint()
}
// use AGSCoordinateFormatter to generate coordinate string for the given point
private func updateCoordinateFieldsForPoint() {
guard let point = point else {
return
}
latLongDDTextField?.text = AGSCoordinateFormatter.latitudeLongitudeString(from: point, format: .decimalDegrees, decimalPlaces: 4)
latLongDMSTextField?.text = AGSCoordinateFormatter.latitudeLongitudeString(from: point, format: .degreesMinutesSeconds, decimalPlaces: 1)
utmTextField?.text = AGSCoordinateFormatter.utmString(from: point, conversionMode: .latitudeBandIndicators, addSpaces: true)
usngTextField?.text = AGSCoordinateFormatter.usngString(from: point, precision: 4, addSpaces: true)
}
@IBAction func textFieldAction(_ sender: UITextField) {
guard let text = sender.text else {
return
}
let newPoint: AGSPoint? = {
switch sender {
case latLongDDTextField, latLongDMSTextField:
return AGSCoordinateFormatter.point(fromLatitudeLongitudeString: text, spatialReference: point?.spatialReference)
case utmTextField:
return AGSCoordinateFormatter.point(fromUTMString: text, spatialReference: point?.spatialReference, conversionMode: .latitudeBandIndicators)
case usngTextField:
return AGSCoordinateFormatter.point(fromUSNGString: text, spatialReference: point?.spatialReference)
default:
return nil
}
}()
if let newPoint = newPoint {
point = newPoint
// fire the handler
changeHandler?(newPoint)
} else {
// invalid input, reset the fields
updateCoordinateFieldsForPoint()
}
}
}
extension FormatCoordinatesTableViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}