Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL
4 : * Purpose: GDALPamDataset with internal storage for georeferencing, with
5 : * priority for PAM over internal georeferencing
6 : * Author: Even Rouault <even dot rouault at spatialys.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #include "gdalgeorefpamdataset.h"
15 :
16 : #include <cstring>
17 :
18 : #include "cpl_conv.h"
19 : #include "cpl_error.h"
20 : #include "gdal.h"
21 :
22 : //! @cond Doxygen_Suppress
23 : /************************************************************************/
24 : /* GDALGeorefPamDataset() */
25 : /************************************************************************/
26 :
27 2429 : GDALGeorefPamDataset::GDALGeorefPamDataset()
28 : : bGeoTransformValid(false), nGCPCount(0), pasGCPList(nullptr),
29 : m_papszRPC(nullptr), m_bPixelIsPoint(false),
30 : m_nGeoTransformGeorefSrcIndex(-1), m_nGCPGeorefSrcIndex(-1),
31 : m_nProjectionGeorefSrcIndex(-1), m_nRPCGeorefSrcIndex(-1),
32 : m_nPixelIsPointGeorefSrcIndex(-1), m_bGotPAMGeorefSrcIndex(false),
33 2429 : m_nPAMGeorefSrcIndex(0), m_bPAMLoaded(false), m_papszMainMD(nullptr)
34 : {
35 2429 : }
36 :
37 : /************************************************************************/
38 : /* ~GDALGeorefPamDataset() */
39 : /************************************************************************/
40 :
41 2429 : GDALGeorefPamDataset::~GDALGeorefPamDataset()
42 : {
43 2429 : if (nGCPCount > 0)
44 : {
45 14 : GDALDeinitGCPs(nGCPCount, pasGCPList);
46 14 : CPLFree(pasGCPList);
47 : }
48 2429 : CSLDestroy(m_papszMainMD);
49 2429 : CSLDestroy(m_papszRPC);
50 2429 : }
51 :
52 : /************************************************************************/
53 : /* GetMetadata() */
54 : /************************************************************************/
55 :
56 1073 : CSLConstList GDALGeorefPamDataset::GetMetadata(const char *pszDomain)
57 : {
58 1073 : if (pszDomain != nullptr && EQUAL(pszDomain, GDAL_MDD_RPC))
59 : {
60 25 : const int nPAMIndex = GetPAMGeorefSrcIndex();
61 25 : if (nPAMIndex >= 0 &&
62 25 : ((m_papszRPC != nullptr && nPAMIndex < m_nRPCGeorefSrcIndex) ||
63 24 : m_nRPCGeorefSrcIndex < 0 || m_papszRPC == nullptr))
64 : {
65 25 : CSLConstList papszMD = GDALPamDataset::GetMetadata(pszDomain);
66 25 : if (papszMD)
67 2 : return papszMD;
68 : }
69 23 : return m_papszRPC;
70 : }
71 :
72 1048 : if (pszDomain == nullptr || EQUAL(pszDomain, ""))
73 : {
74 500 : if (m_papszMainMD)
75 59 : return m_papszMainMD;
76 441 : m_papszMainMD = CSLDuplicate(GDALPamDataset::GetMetadata(pszDomain));
77 441 : const int nPAMIndex = GetPAMGeorefSrcIndex();
78 441 : if (nPAMIndex >= 0 &&
79 441 : ((m_bPixelIsPoint && nPAMIndex < m_nPixelIsPointGeorefSrcIndex) ||
80 437 : m_nPixelIsPointGeorefSrcIndex < 0 || !m_bPixelIsPoint))
81 : {
82 441 : if (CSLFetchNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT) !=
83 : nullptr)
84 0 : return m_papszMainMD;
85 : }
86 441 : if (m_bPixelIsPoint)
87 : {
88 4 : m_papszMainMD = CSLSetNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT,
89 : GDALMD_AOP_POINT);
90 : }
91 : else
92 : {
93 437 : m_papszMainMD =
94 437 : CSLSetNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT, nullptr);
95 : }
96 441 : return m_papszMainMD;
97 : }
98 :
99 548 : return GDALPamDataset::GetMetadata(pszDomain);
100 : }
101 :
102 : /************************************************************************/
103 : /* GetMetadataItem() */
104 : /************************************************************************/
105 :
106 442 : const char *GDALGeorefPamDataset::GetMetadataItem(const char *pszName,
107 : const char *pszDomain)
108 : {
109 442 : if (pszDomain == nullptr || EQUAL(pszDomain, "") ||
110 234 : EQUAL(pszDomain, GDAL_MDD_RPC))
111 : {
112 208 : return CSLFetchNameValue(GetMetadata(pszDomain), pszName);
113 : }
114 234 : return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
115 : }
116 :
117 : /************************************************************************/
118 : /* TryLoadXML() */
119 : /************************************************************************/
120 :
121 1232 : CPLErr GDALGeorefPamDataset::TryLoadXML(CSLConstList papszSiblingFiles)
122 : {
123 1232 : m_bPAMLoaded = true;
124 1232 : CPLErr eErr = GDALPamDataset::TryLoadXML(papszSiblingFiles);
125 1232 : CSLDestroy(m_papszMainMD);
126 1232 : m_papszMainMD = nullptr;
127 1232 : return eErr;
128 : }
129 :
130 : /************************************************************************/
131 : /* SetMetadata() */
132 : /************************************************************************/
133 :
134 18 : CPLErr GDALGeorefPamDataset::SetMetadata(CSLConstList papszMetadata,
135 : const char *pszDomain)
136 : {
137 18 : if (m_bPAMLoaded && (pszDomain == nullptr || EQUAL(pszDomain, "")))
138 : {
139 18 : CSLDestroy(m_papszMainMD);
140 18 : m_papszMainMD = CSLDuplicate(papszMetadata);
141 : }
142 18 : return GDALPamDataset::SetMetadata(papszMetadata, pszDomain);
143 : }
144 :
145 : /************************************************************************/
146 : /* SetMetadata() */
147 : /************************************************************************/
148 :
149 652 : CPLErr GDALGeorefPamDataset::SetMetadataItem(const char *pszName,
150 : const char *pszValue,
151 : const char *pszDomain)
152 : {
153 652 : if (m_bPAMLoaded && (pszDomain == nullptr || EQUAL(pszDomain, "")))
154 : {
155 58 : CSLConstList papszMD = GetMetadata();
156 58 : if (papszMD != m_papszMainMD)
157 : {
158 45 : CSLDestroy(m_papszMainMD);
159 45 : m_papszMainMD = CSLDuplicate(papszMD);
160 : }
161 58 : m_papszMainMD = CSLSetNameValue(m_papszMainMD, pszName, pszValue);
162 : }
163 652 : return GDALPamDataset::SetMetadataItem(pszName, pszValue, pszDomain);
164 : }
165 :
166 : /************************************************************************/
167 : /* GetGCPCount() */
168 : /* */
169 : /* By default, we let PAM override the value stored */
170 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
171 : /************************************************************************/
172 :
173 456 : int GDALGeorefPamDataset::GetGCPCount()
174 :
175 : {
176 456 : const int nPAMIndex = GetPAMGeorefSrcIndex();
177 456 : if (nPAMIndex >= 0 &&
178 439 : ((nGCPCount != 0 && nPAMIndex < m_nGCPGeorefSrcIndex) ||
179 423 : m_nGCPGeorefSrcIndex < 0 || nGCPCount == 0))
180 : {
181 439 : const int nPAMGCPCount = GDALPamDataset::GetGCPCount();
182 439 : if (nPAMGCPCount)
183 2 : return nPAMGCPCount;
184 : }
185 :
186 454 : return nGCPCount;
187 : }
188 :
189 : /************************************************************************/
190 : /* GetGCPSpatialRef() */
191 : /* */
192 : /* By default, we let PAM override the value stored */
193 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
194 : /************************************************************************/
195 :
196 6 : const OGRSpatialReference *GDALGeorefPamDataset::GetGCPSpatialRef() const
197 :
198 : {
199 6 : const int nPAMIndex = GetPAMGeorefSrcIndex();
200 12 : if (nPAMIndex >= 0 &&
201 6 : ((!m_oSRS.IsEmpty() && nPAMIndex < m_nProjectionGeorefSrcIndex) ||
202 1 : m_nProjectionGeorefSrcIndex < 0 || m_oSRS.IsEmpty()))
203 : {
204 : const OGRSpatialReference *pszPAMGCPSRS =
205 6 : GDALPamDataset::GetGCPSpatialRef();
206 6 : if (pszPAMGCPSRS != nullptr)
207 1 : return pszPAMGCPSRS;
208 : }
209 :
210 5 : if (!m_oSRS.IsEmpty())
211 5 : return &m_oSRS;
212 :
213 0 : return nullptr;
214 : }
215 :
216 : /************************************************************************/
217 : /* GetGCP() */
218 : /* */
219 : /* By default, we let PAM override the value stored */
220 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
221 : /************************************************************************/
222 :
223 9 : const GDAL_GCP *GDALGeorefPamDataset::GetGCPs()
224 :
225 : {
226 9 : const int nPAMIndex = GetPAMGeorefSrcIndex();
227 9 : if (nPAMIndex >= 0 &&
228 9 : ((nGCPCount != 0 && nPAMIndex < m_nGCPGeorefSrcIndex) ||
229 4 : m_nGCPGeorefSrcIndex < 0 || nGCPCount == 0))
230 : {
231 9 : const GDAL_GCP *pasPAMGCPList = GDALPamDataset::GetGCPs();
232 9 : if (pasPAMGCPList)
233 1 : return pasPAMGCPList;
234 : }
235 :
236 8 : return pasGCPList;
237 : }
238 :
239 : /************************************************************************/
240 : /* GetSpatialRef() */
241 : /* */
242 : /* By default, we let PAM override the value stored */
243 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
244 : /************************************************************************/
245 :
246 365 : const OGRSpatialReference *GDALGeorefPamDataset::GetSpatialRef() const
247 :
248 : {
249 365 : if (const_cast<GDALGeorefPamDataset *>(this)->GetGCPCount() > 0)
250 2 : return nullptr;
251 :
252 363 : const int nPAMIndex = GetPAMGeorefSrcIndex();
253 709 : if (nPAMIndex >= 0 &&
254 346 : ((!m_oSRS.IsEmpty() && nPAMIndex < m_nProjectionGeorefSrcIndex) ||
255 83 : m_nProjectionGeorefSrcIndex < 0 || m_oSRS.IsEmpty()))
256 : {
257 342 : const OGRSpatialReference *poPAMSRS = GDALPamDataset::GetSpatialRef();
258 342 : if (poPAMSRS != nullptr)
259 20 : return poPAMSRS;
260 : }
261 :
262 343 : if (!m_oSRS.IsEmpty())
263 279 : return &m_oSRS;
264 :
265 64 : return nullptr;
266 : }
267 :
268 : /************************************************************************/
269 : /* GetGeoTransform() */
270 : /* */
271 : /* By default, we let PAM override the value stored */
272 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
273 : /************************************************************************/
274 :
275 502 : CPLErr GDALGeorefPamDataset::GetGeoTransform(GDALGeoTransform >) const
276 :
277 : {
278 502 : const int nPAMIndex = GetPAMGeorefSrcIndex();
279 502 : if (nPAMIndex >= 0 &&
280 485 : ((bGeoTransformValid && nPAMIndex <= m_nGeoTransformGeorefSrcIndex) ||
281 105 : m_nGeoTransformGeorefSrcIndex < 0 || !bGeoTransformValid))
282 : {
283 474 : if (GDALPamDataset::GetGeoTransform(gt) == CE_None)
284 : {
285 14 : m_nGeoTransformGeorefSrcIndex = nPAMIndex;
286 14 : return CE_None;
287 : }
288 : }
289 :
290 488 : if (bGeoTransformValid)
291 : {
292 415 : gt = m_gt;
293 415 : return (CE_None);
294 : }
295 :
296 73 : return CE_Failure;
297 : }
298 :
299 : /************************************************************************/
300 : /* GetPAMGeorefSrcIndex() */
301 : /* */
302 : /* Get priority index of PAM (the lower, the more priority) */
303 : /************************************************************************/
304 1802 : int GDALGeorefPamDataset::GetPAMGeorefSrcIndex() const
305 : {
306 1802 : if (!m_bGotPAMGeorefSrcIndex)
307 : {
308 23 : m_bGotPAMGeorefSrcIndex = true;
309 23 : const char *pszGeorefSources = CSLFetchNameValueDef(
310 23 : papszOpenOptions, "GEOREF_SOURCES",
311 : CPLGetConfigOption("GDAL_GEOREF_SOURCES", "PAM,OTHER"));
312 23 : char **papszTokens = CSLTokenizeString2(pszGeorefSources, ",", 0);
313 23 : m_nPAMGeorefSrcIndex = CSLFindString(papszTokens, "PAM");
314 23 : CSLDestroy(papszTokens);
315 : }
316 1802 : return m_nPAMGeorefSrcIndex;
317 : }
318 :
319 : //! @endcond
|