Mock and websocket - go to homepage
Mock and websocket logo

Mock and websocket

Android mock locations

All positions shared via Trimble Mobile Manager (TMM) share the same properties and are identical to the values shown in the TMM UI.

This means that shared positions are

  • in the geodetic datum as configured in TMM (via Settings –> target reference frame)
  • reduced to the bottom mount of the receiver

TMM also adds a set of additional meta data to location.extras while position sharing is enabled. Details on location extras can be found in the corresponding Google Android help.

Location extras

The following dictionary keys are added:

Key Data type Details
hdop float HDOP value
vdop float VDOP value
pdop float PDOP value
diffAge float Message age of any RTK message in seconds
diffStatus int Position solution status: 1=Autonomous, 2=DGPS, 4=Fixed, 5=Float
diffID int -1 if unknown, otherwise 4-digits ID
vrms float Vertical accuracy (RMS) in meters
hrms float Horizontal accuracy (RMS) in meters
receiverModel string Receiver model string
mockProvider string Trimble Mobile Manager
mslHeight double Height above mean sea level - so geoid height if geoid is available
undulation double Height difference between ellipsoid and geoid
utcTime float UTC time
satellites int Number of satellites that are used for the position solution
totalSatInView int Number of satellites in view, identical to satellitesView
satellitesView int Number of satellites in view
satellitesId int[] Array containing IDs of satellites in view. The number of elements in the array is indicated by the satellitesView data specified above.
satellitesElv int[] Array containing elevation angles of satellites in view expressed in degrees. The number of elements in the array is indicated by the satellitesView data specified above. Satellite elevations are stored in the same order as their IDs in the satellitesId array specified above.
satellitesAzm int[] Array containing azimuth angles of satellites in view expressed in degrees. The number of elements in the array is indicated by the satellitesView data specified above. Satellite azimuth angles are stored in the same order as their IDs in the satellitesId array specified above.
satellitesSnr int[] Array containing signal-to-noise ratio (SNR) values for the satellites in view. The number of elements in the array is indicated by the satellitesView data specified above. SNR values are stored in the same order as the corresponding satellite IDs in the satellitesId array specified above.
satellitesUse boolean[] Array of flags indicating if a particular satellite has been used in a position computation. The number of elements in the array is indicated by the satellitesView data specified above. The flags are stored in the same order as the corresponding satellite IDs in the satellitesId array specified above.
satellitesType int[] The system of the tracked satellite: GPS == 0; SBAS == 1; GLONASS == 2; OMNISTAR == 3; GALILEO == 4; BEIDOU == 5; QZSS == 6; IRNSS == 7
subscriptionType int The type of the currently used subscription: 0 == free; 1 == meter; 2 == submeter; 3 == decimeter; 4 == precision; 5 == precision on-demand; 100 == GNSS receiver

 

Consuming location extras

The following example shows how to use/ parse mock location extras.

Note that the class implements the ILocationListener interface - so the OnLocationChanged callback is part of this interface.

This snippet is part of the TPSDK Sample app and shows how to consume mock locations/ locations extras and transforms them back to the default TPSDK-SSI observation containers.

public void OnLocationChanged(Location location)
{
	var coordinates = new Coordinates(ToRadians(location.Longitude), ToRadians(location.Latitude), location.HasAltitude ? location.Altitude : 0.0);
	var gpsTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(location.Time);
	var numOfSatellites = location.Extras.ContainsKey("satellites") ? location.Extras.GetInt("satellites") : 0;

	var handler = NewPositioningObservations;
	if (handler != null)
	{
		var container = new ObservationContainer();
		try
		{
			switch (location.Extras.GetInt("diffStatus", 0))
			{
				case 2:
					container.Add(new SolutionTypeObservation(SolutionType.Differential));
					break;
				case 4:
					container.Add(new SolutionTypeObservation(SolutionType.RTKFixed));
					break;
				case 5:
					container.Add(new SolutionTypeObservation(SolutionType.RTKFloat));
					break;
				default:
					container.Add(new SolutionTypeObservation(SolutionType.Autonomous));
					break;
			}
		}
		catch
		{
			container.Add(new SolutionTypeObservation(SolutionType.Autonomous));
		}

		container.Add(new CoordinateObservation(coordinates));
		container.Add(new SatellitesObservation(numOfSatellites));
		container.Add(new GpsTimeObservation(gpsTime, 0));

		try
		{
			var hdop = location.Extras.GetFloat("hdop", float.NaN);
			var vdop = location.Extras.GetFloat("vdop", float.NaN);
			var pdop = location.Extras.GetFloat("pdop", float.NaN);
			if (!float.IsNaN(hdop) && !float.IsNaN(vdop) && !float.IsNaN(pdop))
				container.Add(new DilutionOfPrecisionObservation(hdop, vdop, pdop));
		}
		catch
		{}

		try
		{
			if (location.Extras.ContainsKey("diffAge"))
				container.Add(new CorrectionAgeObservation(TimeSpan.FromSeconds(location.Extras.GetFloat("diffAge"))));
		}
		catch
		{}

		handler(this, new PositioningObservationEventArgs(container));
	}
}