Método para convertir coordenadas geocéntricas en geográficas (cambio de datum 7 parámetros): Clase Coordenadas (C/C++)

En el artículo anterior, intenté esbozar una clase Coordenadas en la cuál, entre otros, tenía un método para convertir coordenadas geocéntricas en geográficas (cambio de datum 7 parámetros). Este método es complementario a la transformación que se puede realizar del cambio de coordenadas UTM a UTM, con cambio de datum, que pasaría por los siguientes pasos: de UTM a geográficas, de geográficas a geocéntricas, de geocéntricas a geográficas (cambio de datum 7 parámetros o de Bursa-Wolf) y de geográficas a UTM; todos métodos de la Clase Coordenadas.

El código es el siguiente:

void Coordenadas::

	CambioGeocent_Geo (int selector, Coordenadas v, Coordenadas &t){

	const double pi = 3.14159265358979323846;

	double a, b;

	double Rx, Ry, Rz, esc;

	double D[3][1];

	switch (selector){

    case 1:

//************* Bursa-Wolf para Canoa-Regven ***********************

		 Rx=-2.904, Ry=-0.817, Rz=-1.210, esc = 1+(-0.000004688);

		 D[0][0] = -296.497, D[1][0] = 85.260, D[2][0] = -263.967;

	// Elipsoide de WGS 84

		a = 6378137.0;  b = 6356752.3142;

//****************************************************************

	break;

	case 2:

//************* Bursa-Wolf para Regven-Canoa ***********************

		 Rx= 2.904, Ry= 0.817, Rz= 1.210, esc = 1+(0.000004688);

		 D[0][0] = 296.497, D[1][0] = -85.260, D[2][0] = 263.967;

	// Elipsoide de Hayford

		a = 6378388.0, b = 6356911.946130;

//****************************************************************

	break;

	case 3:

//************* Bursa-Wolf para WGS 84-ED50 **********************
	
		Rx=-1.2438, Ry=-0.0195, Rz=-1.1436, esc = 1+(-0.00000939);

		D[0][0] = 131.032, D[1][0] = 100.251, D[2][0] = 163.354;

	// Elipsoide de Hayford

		a = 6378388.0, b = 6356911.946130;

//****************************************************************

	break;

	case 4:

//************* Bursa-Wolf para ED50-WGS 84 **********************
	
		Rx= 1.2438, Ry= 0.0195, Rz= 1.1436, esc = 1+(0.00000939);

		D[0][0] = -131.032, D[1][0] = -100.251, D[2][0] = -163.354;

	// Elipsoide de WGS 84

		a = 6378137.0;  b = 6356752.3142;

//****************************************************************

	break;

}
	Rx = (Rx*pi)/(3600.0*180.0); Ry = (Ry*pi)/(3600.0*180.0); Rz = (Rz*pi)/(3600.0*180.0);	

	double R[][3]={ 1.0,  Rz,  -Ry,
                    -Rz,  1.0,  Rx,
                     Ry, -Rx,  1.0};

	double B[][1] = {v.a[0],
                     v.a[1],
                     v.a[2]};

	double C[][1] = {0.0,
                     0.0,
                     0.0};

	int i, j, k;

	for(i=0; i < 3; i++){

		for(j=0; j < 3; j++){

			R[i][j]= esc*R[i][j];			
		
		}

	}
	

	for(i=0; i<3; i++){

		for(j=0; j<1; j++){

		C[i][j]=0;			

			for(k=0; k<3; k++){

				C[i][j]= C[i][j]+R[i][k]*B[k][j];

			}

		}

	}

	for(i=0; i<3; i++){

		for(j=0; j<1; j++){

			C[i][j]= C[i][j] + D[i][j];

		}

	}

	double e1, e2, p, theta, lambda, phi, N;

	e1 = sqrt (pow(a,2) - pow(b, 2)) / a;
	e2 = sqrt (pow(a,2) - pow(b, 2)) / b;

	p =sqrt(pow(C[0][0],2) + pow(C[1][0],2));

	theta = atan((C[2][0]*a)/(p*b));

	phi = atan((C[2][0]+pow(e2,2)*b*pow(sin(theta),3))/(p-pow(e1,2)*a*pow(cos(theta),3)));

	lambda = atan(C[1][0]/C[0][0]);

	N = a*a/sqrt(a*a*pow(cos(phi),2)+b*b*pow(sin(phi),2));

	t.a[0] = lambda*180.0/pi;

	t.a[1] = phi*180.0/pi;

	t.a[2] = (p/cos(phi))-N;

}

Implementado en el programa principal para el vértice de Carbonera (España); cuyas coordenadas geocéntricas son (4915809.5115, -309222.2929, 4039765.1165) y el cambio de datum es de WGS 84-ED50, es decir, opción 3.

#include "Coordenadas.h"

int main(){

	system("clear");

	Coordenadas a, b; // Declara objetos de la Clase Coordenadas 

	double u[3];
	
	u[0]=4915809.5115; u[1]=-309222.2929; u[2]=4039765.1165;

	a.Iniciar(u); // Inicia el objeto a (vertice de Carbonera en coordenadas geocentricas)

	cout << "vertice de Carbonera en Coordenadas geocentricas:\n" << a;

	b.CambioGeocent_Geo(3,a,b);        //De geocentricas a geograficas (cambio de datum) 

	cout << "vertice de Carbonera en Coordenadas geograficas (datum ED50):\n" << b;

	return 0;

}

La salida es:

vertice de Carbonera en Coordenadas geocentricas:
(4915809.5115, -309222.2929, 4039765.1165)
vertice de Carbonera en Coordenadas geograficas (datum ED50):
(-3.5981, 39.5476, 697.8972)

que concuerda con lo esperado.

Esta entrada fue publicada en Código C++, SIG, Transformar Coordenadas. Guarda el enlace permanente.

Una respuesta a Método para convertir coordenadas geocéntricas en geográficas (cambio de datum 7 parámetros): Clase Coordenadas (C/C++)

  1. Pingback: Conversión de coordenadas geográficas a Gauss-Krüger usando los elipsoides Hayford o WGS 84: caso Argentina |

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

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