Определение UTM зоны (для конвертации) по долготе / широте - PullRequest
18 голосов
/ 08 февраля 2012

Я пишу программу, которая ожидает несколько широт / длинных точек, и конвертирую их внутренне в UTM, чтобы выполнить некоторые вычисления в метрах.

Диапазон самих широт / длинных точекдовольно маленький - около 200 х 200 м.На них почти всегда можно положиться, что они находятся в пределах одной зоны UTM (если только вам не повезло и вы пересекаете границу зоны).

Однако зона, в которой находятся широты и долготы, не ограничена.Однажды программа может быть запущена для людей в Австралии (и, о, сколько зон находится даже в одном штате, и сколько боли это уже причинило мне ...), и еще один день для людей в Мексике.

Мой вопрос - есть ли способ определить, в какой зоне находится конкретный long / lat, чтобы он мог быть передан в библиотеку конвертации (в настоящее время я использую proj4, а также пакет R rgdal).

Мой язык - R, но ответ не должен быть - может быть, это просто простой расчет, или, может быть, я могу встроить системный вызов в proj exectuable.

веселит.

Ответы [ 2 ]

38 голосов
/ 08 февраля 2012

Редактировать: Для (не-R) кода, который работает для всех неполярных областей на земле, см. здесь или здесь .


Если вы не имеете дело с данными из нескольких исключительных областей ( Шпицберген и некоторые районы Норвегии ), это достаточно простой расчет, который вы также можете просто сделать самостоятельно в R. Вот это Описание Википедии того, как долгота связана с номером зоны UTM:

Система UTM делит поверхность Земли между 80 ° S и 84 ° N широты на 60 зон, каждая по 6 ° долготы по ширине. Зона 1 охватывает долготу от 180 ° до 174 ° W; Нумерация зон увеличивается на восток до зоны 60, которая охватывает долготу от 174 до 180 восточной долготы.

Итак, если предположить, что в ваших данных долготы к западу от простого меридиана закодированы как бегущие от -180 до 0 градусов, вот версия R-кода выше:

long2UTM <- function(long) {
    (floor((long + 180)/6) %% 60) + 1
}

# Trying it out for San Francisco, clearly in UTM Zone 10 
# in the figure in the Wikipedia article linked above
SFlong <- -122.4192
long2UTM(SFlong)
# [1] 10

Это выражение, очевидно, можно немного упростить, но я думаю, что в этой форме логика, лежащая в основе его построения, наиболее ясна. Бит %% 60 находится на всякий случай, если некоторые из ваших долгот больше 180 или меньше -180.

2 голосов
/ 13 сентября 2013

Я не знаю r-код, но я полагаю, что этот код PL / SQL может помочь вам с исключениями:

   UTMZone := Trunc((lon - Zone0WestMeridian) / d);
    --Special Cases for Norway & Svalbard
    CASE 
    WHEN (lat > 55) AND (UTMZone = 31) AND (lat < 64) AND (lon >  2) THEN UTMZone := 32;
    WHEN (lat > 71) AND (UTMZone = 32) AND (lon <  9) THEN UTMZone := 31;
    WHEN (lat > 71) AND (UTMZone = 32) AND (lon >  8) THEN UTMZone := 33;
    WHEN (lat > 71) AND (UTMZone = 34) AND (lon < 21) THEN UTMZone := 33;
    WHEN (lat > 71) AND (UTMZone = 34) AND (lon > 20) THEN UTMZone := 35; 
    WHEN (lat > 71) AND (UTMZone = 36) AND (lon < 33) THEN UTMZone := 35;
    WHEN (lat > 71) AND (UTMZone = 36) AND (lon > 32) THEN UTMZone := 37;
    ELSE UTMZone := UTMZone;  
    END CASE;
...