OGRLayer *OGRGeoconceptDataSource::CreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS /* = NULL */, OGRwkbGeometryType eType /* = wkbUnknown */, char ** papszOptions /* = NULL */ ) { GCTypeKind gcioFeaType; GCDim gcioDim; OGRGeoconceptLayer *poFile= NULL; const char *pszFeatureType; char **ft; int iLayer; char pszln[512]; if( _hGXT == NULL ) { CPLError( CE_Failure, CPLE_NotSupported, "Internal Error : null datasource handler." ); return NULL; } if( poSRS == NULL && !_bUpdate) { CPLError( CE_Failure, CPLE_NotSupported, "SRS is mandatory of creating a Geoconcept Layer." ); return NULL; } /* * pszLayerName Class.Subclass if -nln option used, otherwise file name */ if( !(pszFeatureType = CSLFetchNameValue(papszOptions,"FEATURETYPE")) ) { if( !pszLayerName || !strchr(pszLayerName,'.') ) { snprintf(pszln,511,"%s.%s", pszLayerName? pszLayerName:"ANONCLASS", pszLayerName? pszLayerName:"ANONSUBCLASS"); pszln[511]= '\0'; pszFeatureType= pszln; } else pszFeatureType= pszLayerName; } if( !(ft= CSLTokenizeString2(pszFeatureType,".",0)) || CSLCount(ft)!=2 ) { CSLDestroy(ft); CPLError( CE_Failure, CPLE_AppDefined, "Feature type name '%s' is incorrect." "Correct syntax is : Class.Subclass.", pszFeatureType ); return NULL; } /* -------------------------------------------------------------------- */ /* Figure out what type of layer we need. */ /* -------------------------------------------------------------------- */ gcioDim= v2D_GCIO; if( eType == wkbUnknown ) gcioFeaType = vUnknownItemType_GCIO; else if( eType == wkbPoint ) gcioFeaType = vPoint_GCIO; else if( eType == wkbLineString ) gcioFeaType = vLine_GCIO; else if( eType == wkbPolygon ) gcioFeaType = vPoly_GCIO; else if( eType == wkbMultiPoint ) gcioFeaType = vPoint_GCIO; else if( eType == wkbMultiLineString ) gcioFeaType = vLine_GCIO; else if( eType == wkbMultiPolygon ) gcioFeaType = vPoly_GCIO; else if( eType == wkbPoint25D ) { gcioFeaType = vPoint_GCIO; gcioDim= v3DM_GCIO; } else if( eType == wkbLineString25D ) { gcioFeaType = vLine_GCIO; gcioDim= v3DM_GCIO; } else if( eType == wkbPolygon25D ) { gcioFeaType = vPoly_GCIO; gcioDim= v3DM_GCIO; } else if( eType == wkbMultiPoint25D ) { gcioFeaType = vPoint_GCIO; gcioDim= v3DM_GCIO; } else if( eType == wkbMultiLineString25D ) { gcioFeaType = vLine_GCIO; gcioDim= v3DM_GCIO; } else if( eType == wkbMultiPolygon25D ) { gcioFeaType = vPoly_GCIO; gcioDim= v3DM_GCIO; } else { CSLDestroy(ft); CPLError( CE_Failure, CPLE_NotSupported, "Geometry type of '%s' not supported in Geoconcept files.", OGRGeometryTypeToName(eType) ); return NULL; } /* * As long as we use the CONFIG, creating a layer implies the * layer name to exist in the CONFIG as "Class.Subclass". * Removing the CONFIG, implies on-the-fly-creation of layers... */ if( _nLayers > 0 ) for( iLayer= 0; iLayer<_nLayers; iLayer++) { poFile= (OGRGeoconceptLayer*)GetLayer(iLayer); if( EQUAL(poFile->GetLayerDefn()->GetName(),pszFeatureType) ) { break; } poFile= NULL; } if( !poFile ) { GCSubType* aSubclass= NULL; GCExportFileMetadata* m; if( !(m= GetGCMeta_GCIO(_hGXT)) ) { if( !(m= CreateHeader_GCIO()) ) { CSLDestroy(ft); return NULL; } SetMetaExtent_GCIO(m, CreateExtent_GCIO(HUGE_VAL,HUGE_VAL,-HUGE_VAL,-HUGE_VAL)); SetGCMeta_GCIO(_hGXT, m); } if( FindFeature_GCIO(_hGXT, pszFeatureType) ) { CSLDestroy(ft); CPLError( CE_Failure, CPLE_AppDefined, "Layer '%s' already exists.", pszFeatureType ); return NULL; } if( !AddType_GCIO(_hGXT, ft[0], -1L) ) { CSLDestroy(ft); CPLError( CE_Failure, CPLE_AppDefined, "Failed to add layer '%s'.", pszFeatureType ); return NULL; } if( !(aSubclass= AddSubType_GCIO(_hGXT, ft[0], ft[1], -1L, gcioFeaType, gcioDim)) ) { CSLDestroy(ft); CPLError( CE_Failure, CPLE_AppDefined, "Failed to add layer '%s'.", pszFeatureType ); return NULL; } /* complete feature type with private fields : */ AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kIdentifier_GCIO, -100, vIntFld_GCIO, NULL, NULL); AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kClass_GCIO, -101, vMemoFld_GCIO, NULL, NULL); AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kSubclass_GCIO, -102, vMemoFld_GCIO, NULL, NULL); AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kName_GCIO, -103, vMemoFld_GCIO, NULL, NULL); AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kNbFields_GCIO, -104, vIntFld_GCIO, NULL, NULL); AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kX_GCIO, -105, vRealFld_GCIO, NULL, NULL); AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kY_GCIO, -106, vRealFld_GCIO, NULL, NULL); /* user's fields will be added with Layer->CreateField() method ... */ switch( gcioFeaType ) { case vPoint_GCIO : break; case vLine_GCIO : AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kXP_GCIO, -107, vRealFld_GCIO, NULL, NULL); AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kYP_GCIO, -108, vRealFld_GCIO, NULL, NULL); AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kGraphics_GCIO, -109, vUnknownItemType_GCIO, NULL, NULL); break; default : AddSubTypeField_GCIO(_hGXT, ft[0], ft[1], -1L, kGraphics_GCIO, -109, vUnknownItemType_GCIO, NULL, NULL); break; } SetSubTypeGCHandle_GCIO(aSubclass,_hGXT); /* Add layer to data source layers list */ poFile = new OGRGeoconceptLayer; if( poFile->Open(aSubclass) != OGRERR_NONE ) { CSLDestroy(ft); delete poFile; return NULL; } _papoLayers = (OGRGeoconceptLayer **) CPLRealloc( _papoLayers, sizeof(OGRGeoconceptLayer *) * (_nLayers+1) ); _papoLayers[_nLayers++] = poFile; CPLDebug("GEOCONCEPT", "nLayers=%d - last=[%s]", _nLayers, poFile->GetLayerDefn()->GetName()); } CSLDestroy(ft); /* -------------------------------------------------------------------- */ /* Assign the coordinate system (if provided) */ /* -------------------------------------------------------------------- */ if( poSRS != NULL ) poFile->SetSpatialRef( poSRS ); return poFile; }
OGRErr OGRGeoconceptLayer::CreateField( OGRFieldDefn *poField, int bApproxOK ) { if( GetGCMode_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature))==vReadAccess_GCIO ) { CPLError( CE_Failure, CPLE_NotSupported, "Can't create fields on a read-only Geoconcept layer.\n"); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Add field to layer */ /* -------------------------------------------------------------------- */ { /* check whether field exists ... */ GCField* theField; char* pszName = OGRGeoconceptLayer_GetCompatibleFieldName(poField->GetNameRef()); if( !(theField= FindFeatureField_GCIO(_gcFeature,pszName)) ) { if( GetFeatureCount(TRUE) > 0 ) { CPLError( CE_Failure, CPLE_NotSupported, "Can't create field '%s' on existing Geoconcept layer '%s.%s'.\n", pszName, GetSubTypeName_GCIO(_gcFeature), GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)) ); CPLFree(pszName); return OGRERR_FAILURE; } if( GetSubTypeNbFields_GCIO(_gcFeature)==-1) SetSubTypeNbFields_GCIO(_gcFeature, 0L); if( !(theField= AddSubTypeField_GCIO(GetSubTypeGCHandle_GCIO(_gcFeature), GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)), GetSubTypeName_GCIO(_gcFeature), FindFeatureFieldIndex_GCIO(_gcFeature,kNbFields_GCIO) +GetSubTypeNbFields_GCIO(_gcFeature)+1L, pszName, GetSubTypeNbFields_GCIO(_gcFeature)-999L, vUnknownItemType_GCIO, NULL, NULL)) ) { CPLError( CE_Failure, CPLE_AppDefined, "Field '%s' could not be created for Feature %s.%s.\n", pszName, GetSubTypeName_GCIO(_gcFeature), GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)) ); CPLFree(pszName); return OGRERR_FAILURE; } SetSubTypeNbFields_GCIO(_gcFeature, GetSubTypeNbFields_GCIO(_gcFeature)+1L); _poFeatureDefn->AddFieldDefn(poField); } else { if( _poFeatureDefn->GetFieldIndex(GetFieldName_GCIO(theField))==-1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Field %s not found for Feature %s.%s.\n", GetFieldName_GCIO(theField), GetSubTypeName_GCIO(_gcFeature), GetTypeName_GCIO(GetSubTypeType_GCIO(_gcFeature)) ); CPLFree(pszName); return OGRERR_FAILURE; } } CPLFree(pszName); pszName = NULL; /* check/update type ? */ if( GetFieldKind_GCIO(theField)==vUnknownItemType_GCIO ) { switch(poField->GetType()) { case OFTInteger : SetFieldKind_GCIO(theField,vIntFld_GCIO); break; case OFTReal : SetFieldKind_GCIO(theField,vRealFld_GCIO); break; case OFTDate : SetFieldKind_GCIO(theField,vDateFld_GCIO); break; case OFTTime : case OFTDateTime : SetFieldKind_GCIO(theField,vTimeFld_GCIO); break; case OFTString : SetFieldKind_GCIO(theField,vMemoFld_GCIO); break; case OFTIntegerList : case OFTRealList : case OFTStringList : case OFTBinary : default : CPLError( CE_Failure, CPLE_NotSupported, "Can't create fields of type %s on Geoconcept feature %s.\n", OGRFieldDefn::GetFieldTypeName(poField->GetType()), _poFeatureDefn->GetName() ); return OGRERR_FAILURE; } } } return OGRERR_NONE; }