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;
}
Esempio n. 2
0
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;
}