Inicio > Programación > Funciones geodésicas en VB6

Funciones geodésicas en VB6

Martes, 14 octubre 2008 Deja un comentario Go to comments

Hola,

os dejo unas funciones en Visual Basic 6 para cálculos geodésicos que espero os sean útiles.

Para las conversiones UTM-Decimal se emplean las ecuaciones de Coticchia-Surace. Teneis más información sobre su implementación en la web de Gabriel Ortiz


Option Explicit

'This software is free software; you can redistribute it and/or modify it under the terms of
'the GNU General Public License as published by the Free Software Foundation; either version 2
'of the License, or (at your option) any later version.
'
'This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
'without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
'See the GNU General Public License for more details.

'Copyright (C) 2006 Carlos Francisco Andión López candion@gmail.com

'**********************************************************************************
' Módulo de diversas funciones geodésicas
'**********************************************************************************

Const pi As Double = 3.14159265358979
Const e As Double = 2.71828182845905

'**********************************************************************************
' Funcion que convierte grados decimales en sexagesimales
'**********************************************************************************
Function DecToSex(ByVal Decimalgrad As Double) As String

    Dim grados As Double
    Dim minutos As Double
    Dim segundos As Double
    Dim tmp As Double

    tmp = Decimalgrad

    If Decimalgrad < 0 Then
        Decimalgrad = -Decimalgrad
    End If

    grados = Int(Decimalgrad)
    minutos = Int((Decimalgrad - grados) * 60)
    segundos = Left(((Decimalgrad - grados) * 60 - minutos) * 60, 10)

      If tmp < 0 Then
        DecToSex = "-" & grados & "º " & minutos & "´" & segundos
            Else
            DecToSex = grados & "º " & minutos & "´" & segundos
    End If

End Function

'**********************************************************************************
' Funcion que convierte grados sexagesimales en decimales
'**********************************************************************************
Function SexToDec(ByVal grados As Integer, ByVal minutos As Double, ByVal segundos As Double) As Double

    SexToDec = grados + minutos / 60 + segundos / 3600

End Function

'**********************************************************************************
' Funcion que convierte coordenadas UTM a Decimal
' Emplea las ecuaciones de Coticchia-Surace empleando el elipsoide de Hayford o internacional 1924
' Devuelve un array con las coordenadas (latitud,longitud)
'**********************************************************************************

Public Function Utm2Dec(ByVal X As Double, ByVal y As Double, ByVal zone As String, ByVal Hemisf As String) As Double()

    Dim SMayor As Double
    Dim SMenor As Double
    Dim Ex As Double
    Dim Ex2 As Double
    Dim Ex2c As Double
    Dim Rc As Double
    Dim Apl As Double
    Dim Lambda As Double
    Dim Phi As Double
    Dim Ny As Double
    Dim A As Double
    Dim A1 As Double
    Dim A2 As Double
    Dim J2 As Double
    Dim J4 As Double
    Dim J6 As Double
    Dim Alfa As Double
    Dim Beta As Double
    Dim Gamma As Double
    Dim b As Double
    Dim bphi As Double
    Dim Sigma As Double
    Dim Xi As Double
    Dim Eta As Double
    Dim Tau As Double
    Dim Sen_h_Xi As Double
    Dim DeltaLambda As Double
    Dim coord() As Double

    ReDim coord(2)

    ' Datos elipsoide hayford
    SMayor = 6378388#
    SMenor = 6356911.94613
    Ex = Sqr(SMayor ^ 2 - SMenor ^ 2) / SMayor
    Ex2 = Sqr(SMayor ^ 2 - SMenor ^ 2) / SMenor
    Ex2c = Ex2 ^ 2
    Rc = (SMayor ^ 2) / SMenor
    Apl = (SMayor - SMenor) / SMayor

    Lambda = zone * 6 - 183
    X = X - 500000

    Select Case Hemisf
        Case "N", "n"
            y = y

        Case "S", "s"
            y = y - 10000000
    End Select

     ' aplico las ecuaciones de Coticchia-Surace
    Phi = y / (6366197.724 * 0.9996)
    Ny = (Rc / (1 + Ex2c * (Cos(Phi)) ^ 2) ^ (1 / 2)) * 0.9996
    A = X / Ny
    A1 = Sin(2 * Phi)
    A2 = A1 * (Cos(Phi)) ^ 2
    J2 = Phi + (A1 / 2)
    J4 = (3 * J2 + A2) / 4
    J6 = (5 * J4 + A2 * (Cos(Phi)) ^ 2) / 3
    Alfa = (3 / 4) * Ex2c
    Beta = (5 / 3) * Alfa ^ 2
    Gamma = (35 / 27) * Alfa ^ 3
    bphi = 0.9996 * Rc * (Phi - Alfa * J2 + Beta * J4 - Gamma * J6)
    b = (y - bphi) / Ny
    Sigma = ((Ex2c * A ^ 2) / 2) * (Cos(Phi)) ^ 2
    Xi = A * (1 - Sigma / 3)
    Eta = b * (1 - Sigma) + Phi
    Sen_h_Xi = ((e ^ Xi) - (e ^ (-Xi))) / 2
    DeltaLambda = ArcTan(Sen_h_Xi / Cos(Eta))
    Tau = ArcTan(Cos(DeltaLambda) * Tan(Eta))

    ' calculo la longitud
    coord(1) = (DeltaLambda / pi * 180) + Lambda

    'calculo la latitud
    coord(0) = (Phi + (1 + Ex2c * (Cos(Phi)) ^ 2 - (3 / 2) * Ex2c * Sin(Phi) * Cos(Phi) * (Tau - Phi)) * (Tau - Phi)) / pi * 180

    Utm2Dec = coord

