/src/gdal/ogr/ogrmitabspatialref.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // SPDX-License-Identifier: MIT |
2 | | // Copyright 1999-2003, Daniel Morissette |
3 | | // Copyright (c) 1999-2001, Frank Warmerdam |
4 | | // Implementation translation between MIF CoordSys format, and |
5 | | // and OGRSpatialRef format. |
6 | | |
7 | | /*! @cond Doxygen_Suppress */ |
8 | | |
9 | | #include "ogrmitabspatialref.h" |
10 | | |
11 | | #include "cpl_port.h" |
12 | | |
13 | | #include <algorithm> |
14 | | #include <cmath> |
15 | | #include <cstddef> |
16 | | #include <cstdio> |
17 | | #include <cstdlib> |
18 | | #include <cstring> |
19 | | |
20 | | #include "cpl_conv.h" |
21 | | #include "cpl_error.h" |
22 | | #include "cpl_string.h" |
23 | | #include "ogr_spatialref.h" |
24 | | #include "ogr_srs_api.h" |
25 | | |
26 | | typedef struct |
27 | | { |
28 | | int nDatumEPSGCode; |
29 | | int nMapInfoDatumID; |
30 | | const char *pszOGCDatumName; |
31 | | int nEllipsoid; |
32 | | double dfShiftX; |
33 | | double dfShiftY; |
34 | | double dfShiftZ; |
35 | | double dfDatumParm0; /* RotX */ |
36 | | double dfDatumParm1; /* RotY */ |
37 | | double dfDatumParm2; /* RotZ */ |
38 | | double dfDatumParm3; /* Scale Factor */ |
39 | | double dfDatumParm4; /* Prime Meridian */ |
40 | | } MapInfoDatumInfo; |
41 | | |
42 | | typedef struct |
43 | | { |
44 | | int nMapInfoId; |
45 | | const char *pszMapinfoName; |
46 | | double dfA; /* semi major axis in meters */ |
47 | | double dfInvFlattening; /* Inverse flattening */ |
48 | | } MapInfoSpheroidInfo; |
49 | | |
50 | | /********************************************************************** |
51 | | * MapInfo Units string to numeric ID conversion |
52 | | **********************************************************************/ |
53 | | typedef struct |
54 | | { |
55 | | int nUnitId; |
56 | | const char *pszAbbrev; |
57 | | } MapInfoUnitsInfo; |
58 | | |
59 | | static const MapInfoUnitsInfo gasUnitsList[] = { |
60 | | {0, "mi"}, {1, "km"}, {2, "in"}, {3, "ft"}, |
61 | | {4, "yd"}, {5, "mm"}, {6, "cm"}, {7, "m"}, |
62 | | {8, "survey ft"}, {8, "survey foot"}, // alternate |
63 | | {13, nullptr}, {9, "nmi"}, {30, "li"}, {31, "ch"}, |
64 | | {32, "rd"}, {-1, nullptr}}; |
65 | | |
66 | | /********************************************************************** |
67 | | * TABUnitIdToString() |
68 | | * |
69 | | * Return the MIF units name for specified units id. |
70 | | * Return "" if no match found. |
71 | | * |
72 | | * The returned string should not be freed by the caller. |
73 | | **********************************************************************/ |
74 | | static const char *TABUnitIdToString(int nId) |
75 | 0 | { |
76 | 0 | const MapInfoUnitsInfo *psList = gasUnitsList; |
77 | |
|
78 | 0 | while (psList->nUnitId != -1) |
79 | 0 | { |
80 | 0 | if (psList->nUnitId == nId) |
81 | 0 | return psList->pszAbbrev; |
82 | 0 | psList++; |
83 | 0 | } |
84 | | |
85 | 0 | return ""; |
86 | 0 | } |
87 | | |
88 | | /********************************************************************** |
89 | | * TABUnitIdFromString() |
90 | | * |
91 | | * Return the units ID for specified MIF units name |
92 | | * |
93 | | * Returns -1 if no match found. |
94 | | **********************************************************************/ |
95 | | static int TABUnitIdFromString(const char *pszName) |
96 | 0 | { |
97 | 0 | if (pszName == nullptr) |
98 | 0 | return 13; |
99 | | |
100 | 0 | const MapInfoUnitsInfo *psList = gasUnitsList; |
101 | |
|
102 | 0 | while (psList->nUnitId != -1) |
103 | 0 | { |
104 | 0 | if (psList->pszAbbrev != nullptr && EQUAL(psList->pszAbbrev, pszName)) |
105 | 0 | return psList->nUnitId; |
106 | 0 | psList++; |
107 | 0 | } |
108 | | |
109 | 0 | return -1; |
110 | 0 | } |
111 | | |
112 | | /* -------------------------------------------------------------------- */ |
113 | | /* This table was automatically generated by doing translations */ |
114 | | /* between mif and tab for each datum, and extracting the */ |
115 | | /* parameters from the tab file. The EPSG codes and OGC names */ |
116 | | /* were added afterwards and may be incomplete or inaccurate. */ |
117 | | /* -------------------------------------------------------------------- */ |
118 | | |
119 | | extern const MapInfoDatumInfo asDatumInfoList[]; |
120 | | extern const MapInfoSpheroidInfo asSpheroidInfoList[]; |
121 | | |
122 | | /* EPSG code, MapInfo datum ID (or 9999), OGC Name, datum parameters... */ |
123 | | const MapInfoDatumInfo asDatumInfoList[] = { |
124 | | |
125 | | {0, 104, "WGS_1984", 28, 0, 0, 0, 0, 0, 0, 0, 0}, |
126 | | {6269, 74, "North_American_Datum_1983", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
127 | | |
128 | | {0, 0, "", 29, 0, 0, 0, 0, 0, 0, 0, 0}, // Datum ignore |
129 | | |
130 | | {6201, 1, "Adindan", 6, -162, -12, 206, 0, 0, 0, 0, 0}, |
131 | | {6205, 2, "Afgooye", 3, -43, -163, 45, 0, 0, 0, 0, 0}, |
132 | | {6204, 3, "Ain_el_Abd_1970", 4, -150, -251, -2, 0, 0, 0, 0, 0}, |
133 | | {0, 4, "Anna_1_Astro_1965", 2, -491, -22, 435, 0, 0, 0, 0, 0}, |
134 | | {6209, 5, "Arc_1950", 15, -143, -90, -294, 0, 0, 0, 0, 0}, |
135 | | {6210, 6, "Arc_1960", 6, -160, -8, -300, 0, 0, 0, 0, 0}, |
136 | | {0, 7, "Ascension_Islands", 4, -207, 107, 52, 0, 0, 0, 0, 0}, |
137 | | {0, 8, "Astro_Beacon_E", 4, 145, 75, -272, 0, 0, 0, 0, 0}, |
138 | | {0, 9, "Astro_B4_Sorol_Atoll", 4, 114, -116, -333, 0, 0, 0, 0, 0}, |
139 | | {0, 10, "Astro_Dos_71_4", 4, -320, 550, -494, 0, 0, 0, 0, 0}, |
140 | | {0, 11, "Astronomic_Station_1952", 4, 124, -234, -25, 0, 0, 0, 0, 0}, |
141 | | {6202, 12, "Australian_Geodetic_Datum_66", 2, -133, -48, 148, 0, 0, 0, 0, |
142 | | 0}, |
143 | | {6203, 13, "Australian_Geodetic_Datum_84", 2, -134, -48, 149, 0, 0, 0, 0, |
144 | | 0}, |
145 | | {0, 14, "Bellevue_Ign", 4, -127, -769, 472, 0, 0, 0, 0, 0}, |
146 | | {6216, 15, "Bermuda_1957", 7, -73, 213, 296, 0, 0, 0, 0, 0}, |
147 | | {6218, 16, "Bogota", 4, 307, 304, -318, 0, 0, 0, 0, 0}, |
148 | | {6221, 17, "Campo_Inchauspe", 4, -148, 136, 90, 0, 0, 0, 0, 0}, |
149 | | {0, 18, "Canton_Astro_1966", 4, 298, -304, -375, 0, 0, 0, 0, 0}, |
150 | | {6222, 19, "Cape", 6, -136, -108, -292, 0, 0, 0, 0, 0}, |
151 | | {6717, 20, "Cape_Canaveral", 7, -2, 150, 181, 0, 0, 0, 0, 0}, |
152 | | {6223, 21, "Carthage", 6, -263, 6, 431, 0, 0, 0, 0, 0}, |
153 | | {6672, 22, "Chatham_1971", 4, 175, -38, 113, 0, 0, 0, 0, 0}, |
154 | | {6224, 23, "Chua", 4, -134, 229, -29, 0, 0, 0, 0, 0}, |
155 | | {6225, 24, "Corrego_Alegre", 4, -206, 172, -6, 0, 0, 0, 0, 0}, |
156 | | {6211, 25, "Batavia", 10, -377, 681, -50, 0, 0, 0, 0, 0}, |
157 | | {0, 26, "Dos_1968", 4, 230, -199, -752, 0, 0, 0, 0, 0}, |
158 | | {6719, 27, "Easter_Island_1967", 4, 211, 147, 111, 0, 0, 0, 0, 0}, |
159 | | {6230, 28, "European_Datum_1950", 4, -87, -98, -121, 0, 0, 0, 0, 0}, |
160 | | {6668, 29, "European_Datum_1979", 4, -86, -98, -119, 0, 0, 0, 0, 0}, |
161 | | {6233, 30, "Gandajika_1970", 4, -133, -321, 50, 0, 0, 0, 0, 0}, |
162 | | {6272, 31, "New_Zealand_GD49", 4, 84, -22, 209, 0, 0, 0, 0, 0}, |
163 | | {6272, 31, "New_Zealand_Geodetic_Datum_1949", 4, 84, -22, 209, 0, 0, 0, 0, |
164 | | 0}, |
165 | | {0, 32, "GRS_67", 21, 0, 0, 0, 0, 0, 0, 0, 0}, |
166 | | {0, 33, "GRS_80", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
167 | | {6171, 33, "Reseau_Geodesique_Francais_1993", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
168 | | {6619, 33, "SWEREF99", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
169 | | {6675, 34, "Guam_1963", 7, -100, -248, 259, 0, 0, 0, 0, 0}, |
170 | | {0, 35, "Gux_1_Astro", 4, 252, -209, -751, 0, 0, 0, 0, 0}, |
171 | | {6254, 36, "Hito_XVIII_1963", 4, 16, 196, 93, 0, 0, 0, 0, 0}, |
172 | | {6658, 37, "Hjorsey_1955", 4, -73, 46, -86, 0, 0, 0, 0, 0}, |
173 | | {6738, 38, "Hong_Kong_1963", 4, -156, -271, -189, 0, 0, 0, 0, 0}, |
174 | | {6236, 39, "Hu_Tzu_Shan", 4, -634, -549, -201, 0, 0, 0, 0, 0}, |
175 | | {0, 40, "Indian_Thailand_Vietnam", 11, 214, 836, 303, 0, 0, 0, 0, 0}, |
176 | | {0, 41, "Indian_Bangladesh", 11, 289, 734, 257, 0, 0, 0, 0, 0}, |
177 | | {6299, 42, "Ireland_1965", 13, 506, -122, 611, 0, 0, 0, 0, 0}, |
178 | | {0, 43, "ISTS_073_Astro_1969", 4, 208, -435, -229, 0, 0, 0, 0, 0}, |
179 | | {6725, 44, "Johnston_Island_1961", 4, 191, -77, -204, 0, 0, 0, 0, 0}, |
180 | | {6244, 45, "Kandawala", 11, -97, 787, 86, 0, 0, 0, 0, 0}, |
181 | | {0, 46, "Kerguyelen_Island", 4, 145, -187, 103, 0, 0, 0, 0, 0}, |
182 | | {6245, 47, "Kertau", 17, -11, 851, 5, 0, 0, 0, 0, 0}, |
183 | | {0, 48, "L_C_5_Astro", 7, 42, 124, 147, 0, 0, 0, 0, 0}, |
184 | | {6251, 49, "Liberia_1964", 6, -90, 40, 88, 0, 0, 0, 0, 0}, |
185 | | {0, 50, "Luzon_Phillippines", 7, -133, -77, -51, 0, 0, 0, 0, 0}, |
186 | | {0, 51, "Luzon_Mindanao_Island", 7, -133, -79, -72, 0, 0, 0, 0, 0}, |
187 | | {6256, 52, "Mahe_1971", 6, 41, -220, -134, 0, 0, 0, 0, 0}, |
188 | | {0, 53, "Marco_Astro", 4, -289, -124, 60, 0, 0, 0, 0, 0}, |
189 | | {6262, 54, "Massawa", 10, 639, 405, 60, 0, 0, 0, 0, 0}, |
190 | | {6261, 55, "Merchich", 16, 31, 146, 47, 0, 0, 0, 0, 0}, |
191 | | {0, 56, "Midway_Astro_1961", 4, 912, -58, 1227, 0, 0, 0, 0, 0}, |
192 | | {6263, 57, "Minna", 6, -92, -93, 122, 0, 0, 0, 0, 0}, |
193 | | {0, 58, "Nahrwan_Masirah_Island", 6, -247, -148, 369, 0, 0, 0, 0, 0}, |
194 | | {0, 59, "Nahrwan_Un_Arab_Emirates", 6, -249, -156, 381, 0, 0, 0, 0, 0}, |
195 | | {0, 60, "Nahrwan_Saudi_Arabia", 6, -231, -196, 482, 0, 0, 0, 0, 0}, |
196 | | {6271, 61, "Naparima_1972", 4, -2, 374, 172, 0, 0, 0, 0, 0}, |
197 | | {6267, 62, "NAD_1927", 7, -8, 160, 176, 0, 0, 0, 0, 0}, |
198 | | {6267, 62, "North_American_Datum_1927", 7, -8, 160, 176, 0, 0, 0, 0, 0}, |
199 | | {0, 63, "NAD_27_Alaska", 7, -5, 135, 172, 0, 0, 0, 0, 0}, |
200 | | {0, 64, "NAD_27_Bahamas", 7, -4, 154, 178, 0, 0, 0, 0, 0}, |
201 | | {0, 65, "NAD_27_San_Salvador", 7, 1, 140, 165, 0, 0, 0, 0, 0}, |
202 | | {0, 66, "NAD_27_Canada", 7, -10, 158, 187, 0, 0, 0, 0, 0}, |
203 | | {0, 67, "NAD_27_Canal_Zone", 7, 0, 125, 201, 0, 0, 0, 0, 0}, |
204 | | {0, 68, "NAD_27_Caribbean", 7, -7, 152, 178, 0, 0, 0, 0, 0}, |
205 | | {0, 69, "NAD_27_Central_America", 7, 0, 125, 194, 0, 0, 0, 0, 0}, |
206 | | {0, 70, "NAD_27_Cuba", 7, -9, 152, 178, 0, 0, 0, 0, 0}, |
207 | | {0, 71, "NAD_27_Greenland", 7, 11, 114, 195, 0, 0, 0, 0, 0}, |
208 | | {0, 72, "NAD_27_Mexico", 7, -12, 130, 190, 0, 0, 0, 0, 0}, |
209 | | {0, 73, "NAD_27_Michigan", 8, -8, 160, 176, 0, 0, 0, 0, 0}, |
210 | | {0, 75, "Observatorio_1966", 4, -425, -169, 81, 0, 0, 0, 0, 0}, |
211 | | {0, 76, "Old_Egyptian", 22, -130, 110, -13, 0, 0, 0, 0, 0}, |
212 | | {6135, 77, "Old_Hawaiian", 7, 61, -285, -181, 0, 0, 0, 0, 0}, |
213 | | {0, 78, "Oman", 6, -346, -1, 224, 0, 0, 0, 0, 0}, |
214 | | {6277, 79, "OSGB_1936", 9, 375, -111, 431, 0, 0, 0, 0, 0}, |
215 | | {0, 80, "Pico_De_Las_Nieves", 4, -307, -92, 127, 0, 0, 0, 0, 0}, |
216 | | {6729, 81, "Pitcairn_Astro_1967", 4, 185, 165, 42, 0, 0, 0, 0, 0}, |
217 | | {6248, 82, "Provisional_South_American", 4, -288, 175, -376, 0, 0, 0, 0, 0}, |
218 | | {6139, 83, "Puerto_Rico", 7, 11, 72, -101, 0, 0, 0, 0, 0}, |
219 | | {6614, 84, "Qatar_National", 4, -128, -283, 22, 0, 0, 0, 0, 0}, |
220 | | {6287, 85, "Qornoq", 4, 164, 138, -189, 0, 0, 0, 0, 0}, |
221 | | {6627, 86, "Reunion", 4, 94, -948, -1262, 0, 0, 0, 0, 0}, |
222 | | {6265, 87, "Monte_Mario", 4, -225, -65, 9, 0, 0, 0, 0, 0}, |
223 | | {0, 88, "Santo_Dos", 4, 170, 42, 84, 0, 0, 0, 0, 0}, |
224 | | {0, 89, "Sao_Braz", 4, -203, 141, 53, 0, 0, 0, 0, 0}, |
225 | | {6292, 90, "Sapper_Hill_1943", 4, -355, 16, 74, 0, 0, 0, 0, 0}, |
226 | | {6293, 91, "Schwarzeck", 14, 616, 97, -251, 0, 0, 0, 0, 0}, |
227 | | {6618, 92, "South_American_Datum_1969", 24, -57, 1, -41, 0, 0, 0, 0, 0}, |
228 | | {0, 93, "South_Asia", 19, 7, -10, -26, 0, 0, 0, 0, 0}, |
229 | | {0, 94, "Southeast_Base", 4, -499, -249, 314, 0, 0, 0, 0, 0}, |
230 | | {0, 95, "Southwest_Base", 4, -104, 167, -38, 0, 0, 0, 0, 0}, |
231 | | {6298, 96, "Timbalai_1948", 11, -689, 691, -46, 0, 0, 0, 0, 0}, |
232 | | {6301, 97, "Tokyo", 10, -128, 481, 664, 0, 0, 0, 0, 0}, |
233 | | {0, 98, "Tristan_Astro_1968", 4, -632, 438, -609, 0, 0, 0, 0, 0}, |
234 | | {6731, 99, "Viti_Levu_1916", 6, 51, 391, -36, 0, 0, 0, 0, 0}, |
235 | | {0, 100, "Wake_Entiwetok_1960", 23, 101, 52, -39, 0, 0, 0, 0, 0}, |
236 | | {0, 101, "WGS_60", 26, 0, 0, 0, 0, 0, 0, 0, 0}, |
237 | | {6760, 102, "WGS_66", 27, 0, 0, 0, 0, 0, 0, 0, 0}, |
238 | | {6322, 103, "WGS_1972", 1, 0, 8, 10, 0, 0, 0, 0, 0}, |
239 | | {6322, 103, "World_Geodetic_System_1972", 1, 0, 8, 10, 0, 0, 0, 0, 0}, |
240 | | {6326, 104, "WGS_1984", 28, 0, 0, 0, 0, 0, 0, 0, 0}, |
241 | | {6309, 105, "Yacare", 4, -155, 171, 37, 0, 0, 0, 0, 0}, |
242 | | {6311, 106, "Zanderij", 4, -265, 120, -358, 0, 0, 0, 0, 0}, |
243 | | {0, 107, "NTF", 30, -168, -60, 320, 0, 0, 0, 0, 0}, |
244 | | {6231, 108, "European_Datum_1987", 4, -83, -96, -113, 0, 0, 0, 0, 0}, |
245 | | {0, 109, "Netherlands_Bessel", 10, 593, 26, 478, 0, 0, 0, 0, 0}, |
246 | | {0, 110, "Belgium_Hayford", 4, 81, 120, 129, 0, 0, 0, 0, 0}, |
247 | | {0, 111, "NWGL_10", 1, -1, 15, 1, 0, 0, 0, 0, 0}, |
248 | | {6124, 112, "Rikets_koordinatsystem_1990", 10, 498, -36, 568, 0, 0, 0, 0, |
249 | | 0}, |
250 | | {0, 113, "Lisboa_DLX", 4, -303, -62, 105, 0, 0, 0, 0, 0}, |
251 | | {0, 114, "Melrica_1973_D73", 4, -223, 110, 37, 0, 0, 0, 0, 0}, |
252 | | {6258, 115, "European_Terrestrial_Reference_System_1989", 0, 0, 0, 0, 0, 0, |
253 | | 0, 0, 0}, |
254 | | {6258, 115, "Euref_89", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
255 | | {6180, 115, "Estonia_1997", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
256 | | {6283, 116, "GDA94", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
257 | | {6283, 116, "Geocentric_Datum_of_Australia_1994", 0, 0, 0, 0, 0, 0, 0, 0, |
258 | | 0}, |
259 | | {6167, 117, "NZGD2000", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
260 | | {6167, 117, "New_Zealand_Geodetic_Datum_2000", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
261 | | {6169, 118, "America_Samoa", 7, -115, 118, 426, 0, 0, 0, 0, 0}, |
262 | | {0, 119, "Antigua_Astro_1965", 6, -270, 13, 62, 0, 0, 0, 0, 0}, |
263 | | {6713, 120, "Ayabelle_Lighthouse", 6, -79, -129, 145, 0, 0, 0, 0, 0}, |
264 | | {6219, 121, "Bukit_Rimpah", 10, -384, 664, -48, 0, 0, 0, 0, 0}, |
265 | | {0, 122, "Estonia_1937", 10, 374, 150, 588, 0, 0, 0, 0, 0}, |
266 | | {6155, 123, "Dabola", 6, -83, 37, 124, 0, 0, 0, 0, 0}, |
267 | | {6736, 124, "Deception_Island", 6, 260, 12, -147, 0, 0, 0, 0, 0}, |
268 | | {0, 125, "Fort_Thomas_1955", 6, -7, 215, 225, 0, 0, 0, 0, 0}, |
269 | | {0, 126, "Graciosa_base_1948", 4, -104, 167, -38, 0, 0, 0, 0, 0}, |
270 | | {6255, 127, "Herat_North", 4, -333, -222, 114, 0, 0, 0, 0, 0}, |
271 | | {0, 128, "Hermanns_Kogel", 10, 682, -203, 480, 0, 0, 0, 0, 0}, |
272 | | {6240, 129, "Indian", 50, 283, 682, 231, 0, 0, 0, 0, 0}, |
273 | | {6239, 130, "Indian_1954", 11, 217, 823, 299, 0, 0, 0, 0, 0}, |
274 | | {6131, 131, "Indian_1960", 11, 198, 881, 317, 0, 0, 0, 0, 0}, |
275 | | {6240, 132, "Indian_1975", 11, 210, 814, 289, 0, 0, 0, 0, 0}, |
276 | | {6238, 133, "Indonesian_Datum_1974", 4, -24, -15, 5, 0, 0, 0, 0, 0}, |
277 | | {0, 134, "ISTS061_Astro_1968", 4, -794, 119, -298, 0, 0, 0, 0, 0}, |
278 | | {0, 135, "Kusaie_Astro_1951", 4, 647, 1777, -1124, 0, 0, 0, 0, 0}, |
279 | | {6250, 136, "Leigon", 6, -130, 29, 364, 0, 0, 0, 0, 0}, |
280 | | {0, 137, "Montserrat_Astro_1958", 6, 174, 359, 365, 0, 0, 0, 0, 0}, |
281 | | {6266, 138, "Mporaloko", 6, -74, -130, 42, 0, 0, 0, 0, 0}, |
282 | | {0, 139, "North_Sahara_1959", 6, -186, -93, 310, 0, 0, 0, 0, 0}, |
283 | | {0, 140, "Observatorio_Met_1939", 4, -425, -169, 81, 0, 0, 0, 0, 0}, |
284 | | {6620, 141, "Point_58", 6, -106, -129, 165, 0, 0, 0, 0, 0}, |
285 | | {6282, 142, "Pointe_Noire", 6, -148, 51, -291, 0, 0, 0, 0, 0}, |
286 | | {6615, 143, "Porto_Santo_1936", 4, -499, -249, 314, 0, 0, 0, 0, 0}, |
287 | | {6616, 144, "Selvagem_Grande_1938", 4, -289, -124, 60, 0, 0, 0, 0, 0}, |
288 | | {0, 145, "Sierra_Leone_1960", 6, -88, 4, 101, 0, 0, 0, 0, 0}, |
289 | | {6156, 146, "S_JTSK_Ferro", 10, 589, 76, 480, 0, 0, 0, 0, 0}, |
290 | | {6297, 147, "Tananarive_1925", 4, -189, -242, -91, 0, 0, 0, 0, 0}, |
291 | | {6811, 148, "Voirol_1874", 6, -73, -247, 227, 0, 0, 0, 0, 0}, |
292 | | {0, 149, "Virol_1960", 6, -123, -206, 219, 0, 0, 0, 0, 0}, |
293 | | {6148, 150, "Hartebeesthoek94", 28, 0, 0, 0, 0, 0, 0, 0, 0}, |
294 | | {6122, 151, "ATS77", 51, 0, 0, 0, 0, 0, 0, 0, 0}, |
295 | | {6612, 152, "JGD2000", 0, 0, 0, 0, 0, 0, 0, 0, 0}, |
296 | | {0, 153, "HGRS87", 0, -199.87, 74.79, 246.62, 0, 0, 0, 0, 0}, |
297 | | {6214, 154, "Beijing 1954", 3, -31.4, 144.3, 81.2, 0, 0, 0, 0, 0}, |
298 | | {6754, 155, "Libya (LGD 2006)", 4, 208.4058, 109.8777, 2.5764, 0, 0, 0, 0, |
299 | | 0}, |
300 | | {6317, 156, "Dealul Piscului 1970", 3, 28, -121, -77, 0, 0, 0, 0, 0}, |
301 | | {0, 157, "WGS_1984", 54, 0, 0, 0, 0, 0, 0, 0, 0}, // Google merc |
302 | | {6150, 158, "CH1903+ datum for Switzerland", 10, 674.374, 15.056, 405.346, |
303 | | 0, 0, 0, 0, 0}, |
304 | | {0, 159, "Schwarzeck (updated) datum for Namibia", 14, 616.8, 103.3, -256.9, |
305 | | 0, 0, 0, 0, 0}, |
306 | | {0, 161, "NOAA GCS_Sphere", 55, 0, 0, 0, 0, 0, 0, 0, 0}, |
307 | | // Ellipsoid 40 got from https://docs.precisely.com/docs/sftw/mapinfo-pro/v2021/en-us/pdf/mapinfo-pro-v2021-user-guide.pdf |
308 | | // Ellipsoid 40 is "Everest (India 1956)", 6377301.243, 300.80174 |
309 | | // but EPSG uses "Everest 1830 (RSO 1969)",6377295.664,300.8017 |
310 | | {6751, 164, "Kertau (RSO)", 40, -11, 851, 5, 0, 0, 0, 0, 0}, |
311 | | {0, 1000, "DHDN_Potsdam_Rauenberg", 10, 582, 105, 414, -1.04, -0.35, 3.08, |
312 | | 8.3, 0}, |
313 | | {6284, 1001, "Pulkovo_1942", 3, 24, -123, -94, -0.02, 0.25, 0.13, 1.1, 0}, |
314 | | {6807, 1002, "NTF_Paris_Meridian", 30, -168, -60, 320, 0, 0, 0, 0, |
315 | | 2.337229166667}, |
316 | | {6149, 1003, "Switzerland_CH_1903", 10, 660.077, 13.551, 369.344, 0.804816, |
317 | | 0.577692, 0.952236, 5.66, 0}, |
318 | | {6237, 1004, "Hungarian_Datum_1972", 21, -56, 75.77, 15.31, -0.37, -0.2, |
319 | | -0.21, -1.01, 0}, |
320 | | {0, 1005, "Cape_7_Parameter", 28, -134.73, -110.92, -292.66, 0, 0, 0, 1, 0}, |
321 | | {6203, 1006, "AGD84_7_Param_Aust", 2, -117.763, -51.51, 139.061, -0.292, |
322 | | -0.443, -0.277, -0.191, 0}, |
323 | | {0, 1007, "AGD66_7_Param_ACT", 2, -129.193, -41.212, 130.73, -0.246, -0.374, |
324 | | -0.329, -2.955, 0}, |
325 | | {0, 1008, "AGD66_7_Param_TAS", 2, -120.271, -64.543, 161.632, -0.2175, |
326 | | 0.0672, 0.1291, 2.4985, 0}, |
327 | | {0, 1009, "AGD66_7_Param_VIC_NSW", 2, -119.353, -48.301, 139.484, -0.415, |
328 | | -0.26, -0.437, -0.613, 0}, |
329 | | {6272, 1010, "NZGD_7_Param_49", 4, 59.47, -5.04, 187.44, -0.47, 0.1, -1.024, |
330 | | -4.5993, 0}, |
331 | | {0, 1011, "Rikets_Tri_7_Param_1990", 10, 419.3836, 99.3335, 591.3451, |
332 | | -0.850389, -1.817277, 7.862238, -0.99496, 0}, |
333 | | {0, 1012, "Russia_PZ90", 52, -1.08, -0.27, -0.9, 0, 0, -0.16, -0.12, 0}, |
334 | | {0, 1013, "Russia_SK42", 52, 23.92, -141.27, -80.9, 0, -0.35, -0.82, -0.12, |
335 | | 0}, |
336 | | {0, 1014, "Russia_SK95", 52, 24.82, -131.21, -82.66, 0, 0, -0.16, -0.12, 0}, |
337 | | {6301, 1015, "Tokyo", 10, -146.414, 507.337, 680.507, 0, 0, 0, 0, 0}, |
338 | | {6123, 1016, "Kartastokoordinaattijarjestelma_1966", 4, -96.062, -82.428, |
339 | | -121.754, -4.801, -0.345, 1.376, 1.496, 0}, |
340 | | {6610, 1017, "Xian 1980", 53, 24, -123, -94, -0.02, -0.25, 0.13, 1.1, 0}, |
341 | | {0, 1018, "Lithuanian Pulkovo 1942", 4, -40.59527, -18.54979, -69.33956, |
342 | | -2.508, -1.8319, 2.6114, -4.2991, 0}, |
343 | | {6313, 1019, "Belgian 1972 7 Parameter", 4, -99.059, 53.322, -112.486, |
344 | | -0.419, 0.83, -1.885, 0.999999, 0}, |
345 | | {6818, 1020, "S-JTSK with Ferro prime meridian", 10, 589, 76, 480, 0, 0, 0, |
346 | | 0, -17.666666666667}, |
347 | | {1031, 1021, "Serbia datum MGI 1901", 10, 574.027, 170.175, 401.545, |
348 | | 4.88786, -0.66524, -13.24673, 6.88933, 0}, |
349 | | {0, 1022, "North Sahara 7-parameter", 6, -38.7086, -128.8054, 118.8837, |
350 | | 0.83822, 7.38459, -1.57989, 3.9904, 0}, |
351 | | {0, 1023, "Hungarian Projection System (EOV) - updated", 21, 52.684, |
352 | | -71.194, -13.975, 0.312, 0.1063, 0.3729, 1.0191, 0}, |
353 | | {1052, 1024, "S-JTSK (Krovak) Coordinate system - updated", 10, 570.6934, |
354 | | 85.6936, 462.8393, -4.99825, -1.58663, -5.26114, 3.5430155, 0}, |
355 | | {0, 1025, "JTSK03 (Slovak Republic)", 10, 485.014055, 169.473618, |
356 | | 483.842943, -7.78625453, -4.39770887, -4.10248899, 0, 0}, |
357 | | {1168, 1028, "Geocentric Datum of Australia 2020", 0, -0.06155, 0.01087, |
358 | | 0.04019, 0.0394924, 0.0327221, 0.0328979, 0.009994, 0}, |
359 | | // For some weird reason, MapInfo uses nEllipsoid=8 "Clarke 1866 (modified |
360 | | // for Michigan)" cf |
361 | | // https://docs.precisely.com/docs/sftw/mapinfo-pro/v2021.1/en-us/pdf/mapinfo-pro-v2021.1-release-notes.pdf |
362 | | // page 8 whereas EPSG uses the regular Clarke 1866 ellipsoid. |
363 | | {6683, 1031, "Philippine Reference System 1992", 8, -127.62, -67.24, -47.04, |
364 | | -3.068, 4.903, 1.578, -1.06, 0}, |
365 | | {0, 9999, "Bosnia-Herzegovina", 10, 472.8677, 187.8769, 544.7084, |
366 | | -5.76198422, -5.3222842, 12.80666941, 1.54517287, 0}, |
367 | | {6181, 9999, "Luxembourg 1930 / Gauss", 4, -192.986, 13.673, -39.309, |
368 | | 0.4099, 2.9332, -2.6881, 0.43, 0}, |
369 | | {1168, 9999, "Geocentric Datum of Australia 2020", 0, -0.06155, 0.01087, |
370 | | 0.04019, 0.0394924, 0.0327221, 0.0328979, 0.009994, 0}, |
371 | | {-1, -1, nullptr, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; |
372 | | |
373 | | /* -------------------------------------------------------------------- */ |
374 | | /* This table was hand entered from Appendix I of the mapinfo 6 */ |
375 | | /* manuals. */ |
376 | | /* -------------------------------------------------------------------- */ |
377 | | |
378 | | const MapInfoSpheroidInfo asSpheroidInfoList[] = { |
379 | | {9, "Airy 1930", 6377563.396, 299.3249646}, |
380 | | {13, "Airy 1930 (modified for Ireland 1965", 6377340.189, 299.3249646}, |
381 | | {51, "ATS77 (Average Terrestrial System 1977)", 6378135, 298.257}, |
382 | | {2, "Australian", 6378160.0, 298.25}, |
383 | | {10, "Bessel 1841", 6377397.155, 299.1528128}, |
384 | | {35, "Bessel 1841 (modified for NGO 1948)", 6377492.0176, 299.15281}, |
385 | | {14, "Bessel 1841 (modified for Schwarzeck)", 6377483.865, 299.1528128}, |
386 | | {36, "Clarke 1858", 6378293.639, 294.26068}, |
387 | | {7, "Clarke 1866", 6378206.4, 294.9786982}, |
388 | | {8, "Clarke 1866 (modified for Michigan)", 6378450.047484481, 294.9786982}, |
389 | | {6, "Clarke 1880", 6378249.145, 293.465}, |
390 | | {15, "Clarke 1880 (modified for Arc 1950)", 6378249.145326, 293.4663076}, |
391 | | {30, "Clarke 1880 (modified for IGN)", 6378249.2, 293.4660213}, |
392 | | {37, "Clarke 1880 (modified for Jamaica)", 6378249.136, 293.46631}, |
393 | | {16, "Clarke 1880 (modified for Merchich)", 6378249.2, 293.46598}, |
394 | | {38, "Clarke 1880 (modified for Palestine)", 6378300.79, 293.46623}, |
395 | | {39, "Everest (Brunei and East Malaysia)", 6377298.556, 300.8017}, |
396 | | {11, "Everest (India 1830)", 6377276.345, 300.8017}, |
397 | | {40, "Everest (India 1956)", 6377301.243, 300.80174}, |
398 | | {50, "Everest (Pakistan)", 6377309.613, 300.8017}, |
399 | | {17, "Everest (W. Malaysia and Singapore 1948)", 6377304.063, 300.8017}, |
400 | | {48, "Everest (West Malaysia 1969)", 6377304.063, 300.8017}, |
401 | | {18, "Fischer 1960", 6378166.0, 298.3}, |
402 | | {19, "Fischer 1960 (modified for South Asia)", 6378155.0, 298.3}, |
403 | | {20, "Fischer 1968", 6378150.0, 298.3}, |
404 | | {21, "GRS 67", 6378160.0, 298.247167427}, |
405 | | {0, "GRS 80", 6378137.0, 298.257222101}, |
406 | | {56, "GSK2011", 6378136.5, 298.2564151}, |
407 | | {5, "Hayford", 6378388.0, 297.0}, |
408 | | {22, "Helmert 1906", 6378200.0, 298.3}, |
409 | | {23, "Hough", 6378270.0, 297.0}, |
410 | | {31, "IAG 75", 6378140.0, 298.257222}, |
411 | | {41, "Indonesian", 6378160.0, 298.247}, |
412 | | {4, "International 1924", 6378388.0, 297.0}, |
413 | | {49, "Irish (WOFO)", 6377542.178, 299.325}, |
414 | | {3, "Krassovsky", 6378245.0, 298.3}, |
415 | | {32, "MERIT 83", 6378137.0, 298.257}, |
416 | | {33, "New International 1967", 6378157.5, 298.25}, |
417 | | {42, "NWL 9D", 6378145.0, 298.25}, |
418 | | {43, "NWL 10D", 6378135.0, 298.26}, |
419 | | {44, "OSU86F", 6378136.2, 298.25722}, |
420 | | {45, "OSU91A", 6378136.3, 298.25722}, |
421 | | {46, "Plessis 1817", 6376523.0, 308.64}, |
422 | | {52, "PZ90", 6378136.0, 298.257839303}, |
423 | | {57, "PZ90.11", 6378136.0, 298.25784}, |
424 | | {24, "South American", 6378160.0, 298.25}, |
425 | | {12, "Sphere", 6370997.0, 0.0}, |
426 | | {47, "Struve 1860", 6378297.0, 294.73}, |
427 | | {34, "Walbeck", 6376896.0, 302.78}, |
428 | | {25, "War Office", 6378300.583, 296.0}, |
429 | | {26, "WGS 60", 6378165.0, 298.3}, |
430 | | {27, "WGS 66", 6378145.0, 298.25}, |
431 | | {1, "WGS 72", 6378135.0, 298.26}, |
432 | | {28, "WGS 84", 6378137.0, 298.257223563}, |
433 | | {29, "WGS 84 (MAPINFO Datum 0)", 6378137.01, 298.257223563}, |
434 | | {54, "WGS 84 (MAPINFO Datum 157)", 6378137.01, 298.257223563}, |
435 | | {-1, nullptr, 0.0, 0.0}}; |
436 | | |
437 | | /* For LCC, standard parallel 1 and 2 can be switched indifferently */ |
438 | | /* So the MapInfo order and the EPSG order are not generally identical */ |
439 | | /* which may cause recognition problems when reading in MapInfo */ |
440 | | /* This table contains the parameters in the order expected by MapInfo */ |
441 | | typedef struct |
442 | | { |
443 | | int nEPSGCode; |
444 | | int bReverseStdP; |
445 | | int nMapInfoDatumID; |
446 | | double dfCenterLong; |
447 | | double dfCenterLat; |
448 | | double dfStdP1; |
449 | | double dfStdP2; |
450 | | } MapInfoLCCSRS; |
451 | | |
452 | | static const MapInfoLCCSRS asMapInfoLCCSRSList[] = { |
453 | | {2154, 1, 33, 3, 46.5, 44, 49}, |
454 | | {2154, 1, 33, 3, 46.5, 44, 49.00000000001}, |
455 | | {2154, 1, 33, 3, 46.5, 44, 49.00000000002}, |
456 | | {2225, 1, 74, -122, 39.3333333333, 40, 41.6666666667}, |
457 | | {2226, 1, 74, -122, 37.6666666667, 38.3333333333, 39.8333333333}, |
458 | | {2227, 1, 74, -120.5, 36.5, 37.0666666667, 38.4333333333}, |
459 | | {2228, 1, 74, -119, 35.3333333333, 36, 37.25}, |
460 | | {2229, 1, 74, -118, 33.5, 34.0333333333, 35.4666666667}, |
461 | | {2230, 1, 74, -116.25, 32.1666666667, 32.7833333333, 33.8833333333}, |
462 | | {2231, 1, 74, -105.5, 39.3333333333, 39.7166666667, 40.7833333333}, |
463 | | {2232, 1, 74, -105.5, 37.8333333333, 38.45, 39.75}, |
464 | | {2233, 1, 74, -105.5, 36.6666666667, 37.2333333333, 38.4333333333}, |
465 | | {2234, 1, 74, -72.75, 40.8333333333, 41.2, 41.8666666667}, |
466 | | {2238, 1, 74, -84.5, 29, 29.5833333333, 30.75}, |
467 | | {2246, 0, 74, -84.25, 37.5, 37.9666666667, 38.9666666667}, |
468 | | {2247, 1, 74, -85.75, 36.3333333333, 36.7333333333, 37.9333333333}, |
469 | | {2248, 1, 74, -77, 37.6666666667, 38.3, 39.45}, |
470 | | {2249, 1, 74, -71.5, 41, 41.7166666667, 42.6833333333}, |
471 | | {2250, 1, 74, -70.5, 41, 41.2833333333, 41.4833333333}, |
472 | | {2251, 1, 74, -87, 44.7833333333, 45.4833333333, 47.0833333333}, |
473 | | {2252, 1, 74, -84.3666666667, 43.3166666667, 44.1833333333, 45.7}, |
474 | | {2253, 1, 74, -84.3666666667, 41.5, 42.1, 43.6666666667}, |
475 | | {2256, 1, 74, -109.5, 44.25, 45, 49}, |
476 | | {2263, 1, 74, -74, 40.1666666667, 40.6666666667, 41.0333333333}, |
477 | | {2264, 1, 74, -79, 33.75, 34.3333333333, 36.1666666667}, |
478 | | {2265, 1, 74, -100.5, 47, 47.4333333333, 48.7333333333}, |
479 | | {2266, 1, 74, -100.5, 45.6666666667, 46.1833333333, 47.4833333333}, |
480 | | {2267, 1, 74, -98, 35, 35.5666666667, 36.7666666667}, |
481 | | {2268, 1, 74, -98, 33.3333333333, 33.9333333333, 35.2333333333}, |
482 | | {2269, 1, 74, -120.5, 43.6666666667, 44.3333333333, 46}, |
483 | | {2270, 1, 74, -120.5, 41.6666666667, 42.3333333333, 44}, |
484 | | {2271, 1, 74, -77.75, 40.1666666667, 40.8833333333, 41.95}, |
485 | | {2272, 1, 74, -77.75, 39.3333333333, 39.9333333333, 40.9666666667}, |
486 | | {2273, 1, 74, -81, 31.8333333333, 32.5, 34.8333333333}, |
487 | | {2274, 1, 74, -86, 34.3333333333, 35.25, 36.4166666667}, |
488 | | {2275, 1, 74, -101.5, 34, 34.65, 36.1833333333}, |
489 | | {2276, 1, 74, -98.5, 31.6666666667, 32.1333333333, 33.9666666667}, |
490 | | {2277, 1, 74, -100.3333333333, 29.6666666667, 30.1166666667, 31.8833333333}, |
491 | | {2278, 1, 74, -99, 27.8333333333, 28.3833333333, 30.2833333333}, |
492 | | {2279, 1, 74, -98.5, 25.6666666667, 26.1666666667, 27.8333333333}, |
493 | | {2280, 1, 74, -111.5, 40.3333333333, 40.7166666667, 41.7833333333}, |
494 | | {2281, 1, 74, -111.5, 38.3333333333, 39.0166666667, 40.65}, |
495 | | {2282, 1, 74, -111.5, 36.6666666667, 37.2166666667, 38.35}, |
496 | | {2283, 1, 74, -78.5, 37.6666666667, 38.0333333333, 39.2}, |
497 | | {2284, 1, 74, -78.5, 36.3333333333, 36.7666666667, 37.9666666667}, |
498 | | {2285, 1, 74, -120.8333333333, 47, 47.5, 48.7333333333}, |
499 | | {2286, 1, 74, -120.5, 45.3333333333, 45.8333333333, 47.3333333333}, |
500 | | {2287, 1, 74, -90, 45.1666666667, 45.5666666667, 46.7666666667}, |
501 | | {2288, 1, 74, -90, 43.8333333333, 44.25, 45.5}, |
502 | | {2289, 1, 74, -90, 42, 42.7333333333, 44.0666666667}, |
503 | | {26740, 1, 63, -176, 51, 51.8333333333, 53.8333333333}, |
504 | | {26741, 1, 62, -122, 39.3333333333, 40, 41.6666666667}, |
505 | | {26742, 1, 62, -122, 37.6666666667, 38.3333333333, 39.8333333333}, |
506 | | {26743, 1, 62, -120.5, 36.5, 37.0666666667, 38.4333333333}, |
507 | | {26744, 1, 62, -119, 35.3333333333, 36, 37.25}, |
508 | | {26745, 1, 62, -118, 33.5, 34.0333333333, 35.4666666667}, |
509 | | {26746, 1, 62, -116.25, 32.1666666667, 32.7833333333, 33.8833333333}, |
510 | | {26747, 1, 62, -118.3333333333, 34.1333333333, 33.8666666667, |
511 | | 34.4166666667}, |
512 | | {26751, 1, 62, -92, 34.3333333333, 34.9333333333, 36.2333333333}, |
513 | | {26752, 1, 62, -92, 32.6666666667, 33.3, 34.7666666667}, |
514 | | {26753, 0, 62, -105.5, 39.3333333333, 39.7166666667, 40.7833333333}, |
515 | | {26754, 1, 62, -105.5, 37.8333333333, 38.45, 39.75}, |
516 | | {26755, 1, 62, -105.5, 36.6666666667, 37.2333333333, 38.4333333333}, |
517 | | {26756, 1, 62, -72.75, 40.8333333333, 41.2, 41.8666666667}, |
518 | | {26760, 1, 62, -84.5, 29, 29.5833333333, 30.75}, |
519 | | {26775, 1, 62, -93.5, 41.5, 42.0666666667, 43.2666666667}, |
520 | | {26776, 1, 62, -93.5, 40, 40.6166666667, 41.7833333333}, |
521 | | {26777, 1, 62, -98, 38.3333333333, 38.7166666667, 39.7833333333}, |
522 | | {26778, 0, 62, -98.5, 36.6666666667, 38.5666666667, 37.2666666667}, |
523 | | {26779, 0, 62, -84.25, 37.5, 37.9666666667, 38.9666666667}, |
524 | | {26780, 0, 62, -85.75, 36.3333333333, 36.7333333333, 37.9333333333}, |
525 | | {26781, 0, 62, -92.5, 30.6666666667, 31.1666666667, 32.6666666667}, |
526 | | {26785, 0, 62, -77, 37.8333333333, 38.3, 39.45}, |
527 | | {26786, 0, 62, -71.5, 41, 41.7166666667, 42.6833333333}, |
528 | | {26788, 0, 73, -87, 44.7833333333, 45.4833333333, 47.0833333333}, |
529 | | {26789, 0, 73, -84.3333333333, 43.3166666667, 44.1833333333, 45.7}, |
530 | | {26790, 0, 73, -84.3333333333, 41.5, 42.1, 43.6666666667}, |
531 | | {26791, 0, 62, -93.1, 46.5, 47.0333333333, 48.6333333333}, |
532 | | {26792, 0, 62, -94.25, 45, 45.6166666667, 47.05}, |
533 | | {26793, 0, 62, -94, 43, 43.7833333333, 45.2166666667}, |
534 | | {26940, 1, 74, -176, 51, 51.8333333333, 53.8333333333}, |
535 | | {26941, 1, 74, -122, 39.3333333333, 40, 41.6666666667}, |
536 | | {26942, 1, 74, -122, 37.6666666667, 38.3333333333, 39.8333333333}, |
537 | | {26943, 1, 74, -120.5, 36.5, 37.0666666667, 38.4333333333}, |
538 | | {26944, 1, 74, -119, 35.3333333333, 36, 37.25}, |
539 | | {26945, 1, 74, -118, 33.5, 34.0333333333, 35.4666666667}, |
540 | | {26946, 1, 74, -116.25, 32.1666666667, 32.7833333333, 33.8833333333}, |
541 | | {26951, 1, 74, -92, 34.3333333333, 34.9333333333, 36.2333333333}, |
542 | | {26952, 1, 74, -92, 32.6666666667, 33.3, 34.7666666667}, |
543 | | {26953, 1, 74, -105.5, 39.3333333333, 39.7166666667, 40.7833333333}, |
544 | | {26954, 1, 74, -105.5, 37.8333333333, 38.45, 39.75}, |
545 | | {26955, 1, 74, -105.5, 36.6666666667, 37.2333333333, 38.4333333333}, |
546 | | {26956, 1, 74, -72.75, 40.8333333333, 41.2, 41.8666666667}, |
547 | | {26960, 1, 74, -84.5, 29, 29.5833333333, 30.75}, |
548 | | {26975, 1, 74, -93.5, 41.5, 42.0666666667, 43.2666666667}, |
549 | | {26976, 1, 74, -93.5, 40, 40.6166666667, 41.7833333333}, |
550 | | {26977, 1, 74, -98, 38.3333333333, 38.7166666667, 39.7833333333}, |
551 | | {26978, 0, 74, -98.5, 36.6666666667, 38.5666666667, 37.2666666667}, |
552 | | {26980, 1, 74, -85.75, 36.3333333333, 36.7333333333, 37.9333333333}, |
553 | | {26981, 1, 74, -92.5, 30.5, 31.1666666667, 32.6666666667}, |
554 | | {26982, 1, 74, -91.3333333333, 28.5, 29.3, 30.7}, |
555 | | {26985, 1, 74, -77, 37.6666666667, 38.3, 39.45}, |
556 | | {26986, 1, 74, -71.5, 41, 41.7166666667, 42.6833333333}, |
557 | | {26987, 1, 74, -70.5, 41, 41.2833333333, 41.4833333333}, |
558 | | {26988, 1, 74, -87, 44.7833333333, 45.4833333333, 47.0833333333}, |
559 | | {26989, 1, 74, -84.3666666667, 43.3166666667, 44.1833333333, 45.7}, |
560 | | {26990, 1, 74, -84.3666666667, 41.5, 42.1, 43.6666666667}, |
561 | | {26991, 1, 74, -93.1, 46.5, 47.0333333333, 48.6333333333}, |
562 | | {26992, 1, 74, -94.25, 45, 45.6166666667, 47.05}, |
563 | | {26993, 1, 74, -94, 43, 43.7833333333, 45.2166666667}, |
564 | | {3111, 0, 116, 145, -37, -36, -38}, |
565 | | {31370, 1, 1019, 4.3674866667, 90, 49.8333339000, 51.1666672333}, |
566 | | {32001, 1, 62, -109.5, 47, 47.85, 48.7166666667}, |
567 | | {32002, 1, 62, -109.5, 45.8333333333, 46.45, 47.8833333333}, |
568 | | {32003, 1, 62, -109.5, 44, 44.8666666667, 46.4}, |
569 | | {32005, 0, 62, -100, 41.3333333333, 41.85, 42.8166666667}, |
570 | | {32006, 0, 62, -99.5, 39.6666666667, 40.2833333333, 41.7166666667}, |
571 | | {32018, 1, 62, -74, 40.5, 40.6666666667, 41.0333333333}, |
572 | | {32019, 0, 62, -79, 33.75, 34.3333333333, 36.1666666667}, |
573 | | {32020, 0, 62, -100.5, 47, 47.4333333333, 48.7333333333}, |
574 | | {32021, 0, 62, -100.5, 45.6666666667, 46.1833333333, 47.4833333333}, |
575 | | {32022, 0, 62, -82.5, 39.6666666667, 40.4333333333, 41.7}, |
576 | | {32023, 0, 62, -82.5, 38, 38.7333333333, 40.0333333333}, |
577 | | {32024, 0, 62, -98, 35, 35.5666666667, 36.7666666667}, |
578 | | {32025, 0, 62, -98, 33.3333333333, 33.9333333333, 35.2333333333}, |
579 | | {32026, 0, 62, -120.5, 43.6666666667, 44.3333333333, 46}, |
580 | | {32027, 0, 62, -120.5, 41.6666666667, 42.3333333333, 44}, |
581 | | {32028, 0, 62, -77.75, 40.1666666667, 40.8833333333, 41.95}, |
582 | | {32031, 0, 62, -81, 33, 33.7666666667, 34.9666666667}, |
583 | | {32033, 0, 62, -81, 31.8333333333, 32.3333333333, 33.6666666667}, |
584 | | {32034, 0, 62, -100, 43.8333333333, 44.4166666667, 45.6833333333}, |
585 | | {32035, 0, 62, -100.3333333333, 42.3333333333, 42.8333333333, 44.4}, |
586 | | {32036, 0, 62, -86, 34.6666666667, 35.25, 36.4166666667}, |
587 | | {32037, 0, 62, -101.5, 34, 34.65, 36.1833333333}, |
588 | | {32038, 0, 62, -97.5, 31.6666666667, 32.1333333333, 33.9666666667}, |
589 | | {32039, 0, 62, -100.3333333333, 29.6666666667, 30.1166666667, |
590 | | 31.8833333333}, |
591 | | {32040, 0, 62, -99, 27.8333333333, 28.3833333333, 30.2833333333}, |
592 | | {32041, 0, 62, -98.5, 25.6666666667, 26.1666666667, 27.8333333333}, |
593 | | {32042, 0, 62, -111.5, 40.3333333333, 40.7166666667, 41.7833333333}, |
594 | | {32043, 0, 62, -111.5, 38.3333333333, 39.0166666667, 40.65}, |
595 | | {32044, 0, 62, -111.5, 36.6666666667, 37.2166666667, 38.35}, |
596 | | {32046, 0, 62, -78.5, 37.6666666667, 38.0333333333, 39.2}, |
597 | | {32047, 0, 62, -78.5, 36.3333333333, 36.7666666667, 37.9666666667}, |
598 | | {32048, 0, 62, -120.8333333333, 47, 47.5, 48.7333333333}, |
599 | | {32049, 0, 62, -120.5, 45.3333333333, 45.8333333333, 47.3333333333}, |
600 | | {32050, 0, 62, -79.5, 38.5, 39, 40.25}, |
601 | | {32051, 0, 62, -81, 37, 37.4833333333, 38.8833333333}, |
602 | | {32052, 0, 62, -90, 45.1666666667, 45.5666666667, 46.7666666667}, |
603 | | {32053, 0, 62, -90, 43.8333333333, 44.25, 45.5}, |
604 | | {32054, 0, 62, -90, 42, 42.7333333333, 44.0666666667}, |
605 | | {32059, 0, 62, -66.4333333333, 18.4333333333, 18.0333333333, 18.4333333333}, |
606 | | {32060, 0, 62, -66.4333333333, 18.4333333333, 18.0333333333, 18.4333333333}, |
607 | | {32100, 1, 74, -109.5, 44.25, 45, 49}, |
608 | | {32104, 1, 74, -100, 39.8333333333, 40, 43}, |
609 | | {32118, 1, 74, -74, 40.1666666667, 40.6666666667, 41.0333333333}, |
610 | | {32119, 1, 74, -79, 33.75, 34.3333333333, 36.1666666667}, |
611 | | {32120, 1, 74, -100.5, 47, 47.4333333333, 48.7333333333}, |
612 | | {32121, 1, 74, -100.5, 45.6666666667, 46.1833333333, 47.4833333333}, |
613 | | {32122, 1, 74, -82.5, 39.6666666667, 40.4333333333, 41.7}, |
614 | | {32123, 1, 74, -82.5, 38, 38.7333333333, 40.0333333333}, |
615 | | {32124, 1, 74, -98, 35, 35.5666666667, 36.7666666667}, |
616 | | {32125, 1, 74, -98, 33.3333333333, 33.9333333333, 35.2333333333}, |
617 | | {32126, 1, 74, -120.5, 43.6666666667, 44.3333333333, 46}, |
618 | | {32127, 1, 74, -120.5, 41.6666666667, 42.3333333333, 44}, |
619 | | {32128, 1, 74, -77.75, 40.1666666667, 40.8833333333, 41.95}, |
620 | | {32129, 1, 74, -77.75, 39.3333333333, 39.9333333333, 40.9666666667}, |
621 | | {32133, 1, 74, -81, 31.8333333333, 32.5, 34.8333333333}, |
622 | | {32134, 1, 74, -100, 43.8333333333, 44.4166666667, 45.6833333333}, |
623 | | {32135, 1, 74, -100.3333333333, 42.3333333333, 42.8333333333, 44.4}, |
624 | | {32136, 1, 74, -86, 34.3333333333, 35.25, 36.4166666667}, |
625 | | {32137, 1, 74, -101.5, 34, 34.65, 36.1833333333}, |
626 | | {32138, 1, 74, -98.5, 31.6666666667, 32.1333333333, 33.9666666667}, |
627 | | {32139, 1, 74, -100.3333333333, 29.6666666667, 30.1166666667, |
628 | | 31.8833333333}, |
629 | | {32140, 1, 74, -99, 27.8333333333, 28.3833333333, 30.2833333333}, |
630 | | {32141, 1, 74, -98.5, 25.6666666667, 26.1666666667, 27.8333333333}, |
631 | | {32142, 1, 74, -111.5, 40.3333333333, 40.7166666667, 41.7833333333}, |
632 | | {32143, 1, 74, -111.5, 38.3333333333, 39.0166666667, 40.65}, |
633 | | {32144, 1, 74, -111.5, 36.6666666667, 37.2166666667, 38.35}, |
634 | | {32146, 1, 74, -78.5, 37.6666666667, 38.0333333333, 39.2}, |
635 | | {32147, 1, 74, -78.5, 36.3333333333, 36.7666666667, 37.9666666667}, |
636 | | {32148, 1, 74, -120.8333333333, 47, 47.5, 48.7333333333}, |
637 | | {32149, 1, 74, -120.5, 45.3333333333, 45.8333333333, 47.3333333333}, |
638 | | {32150, 1, 74, -79.5, 38.5, 39, 40.25}, |
639 | | {32151, 1, 74, -81, 37, 37.4833333333, 38.8833333333}, |
640 | | {32152, 1, 74, -90, 45.1666666667, 45.5666666667, 46.7666666667}, |
641 | | {32153, 1, 74, -90, 43.8333333333, 44.25, 45.5}, |
642 | | {32154, 1, 74, -90, 42, 42.7333333333, 44.0666666667}, |
643 | | {32161, 1, 74, -66.4333333333, 17.8333333333, 18.0333333333, 18.4333333333}, |
644 | | {3300, 1, 115, 24, 57.51755394, 58, 59.33333333}, |
645 | | {3301, 1, 115, 24, 57.51755393056, 58, 59.33333333}, |
646 | | {3797, 0, 66, -70, 44, 50, 46}, |
647 | | {3798, 0, 74, -70, 44, 50, 46}, |
648 | | {3799, 0, 74, -70, 44, 50, 46}, |
649 | | {3942, 0, 33, 3, 42, 41.25, 42.75}, |
650 | | {3943, 0, 33, 3, 43, 42.25, 43.75}, |
651 | | {3944, 0, 33, 3, 44, 43.25, 44.75}, |
652 | | {3945, 0, 33, 3, 45, 44.25, 45.75}, |
653 | | {3946, 0, 33, 3, 46, 45.25, 46.75}, |
654 | | {3947, 0, 33, 3, 47, 46.25, 47.75}, |
655 | | {3948, 0, 33, 3, 48, 47.25, 48.75}, |
656 | | {3949, 0, 33, 3, 49, 48.25, 49.75}, |
657 | | {3950, 0, 33, 3, 50, 49.25, 50.75}, |
658 | | {42101, 0, 104, -95, 0, 49, 77}, |
659 | | {42103, 0, 104, -100, 0, 33, 45}, |
660 | | {42304, 0, 74, -95, 49, 49, 77}, |
661 | | {0, 0, 0, 110, 10, 25, 40}, |
662 | | {0, 0, 0, 132.5, -10, -21.5, -33.5}, |
663 | | {0, 0, 0, 25, 35, 40, 65}, |
664 | | {0, 0, 0, 47.5, 25, 15, 35}, |
665 | | {0, 0, 0, 95, 40, 20, 60}, |
666 | | {0, 0, 1002, 0, 42.165, 41.5603877778, 42.76766333}, |
667 | | {0, 0, 1002, 0, 42.165, 41.5603877778, 42.767663333}, |
668 | | {0, 0, 1002, 0, 42.165, 41.560387778, 42.76766333}, |
669 | | {0, 0, 1002, 0, 42.165, 41.560387778, 42.767663333}, |
670 | | {0, 0, 1002, 0, 42.165, 41.56038778, 42.76766333}, |
671 | | {0, 0, 1002, 0, 42.165, 41.560387840948, 42.76766346965}, |
672 | | {0, 0, 1002, 0, 44.1, 43.199291275544, 44.996093814511}, |
673 | | {0, 0, 1002, 0, 44.1, 43.1992913889, 44.99609389}, |
674 | | {0, 0, 1002, 0, 44.1, 43.199291389, 44.99609389}, |
675 | | {0, 0, 1002, 0, 44.1, 43.19929139, 44.99609389}, |
676 | | {0, 0, 1002, 0, 46.8, 45.8989188889, 47.69601444}, |
677 | | {0, 0, 1002, 0, 46.8, 45.898918889, 47.69601444}, |
678 | | {0, 0, 1002, 0, 46.8, 45.89891889, 47.69601444}, |
679 | | {0, 0, 1002, 0, 46.8, 45.898918964419, 47.696014502038}, |
680 | | {0, 0, 1002, 0, 49.5, 48.5985227778, 50.39591167}, |
681 | | {0, 0, 1002, 0, 49.5, 48.598522778, 50.39591167}, |
682 | | {0, 0, 1002, 0, 49.5, 48.59852278, 50.39591167}, |
683 | | {0, 0, 1002, 0, 49.5, 48.598522847174, 50.395911631678}, |
684 | | {0, 0, 1005, 23, -23, -18, -32}, |
685 | | {0, 0, 1022, 2.7, 36, 37.575, 34.425}, |
686 | | {0, 0, 104, 13.33333333, 47.5, 46, 49}, |
687 | | {0, 0, 104, 13.33333333, 48, 46, 49}, |
688 | | {0, 0, 104, -19, 65, 64.25, 65.75}, |
689 | | {0, 0, 104, 36.0, 25.0, 37.5, 40.5}, |
690 | | {0, 0, 104, 36, 25, 37.5, 40.5}, |
691 | | {0, 0, 104, 70, -50, -68.5, -74.5}, |
692 | | {0, 0, 110, 4.367975, 90, 49.8333333333, 51.1666666667}, |
693 | | {0, 0, 115, 10, 52, 35, 45}, |
694 | | {0, 0, 116, 135, -24, -18, -36}, |
695 | | {0, 0, 116, 135, -32, -28, -36}, |
696 | | {0, 0, 12, 135, -24, -18, -36}, |
697 | | {0, 0, 12, 145, -37, -36, -38}, |
698 | | {0, 0, 13, 135, -24, -18, -36}, |
699 | | {0, 0, 19, 23, -23, -18, -32}, |
700 | | {0, 0, 28, 17, 29.77930555, 42, 56}, |
701 | | {0, 0, 28, 19, 29.77930555, 42, 56}, |
702 | | {0, 0, 28, 36.0, 25.0, 37.5, 40.5}, |
703 | | {0, 0, 33, 13.5, 0, 52.6666666667, 55.3333333333}, |
704 | | {0, 0, 33, 15, 0, 56.5, 60.5}, |
705 | | {0, 0, 33, 15, 0, 58, 66}, |
706 | | {0, 0, 33, 15, 0, 63.5, 67.5}, |
707 | | {0, 0, 33, 15.5, 0, 56.6666666667, 59.3333333333}, |
708 | | {0, 0, 33, 15.5, 0, 60.6666666667, 63.3333333333}, |
709 | | {0, 0, 33, 16.5, 0, 60.6666666667, 63.3333333333}, |
710 | | {0, 0, 33, 18.5, 0, 64.6666666667, 67.3333333333}, |
711 | | {0, 0, 33, 19, 0, 64.6666666667, 67.3333333333}, |
712 | | {0, 0, 55, -5.4, 22.5, 20.9075742561, 24.0921050540}, |
713 | | {0, 0, 55, -5.4, 26.1, 24.5075340813, 27.6921073632}, |
714 | | {0, 0, 55, -5.4, 29.7, 28.1063294800, 31.2932791054}, |
715 | | {0, 0, 55, -5.4, 33.3, 31.72786641202, 34.8717272112}, |
716 | | {0, 0, 62, -70.5, 41, 41.2833333333, 41.4833333333}, |
717 | | {0, 0, 62, -77.75, 39.3333333333, 39.9333333333, 40.9666666667}, |
718 | | {0, 0, 62, -91.3333333333, 25.6666666667, 26.1666666667, 27.8333333333}, |
719 | | {0, 0, 62, -91.3333333333, 28.6666666667, 29.3, 30.67}, |
720 | | {0, 0, 62, -96, 23, 20, 60}, |
721 | | {0, 0, 62, -96, 23, 33, 45}, |
722 | | {0, 0, 62, -96, 39, 33, 45}, |
723 | | {0, 0, 66, -68.5, 44, 46, 60}, |
724 | | {0, 0, 74, -100.3333333333, 42.3333333333, 42.8333333333, 44.4}, |
725 | | {0, 0, 74, -100, 39.8333333333, 40, 43}, |
726 | | {0, 0, 74, -100, 43.8333333333, 44.4166666667, 45.6833333333}, |
727 | | {0, 0, 74, -109.5, 44.25, 45, 49}, |
728 | | {0, 0, 74, -111.5, 36.6666666667, 37.2166666667, 38.35}, |
729 | | {0, 0, 74, -111.5, 38.3333333333, 39.0166666667, 40.65}, |
730 | | {0, 0, 74, -111.5, 40.3333333333, 40.7166666667, 41.7833333333}, |
731 | | {0, 0, 74, -120.5, 41.6666666667, 42.3333333333, 44}, |
732 | | {0, 0, 74, -120.5, 43.6666666667, 44.3333333333, 46}, |
733 | | {0, 0, 74, -176, 51, 51.8333333333, 53.8333333333}, |
734 | | {0, 0, 74, -66.4333333333, 17.8333333333, 18.0333333333, 18.4333333333}, |
735 | | {0, 0, 74, -68.5, 44, 46, 60}, |
736 | | {0, 0, 74, -79.5, 38.5, 39, 40.25}, |
737 | | {0, 0, 74, -81, 31.8333333333, 32.5, 34.8333333333}, |
738 | | {0, 0, 74, -81, 37, 37.4833333333, 38.8833333333}, |
739 | | {0, 0, 74, -82.5, 38, 38.7333333333, 40.0333333333}, |
740 | | {0, 0, 74, -82.5, 39.6666666667, 40.4333333333, 41.7}, |
741 | | {0, 0, 74, -84.25, 37.5, 37.9666666667, 38.9666666667}, |
742 | | {0, 0, 74, -84.3666666667, 41.5, 42.1, 43.6666666667}, |
743 | | {0, 0, 74, -84.3666666667, 43.3166666667, 44.1833333333, 45.7}, |
744 | | {0, 0, 74, -87, 44.7833333333, 45.4833333333, 47.0833333333}, |
745 | | {0, 0, 74, -91.3333333333, 25.5, 26.1666666667, 27.8333333333}, |
746 | | {0, 0, 74, -91.3333333333, 28.5, 29.3, 30.7}, |
747 | | {0, 0, 74, -92, 32.6666666667, 33.3, 34.7666666667}, |
748 | | {0, 0, 74, -92, 34.3333333333, 34.9333333333, 36.2333333333}, |
749 | | {0, 0, 74, -92.5, 30.5, 31.1666666667, 32.6666666667}, |
750 | | {0, 0, 74, -93.1, 46.5, 47.0333333333, 48.6333333333}, |
751 | | {0, 0, 74, -93.5, 40, 40.6166666667, 41.7833333333}, |
752 | | {0, 0, 74, -93.5, 41.5, 42.0666666667, 43.2666666667}, |
753 | | {0, 0, 74, -94.25, 45, 45.6166666667, 47.05}, |
754 | | {0, 0, 74, -94, 43, 43.7833333333, 45.2166666667}, |
755 | | {0, 0, 74, -98, 38.3333333333, 38.7166666667, 39.7833333333}, |
756 | | {0, 0, 74, -98.5, 36.6666666667, 38.5666666667, 37.2666666667}, |
757 | | }; |
758 | | |
759 | | /********************************************************************** |
760 | | * TABFile::GetSpatialRefFromTABProj() |
761 | | **********************************************************************/ |
762 | | |
763 | | static bool TAB_EQUAL(double a, double b) |
764 | 0 | { |
765 | 0 | return std::fabs(a - b) < 1.0e-10; |
766 | 0 | } |
767 | | |
768 | | OGRSpatialReference * |
769 | | TABFileGetSpatialRefFromTABProj(const TABProjInfo &sTABProj) |
770 | 0 | { |
771 | | /*----------------------------------------------------------------- |
772 | | * Get the units name, and translation factor. |
773 | | *----------------------------------------------------------------*/ |
774 | 0 | const char *pszUnitsName = nullptr; |
775 | 0 | const char *pszUnitsConv = nullptr; |
776 | | /* double dfConv = 1.0; */ |
777 | |
|
778 | 0 | switch (sTABProj.nUnitsId) |
779 | 0 | { |
780 | 0 | case 0: |
781 | 0 | pszUnitsName = "Mile"; |
782 | 0 | pszUnitsConv = "1609.344"; |
783 | 0 | break; |
784 | | |
785 | 0 | case 1: |
786 | 0 | pszUnitsName = "Kilometer"; |
787 | 0 | pszUnitsConv = "1000.0"; |
788 | 0 | break; |
789 | | |
790 | 0 | case 2: |
791 | 0 | pszUnitsName = "IINCH"; |
792 | 0 | pszUnitsConv = "0.0254"; |
793 | 0 | break; |
794 | | |
795 | 0 | case 3: |
796 | 0 | pszUnitsName = SRS_UL_FOOT; |
797 | 0 | pszUnitsConv = SRS_UL_FOOT_CONV; |
798 | 0 | break; |
799 | | |
800 | 0 | case 4: |
801 | 0 | pszUnitsName = "IYARD"; |
802 | 0 | pszUnitsConv = "0.9144"; |
803 | 0 | break; |
804 | | |
805 | 0 | case 5: |
806 | 0 | pszUnitsName = "Millimeter"; |
807 | 0 | pszUnitsConv = "0.001"; |
808 | 0 | break; |
809 | | |
810 | 0 | case 6: |
811 | 0 | pszUnitsName = "Centimeter"; |
812 | 0 | pszUnitsConv = "0.01"; |
813 | 0 | break; |
814 | | |
815 | 0 | case 7: |
816 | 0 | pszUnitsName = SRS_UL_METER; |
817 | 0 | pszUnitsConv = "1.0"; |
818 | 0 | break; |
819 | | |
820 | 0 | case 8: |
821 | 0 | pszUnitsName = SRS_UL_US_FOOT; |
822 | 0 | pszUnitsConv = SRS_UL_US_FOOT_CONV; |
823 | 0 | break; |
824 | | |
825 | 0 | case 9: |
826 | 0 | pszUnitsName = SRS_UL_NAUTICAL_MILE; |
827 | 0 | pszUnitsConv = SRS_UL_NAUTICAL_MILE_CONV; |
828 | 0 | break; |
829 | | |
830 | 0 | case 30: |
831 | 0 | pszUnitsName = SRS_UL_LINK; |
832 | 0 | pszUnitsConv = SRS_UL_LINK_CONV; |
833 | 0 | break; |
834 | | |
835 | 0 | case 31: |
836 | 0 | pszUnitsName = SRS_UL_CHAIN; |
837 | 0 | pszUnitsConv = SRS_UL_CHAIN_CONV; |
838 | 0 | break; |
839 | | |
840 | 0 | case 32: |
841 | 0 | pszUnitsName = SRS_UL_ROD; |
842 | 0 | pszUnitsConv = SRS_UL_ROD_CONV; |
843 | 0 | break; |
844 | | |
845 | 0 | default: |
846 | 0 | pszUnitsName = SRS_UL_METER; |
847 | 0 | pszUnitsConv = "1.0"; |
848 | 0 | break; |
849 | 0 | } |
850 | | |
851 | | /* dfConv = CPLAtof(pszUnitsConv); */ |
852 | | |
853 | | /*----------------------------------------------------------------- |
854 | | * Transform them into an OGRSpatialReference. |
855 | | *----------------------------------------------------------------*/ |
856 | 0 | OGRSpatialReference *poSpatialRef = new OGRSpatialReference; |
857 | 0 | poSpatialRef->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); |
858 | | |
859 | | /*----------------------------------------------------------------- |
860 | | * Handle the PROJCS style projections, but add the datum later. |
861 | | *----------------------------------------------------------------*/ |
862 | 0 | switch (sTABProj.nProjId) |
863 | 0 | { |
864 | 0 | case 0: |
865 | 0 | poSpatialRef->SetLocalCS("Nonearth"); |
866 | 0 | poSpatialRef->SetLinearUnits(pszUnitsName, CPLAtof(pszUnitsConv)); |
867 | 0 | break; |
868 | | |
869 | | /*-------------------------------------------------------------- |
870 | | * lat/long .. just add the GEOGCS later. |
871 | | *-------------------------------------------------------------*/ |
872 | 0 | case 1: |
873 | 0 | break; |
874 | | |
875 | | /*-------------------------------------------------------------- |
876 | | * Cylindrical Equal Area |
877 | | *-------------------------------------------------------------*/ |
878 | 0 | case 2: |
879 | 0 | poSpatialRef->SetCEA( |
880 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
881 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3]); |
882 | 0 | break; |
883 | | |
884 | | /*-------------------------------------------------------------- |
885 | | * Lambert Conic Conformal |
886 | | *-------------------------------------------------------------*/ |
887 | 0 | case 3: |
888 | 0 | poSpatialRef->SetLCC( |
889 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
890 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
891 | 0 | sTABProj.adProjParams[4], sTABProj.adProjParams[5]); |
892 | 0 | break; |
893 | | |
894 | | /*-------------------------------------------------------------- |
895 | | * Lambert Azimuthal Equal Area |
896 | | *-------------------------------------------------------------*/ |
897 | 0 | case 4: |
898 | 0 | case 29: |
899 | 0 | poSpatialRef->SetLAEA(sTABProj.adProjParams[1], |
900 | 0 | sTABProj.adProjParams[0], 0.0, 0.0); |
901 | 0 | break; |
902 | | |
903 | | /*-------------------------------------------------------------- |
904 | | * Azimuthal Equidistant (Polar aspect only) |
905 | | *-------------------------------------------------------------*/ |
906 | 0 | case 5: |
907 | 0 | case 28: |
908 | 0 | poSpatialRef->SetAE(sTABProj.adProjParams[1], |
909 | 0 | sTABProj.adProjParams[0], 0.0, 0.0); |
910 | 0 | break; |
911 | | |
912 | | /*-------------------------------------------------------------- |
913 | | * Equidistant Conic |
914 | | *-------------------------------------------------------------*/ |
915 | 0 | case 6: |
916 | 0 | poSpatialRef->SetEC( |
917 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
918 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
919 | 0 | sTABProj.adProjParams[4], sTABProj.adProjParams[5]); |
920 | 0 | break; |
921 | | |
922 | | /*-------------------------------------------------------------- |
923 | | * Hotine Oblique Mercator |
924 | | *-------------------------------------------------------------*/ |
925 | 0 | case 7: |
926 | 0 | poSpatialRef->SetHOM( |
927 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
928 | 0 | sTABProj.adProjParams[2], 90.0, sTABProj.adProjParams[3], |
929 | 0 | sTABProj.adProjParams[4], sTABProj.adProjParams[5]); |
930 | 0 | break; |
931 | | |
932 | | /*-------------------------------------------------------------- |
933 | | * Hotine Oblique Mercator with Angle from Rectified to Skew Grid |
934 | | *-------------------------------------------------------------*/ |
935 | 0 | case 35: |
936 | 0 | poSpatialRef->SetHOM( |
937 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
938 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
939 | 0 | sTABProj.adProjParams[4], sTABProj.adProjParams[5], |
940 | 0 | sTABProj.adProjParams[6]); |
941 | 0 | break; |
942 | | |
943 | | /*-------------------------------------------------------------- |
944 | | * Transverse Mercator |
945 | | *-------------------------------------------------------------*/ |
946 | 0 | case 8: |
947 | 0 | case 34: // Extended Transverse Mercator |
948 | 0 | poSpatialRef->SetTM( |
949 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
950 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
951 | 0 | sTABProj.adProjParams[4]); |
952 | 0 | break; |
953 | | |
954 | | /*---------------------------------------------------------------- |
955 | | * Transverse Mercator,(modified for Danish System 34 Jylland-Fyn) |
956 | | *---------------------------------------------------------------*/ |
957 | 0 | case 21: |
958 | | // poSpatialRef->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_21, |
959 | 0 | poSpatialRef->SetTM( |
960 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
961 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
962 | 0 | sTABProj.adProjParams[4]); |
963 | 0 | break; |
964 | | |
965 | | /*-------------------------------------------------------------- |
966 | | * Transverse Mercator,(modified for Danish System 34 Sjaelland) |
967 | | *-------------------------------------------------------------*/ |
968 | 0 | case 22: |
969 | | // poSpatialRef->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_22, |
970 | 0 | poSpatialRef->SetTM( |
971 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
972 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
973 | 0 | sTABProj.adProjParams[4]); |
974 | 0 | break; |
975 | | |
976 | | /*---------------------------------------------------------------- |
977 | | * Transverse Mercator,(modified for Danish System 34/45 Bornholm) |
978 | | *---------------------------------------------------------------*/ |
979 | 0 | case 23: |
980 | | // poSpatialRef->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_23, |
981 | 0 | poSpatialRef->SetTM( |
982 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
983 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
984 | 0 | sTABProj.adProjParams[4]); |
985 | 0 | break; |
986 | | |
987 | | /*-------------------------------------------------------------- |
988 | | * Transverse Mercator,(modified for Finnish KKJ) |
989 | | *-------------------------------------------------------------*/ |
990 | 0 | case 24: |
991 | | // poSpatialRef->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_24, |
992 | 0 | poSpatialRef->SetTM( |
993 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
994 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
995 | 0 | sTABProj.adProjParams[4]); |
996 | 0 | break; |
997 | | |
998 | | /*-------------------------------------------------------------- |
999 | | * Albers Conic Equal Area |
1000 | | *-------------------------------------------------------------*/ |
1001 | 0 | case 9: |
1002 | 0 | poSpatialRef->SetACEA( |
1003 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
1004 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1005 | 0 | sTABProj.adProjParams[4], sTABProj.adProjParams[5]); |
1006 | 0 | break; |
1007 | | |
1008 | | /*-------------------------------------------------------------- |
1009 | | * Mercator |
1010 | | *-------------------------------------------------------------*/ |
1011 | 0 | case 10: |
1012 | 0 | poSpatialRef->SetMercator(0.0, sTABProj.adProjParams[0], 1.0, 0.0, |
1013 | 0 | 0.0); |
1014 | 0 | break; |
1015 | | |
1016 | | /*-------------------------------------------------------------- |
1017 | | * Miller Cylindrical |
1018 | | *-------------------------------------------------------------*/ |
1019 | 0 | case 11: |
1020 | 0 | poSpatialRef->SetMC(0.0, sTABProj.adProjParams[0], 0.0, 0.0); |
1021 | 0 | break; |
1022 | | |
1023 | | /*-------------------------------------------------------------- |
1024 | | * Robinson |
1025 | | *-------------------------------------------------------------*/ |
1026 | 0 | case 12: |
1027 | 0 | poSpatialRef->SetRobinson(sTABProj.adProjParams[0], 0.0, 0.0); |
1028 | 0 | break; |
1029 | | |
1030 | | /*-------------------------------------------------------------- |
1031 | | * Mollweide |
1032 | | *-------------------------------------------------------------*/ |
1033 | 0 | case 13: |
1034 | 0 | poSpatialRef->SetMollweide(sTABProj.adProjParams[0], 0.0, 0.0); |
1035 | 0 | break; |
1036 | | |
1037 | | /*-------------------------------------------------------------- |
1038 | | * Eckert IV |
1039 | | *-------------------------------------------------------------*/ |
1040 | 0 | case 14: |
1041 | 0 | poSpatialRef->SetEckertIV(sTABProj.adProjParams[0], 0.0, 0.0); |
1042 | 0 | break; |
1043 | | |
1044 | | /*-------------------------------------------------------------- |
1045 | | * Eckert VI |
1046 | | *-------------------------------------------------------------*/ |
1047 | 0 | case 15: |
1048 | 0 | poSpatialRef->SetEckertVI(sTABProj.adProjParams[0], 0.0, 0.0); |
1049 | 0 | break; |
1050 | | |
1051 | | /*-------------------------------------------------------------- |
1052 | | * Sinusoidal |
1053 | | *-------------------------------------------------------------*/ |
1054 | 0 | case 16: |
1055 | 0 | poSpatialRef->SetSinusoidal(sTABProj.adProjParams[0], 0.0, 0.0); |
1056 | 0 | break; |
1057 | | |
1058 | | /*-------------------------------------------------------------- |
1059 | | * Gall Stereographic |
1060 | | *-------------------------------------------------------------*/ |
1061 | 0 | case 17: |
1062 | 0 | poSpatialRef->SetGS(sTABProj.adProjParams[0], 0.0, 0.0); |
1063 | 0 | break; |
1064 | | |
1065 | | /*-------------------------------------------------------------- |
1066 | | * New Zealand Map Grid |
1067 | | *-------------------------------------------------------------*/ |
1068 | 0 | case 18: |
1069 | 0 | poSpatialRef->SetNZMG( |
1070 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1071 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3]); |
1072 | 0 | break; |
1073 | | |
1074 | | /*-------------------------------------------------------------- |
1075 | | * Lambert Conic Conformal (Belgium) |
1076 | | *-------------------------------------------------------------*/ |
1077 | 0 | case 19: |
1078 | 0 | poSpatialRef->SetLCCB( |
1079 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
1080 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1081 | 0 | sTABProj.adProjParams[4], sTABProj.adProjParams[5]); |
1082 | 0 | break; |
1083 | | |
1084 | | /*-------------------------------------------------------------- |
1085 | | * Stereographic |
1086 | | *-------------------------------------------------------------*/ |
1087 | 0 | case 20: |
1088 | 0 | poSpatialRef->SetStereographic( |
1089 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1090 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
1091 | 0 | sTABProj.adProjParams[4]); |
1092 | 0 | break; |
1093 | | |
1094 | | /*-------------------------------------------------------------- |
1095 | | * Swiss Oblique Mercator / Cylindrical |
1096 | | *-------------------------------------------------------------*/ |
1097 | 0 | case 25: |
1098 | 0 | poSpatialRef->SetSOC( |
1099 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1100 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3]); |
1101 | 0 | break; |
1102 | | |
1103 | | /*-------------------------------------------------------------- |
1104 | | * Regional Mercator (regular mercator with a latitude). |
1105 | | *-------------------------------------------------------------*/ |
1106 | 0 | case 26: |
1107 | 0 | poSpatialRef->SetMercator2SP(sTABProj.adProjParams[1], 0.0, |
1108 | 0 | sTABProj.adProjParams[0], 0.0, 0.0); |
1109 | 0 | break; |
1110 | | |
1111 | | /*-------------------------------------------------------------- |
1112 | | * Polyconic |
1113 | | *-------------------------------------------------------------*/ |
1114 | 0 | case 27: |
1115 | 0 | poSpatialRef->SetPolyconic( |
1116 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1117 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3]); |
1118 | 0 | break; |
1119 | | |
1120 | | /*-------------------------------------------------------------- |
1121 | | * Cassini/Soldner |
1122 | | *-------------------------------------------------------------*/ |
1123 | 0 | case 30: |
1124 | 0 | poSpatialRef->SetCS( |
1125 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1126 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3]); |
1127 | 0 | break; |
1128 | | |
1129 | | /*-------------------------------------------------------------- |
1130 | | * Oblique Stereographic |
1131 | | *-------------------------------------------------------------*/ |
1132 | 0 | case 31: |
1133 | 0 | poSpatialRef->SetOS( |
1134 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1135 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3], |
1136 | 0 | sTABProj.adProjParams[4]); |
1137 | 0 | break; |
1138 | | |
1139 | | /*-------------------------------------------------------------- |
1140 | | * Krovak |
1141 | | *-------------------------------------------------------------*/ |
1142 | 0 | case 32: |
1143 | 0 | poSpatialRef->SetKrovak( |
1144 | 0 | sTABProj.adProjParams[1], // dfCenterLat |
1145 | 0 | sTABProj.adProjParams[0], // dfCenterLong |
1146 | 0 | sTABProj.adProjParams[3], // dfAzimuth |
1147 | 0 | sTABProj.adProjParams[2], // dfPseudoStdParallelLat |
1148 | 0 | 1.0, // dfScale |
1149 | 0 | sTABProj.adProjParams[4], // dfFalseEasting |
1150 | 0 | sTABProj.adProjParams[5]); // dfFalseNorthing |
1151 | 0 | break; |
1152 | | |
1153 | | /*-------------------------------------------------------------- |
1154 | | * Equidistant Cylindrical / Equirectangular |
1155 | | *-------------------------------------------------------------*/ |
1156 | 0 | case 33: |
1157 | 0 | poSpatialRef->SetEquirectangular( |
1158 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1159 | 0 | sTABProj.adProjParams[2], sTABProj.adProjParams[3]); |
1160 | 0 | break; |
1161 | | |
1162 | 0 | default: |
1163 | 0 | poSpatialRef->SetProjection(CPLSPrintf( |
1164 | 0 | "Unhandled MapInfo projection method %d", sTABProj.nProjId)); |
1165 | 0 | break; |
1166 | 0 | } |
1167 | | |
1168 | | /*----------------------------------------------------------------- |
1169 | | * Local (nonearth) coordinate systems have no Geographic relationship |
1170 | | * so we just return from here. |
1171 | | *----------------------------------------------------------------*/ |
1172 | 0 | if (sTABProj.nProjId == 0) |
1173 | 0 | return poSpatialRef; |
1174 | | |
1175 | | /*----------------------------------------------------------------- |
1176 | | * Set the datum. We are only given the X, Y and Z shift for |
1177 | | * the datum, so for now we just synthesize a name from this. |
1178 | | * It would be better if we could lookup a name based on the shift. |
1179 | | * |
1180 | | * Since we have already encountered files in which adDatumParams[] values |
1181 | | * were in the order of 1e-150 when they should have actually been zeros, |
1182 | | * we will use an epsilon in our scan instead of looking for equality. |
1183 | | *----------------------------------------------------------------*/ |
1184 | 0 | const MapInfoDatumInfo *psDatumInfo = nullptr; |
1185 | |
|
1186 | 0 | for (int iDatumInfo = 0; asDatumInfoList[iDatumInfo].nMapInfoDatumID != -1; |
1187 | 0 | iDatumInfo++) |
1188 | 0 | { |
1189 | 0 | psDatumInfo = asDatumInfoList + iDatumInfo; |
1190 | |
|
1191 | 0 | if (TAB_EQUAL(psDatumInfo->nEllipsoid, sTABProj.nEllipsoidId) && |
1192 | 0 | ((sTABProj.nDatumId > 0 && |
1193 | 0 | sTABProj.nDatumId == psDatumInfo->nMapInfoDatumID) || |
1194 | 0 | (sTABProj.nDatumId <= 0 && |
1195 | 0 | TAB_EQUAL(psDatumInfo->dfShiftX, sTABProj.dDatumShiftX) && |
1196 | 0 | TAB_EQUAL(psDatumInfo->dfShiftY, sTABProj.dDatumShiftY) && |
1197 | 0 | TAB_EQUAL(psDatumInfo->dfShiftZ, sTABProj.dDatumShiftZ) && |
1198 | 0 | TAB_EQUAL(psDatumInfo->dfDatumParm0, sTABProj.adDatumParams[0]) && |
1199 | 0 | TAB_EQUAL(psDatumInfo->dfDatumParm1, sTABProj.adDatumParams[1]) && |
1200 | 0 | TAB_EQUAL(psDatumInfo->dfDatumParm2, sTABProj.adDatumParams[2]) && |
1201 | 0 | TAB_EQUAL(psDatumInfo->dfDatumParm3, sTABProj.adDatumParams[3]) && |
1202 | 0 | TAB_EQUAL(psDatumInfo->dfDatumParm4, sTABProj.adDatumParams[4])))) |
1203 | 0 | break; |
1204 | | |
1205 | 0 | psDatumInfo = nullptr; |
1206 | 0 | } |
1207 | |
|
1208 | 0 | char szDatumName[200] = {}; |
1209 | 0 | if (psDatumInfo == nullptr) |
1210 | 0 | { |
1211 | 0 | if (sTABProj.adDatumParams[0] == 0.0 && |
1212 | 0 | sTABProj.adDatumParams[1] == 0.0 && |
1213 | 0 | sTABProj.adDatumParams[2] == 0.0 && |
1214 | 0 | sTABProj.adDatumParams[3] == 0.0 && |
1215 | 0 | sTABProj.adDatumParams[4] == 0.0) |
1216 | 0 | { |
1217 | 0 | snprintf(szDatumName, sizeof(szDatumName), |
1218 | 0 | "MIF 999,%u,%.15g,%.15g,%.15g", sTABProj.nEllipsoidId, |
1219 | 0 | sTABProj.dDatumShiftX, sTABProj.dDatumShiftY, |
1220 | 0 | sTABProj.dDatumShiftZ); |
1221 | 0 | } |
1222 | 0 | else |
1223 | 0 | { |
1224 | 0 | snprintf( |
1225 | 0 | szDatumName, sizeof(szDatumName), |
1226 | 0 | "MIF 9999,%u,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g", |
1227 | 0 | sTABProj.nEllipsoidId, sTABProj.dDatumShiftX, |
1228 | 0 | sTABProj.dDatumShiftY, sTABProj.dDatumShiftZ, |
1229 | 0 | sTABProj.adDatumParams[0], sTABProj.adDatumParams[1], |
1230 | 0 | sTABProj.adDatumParams[2], sTABProj.adDatumParams[3], |
1231 | 0 | sTABProj.adDatumParams[4]); |
1232 | 0 | } |
1233 | 0 | } |
1234 | 0 | else if (strlen(psDatumInfo->pszOGCDatumName) > 0) |
1235 | 0 | { |
1236 | 0 | CPLStrlcpy(szDatumName, psDatumInfo->pszOGCDatumName, |
1237 | 0 | sizeof(szDatumName)); |
1238 | 0 | } |
1239 | 0 | else |
1240 | 0 | { |
1241 | 0 | snprintf(szDatumName, sizeof(szDatumName), "MIF %d", |
1242 | 0 | psDatumInfo->nMapInfoDatumID); |
1243 | 0 | } |
1244 | | |
1245 | | /*----------------------------------------------------------------- |
1246 | | * Set the spheroid. |
1247 | | *----------------------------------------------------------------*/ |
1248 | 0 | double dfSemiMajor = 0.0; |
1249 | 0 | double dfInvFlattening = 0.0; |
1250 | 0 | const char *pszSpheroidName = nullptr; |
1251 | |
|
1252 | 0 | for (int i = 0; asSpheroidInfoList[i].nMapInfoId != -1; i++) |
1253 | 0 | { |
1254 | 0 | if (asSpheroidInfoList[i].nMapInfoId == sTABProj.nEllipsoidId) |
1255 | 0 | { |
1256 | 0 | dfSemiMajor = asSpheroidInfoList[i].dfA; |
1257 | 0 | dfInvFlattening = asSpheroidInfoList[i].dfInvFlattening; |
1258 | 0 | pszSpheroidName = asSpheroidInfoList[i].pszMapinfoName; |
1259 | 0 | break; |
1260 | 0 | } |
1261 | 0 | } |
1262 | | |
1263 | | // use WGS 84 if nothing is known. |
1264 | 0 | if (pszSpheroidName == nullptr) |
1265 | 0 | { |
1266 | 0 | pszSpheroidName = "unknown"; |
1267 | 0 | dfSemiMajor = 6378137.0; |
1268 | 0 | dfInvFlattening = 298.257223563; |
1269 | 0 | } |
1270 | | |
1271 | | /*----------------------------------------------------------------- |
1272 | | * Set the prime meridian. |
1273 | | *----------------------------------------------------------------*/ |
1274 | 0 | double dfPMOffset = 0.0; |
1275 | 0 | const char *pszPMName = "Greenwich"; |
1276 | |
|
1277 | 0 | if (/*sTABProj.nDatumId == 9999 ||*/ sTABProj.adDatumParams[4] != 0.0) |
1278 | 0 | { |
1279 | 0 | dfPMOffset = sTABProj.adDatumParams[4]; |
1280 | |
|
1281 | 0 | if (fabs(dfPMOffset - 2.337229166667) < 1e-10) |
1282 | 0 | pszPMName = "Paris"; |
1283 | 0 | else |
1284 | 0 | pszPMName = "non-Greenwich"; |
1285 | 0 | } |
1286 | | |
1287 | | /*----------------------------------------------------------------- |
1288 | | * Create a GEOGCS definition. |
1289 | | *----------------------------------------------------------------*/ |
1290 | |
|
1291 | 0 | poSpatialRef->SetGeogCS("unnamed", szDatumName, pszSpheroidName, |
1292 | 0 | dfSemiMajor, dfInvFlattening, pszPMName, dfPMOffset, |
1293 | 0 | SRS_UA_DEGREE, CPLAtof(SRS_UA_DEGREE_CONV)); |
1294 | |
|
1295 | 0 | if (psDatumInfo != nullptr) |
1296 | 0 | { |
1297 | 0 | if (CPLTestBool( |
1298 | 0 | CPLGetConfigOption("MITAB_SET_TOWGS84_ON_KNOWN_DATUM", "NO"))) |
1299 | 0 | { |
1300 | 0 | poSpatialRef->SetTOWGS84( |
1301 | 0 | psDatumInfo->dfShiftX, psDatumInfo->dfShiftY, |
1302 | 0 | psDatumInfo->dfShiftZ, |
1303 | 0 | psDatumInfo->dfDatumParm0 == 0 |
1304 | 0 | ? 0 |
1305 | 0 | : -psDatumInfo->dfDatumParm0, /* avoids 0 to be transformed |
1306 | | into -0 */ |
1307 | 0 | psDatumInfo->dfDatumParm1 == 0 ? 0 : -psDatumInfo->dfDatumParm1, |
1308 | 0 | psDatumInfo->dfDatumParm2 == 0 ? 0 : -psDatumInfo->dfDatumParm2, |
1309 | 0 | psDatumInfo->dfDatumParm3); |
1310 | 0 | } |
1311 | 0 | } |
1312 | 0 | else |
1313 | 0 | { |
1314 | 0 | poSpatialRef->SetTOWGS84( |
1315 | 0 | sTABProj.dDatumShiftX, sTABProj.dDatumShiftY, sTABProj.dDatumShiftZ, |
1316 | 0 | sTABProj.adDatumParams[0] == 0 ? 0 : -sTABProj.adDatumParams[0], |
1317 | 0 | sTABProj.adDatumParams[1] == 0 ? 0 : -sTABProj.adDatumParams[1], |
1318 | 0 | sTABProj.adDatumParams[2] == 0 ? 0 : -sTABProj.adDatumParams[2], |
1319 | 0 | sTABProj.adDatumParams[3]); |
1320 | 0 | } |
1321 | | |
1322 | | /*----------------------------------------------------------------- |
1323 | | * Special case for Google Mercator (datum=157, ellipse=54, gdal #4115) |
1324 | | *----------------------------------------------------------------*/ |
1325 | 0 | if (sTABProj.nProjId == 10 && sTABProj.nDatumId == 157 && |
1326 | 0 | sTABProj.nEllipsoidId == 54) |
1327 | 0 | { |
1328 | 0 | poSpatialRef->SetNode("PROJCS", "WGS 84 / Pseudo-Mercator"); |
1329 | 0 | poSpatialRef->SetExtension( |
1330 | 0 | "PROJCS", "PROJ4", |
1331 | 0 | "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 " |
1332 | 0 | "+y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"); |
1333 | 0 | } |
1334 | | |
1335 | | /*----------------------------------------------------------------- |
1336 | | * Special case for France Lambert-93 |
1337 | | *----------------------------------------------------------------*/ |
1338 | 0 | if (sTABProj.nProjId == 3 && sTABProj.nDatumId == 33 && |
1339 | 0 | sTABProj.nEllipsoidId == 0 && |
1340 | 0 | TAB_EQUAL(poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0), |
1341 | 0 | 3.0) && |
1342 | 0 | TAB_EQUAL(poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0), |
1343 | 0 | 46.5)) |
1344 | 0 | { |
1345 | 0 | poSpatialRef->SetNode("PROJCS", "RGF93 / Lambert-93"); |
1346 | 0 | poSpatialRef->SetNode("PROJCS|GEOGCS", "RGF93"); |
1347 | 0 | poSpatialRef->SetNode("PROJCS|GEOGCS|DATUM", |
1348 | 0 | "Reseau_Geodesique_Francais_1993"); |
1349 | 0 | } |
1350 | |
|
1351 | 0 | if (sTABProj.nProjId == 3) |
1352 | 0 | { |
1353 | | // If the LCC_2SP can be turned into a LCC_1SP that has the same |
1354 | | // latitude of origin, then it is a better candidate |
1355 | 0 | OGRSpatialReference *poLCC1SP = poSpatialRef->convertToOtherProjection( |
1356 | 0 | SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP); |
1357 | 0 | if (poLCC1SP) |
1358 | 0 | { |
1359 | 0 | if (TAB_EQUAL( |
1360 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, |
1361 | 0 | 0.0), |
1362 | 0 | poLCC1SP->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0))) |
1363 | 0 | { |
1364 | 0 | delete poSpatialRef; |
1365 | 0 | poSpatialRef = poLCC1SP; |
1366 | 0 | } |
1367 | 0 | else |
1368 | 0 | { |
1369 | 0 | delete poLCC1SP; |
1370 | 0 | } |
1371 | 0 | } |
1372 | 0 | } |
1373 | | |
1374 | | /* For LCC, standard parallel 1 and 2 can be switched indifferently */ |
1375 | | /* So the MapInfo order and the EPSG order are not generally identical */ |
1376 | | /* which may cause recognition problems when reading in MapInfo */ |
1377 | 0 | int nEPSGCandidateCode = 0; |
1378 | 0 | if (sTABProj.nProjId == 3) |
1379 | 0 | { |
1380 | 0 | double dfCenterLong = sTABProj.adProjParams[0]; |
1381 | 0 | double dfCenterLat = sTABProj.adProjParams[1]; |
1382 | 0 | double dfStdP1 = sTABProj.adProjParams[2]; |
1383 | 0 | double dfStdP2 = sTABProj.adProjParams[3]; |
1384 | |
|
1385 | 0 | for (size_t i = 0; |
1386 | 0 | i < sizeof(asMapInfoLCCSRSList) / sizeof(asMapInfoLCCSRSList[0]); |
1387 | 0 | i++) |
1388 | 0 | { |
1389 | 0 | if (sTABProj.nDatumId == asMapInfoLCCSRSList[i].nMapInfoDatumID && |
1390 | 0 | TAB_EQUAL(dfCenterLong, asMapInfoLCCSRSList[i].dfCenterLong) && |
1391 | 0 | TAB_EQUAL(dfCenterLat, asMapInfoLCCSRSList[i].dfCenterLat)) |
1392 | 0 | { |
1393 | 0 | if (TAB_EQUAL(dfStdP1, asMapInfoLCCSRSList[i].dfStdP1) && |
1394 | 0 | (TAB_EQUAL(dfStdP2, asMapInfoLCCSRSList[i].dfStdP2) || |
1395 | | // EPSG:3301 "Estonian Coordinate System of 1997" |
1396 | | // MapInfo uses a less accurate value of StdP2 than EPSG |
1397 | 0 | (TAB_EQUAL(asMapInfoLCCSRSList[i].dfStdP2, 59.33333333) && |
1398 | 0 | TAB_EQUAL(dfStdP2, 59.3333333333333)))) |
1399 | 0 | { |
1400 | 0 | if (nEPSGCandidateCode) |
1401 | 0 | { |
1402 | 0 | poSpatialRef->SetAuthority("PROJCS", "EPSG", |
1403 | 0 | nEPSGCandidateCode); |
1404 | 0 | nEPSGCandidateCode = 0; |
1405 | 0 | break; |
1406 | 0 | } |
1407 | 0 | if (asMapInfoLCCSRSList[i].bReverseStdP) |
1408 | 0 | { |
1409 | 0 | CPLDebug("MITAB", |
1410 | 0 | "Switching standard parallel 1 and 2"); |
1411 | 0 | poSpatialRef->SetLCC( |
1412 | 0 | sTABProj.adProjParams[3], sTABProj.adProjParams[2], |
1413 | 0 | sTABProj.adProjParams[1], sTABProj.adProjParams[0], |
1414 | 0 | sTABProj.adProjParams[4], sTABProj.adProjParams[5]); |
1415 | 0 | } |
1416 | 0 | if (asMapInfoLCCSRSList[i].nEPSGCode > 0) |
1417 | 0 | nEPSGCandidateCode = asMapInfoLCCSRSList[i].nEPSGCode; |
1418 | 0 | else |
1419 | 0 | break; |
1420 | 0 | } |
1421 | 0 | } |
1422 | 0 | } |
1423 | 0 | } |
1424 | | |
1425 | | /*----------------------------------------------------------------- |
1426 | | * Apply linear units. Do that only after all above manipulations of |
1427 | | * projection parameters. |
1428 | | *----------------------------------------------------------------*/ |
1429 | 0 | if (sTABProj.nProjId != 0 && sTABProj.nProjId != 1 && |
1430 | 0 | CPLAtof(pszUnitsConv) != 1) |
1431 | 0 | { |
1432 | 0 | poSpatialRef->SetTargetLinearUnits(nullptr, pszUnitsName, |
1433 | 0 | CPLAtof(pszUnitsConv)); |
1434 | 0 | } |
1435 | |
|
1436 | 0 | if (nEPSGCandidateCode) |
1437 | 0 | { |
1438 | 0 | OGRSpatialReference oTmp; |
1439 | 0 | oTmp.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); |
1440 | 0 | if (oTmp.importFromEPSG(nEPSGCandidateCode) == OGRERR_NONE) |
1441 | 0 | { |
1442 | 0 | *poSpatialRef = std::move(oTmp); |
1443 | 0 | } |
1444 | 0 | } |
1445 | | |
1446 | | /*----------------------------------------------------------------- |
1447 | | * Special case for Philippine Reference System 1992, to override |
1448 | | * the MapInfo ellipsoid=8 "Clarke 1866 (modified for Michigan)" |
1449 | | * by the regular Clarke 1866 of EPSG |
1450 | | *----------------------------------------------------------------*/ |
1451 | 0 | if (sTABProj.nDatumId == 1031 && sTABProj.nEllipsoidId == 8) |
1452 | 0 | { |
1453 | 0 | OGRSpatialReference oSRS_EPSG_4683; |
1454 | 0 | if (oSRS_EPSG_4683.importFromEPSG(4683) == OGRERR_NONE) |
1455 | 0 | poSpatialRef->CopyGeogCSFrom(&oSRS_EPSG_4683); |
1456 | 0 | } |
1457 | | |
1458 | | /*----------------------------------------------------------------- |
1459 | | * Special case for Kertau (RSO), to override |
1460 | | * the MapInfo ellipsoid=40 "Everest (India 1956)", 6377301.243, 300.80174 |
1461 | | * with EPSG's "Everest 1830 (RSO 1969)",6377295.664,300.8017 |
1462 | | *----------------------------------------------------------------*/ |
1463 | 0 | if (sTABProj.nDatumId == 164 && sTABProj.nEllipsoidId == 40) |
1464 | 0 | { |
1465 | 0 | OGRSpatialReference oSRS_EPSG_4751; |
1466 | 0 | if (oSRS_EPSG_4751.importFromEPSG(4751) == OGRERR_NONE) |
1467 | 0 | poSpatialRef->CopyGeogCSFrom(&oSRS_EPSG_4751); |
1468 | 0 | } |
1469 | |
|
1470 | 0 | return poSpatialRef; |
1471 | 0 | } |
1472 | | |
1473 | | static int MITABGetCustomDatum(const OGRSpatialReference *poSpatialRef, |
1474 | | TABProjInfo &sTABProj) |
1475 | 0 | { |
1476 | 0 | double adfTOWGS[7] = {0}; |
1477 | 0 | if (OGRERR_NONE != poSpatialRef->GetTOWGS84( |
1478 | 0 | adfTOWGS, sizeof(adfTOWGS) / sizeof(adfTOWGS[0]))) |
1479 | 0 | { |
1480 | 0 | return FALSE; |
1481 | 0 | } |
1482 | 0 | sTABProj.nDatumId = 9999; |
1483 | 0 | sTABProj.dDatumShiftX = adfTOWGS[0]; |
1484 | 0 | sTABProj.dDatumShiftY = adfTOWGS[1]; |
1485 | 0 | sTABProj.dDatumShiftZ = adfTOWGS[2]; |
1486 | 0 | sTABProj.adDatumParams[0] = -adfTOWGS[3]; |
1487 | 0 | sTABProj.adDatumParams[1] = -adfTOWGS[4]; |
1488 | 0 | sTABProj.adDatumParams[2] = -adfTOWGS[5]; |
1489 | 0 | sTABProj.adDatumParams[3] = adfTOWGS[6]; |
1490 | |
|
1491 | 0 | int nSpheroidId = -1; |
1492 | |
|
1493 | 0 | const char *pszWKTSpheroid = poSpatialRef->GetAttrValue("SPHEROID"); |
1494 | 0 | for (int i = 0; asSpheroidInfoList[i].nMapInfoId != -1; i++) |
1495 | 0 | { |
1496 | 0 | if (EQUAL(pszWKTSpheroid, asSpheroidInfoList[i].pszMapinfoName)) |
1497 | 0 | { |
1498 | 0 | nSpheroidId = asSpheroidInfoList[i].nMapInfoId; |
1499 | 0 | break; |
1500 | 0 | } |
1501 | 0 | } |
1502 | |
|
1503 | 0 | if (nSpheroidId == -1) |
1504 | 0 | { |
1505 | 0 | double adSemiMajor = poSpatialRef->GetSemiMajor(); |
1506 | 0 | double adInvFlattening = poSpatialRef->GetInvFlattening(); |
1507 | |
|
1508 | 0 | for (int i = 0; asSpheroidInfoList[i].nMapInfoId != -1; i++) |
1509 | 0 | { |
1510 | 0 | if (CPLIsEqual(adSemiMajor, asSpheroidInfoList[i].dfA) && |
1511 | 0 | CPLIsEqual(adInvFlattening, |
1512 | 0 | asSpheroidInfoList[i].dfInvFlattening)) |
1513 | 0 | { |
1514 | 0 | nSpheroidId = asSpheroidInfoList[i].nMapInfoId; |
1515 | 0 | break; |
1516 | 0 | } |
1517 | 0 | } |
1518 | 0 | } |
1519 | 0 | if (nSpheroidId == -1) |
1520 | 0 | { |
1521 | 0 | CPLDebug( |
1522 | 0 | "MITAB", |
1523 | 0 | "Cannot find MapInfo spheroid matching %s. Defaulting to WGS 84", |
1524 | 0 | pszWKTSpheroid); |
1525 | 0 | nSpheroidId = 28; /* WGS 84 */ |
1526 | 0 | } |
1527 | 0 | sTABProj.nEllipsoidId = static_cast<GByte>(nSpheroidId); |
1528 | 0 | return TRUE; |
1529 | 0 | } |
1530 | | |
1531 | | int TABFileGetTABProjFromSpatialRef(const OGRSpatialReference *poSpatialRef, |
1532 | | TABProjInfo &sTABProj, int &nParamCount) |
1533 | 0 | { |
1534 | | /*----------------------------------------------------------------- |
1535 | | * Initialize TABProjInfo |
1536 | | *----------------------------------------------------------------*/ |
1537 | 0 | sTABProj.nProjId = 0; |
1538 | 0 | sTABProj.nEllipsoidId = 0; /* how will we set this? */ |
1539 | 0 | sTABProj.nUnitsId = 7; |
1540 | 0 | sTABProj.adProjParams[0] = sTABProj.adProjParams[1] = 0.0; |
1541 | 0 | sTABProj.adProjParams[2] = sTABProj.adProjParams[3] = 0.0; |
1542 | 0 | sTABProj.adProjParams[4] = sTABProj.adProjParams[5] = 0.0; |
1543 | |
|
1544 | 0 | sTABProj.nDatumId = 0; |
1545 | 0 | sTABProj.dDatumShiftX = 0.0; |
1546 | 0 | sTABProj.dDatumShiftY = 0.0; |
1547 | 0 | sTABProj.dDatumShiftZ = 0.0; |
1548 | 0 | sTABProj.adDatumParams[0] = 0.0; |
1549 | 0 | sTABProj.adDatumParams[1] = 0.0; |
1550 | 0 | sTABProj.adDatumParams[2] = 0.0; |
1551 | 0 | sTABProj.adDatumParams[3] = 0.0; |
1552 | 0 | sTABProj.adDatumParams[4] = 0.0; |
1553 | |
|
1554 | 0 | sTABProj.nAffineFlag = 0; |
1555 | 0 | sTABProj.nAffineUnits = 7; |
1556 | 0 | sTABProj.dAffineParamA = 0.0; |
1557 | 0 | sTABProj.dAffineParamB = 0.0; |
1558 | 0 | sTABProj.dAffineParamC = 0.0; |
1559 | 0 | sTABProj.dAffineParamD = 0.0; |
1560 | 0 | sTABProj.dAffineParamE = 0.0; |
1561 | 0 | sTABProj.dAffineParamF = 0.0; |
1562 | | |
1563 | | /*----------------------------------------------------------------- |
1564 | | * Get the linear units and conversion. |
1565 | | *----------------------------------------------------------------*/ |
1566 | 0 | const char *pszLinearUnits = nullptr; |
1567 | 0 | double dfLinearConv = poSpatialRef->GetLinearUnits(&pszLinearUnits); |
1568 | 0 | if (dfLinearConv == 0.0) |
1569 | 0 | dfLinearConv = 1.0; |
1570 | | |
1571 | | // Get datum information |
1572 | 0 | const char *pszWKTDatum = poSpatialRef->GetAttrValue("DATUM"); |
1573 | |
|
1574 | 0 | const auto GetDatumCode = [](const OGRSpatialReference *poSRS) |
1575 | 0 | { |
1576 | 0 | const char *pszDatumAuthority = poSRS->GetAuthorityName("DATUM"); |
1577 | 0 | const char *pszDatumCode = poSRS->GetAuthorityCode("DATUM"); |
1578 | 0 | if (pszDatumCode && pszDatumAuthority && |
1579 | 0 | EQUAL(pszDatumAuthority, "EPSG")) |
1580 | 0 | { |
1581 | 0 | return atoi(pszDatumCode); |
1582 | 0 | } |
1583 | 0 | return -1; |
1584 | 0 | }; |
1585 | |
|
1586 | 0 | int nDatumEPSGCode = GetDatumCode(poSpatialRef); |
1587 | 0 | if (nDatumEPSGCode < 0) |
1588 | 0 | { |
1589 | 0 | const auto GetDatumCodeFromCRSIndirect = |
1590 | 0 | [&GetDatumCode](const OGRSpatialReference *poSRS, |
1591 | 0 | const char *pszNode) |
1592 | 0 | { |
1593 | 0 | const char *pszAuthorityName = poSRS->GetAuthorityName(pszNode); |
1594 | 0 | const char *pszAuthorityCode = poSRS->GetAuthorityCode(pszNode); |
1595 | 0 | if (pszAuthorityName && pszAuthorityCode) |
1596 | 0 | { |
1597 | 0 | OGRSpatialReference oSRSTmp; |
1598 | 0 | if (oSRSTmp.SetFromUserInput(CPLSPrintf( |
1599 | 0 | "%s:%s", pszAuthorityName, pszAuthorityCode)) == |
1600 | 0 | OGRERR_NONE) |
1601 | 0 | { |
1602 | 0 | return GetDatumCode(&oSRSTmp); |
1603 | 0 | } |
1604 | 0 | } |
1605 | 0 | return -1; |
1606 | 0 | }; |
1607 | | |
1608 | | // When the CRS is built from WKT2 CRS string, the DATUM code will |
1609 | | // typically be absent from the CRS string. |
1610 | | // Try to get the AUTHORITY:CODE from the CRS to instantiate |
1611 | | // a temporary CRS and get its DATUM code. |
1612 | 0 | nDatumEPSGCode = GetDatumCodeFromCRSIndirect(poSpatialRef, nullptr); |
1613 | 0 | if (nDatumEPSGCode < 0 && !poSpatialRef->IsGeographic()) |
1614 | 0 | { |
1615 | | // If there's no AUTHORITY:CODE on the CRS, then retry with its |
1616 | | // geographic CRS |
1617 | 0 | nDatumEPSGCode = |
1618 | 0 | GetDatumCodeFromCRSIndirect(poSpatialRef, "GEOGCS"); |
1619 | 0 | } |
1620 | 0 | } |
1621 | | |
1622 | | /*----------------------------------------------------------------- |
1623 | | * Transform the projection and projection parameters. |
1624 | | *----------------------------------------------------------------*/ |
1625 | 0 | const char *pszProjection = poSpatialRef->GetAttrValue("PROJECTION"); |
1626 | 0 | double *params = sTABProj.adProjParams; |
1627 | 0 | nParamCount = 0; |
1628 | |
|
1629 | 0 | if (pszProjection == nullptr && |
1630 | 0 | poSpatialRef->GetAttrNode("GEOGCS") == nullptr) |
1631 | 0 | { |
1632 | | /* nonearth */ |
1633 | 0 | sTABProj.nProjId = 0; |
1634 | 0 | } |
1635 | | |
1636 | 0 | else if (pszProjection == nullptr) |
1637 | 0 | { |
1638 | 0 | sTABProj.nProjId = 1; |
1639 | 0 | } |
1640 | | |
1641 | 0 | else if (EQUAL(pszProjection, SRS_PT_ALBERS_CONIC_EQUAL_AREA)) |
1642 | 0 | { |
1643 | 0 | sTABProj.nProjId = 9; |
1644 | 0 | params[0] = |
1645 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER, 0.0); |
1646 | 0 | params[1] = |
1647 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER, 0.0); |
1648 | 0 | params[2] = |
1649 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0); |
1650 | 0 | params[3] = |
1651 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0); |
1652 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1653 | 0 | params[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1654 | 0 | nParamCount = 6; |
1655 | 0 | } |
1656 | | |
1657 | 0 | else if (EQUAL(pszProjection, SRS_PT_AZIMUTHAL_EQUIDISTANT)) |
1658 | 0 | { |
1659 | 0 | sTABProj.nProjId = 5; |
1660 | 0 | params[0] = |
1661 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER, 0.0); |
1662 | 0 | params[1] = |
1663 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER, 0.0); |
1664 | 0 | params[2] = 90.0; |
1665 | 0 | nParamCount = 3; |
1666 | |
|
1667 | 0 | if (std::abs((std::abs(params[1]) - 90)) > 0.001) |
1668 | 0 | sTABProj.nProjId = 28; |
1669 | 0 | } |
1670 | | |
1671 | 0 | else if (EQUAL(pszProjection, SRS_PT_CYLINDRICAL_EQUAL_AREA)) |
1672 | 0 | { |
1673 | 0 | sTABProj.nProjId = 2; |
1674 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1675 | 0 | params[1] = |
1676 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0); |
1677 | 0 | nParamCount = 2; |
1678 | 0 | } |
1679 | | |
1680 | 0 | else if (EQUAL(pszProjection, SRS_PT_ECKERT_IV)) |
1681 | 0 | { |
1682 | 0 | sTABProj.nProjId = 14; |
1683 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1684 | 0 | nParamCount = 1; |
1685 | 0 | } |
1686 | | |
1687 | 0 | else if (EQUAL(pszProjection, SRS_PT_ECKERT_VI)) |
1688 | 0 | { |
1689 | 0 | sTABProj.nProjId = 15; |
1690 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1691 | 0 | nParamCount = 1; |
1692 | 0 | } |
1693 | | |
1694 | 0 | else if (EQUAL(pszProjection, SRS_PT_EQUIDISTANT_CONIC)) |
1695 | 0 | { |
1696 | 0 | sTABProj.nProjId = 6; |
1697 | 0 | params[0] = |
1698 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER, 0.0); |
1699 | 0 | params[1] = |
1700 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER, 0.0); |
1701 | 0 | params[2] = |
1702 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0); |
1703 | 0 | params[3] = |
1704 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0); |
1705 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1706 | 0 | params[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1707 | 0 | nParamCount = 6; |
1708 | 0 | } |
1709 | | |
1710 | 0 | else if (EQUAL(pszProjection, SRS_PT_GALL_STEREOGRAPHIC)) |
1711 | 0 | { |
1712 | 0 | sTABProj.nProjId = 17; |
1713 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1714 | 0 | nParamCount = 1; |
1715 | 0 | } |
1716 | | |
1717 | 0 | else if (EQUAL(pszProjection, SRS_PT_HOTINE_OBLIQUE_MERCATOR)) |
1718 | 0 | { |
1719 | 0 | if (std::abs(poSpatialRef->GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE, |
1720 | 0 | 90.0) - |
1721 | 0 | 90.0) < 1e-8) |
1722 | 0 | { |
1723 | 0 | sTABProj.nProjId = 7; |
1724 | 0 | params[0] = |
1725 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER, 0.0); |
1726 | 0 | params[1] = |
1727 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER, 0.0); |
1728 | 0 | params[2] = poSpatialRef->GetNormProjParm(SRS_PP_AZIMUTH, 0.0); |
1729 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1730 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1731 | 0 | params[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1732 | 0 | nParamCount = 6; |
1733 | 0 | } |
1734 | 0 | else |
1735 | 0 | { |
1736 | 0 | sTABProj.nProjId = 35; |
1737 | 0 | params[0] = |
1738 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER, 0.0); |
1739 | 0 | params[1] = |
1740 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER, 0.0); |
1741 | 0 | params[2] = poSpatialRef->GetNormProjParm(SRS_PP_AZIMUTH, 0.0); |
1742 | 0 | params[3] = |
1743 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE, 0.0); |
1744 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1745 | 0 | params[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1746 | 0 | params[6] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1747 | 0 | nParamCount = 7; |
1748 | 0 | } |
1749 | 0 | } |
1750 | | |
1751 | 0 | else if (EQUAL(pszProjection, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA)) |
1752 | 0 | { |
1753 | 0 | sTABProj.nProjId = 4; |
1754 | 0 | params[0] = |
1755 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER, 0.0); |
1756 | 0 | params[1] = |
1757 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER, 0.0); |
1758 | 0 | params[2] = 90.0; |
1759 | 0 | nParamCount = 3; |
1760 | |
|
1761 | 0 | if (std::abs((std::abs(params[1]) - 90)) > 0.001) |
1762 | 0 | sTABProj.nProjId = 29; |
1763 | 0 | } |
1764 | | |
1765 | 0 | else if (EQUAL(pszProjection, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP)) |
1766 | 0 | { |
1767 | 0 | sTABProj.nProjId = 3; |
1768 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1769 | 0 | params[1] = |
1770 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1771 | 0 | params[2] = |
1772 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0); |
1773 | 0 | params[3] = |
1774 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0); |
1775 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1776 | 0 | params[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1777 | 0 | nParamCount = 6; |
1778 | 0 | } |
1779 | | |
1780 | 0 | else if (EQUAL(pszProjection, SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP)) |
1781 | 0 | { |
1782 | 0 | OGRSpatialReference *poOtherSRS = |
1783 | 0 | poSpatialRef->convertToOtherProjection( |
1784 | 0 | SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP); |
1785 | 0 | if (poOtherSRS) |
1786 | 0 | { |
1787 | 0 | sTABProj.nProjId = 3; |
1788 | 0 | params[0] = |
1789 | 0 | poOtherSRS->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1790 | 0 | params[1] = |
1791 | 0 | poOtherSRS->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1792 | 0 | params[2] = |
1793 | 0 | poOtherSRS->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0); |
1794 | 0 | params[3] = |
1795 | 0 | poOtherSRS->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0); |
1796 | 0 | params[4] = poOtherSRS->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1797 | 0 | params[5] = poOtherSRS->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1798 | 0 | nParamCount = 6; |
1799 | 0 | delete poOtherSRS; |
1800 | 0 | } |
1801 | 0 | } |
1802 | | |
1803 | 0 | else if (EQUAL(pszProjection, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM)) |
1804 | 0 | { |
1805 | 0 | sTABProj.nProjId = 19; |
1806 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1807 | 0 | params[1] = |
1808 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1809 | 0 | params[2] = |
1810 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0); |
1811 | 0 | params[3] = |
1812 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2, 0.0); |
1813 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1814 | 0 | params[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1815 | 0 | nParamCount = 6; |
1816 | 0 | } |
1817 | | |
1818 | 0 | else if (EQUAL(pszProjection, SRS_PT_MERCATOR_1SP)) |
1819 | 0 | { |
1820 | 0 | sTABProj.nProjId = 10; |
1821 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1822 | 0 | params[1] = |
1823 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1824 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1825 | 0 | nParamCount = 1; // FIXME for MIF export ? |
1826 | |
|
1827 | 0 | if (params[1] != 0.0) |
1828 | 0 | { |
1829 | 0 | sTABProj.nProjId = 26; |
1830 | 0 | nParamCount = 2; // FIXME for MIF export ? |
1831 | 0 | } |
1832 | 0 | } |
1833 | | |
1834 | 0 | else if (EQUAL(pszProjection, SRS_PT_MERCATOR_2SP)) |
1835 | 0 | { |
1836 | 0 | sTABProj.nProjId = 26; |
1837 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1838 | 0 | params[1] = |
1839 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1, 0.0); |
1840 | 0 | nParamCount = 2; // FIXME for MIF export ? |
1841 | 0 | } |
1842 | | |
1843 | 0 | else if (EQUAL(pszProjection, SRS_PT_MILLER_CYLINDRICAL)) |
1844 | 0 | { |
1845 | 0 | sTABProj.nProjId = 11; |
1846 | 0 | params[0] = |
1847 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER, 0.0); |
1848 | 0 | nParamCount = 1; |
1849 | 0 | } |
1850 | | |
1851 | 0 | else if (EQUAL(pszProjection, SRS_PT_MOLLWEIDE)) |
1852 | 0 | { |
1853 | 0 | sTABProj.nProjId = 13; |
1854 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1855 | 0 | nParamCount = 1; |
1856 | 0 | } |
1857 | | |
1858 | 0 | else if (EQUAL(pszProjection, SRS_PT_NEW_ZEALAND_MAP_GRID)) |
1859 | 0 | { |
1860 | 0 | sTABProj.nProjId = 18; |
1861 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1862 | 0 | params[1] = |
1863 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1864 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1865 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1866 | 0 | nParamCount = 4; |
1867 | 0 | } |
1868 | | |
1869 | 0 | else if (EQUAL(pszProjection, SRS_PT_SWISS_OBLIQUE_CYLINDRICAL)) |
1870 | 0 | { |
1871 | 0 | sTABProj.nProjId = 25; |
1872 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1873 | 0 | params[1] = |
1874 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1875 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1876 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1877 | 0 | nParamCount = 4; |
1878 | 0 | } |
1879 | | |
1880 | | // Swiss Oblique expressed as Hotine Oblique Mercator Azimuth Center |
1881 | 0 | else if (EQUAL(pszProjection, |
1882 | 0 | SRS_PT_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER) && |
1883 | 0 | std::abs(poSpatialRef->GetNormProjParm(SRS_PP_AZIMUTH, 90.0) - |
1884 | 0 | 90.0) < 1e-8 && |
1885 | 0 | std::abs(poSpatialRef->GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE, |
1886 | 0 | 90.0) - |
1887 | 0 | 90.0) < 1e-8 && |
1888 | 0 | std::abs(poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0) - |
1889 | 0 | 1.0) < 1e-8) |
1890 | 0 | { |
1891 | 0 | sTABProj.nProjId = 25; |
1892 | 0 | params[0] = |
1893 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER, 0.0); |
1894 | 0 | params[1] = |
1895 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER, 0.0); |
1896 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1897 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1898 | 0 | nParamCount = 4; |
1899 | 0 | } |
1900 | | |
1901 | 0 | else if (EQUAL(pszProjection, SRS_PT_ROBINSON)) |
1902 | 0 | { |
1903 | 0 | sTABProj.nProjId = 12; |
1904 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1905 | 0 | nParamCount = 1; |
1906 | 0 | } |
1907 | | |
1908 | 0 | else if (EQUAL(pszProjection, SRS_PT_SINUSOIDAL)) |
1909 | 0 | { |
1910 | 0 | sTABProj.nProjId = 16; |
1911 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1912 | 0 | nParamCount = 1; |
1913 | 0 | } |
1914 | | |
1915 | 0 | else if (EQUAL(pszProjection, SRS_PT_STEREOGRAPHIC)) |
1916 | 0 | { |
1917 | 0 | sTABProj.nProjId = 20; |
1918 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1919 | 0 | params[1] = |
1920 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1921 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1922 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1923 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1924 | 0 | nParamCount = 5; |
1925 | 0 | } |
1926 | | |
1927 | 0 | else if (EQUAL(pszProjection, SRS_PT_OBLIQUE_STEREOGRAPHIC)) |
1928 | 0 | { |
1929 | 0 | sTABProj.nProjId = 31; |
1930 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1931 | 0 | params[1] = |
1932 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1933 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1934 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1935 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1936 | 0 | nParamCount = 5; |
1937 | 0 | } |
1938 | | |
1939 | 0 | else if (EQUAL(pszProjection, SRS_PT_TRANSVERSE_MERCATOR)) |
1940 | 0 | { |
1941 | 0 | sTABProj.nProjId = 8; |
1942 | 0 | if ((pszWKTDatum && |
1943 | 0 | EQUAL(pszWKTDatum, "Kartastokoordinaattijarjestelma_1966")) || |
1944 | 0 | nDatumEPSGCode == 6123) |
1945 | 0 | { |
1946 | | // Special case for Finnish KKJ |
1947 | 0 | sTABProj.nProjId = 24; |
1948 | 0 | } |
1949 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1950 | 0 | params[1] = |
1951 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1952 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1953 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1954 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1955 | 0 | nParamCount = 5; |
1956 | 0 | } |
1957 | | |
1958 | 0 | else if (EQUAL(pszProjection, |
1959 | 0 | SRS_PT_TRANSVERSE_MERCATOR_MI_21)) // Encom 2003 |
1960 | 0 | { |
1961 | 0 | sTABProj.nProjId = 21; |
1962 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1963 | 0 | params[1] = |
1964 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1965 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1966 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1967 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1968 | 0 | nParamCount = 5; |
1969 | 0 | } |
1970 | | |
1971 | 0 | else if (EQUAL(pszProjection, |
1972 | 0 | SRS_PT_TRANSVERSE_MERCATOR_MI_22)) // Encom 2003 |
1973 | 0 | { |
1974 | 0 | sTABProj.nProjId = 22; |
1975 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1976 | 0 | params[1] = |
1977 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1978 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1979 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1980 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1981 | 0 | nParamCount = 5; |
1982 | 0 | } |
1983 | | |
1984 | 0 | else if (EQUAL(pszProjection, |
1985 | 0 | SRS_PT_TRANSVERSE_MERCATOR_MI_23)) // Encom 2003 |
1986 | 0 | { |
1987 | 0 | sTABProj.nProjId = 23; |
1988 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
1989 | 0 | params[1] = |
1990 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
1991 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
1992 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
1993 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
1994 | 0 | nParamCount = 5; |
1995 | 0 | } |
1996 | | |
1997 | 0 | else if (EQUAL(pszProjection, |
1998 | 0 | SRS_PT_TRANSVERSE_MERCATOR_MI_24)) // Encom 2003 |
1999 | 0 | { |
2000 | 0 | sTABProj.nProjId = 24; |
2001 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
2002 | 0 | params[1] = |
2003 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
2004 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR, 1.0); |
2005 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
2006 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
2007 | 0 | nParamCount = 5; |
2008 | 0 | } |
2009 | | |
2010 | 0 | else if (EQUAL(pszProjection, SRS_PT_CASSINI_SOLDNER)) |
2011 | 0 | { |
2012 | 0 | sTABProj.nProjId = 30; |
2013 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
2014 | 0 | params[1] = |
2015 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
2016 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
2017 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
2018 | 0 | nParamCount = 4; |
2019 | 0 | } |
2020 | | |
2021 | 0 | else if (EQUAL(pszProjection, SRS_PT_POLYCONIC)) |
2022 | 0 | { |
2023 | 0 | sTABProj.nProjId = 27; |
2024 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
2025 | 0 | params[1] = |
2026 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
2027 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
2028 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
2029 | 0 | nParamCount = 4; |
2030 | 0 | } |
2031 | | |
2032 | 0 | else if (EQUAL(pszProjection, SRS_PT_KROVAK)) |
2033 | 0 | { |
2034 | 0 | sTABProj.nProjId = 32; |
2035 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
2036 | 0 | params[1] = |
2037 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
2038 | 0 | params[2] = |
2039 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_PSEUDO_STD_PARALLEL_1, 0.0); |
2040 | 0 | params[3] = poSpatialRef->GetNormProjParm(SRS_PP_AZIMUTH, 0.0); |
2041 | 0 | params[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
2042 | 0 | params[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
2043 | 0 | nParamCount = 6; |
2044 | 0 | } |
2045 | | |
2046 | 0 | else if (EQUAL(pszProjection, SRS_PT_EQUIRECTANGULAR)) |
2047 | 0 | { |
2048 | 0 | sTABProj.nProjId = 33; |
2049 | 0 | params[0] = poSpatialRef->GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0); |
2050 | 0 | params[1] = |
2051 | 0 | poSpatialRef->GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0); |
2052 | 0 | params[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING, 0.0); |
2053 | 0 | params[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING, 0.0); |
2054 | 0 | nParamCount = 4; |
2055 | 0 | } |
2056 | | |
2057 | 0 | else |
2058 | 0 | { |
2059 | 0 | CPLError(CE_Warning, CPLE_AppDefined, |
2060 | 0 | "No translation from %s to MapInfo known", pszProjection); |
2061 | 0 | } |
2062 | | |
2063 | | /* ============================================================== |
2064 | | * Translate Datum and Ellipsoid |
2065 | | * ============================================================== */ |
2066 | 0 | const MapInfoDatumInfo *psDatumInfo = nullptr; |
2067 | | |
2068 | | /*----------------------------------------------------------------- |
2069 | | * Default to WGS84 if we have no datum at all. |
2070 | | *----------------------------------------------------------------*/ |
2071 | 0 | if (pszWKTDatum == nullptr) |
2072 | 0 | { |
2073 | 0 | CPLDebug("MITAB", |
2074 | 0 | "Cannot find MapInfo datum matching %d. Defaulting to WGS 84", |
2075 | 0 | nDatumEPSGCode); |
2076 | 0 | psDatumInfo = asDatumInfoList + 0; /* WGS 84 */ |
2077 | | // From MIF export code. FIXME? |
2078 | | // if( nProjection == 1 ) |
2079 | | // nProjection = 0; |
2080 | 0 | } |
2081 | | |
2082 | | /*----------------------------------------------------------------- |
2083 | | * We know the MIF datum number, and need to look it up to |
2084 | | * translate into datum parameters. |
2085 | | *----------------------------------------------------------------*/ |
2086 | 0 | else if (STARTS_WITH_CI(pszWKTDatum, "MIF ") && |
2087 | 0 | atoi(pszWKTDatum + 4) != 999 && atoi(pszWKTDatum + 4) != 9999) |
2088 | 0 | { |
2089 | 0 | int nDatum = atoi(pszWKTDatum + 4); |
2090 | 0 | for (int i = 0; asDatumInfoList[i].nMapInfoDatumID != -1; i++) |
2091 | 0 | { |
2092 | 0 | if (nDatum == asDatumInfoList[i].nMapInfoDatumID) |
2093 | 0 | { |
2094 | 0 | psDatumInfo = asDatumInfoList + i; |
2095 | 0 | break; |
2096 | 0 | } |
2097 | 0 | } |
2098 | |
|
2099 | 0 | if (psDatumInfo == nullptr) |
2100 | 0 | { |
2101 | 0 | CPLDebug( |
2102 | 0 | "MITAB", |
2103 | 0 | "Cannot find MapInfo datum matching %s. Defaulting to WGS 84", |
2104 | 0 | pszWKTDatum); |
2105 | 0 | psDatumInfo = asDatumInfoList + 0; /* WGS 84 */ |
2106 | 0 | } |
2107 | 0 | } |
2108 | | |
2109 | | /*----------------------------------------------------------------- |
2110 | | * We have the MIF datum parameters, and apply those directly. |
2111 | | *----------------------------------------------------------------*/ |
2112 | 0 | else if (STARTS_WITH_CI(pszWKTDatum, "MIF ") && |
2113 | 0 | (atoi(pszWKTDatum + 4) == 999 || atoi(pszWKTDatum + 4) == 9999)) |
2114 | 0 | { |
2115 | 0 | sTABProj.nDatumId = static_cast<GInt16>(atoi(pszWKTDatum + 4)); |
2116 | 0 | char **papszFields = |
2117 | 0 | CSLTokenizeStringComplex(pszWKTDatum + 4, ",", FALSE, TRUE); |
2118 | |
|
2119 | 0 | if (CSLCount(papszFields) >= 5) |
2120 | 0 | { |
2121 | 0 | sTABProj.nEllipsoidId = static_cast<GByte>(atoi(papszFields[1])); |
2122 | 0 | sTABProj.dDatumShiftX = CPLAtof(papszFields[2]); |
2123 | 0 | sTABProj.dDatumShiftY = CPLAtof(papszFields[3]); |
2124 | 0 | sTABProj.dDatumShiftZ = CPLAtof(papszFields[4]); |
2125 | 0 | } |
2126 | |
|
2127 | 0 | if (CSLCount(papszFields) >= 10) |
2128 | 0 | { |
2129 | 0 | sTABProj.adDatumParams[0] = CPLAtof(papszFields[5]); |
2130 | 0 | sTABProj.adDatumParams[1] = CPLAtof(papszFields[6]); |
2131 | 0 | sTABProj.adDatumParams[2] = CPLAtof(papszFields[7]); |
2132 | 0 | sTABProj.adDatumParams[3] = CPLAtof(papszFields[8]); |
2133 | 0 | sTABProj.adDatumParams[4] = CPLAtof(papszFields[9]); |
2134 | 0 | } |
2135 | |
|
2136 | 0 | if (CSLCount(papszFields) < 5) |
2137 | 0 | { |
2138 | 0 | CPLDebug( |
2139 | 0 | "MITAB", |
2140 | 0 | "Cannot find MapInfo datum matching %s. Defaulting to WGS 84", |
2141 | 0 | pszWKTDatum); |
2142 | 0 | psDatumInfo = asDatumInfoList + 0; /* WGS 84 */ |
2143 | 0 | } |
2144 | |
|
2145 | 0 | CSLDestroy(papszFields); |
2146 | 0 | } |
2147 | | |
2148 | | /*----------------------------------------------------------------- |
2149 | | * We have a "real" datum name, and possibly an EPSG code for the |
2150 | | * datum. Try to look it up (using EPSG code first) and get the |
2151 | | * parameters. If we don't find it with either just use WGS84. |
2152 | | *----------------------------------------------------------------*/ |
2153 | 0 | else |
2154 | 0 | { |
2155 | 0 | for (int i = 0; asDatumInfoList[i].nMapInfoDatumID != -1; i++) |
2156 | 0 | { |
2157 | 0 | if ((nDatumEPSGCode > 0 && |
2158 | 0 | asDatumInfoList[i].nDatumEPSGCode == nDatumEPSGCode) || |
2159 | 0 | EQUAL(pszWKTDatum, asDatumInfoList[i].pszOGCDatumName)) |
2160 | 0 | { |
2161 | 0 | psDatumInfo = asDatumInfoList + i; |
2162 | 0 | break; |
2163 | 0 | } |
2164 | 0 | } |
2165 | |
|
2166 | 0 | if (psDatumInfo == nullptr && |
2167 | 0 | !MITABGetCustomDatum(poSpatialRef, sTABProj)) |
2168 | 0 | { |
2169 | 0 | CPLDebug("MITAB", |
2170 | 0 | "Cannot find MapInfo datum matching %s,%d. Defaulting to " |
2171 | 0 | "WGS 84", |
2172 | 0 | pszWKTDatum, nDatumEPSGCode); |
2173 | 0 | psDatumInfo = asDatumInfoList + 0; /* WGS 84 */ |
2174 | 0 | } |
2175 | 0 | } |
2176 | |
|
2177 | 0 | if (psDatumInfo != nullptr) |
2178 | 0 | { |
2179 | 0 | sTABProj.nEllipsoidId = static_cast<GByte>(psDatumInfo->nEllipsoid); |
2180 | 0 | sTABProj.nDatumId = static_cast<GInt16>(psDatumInfo->nMapInfoDatumID); |
2181 | 0 | sTABProj.dDatumShiftX = psDatumInfo->dfShiftX; |
2182 | 0 | sTABProj.dDatumShiftY = psDatumInfo->dfShiftY; |
2183 | 0 | sTABProj.dDatumShiftZ = psDatumInfo->dfShiftZ; |
2184 | 0 | sTABProj.adDatumParams[0] = psDatumInfo->dfDatumParm0; |
2185 | 0 | sTABProj.adDatumParams[1] = psDatumInfo->dfDatumParm1; |
2186 | 0 | sTABProj.adDatumParams[2] = psDatumInfo->dfDatumParm2; |
2187 | 0 | sTABProj.adDatumParams[3] = psDatumInfo->dfDatumParm3; |
2188 | 0 | sTABProj.adDatumParams[4] = psDatumInfo->dfDatumParm4; |
2189 | | |
2190 | | /* For LCC, standard parallel 1 and 2 can be switched indifferently */ |
2191 | | /* So the MapInfo order and the EPSG order are not generally identical |
2192 | | */ |
2193 | | /* which may cause recognition problems when reading in MapInfo */ |
2194 | 0 | if (sTABProj.nProjId == 3) |
2195 | 0 | { |
2196 | 0 | const double dfCenterLong = params[0]; |
2197 | 0 | const double dfCenterLat = params[1]; |
2198 | 0 | const double dfStdP1 = params[2]; |
2199 | 0 | const double dfStdP2 = params[3]; |
2200 | | |
2201 | | // EPSG:3301 "Estonian Coordinate System of 1997" |
2202 | 0 | if (std::fabs(dfCenterLong - 24) <= 1e-10 && |
2203 | 0 | std::fabs(dfCenterLat - 57.51755393056) <= 1e-10 && |
2204 | | // MapInfo uses a less accurate value of StdP2 than EPSG |
2205 | 0 | std::fabs(dfStdP1 - 59.33333333) <= 1e-8 && |
2206 | 0 | std::fabs(dfStdP2 - 58) <= 1e-8) |
2207 | 0 | { |
2208 | 0 | CPLDebug("MITAB", "Switching standard parallel 1 and 2"); |
2209 | 0 | std::swap(params[2], params[3]); |
2210 | 0 | } |
2211 | 0 | else |
2212 | 0 | { |
2213 | 0 | for (size_t i = 0; i < sizeof(asMapInfoLCCSRSList) / |
2214 | 0 | sizeof(asMapInfoLCCSRSList[0]); |
2215 | 0 | i++) |
2216 | 0 | { |
2217 | 0 | if (sTABProj.nDatumId == |
2218 | 0 | asMapInfoLCCSRSList[i].nMapInfoDatumID && |
2219 | 0 | TAB_EQUAL(dfCenterLong, |
2220 | 0 | asMapInfoLCCSRSList[i].dfCenterLong) && |
2221 | 0 | TAB_EQUAL(dfCenterLat, |
2222 | 0 | asMapInfoLCCSRSList[i].dfCenterLat)) |
2223 | 0 | { |
2224 | 0 | if (TAB_EQUAL(dfStdP1, |
2225 | 0 | asMapInfoLCCSRSList[i].dfStdP1) && |
2226 | 0 | TAB_EQUAL(dfStdP2, asMapInfoLCCSRSList[i].dfStdP2)) |
2227 | 0 | { |
2228 | 0 | break; |
2229 | 0 | } |
2230 | 0 | else if (TAB_EQUAL(dfStdP1, |
2231 | 0 | asMapInfoLCCSRSList[i].dfStdP2) && |
2232 | 0 | TAB_EQUAL(dfStdP2, |
2233 | 0 | asMapInfoLCCSRSList[i].dfStdP1)) |
2234 | 0 | { |
2235 | 0 | CPLDebug("MITAB", |
2236 | 0 | "Switching standard parallel 1 and 2"); |
2237 | 0 | std::swap(params[2], params[3]); |
2238 | 0 | break; |
2239 | 0 | } |
2240 | 0 | } |
2241 | 0 | } |
2242 | 0 | } |
2243 | 0 | } |
2244 | 0 | } |
2245 | | |
2246 | | // Google Merc |
2247 | 0 | const char *pszAuthorityName = nullptr; |
2248 | 0 | const char *pszAuthorityCode = nullptr; |
2249 | 0 | const char *pszExtension = nullptr; |
2250 | 0 | if (((pszAuthorityName = poSpatialRef->GetAuthorityName(nullptr)) != |
2251 | 0 | nullptr && |
2252 | 0 | EQUAL(pszAuthorityName, "EPSG") && |
2253 | 0 | (pszAuthorityCode = poSpatialRef->GetAuthorityCode(nullptr)) != |
2254 | 0 | nullptr && |
2255 | 0 | atoi(pszAuthorityCode) == 3857) || |
2256 | 0 | ((pszExtension = poSpatialRef->GetExtension(nullptr, "PROJ4")) != |
2257 | 0 | nullptr && |
2258 | 0 | (EQUAL(pszExtension, "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 " |
2259 | 0 | "+lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m " |
2260 | 0 | "+nadgrids=@null +wktext +no_defs") || |
2261 | 0 | EQUAL(pszExtension, |
2262 | 0 | "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 " |
2263 | 0 | "+y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs")))) |
2264 | 0 | { |
2265 | 0 | sTABProj.nDatumId = 157; |
2266 | 0 | sTABProj.nEllipsoidId = 54; |
2267 | 0 | } |
2268 | | |
2269 | | /*----------------------------------------------------------------- |
2270 | | * Translate the units |
2271 | | *----------------------------------------------------------------*/ |
2272 | 0 | if (sTABProj.nProjId == 1 || pszLinearUnits == nullptr) |
2273 | 0 | sTABProj.nUnitsId = 13; |
2274 | 0 | else if (dfLinearConv == 1000.0) |
2275 | 0 | sTABProj.nUnitsId = 1; |
2276 | 0 | else if (dfLinearConv == 0.0254 || EQUAL(pszLinearUnits, "Inch") || |
2277 | 0 | EQUAL(pszLinearUnits, "IINCH")) |
2278 | 0 | sTABProj.nUnitsId = 2; |
2279 | 0 | else if (fabs(dfLinearConv - CPLAtof(SRS_UL_FOOT_CONV)) < |
2280 | 0 | 1e-15 * dfLinearConv || |
2281 | 0 | EQUAL(pszLinearUnits, SRS_UL_FOOT)) |
2282 | 0 | sTABProj.nUnitsId = 3; |
2283 | 0 | else if (EQUAL(pszLinearUnits, "YARD") || EQUAL(pszLinearUnits, "IYARD") || |
2284 | 0 | dfLinearConv == 0.9144) |
2285 | 0 | sTABProj.nUnitsId = 4; |
2286 | 0 | else if (dfLinearConv == 0.001) |
2287 | 0 | sTABProj.nUnitsId = 5; |
2288 | 0 | else if (dfLinearConv == 0.01) |
2289 | 0 | sTABProj.nUnitsId = 6; |
2290 | 0 | else if (dfLinearConv == 1.0) |
2291 | 0 | sTABProj.nUnitsId = 7; |
2292 | 0 | else if (fabs(dfLinearConv - CPLAtof(SRS_UL_US_FOOT_CONV)) < |
2293 | 0 | 1e-15 * dfLinearConv || |
2294 | 0 | EQUAL(pszLinearUnits, SRS_UL_US_FOOT)) |
2295 | 0 | sTABProj.nUnitsId = 8; |
2296 | 0 | else if (dfLinearConv == 1852.0 || |
2297 | 0 | EQUAL(pszLinearUnits, SRS_UL_NAUTICAL_MILE)) |
2298 | 0 | sTABProj.nUnitsId = 9; |
2299 | 0 | else if (EQUAL(pszLinearUnits, SRS_UL_LINK) || |
2300 | 0 | EQUAL(pszLinearUnits, "GUNTERLINK")) |
2301 | 0 | sTABProj.nUnitsId = 30; |
2302 | 0 | else if (EQUAL(pszLinearUnits, SRS_UL_CHAIN) || |
2303 | 0 | EQUAL(pszLinearUnits, "GUNTERCHAIN")) |
2304 | 0 | sTABProj.nUnitsId = 31; |
2305 | 0 | else if (EQUAL(pszLinearUnits, SRS_UL_ROD)) |
2306 | 0 | sTABProj.nUnitsId = 32; |
2307 | 0 | else if (EQUAL(pszLinearUnits, "Mile") || EQUAL(pszLinearUnits, "IMILE")) |
2308 | 0 | sTABProj.nUnitsId = 0; |
2309 | 0 | else |
2310 | 0 | sTABProj.nUnitsId = 7; |
2311 | |
|
2312 | 0 | return 0; |
2313 | 0 | } |
2314 | | |
2315 | | extern const MapInfoDatumInfo asDatumInfoList[]; |
2316 | | extern const MapInfoSpheroidInfo asSpheroidInfoList[]; |
2317 | | |
2318 | | /************************************************************************/ |
2319 | | /* MITABCoordSys2SpatialRef() */ |
2320 | | /* */ |
2321 | | /* Convert a MIF COORDSYS string into a new OGRSpatialReference */ |
2322 | | /* object. */ |
2323 | | /************************************************************************/ |
2324 | | |
2325 | | OGRSpatialReference *MITABCoordSys2SpatialRef(const char *pszCoordSys) |
2326 | | |
2327 | 0 | { |
2328 | 0 | TABProjInfo sTABProj; |
2329 | 0 | if (MITABCoordSys2TABProjInfo(pszCoordSys, &sTABProj) < 0) |
2330 | 0 | return nullptr; |
2331 | 0 | OGRSpatialReference *poSR = TABFileGetSpatialRefFromTABProj(sTABProj); |
2332 | | |
2333 | | // Report on translation. |
2334 | 0 | char *pszWKT = nullptr; |
2335 | |
|
2336 | 0 | poSR->exportToWkt(&pszWKT); |
2337 | 0 | if (pszWKT != nullptr) |
2338 | 0 | { |
2339 | 0 | CPLDebug("MITAB", "This CoordSys value:\n%s\nwas translated to:\n%s", |
2340 | 0 | pszCoordSys, pszWKT); |
2341 | 0 | CPLFree(pszWKT); |
2342 | 0 | } |
2343 | |
|
2344 | 0 | return poSR; |
2345 | 0 | } |
2346 | | |
2347 | | /************************************************************************/ |
2348 | | /* MITABSpatialRef2CoordSys() */ |
2349 | | /* */ |
2350 | | /* Converts a OGRSpatialReference object into a MIF COORDSYS */ |
2351 | | /* string. */ |
2352 | | /* */ |
2353 | | /* The function returns a newly allocated string that should be */ |
2354 | | /* CPLFree()'d by the caller. */ |
2355 | | /************************************************************************/ |
2356 | | |
2357 | | char *MITABSpatialRef2CoordSys(const OGRSpatialReference *poSR) |
2358 | | |
2359 | 0 | { |
2360 | 0 | if (poSR == nullptr) |
2361 | 0 | return nullptr; |
2362 | | |
2363 | 0 | TABProjInfo sTABProj; |
2364 | 0 | int nParamCount = 0; |
2365 | 0 | TABFileGetTABProjFromSpatialRef(poSR, sTABProj, nParamCount); |
2366 | | |
2367 | | // Do coordsys lookup. |
2368 | 0 | double dXMin = 0.0; |
2369 | 0 | double dYMin = 0.0; |
2370 | 0 | double dXMax = 0.0; |
2371 | 0 | double dYMax = 0.0; |
2372 | 0 | bool bHasBounds = false; |
2373 | 0 | if (sTABProj.nProjId > 1 && |
2374 | 0 | MITABLookupCoordSysBounds(&sTABProj, dXMin, dYMin, dXMax, dYMax, true)) |
2375 | 0 | { |
2376 | 0 | bHasBounds = true; |
2377 | 0 | } |
2378 | | |
2379 | | // Translate the units. |
2380 | 0 | const char *pszMIFUnits = TABUnitIdToString(sTABProj.nUnitsId); |
2381 | | |
2382 | | // Build coordinate system definition. |
2383 | 0 | CPLString osCoordSys; |
2384 | |
|
2385 | 0 | if (sTABProj.nProjId != 0) |
2386 | 0 | { |
2387 | 0 | osCoordSys.Printf("Earth Projection %d", sTABProj.nProjId); |
2388 | 0 | } |
2389 | 0 | else |
2390 | 0 | { |
2391 | 0 | osCoordSys.Printf("NonEarth Units"); |
2392 | 0 | } |
2393 | | |
2394 | | // Append Datum. |
2395 | 0 | if (sTABProj.nProjId != 0) |
2396 | 0 | { |
2397 | 0 | osCoordSys += CPLSPrintf(", %d", sTABProj.nDatumId); |
2398 | |
|
2399 | 0 | if (sTABProj.nDatumId == 999 || sTABProj.nDatumId == 9999) |
2400 | 0 | { |
2401 | 0 | osCoordSys += |
2402 | 0 | CPLSPrintf(", %d, %.15g, %.15g, %.15g", sTABProj.nEllipsoidId, |
2403 | 0 | sTABProj.dDatumShiftX, sTABProj.dDatumShiftY, |
2404 | 0 | sTABProj.dDatumShiftZ); |
2405 | 0 | } |
2406 | |
|
2407 | 0 | if (sTABProj.nDatumId == 9999) |
2408 | 0 | { |
2409 | 0 | osCoordSys += |
2410 | 0 | CPLSPrintf(", %.15g, %.15g, %.15g, %.15g, %.15g", |
2411 | 0 | sTABProj.adDatumParams[0], sTABProj.adDatumParams[1], |
2412 | 0 | sTABProj.adDatumParams[2], sTABProj.adDatumParams[3], |
2413 | 0 | sTABProj.adDatumParams[4]); |
2414 | 0 | } |
2415 | 0 | } |
2416 | | |
2417 | | // Append units. |
2418 | 0 | if (sTABProj.nProjId != 1 && pszMIFUnits != nullptr) |
2419 | 0 | { |
2420 | 0 | if (sTABProj.nProjId != 0) |
2421 | 0 | osCoordSys += ","; |
2422 | |
|
2423 | 0 | osCoordSys += CPLSPrintf(" \"%s\"", pszMIFUnits); |
2424 | 0 | } |
2425 | | |
2426 | | // Append Projection Params. |
2427 | 0 | for (int iParam = 0; iParam < nParamCount; iParam++) |
2428 | 0 | osCoordSys += CPLSPrintf(", %.15g", sTABProj.adProjParams[iParam]); |
2429 | | |
2430 | | // Append user bounds. |
2431 | 0 | if (bHasBounds) |
2432 | 0 | { |
2433 | 0 | if (fabs(dXMin - floor(dXMin + 0.5)) < 1e-8 && |
2434 | 0 | fabs(dYMin - floor(dYMin + 0.5)) < 1e-8 && |
2435 | 0 | fabs(dXMax - floor(dXMax + 0.5)) < 1e-8 && |
2436 | 0 | fabs(dYMax - floor(dYMax + 0.5)) < 1e-8) |
2437 | 0 | { |
2438 | 0 | osCoordSys += |
2439 | 0 | CPLSPrintf(" Bounds (%d, %d) (%d, %d)", static_cast<int>(dXMin), |
2440 | 0 | static_cast<int>(dYMin), static_cast<int>(dXMax), |
2441 | 0 | static_cast<int>(dYMax)); |
2442 | 0 | } |
2443 | 0 | else |
2444 | 0 | { |
2445 | 0 | osCoordSys += CPLSPrintf(" Bounds (%f, %f) (%f, %f)", dXMin, dYMin, |
2446 | 0 | dXMax, dYMax); |
2447 | 0 | } |
2448 | 0 | } |
2449 | | |
2450 | | // Report on translation. |
2451 | 0 | char *pszWKT = nullptr; |
2452 | |
|
2453 | 0 | poSR->exportToWkt(&pszWKT); |
2454 | 0 | if (pszWKT != nullptr) |
2455 | 0 | { |
2456 | 0 | CPLDebug("MITAB", "This WKT Projection:\n%s\n\ntranslates to:\n%s", |
2457 | 0 | pszWKT, osCoordSys.c_str()); |
2458 | 0 | CPLFree(pszWKT); |
2459 | 0 | } |
2460 | |
|
2461 | 0 | return CPLStrdup(osCoordSys.c_str()); |
2462 | 0 | } |
2463 | | |
2464 | | /************************************************************************/ |
2465 | | /* MITABExtractCoordSysBounds */ |
2466 | | /* */ |
2467 | | /* Return true if MIF coordsys string contains a BOUNDS parameter and */ |
2468 | | /* Set x/y min/max values. */ |
2469 | | /************************************************************************/ |
2470 | | |
2471 | | bool MITABExtractCoordSysBounds(const char *pszCoordSys, double &dXMin, |
2472 | | double &dYMin, double &dXMax, double &dYMax) |
2473 | | |
2474 | 0 | { |
2475 | 0 | if (pszCoordSys == nullptr) |
2476 | 0 | return false; |
2477 | | |
2478 | 0 | char **papszFields = |
2479 | 0 | CSLTokenizeStringComplex(pszCoordSys, " ,()", TRUE, FALSE); |
2480 | |
|
2481 | 0 | int iBounds = CSLFindString(papszFields, "Bounds"); |
2482 | |
|
2483 | 0 | if (iBounds >= 0 && iBounds + 4 < CSLCount(papszFields)) |
2484 | 0 | { |
2485 | 0 | dXMin = CPLAtof(papszFields[++iBounds]); |
2486 | 0 | dYMin = CPLAtof(papszFields[++iBounds]); |
2487 | 0 | dXMax = CPLAtof(papszFields[++iBounds]); |
2488 | 0 | dYMax = CPLAtof(papszFields[++iBounds]); |
2489 | 0 | CSLDestroy(papszFields); |
2490 | 0 | return true; |
2491 | 0 | } |
2492 | | |
2493 | 0 | CSLDestroy(papszFields); |
2494 | 0 | return false; |
2495 | 0 | } |
2496 | | |
2497 | | /********************************************************************** |
2498 | | * MITABCoordSys2TABProjInfo() |
2499 | | * |
2500 | | * Convert a MIF COORDSYS string into a TABProjInfo structure. |
2501 | | * |
2502 | | * Returns 0 on success, -1 on error. |
2503 | | **********************************************************************/ |
2504 | | int MITABCoordSys2TABProjInfo(const char *pszCoordSys, TABProjInfo *psProj) |
2505 | | |
2506 | 0 | { |
2507 | | // Set all fields to zero, equivalent of NonEarth Units "mi" |
2508 | 0 | memset(psProj, 0, sizeof(TABProjInfo)); |
2509 | |
|
2510 | 0 | if (pszCoordSys == nullptr) |
2511 | 0 | return -1; |
2512 | | |
2513 | | // Parse the passed string into words. |
2514 | 0 | while (*pszCoordSys == ' ') |
2515 | 0 | pszCoordSys++; // Eat leading spaces. |
2516 | 0 | if (STARTS_WITH_CI(pszCoordSys, "CoordSys") && pszCoordSys[8] != '\0') |
2517 | 0 | pszCoordSys += 9; |
2518 | |
|
2519 | 0 | char **papszFields = |
2520 | 0 | CSLTokenizeStringComplex(pszCoordSys, " ,", TRUE, FALSE); |
2521 | | |
2522 | | // Clip off Bounds information. |
2523 | 0 | int iBounds = CSLFindString(papszFields, "Bounds"); |
2524 | |
|
2525 | 0 | while (iBounds != -1 && papszFields[iBounds] != nullptr) |
2526 | 0 | { |
2527 | 0 | CPLFree(papszFields[iBounds]); |
2528 | 0 | papszFields[iBounds] = nullptr; |
2529 | 0 | iBounds++; |
2530 | 0 | } |
2531 | | |
2532 | | // Fetch the projection. |
2533 | 0 | char **papszNextField = nullptr; |
2534 | |
|
2535 | 0 | if (CSLCount(papszFields) >= 3 && EQUAL(papszFields[0], "Earth") && |
2536 | 0 | EQUAL(papszFields[1], "Projection")) |
2537 | 0 | { |
2538 | 0 | int nProjId = atoi(papszFields[2]); |
2539 | 0 | if (nProjId >= 3000) |
2540 | 0 | nProjId -= 3000; |
2541 | 0 | else if (nProjId >= 2000) |
2542 | 0 | nProjId -= 2000; |
2543 | 0 | else if (nProjId >= 1000) |
2544 | 0 | nProjId -= 1000; |
2545 | |
|
2546 | 0 | psProj->nProjId = static_cast<GByte>(nProjId); |
2547 | 0 | papszNextField = papszFields + 3; |
2548 | 0 | } |
2549 | 0 | else if (CSLCount(papszFields) >= 2 && EQUAL(papszFields[0], "NonEarth")) |
2550 | 0 | { |
2551 | | // NonEarth Units "..." Bounds (x, y) (x, y) |
2552 | 0 | psProj->nProjId = 0; |
2553 | 0 | papszNextField = papszFields + 2; |
2554 | |
|
2555 | 0 | if (papszNextField[0] != nullptr && EQUAL(papszNextField[0], "Units")) |
2556 | 0 | papszNextField++; |
2557 | 0 | } |
2558 | 0 | else |
2559 | 0 | { |
2560 | | // Invalid projection string ??? |
2561 | 0 | if (CSLCount(papszFields) > 0) |
2562 | 0 | CPLError(CE_Warning, CPLE_IllegalArg, |
2563 | 0 | "Failed parsing CoordSys: '%s'", pszCoordSys); |
2564 | 0 | CSLDestroy(papszFields); |
2565 | 0 | return -1; |
2566 | 0 | } |
2567 | | |
2568 | | // Fetch the datum information. |
2569 | 0 | int nDatum = 0; |
2570 | |
|
2571 | 0 | if (psProj->nProjId != 0 && CSLCount(papszNextField) > 0) |
2572 | 0 | { |
2573 | 0 | nDatum = atoi(papszNextField[0]); |
2574 | 0 | papszNextField++; |
2575 | 0 | } |
2576 | |
|
2577 | 0 | if ((nDatum == 999 || nDatum == 9999) && CSLCount(papszNextField) >= 4) |
2578 | 0 | { |
2579 | 0 | psProj->nEllipsoidId = static_cast<GByte>(atoi(papszNextField[0])); |
2580 | 0 | psProj->dDatumShiftX = CPLAtof(papszNextField[1]); |
2581 | 0 | psProj->dDatumShiftY = CPLAtof(papszNextField[2]); |
2582 | 0 | psProj->dDatumShiftZ = CPLAtof(papszNextField[3]); |
2583 | 0 | papszNextField += 4; |
2584 | |
|
2585 | 0 | if (nDatum == 9999 && CSLCount(papszNextField) >= 5) |
2586 | 0 | { |
2587 | 0 | psProj->adDatumParams[0] = CPLAtof(papszNextField[0]); |
2588 | 0 | psProj->adDatumParams[1] = CPLAtof(papszNextField[1]); |
2589 | 0 | psProj->adDatumParams[2] = CPLAtof(papszNextField[2]); |
2590 | 0 | psProj->adDatumParams[3] = CPLAtof(papszNextField[3]); |
2591 | 0 | psProj->adDatumParams[4] = CPLAtof(papszNextField[4]); |
2592 | 0 | papszNextField += 5; |
2593 | 0 | } |
2594 | 0 | } |
2595 | 0 | else if (nDatum != 999 && nDatum != 9999) |
2596 | 0 | { |
2597 | | // Find the datum, and collect its parameters if possible. |
2598 | 0 | const MapInfoDatumInfo *psDatumInfo = nullptr; |
2599 | |
|
2600 | 0 | int iDatum = 0; // Used after for. |
2601 | 0 | for (; asDatumInfoList[iDatum].nMapInfoDatumID != -1; iDatum++) |
2602 | 0 | { |
2603 | 0 | if (asDatumInfoList[iDatum].nMapInfoDatumID == nDatum) |
2604 | 0 | { |
2605 | 0 | psDatumInfo = asDatumInfoList + iDatum; |
2606 | 0 | break; |
2607 | 0 | } |
2608 | 0 | } |
2609 | |
|
2610 | 0 | if (asDatumInfoList[iDatum].nMapInfoDatumID == -1) |
2611 | 0 | { |
2612 | | // Use WGS84. |
2613 | 0 | psDatumInfo = asDatumInfoList + 0; |
2614 | 0 | } |
2615 | |
|
2616 | 0 | if (psDatumInfo != nullptr) |
2617 | 0 | { |
2618 | 0 | psProj->nEllipsoidId = static_cast<GByte>(psDatumInfo->nEllipsoid); |
2619 | 0 | psProj->nDatumId = |
2620 | 0 | static_cast<GInt16>(psDatumInfo->nMapInfoDatumID); |
2621 | 0 | psProj->dDatumShiftX = psDatumInfo->dfShiftX; |
2622 | 0 | psProj->dDatumShiftY = psDatumInfo->dfShiftY; |
2623 | 0 | psProj->dDatumShiftZ = psDatumInfo->dfShiftZ; |
2624 | 0 | psProj->adDatumParams[0] = psDatumInfo->dfDatumParm0; |
2625 | 0 | psProj->adDatumParams[1] = psDatumInfo->dfDatumParm1; |
2626 | 0 | psProj->adDatumParams[2] = psDatumInfo->dfDatumParm2; |
2627 | 0 | psProj->adDatumParams[3] = psDatumInfo->dfDatumParm3; |
2628 | 0 | psProj->adDatumParams[4] = psDatumInfo->dfDatumParm4; |
2629 | 0 | } |
2630 | 0 | } |
2631 | | |
2632 | | // Fetch the units string. |
2633 | 0 | if (CSLCount(papszNextField) > 0) |
2634 | 0 | { |
2635 | 0 | if (isdigit(static_cast<unsigned char>(papszNextField[0][0]))) |
2636 | 0 | { |
2637 | 0 | psProj->nUnitsId = static_cast<GByte>(atoi(papszNextField[0])); |
2638 | 0 | } |
2639 | 0 | else |
2640 | 0 | { |
2641 | 0 | psProj->nUnitsId = |
2642 | 0 | static_cast<GByte>(TABUnitIdFromString(papszNextField[0])); |
2643 | 0 | } |
2644 | 0 | papszNextField++; |
2645 | 0 | } |
2646 | | |
2647 | | // Finally the projection parameters. |
2648 | 0 | for (int iParam = 0; iParam < 7 && CSLCount(papszNextField) > 0; iParam++) |
2649 | 0 | { |
2650 | 0 | psProj->adProjParams[iParam] = CPLAtof(papszNextField[0]); |
2651 | 0 | papszNextField++; |
2652 | 0 | } |
2653 | |
|
2654 | 0 | CSLDestroy(papszFields); |
2655 | |
|
2656 | 0 | return 0; |
2657 | 0 | } |
2658 | | |
2659 | | /*! @endcond */ |