📄 datconv.c
字号:
#include "g7to.h"
#define RADtoDEG 57.295779513082322
#define DEGtoRAD 0.017453292519943296
static FILE *in;
static INT fileopen=0;
//
// 'a' is the Equitorial radius (ER) of the Ellipsoid.
// It is calculated by subtracting the value of the destination ellipsoids ER
// from the source ellipsoids ER
//
// For example, in converting from WGS84 to NAD27 CONUS WGS84 uses it's own ER and
// NAD27 used the ER of the Clarke 1866 Ellipsoid:
//
// a = 6378137.0 - 6388206.4 = -69.4
//
// '1/f' is the inverse of the flattening for the Ellipsoid.
// It is calculated by subtracting the inverse of the flattening of the destination
// ellipsoid from the inverse of the flattening of the source ellipsoid:
//
// For example, in converting from WGS84 to NAD27 CONUS WGS84 uses it's own 'f' and
// NAD27 used the 'f' of the Clarke 1866 Ellipsoid:
//
// 1/f = 1/298.257223563 - 1/294.9786982 = -3.72646393410366794084897857141e-5
//
// This is multiplied by 10*e4 to give the result -0.37264639341036679408489785714167
// which is rounded off to -0.37264639 in the table below.
//
// In the interest of speed these values (a, invf) are pre-calculated and placed in the table.
//
// The delta values of 'a' and '1/f' are also shown in the table below.
//
//
// Commonly used Ellipsoids:
// name a 1/f WGS84a-a (WGS84-1/f-1/f)*1e4
// ========================== =========== =========== ========= ==========
// "Airy 1830 ", 6377563.396, 299.3249646, 573.604, 0.11960023, // 0
// "Modified Airy ", 6377340.189, 299.3249646, 796.811, 0.11960023, // 1
// "Australian National ", 6378160.0, 298.250, -23.0, -0.00081204, // 2
// "Bessel 1841 ", 6377397.155, 299.1528128, 739.845, 0.10037483, // 3
// "Clarke 1866 ", 6378206.4, 294.9786982, -69.4, -0.37264639, // 4
// "Clarke 1880 ", 6378249.145, 293.465, -112.145, -0.54750714, // 5
// "Everest (India 1830) ", 6377276.345, 300.80170, 860.655, 0.28361368, // 6
// "Everest (1948) ", 6377304.063, 300.80170, 832.937, 0.28361368, // 7
// "Modified Fischer 1960 ", 6378155.0, 298.3, -18.0, 0.00480795, // 8
// "Everest (Pakistan) ", 6377309.613, 300.80170, 827.387, 0.28361368, // 9
// "Indonesian 1974 ", 6378160.0, 298.247, -23.0, -0.00114930, // 10
// "GRS 80 ", 6378137.0, 298.257222101, 0.0, -0.00000016, // 11
// "Helmert 1906 ", 6378200.0, 298.3, -63.0, 0.00480795, // 12
// "Hough 1960 ", 6378270.0, 297.0, -133.0, -0.14192702, // 13
// "International 1924 ", 6378388.0, 297.0, -251.0, -0.14192702, // 14
// "Krassovsky 1940 ", 6378245.0, 298.3, -108.0, 0.00480795, // 15
// "South American 1969 ", 6378160.0, 298.250, -23.0, -0.00081204, // 16
// "Everest (Malaysia 1969) ", 6377295.664, 300.80170, 841.336, 0.28361368, // 17
// "Everest (Sabah Sarawak) ", 6377298.556, 300.80170, 838.444, 0.28361368, // 18
// "WGS 72 ", 6378135.0, 298.260, 2.0, 0.00031211, // 19
// "WGS 84 ", 6378137.0, 298.257223563, 0.0, 0.0, // 20
// "Bessel 1841 (Namibia) ", 6377483.865, 299.1528128, 653.135, 0.10037483, // 21
// "Everest (India 1956) ", 6377301.243, 300.80170, 835.757, 0.28361368, // 22
// "Fischer 1960 (Mercury) ", 6378166.0, 298.3, -29.0, 0.00480795, // 23
// "Fischer 1968 ", 6378150.0, 298.3, -13.0, 0.00480795, // 24
// "GRS 1967 ", 6378160.0, 298.247167427, -23.0, -0.00113048, // 25
// "WGS 66 ", 6378145.0, 298.250, -8.0, -0.00081204, // 26
// "WGS 60 ", 6378165.0, 298.3, -28.0, 0.00480795, // 27
struct DATUM {
char *name;
double a;
double invf;
short dX;
short dY;
short dZ;
};
struct DATUM const gDatum[] = {
// Name a invf*1e4 X Y Z
// ==================== ========= =========== ==== ==== ====
{ "ARC-1950_mean" , -112.145, -0.54750714, -143, -90, -294 },
{ "ARC-1960_mean" , -112.145, -0.54750714, -160, -8, -300 },
{ "Adindan" , -112.145, -0.54750714, -162, -12, 206 },
{ "Afgooye" , -108.000, 0.00480795, -43, -163, 45 },
{ "Ain_El_Abd_1970" , -251.000, -0.14192702, -150, -251, -2 },
{ "Alaska/Canada_NAD-27", -69.400, -0.37264639, -9, 151, 185 },
{ "Alaska_(NAD-27)" , -69.400, -0.37264639, -5, 135, 172 },
{ "Anna_1_Astro_1965" , -23.000, -0.00081204, -491, -22, 435 },
{ "Arc_1950" , -112.145, -0.54750714, -143, -90, -294 },
{ "Arc_1960" , -112.145, -0.54750714, -160, -8, -300 },
{ "Ascension_Island_58", -251.000, -0.14192702, -207, 107, 52 },
{ "Astro_B4_Sorol_Atoll", -251.000, -0.14192702, 114, -116, -333 },
{ "Astro_Beacon_E" , -251.000, -0.14192702, 145, 75, -272 },
{ "Astro_DOS_71/4" , -251.000, -0.14192702, -320, 550, -494 },
{ "Astro_DOS_71/4" , -251.000, -0.14192702, -320, 550, -494 },
{ "Astronomic_Stn_52" , -251.000, -0.14192702, 124, -234, -25 },
{ "Australian_Geod_66" , -23.000, -0.00081204, -133, -48, 148 },
{ "Australian_Geod_84" , -23.000, -0.00081204, -134, -48, 149 },
{ "Australian_Geodetic_1984", -23.000, -0.00081204, -134, -48, 149 },
{ "Bahamas_(NAD-27)" , -69.400, -0.37264639, -4, 154, 178 },
{ "Bellevue_(IGN)" , -251.000, -0.14192702, -127, -769, 472 },
{ "Bermuda_1957" , -69.400, -0.37264639, -73, 213, 296 },
{ "Bogota_Observatory" , -251.000, -0.14192702, 307, 304, -318 },
{ "Bukit_Rimpah" , 739.845, 0.10037483, -384, 664, -48 },
{ "CH-1903" , 739.845, 0.10037483, 674, 15, 405 },
{ "Camp_Area_Astro" , -251.000, -0.14192702, -104, -129, 239 },
{ "Campo_Inchauspe" , -251.000, -0.14192702, -148, 136, 90 },
{ "Canada_Mean_(NAD27)", -69.400, -0.37264639, -10, 158, 187 },
{ "Canal_Zone_(NAD27)" , -69.400, -0.37264639, 0, 125, 201 },
{ "Canton_Astro_1966" , -251.000, -0.14192702, 298, -304, -375 },
{ "Canton_Island_1966" , -251.000, -0.14192702, 298, -304, -375 },
{ "Cape" , -112.145, -0.54750714, -136, -108, -292 },
{ "Cape_Canaveral" , -69.400, -0.37264639, -2, 150, 181 },
{ "Cape_Canaveral_mean", -69.400, -0.37264639, -2, 150, 181 },
{ "Carribean_(NAD27)" , -69.400, -0.37264639, -7, 152, 178 },
{ "Carthage" , -112.145, -0.54750714, -263, 6, 431 },
{ "Central_America_(NAD27)", -69.400, -0.37264639, 0, 125, 194 },
{ "Chatham_1971" , -251.000, -0.14192702, 175, -38, 113 },
{ "Chua_Astro" , -251.000, -0.14192702, -134, 229, -29 },
{ "Corrego_Alegre" , -251.000, -0.14192702, -206, 172, -6 },
{ "Corrego_Alegre_(Provisional)", -251.000, -0.14192702, -206, 172, -6 },
{ "Cuba_(NAD27)" , -69.400, -0.37264639, -9, 152, 178 },
{ "Cyprus" , -251.000, -0.14192702, -104, -101, -140 },
{ "DOS_1968" , -251.000, -0.14192702, 230, -199, -752 },
{ "Djakarta_(Batavia)" , 739.845, 0.10037483, -377, 681, -50 },
{ "Easter_Island_1967" , -251.000, -0.14192702, 211, 147, 111 },
{ "Egypt" , -251.000, -0.14192702, -130, -117, -151 },
{ "European_1950" , -251.000, -0.14192702, -87, -98, -121 },
{ "European_1950_mean" , -251.000, -0.14192702, -87, -98, -121 },
{ "European_1979" , -251.000, -0.14192702, -86, -98, -119 },
{ "European_1979_mean" , -251.000, -0.14192702, -86, -98, -119 },
{ "Finland_Hayford" , -251.000, -0.14192702, -78, -231, -97 },
{ "Finnish_Nautical_Chart", -251.000, -0.14192702, -78, -231, -97 },
{ "GUX_1_Astro" , -251.000, -0.14192702, 252, -209, -751 },
{ "Gandajika_Base" , -251.000, -0.14192702, -133, -321, 50 },
{ "Geodetic_Datum_49" , -251.000, -0.14192702, 84, -22, 209 },
{ "Ghana" , 0.000, 0.00000000, 0, 0, 0 },
{ "Greenland_(NAD27)" , -69.400, -0.37264639, 11, 114, 195 },
{ "Guam_1963" , -69.400, -0.37264639, -100, -248, 259 },
{ "Gunung_Segara" , 739.845, 0.10037483, -403, 684, 41 },
{ "Gunung_Serindung_1962", 0.000, 0.00000000, 0, 0, 0 },
{ "Herat_North" , -251.000, -0.14192702, -333, -222, 114 },
{ "Hjorsey_1955" , -251.000, -0.14192702, -73, 46, -86 },
{ "Hong_Kong_1963" , -251.000, -0.14192702, -156, -271, -189 },
{ "Hu-Tzu-Shan" , -251.000, -0.14192702, -634, -549, -201 },
{ "ISTS_073_Astro_69" , -251.000, -0.14192702, 208, -435, -229 },
{ "Indian" , 860.655, 0.28361368, 289, 734, 257 },
{ "Indian_Bangladesh" , 860.655, 0.28361368, 289, 734, 257 },
{ "Indian_Thailand" , 860.655, 0.28361368, 214, 836, 303 },
{ "Iran" , -251.000, -0.14192702, -117, -132, -164 },
{ "Ireland_1965" , 796.811, 0.11960023, 506, -122, 611 },
{ "Johnston_Island" , -251.000, -0.14192702, 191, -77, -204 },
{ "Johnston_Island_61" , -251.000, -0.14192702, 191, -77, -204 },
{ "Kandawala" , 860.655, 0.28361368, -97, 787, 86 },
{ "Kerguelen_Island" , -251.000, -0.14192702, 145, -187, 103 },
{ "Kertau_1948" , 832.937, 0.28361368, -11, 851, 5 },
{ "L.C._5_Astro" , -69.400, -0.37264639, 42, 124, 147 },
{ "La_Reunion" , -251.000, -0.14192702, 94, -948,-1262 },
{ "Liberia_1964" , -112.145, -0.54750714, -90, 40, 88 },
{ "Luzon" , -69.400, -0.37264639, -133, -77, -51 },
{ "Luzon_Mindanao" , -69.400, -0.37264639, -133, -79, -72 },
{ "Luzon_Philippines" , -69.400, -0.37264639, -133, -77, -51 },
{ "Mahe_1971" , -112.145, -0.54750714, 41, -220, -134 },
{ "Marco_Astro" , -251.000, -0.14192702, -289, -124, 60 },
{ "Masirah_Is._(Nahrwan)", -112.145, -0.54750714, -247, -148, 369 },
{ "Massawa" , 739.845, 0.10037483, 639, 405, 60 },
{ "Merchich" , -112.145, -0.54750714, 31, 146, 47 },
{ "Mexico_(NAD27)" , -69.400, -0.37264639, -12, 130, 190 },
{ "Midway_Astro_1961" , -251.000, -0.14192702, 912, -58, 1227 },
{ "Mindanao" , -69.400, -0.37264639, -133, -79, -72 },
{ "Minna" , -112.145, -0.54750714, -92, -93, 122 },
{ "Montjong_Lowe" , 0.000, 0.00000000, 0, 0, 0 },
{ "NAD27_Alaska" , -69.400, -0.37264639, -5, 135, 172 },
{ "NAD27_Bahamas" , -69.400, -0.37264639, -4, 154, 178 },
{ "NAD27_CONUS" , -69.400, -0.37264639, -8, 160, 176 },
{ "NAD27_Canada" , -69.400, -0.37264639, -10, 158, 187 },
{ "NAD27_Canal_Zone" , -69.400, -0.37264639, 0, 125, 201 },
{ "NAD27_Caribbean" , -69.400, -0.37264639, -7, 152, 178 },
{ "NAD27_Central" , -69.400, -0.37264639, 0, 125, 194 },
{ "NAD27_Cuba" , -69.400, -0.37264639, -9, 152, 178 },
{ "NAD27_Greenland" , -69.400, -0.37264639, 11, 114, 195 },
{ "NAD27_Mexico" , -69.400, -0.37264639, -12, 130, 190 },
{ "NAD27_San_Salvador" , -69.400, -0.37264639, 1, 140, 165 },
{ "NAD83" , 0.000, -0.00000016, 0, 0, 0 },
{ "Nahrwan" , -112.145, -0.54750714, -231, -196, 482 },
{ "Nahrwn_Masirah_Ilnd", -112.145, -0.54750714, -247, -148, 369 },
{ "Nahrwn_Saudi_Arbia" , -112.145, -0.54750714, -231, -196, 482 },
{ "Nahrwn_United_Arab" , -112.145, -0.54750714, -249, -156, 381 },
{ "Naparima_BWI" , -251.000, -0.14192702, -2, 374, 172 },
{ "North_America_83" , 0.000, -0.00000016, 0, 0, 0 },
{ "North_America_1927_mean", -69.400, -0.37264639, -8, 160, 176 },
{ "Observatorio_1966" , -251.000, -0.14192702, -425, -169, 81 },
{ "Old_Egyptian" , -63.000, 0.00480795, -130, 110, -13 },
{ "Old_Hawaiian" , -69.400, -0.37264639, 61, -285, -181 },
{ "Old_Hawaiian_Kauai" , -69.400, -0.37264639, 45, -290, -172 },
{ "Old_Hawaiian_Maui" , -69.400, -0.37264639, 65, -290, -190 },
{ "Old_Hawaiian_Oahu" , -69.400, -0.37264639, 56, -284, -181 },
{ "Old_Hawaiian_mean" , -69.400, -0.37264639, 89, -279, -183 },
{ "Oman" , -112.145, -0.54750714, -346, -1, 224 },
{ "Ord_Srvy_Grt_Britn" , 573.604, 0.11960023, 375, -111, 431 },
{ "Ordnance_Survey_of_Great_Britain_36", 573.604, 0.11960023, 375, -111, 431 },
{ "Pico_De_Las_Nieves" , -251.000, -0.14192702, -307, -92, 127 },
{ "Pitcairn_Astro_1967", -251.000, -0.14192702, 185, 165, 42 },
{ "Potsdam_Rauenberg_DHDN", 739.845, 0.10037483, 606, 23, 413 },
{ "Prov_So_Amrican_56" , -251.000, -0.14192702, -288, 175, -376 },
{ "Prov_So_Chilean_63" , -251.000, -0.14192702, 16, 196, 93 },
{ "Provisional_South_American_1956_mean", -251.000, -0.14192702, -288, 175, -376 },
{ "Provisional_South_Chilean_1963", -251.000, -0.14192702, 16, 196, 93 },
{ "Puerto_Rico" , -69.400, -0.37264639, 11, 72, -101 },
{ "Pulkovo_1942" , -108.000, 0.00480795, 28, -130, -95 },
{ "Qatar_National" , -251.000, -0.14192702, -128, -283, 22 },
{ "Qornoq" , -251.000, -0.14192702, 164, 138, -189 },
{ "Quatar_National" , -251.000, -0.14192702, -128, -283, 22 },
{ "RT_90" , 739.845, 0.10037483, 498, -36, 568 },
{ "Reunion" , -251.000, -0.14192702, 94, -948,-1262 },
{ "Rome_1940" , -251.000, -0.14192702, -225, -65, 9 },
{ "S.E.Asia_(Indian)" , 860.655, 0.28361368, 173, 750, 264 },
{ "SAD-69/Brazil" , -23.000, -0.00081204, -60, -2, -41 },
{ "S_42" , -108.000, 0.00480795, 28, -121, -77 },
{ "Santa_Braz" , -251.000, -0.14192702, -203, 141, 53 },
{ "Santo_(DOS)" , -251.000, -0.14192702, 170, 42, 84 },
{ "Sao_Braz" , -251.000, -0.14192702, -203, 141, 53 },
{ "Sapper_Hill_1943" , -251.000, -0.14192702, -355, 16, 74 },
{ "Schwarzeck" , 653.135, 0.10037483, 616, 97, -251 },
{ "Sicily" , -251.000, -0.14192702, -97, -88, -135 },
{ "Sierra_Leone_1960" , 0.000, 0.00000000, 0, 0, 0 },
{ "South_American_1969_mean", -23.000, -0.00081204, -57, 1, -41 },
{ "South_American_69" , -23.000, -0.00081204, -57, 1, -41 },
{ "South_Asia" , -18.000, 0.00480795, 7, -10, -26 },
{ "Southeast_Base" , -251.000, -0.14192702, -499, -249, 314 },
{ "Southwest_Base" , -251.000, -0.14192702, -104, 167, -38 },
{ "Tananarive_Observatory_25", -251.000, -0.14192702, -189, -242, -91 },
{ "Thai/Viet_(Indian)" , 860.655, 0.28361368, 214, 836, 303 },
{ "Timbalai_1948" , 860.655, 0.28361368, -689, 691, -46 },
{ "Tokyo" , 739.845, 0.10037483, -128, 481, 664 },
{ "Tokyo_mean" , 739.845, 0.10037483, -128, 481, 664 },
{ "Tristan_Astro_1968" , -251.000, -0.14192702, -632, 438, -609 },
{ "Unites_Arab_Emirates_(Nahrwan)", -112.145, -0.54750714, -249, -156, 381 },
{ "Viti_Levu_1916" , -112.145, -0.54750714, 51, 391, -36 },
{ "WGS-72" , 2.000, 0.00031211, 0, 0, 5 },
{ "WGS-84" , 0.000, 0.00000000, 0, 0, 0 },
{ "Wake-Eniwetok_60" , -133.000, -0.14192702, 101, 52, -39 },
{ "Yacare" , -251.000, -0.14192702, -155, 171, 37 },
{ "Zanderij" , -251.000, -0.14192702, -265, 120, -358 },
{ "FINISXXY" , -251.000, -0.14192702, -265, 120, -358 },
};
extern char outputdatum[150];
extern char inputdatum[150];
static double WGS84a = 6378137.0; //WGS-84 Equatorial Radius (a)
static double WGS84f = 1/298.257223563; //WGS-84 Flattening (f)
double from_es, from_a, from_f, from_x, from_y, from_z;
double to_a, to_f, to_x, to_y, to_z;
double dA, dF, dX, dY, dZ;
double LA,LO;
double UTMa_in,UTMf_in;
double UTMa,UTMf;
double UTMa_out,UTMf_out;
PROCX void print_datums(void)
{
int i;
char k[100];
i=0;
while(stricmp("FINISXXY",gDatum[i].name) != 0) {
strcpy(k,gDatum[i].name);
strcat(k,", -------------------------------------");
k[37]=0;
printf("%-37s %10.3lf,%13.9lf,%5d,%5d,%5d\n",
k,
gDatum[i].a,
gDatum[i].invf,
gDatum[i].dX,
gDatum[i].dY,
gDatum[i].dZ);
i++;
}
} // print_datums
//
// lat/long assumed to be passed in in degrees;
//
// N lat and E longitude are +
// S lat and W longitude are -
//
PROCX void datumconv(double la, double lo)
{
double bda, from_h=0.0;
double slo,clo,sla,cla;
double Rn, Rm, dla, dlo;
//
// convert to radians
//
la=la*DEGtoRAD;
lo=lo*DEGtoRAD;
slo=sin(lo); sla=sin(la); clo=cos(lo); cla=cos(la);
bda = 1.0 - from_f;
Rn = from_a/(sqrt(1.0-from_es*sla*sla));
Rm = from_a * (1.0-from_es)/pow((1.0-from_es*sla*sla),1.5);
dla = ( ((-dX*sla*clo-dY*sla*slo+dZ*cla) +
dA*Rn*from_es*sla*cla/from_a) +
dF*(Rm/bda + Rn*bda)*sla*cla)/(Rm+from_h);
dlo = (-dX*slo+dY*clo)/((Rn+from_h)*cla);
la = la + dla;
lo = lo + dlo;
la*=RADtoDEG;
lo*=RADtoDEG;
LA=la;
LO=lo;
} // datumconv
PROCX void get_datum(INT to, char *datumstr)
{
char *p,bin[MAX_LENGTH];
char fname[MAX_LENGTH];
double deltaA, deltaX, deltaY, deltaZ, deltaF;
char df[50];
char pathbuffer[_MAX_PATH];
INT done,i,found;
#if ! __BORLANDC__
char searchfile[] = "g7datums.txt";
char envvar[] = "PATH"; /* Search for file in PATH environment variable: */
#endif
found=0;
strcpy(df,datumstr);
if(strcmp(datumstr,"WGS-84") == 0) {
notfound:;
deltaA = deltaF = deltaX = deltaY = deltaZ = 0.0;
strcpy(df,"WGS-84");
found=1;
goto setval;
}
if(!fileopen) {
#if __BORLANDC__
p=searchpath("g7datums.txt");
if(p!=NULL) strcpy(pathbuffer,p);
else {
strcpy(fname,ProgramName);
if((p=strrchr(fname,'\\')) == NULL) {
strcpy(pathbuffer,"g7datums.txt");
}
else {
strcpy(++p,"g7datums.txt");
strcpy(pathbuffer,fname);
}
}
strcpy(fname,pathbuffer);
#else
_searchenv( searchfile, envvar, pathbuffer );
if(pathbuffer[0]==0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -