In this article we will explain the Spatial Reference object model and highlight what you need to know in order to build effective mobile applications that leverage the complexity of coordinate systems and the transformations between them.
Also find with this article a recent posting to the code gallery by Sabine Barrera that illustrates how to transform GPS positions from WGS84 into the spatial reference of a mobile service.
DISCLAIMER: This is not for the faint of heart and the discussion implies that you have good foundational knowledge on map projections in ArcGIS. Here is some very well written background information that you can read on the subject.
Mobile Spatial Reference
A Mobile Service is both a web service and a data source in ArcGIS Mobile. The Mobile Service is your gateway to a map document that was published with “mobile data access” capabilities and as a data source it contains the map data that you have requested and cached on the client as the edits you have made in the field.
When thinking about the mobile service, it is important to understand that the mobile service always references the “active” data frame in a map document. That data frame contains a set of map layers and has a spatial reference and precision associated with it. Note that since ArcMap supports “projection on the fly”, the spatial reference of the data frame may be different than the spatial reference of the map layer’s data source. The Mobile SDK operates in the spatial reference of the data frame.
Within the ArcGIS Mobile SDK you will find the classes necessary to access the spatial reference of the mobile service. Here is an object model diagram that illustrates the classes available:
The spatial reference class itself provides access to the string defining the coordinate system, the current geotransformation, and a collection of supported geotransformations as well. The spatial reference class supports the following projections at the 9.3.1 release: Lambert Conformal Conic, Transverse Mercator, Albers, Mercator, Double Stereographic, and Oblique Mercator. Note that spatial reference implementation for the Mobile SDK is the exact same spatial reference engine used inside of ArcGIS Engine/Desktop, however a subset of all projects are contained in the mobile engine for performance reasons.
The spatial reference class also contains methods to convert between WGS84 coordinates and the spatial reference of the mobile service. Most conventional GPS systems use WGS84 – hence the explicit methods for converting between WGS84. Please note that we are enhancing this functionality in the 9.4 release. More on this as we come closer to the release of 9.4.
The spatial reference itself is stored within the MapSchema.bin file that is located inside of the mobile cache directory. It is created when the mobile service is opened using MobileService.Open(). The map schema contains additional information about the map including the map name, full extent, initial extent, layers and their workspaces. It is important to note that the precision of the mobile cache is derived directly from the full extent property of the map. By default (in ArcMap) the full extent of the map is defined by unioning the extent of all layers in the map document. This can lead to coarse precision if your feature classes span a very large extent. You can constrain the full extent and increase precision of your cache by setting a custom full extent for the map.
If you plan to leverage GPS in your mobile application, you need to think about datum transformations!! Most GPS systems use WGS84, and as a result, the GPS components in ArcGIS Mobile assume WGS84. The map that you publish as a mobile service may not be. If it is not, and you do not apply a geotransformation when projecting the GPS positing on top of the mobile service, you will find that the location is NOT where it should be!!
If, however, you do set the coordinate system in the map document to WGS84 then no transformation need be applied. When no transformation is applied, the MobileService.SpatialReference will return “Direct” as the value for the geotransformation.
The Mobile SDK supports the following transformation methods: Direct, MolodenskyBadekas, MolodenskyAbridged, Molodensky, GeocentricTranslation, CoordinateFrame, PositionVector, LongitudeRotation and BursaWolf. Note that Grid or file-based methonds (NADCON/HARN and NTv2) are not supported.
Specifying the transformation in ArcMap
As mentioned above, if your map is not using WGS84, a datum transformation will be required to convert GPS positions from WGS84 into the datum of your map. For example, if the coordinate system of the map is GCS_Deutsches_Hauptdreicksnetz, the author of the map will need to specify a transformation that will convert from GCS_WGS_1984 into GCS_Deutsches_Hauptdreiecksnetz.
If none of the data sources in the map are in WGS84, you will need to add a datasource that is. This will enable the Transformations dialog in ArcMap so that you can easily set the transformation. When a source is added to the map, a geographic coordinate systems warning will appear. Click on the “Transformations…” button and select GCS_WGS_1984 in the “Convert from” list box and then choose a transformation. You can now remove the WGS84 layer from your data frame and save the map document – your transformation will still be available.
In the example above, DHDN_To_WGS_1984_3s was selected. For this map and published mobile service, the spatial reference will use this transformation to convert GPS positions to your coordinate system. The MobileService.SpatialReference.CurrentGeoTransformation will return “DHDN_To_WGS_1984_3x”. If you have not specified the transformation, it will return “Not Defined” and your GPS positions may be quite off.
Converting Data Sources to WGS84
If you want to project your data source from its existing datum to WGS84, you can use the Project Geoprocessing Tool that is located inside ArcToolbox under the Data Management Tools > Projections and Transformations > Feature.
Specifying the Transformation in your Mobile Application
If you need to specify the transformation in your mobile application, you can implement a Wgs84GeoTransformation. The code below shows how to implement a transformation from WGS84 into German Zone 4.
This transformation string will set the required parameters used. The geotransformation is shown in the WKT form first.
// 108206 GEOGTRAN["DHDN_To_WGS_1984_3x", GEOGCS["GCS_Deutsches_Hauptdreiecksnetz", DATUM["D_Deutsches_Hauptdreiecksnetz",
// SPHEROID["Bessel_1841",6377397.155,299.1528128]], PRIMEM["Greenwich",0.0], UNIT["Degree",0.0174532925199433]], GEOGCS["GCS_WGS_1984",
// DATUM["D_WGS_1984", SPHEROID["WGS_1984",6378137.0,298.257223563]], PRIMEM["Greenwich",0.0],
double parameters = new double;
parameters[Wgs84GeoTransformation.XTranslation] = 597.1;
parameters[Wgs84GeoTransformation.YTranslation] = 71.4;
parameters[Wgs84GeoTransformation.ZTranslation] = 412.1;
parameters[Wgs84GeoTransformation.XRotation] = 0.894;
parameters[Wgs84GeoTransformation.YRotation] = 0.068;
parameters[Wgs84GeoTransformation.ZRotation] = -1.563;
// ScaleTranslation or ScaleDifference
parameters[Wgs84GeoTransformation.ScaleTranslation] = 7.58;
// The following parameters are only use by the MolodenskyBadekas method
parameters[Wgs84GeoTransformation.XCenterRotation] = 0;
parameters[Wgs84GeoTransformation.YCenterRotation] = 0;
parameters[Wgs84GeoTransformation.ZCenterRotation] = 0;
// This Wgs84GeoTransformation constructor requires a spatial reference,
// the name of the new transformation, the transformation type, if the
// transformation is forward (from a coordinate system to WGS84) or backward
// and the transformation parameters
customGeotransformation = new Wgs84GeoTransformation(mobileService1.SpatialReference, “DHDN_To_WGS_1984_3x”, GeoTransformationType.PositionVector, false, parameters);
// Add the new transformation to the collection of GeoTransformations in the SpatialReference
// Set the current GeoTransformation Index to the be just added
mobileService1.SpatialReference.CurrentGeoTransformationIndex = mobileService1.SpatialReference.GeoTransformations.Count – 1;
Thanks to Sabine for contributing content for this posting. Our apologies for the length. We hope it helps your application development…