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