Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Some private helper functions and stuff for OGR implementation.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 1999, Frank Warmerdam
9 : * Copyright (c) 2008-2014, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #ifndef OGR_P_H_INCLUDED
15 : #define OGR_P_H_INCLUDED
16 :
17 : /* -------------------------------------------------------------------- */
18 : /* Include the common portability library ... lets us do lots */
19 : /* of stuff easily. */
20 : /* -------------------------------------------------------------------- */
21 :
22 : #include "cpl_string.h"
23 : #include "cpl_conv.h"
24 : #include "cpl_minixml.h"
25 :
26 : #include "ogr_core.h"
27 :
28 : #include <limits>
29 : #include <string_view>
30 :
31 : class OGRGeometry;
32 : class OGRFieldDefn;
33 :
34 : /* A default name for the default geometry column, instead of '' */
35 : #define OGR_GEOMETRY_DEFAULT_NON_EMPTY_NAME "_ogr_geometry_"
36 :
37 : #ifdef CPL_MSB
38 : #define OGR_SWAP(x) (x == wkbNDR)
39 : #else
40 : #define OGR_SWAP(x) (x == wkbXDR)
41 : #endif
42 :
43 : /* PostGIS 1.X has non standard codes for the following geometry types */
44 : #define POSTGIS15_CURVEPOLYGON 13 /* instead of 10 */
45 : #define POSTGIS15_MULTICURVE 14 /* instead of 11 */
46 : #define POSTGIS15_MULTISURFACE 15 /* instead of 12 */
47 :
48 : /* Has been deprecated. Can only be used in very specific circumstances */
49 : #ifdef GDAL_COMPILATION
50 : #define wkb25DBitInternalUse 0x80000000
51 : #endif
52 :
53 : void CPL_DLL OGRFormatDouble(char *pszBuffer, int nBufferLen, double dfVal,
54 : char chDecimalSep, int nPrecision = 15,
55 : char chConversionSpecifier = 'f');
56 :
57 : int OGRFormatFloat(char *pszBuffer, int nBufferLen, float fVal, int nPrecision,
58 : char chConversionSpecifier);
59 :
60 : /* -------------------------------------------------------------------- */
61 : /* Date-time parsing and processing functions */
62 : /* -------------------------------------------------------------------- */
63 :
64 : /* Internal use by OGR drivers only, CPL_DLL is just there in case */
65 : /* they are compiled as plugins */
66 :
67 : int CPL_DLL OGRTimezoneToTZFlag(const char *pszTZ,
68 : bool bEmitErrorIfUnhandledFormat);
69 : std::string CPL_DLL OGRTZFlagToTimezone(int nTZFlag,
70 : const char *pszUTCRepresentation);
71 :
72 : int CPL_DLL OGRGetDayOfWeek(int day, int month, int year);
73 : int CPL_DLL OGRParseXMLDateTime(const char *pszXMLDateTime, OGRField *psField);
74 : int CPL_DLL OGRParseRFC822DateTime(const char *pszRFC822DateTime,
75 : OGRField *psField);
76 : char CPL_DLL *OGRGetRFC822DateTime(const OGRField *psField);
77 : char CPL_DLL *OGRGetXMLDateTime(const OGRField *psField);
78 : char CPL_DLL *OGRGetXMLDateTime(const OGRField *psField,
79 : bool bAlwaysMillisecond);
80 : // 30 = strlen("YYYY-MM-DDThh:mm:ss.sss+hh:mm") + 1
81 : #define OGR_SIZEOF_ISO8601_DATETIME_BUFFER 30
82 : int CPL_DLL
83 : OGRGetISO8601DateTime(const OGRField *psField, bool bAlwaysMillisecond,
84 : char szBuffer[OGR_SIZEOF_ISO8601_DATETIME_BUFFER]);
85 :
86 : /** Precision of formatting */
87 : enum class OGRISO8601Precision
88 : {
89 : /** Automated mode: millisecond included if non zero, otherwise truncated at second */
90 : AUTO,
91 : /** Always include millisecond */
92 : MILLISECOND,
93 : /** Always include second, but no millisecond */
94 : SECOND,
95 : /** Always include minute, but no second */
96 : MINUTE
97 : };
98 :
99 : /** Configuration of the ISO8601 formatting output */
100 : struct OGRISO8601Format
101 : {
102 : /** Precision of formatting */
103 : OGRISO8601Precision ePrecision;
104 : };
105 :
106 : int CPL_DLL
107 : OGRGetISO8601DateTime(const OGRField *psField, const OGRISO8601Format &sFormat,
108 : char szBuffer[OGR_SIZEOF_ISO8601_DATETIME_BUFFER]);
109 : char CPL_DLL *OGRGetXML_UTF8_EscapedString(const char *pszString);
110 :
111 : #ifdef GDAL_COMPILATION
112 : bool CPL_DLL OGRParseDateTimeYYYYMMDDTHHMMZ(std::string_view sInput,
113 : OGRField *psField);
114 : bool CPL_DLL OGRParseDateTimeYYYYMMDDTHHMMSSZ(std::string_view sInput,
115 : OGRField *psField);
116 : bool CPL_DLL OGRParseDateTimeYYYYMMDDTHHMMSSsssZ(std::string_view sInput,
117 : OGRField *psField);
118 : #endif
119 :
120 : int OGRCompareDate(const OGRField *psFirstTuple,
121 : const OGRField *psSecondTuple); /* used by ogr_gensql.cpp and
122 : ogrfeaturequery.cpp */
123 :
124 : bool CPL_DLL OGRIsGeoJSONMediaType(const char *pszMediaType);
125 :
126 : /* General utility option processing. */
127 : int CPL_DLL OGRGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv,
128 : int nOptions);
129 :
130 : /************************************************************************/
131 : /* Support for special attributes (feature query and selection) */
132 : /************************************************************************/
133 : #define SPF_FID 0
134 : #define SPF_OGR_GEOMETRY 1
135 : #define SPF_OGR_STYLE 2
136 : #define SPF_OGR_GEOM_WKT 3
137 : #define SPF_OGR_GEOM_AREA 4
138 : #define SPECIAL_FIELD_COUNT 5
139 :
140 : extern const char *const SpecialFieldNames[SPECIAL_FIELD_COUNT];
141 :
142 : /************************************************************************/
143 : /* Some SRS related stuff, search in SRS data files. */
144 : /************************************************************************/
145 :
146 : OGRErr CPL_DLL OSRGetEllipsoidInfo(int, char **, double *, double *);
147 :
148 : /* Fast atof function */
149 : double OGRFastAtof(const char *pszStr);
150 :
151 : OGRErr CPL_DLL OGRCheckPermutation(const int *panPermutation, int nSize);
152 :
153 : /************************************************************************/
154 : /* PostGIS EWKB encoding */
155 : /************************************************************************/
156 :
157 : OGRGeometry CPL_DLL *OGRGeometryFromEWKB(GByte *pabyWKB, int nLength,
158 : int *pnSRID, int bIsPostGIS1_EWKB);
159 : OGRGeometry CPL_DLL *OGRGeometryFromHexEWKB(const char *pszBytea, int *pnSRID,
160 : int bIsPostGIS1_EWKB);
161 : char CPL_DLL *OGRGeometryToHexEWKB(const OGRGeometry *poGeometry, int nSRSId,
162 : int nPostGISMajor, int nPostGISMinor);
163 :
164 : /************************************************************************/
165 : /* WKB Type Handling encoding */
166 : /************************************************************************/
167 :
168 : OGRErr CPL_DLL OGRReadWKBGeometryType(const unsigned char *pabyData,
169 : OGRwkbVariant wkbVariant,
170 : OGRwkbGeometryType *eGeometryType);
171 :
172 : /************************************************************************/
173 : /* WKT Type Handling encoding */
174 : /************************************************************************/
175 :
176 : OGRErr CPL_DLL OGRReadWKTGeometryType(const char *pszWKT,
177 : OGRwkbGeometryType *peGeometryType);
178 :
179 : /************************************************************************/
180 : /* Other */
181 : /************************************************************************/
182 :
183 : void CPL_DLL OGRUpdateFieldType(OGRFieldDefn *poFDefn, OGRFieldType eNewType,
184 : OGRFieldSubType eNewSubType);
185 :
186 : /************************************************************************/
187 : /* OGRRoundValueIEEE754() */
188 : /************************************************************************/
189 :
190 : /** Set to zero least significants bits of a double precision floating-point
191 : * number (passed as an integer), taking into account a desired bit precision.
192 : *
193 : * @param nVal Integer representation of a IEEE754 double-precision number.
194 : * @param nBitsPrecision Desired precision (number of bits after integral part)
195 : * @return quantized nVal.
196 : * @since GDAL 3.9
197 : */
198 : inline uint64_t OGRRoundValueIEEE754(uint64_t nVal,
199 : int nBitsPrecision) CPL_WARN_UNUSED_RESULT;
200 :
201 104 : inline uint64_t OGRRoundValueIEEE754(uint64_t nVal, int nBitsPrecision)
202 : {
203 104 : constexpr int MANTISSA_SIZE = std::numeric_limits<double>::digits - 1;
204 104 : constexpr int MAX_EXPONENT = std::numeric_limits<double>::max_exponent;
205 : #if __cplusplus >= 201703L
206 : static_assert(MANTISSA_SIZE == 52);
207 : static_assert(MAX_EXPONENT == 1024);
208 : #endif
209 : // Extract the binary exponent from the IEEE754 representation
210 104 : const int nExponent =
211 104 : ((nVal >> MANTISSA_SIZE) & (2 * MAX_EXPONENT - 1)) - (MAX_EXPONENT - 1);
212 : // Add 1 to round-up and the desired precision
213 104 : const int nBitsRequired = 1 + nExponent + nBitsPrecision;
214 : // Compute number of nullified bits
215 104 : int nNullifiedBits = MANTISSA_SIZE - nBitsRequired;
216 : // this will also capture NaN and Inf since nExponent = 1023,
217 : // and thus nNullifiedBits < 0
218 104 : if (nNullifiedBits <= 0)
219 2 : return nVal;
220 102 : if (nNullifiedBits >= MANTISSA_SIZE)
221 2 : nNullifiedBits = MANTISSA_SIZE;
222 102 : nVal >>= nNullifiedBits;
223 102 : nVal <<= nNullifiedBits;
224 102 : return nVal;
225 : }
226 :
227 : /************************************************************************/
228 : /* OGRRoundCoordinatesIEEE754XYValues() */
229 : /************************************************************************/
230 :
231 : /** Quantize XY values.
232 : *
233 : * @since GDAL 3.9
234 : */
235 : template <int SPACING>
236 707426 : inline void OGRRoundCoordinatesIEEE754XYValues(int nBitsPrecision,
237 : GByte *pabyBase, size_t nPoints)
238 : {
239 : // Note: we use SPACING as template for improved code generation.
240 :
241 707426 : if (nBitsPrecision != INT_MIN)
242 : {
243 42 : for (size_t i = 0; i < nPoints; i++)
244 : {
245 : uint64_t nVal;
246 :
247 29 : memcpy(&nVal, pabyBase + SPACING * i, sizeof(uint64_t));
248 29 : nVal = OGRRoundValueIEEE754(nVal, nBitsPrecision);
249 29 : memcpy(pabyBase + SPACING * i, &nVal, sizeof(uint64_t));
250 :
251 29 : memcpy(&nVal, pabyBase + sizeof(uint64_t) + SPACING * i,
252 : sizeof(uint64_t));
253 29 : nVal = OGRRoundValueIEEE754(nVal, nBitsPrecision);
254 29 : memcpy(pabyBase + sizeof(uint64_t) + SPACING * i, &nVal,
255 : sizeof(uint64_t));
256 : }
257 : }
258 707426 : }
259 :
260 : /************************************************************************/
261 : /* OGRRoundCoordinatesIEEE754() */
262 : /************************************************************************/
263 :
264 : /** Quantize Z or M values.
265 : *
266 : * @since GDAL 3.9
267 : */
268 : template <int SPACING>
269 216701 : inline void OGRRoundCoordinatesIEEE754(int nBitsPrecision, GByte *pabyBase,
270 : size_t nPoints)
271 : {
272 216701 : if (nBitsPrecision != INT_MIN)
273 : {
274 52 : for (size_t i = 0; i < nPoints; i++)
275 : {
276 : uint64_t nVal;
277 :
278 34 : memcpy(&nVal, pabyBase + SPACING * i, sizeof(uint64_t));
279 34 : nVal = OGRRoundValueIEEE754(nVal, nBitsPrecision);
280 34 : memcpy(pabyBase + SPACING * i, &nVal, sizeof(uint64_t));
281 : }
282 : }
283 216701 : }
284 :
285 : /* -------------------------------------------------------------------- */
286 : /* helper functions for string escaping. */
287 : /* -------------------------------------------------------------------- */
288 :
289 : /** Replace all occurrences of ch by it repeated twice.
290 : * Typically used for SQL string literal or identifier escaping.
291 : */
292 : std::string CPL_DLL OGRDuplicateCharacter(const std::string &osStr, char ch);
293 :
294 : #endif /* ndef OGR_P_H_INCLUDED */
295 :
296 : /* -------------------------------------------------------------------- */
297 : /* Declarations that depend on ogr_geometry.h. */
298 : /* */
299 : /* These live outside the OGR_P_H_INCLUDED guard above so that */
300 : /* they are still processed when a translation unit includes */
301 : /* ogr_geometry.h and then ogr_p.h, even if ogr_p.h had already */
302 : /* been included earlier without ogr_geometry.h. That ordering */
303 : /* arises in CMake unity builds and would otherwise leave these */
304 : /* functions undeclared. Their own guard prevents duplicate */
305 : /* declarations. */
306 : /* -------------------------------------------------------------------- */
307 :
308 : #if defined(OGR_GEOMETRY_H_INCLUDED) && !defined(OGR_P_H_GEOMETRY_INCLUDED)
309 : #define OGR_P_H_GEOMETRY_INCLUDED
310 :
311 : #define OGR_WKT_TOKEN_MAX 64
312 :
313 : const char CPL_DLL *OGRWktReadToken(const char *pszInput, char *pszToken);
314 :
315 : const char CPL_DLL *OGRWktReadPoints(const char *pszInput,
316 : OGRRawPoint **ppaoPoints, double **ppadfZ,
317 : int *pnMaxPoints, int *pnReadPoints);
318 :
319 : const char CPL_DLL *
320 : OGRWktReadPointsM(const char *pszInput, OGRRawPoint **ppaoPoints,
321 : double **ppadfZ, double **ppadfM,
322 : int *flags, /* geometry flags, are we expecting Z, M, or both;
323 : may change due to input */
324 : int *pnMaxPoints, int *pnReadPoints);
325 :
326 : void CPL_DLL OGRMakeWktCoordinate(char *, double, double, double, int);
327 : std::string CPL_DLL OGRMakeWktCoordinate(double, double, double, int,
328 : const OGRWktOptions &opts);
329 : void CPL_DLL OGRMakeWktCoordinateM(char *, double, double, double, double, bool,
330 : bool);
331 : std::string CPL_DLL OGRMakeWktCoordinateM(double, double, double, double, bool,
332 : bool, const OGRWktOptions &opts);
333 :
334 : std::string CPL_DLL OGRFormatDouble(double val, const OGRWktOptions &opts,
335 : int nDimIdx);
336 :
337 : #endif /* OGR_GEOMETRY_H_INCLUDED && !OGR_P_H_GEOMETRY_INCLUDED */
|