in Backend/src/System.Device/Location/LocationProviderInternal.cs [347:454]
private void HandleLocationChangedEvent(ILocationReport locationReport)
{
const double KnotsToMetersPerSec = 463.0 / 900.0;
GeoCoordinate coordinate = GeoCoordinate.Unknown;
CivicAddress address = CivicAddress.Unknown;
//
// If we are listening for latlong reports and this is one,
// extract the coordinate properties
//
if (m_latLongStatus != ReportStatus.NotSupported)
{
ILatLongReport latLongReport = locationReport as ILatLongReport;
if (latLongReport != null)
{
double latitude, longitude, errorRadius, altitude, altitudeError;
if ((latLongReport.GetLatitude(out latitude) == 0) &&
(latLongReport.GetLongitude(out longitude) == 0))
{
latLongReport.GetErrorRadius(out errorRadius);
latLongReport.GetAltitude(out altitude);
latLongReport.GetAltitudeError(out altitudeError);
coordinate = new GeoCoordinate(latitude, longitude, errorRadius, altitude, altitudeError);
}
}
}
//
// Now see if there is civic address data in the report. We do this for both latlong and civic address
// reports to handle the case of one sensor providing both types of data. Only generate a report if
// countryRegion and at least one other string is present. For Win 7 a country string is always present
// because the native location provider API defaults to UserGeoID if no sensor provides one.
//
string countryRegion = GetStringProperty(locationReport, LocationPropertyKey.CountryRegion);
if (countryRegion != String.Empty)
{
string address1 = GetStringProperty(locationReport, LocationPropertyKey.AddressLine1);
string address2 = GetStringProperty(locationReport, LocationPropertyKey.AddressLine2);
string city = GetStringProperty(locationReport, LocationPropertyKey.City);
string postalCode = GetStringProperty(locationReport, LocationPropertyKey.PostalCode);
string stateProvince = GetStringProperty(locationReport, LocationPropertyKey.StateProvince);
if (address1 != String.Empty || address2 != String.Empty || city != String.Empty ||
postalCode != String.Empty || stateProvince != String.Empty)
{
address = new CivicAddress(address1, address2, String.Empty, city, countryRegion, String.Empty, postalCode, stateProvince);
}
}
//
// if we have either coordinate or civic address report data, continue the processing
//
if (coordinate != GeoCoordinate.Unknown || address != CivicAddress.Unknown)
{
double heading = GetDoubleProperty(locationReport, LocationPropertyKey.Heading);
double speed = GetDoubleProperty(locationReport, LocationPropertyKey.Speed) * KnotsToMetersPerSec;
DateTimeOffset timestamp = DateTimeOffset.Now;
SYSTEMTIME systime;
if (0 == locationReport.GetTimestamp(out systime))
{
timestamp = new DateTimeOffset(systime.wYear, systime.wMonth, systime.wDay, systime.wHour,
systime.wMinute, systime.wSecond, systime.wMilliseconds, TimeSpan.Zero);
}
GeoLocationStatus prevStatus = Status;
m_curLocation = new GeoLocation(coordinate, heading, speed, address, timestamp);
if (m_started)
{
//
// Send a location change event if we are reporting a ready status. Otherwise, set
// an event pending flag which will cause the event to be sent when the status
// does switch to ready.
//
if (GeoLocationStatus.Ready == Status)
{
//
// The reported status may have changed because of the received data. If it
// has then generate a status change event.
//
if (Status != prevStatus)
{
OnStatusChanged(new GeoLocationStatusChangedEventArgs(m_curStatus));
}
OnLocationChanged(new GeoLocationChangedEventArgs(m_curLocation));
}
else
{
m_eventPending = true;
}
}
else
{
//
// Fire Ready event when location is available in case Start() hasn't been called
//
if (GeoLocationStatus.Ready == m_curStatus)
{
OnStatusChanged(new GeoLocationStatusChangedEventArgs(m_curStatus));
}
}
}
}