Вычислить юго-западную и северо-восточную широту/долготу квадрата на X миль от центра широта/долгота

Я работаю над получением данных из Noaa API.

При разговоре с Noaa API вы можете получить список метеостанций в пределах квадрата. Они называют их «экстентами», и они представляют собой 2 набора широты и долготы. Нижняя левая широта/долгота и верхняя правая широта/долгота

Как подробно здесь:

http://www.ncdc.noaa.gov/cdo-web/webservices/v2#stations

Мне дали список широты и долготы для ряда городов в США, и я пытаюсь найти лучший способ разместить коробку.

Итак, мое первое предположение состояло бы в том, чтобы взять центральную широту/долготу, вычислить широту/долготу в 75 милях к западу, а затем определить широту/долготу точки в 75 милях к югу от этой точки.

В идеале я хотел бы иметь это как функцию С#.

У кого-нибудь есть идеи о том, как лучше всего закодировать это, пожалуйста?

Спасибо


person Trevor Daniel    schedule 14.05.2014    source источник


Ответы (1)


Ура! - нашел решение...

Сначала простой класс:

public class LatLonAlt
    {
        public double Latitude { get; set; }
        public double Longitude { get; set; }
        public double Altitude { get; set; }
    }

Затем функция для расчета новой позиции:

public static HelpersModel.LatLonAlt CalculateDerivedPosition(HelpersModel.LatLonAlt source, double range, double bearing)
    {
        double latA = Convert.ToDouble(source.Latitude) * (Math.PI / 180);
        double lonA = Convert.ToDouble(source.Longitude) * (Math.PI / 180);
        double angularDistance = range / 6371;
        double trueCourse = bearing * (Math.PI / 180);

        double lat = Math.Asin(
            Math.Sin(latA) * Math.Cos(angularDistance) +
            Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));

        double dlon = Math.Atan2(
            Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
            Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));

        double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

        HelpersModel.LatLonAlt results = new HelpersModel.LatLonAlt();
        results.Latitude = lat * (180 / Math.PI);
        results.Longitude = lon * (180 / Math.PI);
        results.Altitude = source.Altitude;

        return results;
    }

Тогда, и я знаю, что могу сделать это лучше... но пока это работает...

2 функции, которые обрабатывают нижний левый и верхний правый экстенты:

public static HelpersModel.LatLonAlt FindBottomLeftExtent(HelpersModel.LatLonAlt startpoint)
    {
        // first move left
        HelpersModel.LatLonAlt movedleft = CalculateDerivedPosition(startpoint, 72.42, 270);
        // move down
        HelpersModel.LatLonAlt moveddown = CalculateDerivedPosition(movedleft, 72.42, 180);

        return moveddown;
    }
    public static HelpersModel.LatLonAlt FindTopRightExtent(HelpersModel.LatLonAlt startpoint)
    {
        // first move right
        HelpersModel.LatLonAlt movedright = CalculateDerivedPosition(startpoint, 72.42, 90);
        // move up
        HelpersModel.LatLonAlt movedup = CalculateDerivedPosition(movedright, 72.42, 0);

        return movedup;
    }

ХТХ!

Трев

person Trevor Daniel    schedule 14.05.2014
comment
Поскольку вы повторяете определенные вычисления несколько раз, вам может оказаться полезным определить для них константы для ясности — например, замените Math.PI / 180 на DegreesToRadians. - person Adrian Wragg; 14.05.2014
comment
@AdrianWragg Я в деле! - person Trevor Daniel; 14.05.2014