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 : /* -------------------------------------------------------------------- */
54 : /* helper function for parsing well known text format vector objects.*/
55 : /* -------------------------------------------------------------------- */
56 :
57 : #ifdef OGR_GEOMETRY_H_INCLUDED
58 : #define OGR_WKT_TOKEN_MAX 64
59 :
60 : const char CPL_DLL *OGRWktReadToken(const char *pszInput, char *pszToken);
61 :
62 : const char CPL_DLL *OGRWktReadPoints(const char *pszInput,
63 : OGRRawPoint **ppaoPoints, double **ppadfZ,
64 : int *pnMaxPoints, int *pnReadPoints);
65 :
66 : const char CPL_DLL *
67 : OGRWktReadPointsM(const char *pszInput, OGRRawPoint **ppaoPoints,
68 : double **ppadfZ, double **ppadfM,
69 : int *flags, /* geometry flags, are we expecting Z, M, or both;
70 : may change due to input */
71 : int *pnMaxPoints, int *pnReadPoints);
72 :
73 : void CPL_DLL OGRMakeWktCoordinate(char *, double, double, double, int);
74 : std::string CPL_DLL OGRMakeWktCoordinate(double, double, double, int,
75 : const OGRWktOptions &opts);
76 : void CPL_DLL OGRMakeWktCoordinateM(char *, double, double, double, double,
77 : OGRBoolean, OGRBoolean);
78 : std::string CPL_DLL OGRMakeWktCoordinateM(double, double, double, double,
79 : OGRBoolean, OGRBoolean,
80 : const OGRWktOptions &opts);
81 :
82 : #endif
83 :
84 : void CPL_DLL OGRFormatDouble(char *pszBuffer, int nBufferLen, double dfVal,
85 : char chDecimalSep, int nPrecision = 15,
86 : char chConversionSpecifier = 'f');
87 :
88 : #ifdef OGR_GEOMETRY_H_INCLUDED
89 : std::string CPL_DLL OGRFormatDouble(double val, const OGRWktOptions &opts,
90 : int nDimIdx);
91 : #endif
92 :
93 : int OGRFormatFloat(char *pszBuffer, int nBufferLen, float fVal, int nPrecision,
94 : char chConversionSpecifier);
95 :
96 : /* -------------------------------------------------------------------- */
97 : /* Date-time parsing and processing functions */
98 : /* -------------------------------------------------------------------- */
99 :
100 : /* Internal use by OGR drivers only, CPL_DLL is just there in case */
101 : /* they are compiled as plugins */
102 :
103 : int CPL_DLL OGRTimezoneToTZFlag(const char *pszTZ,
104 : bool bEmitErrorIfUnhandledFormat);
105 : std::string CPL_DLL OGRTZFlagToTimezone(int nTZFlag,
106 : const char *pszUTCRepresentation);
107 :
108 : int CPL_DLL OGRGetDayOfWeek(int day, int month, int year);
109 : int CPL_DLL OGRParseXMLDateTime(const char *pszXMLDateTime, OGRField *psField);
110 : int CPL_DLL OGRParseRFC822DateTime(const char *pszRFC822DateTime,
111 : OGRField *psField);
112 : char CPL_DLL *OGRGetRFC822DateTime(const OGRField *psField);
113 : char CPL_DLL *OGRGetXMLDateTime(const OGRField *psField);
114 : char CPL_DLL *OGRGetXMLDateTime(const OGRField *psField,
115 : bool bAlwaysMillisecond);
116 : // 30 = strlen("YYYY-MM-DDThh:mm:ss.sss+hh:mm") + 1
117 : #define OGR_SIZEOF_ISO8601_DATETIME_BUFFER 30
118 : int CPL_DLL
119 : OGRGetISO8601DateTime(const OGRField *psField, bool bAlwaysMillisecond,
120 : char szBuffer[OGR_SIZEOF_ISO8601_DATETIME_BUFFER]);
121 :
122 : /** Precision of formatting */
123 : enum class OGRISO8601Precision
124 : {
125 : /** Automated mode: millisecond included if non zero, otherwise truncated at second */
126 : AUTO,
127 : /** Always include millisecond */
128 : MILLISECOND,
129 : /** Always include second, but no millisecond */
130 : SECOND,
131 : /** Always include minute, but no second */
132 : MINUTE
133 : };
134 :
135 : /** Configuration of the ISO8601 formatting output */
136 : struct OGRISO8601Format
137 : {
138 : /** Precision of formatting */
139 : OGRISO8601Precision ePrecision;
140 : };
141 :
142 : int CPL_DLL
143 : OGRGetISO8601DateTime(const OGRField *psField, const OGRISO8601Format &sFormat,
144 : char szBuffer[OGR_SIZEOF_ISO8601_DATETIME_BUFFER]);
145 : char CPL_DLL *OGRGetXML_UTF8_EscapedString(const char *pszString);
146 :
147 : #ifdef GDAL_COMPILATION
148 : bool CPL_DLL OGRParseDateTimeYYYYMMDDTHHMMZ(std::string_view sInput,
149 : OGRField *psField);
150 : bool CPL_DLL OGRParseDateTimeYYYYMMDDTHHMMSSZ(std::string_view sInput,
151 : OGRField *psField);
152 : bool CPL_DLL OGRParseDateTimeYYYYMMDDTHHMMSSsssZ(std::string_view sInput,
153 : OGRField *psField);
154 : #endif
155 :
156 : int OGRCompareDate(const OGRField *psFirstTuple,
157 : const OGRField *psSecondTuple); /* used by ogr_gensql.cpp and
158 : ogrfeaturequery.cpp */
159 :
160 : /* General utility option processing. */
161 : int CPL_DLL OGRGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv,
162 : int nOptions);
163 :
164 : /************************************************************************/
165 : /* Support for special attributes (feature query and selection) */
166 : /************************************************************************/
167 : #define SPF_FID 0
168 : #define SPF_OGR_GEOMETRY 1
169 : #define SPF_OGR_STYLE 2
170 : #define SPF_OGR_GEOM_WKT 3
171 : #define SPF_OGR_GEOM_AREA 4
172 : #define SPECIAL_FIELD_COUNT 5
173 :
174 : extern const char *const SpecialFieldNames[SPECIAL_FIELD_COUNT];
175 :
176 : /************************************************************************/
177 : /* Some SRS related stuff, search in SRS data files. */
178 : /************************************************************************/
179 :
180 : OGRErr CPL_DLL OSRGetEllipsoidInfo(int, char **, double *, double *);
181 :
182 : /* Fast atof function */
183 : double OGRFastAtof(const char *pszStr);
184 :
185 : OGRErr CPL_DLL OGRCheckPermutation(const int *panPermutation, int nSize);
186 :
187 : /* GML related */
188 :
189 : OGRGeometry CPL_DLL *GML2OGRGeometry_XMLNode(
190 : const CPLXMLNode *psNode, int nPseudoBoolGetSecondaryGeometryOption,
191 : int nRecLevel = 0, int nSRSDimension = 0, bool bIgnoreGSG = false,
192 : bool bOrientation = true, bool bFaceHoleNegative = false,
193 : const char *pszId = nullptr);
194 :
195 : /************************************************************************/
196 : /* PostGIS EWKB encoding */
197 : /************************************************************************/
198 :
199 : OGRGeometry CPL_DLL *OGRGeometryFromEWKB(GByte *pabyWKB, int nLength,
200 : int *pnSRID, int bIsPostGIS1_EWKB);
201 : OGRGeometry CPL_DLL *OGRGeometryFromHexEWKB(const char *pszBytea, int *pnSRID,
202 : int bIsPostGIS1_EWKB);
203 : char CPL_DLL *OGRGeometryToHexEWKB(OGRGeometry *poGeometry, int nSRSId,
204 : int nPostGISMajor, int nPostGISMinor);
205 :
206 : /************************************************************************/
207 : /* WKB Type Handling encoding */
208 : /************************************************************************/
209 :
210 : OGRErr CPL_DLL OGRReadWKBGeometryType(const unsigned char *pabyData,
211 : OGRwkbVariant wkbVariant,
212 : OGRwkbGeometryType *eGeometryType);
213 :
214 : /************************************************************************/
215 : /* WKT Type Handling encoding */
216 : /************************************************************************/
217 :
218 : OGRErr CPL_DLL OGRReadWKTGeometryType(const char *pszWKT,
219 : OGRwkbGeometryType *peGeometryType);
220 :
221 : /************************************************************************/
222 : /* Other */
223 : /************************************************************************/
224 :
225 : void CPL_DLL OGRUpdateFieldType(OGRFieldDefn *poFDefn, OGRFieldType eNewType,
226 : OGRFieldSubType eNewSubType);
227 :
228 : /************************************************************************/
229 : /* OGRRoundValueIEEE754() */
230 : /************************************************************************/
231 :
232 : /** Set to zero least significants bits of a double precision floating-point
233 : * number (passed as an integer), taking into account a desired bit precision.
234 : *
235 : * @param nVal Integer representation of a IEEE754 double-precision number.
236 : * @param nBitsPrecision Desired precision (number of bits after integral part)
237 : * @return quantized nVal.
238 : * @since GDAL 3.9
239 : */
240 : inline uint64_t OGRRoundValueIEEE754(uint64_t nVal,
241 : int nBitsPrecision) CPL_WARN_UNUSED_RESULT;
242 :
243 104 : inline uint64_t OGRRoundValueIEEE754(uint64_t nVal, int nBitsPrecision)
244 : {
245 104 : constexpr int MANTISSA_SIZE = std::numeric_limits<double>::digits - 1;
246 104 : constexpr int MAX_EXPONENT = std::numeric_limits<double>::max_exponent;
247 : #if __cplusplus >= 201703L
248 : static_assert(MANTISSA_SIZE == 52);
249 : static_assert(MAX_EXPONENT == 1024);
250 : #endif
251 : // Extract the binary exponent from the IEEE754 representation
252 104 : const int nExponent =
253 104 : ((nVal >> MANTISSA_SIZE) & (2 * MAX_EXPONENT - 1)) - (MAX_EXPONENT - 1);
254 : // Add 1 to round-up and the desired precision
255 104 : const int nBitsRequired = 1 + nExponent + nBitsPrecision;
256 : // Compute number of nullified bits
257 104 : int nNullifiedBits = MANTISSA_SIZE - nBitsRequired;
258 : // this will also capture NaN and Inf since nExponent = 1023,
259 : // and thus nNullifiedBits < 0
260 104 : if (nNullifiedBits <= 0)
261 2 : return nVal;
262 102 : if (nNullifiedBits >= MANTISSA_SIZE)
263 2 : nNullifiedBits = MANTISSA_SIZE;
264 102 : nVal >>= nNullifiedBits;
265 102 : nVal <<= nNullifiedBits;
266 102 : return nVal;
267 : }
268 :
269 : /************************************************************************/
270 : /* OGRRoundCoordinatesIEEE754XYValues() */
271 : /************************************************************************/
272 :
273 : /** Quantize XY values.
274 : *
275 : * @since GDAL 3.9
276 : */
277 : template <int SPACING>
278 673282 : inline void OGRRoundCoordinatesIEEE754XYValues(int nBitsPrecision,
279 : GByte *pabyBase, size_t nPoints)
280 : {
281 : // Note: we use SPACING as template for improved code generation.
282 :
283 673282 : if (nBitsPrecision != INT_MIN)
284 : {
285 42 : for (size_t i = 0; i < nPoints; i++)
286 : {
287 : uint64_t nVal;
288 :
289 29 : memcpy(&nVal, pabyBase + SPACING * i, sizeof(uint64_t));
290 29 : nVal = OGRRoundValueIEEE754(nVal, nBitsPrecision);
291 29 : memcpy(pabyBase + SPACING * i, &nVal, sizeof(uint64_t));
292 :
293 29 : memcpy(&nVal, pabyBase + sizeof(uint64_t) + SPACING * i,
294 : sizeof(uint64_t));
295 29 : nVal = OGRRoundValueIEEE754(nVal, nBitsPrecision);
296 29 : memcpy(pabyBase + sizeof(uint64_t) + SPACING * i, &nVal,
297 : sizeof(uint64_t));
298 : }
299 : }
300 673282 : }
301 :
302 : /************************************************************************/
303 : /* OGRRoundCoordinatesIEEE754() */
304 : /************************************************************************/
305 :
306 : /** Quantize Z or M values.
307 : *
308 : * @since GDAL 3.9
309 : */
310 : template <int SPACING>
311 215510 : inline void OGRRoundCoordinatesIEEE754(int nBitsPrecision, GByte *pabyBase,
312 : size_t nPoints)
313 : {
314 215510 : if (nBitsPrecision != INT_MIN)
315 : {
316 52 : for (size_t i = 0; i < nPoints; i++)
317 : {
318 : uint64_t nVal;
319 :
320 34 : memcpy(&nVal, pabyBase + SPACING * i, sizeof(uint64_t));
321 34 : nVal = OGRRoundValueIEEE754(nVal, nBitsPrecision);
322 34 : memcpy(pabyBase + SPACING * i, &nVal, sizeof(uint64_t));
323 : }
324 : }
325 215510 : }
326 :
327 : /* -------------------------------------------------------------------- */
328 : /* helper functions for string escaping. */
329 : /* -------------------------------------------------------------------- */
330 :
331 : /** Replace all occurrences of ch by it repeated twice.
332 : * Typically used for SQL string literal or identifier escaping.
333 : */
334 : std::string CPL_DLL OGRDuplicateCharacter(const std::string &osStr, char ch);
335 :
336 : #endif /* ndef OGR_P_H_INCLUDED */
|