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