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 2422 : 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 2422 : m_nPAMGeorefSrcIndex(0), m_bPAMLoaded(false), m_papszMainMD(nullptr)
34 : {
35 2422 : }
36 :
37 : /************************************************************************/
38 : /* ~GDALGeorefPamDataset() */
39 : /************************************************************************/
40 :
41 2422 : GDALGeorefPamDataset::~GDALGeorefPamDataset()
42 : {
43 2422 : if (nGCPCount > 0)
44 : {
45 14 : GDALDeinitGCPs(nGCPCount, pasGCPList);
46 14 : CPLFree(pasGCPList);
47 : }
48 2422 : CSLDestroy(m_papszMainMD);
49 2422 : CSLDestroy(m_papszRPC);
50 2422 : }
51 :
52 : /************************************************************************/
53 : /* GetMetadata() */
54 : /************************************************************************/
55 :
56 837 : char **GDALGeorefPamDataset::GetMetadata(const char *pszDomain)
57 : {
58 837 : if (pszDomain != nullptr && EQUAL(pszDomain, "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 : char **papszMD = GDALPamDataset::GetMetadata(pszDomain);
66 25 : if (papszMD)
67 2 : return papszMD;
68 : }
69 23 : return m_papszRPC;
70 : }
71 :
72 812 : if (pszDomain == nullptr || EQUAL(pszDomain, ""))
73 : {
74 495 : if (m_papszMainMD)
75 59 : return m_papszMainMD;
76 436 : m_papszMainMD = CSLDuplicate(GDALPamDataset::GetMetadata(pszDomain));
77 436 : const int nPAMIndex = GetPAMGeorefSrcIndex();
78 436 : if (nPAMIndex >= 0 &&
79 436 : ((m_bPixelIsPoint && nPAMIndex < m_nPixelIsPointGeorefSrcIndex) ||
80 432 : m_nPixelIsPointGeorefSrcIndex < 0 || !m_bPixelIsPoint))
81 : {
82 436 : if (CSLFetchNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT) !=
83 : nullptr)
84 0 : return m_papszMainMD;
85 : }
86 436 : if (m_bPixelIsPoint)
87 : {
88 4 : m_papszMainMD = CSLSetNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT,
89 : GDALMD_AOP_POINT);
90 : }
91 : else
92 : {
93 432 : m_papszMainMD =
94 432 : CSLSetNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT, nullptr);
95 : }
96 436 : return m_papszMainMD;
97 : }
98 :
99 317 : return GDALPamDataset::GetMetadata(pszDomain);
100 : }
101 :
102 : /************************************************************************/
103 : /* GetMetadataItem() */
104 : /************************************************************************/
105 :
106 438 : const char *GDALGeorefPamDataset::GetMetadataItem(const char *pszName,
107 : const char *pszDomain)
108 : {
109 438 : if (pszDomain == nullptr || EQUAL(pszDomain, "") || EQUAL(pszDomain, "RPC"))
110 : {
111 204 : return CSLFetchNameValue(GetMetadata(pszDomain), pszName);
112 : }
113 234 : return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
114 : }
115 :
116 : /************************************************************************/
117 : /* TryLoadXML() */
118 : /************************************************************************/
119 :
120 1227 : CPLErr GDALGeorefPamDataset::TryLoadXML(CSLConstList papszSiblingFiles)
121 : {
122 1227 : m_bPAMLoaded = true;
123 1227 : CPLErr eErr = GDALPamDataset::TryLoadXML(papszSiblingFiles);
124 1227 : CSLDestroy(m_papszMainMD);
125 1227 : m_papszMainMD = nullptr;
126 1227 : return eErr;
127 : }
128 :
129 : /************************************************************************/
130 : /* SetMetadata() */
131 : /************************************************************************/
132 :
133 18 : CPLErr GDALGeorefPamDataset::SetMetadata(char **papszMetadata,
134 : const char *pszDomain)
135 : {
136 18 : if (m_bPAMLoaded && (pszDomain == nullptr || EQUAL(pszDomain, "")))
137 : {
138 18 : CSLDestroy(m_papszMainMD);
139 18 : m_papszMainMD = CSLDuplicate(papszMetadata);
140 : }
141 18 : return GDALPamDataset::SetMetadata(papszMetadata, pszDomain);
142 : }
143 :
144 : /************************************************************************/
145 : /* SetMetadata() */
146 : /************************************************************************/
147 :
148 646 : CPLErr GDALGeorefPamDataset::SetMetadataItem(const char *pszName,
149 : const char *pszValue,
150 : const char *pszDomain)
151 : {
152 646 : if (m_bPAMLoaded && (pszDomain == nullptr || EQUAL(pszDomain, "")))
153 : {
154 57 : char **papszMD = GetMetadata();
155 57 : if (papszMD != m_papszMainMD)
156 : {
157 45 : CSLDestroy(m_papszMainMD);
158 45 : m_papszMainMD = CSLDuplicate(papszMD);
159 : }
160 57 : m_papszMainMD = CSLSetNameValue(m_papszMainMD, pszName, pszValue);
161 : }
162 646 : return GDALPamDataset::SetMetadataItem(pszName, pszValue, pszDomain);
163 : }
164 :
165 : /************************************************************************/
166 : /* GetGCPCount() */
167 : /* */
168 : /* By default, we let PAM override the value stored */
169 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
170 : /************************************************************************/
171 :
172 453 : int GDALGeorefPamDataset::GetGCPCount()
173 :
174 : {
175 453 : const int nPAMIndex = GetPAMGeorefSrcIndex();
176 453 : if (nPAMIndex >= 0 &&
177 436 : ((nGCPCount != 0 && nPAMIndex < m_nGCPGeorefSrcIndex) ||
178 420 : m_nGCPGeorefSrcIndex < 0 || nGCPCount == 0))
179 : {
180 436 : const int nPAMGCPCount = GDALPamDataset::GetGCPCount();
181 436 : if (nPAMGCPCount)
182 2 : return nPAMGCPCount;
183 : }
184 :
185 451 : return nGCPCount;
186 : }
187 :
188 : /************************************************************************/
189 : /* GetGCPSpatialRef() */
190 : /* */
191 : /* By default, we let PAM override the value stored */
192 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
193 : /************************************************************************/
194 :
195 6 : const OGRSpatialReference *GDALGeorefPamDataset::GetGCPSpatialRef() const
196 :
197 : {
198 6 : const int nPAMIndex = GetPAMGeorefSrcIndex();
199 12 : if (nPAMIndex >= 0 &&
200 6 : ((!m_oSRS.IsEmpty() && nPAMIndex < m_nProjectionGeorefSrcIndex) ||
201 1 : m_nProjectionGeorefSrcIndex < 0 || m_oSRS.IsEmpty()))
202 : {
203 : const OGRSpatialReference *pszPAMGCPSRS =
204 6 : GDALPamDataset::GetGCPSpatialRef();
205 6 : if (pszPAMGCPSRS != nullptr)
206 1 : return pszPAMGCPSRS;
207 : }
208 :
209 5 : if (!m_oSRS.IsEmpty())
210 5 : return &m_oSRS;
211 :
212 0 : return nullptr;
213 : }
214 :
215 : /************************************************************************/
216 : /* GetGCP() */
217 : /* */
218 : /* By default, we let PAM override the value stored */
219 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
220 : /************************************************************************/
221 :
222 9 : const GDAL_GCP *GDALGeorefPamDataset::GetGCPs()
223 :
224 : {
225 9 : const int nPAMIndex = GetPAMGeorefSrcIndex();
226 9 : if (nPAMIndex >= 0 &&
227 9 : ((nGCPCount != 0 && nPAMIndex < m_nGCPGeorefSrcIndex) ||
228 4 : m_nGCPGeorefSrcIndex < 0 || nGCPCount == 0))
229 : {
230 9 : const GDAL_GCP *pasPAMGCPList = GDALPamDataset::GetGCPs();
231 9 : if (pasPAMGCPList)
232 1 : return pasPAMGCPList;
233 : }
234 :
235 8 : return pasGCPList;
236 : }
237 :
238 : /************************************************************************/
239 : /* GetSpatialRef() */
240 : /* */
241 : /* By default, we let PAM override the value stored */
242 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
243 : /************************************************************************/
244 :
245 363 : const OGRSpatialReference *GDALGeorefPamDataset::GetSpatialRef() const
246 :
247 : {
248 363 : if (const_cast<GDALGeorefPamDataset *>(this)->GetGCPCount() > 0)
249 2 : return nullptr;
250 :
251 361 : const int nPAMIndex = GetPAMGeorefSrcIndex();
252 705 : if (nPAMIndex >= 0 &&
253 344 : ((!m_oSRS.IsEmpty() && nPAMIndex < m_nProjectionGeorefSrcIndex) ||
254 82 : m_nProjectionGeorefSrcIndex < 0 || m_oSRS.IsEmpty()))
255 : {
256 340 : const OGRSpatialReference *poPAMSRS = GDALPamDataset::GetSpatialRef();
257 340 : if (poPAMSRS != nullptr)
258 20 : return poPAMSRS;
259 : }
260 :
261 341 : if (!m_oSRS.IsEmpty())
262 278 : return &m_oSRS;
263 :
264 63 : return nullptr;
265 : }
266 :
267 : /************************************************************************/
268 : /* GetGeoTransform() */
269 : /* */
270 : /* By default, we let PAM override the value stored */
271 : /* inside our file, unless GDAL_GEOREF_SOURCES is defined. */
272 : /************************************************************************/
273 :
274 500 : CPLErr GDALGeorefPamDataset::GetGeoTransform(GDALGeoTransform >) const
275 :
276 : {
277 500 : const int nPAMIndex = GetPAMGeorefSrcIndex();
278 500 : if (nPAMIndex >= 0 &&
279 483 : ((bGeoTransformValid && nPAMIndex <= m_nGeoTransformGeorefSrcIndex) ||
280 104 : m_nGeoTransformGeorefSrcIndex < 0 || !bGeoTransformValid))
281 : {
282 472 : if (GDALPamDataset::GetGeoTransform(gt) == CE_None)
283 : {
284 14 : m_nGeoTransformGeorefSrcIndex = nPAMIndex;
285 14 : return CE_None;
286 : }
287 : }
288 :
289 486 : if (bGeoTransformValid)
290 : {
291 414 : gt = m_gt;
292 414 : return (CE_None);
293 : }
294 :
295 72 : return CE_Failure;
296 : }
297 :
298 : /************************************************************************/
299 : /* GetPAMGeorefSrcIndex() */
300 : /* */
301 : /* Get priority index of PAM (the lower, the more prioritary) */
302 : /************************************************************************/
303 1790 : int GDALGeorefPamDataset::GetPAMGeorefSrcIndex() const
304 : {
305 1790 : if (!m_bGotPAMGeorefSrcIndex)
306 : {
307 23 : m_bGotPAMGeorefSrcIndex = true;
308 23 : const char *pszGeorefSources = CSLFetchNameValueDef(
309 23 : papszOpenOptions, "GEOREF_SOURCES",
310 : CPLGetConfigOption("GDAL_GEOREF_SOURCES", "PAM,OTHER"));
311 23 : char **papszTokens = CSLTokenizeString2(pszGeorefSources, ",", 0);
312 23 : m_nPAMGeorefSrcIndex = CSLFindString(papszTokens, "PAM");
313 23 : CSLDestroy(papszTokens);
314 : }
315 1790 : return m_nPAMGeorefSrcIndex;
316 : }
317 :
318 : //! @endcond
|