Хотя я придерживаюсь своего мнения, что Microsoft должна проявлять здравый смысл и гарантировать, что такие классы, как GeoCoordinate, являются сериализуемыми в DataContract, я нашел удобный обходной путь.Обычно, когда кто-то выполняет такую работу, он импортирует интерфейс для веб-службы BingRoute или аналогичный.
Очевидно, что все классы в них являются сериализуемыми, поэтому я преобразовал весь свой код для использования типа BingRoute.Location
вместо GeoCoordinate
, и проблема исчезла.Где необходимо, метод расширения ToGeoCoordinate()
делает преобразование достаточно незаметным, чтобы не было смысла для существующего кода.
public static GeoCoordinate ToGeoCoordinate(this BingRoute.Location loc)
{
return new GeoCoordinate(loc.Latitude, loc.Longitude, loc.Altitude);
}
Если вы воспользуетесь моим советом, то рано или поздно вы пропустите метод GeDoCoordinate GetDistanceTo ().Методы расширения здесь тоже ваши друзья.
Вы можете преобразовать обе точки в GeoCoordinate
и использовать встроенный метод, но это приведет к большому количеству временных объектов, и в какой-то момент ваше приложение захлебнется, пока сборщик мусора выполнит свою задачу.
Я добавил другой тип локации для хорошей меры.Обратите внимание, что код расстояния реализует Haversine, который является вычислением большого круга с рядом ограничений.Предостережение emptor.
public static double GetDistanceTo(this BingRoute.Location A, BingRoute.Location B)
{
return GetDistanceTo(A.Latitude, A.Longitude, B.Latitude, B.Longitude);
}
public static double GetDistanceTo(
this Microsoft.Phone.Controls.Maps.Platform.Location A,
Microsoft.Phone.Controls.Maps.Platform.Location B)
{
return GetDistanceTo(A.Latitude, A.Longitude, B.Latitude, B.Longitude);
}
static double toRad = Math.PI / 180D;
static double toDeg = 180D / Math.PI;
static double GetDistanceTo(double lat1, double lng1, double lat2, double lng2)
{
lat1 *= toRad;
lng1 *= toRad;
lat2 *= toRad;
lng2 *= toRad;
double sin_dLng_on2_squared = Math.Sin((lng2 - lng1) / 2);
sin_dLng_on2_squared *= sin_dLng_on2_squared;
double sin_dLat_on2_squared = Math.Sin((lat2 - lat1) / 2);
sin_dLat_on2_squared *= sin_dLat_on2_squared;
double a = sin_dLat_on2_squared + Math.Cos(lat1 * Math.Cos(lat2) * sin_dLng_on2_squared);
double c = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)));
return c * 6371000;
}
Также очень важно отметить, что чем больше вы сохраняете, тем медленнее запускается ваше приложение, потому что для создания объекта настроек при активации требуется больше времени.Поэтому лучше всего хранить здесь только простое состояние параметра и хранить как можно больше в изолированных файлах хранения.