forked from OSGeo/gdal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MIGRATION_GUIDE.TXT
481 lines (356 loc) · 21.2 KB
/
MIGRATION_GUIDE.TXT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
MIGRATION GUIDE FROM GDAL 3.3 to GDAL 3.4
-----------------------------------------
- Out-of-tree vector drivers:
* OGRFeatureDefn protected member variables have been changed.
- (nFieldCount, papoFieldDefn) ==> std::vector<std::unique_ptr<OGRFieldDefn>> apoFieldDefn{};
- (nGeomFieldCount, paoGeomFieldDefn) ==> std::vector<std::unique_ptr<OGRGeomFieldDefn>> apoGeomFieldDefn{};
* OGRFeatureDefn::AddGeomFieldDefn( OGRGeomFieldDefn *, bCopy = FALSE ) is
replaced by AddGeomFieldDefn( std::unique_ptr<OGRGeomFieldDefn>&& )
* GDALDataset::FlushCache() and GDALRasterBand::FlushCache() now takes a bool bAtClosing argument.
That argument is set to true when FlushCache() is called from the dataset/band destructor.
This can be used as a hint, for example to avoid doing extra work if the dataset is marked
for deletion at closing. Driver implementing that method should propagate the argument to the
base implementation when calling it.
MIGRATION GUIDE FROM GDAL 3.2 to GDAL 3.3
-----------------------------------------
- Python bindings:
* Python 2 is no longer supported per RFC 77. Python 3.6 or later required
* "osgeo.utils" was replaced by "osgeo_utils" (more details: see RFC78)
* The following undocumented, untested utility scripts are no longer installed as system scripts and were moved
from "gdal/swig/python/gdal-utils" to: "gdal/swig/python/gdal-utils/samples":
- epsg_tr.py
- esri2wkt.py
- gcps2vec.py
- gcps2wld.py
- gdal_auth.py
- gdalchksum.py
- gdalident.py
- gdalimport.py
- mkgraticule.py
In order to import sample script X (i.e. `epsg_tr`) as a module, use: `from osgeo_utils.samples import X`.
In order to run it as a script run: `python -m osgeo_utils.samples.X`.
* packaging:
- "gdal/swig/python/samples" moved to: "gdal/swig/python/gdal-utils/osgeo_utils/samples"
- "gdal/swig/python/scripts" moved to: "gdal/swig/python/gdal-utils/scripts"
- gdaldem TRI: default algorithm has been changed to use Riley et al. 1999. Use -alg Wilson to select the algorithm used previously
- Disable by default raster drivers DODS, JPEG2000(Jasper), JPEGLS, MG4LIDAR, FUJIBAS, IDA, INGR, ZMAP and vector driver ARCGEN, ArcObjects, CLOUDANT, COUCHDB, DB2, DODS, FME, GEOMEDIA, GTM, INGRES, MONGODB, REC, WALK at runtime, unless the GDAL_ENABLE_DEPRECATED_DRIVER_{drivername} configuration option is set to YES. Those drivers are planned for complete removal in GDAL 3.5
- Perl bindings are deprecated. Removal planned for GDAL 3.5. Use Geo::GDAL::FFI instead
- Removal of BNA, AeronavFAA, HTF, OpenAir, SEGUKOOA, SEGY, SUA, XPlane, BPG, E00GRID, EPSILON, IGNFHeightASCIIGrid, NTV1 drivers. Moved to (unsupported) https://github.com/OSGeo/gdal-extra-drivers repository.
MIGRATION GUIDE FROM GDAL 3.1 to GDAL 3.2
-----------------------------------------
- Python bindings: old-style, deprecated for many years, import method of
importing the gdal module through "import gdal" is no longer available.
"from osgeo import gdal" must now be used. This holds true for the ogr, osr,
gdalconst and gdalnumeric modules.
MIGRATION GUIDE FROM GDAL 3.0 to GDAL 3.1
-----------------------------------------
- OGR SQL: the 'LIKE' operator is now case sensitive by default. ILIKE (supported
in previous versions) must be used for case insensitive comparison. The
OGR_SQL_LIKE_AS_ILIKE configuration option can be set to YES to make LIKE behave
in a case insensitive way as in previous versions.
MIGRATION GUIDE FROM GDAL 2.4 to GDAL 3.0
-----------------------------------------
- Unix Build: ./configure arguments --without-bsb, --without-grib,
and --without-mrf have been renamed to --disable-driver-bsb,
--disable-driver-grib and --disable-driver-mrf
- Unix build: Arguments of --with-pg changed to yes/no only.
- Substantial changes, sometimes backward incompatible, in coordinate reference
system and coordinate transformations have been introduced per
https://trac.osgeo.org/gdal/wiki/rfc73_proj6_wkt2_srsbarn
* OSRImportFromEPSG() takes into account official axis order.
Traditional GIS-friendly axis order can be restored with
OGRSpatialReference::SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
* Same for SetWellKnownGeogCS("WGS84") / SetFromUserInput("WGS84")
* removal of OPTGetProjectionMethods(), OPTGetParameterList() and OPTGetParameterInfo()
No equivalent.
* removal of OSRFixup() and OSRFixupOrdering(): no longer needed since objects
constructed are always valid
* removal of OSRStripCTParms(). Use OSRExportToWktEx() instead with the
FORMAT=SQSQL option
* exportToWkt() outputs AXIS nodes
* OSRIsSame(): now takes into account data axis to CRS axis mapping, unless
IGNORE_DATA_AXIS_TO_SRS_AXIS_MAPPING=YES is set as an option to OSRIsSameEx()
* ogr_srs_api.h: SRS_WKT_WGS84 macro is no longer declared by default since
WKT without AXIS is too ambiguous. Preferred remediation: use SRS_WKT_WGS84_LAT_LONG.
Or #define USE_DEPRECATED_SRS_WKT_WGS84 before including ogr_srs_api.h
Out-of-tree drivers:
* GDALDataset::GetProjectionRef() made non-virtual.
Replaced by GetSpatialRef() virtual method.
Compatibility emulation possible by defining:
const char* _GetProjectionRef() override; // note leading underscore
const OGRSpatialReference* GetSpatialRef() const override {
return GetSpatialRefFromOldGetProjectionRef();
}
* GDALDataset::SetProjection() made non-virtual.
Replaced by SetSpatialRef() virtual method.
Compatibility emulation possible by defining:
CPLErr _SetProjection(const char*) override; // note leading underscore
CPLErr SetSpatialRef(const OGRSpatialReference* poSRS) override {
return OldSetProjectionFromSetSpatialRef(poSRS);
}
* GDALDataset::GetGCPProjection() made non-virtual.
Replaced by GetGCPSpatialRef() virtual method.
Compatibility emulation possible by defining:
const char* _GetGCPProjectionRef() override; // note leading underscore
const OGRSpatialReference* GetGCPSpatialRef() const override {
return GetGCPSpatialRefFromOldGetGCPProjection();
}
* GDALDataset::SetGCPs(..., const char* pszWKT) made non-virtual.
Replaced by SetGCPs(..., const OGRSpatialReference* poSRS) virtual mode.
CPLErr _SetGCPs( int nGCPCount, const GDAL_GCP *pasGCPList,
const char *pszGCPProjection ) override; // note leading underscore
CPLErr SetGCPs( int nGCPCountIn, const GDAL_GCP *pasGCPListIn,
const OGRSpatialReference* poSRS ) override {
return OldSetGCPsFromNew(nGCPCountIn, pasGCPListIn, poSRS);
}
MIGRATION GUIDE FROM GDAL 2.3 to GDAL 2.4
-----------------------------------------
1) Out-of-tree drivers: RawRasterBand() constructor changes
RawRasterBand now only accepts a VSILFILE* file. Consequently the void* fpRaw
argument has become a VSILFILE* one. And the bIsVSIL = FALSE argument has
been removed. The int bOwnsFP = FALSE has seen its default value suppressed,
and has seen its type changed to the RawRasterBand::OwnFP::YES/NO enumeration,
to detect places where your code must be changed.
Caution: code like RawRasterBand(..., bNativeOrder, TRUE) must be changed to
RawRasterBand(..., bNativeOrder, RawRasterBand::OwnFP::NO, the TRUE value
being the bIsVSIL value, and the default argument being bOwnsFP == FALSE.
MIGRATION GUIDE FROM GDAL 2.2 to GDAL 2.3
-----------------------------------------
1) RFC 70: Guessing output format from output file name extension for utilities
Link: https://trac.osgeo.org/gdal/wiki/rfc70_output_format_guess
Before GDAL 2.3, if not specifying the output format to utilities, GeoTIFF or
Shapefile were assumed for most utilities. Now, the output format will be
guessed from the output filename extension. This might break usages where
non-standard extensions are used for GeoTIFF or Shapefile output when -f/-of is
not specified (but warnings were already emitted in such situations).
2) RFC 68: C++11 Compilation requirement
Link: https://trac.osgeo.org/gdal/wiki/rfc68_cplusplus11
GDAL now requires a C++11 compatible compiler. External code using GDAL C++ API
will also need to enable at least C++11 compilation mode, if the compiler
defaults to C++98/C++03.
3) Stricter const-ness in OGRGeomFieldDefn, OGRFeatureDefn and OGRFeature
classes, impacting out-of-tree drivers that subclass them.
The following methods are now const qualified:
OGRGeomFieldDefn class:
virtual OGRSpatialReference* GetSpatialRef() const
OGRFeatureDefn class:
virtual const char* GetName() const
virtual int GetFieldCount() const
virtual int GetFieldIndex(const char*) const
virtual int GetGeomFieldCount() const
virtual int GetGeomFieldIndex(const char*) const
virtual OGRwkbGeometryType GetGeomType() const
virtual OGRFeatureDefn* Clone() const
virtual int IsGeometryIgnored() const
virtual int IsSame(const OGRFeatureDefn*) const // argument is const now too
OGRFeature class:
virtual OGRBoolean Equal(const OGRFeature*) const // argument is const now too
virtual const char* GetStyleString() const
virtual OGRStyleTable* GetStyleTable() const
The following virtual methods, offering const alternatives to their
non-const equivalent methods, should be overloaded if the non-const
method is overloaded.
OGRFeatureDefn class:
virtual const OGRFieldDefn* GetFieldDefn(int) const
virtual const OGRGeomFieldDefn* GetGeomFieldDefn(int) const
MIGRATION GUIDE FROM GDAL 2.1 to GDAL 2.2
-----------------------------------------
A) RFC 64: Triangle, Polyhedral surface and TIN
Link: https://trac.osgeo.org/gdal/wiki/rfc64_triangle_polyhedralsurface_tin
Vector drivers can now return geometries of type wkbPolyhedralSurface, wkbTIN
and wkbTriangle; and their Z, M and ZM variants (as well as for the type of
geometry fields). Client code, as well as out-of-tree drivers that support
writing geometries, must be ready to deal with them.
B) RFC 67: Null values in OGR
Link: https://trac.osgeo.org/gdal/wiki/rfc67_nullfieldvalues
Previously, the "unset" state of a field was used both for a unset state
(ie no information for the field of the feature) or the NULL state of the
field. Now there is OGR_F_IsFieldSet() / OGRFeature::IsFieldSet() for the
unset state, and a new OGR_F_IsFieldNull() / OGRFeature::IsFieldNull() for the
new NULL state. Code that used OGR_F_IsFieldSet() / OGRFeature::IsFieldSet()
should also test the NULL state, otherwise empty strings or 0 numeric values
will be returned. A convenient way of migrating is to replace the use of
OGR_F_IsFieldSet() / OGRFeature::IsFieldSet() by OGR_F_IsFieldSetAndNotNull() /
OGRFeature::IsFieldSetAndNotNull() if there is no need to distinguish both
states.
On the writing side, a few drivers will now distinguish between the unset
and null state, namely GeoJSON, CouchDB, Cloudant, MongoDB, ElasticSearch and
GML. For example, for the GeoJSON driver, in GDAL 2.1 or before, a unset field
was written as field_name: null. Starting with GDAL 2.2, only fields explicitly
set as null with OGR_F_SetFieldNull() will be written with a null value.
Unset fields of a feature will not be present in the corresponding JSon feature
element.
MIGRATION GUIDE FROM GDAL 2.0 to GDAL 2.1
------------------------------------------
A) RFC 61: Support for measured geometries
Link: https://trac.osgeo.org/gdal/wiki/rfc61_support_for_measured_geometries
The OGRwkbGeometryType enumeration has been extended with new values for the
M and ZM variants of the geometry types. Client code may have to be upgraded
to take into account those new values. Note that the wkbPolyhedralSurface, wkbTIN
and wkbTriangle types and their Z, M and ZM variants, have also been introduced
as a provision for a potential support in a future version (they are unused in
OGR core and drivers for now).
Previously the ESRI Shapefile driver read XYM data as XYZ. Now it is read
as XYM.
MIGRATION GUIDE FROM GDAL 1.11 to GDAL 2.0
------------------------------------------
This file documents backwards incompatible changes. You are strongly encouraged
to read the relevant RFCs for details and rationale for those changes.
Changes to the Perl bindings API are listed in swig/perl/Changes-in-the-API-in-2.0.
A) RFC 46: Unification of GDAL and OGR driver models
Link: http://trac.osgeo.org/gdal/wiki/rfc46_gdal_ogr_unification
C++ API:
* OGRSFDriverRegistrar and OGRSFDriver are now deprecated. Use GDALDriverManager
and GDALDriver instead.
* The following methods from OGRSFDriverRegistrar are removed : Open(),
OpenShared(), ReleaseDataSource(), DeregisterDriver(), AutoLoadDrivers()
GetDriver() and GetDriverByName() now return a GDALDriver* instance.
* OGRDataSource::CreateLayer() specialized implementations should be renamed
as ICreateLayer() to benefit from layer creation options validation.
* OGRLayer::GetInfo() has been removed.
* All methods of OGRDataSource have been transferred to GDALDataset, except
SyncToDisk() that should now be implemented as FlushCache() in drivers.
* GDALOpenInfo::papszSiblingFiles member is now private. Use the new
GetSiblingFiles() method instead.
* GDALOpenInfo::fp member is replaced by fpL member of type VSILFILE*.
* OGRSFDriver::CopyDataSource() has been removed.
* GDALDriverManager::GetHome() and SetHome() have been removed.
Out-of-tree drivers :
* Read RFC 46 for the needed changes. Changes in GDALOpenInfo will impact GDAL
drivers. GDAL drivers should also declare SetMetadataItem( GDAL_DCAP_RASTER, "YES" ).
OGRDataSource::CreateLayer() and SyncToDisk() changes will affect OGR drivers.
Behavior changes :
* GDALDriverManager::GetDriverCount() and GetDriver() return both raster and
vector drivers. The nature of a driver can be tested with the GDAL_DCAP_RASTER
and GDAL_DCAP_VECTOR driver metadata item.
* GetRefCount() starts at 1 for OGRDataSource instead of 0.
B) RFC 49: Curve geometries
Link: http://trac.osgeo.org/gdal/wiki/rfc49_curve_geometries
C/C++ API :
* Use of wkb25DBit macro is strongly discouraged, as not compatible with new
geometry types. Use wkbFlatten(), wkbHasZ(), wkbSetZ() instead
* OGRwkbGeometryType enumeration has new values.
Behavior changes :
* GML, NAS, WFS, PostGIS, VRT, GeoPackage and CSV drivers can return non-linear geometries.
Applications that do not wish to get such geometries can call
OGRSetNonLinearGeometriesEnabledFlag(FALSE)
Out-of-tree drivers :
* Read RFC 49 for the needed changes. CreateFeature() and SetFeature() virtual
methods must be renamed ICreateFeature() and ISetFeature().
C) RFC 51: RasterIO() improvements : resampling and progress callback
Link: http://trac.osgeo.org/gdal/wiki/rfc51_rasterio_resampling_progress
Out-of-tree drivers :
* Read RFC 51 for the needed changes. GDALRasterBand and GDALDataset::IRasterIO()
take a new GDALRasterIOExtraArg* psExtraArg argument.
GDALRasterBand and GDALDataset::RasterIO() take a new
GDALRasterIOExtraArg* psExtraArg argument
D) RFC 31: OGR 64bit Integer Fields and FIDs
Link:http://trac.osgeo.org/gdal/wiki/rfc31_ogr_64
C++ API:
* OGRLayer::GetFeature(), OGRLayer::DeleteFeature(), OGRLayer::SetNextByIndex() take a GIntBig instead of a long
* OGRFeature::GetFID() and OGRLayer::GetFeatureCount() now returns a GIntBig
C API:
* OGR_L_GetFeature(), OGR_L_DeleteFeature(), OGR_L_SetNextByIndex() take a GIntBig instead of a long
* OGR_F_GetFID() and OGR_L_GetFeatureCount() now returns a GIntBig
Behavior changes :
* OFTInteger64 and OFTIntegerList64 can be returned whereas OGRFieldType is returned.
Out-of-tree drivers :
* Virtual method signature change: OGRLayer::GetFeature(), OGRLayer::DeleteFeature(),
OGRLayer::SetNextByIndex() take a GIntBig argument instead of a long
* Virtual method signature change: OGRLayer::GetFeatureCount() now returns a GIntBig
* OGRFeature::GetFID() returns a GIntBig
E) RFC 52: Strict OGR SQL quoting
Link: http://trac.osgeo.org/gdal/wiki/rfc52_strict_sql_quoting
No API changes
Behavior changes:
* Identifiers, i.e column names or table names, can no longer be quoted with
single quote characters, but must use double quote characters if quoting is
needed, conforming with SQL 92 syntax. Failure to do the change will not
necessarily need to verbose errors at runtime since an expression like
WHERE 'a_column_name' = 'a_value' will now always evaluate to FALSE whereas
it would have been interpreted as WHERE "a_column_name" = 'a_value" if
a_column_name was indeed a column name.
F) RFC 53: OGR not-null constraints and default values
Link: http://trac.osgeo.org/gdal/wiki/rfc53_ogr_notnull_default
API changes:
* OGRFieldDefn::SetDefault() now takes a const char* as argument.
OGRFieldDefn::GetDefaultRef() removed and replaced by GetDefault() that
returns a const char*
G) RFC 54: Dataset transactions
Link: http://trac.osgeo.org/gdal/wiki/rfc54_dataset_transactions
Only API additions.
Behavior changes:
* As described in the RFC, subtle behavior changes can be observed with the PG driver,
related to implicit transactions that were flushed before and are no longer now,
but this should hopefully be restricted to non-typical use cases. So some cases that "worked" before might
no longer work, but the new behavior should hopefully be more understandable.
* The PG and SQLite drivers could accept apparently nested calls to StartTransaction()
(at the layer level). This is no longer possible since they are now redirected
to dataset transactions, that explicitly do not support it.
H) RFC 55: Refined SetFeature() and DeleteFeature() semantics
Link: http://trac.osgeo.org/gdal/wiki/rfc55_refined_setfeature_deletefeature_semantics
Behavior changes:
* Drivers will now return OGRERR_NON_EXISTING_FEATURE when calling SetFeature()
or DeleteFeature() with a feature id that does not exist.
I) RFC 56:
Link: https://trac.osgeo.org/gdal/wiki/rfc56_millisecond_precision
API/ABI changes:
* OGRField.Date structure has now a Reserved field that must be set to 0 when
using the OGRFeature::SetField( int i, OGRField * puValue ) method.
The "GByte Second" field is now a "float Second".
* OGRFeature::SetField( int i, int nYear, int nMonth, int nDay,
int nHour=0, int nMinute=0, float fSecond=0.f,
int nTZFlag = 0 )
and the variant that take a const char* as first argument now accept a
floating-point number for seconds.
API additions :
* OGRFeature::GetFieldAsDateTime( int i,
int *pnYear, int *pnMonth, int *pnDay,
int *pnHour, int *pnMinute, float *pfSecond,
int *pnTZFlag );
* OGR_F_GetFieldAsDateTimeEx() and OGR_F_SetFieldDateTimeEx() are added.
Driver related changes:
* The following functions, mainly used by driver implementations, have
seen their signature change :
int CPL_DLL OGRParseXMLDateTime( const char* pszXMLDateTime,
OGRField* psField );
int CPL_DLL OGRParseRFC822DateTime( const char* pszRFC822DateTime,
OGRField* psField );
char CPL_DLL * OGRGetRFC822DateTime(const OGRField* psField);
char CPL_DLL * OGRGetXMLDateTime(const OGRField* psField);
Behavior changes:
* OGRFeature::GetFieldAsString() will now output milliseconds if a DateTime/Time
field has such precision.
* Drivers will now output milliseconds if a DateTime/Time field has such precision.
J) RFC 57: 64-bit bucket count for histograms
Link: https://trac.osgeo.org/gdal/wiki/rfc57_histogram_64bit_count
C++ API:
* GDALRasterBand::GetHistogram() and GDALRasterBand::SetDefaultHistogram() take a GUIntBig* instead of a int* for bucket counts.
* GDALRasterBand::GetDefaultHistogram() takes a GUIntBig** instead of a int** for bucket counts.
* GDALRasterBand::GetRasterSampleOverview() takes a GUIntBig instead of int.
C API:
* GDALGetRasterHistogramEx(), GDALGetDefaultHistogramEx() and GDALSetDefaultHistogramEx() are added
and deprecate the old interfaces.
* GDALGetRasterSampleOverviewEx() is added.
Out-of-tree drivers :
* See the virtual method API changes mentioned above in the C++ API paragraph.
MIGRATION GUIDE FROM GDAL 1.10 to GDAL 1.11
-------------------------------------------
This file documents backwards incompatible changes.
C++ API:
* GDALRasterAttributeTable is now an abstract class.
See http://trac.osgeo.org/gdal/wiki/rfc40_enhanced_rat_support
The functionality of GDAL 1.X GDALRasterAttributeTable is now in
GDALDefaultRasterAttributeTable.
OGR drivers :
* Due to RFC 41, if a OGR driver calls SetGeomType(wkbNone) on a layer,
it will be impossible to affect geometries to features of that layer.
This worked before, although it was inconsistent, but it does no longer now.
In the development of RFC 41, the CSV and VRT drivers have been upgraded
to fix such errors.
Changes that should likely not impact anybody :
* OGRGeometry::exportToGEOS() and OGRGeometryFactory::createFromGEOS() now
take a GEOSContextHandle_t argument ( GEOS >= 3.1.0 )
* OGRGeometryFactory::getGEOSGeometryFactory() has been removed.
This method returned NULL since 2006
( http://trac.osgeo.org/gdal/changeset/9899/trunk/ogr/ogrgeometryfactory.cpp )