Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Implements OGRGeoconceptLayer class.
5 : * Author: Didier Richard, didier.richard@ign.fr
6 : * Language: C++
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2007, Geoconcept and IGN
10 : * Copyright (c) 2008, 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 : #include "cpl_conv.h"
32 : #include "cpl_string.h"
33 : #include "ogrgeoconceptlayer.h"
34 :
35 : /************************************************************************/
36 : /* OGRGeoconceptLayer() */
37 : /************************************************************************/
38 :
39 9 : OGRGeoconceptLayer::OGRGeoconceptLayer()
40 9 : : _poFeatureDefn(nullptr), _gcFeature(nullptr)
41 : {
42 9 : }
43 :
44 : /************************************************************************/
45 : /* ~OGRGeoconceptLayer() */
46 : /************************************************************************/
47 :
48 36 : OGRGeoconceptLayer::~OGRGeoconceptLayer()
49 :
50 : {
51 9 : if (_poFeatureDefn)
52 : {
53 18 : CPLDebug("GEOCONCEPT", "%ld features on layer %s.",
54 9 : GetSubTypeNbFeatures_GCIO(_gcFeature),
55 9 : _poFeatureDefn->GetName());
56 :
57 9 : _poFeatureDefn->Release();
58 : }
59 :
60 9 : _gcFeature = nullptr; /* deleted when OGCGeoconceptDatasource destroyed */
61 18 : }
62 :
63 : /************************************************************************/
64 : /* Open() */
65 : /************************************************************************/
66 :
67 9 : OGRErr OGRGeoconceptLayer::Open(GCSubType *Subclass)
68 :
69 : {
70 9 : _gcFeature = Subclass;
71 9 : if (GetSubTypeFeatureDefn_GCIO(_gcFeature))
72 : {
73 8 : _poFeatureDefn = reinterpret_cast<OGRFeatureDefn *>(
74 8 : GetSubTypeFeatureDefn_GCIO(_gcFeature));
75 8 : SetDescription(_poFeatureDefn->GetName());
76 8 : _poFeatureDefn->Reference();
77 : }
78 : else
79 : {
80 : char pszln[512];
81 1 : snprintf(pszln, 511, "%s.%s", GetSubTypeName_GCIO(_gcFeature),
82 1 : GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)));
83 1 : pszln[511] = '\0';
84 :
85 1 : _poFeatureDefn = new OGRFeatureDefn(pszln);
86 1 : SetDescription(_poFeatureDefn->GetName());
87 1 : _poFeatureDefn->Reference();
88 1 : _poFeatureDefn->SetGeomType(wkbUnknown);
89 :
90 1 : const int n = CountSubTypeFields_GCIO(_gcFeature);
91 1 : if (n > 0)
92 : {
93 : OGRFieldType oft;
94 8 : for (int i = 0; i < n; i++)
95 : {
96 7 : GCField *aField = GetSubTypeField_GCIO(_gcFeature, i);
97 7 : if (aField)
98 : {
99 7 : if (IsPrivateField_GCIO(aField))
100 7 : continue;
101 0 : switch (GetFieldKind_GCIO(aField))
102 : {
103 0 : case vIntFld_GCIO:
104 : case vPositionFld_GCIO:
105 0 : oft = OFTInteger;
106 0 : break;
107 0 : case vRealFld_GCIO:
108 : case vLengthFld_GCIO:
109 : case vAreaFld_GCIO:
110 0 : oft = OFTReal;
111 0 : break;
112 0 : case vDateFld_GCIO:
113 0 : oft = OFTDate;
114 0 : break;
115 0 : case vTimeFld_GCIO:
116 0 : oft = OFTTime;
117 0 : break;
118 0 : case vMemoFld_GCIO:
119 : case vChoiceFld_GCIO:
120 : case vInterFld_GCIO:
121 : default:
122 0 : oft = OFTString;
123 0 : break;
124 : }
125 0 : OGRFieldDefn ofd(GetFieldName_GCIO(aField), oft);
126 0 : _poFeatureDefn->AddFieldDefn(&ofd);
127 : }
128 : }
129 : }
130 1 : SetSubTypeFeatureDefn_GCIO(_gcFeature, (OGRFeatureDefnH)_poFeatureDefn);
131 1 : _poFeatureDefn->Reference();
132 : }
133 :
134 9 : if (_poFeatureDefn->GetGeomFieldCount() > 0)
135 9 : _poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(GetSpatialRef());
136 :
137 9 : return OGRERR_NONE;
138 : }
139 :
140 : /************************************************************************/
141 : /* ResetReading() */
142 : /************************************************************************/
143 :
144 6 : void OGRGeoconceptLayer::ResetReading()
145 :
146 : {
147 6 : Rewind_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature), _gcFeature);
148 6 : }
149 :
150 : /************************************************************************/
151 : /* GetNextFeature() */
152 : /************************************************************************/
153 :
154 37 : OGRFeature *OGRGeoconceptLayer::GetNextFeature()
155 :
156 : {
157 37 : OGRFeature *poFeature = nullptr;
158 :
159 : for (;;)
160 : {
161 37 : if (!(poFeature = (OGRFeature *)ReadNextFeature_GCIO(_gcFeature)))
162 : {
163 : /*
164 : * As several features are embed in the Geoconcept file,
165 : * when reaching the end of the feature type, resetting
166 : * the reader would allow reading other features :
167 : * ogrinfo -ro export.gxt FT1 FT2 ...
168 : * will be all features for all features types !
169 : */
170 6 : Rewind_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature), nullptr);
171 6 : break;
172 : }
173 62 : if ((m_poFilterGeom == nullptr ||
174 62 : FilterGeometry(poFeature->GetGeometryRef())) &&
175 31 : (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
176 : {
177 31 : break;
178 : }
179 0 : delete poFeature;
180 : }
181 :
182 130 : CPLDebug("GEOCONCEPT",
183 : "FID : " CPL_FRMT_GIB "\n"
184 : "%s : %s",
185 31 : poFeature ? poFeature->GetFID() : -1L,
186 31 : poFeature && poFeature->GetFieldCount() > 0
187 31 : ? poFeature->GetFieldDefnRef(0)->GetNameRef()
188 : : "-",
189 31 : poFeature && poFeature->GetFieldCount() > 0
190 31 : ? poFeature->GetFieldAsString(0)
191 : : "");
192 :
193 37 : return poFeature;
194 : }
195 :
196 : /************************************************************************/
197 : /* OGRGeoconceptLayer_GetCompatibleFieldName() */
198 : /************************************************************************/
199 :
200 15 : static char *OGRGeoconceptLayer_GetCompatibleFieldName(const char *pszName)
201 : {
202 15 : char *pszCompatibleName = CPLStrdup(pszName);
203 169 : for (int i = 0; pszCompatibleName[i] != 0; i++)
204 : {
205 154 : if (pszCompatibleName[i] == ' ')
206 0 : pszCompatibleName[i] = '_';
207 : }
208 15 : return pszCompatibleName;
209 : }
210 :
211 : /************************************************************************/
212 : /* ICreateFeature() */
213 : /************************************************************************/
214 :
215 2 : OGRErr OGRGeoconceptLayer::ICreateFeature(OGRFeature *poFeature)
216 :
217 : {
218 2 : OGRGeometry *poGeom = poFeature->GetGeometryRef();
219 :
220 2 : if (poGeom == nullptr)
221 : {
222 0 : CPLError(
223 : CE_Warning, CPLE_NotSupported,
224 : "NULL geometry not supported in Geoconcept, feature skipped.\n");
225 0 : return OGRERR_NONE;
226 : }
227 :
228 2 : OGRwkbGeometryType eGt = poGeom->getGeometryType();
229 2 : switch (wkbFlatten(eGt))
230 : {
231 2 : case wkbPoint:
232 : case wkbMultiPoint:
233 2 : if (GetSubTypeKind_GCIO(_gcFeature) == vUnknownItemType_GCIO)
234 : {
235 0 : SetSubTypeKind_GCIO(_gcFeature, vPoint_GCIO);
236 : }
237 2 : else if (GetSubTypeKind_GCIO(_gcFeature) != vPoint_GCIO)
238 : {
239 0 : CPLError(CE_Failure, CPLE_NotSupported,
240 : "Can't write non ponctual feature in a ponctual "
241 : "Geoconcept layer %s.\n",
242 0 : _poFeatureDefn->GetName());
243 0 : return OGRERR_FAILURE;
244 : }
245 2 : break;
246 0 : case wkbLineString:
247 : case wkbMultiLineString:
248 0 : if (GetSubTypeKind_GCIO(_gcFeature) == vUnknownItemType_GCIO)
249 : {
250 0 : SetSubTypeKind_GCIO(_gcFeature, vLine_GCIO);
251 : }
252 0 : else if (GetSubTypeKind_GCIO(_gcFeature) != vLine_GCIO)
253 : {
254 0 : CPLError(
255 : CE_Failure, CPLE_NotSupported,
256 : "Can't write non linear feature in a linear Geoconcept "
257 : "layer %s.\n",
258 0 : _poFeatureDefn->GetName());
259 0 : return OGRERR_FAILURE;
260 : }
261 0 : break;
262 0 : case wkbPolygon:
263 : case wkbMultiPolygon:
264 0 : if (GetSubTypeKind_GCIO(_gcFeature) == vUnknownItemType_GCIO)
265 : {
266 0 : SetSubTypeKind_GCIO(_gcFeature, vPoly_GCIO);
267 : }
268 0 : else if (GetSubTypeKind_GCIO(_gcFeature) != vPoly_GCIO)
269 : {
270 0 : CPLError(CE_Failure, CPLE_NotSupported,
271 : "Can't write non polygonal feature in a polygonal "
272 : "Geoconcept layer %s.\n",
273 0 : _poFeatureDefn->GetName());
274 0 : return OGRERR_FAILURE;
275 : }
276 0 : break;
277 0 : default:
278 0 : CPLError(CE_Warning, CPLE_AppDefined,
279 : "Geometry type %s not supported in Geoconcept, "
280 : "feature skipped.\n",
281 : OGRGeometryTypeToName(eGt));
282 0 : return OGRERR_NONE;
283 : }
284 2 : if (GetSubTypeDim_GCIO(_gcFeature) == vUnknown3D_GCIO)
285 : {
286 0 : if (poGeom->getCoordinateDimension() == 3)
287 : {
288 0 : SetSubTypeDim_GCIO(_gcFeature, v3D_GCIO);
289 : }
290 : else
291 : {
292 0 : SetSubTypeDim_GCIO(_gcFeature, v2D_GCIO);
293 : }
294 : }
295 :
296 2 : int nbGeom = 0;
297 2 : bool isSingle = false;
298 :
299 2 : switch (wkbFlatten(eGt))
300 : {
301 2 : case wkbPoint:
302 : case wkbLineString:
303 : case wkbPolygon:
304 2 : nbGeom = 1;
305 2 : isSingle = true;
306 2 : break;
307 0 : case wkbMultiPoint:
308 : case wkbMultiLineString:
309 : case wkbMultiPolygon:
310 0 : nbGeom = poGeom->toGeometryCollection()->getNumGeometries();
311 0 : isSingle = false;
312 0 : break;
313 0 : default:
314 0 : nbGeom = 0;
315 0 : isSingle = false;
316 0 : break;
317 : }
318 :
319 : /* 1st feature, let's write header : */
320 4 : if (GetGCMode_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature)) ==
321 4 : vWriteAccess_GCIO &&
322 2 : GetFeatureCount(TRUE) == 0)
323 1 : if (WriteHeader_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature)) == nullptr)
324 : {
325 0 : return OGRERR_FAILURE;
326 : }
327 :
328 2 : if (nbGeom > 0)
329 : {
330 4 : for (int iGeom = 0; iGeom < nbGeom; iGeom++)
331 : {
332 4 : int nextField = StartWritingFeature_GCIO(
333 : _gcFeature,
334 2 : isSingle ? static_cast<int>(poFeature->GetFID()) : OGRNullFID);
335 10 : while (nextField != WRITECOMPLETED_GCIO)
336 : {
337 8 : if (nextField == WRITEERROR_GCIO)
338 : {
339 0 : return OGRERR_FAILURE;
340 : }
341 8 : if (nextField == GEOMETRYEXPECTED_GCIO)
342 : {
343 : OGRGeometry *poGeomPart =
344 : isSingle
345 2 : ? poGeom
346 0 : : poGeom->toGeometryCollection()->getGeometryRef(
347 2 : iGeom);
348 2 : nextField = WriteFeatureGeometry_GCIO(
349 : _gcFeature, (OGRGeometryH)poGeomPart);
350 : }
351 : else
352 : {
353 : GCField *theField =
354 6 : GetSubTypeField_GCIO(_gcFeature, nextField);
355 : /* for each field, find out its mapping ... */
356 6 : int nF = poFeature->GetFieldCount();
357 6 : if (nF > 0)
358 : {
359 6 : int iF = 0;
360 12 : for (; iF < nF; iF++)
361 : {
362 : OGRFieldDefn *poField =
363 12 : poFeature->GetFieldDefnRef(iF);
364 : char *pszName =
365 12 : OGRGeoconceptLayer_GetCompatibleFieldName(
366 : poField->GetNameRef());
367 12 : if (EQUAL(pszName, GetFieldName_GCIO(theField)))
368 : {
369 6 : CPLFree(pszName);
370 6 : nextField = WriteFeatureFieldAsString_GCIO(
371 : _gcFeature, nextField,
372 6 : poFeature->IsFieldSetAndNotNull(iF)
373 5 : ? poFeature->GetFieldAsString(iF)
374 : : nullptr);
375 6 : break;
376 : }
377 6 : CPLFree(pszName);
378 : }
379 6 : if (iF == nF)
380 : {
381 0 : CPLError(CE_Failure, CPLE_AppDefined,
382 : "Can't find a field attached to %s on "
383 : "Geoconcept layer %s.\n",
384 : GetFieldName_GCIO(theField),
385 0 : _poFeatureDefn->GetName());
386 0 : return OGRERR_FAILURE;
387 : }
388 : }
389 : else
390 : {
391 0 : nextField = WRITECOMPLETED_GCIO;
392 : }
393 : }
394 : }
395 2 : StopWritingFeature_GCIO(_gcFeature);
396 : }
397 : }
398 :
399 2 : return OGRERR_NONE;
400 : }
401 :
402 : /************************************************************************/
403 : /* GetSpatialRef() */
404 : /************************************************************************/
405 :
406 12 : OGRSpatialReference *OGRGeoconceptLayer::GetSpatialRef()
407 :
408 : {
409 12 : GCExportFileH *hGXT = GetSubTypeGCHandle_GCIO(_gcFeature);
410 12 : if (!hGXT)
411 0 : return nullptr;
412 12 : GCExportFileMetadata *Meta = GetGCMeta_GCIO(hGXT);
413 12 : if (!Meta)
414 0 : return nullptr;
415 12 : return (OGRSpatialReference *)GetMetaSRS_GCIO(Meta);
416 : }
417 :
418 : /************************************************************************/
419 : /* GetFeatureCount() */
420 : /* */
421 : /* If a spatial filter is in effect, we turn control over to */
422 : /* the generic counter. Otherwise we return the total count. */
423 : /************************************************************************/
424 :
425 7 : GIntBig OGRGeoconceptLayer::GetFeatureCount(int bForce)
426 :
427 : {
428 7 : if (m_poFilterGeom != nullptr || m_poAttrQuery != nullptr)
429 0 : return OGRLayer::GetFeatureCount(bForce);
430 :
431 7 : return GetSubTypeNbFeatures_GCIO(_gcFeature);
432 : }
433 :
434 : /************************************************************************/
435 : /* GetExtent() */
436 : /************************************************************************/
437 :
438 0 : OGRErr OGRGeoconceptLayer::GetExtent(OGREnvelope *psExtent,
439 : CPL_UNUSED int bForce)
440 : {
441 0 : GCExtent *theExtent = GetSubTypeExtent_GCIO(_gcFeature);
442 0 : if (!theExtent)
443 0 : return OGRERR_FAILURE;
444 0 : psExtent->MinX = GetExtentULAbscissa_GCIO(theExtent);
445 0 : psExtent->MinY = GetExtentLROrdinate_GCIO(theExtent);
446 0 : psExtent->MaxX = GetExtentLRAbscissa_GCIO(theExtent);
447 0 : psExtent->MaxY = GetExtentULOrdinate_GCIO(theExtent);
448 :
449 0 : return OGRERR_NONE;
450 : }
451 :
452 : /************************************************************************/
453 : /* TestCapability() */
454 : /************************************************************************/
455 :
456 2 : int OGRGeoconceptLayer::TestCapability(const char *pszCap)
457 :
458 : {
459 2 : if (EQUAL(pszCap, OLCRandomRead))
460 0 : return FALSE; // the GetFeature() method does not work for this layer.
461 : // TODO
462 :
463 2 : else if (EQUAL(pszCap, OLCSequentialWrite))
464 0 : return TRUE; // the CreateFeature() method works for this layer.
465 :
466 2 : else if (EQUAL(pszCap, OLCRandomWrite))
467 0 : return FALSE; // the SetFeature() method is not operational on this
468 : // layer.
469 :
470 2 : else if (EQUAL(pszCap, OLCFastSpatialFilter))
471 0 : return FALSE; // this layer does not implement spatial filtering
472 : // efficiently.
473 :
474 2 : else if (EQUAL(pszCap, OLCFastFeatureCount))
475 0 : return FALSE; // this layer can not return a feature count efficiently.
476 : // FIXME
477 :
478 2 : else if (EQUAL(pszCap, OLCFastGetExtent))
479 0 : return FALSE; // this layer can not return its data extent efficiently.
480 : // FIXME
481 :
482 2 : else if (EQUAL(pszCap, OLCFastSetNextByIndex))
483 0 : return FALSE; // this layer can not perform the SetNextByIndex() call
484 : // efficiently.
485 :
486 2 : else if (EQUAL(pszCap, OLCDeleteFeature))
487 0 : return FALSE;
488 :
489 2 : else if (EQUAL(pszCap, OLCCreateField))
490 0 : return TRUE;
491 :
492 2 : else if (EQUAL(pszCap, OLCZGeometries))
493 0 : return TRUE;
494 :
495 2 : return FALSE;
496 : }
497 :
498 : /************************************************************************/
499 : /* CreateField() */
500 : /************************************************************************/
501 :
502 3 : OGRErr OGRGeoconceptLayer::CreateField(const OGRFieldDefn *poField,
503 : CPL_UNUSED int bApproxOK)
504 : {
505 3 : if (GetGCMode_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature)) == vReadAccess_GCIO)
506 : {
507 0 : CPLError(CE_Failure, CPLE_NotSupported,
508 : "Can't create fields on a read-only Geoconcept layer.\n");
509 0 : return OGRERR_FAILURE;
510 : }
511 :
512 : /* -------------------------------------------------------------------- */
513 : /* Add field to layer */
514 : /* -------------------------------------------------------------------- */
515 :
516 : {
517 : /* check whether field exists ... */
518 : char *pszName =
519 3 : OGRGeoconceptLayer_GetCompatibleFieldName(poField->GetNameRef());
520 :
521 3 : GCField *theField = FindFeatureField_GCIO(_gcFeature, pszName);
522 3 : if (!theField)
523 : {
524 3 : if (GetFeatureCount(TRUE) > 0)
525 : {
526 0 : CPLError(CE_Failure, CPLE_NotSupported,
527 : "Can't create field '%s' on existing Geoconcept layer "
528 : "'%s.%s'.\n",
529 0 : pszName, GetSubTypeName_GCIO(_gcFeature),
530 0 : GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)));
531 0 : CPLFree(pszName);
532 0 : return OGRERR_FAILURE;
533 : }
534 3 : if (GetSubTypeNbFields_GCIO(_gcFeature) == -1)
535 1 : SetSubTypeNbFields_GCIO(_gcFeature, 0L);
536 3 : if (!(theField = AddSubTypeField_GCIO(
537 3 : GetSubTypeGCHandle_GCIO(_gcFeature),
538 3 : GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)),
539 3 : GetSubTypeName_GCIO(_gcFeature),
540 6 : FindFeatureFieldIndex_GCIO(_gcFeature, kNbFields_GCIO) +
541 3 : GetSubTypeNbFields_GCIO(_gcFeature) + 1,
542 3 : pszName, GetSubTypeNbFields_GCIO(_gcFeature) - 999L,
543 : vUnknownItemType_GCIO, nullptr, nullptr)))
544 : {
545 0 : CPLError(CE_Failure, CPLE_AppDefined,
546 : "Field '%s' could not be created for Feature %s.%s.\n",
547 0 : pszName, GetSubTypeName_GCIO(_gcFeature),
548 0 : GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)));
549 0 : CPLFree(pszName);
550 0 : return OGRERR_FAILURE;
551 : }
552 3 : SetSubTypeNbFields_GCIO(_gcFeature,
553 : GetSubTypeNbFields_GCIO(_gcFeature) + 1);
554 3 : _poFeatureDefn->AddFieldDefn(poField);
555 : }
556 : else
557 : {
558 0 : if (_poFeatureDefn->GetFieldIndex(GetFieldName_GCIO(theField)) ==
559 : -1)
560 : {
561 0 : CPLError(CE_Failure, CPLE_AppDefined,
562 : "Field %s not found for Feature %s.%s.\n",
563 : GetFieldName_GCIO(theField),
564 0 : GetSubTypeName_GCIO(_gcFeature),
565 0 : GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)));
566 0 : CPLFree(pszName);
567 0 : return OGRERR_FAILURE;
568 : }
569 : }
570 :
571 3 : CPLFree(pszName);
572 3 : pszName = nullptr;
573 :
574 : /* check/update type ? */
575 3 : if (GetFieldKind_GCIO(theField) == vUnknownItemType_GCIO)
576 : {
577 3 : switch (poField->GetType())
578 : {
579 0 : case OFTInteger:
580 0 : SetFieldKind_GCIO(theField, vIntFld_GCIO);
581 0 : break;
582 0 : case OFTReal:
583 0 : SetFieldKind_GCIO(theField, vRealFld_GCIO);
584 0 : break;
585 0 : case OFTDate:
586 0 : SetFieldKind_GCIO(theField, vDateFld_GCIO);
587 0 : break;
588 0 : case OFTTime:
589 : case OFTDateTime:
590 0 : SetFieldKind_GCIO(theField, vTimeFld_GCIO);
591 0 : break;
592 3 : case OFTString:
593 3 : SetFieldKind_GCIO(theField, vMemoFld_GCIO);
594 3 : break;
595 0 : case OFTIntegerList:
596 : case OFTRealList:
597 : case OFTStringList:
598 : case OFTBinary:
599 : default:
600 0 : CPLError(CE_Failure, CPLE_NotSupported,
601 : "Can't create fields of type %s on Geoconcept "
602 : "feature %s.\n",
603 : OGRFieldDefn::GetFieldTypeName(poField->GetType()),
604 0 : _poFeatureDefn->GetName());
605 0 : return OGRERR_FAILURE;
606 : }
607 : }
608 : }
609 :
610 3 : return OGRERR_NONE;
611 : }
612 :
613 : /************************************************************************/
614 : /* SyncToDisk() */
615 : /************************************************************************/
616 :
617 0 : OGRErr OGRGeoconceptLayer::SyncToDisk()
618 :
619 : {
620 0 : FFlush_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature));
621 0 : return OGRERR_NONE;
622 : }
623 :
624 : /************************************************************************/
625 : /* SetSpatialRef() */
626 : /************************************************************************/
627 :
628 1 : void OGRGeoconceptLayer::SetSpatialRef(OGRSpatialReference *poSpatialRef)
629 :
630 : {
631 1 : OGRSpatialReference *poSRS = GetSpatialRef();
632 : /*-----------------------------------------------------------------
633 : * Keep a copy of the OGRSpatialReference...
634 : * Note: we have to take the reference count into account...
635 : *----------------------------------------------------------------*/
636 1 : if (poSRS && poSRS->Dereference() == 0)
637 0 : delete poSRS;
638 :
639 1 : if (!poSpatialRef)
640 0 : return;
641 :
642 1 : poSRS = poSpatialRef->Clone();
643 1 : poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
644 1 : GCExportFileH *hGXT = GetSubTypeGCHandle_GCIO(_gcFeature);
645 1 : if (!hGXT)
646 : {
647 0 : delete poSRS;
648 0 : return;
649 : }
650 1 : GCExportFileMetadata *Meta = GetGCMeta_GCIO(hGXT);
651 1 : if (!Meta)
652 : {
653 0 : delete poSRS;
654 0 : return;
655 : }
656 1 : GCSysCoord *os = GetMetaSysCoord_GCIO(Meta);
657 1 : GCSysCoord *ns = OGRSpatialReference2SysCoord_GCSRS(
658 1 : reinterpret_cast<OGRSpatialReferenceH>(poSRS));
659 :
660 1 : if (os && ns && GetSysCoordSystemID_GCSRS(os) != -1 &&
661 0 : (GetSysCoordSystemID_GCSRS(os) != GetSysCoordSystemID_GCSRS(ns) ||
662 0 : GetSysCoordTimeZone_GCSRS(os) != GetSysCoordTimeZone_GCSRS(ns)))
663 : {
664 0 : CPLError(CE_Warning, CPLE_AppDefined,
665 : "Can't change SRS on Geoconcept layers.\n");
666 0 : DestroySysCoord_GCSRS(&ns);
667 0 : delete poSRS;
668 0 : return;
669 : }
670 :
671 1 : if (os)
672 0 : DestroySysCoord_GCSRS(&os);
673 1 : SetMetaSysCoord_GCIO(Meta, ns);
674 1 : SetMetaSRS_GCIO(Meta, (OGRSpatialReferenceH)poSRS);
675 1 : return;
676 : }
|