End Function

'**********************************************************************************
' Funcion que convierte coordenadas  Decimales en UTM
' Emplea las ecuaciones de Coticchia-Surace empleando el elipsoide de Hayford o internacional 1924
' Devuelve un array con las coordenadas (latitud,longitud)
'**********************************************************************************

Public Function Dec2Utm(ByVal X As Double, ByVal y As Double, ByVal Hemisf As String) As Double()

    Dim SMayor As Double
    Dim SMenor As Double
    Dim Ex As Double
    Dim Ex2 As Double
    Dim Ex2c As Double
    Dim Rc As Double
    Dim Apl As Double
    Dim Lambda As Double
    Dim Phi As Double
    Dim Ny As Double
    Dim A As Double
    Dim A1 As Double
    Dim A2 As Double
    Dim J2 As Double
    Dim J4 As Double
    Dim J6 As Double
    Dim Alfa As Double
    Dim Beta As Double
    Dim Gamma As Double
    Dim bphi As Double
    Dim Sigma As Double
    Dim Xi As Double
    Dim Eta As Double
    Dim DeltaLambda As Double
    Dim coord() As Double
    Dim huso As Integer

    ReDim coord(2)

    ' Datos elipsoide hayford
    SMayor = 6378388#
    SMenor = 6356911.94613
    Ex = Sqr(SMayor ^ 2 - SMenor ^ 2) / SMayor
    Ex2 = Sqr(SMayor ^ 2 - SMenor ^ 2) / SMenor
    Ex2c = Ex2 ^ 2
    Rc = (SMayor ^ 2) / SMenor
    Apl = (SMayor - SMenor) / SMayor

    ' calculo el meridiano central del huso y la distancia entre la posicion y el meridiano central
    huso = Int(y / 6 + 31)
    Lambda = huso * 6 - 183

    ' paso a radianes las coordenadas
    X = X * pi / 180
    y = y * pi / 180

    DeltaLambda = y - (Lambda * pi / 180)

    ' aplico las ecuaciones de Coticchia-Surace
    A = Cos(X) * Sin(DeltaLambda)
    Xi = (1 / 2) * log((1 + A) / (1 - A))
    Eta = ArcTan(Tan(X) / Cos(DeltaLambda)) - X
    Ny = (Rc / (1 + Ex2c * (Cos(X)) ^ 2) ^ (1 / 2)) * 0.9996
    Sigma = (Ex2c / 2) * Xi ^ 2 * Cos(X) ^ 2
    A1 = Sin(2 * X)
    A2 = A1 * Cos(X) ^ 2
    J2 = X + A1 / 2
    J4 = (3 * J2 + A2) / 4
    J6 = (5 * J4 + A2 * Cos(X) ^ 2) / 3
    Alfa = 3 / 4 * Ex2c
    Beta = 5 / 3 * Alfa ^ 2
    Gamma = 35 / 27 * Alfa ^ 3
    bphi = 0.9996 * Rc * (X - Alfa * J2 + Beta * J4 - Gamma * J6)

    ' calculo la longitud Y
        Select Case Hemisf
            Case "N", "n"
                coord(1) = Eta * Ny * (1 + Sigma) + bphi
            Case "S", "s"
                coord(1) = Eta * Ny * (1 + Sigma) + bphi + 10000000
        End Select

    'calculo la latitud X
    coord(0) = Xi * Ny * (1 + Sigma / 3) + 500000

    Dec2Utm = coord

End Function

'**********************************************************************************
' Calcula la Cotangente inversa
'**********************************************************************************
Public Function ArcTan(ByVal X As Double) As Double
    ArcTan = Atn(X)
End Function

'**********************************************************************************
'Calcula el seno inverso. El angulo debe estar en radianes
'**********************************************************************************
Public Function ArcSin(ByVal Angle As Double) As Double
  If Abs(Angle)  1# Then
    ArcSin = Atn(Angle / Sqr(-Angle * Angle + 1#))
  Else
    ArcSin = IIf(Angle = 1#, Atn(1#) * 2#, Atn(1#) * 6#)
  End If

End Function

'**********************************************************************************
'Calcula el coseno inverso. El angulo debe estar en radianes
'**********************************************************************************
Public Function ArcCos(ByVal Angle As Double) As Double
  If Abs(Angle)  1# Then
      ArcCos = Atn(-Angle / Sqr(-Angle * Angle + 1#)) + 2# * Atn(1#)
   Else
      ArcCos = IIf(Angle = 1#, 0#, Atn(1#) * 4#)
   End If

End Function

Anuncios
Categorías:Programación Etiquetas:
  1. Jueves, 15 marzo 2012 en 8:42 pm

    @Yavir

    No usé nunca VBA para excell pero tendrían que ser muy parecidas. En las funciones ya se incluye la conversión UTM-Geográficas en ambos sentidos.

    No tengo previsto publicar nada más ya que desde hace tiempo no trabajo con nada relacionado.

  2. Yavir
    Miércoles, 14 marzo 2012 en 8:03 pm

    Gracias por el aporte, muy bueno.
    Si quisiera que este en macros excel, como seria…., ya que entiendo mas en VBA que VB.
    Además, si no fuera molestia, podria programar el cálculo inverso?, es decir de geográficas a UTM.
    Estas rutinas se encuentra muy poco en los blogs, si publicara mas rutinas, sera muy agracedido.

    Saludos

  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: