2012-02-08 18 views
15

Estoy escribiendo un programa que espera un número de puntos lat/long y los convierto internamente en UTM para hacer algunos cálculos en metros.Determinación de la zona UTM (convertir) de longitud/latitud

El rango de los puntos lat/long es en sí mismo bastante pequeño, unos 200 mx 200 m. Se puede confiar en que casi siempre estarán dentro de una única zona UTM (a menos que tengas mala suerte y estés al otro lado de la frontera de una zona).

Sin embargo, la zona en la que se encuentran los lat/longs no está restringida. Un día, el programa podría correr para personas en Australia (y, ¡cuántas zonas se encuentran, incluso un solo estado, y cuánto dolor me ha causado ya ...), y otro día para la gente en México.

Mi pregunta es: ¿hay alguna manera de determinar en qué zona se encuentra un long/lat en particular para que pueda alimentarse a una biblioteca de conversión (actualmente uso proj4 y también el paquete R rgdal).

Mi idioma es R, pero la respuesta no tiene que ser - tal vez solo sea un simple cálculo, o tal vez pueda incrustar una llamada al sistema proj exectuable.

aplausos.

+0

http://stat.ethz.ch/R-manual/R-patched /library/base/html/timezones.html – aatrujillob

+0

Sugeriría mover esto a gis.stackexchange.com. – blindjesse

+0

@AndresT - eso es zonas horarias. Quiero zonas UTM. –

Respuesta

33

Editar: Para el código (no-R) que funcione para todos los zonas no polares en la tierra, ver here o here.


A no ser que se trata de datos de un par de áreas excepcionales (Svalbard and parts of Norway), este es un cálculo bastante simple que puede ser que también acaba de hacerlo usted mismo en R. Aquí es Wikipedia's description de cómo se relaciona con la longitud UTM Número de zona:

El sistema UTM divide la superficie de la Tierra entre 80 ° S y 84 ° de latitud norte en 60 zonas, cada una de 6 ° de longitud de ancho. La zona 1 cubre la longitud 180 ° a 174 ° W; la numeración de la zona aumenta hacia el este hasta la zona 60 que cubre la longitud 174 a 180 este.

Así, en el supuesto de que en los datos de la longitud al oeste de la Prime Meridian se codifican como que va desde -180 a 0 grados, aquí está una versión R-código de lo anterior:

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 

Esa expresión obviamente podría simplificarse un poco, pero creo que de esta forma la lógica subyacente a su construcción es más clara. El bit %% 60 está allí por si alguna de sus longitudes es mayor que 180 o menor que -180.

+0

Ajá, este fue el cálculo que busqué: paso años buscando en Google "cómo calcular la zona UTM a partir de la latitud/longitud" y ni siquiera pensé en consultar Wiki. ¡aclamaciones! –

+0

Sí, pasé por el mismo proceso no hace mucho tiempo. Me alegro de ser de ayuda. Por cierto, si vas a hacer mucho con los datos espaciales, el servicio de listas [R-sig-geo] (https://stat.ethz.ch/mailman/listinfo/r-sig-geo) es invaluable. Hace poco hice una pregunta allí, y obtuve ayuda inmediata del propio Roger Bivand, quien me dio una respuesta que nadie más que él y algunos miembros del R-core podrían haber brindado. ¡Aclamaciones! –

+0

@ToolmakerSteve - Gracias por la corrección sugerida (que fue rechazada incorrectamente por los editores de 3 de 5 SO que la revisaron). –

2

No sé r-código, pero supongo que el código PL/SQL le puede ayudar con las excepciones:

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; 
Cuestiones relacionadas