Pulling data from geopoint questions

11-02-2016 09:02 PM
Esri Notable Contributor
14 26 37.5K

[Last Updated February 23, 2019]

In a previous post, we explored how expressions in the calculation column of your XLSForm could be used to programmatically set values on a geopoint question. In this occasion, we will do the opposite. That is, we will describe how you can extract data out of a geopoint. Here are some good reasons why you may want to do this:

  • Store geopoint properties as attributes: Often times, keeping the X/Y coordinates of a point encoded in a geometry field is not ideal.  By pulling data out of a geopoint question you can store the X/Y coordinates in specific fields. You can also extract and store other values from your geopoint properties such as the elevation, speed or horizontal accuracy if present. Having all these values as attributes can help during QA/QC as well as data exchange processes.  Storing metadata about your locations is particularly important if you are  using an external GNSS receiver with Survey123, because all that metadata is critical to understand the quality of your data.
  • Build data validation rules: You can use geopoint properties in your form to create data validation rules in your form. For example, you can create a rule to warn users if a particular horizontal accuracy has not been reached, or if the location has been captured while the field user was traveling at an excessive speed.

What a geopoint is made of?

We all know that geopoint questions store location information, but what is really inside a geopoint value? At a minimum, unless a geopoint question is empty, you will always find the latitude and longitude of a location. Survey123 never works with projected coordinates: geopoint values are always in geographic coordinates using WGS84.  Now, you could potentially find much more than just a latitude/longitude pair within a geopoint value. The most common properties include:

Property NameDescriptionUnits
xLongitude, positive in eastern hemisphere, negative in western hemisphere

Decimal degrees


Latitude, positive in northern hemisphere, negative in southern hemisphere

Decimal degrees


Altitude, meters above sea level



Horizontal accuracy of the x and y coordinates


Vertical accuracy of the z coordinate

speedGround speed

Meters per second

verticalSpeedVertical speed

Meters per second


Direction of travel measured clockwise from north

Decimal degrees


Angle between magnetic and true north

Decimal degrees


Returns the category of the position source.  Unknown (0), User (1), System Location (2), External Device (3), and Network Device (4).


Returns the type of position fix the coordinate has. Potential results are NoFix (0), GPS (1), DifferentialGPS (2), PrecisePositioningService (3), RTKFixed (4), RTKFloat (5), Estimated (6), Manual (7), Simulator (8), and SBAS (9).

If a geopoint question contains all the properties above or a subset, depends on the following:

  • If the location is set by the end user by manually tapping on the map, then only the x an y properties will be populated. It is possible to also let the user type the elevation, which ultimately would populate the z property. 
  • If the location is set by the device, the number of properties with data will depend on the device and also on how that location was obtained.  The accuracy of the values found in each property is as well completely dependent on the device providing the location information to Survey123.

If relying on consumer devices to retrieve the location properties above, you should take values with a grain of salt. Your average iPad or Android smartphone could often give you a reasonable x,y and horizontal accuracy but everything else could or could not be trustworthy. In fact, many consumer devices do not even populate most of the properties above. I do not want to say consumer devices will give you useless geopoint  properties, but you should proceed with caution understanding through trial and error what devices and in what conditions will give you accurate information. 

By connecting Survey123 to an external GNSS receiver, not only you can significantly improve the location accuracy of your data, but also get many more properties associated with your geopoint values.  Here is a list of the most important properties you can get. The complete list is available in our help.

Property NameDescription
positionSourceInfo.deviceNameThe name of your external GNSS device


Indicates how your GNSS is connected to your device.  Unknown (-1), Bluetooth (0), Serial Port (1), and Bluetooth LE (2).
positionSourceInfo.antennaHeightThe user defined GNSS antenna height.
positionSourceInfo.altitudeTypeIndicates the selected altitude type: altitude above mean sea level (0) and height above ellipsoid (1).
geoidSeparationReturns the difference between the WGS-84 earth ellipsoid and mean sea level as reported by the GNSS receiver. This is also sometimes referred to as orthometric height.
accuracyTypeRMS (0) and DOP (1)
positionAccuracyReturns the mean radial spherical error. Encompasses both horizontal and vertical error.
differentialAgeReturns the age of the differential signal and correction used by the GNSS receiver to differentially correct the position.
referenceStationIdReturns the differential reference station ID (DSID) of the station used by the GPS receiver.
satellitesVisibleReturns the number of satellites visible at the time of location capture.
satellitesInUseReturns the number satellites being used to return the position data.

Reading geopoint properties using the pulldata function

All the geopoint properties described above can be extracted using the pulldata function. For example:

pulldata("@geopoint", ${location}, "horizontalAccuracy")

The "@geopoint" parameter  to the pulldata function indicates that values will be extracted from a geopoint value.

The second parameter indicates the question in your XLSForm that holds the actual geopoint value. You will want to make sure that the question you reference is actually of type geopoint.

The third and last parameter defines the geopoint property you want to extract. You will want to make sure the property name is included in the table above and make sure that you specify it with the proper capitalization: HorizontalAccuracy is not the same as horizontalAccuracy.

Learning by Example:

Here is a simple XLSForm that will extract the X,Y and horizontal accuracy of your geopoint and store these values as attributes. Using this technique, you have complete freedom as to which fields in your feature service will be  used to store the geopoint properties.  You use the Name column in the XLSForm to define which field will keep the data.

decimalLatitudeLatitudepulldata("@geopoint", ${location},"y")
decimalLongitudeLongitudepulldata("@geopoint", ${location},"x")
decimalHorAccMetersAccuracypulldata("@geopoint", ${location},"horizontalAccuracy")

Realistically, I would never store geopoint properties as illustrated in the example above. Mostly because I would not want end-users to get distracted with questions in the survey that get automatically populated with these properties. I would not want end-users to modify these calculated values either. 

A more  refined approach would be to set  the Type of question as hidden. In this way, the Latitude, Longitude and accuracy questions will not be shown in the form, but their information would still be sent to the feature service on submit. To ensure  the actual values are stored as numbers in the feature service, I would also set the esriFieldType column to esriFieldTypeDouble as shown here:

hiddenLatitudeLatitudepulldata("@geopoint", ${location},"y")esriFieldTypeDouble
hiddenLongitudeLongitudepulldata("@geopoint", ${location},"x")esriFieldTypeDouble
hiddenHorAccMetersAccuracypulldata("@geopoint", ${location},"horizontalAccuracy")esriFieldTypeDouble

When working with horizontal accuracy, you should also learn about the meaning of the accuracyThreshold column.

You can use very similar expressions in your constraints and relevant statements. In the next example, we will pop a message in case that the geopoint value was captured while moving faster than 0.2 meters per second.

calculatespeedSpeedpulldata("@geopoint", ${location},"speed")
noteDo not move while fixing location!0.2<number(${speed})

Like every time you use pulldata() it is best practice to use this function alone. This is why I broke down my last example into two separate questions: One calculate question to invoke pulldata() and a separate question where I compare the output of the pulldata function with a number.

In this blog post I simply wanted to introduce the use of the pulldata("@geopoint") function. With it, you can build expressions to persist location metadata as GIS attributes, but also to create powerful data validation rules in your smart forms.