OGRFeatureDefn *OGRLayerWithTransaction::GetLayerDefn()
{
    if( !m_poDecoratedLayer )
    {
        if( m_poFeatureDefn == NULL )
        {
            m_poFeatureDefn = new OGRFeatureDefn(GetDescription());
            m_poFeatureDefn->Reference();
        }
        return m_poFeatureDefn;
    }
    else if( m_poFeatureDefn == NULL )
    {
        OGRFeatureDefn* poSrcFeatureDefn = m_poDecoratedLayer->GetLayerDefn();
        m_poFeatureDefn = poSrcFeatureDefn->Clone();
        m_poFeatureDefn->Reference();
    }
    return m_poFeatureDefn;
}
예제 #2
0
OGRLayer *OGRSOSIDataSource::ICreateLayer( const char *pszNameIn,
                                           OGRSpatialReference  *poSpatialRef,
                                           OGRwkbGeometryType eGType,
                                           CPL_UNUSED char **papszOptions ) {
    /* SOSI does not really support layers - so let's first see that the global settings are consistent */
    if (poSRS == NULL) {
        if (poSpatialRef!=NULL) {
            poSRS = poSpatialRef;
            poSRS->Reference();

            const char *pszKoosys = poSRS->GetAuthorityCode("PROJCS");
            if (pszKoosys == NULL) {
                OGRErr err = poSRS->AutoIdentifyEPSG();
                if (err == OGRERR_UNSUPPORTED_SRS) {
                    CPLError( CE_Failure, CPLE_OpenFailed,
                        "Could not identify EPSG code for spatial reference system");
                    return NULL;
                }
                pszKoosys = poSRS->GetAuthorityCode("PROJCS");
            }

            if (pszKoosys != NULL) {
                int nKoosys = epsg2sosi(atoi(pszKoosys));
                CPLDebug( "[CreateLayer]","Projection set to SOSI %i", nKoosys);
                LC_PutTrans(nKoosys,0,0,0.01,0.01,0.01);
            } else {
                pszKoosys = poSRS->GetAuthorityCode("GEOGCS");
                if (pszKoosys != NULL) {
                    int nKoosys = epsg2sosi(atoi(pszKoosys));
                   LC_PutTrans(nKoosys,0,0,0.01,0.01,0.01);
                } else {
                    CPLError( CE_Failure, CPLE_OpenFailed,
                        "Could not retrieve EPSG code for spatial reference system");
                    return NULL;
                }
            }
        }
        LC_WsGr(poFileadm); /* Writing the header here! */

    } else {
        if (!poSRS->IsSame(poSpatialRef)) {
          CPLError( CE_Failure, CPLE_AppDefined,
                    "SOSI driver does not support different spatial reference systems in one file.");
        }
    }

    OGRFeatureDefn *poFeatureDefn = new OGRFeatureDefn( pszNameIn );
    poFeatureDefn->Reference();
    poFeatureDefn->SetGeomType( eGType );
    OGRSOSILayer *poLayer = new OGRSOSILayer( this, poFeatureDefn, poFileadm, NULL /*poHeaderDefn*/);
    /* todo: where do we delete poLayer and poFeatureDefn? */
    return poLayer;
}
예제 #3
0
JNIEXPORT jint JNICALL Java_es_gva_cit_jogr_JNIBase_referenceFeatureDefnNat
  (JNIEnv *env, jobject obj, jlong cPtr){
  
  	  OGRFeatureDefn 	*fd = (OGRFeatureDefn *) 0 ;
  	  int 				res=-1;
  	  
	  fd = *(OGRFeatureDefn **)&cPtr;
	  if(fd!=NULL){
	  	res = fd->Reference();
	  }
	  return res;
  }
예제 #4
0
OGRFeatureDefn *S57GenerateGeomFeatureDefn( OGRwkbGeometryType eGType,
                                            int nOptionFlags )

{
    OGRFeatureDefn      *poFDefn = NULL;
    
    if( eGType == wkbPoint )                                            
    {
        poFDefn = new OGRFeatureDefn( "Point" );
        poFDefn->SetGeomType( eGType );
    }
    else if( eGType == wkbLineString )
    {
        poFDefn = new OGRFeatureDefn( "Line" );
        poFDefn->SetGeomType( eGType );
    }
    else if( eGType == wkbPolygon )
    {
        poFDefn = new OGRFeatureDefn( "Area" );
        poFDefn->SetGeomType( eGType );
    }
    else if( eGType == wkbNone )
    {
        poFDefn = new OGRFeatureDefn( "Meta" );
        poFDefn->SetGeomType( eGType );
    }
    else if( eGType == wkbUnknown )
    {
        poFDefn = new OGRFeatureDefn( "Generic" );
        poFDefn->SetGeomType( eGType );
    }
    else
        return NULL;

    poFDefn->Reference();
    S57GenerateStandardAttributes( poFDefn, nOptionFlags );

    return poFDefn;
}
예제 #5
0
OGRLayer * OGRCouchDBDataSource::ExecuteSQLStats( const char *pszSQLCommand )
{
    swq_select sSelectInfo;
    if( sSelectInfo.preparse( pszSQLCommand ) != CE_None )
    {
        return NULL;
    }

    if (sSelectInfo.table_count != 1)
    {
        return NULL;
    }

    swq_table_def *psTableDef = &sSelectInfo.table_defs[0];
    if( psTableDef->data_source != NULL )
    {
        return NULL;
    }

    OGRCouchDBLayer* _poSrcLayer =
        (OGRCouchDBLayer* )GetLayerByName( psTableDef->table_name );
    if (_poSrcLayer == NULL)
    {
        return NULL;
    }
    if (_poSrcLayer->GetLayerType() != COUCHDB_TABLE_LAYER)
        return NULL;

    OGRCouchDBTableLayer* poSrcLayer = (OGRCouchDBTableLayer* ) _poSrcLayer;

    int nFieldCount = poSrcLayer->GetLayerDefn()->GetFieldCount();

    swq_field_list sFieldList;
    memset( &sFieldList, 0, sizeof(sFieldList) );
    sFieldList.table_count = sSelectInfo.table_count;
    sFieldList.table_defs = sSelectInfo.table_defs;

    sFieldList.count = 0;
    sFieldList.names = static_cast<char **>(
        CPLMalloc( sizeof(char *) * nFieldCount ));
    sFieldList.types = static_cast<swq_field_type *>(
        CPLMalloc( sizeof(swq_field_type) * nFieldCount ));
    sFieldList.table_ids = static_cast<int *>(
        CPLMalloc( sizeof(int) * nFieldCount ));
    sFieldList.ids = static_cast<int *>(
        CPLMalloc( sizeof(int) * nFieldCount ));

    PointerAutoFree oHolderNames(sFieldList.names);
    PointerAutoFree oHolderTypes(sFieldList.types);
    PointerAutoFree oHolderTableIds(sFieldList.table_ids);
    PointerAutoFree oHolderIds(sFieldList.ids);

    for( int iField = 0;
         iField < poSrcLayer->GetLayerDefn()->GetFieldCount();
         iField++ )
    {
        OGRFieldDefn *poFDefn=poSrcLayer->GetLayerDefn()->GetFieldDefn(iField);
        int iOutField = sFieldList.count++;
        sFieldList.names[iOutField] = (char *) poFDefn->GetNameRef();
        if( poFDefn->GetType() == OFTInteger )
            sFieldList.types[iOutField] = SWQ_INTEGER;
        else if( poFDefn->GetType() == OFTReal )
            sFieldList.types[iOutField] = SWQ_FLOAT;
        else if( poFDefn->GetType() == OFTString )
            sFieldList.types[iOutField] = SWQ_STRING;
        else
            sFieldList.types[iOutField] = SWQ_OTHER;

        sFieldList.table_ids[iOutField] = 0;
        sFieldList.ids[iOutField] = iField;
    }

    CPLString osLastFieldName;
    for( int iField = 0; iField < sSelectInfo.result_columns; iField++ )
    {
        swq_col_def *psColDef = sSelectInfo.column_defs + iField;
        if (psColDef->field_name == NULL)
            return NULL;

        if (strcmp(psColDef->field_name, "*") != 0)
        {
            if (osLastFieldName.empty())
                osLastFieldName = psColDef->field_name;
            else if (strcmp(osLastFieldName, psColDef->field_name) != 0)
                return NULL;

            if (poSrcLayer->GetLayerDefn()->GetFieldIndex(psColDef->field_name) == -1)
                return NULL;
        }

        if (!(psColDef->col_func == SWQCF_AVG ||
              psColDef->col_func == SWQCF_MIN ||
              psColDef->col_func == SWQCF_MAX ||
              psColDef->col_func == SWQCF_COUNT ||
              psColDef->col_func == SWQCF_SUM))
            return NULL;

        if (psColDef->distinct_flag) /* TODO: could perhaps be relaxed */
            return NULL;
    }

    if (osLastFieldName.empty())
        return NULL;

    /* Normalize field name */
    int nIndex = poSrcLayer->GetLayerDefn()->GetFieldIndex(osLastFieldName);
    osLastFieldName = poSrcLayer->GetLayerDefn()->GetFieldDefn(nIndex)->GetNameRef();

/* -------------------------------------------------------------------- */
/*      Finish the parse operation.                                     */
/* -------------------------------------------------------------------- */

    if( sSelectInfo.parse( &sFieldList, NULL ) != CE_None )
    {
        return NULL;
    }

    if (sSelectInfo.join_defs != NULL ||
        sSelectInfo.where_expr != NULL ||
        sSelectInfo.order_defs != NULL ||
        sSelectInfo.query_mode != SWQM_SUMMARY_RECORD)
    {
        return NULL;
    }

    for( int iField = 0; iField < sSelectInfo.result_columns; iField++ )
    {
        swq_col_def *psColDef = sSelectInfo.column_defs + iField;
        if (psColDef->field_index == -1)
        {
            if (psColDef->col_func == SWQCF_COUNT)
                continue;

            return NULL;
        }
        if (psColDef->field_type != SWQ_INTEGER &&
            psColDef->field_type != SWQ_FLOAT)
        {
            return NULL;
        }
    }

    const bool bFoundFilter = CPL_TO_BOOL(
        poSrcLayer->HasFilterOnFieldOrCreateIfNecessary(osLastFieldName));
    if( !bFoundFilter )
        return NULL;

    CPLString osURI = "/";
    osURI += poSrcLayer->GetName();
    osURI += "/_design/ogr_filter_";
    osURI += osLastFieldName;
    osURI += "/_view/filter?reduce=true";

    json_object* poAnswerObj = GET(osURI);
    json_object* poRows = NULL;
    if (!(poAnswerObj != NULL &&
          json_object_is_type(poAnswerObj, json_type_object) &&
          (poRows = CPL_json_object_object_get(poAnswerObj, "rows")) != NULL &&
          json_object_is_type(poRows, json_type_array)))
    {
        json_object_put(poAnswerObj);
        return NULL;
    }

    int nLength = json_object_array_length(poRows);
    if (nLength != 1)
    {
        json_object_put(poAnswerObj);
        return NULL;
    }

    json_object* poRow = json_object_array_get_idx(poRows, 0);
    if (!(poRow && json_object_is_type(poRow, json_type_object)))
    {
        json_object_put(poAnswerObj);
        return NULL;
    }

    json_object* poValue = CPL_json_object_object_get(poRow, "value");
    if (!(poValue != NULL && json_object_is_type(poValue, json_type_object)))
    {
        json_object_put(poAnswerObj);
        return NULL;
    }

    json_object* poSum = CPL_json_object_object_get(poValue, "sum");
    json_object* poCount = CPL_json_object_object_get(poValue, "count");
    json_object* poMin = CPL_json_object_object_get(poValue, "min");
    json_object* poMax = CPL_json_object_object_get(poValue, "max");
    if (poSum != NULL && (json_object_is_type(poSum, json_type_int) ||
                            json_object_is_type(poSum, json_type_double)) &&
        poCount != NULL && (json_object_is_type(poCount, json_type_int) ||
                            json_object_is_type(poCount, json_type_double)) &&
        poMin != NULL && (json_object_is_type(poMin, json_type_int) ||
                            json_object_is_type(poMin, json_type_double)) &&
        poMax != NULL && (json_object_is_type(poMax, json_type_int) ||
                            json_object_is_type(poMax, json_type_double)) )
    {
        double dfSum = json_object_get_double(poSum);
        int nCount = json_object_get_int(poCount);
        double dfMin = json_object_get_double(poMin);
        double dfMax = json_object_get_double(poMax);
        json_object_put(poAnswerObj);

        //CPLDebug("CouchDB", "sum=%f, count=%d, min=%f, max=%f",
        //         dfSum, nCount, dfMin, dfMax);

        OGRFeatureDefn* poFeatureDefn = new OGRFeatureDefn(poSrcLayer->GetName());
        poFeatureDefn->Reference();

        for( int iField = 0; iField < sSelectInfo.result_columns; iField++ )
        {
            swq_col_def *psColDef = sSelectInfo.column_defs + iField;
            OGRFieldDefn oFDefn( "", OFTInteger );

            if( psColDef->field_alias != NULL )
            {
                oFDefn.SetName(psColDef->field_alias);
            }
            else
            {
                const swq_operation *op = swq_op_registrar::GetOperator(
                    (swq_op) psColDef->col_func );
                oFDefn.SetName( CPLSPrintf( "%s_%s",
                                            op->pszName,
                                            psColDef->field_name ) );
            }

            if( psColDef->col_func == SWQCF_COUNT )
                oFDefn.SetType( OFTInteger );
            else if (psColDef->field_type == SWQ_INTEGER)
                oFDefn.SetType( OFTInteger );
            else if (psColDef->field_type == SWQ_FLOAT)
                oFDefn.SetType( OFTReal );

            poFeatureDefn->AddFieldDefn(&oFDefn);
        }

        OGRFeature* poFeature = new OGRFeature(poFeatureDefn);

        for( int iField = 0; iField < sSelectInfo.result_columns; iField++ )
        {
            swq_col_def *psColDef = sSelectInfo.column_defs + iField;
            switch(psColDef->col_func)
            {
                case SWQCF_AVG:
                    if (nCount)
                        poFeature->SetField(iField, dfSum / nCount);
                    break;
                case SWQCF_MIN:
                    poFeature->SetField(iField, dfMin);
                    break;
                case SWQCF_MAX:
                    poFeature->SetField(iField, dfMax);
                    break;
                case SWQCF_COUNT:
                    poFeature->SetField(iField, nCount);
                    break;
                case SWQCF_SUM:
                    poFeature->SetField(iField, dfSum);
                    break;
                default:
                    break;
            }
        }

        poFeature->SetFID(0);

        OGRCouchDBOneLineLayer* poAnswerLayer = new OGRCouchDBOneLineLayer();
        poAnswerLayer->poFeatureDefn = poFeatureDefn;
        poAnswerLayer->poFeature = poFeature;
        return poAnswerLayer;
    }
    json_object_put(poAnswerObj);

    return NULL;
}
예제 #6
0
OGRFeatureDefn *OGRIngresTableLayer::ReadTableDefinition( const char *pszTable )

{
    poDS->EstablishActiveLayer( NULL );

/* -------------------------------------------------------------------- */
/*      Fire off commands to get back the schema of the table.          */
/* -------------------------------------------------------------------- */
    CPLString osCommand;
    OGRIngresStatement oStatement( poDS->GetConn() );

    osCommand.Printf( "select column_name, column_datatype, column_length, "
                      "column_scale, column_ingdatatype, "
                      "column_internal_datatype "
                      "from iicolumns where table_name = '%s'", 
                      pszTable );

    if( !oStatement.ExecuteSQL( osCommand ) )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable );
    char           **papszRow;

    poDefn->Reference();
    poDefn->SetGeomType( wkbNone );

    while( (papszRow = oStatement.GetRow()) != NULL )
    {
        CPLString       osFieldName = papszRow[0];
        CPLString       osIngresType = papszRow[1];
        CPLString       osInternalType = papszRow[5];
        GInt32          nWidth, nScale;

        osIngresType.Trim();
        osFieldName.Trim();
        osInternalType.Trim();

        memcpy( &nWidth, papszRow[2], 4 );
        memcpy( &nScale, papszRow[3], 4 );

        OGRFieldDefn    oField(osFieldName, OFTString);

        if( osGeomColumn.size() == 0
            && (EQUAL(osInternalType,"POINT")
                || EQUAL(osInternalType,"IPOINT")
                || EQUAL(osInternalType,"BOX")
                || EQUAL(osInternalType,"IBOX")
                || EQUAL(osInternalType,"LSEG")
                || EQUAL(osInternalType,"ILSEG")
                || EQUAL(osInternalType,"LINE")
                || EQUAL(osInternalType,"ILINE")
                || EQUAL(osInternalType,"LONG LINE")
                || EQUAL(osInternalType,"POLYGON")
                || EQUAL(osInternalType,"IPOLYGON")
                || EQUAL(osInternalType,"LONG POLYGON")
                || EQUAL(osInternalType,"CIRCLE")
                || EQUAL(osInternalType,"LINESTRING")
                || EQUAL(osInternalType,"MULTIPOINT")
                || EQUAL(osInternalType,"MULTIPOLYGON")
                || EQUAL(osInternalType,"MULTILINESTRING")
                || EQUAL(osInternalType,"GEOMETRYCOLLECTION")
                || EQUAL(osInternalType,"ICIRCLE")) )
        {
            osGeomColumn = osFieldName;
            osIngresGeomType = osInternalType;
            
            if( strstr(osInternalType,"POINT") )
                poDefn->SetGeomType( wkbPoint );
            else if( strstr(osInternalType,"LINE")
                     || strstr(osInternalType,"SEG")
                     || strstr(osInternalType, "LINESTRING"))
                poDefn->SetGeomType( wkbLineString );
            else if( strstr(osInternalType,"MULTIPOINT"))
            	poDefn->SetGeomType(wkbMultiPoint);
            else if( strstr(osInternalType,"MULTIPOLYGON"))
            	poDefn->SetGeomType(wkbMultiPolygon);
            else if( strstr(osInternalType,"MULTILINESTRING"))
            	poDefn->SetGeomType(wkbMultiLineString);
            // Oddly this is the standin for a generic geometry type.
            else if( strstr(osInternalType,"GEOMETRYCOLLECTION"))
            	poDefn->SetGeomType(wkbUnknown);
            else
                poDefn->SetGeomType( wkbPolygon );
            continue;
        }
        else if( EQUALN(osIngresType,"byte",4) 
            || EQUALN(osIngresType,"long byte",9) )
        {
            oField.SetType( OFTBinary );
        }
        else if( EQUALN(osIngresType,"varchar",7) 
                 || EQUAL(osIngresType,"text") 
                 || EQUALN(osIngresType,"long varchar",12) )
        {
            oField.SetType( OFTString );
            oField.SetWidth( nWidth );
        }
        else if( EQUALN(osIngresType,"char",4) || EQUAL(osIngresType,"c") )
        {
            oField.SetType( OFTString );
            oField.SetWidth( nWidth );
        }
        else if( EQUAL(osIngresType,"integer") )
        {
            oField.SetType( OFTInteger );
        }
        else if( EQUALN(osIngresType,"decimal", 7) )
        {
            if( nScale != 0 )
            {
                oField.SetType( OFTReal );
                oField.SetPrecision( nScale );
                oField.SetWidth( nWidth );
            }
            else
            {
                oField.SetType( OFTInteger );
                oField.SetWidth( nWidth );
            }
        }
        else if( EQUALN(osIngresType,"float", 5) )
        {
            oField.SetType( OFTReal );
        }
#ifdef notdef
        else if( EQUAL(osIngresType,"date") 
                 || EQUAL(osIngresType,"ansidate") 
                 || EQUAL(osIngresType,"ingresdate") )
        {
            oField.SetType( OFTDate );
        }
#endif

        // Is this an integer primary key field?
        if( osFIDColumn.size() == 0 
            && oField.GetType() == OFTInteger 
            && EQUAL(oField.GetNameRef(),"ogr_fid") )
        {
            osFIDColumn = oField.GetNameRef();
            continue;
        }

        poDefn->AddFieldDefn( &oField );
    }

    if( osFIDColumn.size() )
        CPLDebug( "Ingres", "table %s has FID column %s.",
                  pszTable, osFIDColumn.c_str() );
    else
        CPLDebug( "Ingres", 
                  "table %s has no FID column, FIDs will not be reliable!",
                  pszTable );

    //We must close the current statement before calling this or else
    //The query within FetchSRSId will fail
    oStatement.Close();

    // Fetch the SRID for this table now
    // But only if it's the new Ingres Geospatial
    if(poDS->IsNewIngres() == TRUE)
        nSRSId = FetchSRSId(poDefn);

    return poDefn;
}
예제 #7
0
int  OGRSOSIDataSource::Open( const char *pszFilename, int bUpdate ) {
    papoBuiltGeometries = NULL;
    poFileadm = NULL;
    poBaseadm = NULL;
    char *pszPos;

    if ( bUpdate ) {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "Update access not supported by the SOSI driver." );
        return FALSE;
    }

    /* Check that the file exists otherwise HO_TestSOSI() emits an error */
    VSIStatBuf sStat;
    if( VSIStat(pszFilename, &sStat) != 0 )
        return FALSE;

    pszName = CPLStrdup( pszFilename );
    /* We ignore any layer parameters for now. */
    pszPos = strchr(pszName, ',');
    if (pszPos != NULL) {
        pszPos[0] = '\0';
    }

    /* Confirm that we are dealing with a SOSI file. Used also by data
     * format auto-detection in some ogr utilities. */
    UT_INT64 nEnd = 0;
    int bIsSosi = HO_TestSOSI ( pszName, &nEnd );
    if ( bIsSosi == UT_FALSE ) {
        return FALSE; /* No error message: This is used by file format auto-detection */
    }

    short nStatus = 0, nDetStatus = 0; /* immediate status, detailed status */

    /* open index base and sosi file */
    poBaseadm = LC_OpenBase(LC_BASE);
    nStatus   = LC_OpenSos(pszName, LC_BASE_FRAMGR, LC_GML_IDX, LC_INGEN_STATUS,
                           &poFileadm, &nDetStatus);
    if ( nStatus == UT_FALSE ) {
        char *pszErrorMessage;
        LC_StrError(nDetStatus, &pszErrorMessage);
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "File %s could not be opened by SOSI Driver: %s", pszName, pszErrorMessage );
        return FALSE;
    }

    /* --------------------------------------------------------------------*
     *      Prefetch all the information needed to determine layers        *
     * 	    and prebuild LineString features for later assembly.           *
     * --------------------------------------------------------------------*/

    /* allocate room for one pointer per feature */
    nNumFeatures = static_cast<unsigned int>(poFileadm->lAntGr);
    void* mem = VSI_MALLOC2_VERBOSE(nNumFeatures, sizeof(void*));
    if (mem == NULL) {
        return FALSE;
    } else {
        papoBuiltGeometries = (OGRGeometry**)mem;
    }
    for (unsigned int i=0; i<nNumFeatures; i++) papoBuiltGeometries[i] = NULL;

    /* Various iterators and return values used to iterate through SOSI features */
    short          nName, nNumLines;
    long           nNumCoo;
    unsigned short nInfo;
    LC_SNR_ADM	   oSnradm;
    LC_BGR		   oNextSerial;
    LC_BGR		  *poNextSerial;
    poNextSerial =&oNextSerial;

    bool bPointLayer = FALSE; /* Initialize four layers for the different geometry types */
    bool bCurveLayer = FALSE;
    bool bPolyLayer  = FALSE;
    bool bTextLayer  = FALSE;
    poPolyHeaders  = new S2I();
    poPointHeaders = new S2I();
    poCurveHeaders = new S2I();
    poTextHeaders  = new S2I();

    LC_SBSn(&oSnradm, poFileadm, 0, nNumFeatures); /* Set FYBA search limits  */
    LC_InitNextBgr(poNextSerial);

    /* Prebuilding simple features and extracting layer information. */
    while (LC_NextBgr(poNextSerial,LC_FRAMGR)) {
        /* Fetch next group information */
        nName = LC_RxGr(poNextSerial, LES_OPTIMALT, &nNumLines, &nNumCoo, &nInfo);

        S2S oHeaders;
        S2S::iterator iHeaders;
        int iH;
        /* Extract all strings from group header. */
        for (short i=1; i<=nNumLines; i++) {
            char *pszLine = LC_GetGi(i);      /* Get one header line */
            if ((pszLine[0] == ':')||(pszLine[0] == '(')) continue;  /* If we have a continued REF line, skip it. */
            if (pszLine[0] == '!') continue;  /* If we have a comment line, skip it. */

            char *pszUTFLine = CPLRecode(pszLine, pszEncoding, CPL_ENC_UTF8); /* switch to UTF encoding here, if it is known. */
            char *pszUTFLineIter = pszUTFLine;
            while (pszUTFLineIter[0] == '.') pszUTFLineIter++; /* Skipping the dots at the beginning of a SOSI line */
            char *pszPos2 = strstr(pszUTFLineIter, " "); /* Split header and value */
            if (pszPos2 != NULL) {
                CPLString osKey = CPLString(std::string(pszUTFLineIter,pszPos2)); /* FIXME: clean instantiation of CPLString? */
                CPLString osValue = CPLString(pszPos2+1);

                oHeaders[osKey]=osValue;          /* Add to header map */
                switch (nName) {             /* Add to header list for the corresponding layer, if it is not */
                case L_FLATE: {            /* in there already */
                    if (poPolyHeaders->find(osKey) == poPolyHeaders->end()) {
                        iH = static_cast<int>(poPolyHeaders->size());
                        (*poPolyHeaders)[osKey] = iH;
                    }
                    break;
                }
                case L_KURVE:  
                case L_LINJE:  
                case L_BUEP:  {    /* FIXME: maybe not use the same headers for both */
                    if (poCurveHeaders->find(osKey) == poCurveHeaders->end()) {
                        iH = static_cast<int>(poCurveHeaders->size());
                        (*poCurveHeaders)[osKey] = iH;
                    }
                    break;
                }
                case L_PUNKT: 
                case L_SYMBOL: {
                    if (poPointHeaders->find(osKey) == poPointHeaders->end()) {
                        iH = static_cast<int>(poPointHeaders->size());
                        (*poPointHeaders)[osKey] = iH;
                    }
                    break;
                }
                case L_TEKST: {
                    if (poTextHeaders->find(osKey) == poTextHeaders->end()) {
                        iH = static_cast<int>(poTextHeaders->size());
                        (*poTextHeaders)[osKey] = iH;
                    }
                    break;
                }
                }
            }
            CPLFree(pszUTFLine);
        }

        /* Feature-specific tasks */
        switch (nName) {
        case L_PUNKT: {
            /* Pre-build a point feature. Activate point layer. */
            bPointLayer = TRUE;
            buildOGRPoint(oNextSerial.lNr);
            break;
        }
        case L_FLATE: {
            /* Activate polygon layer. */
            bPolyLayer = TRUE;
            /* cannot build geometries that reference others yet */
            break;
        }
        case L_KURVE: 
        case L_LINJE: {
            /* Pre-build a line feature. Activate line/curve layer. */
            bCurveLayer = TRUE;
            buildOGRLineString(static_cast<int>(nNumCoo), oNextSerial.lNr);
            break;
        }
        case L_BUEP: {
            /* Pre-build a line feature as interpolation from an arc. Activate line/curve layer. */
            bCurveLayer = TRUE;
            buildOGRLineStringFromArc(oNextSerial.lNr);
            break;
        }
        case L_TEKST: {
            /* Pre-build a text line contour feature. Activate text layer. */
            /* Todo: observe only points 2ff if more than one point is given for follow mode */
            bTextLayer = TRUE;
            buildOGRMultiPoint(static_cast<int>(nNumCoo), oNextSerial.lNr);
            break;
        }
        case L_HODE: {
            /* Get SRS from SOSI header. */
            unsigned short nMask = LC_TR_ALLT;
            LC_TRANSPAR oTrans;
            if (LC_GetTransEx(&nMask,&oTrans) == UT_FALSE) {
                CPLError( CE_Failure, CPLE_OpenFailed,
                          "TRANSPAR section not found - No reference system information available.");
                return FALSE;
            }
            poSRS = new OGRSpatialReference();

            /* Get coordinate system from SOSI header. */
            int nEPSG = sosi2epsg(oTrans.sKoordsys);
            if (poSRS->importFromEPSG(nEPSG) != OGRERR_NONE) {
				CPLError( CE_Failure, CPLE_OpenFailed,
                          "OGR could not load coordinate system definition EPSG:%i.", nEPSG);
                return FALSE;
            }

            /* Get character encoding from SOSI header. */
            iHeaders = oHeaders.find("TEGNSETT");
            if (iHeaders != oHeaders.end()) {
                CPLString osLine = iHeaders->second;
                if (osLine.compare("ISO8859-1")==0) {
                    pszEncoding = CPL_ENC_ISO8859_1;
                } else if (osLine.compare("ISO8859-10")==0) {
                    pszEncoding = CPL_ENC_ISO8859_10;
                } else if (osLine.compare("UTF-8")==0) {
                    pszEncoding = CPL_ENC_UTF8;
                }
            }

            break;
        }
        default: {
            break;
        }
        }
    }

    /* -------------------------------------------------------------------- *
     *      Create a corresponding layers. One per geometry type            *
     * -------------------------------------------------------------------- */
    int l_nLayers = 0;
    if (bPolyLayer)  l_nLayers++;
    if (bCurveLayer) l_nLayers++;
    if (bPointLayer) l_nLayers++;
    if (bTextLayer) l_nLayers++;
    this->nLayers = l_nLayers;
    /* allocate some memory for up to three layers */
    papoLayers = (OGRSOSILayer **) VSI_MALLOC2_VERBOSE(sizeof(void*), l_nLayers);
    if( papoLayers == NULL )
    {
        this->nLayers = 0;
        return FALSE;
    }

    /* Define each layer, using a proper feature definition, geometry type,
     * and adding every SOSI header encountered in the file as field. */
    S2I::iterator i;
    if (bPolyLayer) {
        S2I * poHeadersNew = new S2I();
		OGRFeatureDefn *poFeatureDefn = defineLayer("polygons", wkbPolygon, poPolyHeaders, &poHeadersNew);
        delete poPolyHeaders;
        poPolyHeaders = poHeadersNew;
        poFeatureDefn->Reference();
        papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poPolyHeaders );
    } else {
        delete poPolyHeaders;
        poPolyHeaders = NULL;
    }
    if (bCurveLayer) {
        S2I * poHeadersNew = new S2I();
        OGRFeatureDefn *poFeatureDefn = defineLayer("lines", wkbLineString, poCurveHeaders, &poHeadersNew);
        delete poCurveHeaders;
        poCurveHeaders = poHeadersNew;
        poFeatureDefn->Reference();
        papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poCurveHeaders );
    } else {
        delete poCurveHeaders;
        poCurveHeaders = NULL;
    }
    if (bPointLayer) {
        S2I * poHeadersNew = new S2I();
        OGRFeatureDefn *poFeatureDefn = defineLayer("points", wkbPoint, poPointHeaders, &poHeadersNew);
        delete poPointHeaders;
        poPointHeaders = poHeadersNew;
        poFeatureDefn->Reference();
        papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poPointHeaders );
    } else {
        delete poPointHeaders;
        poPointHeaders = NULL;
    }
    if (bTextLayer) {
        S2I * poHeadersNew = new S2I();
        OGRFeatureDefn *poFeatureDefn = defineLayer("text", wkbMultiPoint, poTextHeaders, &poHeadersNew);
        delete poTextHeaders;
        poTextHeaders = poHeadersNew;
        poFeatureDefn->Reference();
        papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poTextHeaders );
    } else {
        delete poTextHeaders;
        poTextHeaders = NULL;
    }
    return TRUE;
}
예제 #8
0
OGRFeatureDefn *S57GenerateDSIDFeatureDefn()

{
    OGRFeatureDefn      *poFDefn = new OGRFeatureDefn( "DSID" );
    OGRFieldDefn         oField( "", OFTInteger );

    poFDefn->SetGeomType( wkbNone );
    poFDefn->Reference();

/* -------------------------------------------------------------------- */
/*      DSID fields.                                                    */
/* -------------------------------------------------------------------- */
    oField.Set( "DSID_EXPP", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_INTU", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_DSNM", OFTString, 0, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_EDTN", OFTString, 0, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_UPDN", OFTString, 0, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_UADT", OFTString, 8, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_ISDT", OFTString, 8, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_STED", OFTReal, 11, 6 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_PRSP", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_PSDN", OFTString, 0, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_PRED", OFTString, 0, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_PROF", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_AGEN", OFTInteger, 5, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSID_COMT", OFTString, 0, 0 );
    poFDefn->AddFieldDefn( &oField );
    
/* -------------------------------------------------------------------- */
/*      DSSI fields.                                                    */
/* -------------------------------------------------------------------- */

    oField.Set( "DSSI_DSTR", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_AALL", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NALL", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NOMR", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NOCR", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NOGR", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NOLR", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NOIN", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NOCN", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NOED", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSSI_NOFA", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
/* -------------------------------------------------------------------- */
/*      DSPM fields.                                                    */
/* -------------------------------------------------------------------- */

    oField.Set( "DSPM_HDAT", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_VDAT", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_SDAT", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_CSCL", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_DUNI", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_HUNI", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_PUNI", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_COUN", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_COMF", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_SOMF", OFTInteger, 10, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    oField.Set( "DSPM_COMT", OFTString, 0, 0 );
    poFDefn->AddFieldDefn( &oField );
    
    return poFDefn;
}
예제 #9
0
OGRFeatureDefn *S57GenerateObjectClassDefn( S57ClassRegistrar *poCR,
                                            int nOBJL, int nOptionFlags )

{
    OGRFeatureDefn      *poFDefn = NULL;
    char               **papszGeomPrim;

    if( !poCR->SelectClass( nOBJL ) )
        return NULL;
    
/* -------------------------------------------------------------------- */
/*      Create the feature definition based on the object class         */
/*      acronym.                                                        */
/* -------------------------------------------------------------------- */
    poFDefn = new OGRFeatureDefn( poCR->GetAcronym() );
    poFDefn->Reference();

/* -------------------------------------------------------------------- */
/*      Try and establish the geometry type.  If more than one          */
/*      geometry type is allowed we just fall back to wkbUnknown.       */
/* -------------------------------------------------------------------- */
    papszGeomPrim = poCR->GetPrimitives();
    if( CSLCount(papszGeomPrim) == 0 )
    {
        poFDefn->SetGeomType( wkbNone );
    }
    else if( CSLCount(papszGeomPrim) > 1 )
    {
        // leave as unknown geometry type.
    }
    else if( papszGeomPrim[0][0] == 'P' )
    {
        if( EQUAL(poCR->GetAcronym(),"SOUNDG") )
        {
            if( nOptionFlags & S57M_SPLIT_MULTIPOINT )
                poFDefn->SetGeomType( wkbPoint25D );
            else
                poFDefn->SetGeomType( wkbMultiPoint25D );
        }
        else
            poFDefn->SetGeomType( wkbPoint );
    }
    else if( papszGeomPrim[0][0] == 'A' )
    {
        poFDefn->SetGeomType( wkbPolygon );
    }
    else if( papszGeomPrim[0][0] == 'L' )
    {
        // unfortunately this could be a multilinestring
        poFDefn->SetGeomType( wkbUnknown );
    }
    
/* -------------------------------------------------------------------- */
/*      Add the standard attributes.                                    */
/* -------------------------------------------------------------------- */
    S57GenerateStandardAttributes( poFDefn, nOptionFlags );

/* -------------------------------------------------------------------- */
/*      Add the attributes specific to this object class.               */
/* -------------------------------------------------------------------- */
    char        **papszAttrList = poCR->GetAttributeList();

    for( int iAttr = 0;
         papszAttrList != NULL && papszAttrList[iAttr] != NULL;
         iAttr++ )
    {
        int     iAttrIndex = poCR->FindAttrByAcronym( papszAttrList[iAttr] );

        if( iAttrIndex == -1 )
        {
            CPLDebug( "S57", "Can't find attribute %s from class %s:%s.",
                      papszAttrList[iAttr],
                      poCR->GetAcronym(),
                      poCR->GetDescription() );
            continue;
        }

        OGRFieldDefn    oField( papszAttrList[iAttr], OFTInteger );
        
        switch( poCR->GetAttrType( iAttrIndex ) )
        {
          case SAT_ENUM:
          case SAT_INT:
            oField.SetType( OFTInteger );
            break;

          case SAT_FLOAT:
            oField.SetType( OFTReal );
            break;

          case SAT_CODE_STRING:
          case SAT_FREE_TEXT:
            oField.SetType( OFTString );
            break;

          case SAT_LIST:
            oField.SetType( OFTString );
            break;
        }

        poFDefn->AddFieldDefn( &oField );
    }


/* -------------------------------------------------------------------- */
/*      Do we need to add DEPTH attributes to soundings?                */
/* -------------------------------------------------------------------- */
    if( EQUAL(poCR->GetAcronym(),"SOUNDG") 
        && (nOptionFlags & S57M_ADD_SOUNDG_DEPTH) )
    {
        OGRFieldDefn    oField( "DEPTH", OFTReal );
        poFDefn->AddFieldDefn( &oField );
    }

    return poFDefn;
}
예제 #10
0
OGRFeatureDefn *
S57GenerateVectorPrimitiveFeatureDefn( int nRCNM, int nOptionFlags )

{
    OGRFeatureDefn      *poFDefn = NULL;
 
    if( nRCNM == RCNM_VI )
    {
        poFDefn = new OGRFeatureDefn( OGRN_VI );
        poFDefn->SetGeomType( wkbPoint );
    }
    else if( nRCNM == RCNM_VC )
    {
        poFDefn = new OGRFeatureDefn( OGRN_VC );
        poFDefn->SetGeomType( wkbPoint );
    }
    else if( nRCNM == RCNM_VE )
    {
        poFDefn = new OGRFeatureDefn( OGRN_VE );
        poFDefn->SetGeomType( wkbUnknown );
    }
    else if( nRCNM == RCNM_VF )
    {
        poFDefn = new OGRFeatureDefn( OGRN_VF );
        poFDefn->SetGeomType( wkbPolygon );
    }
    else
        return NULL;

    poFDefn->Reference();

/* -------------------------------------------------------------------- */
/*      Core vector primitive attributes                                */
/* -------------------------------------------------------------------- */
    OGRFieldDefn oField("",OFTInteger);

    oField.Set( "RCNM", OFTInteger, 3, 0 );
    poFDefn->AddFieldDefn( &oField );

    oField.Set( "RCID", OFTInteger, 8, 0 );
    poFDefn->AddFieldDefn( &oField );

    oField.Set( "RVER", OFTInteger, 2, 0 );
    poFDefn->AddFieldDefn( &oField );

    oField.Set( "RUIN", OFTInteger, 2, 0 );
    poFDefn->AddFieldDefn( &oField );

/* -------------------------------------------------------------------- */
/*      For lines we want to capture the point links for the first      */
/*      and last nodes.                                                 */
/* -------------------------------------------------------------------- */
    if( nRCNM == RCNM_VE )
    {
        oField.Set( "NAME_RCNM_0", OFTInteger, 3, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "NAME_RCID_0", OFTInteger, 8, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "ORNT_0", OFTInteger, 3, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "USAG_0", OFTInteger, 3, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "TOPI_0", OFTInteger, 1, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "MASK_0", OFTInteger, 3, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "NAME_RCNM_1", OFTInteger, 3, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "NAME_RCID_1", OFTInteger, 8, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "ORNT_1", OFTInteger, 3, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "USAG_1", OFTInteger, 3, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "TOPI_1", OFTInteger, 1, 0 );
        poFDefn->AddFieldDefn( &oField );

        oField.Set( "MASK_1", OFTInteger, 3, 0 );
        poFDefn->AddFieldDefn( &oField );
    }

    return poFDefn;
}
예제 #11
0
OGRFeatureDefn *OGRIngresResultLayer::ReadResultDefinition()

{
/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn = new OGRFeatureDefn( "sql_statement" );
    int            iRawField;

    poDefn->Reference();

    for( iRawField = 0;
         iRawField < (int) poResultSet->getDescrParm.gd_descriptorCount;
         iRawField++ )
    {
        IIAPI_DESCRIPTOR *psFDesc =
            poResultSet->getDescrParm.gd_descriptor + iRawField;
        OGRFieldDefn    oField( psFDesc->ds_columnName, OFTString);

        switch( psFDesc->ds_dataType )
        {
          case IIAPI_CHR_TYPE:
          case IIAPI_CHA_TYPE:
            // string - fixed width.
            oField.SetWidth( psFDesc->ds_length );
            poDefn->AddFieldDefn( &oField );
            break;

          case IIAPI_LVCH_TYPE:
          case IIAPI_LTXT_TYPE:
          case IIAPI_VCH_TYPE:
          case IIAPI_TXT_TYPE:
            // default variable length string
            poDefn->AddFieldDefn( &oField );
            break;

          case IIAPI_INT_TYPE:
            oField.SetType( OFTInteger );
            poDefn->AddFieldDefn( &oField );
            break;

          case IIAPI_FLT_TYPE:
            oField.SetType( OFTReal );
            poDefn->AddFieldDefn( &oField );
            break;

          case IIAPI_DEC_TYPE:
            oField.SetWidth( psFDesc->ds_precision );
            if( psFDesc->ds_scale == 0 )
                oField.SetType( OFTInteger );
            else
            {
                oField.SetType( OFTReal );
                oField.SetPrecision( psFDesc->ds_scale );
            }
            poDefn->AddFieldDefn( &oField );
            break;

          default:
            // any other field we ignore.
            break;
        }
    }

    poDefn->SetGeomType( wkbNone );

    return poDefn;
}
예제 #12
0
OGRFeatureDefn *OGRPGResultLayer::ReadResultDefinition(PGresult *hInitialResultIn)

{
    PGresult            *hResult = hInitialResultIn;

/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn = new OGRFeatureDefn( "sql_statement" );
    int            iRawField;

    poDefn->Reference();

    for( iRawField = 0; iRawField < PQnfields(hResult); iRawField++ )
    {
        OGRFieldDefn    oField( PQfname(hResult,iRawField), OFTString);
        Oid             nTypeOID;

        nTypeOID = PQftype(hResult,iRawField);
        
        if( EQUAL(oField.GetNameRef(),"ogc_fid") )
        {
            bHasFid = TRUE;
            pszFIDColumn = CPLStrdup(oField.GetNameRef());
            continue;
        }
        else if( nTypeOID == poDS->GetGeometryOID()  ||
                 nTypeOID == poDS->GetGeographyOID()  ||
                 EQUAL(oField.GetNameRef(),"ST_AsText") ||
                 EQUAL(oField.GetNameRef(),"ST_AsBinary") ||
                 EQUAL(oField.GetNameRef(),"AsBinary") ||
                 EQUAL(oField.GetNameRef(),"asEWKT") ||
                 EQUAL(oField.GetNameRef(),"asText") )
        {
            if (bHasPostGISGeometry || bHasPostGISGeography )
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "More than one geometry column was found in the result of the SQL request. Only last one will be used");
            }
            if (nTypeOID == poDS->GetGeographyOID())
                bHasPostGISGeography = TRUE;
            else
                bHasPostGISGeometry = TRUE;
            CPLFree(pszGeomColumn);
            pszGeomColumn = CPLStrdup(oField.GetNameRef());
            continue;
        }
        else if( EQUAL(oField.GetNameRef(),"WKB_GEOMETRY") )
        {
            bHasWkb = TRUE;
            if( nTypeOID == OIDOID )
                bWkbAsOid = TRUE;
            continue;
        }

        if( nTypeOID == BYTEAOID )
        {
            oField.SetType( OFTBinary );
        }
        else if( nTypeOID == CHAROID ||
                 nTypeOID == TEXTOID ||
                 nTypeOID == BPCHAROID ||
                 nTypeOID == VARCHAROID )
        {
            oField.SetType( OFTString );

            /* See http://www.mail-archive.com/[email protected]/msg57726.html */
            /* nTypmod = width + 4 */
            int nTypmod = PQfmod(hResult, iRawField);
            if (nTypmod >= 4 && (nTypeOID == BPCHAROID ||
                               nTypeOID == VARCHAROID ) )
            {
                oField.SetWidth( nTypmod - 4);
            }
        }
        else if( nTypeOID == BOOLOID )
        {
            oField.SetType( OFTInteger );
            oField.SetWidth( 1 );
        }
        else if (nTypeOID == INT2OID )
        {
            oField.SetType( OFTInteger );
            oField.SetWidth( 5 );
        }
        else if (nTypeOID == INT4OID )
        {
            oField.SetType( OFTInteger );
        }
        else if ( nTypeOID == INT8OID )
        {
            /* FIXME: OFTInteger can not handle 64bit integers */
            oField.SetType( OFTInteger );
        }
        else if( nTypeOID == FLOAT4OID ||
                 nTypeOID == FLOAT8OID )
        {
            oField.SetType( OFTReal );
        }
        else if( nTypeOID == NUMERICOID )
        {
            /* See http://www.mail-archive.com/[email protected]/msg57726.html */
            /* typmod = (width << 16) + precision + 4 */
            int nTypmod = PQfmod(hResult, iRawField);
            if (nTypmod >= 4)
            {
                int nWidth = (nTypmod - 4) >> 16;
                int nPrecision = (nTypmod - 4) & 0xFFFF;
                if (nWidth <= 10 && nPrecision == 0)
                {
                    oField.SetType( OFTInteger );
                    oField.SetWidth( nWidth );
                }
                else
                {
                    oField.SetType( OFTReal );
                    oField.SetWidth( nWidth );
                    oField.SetPrecision( nPrecision );
                }
            }
            else
OGRFeatureDefn *OGRMySQLTableLayer::ReadTableDefinition( const char *pszTable )

{
    MYSQL_RES    *hResult;
    char         szCommand[1024];
    
/* -------------------------------------------------------------------- */
/*      Fire off commands to get back the schema of the table.          */
/* -------------------------------------------------------------------- */
    sprintf( szCommand, "DESCRIBE `%s`", pszTable );
    pszGeomColumnTable = CPLStrdup(pszTable);
    if( mysql_query( poDS->GetConn(), szCommand ) )
    {
        poDS->ReportError( "DESCRIBE Failed" );
        return FALSE;
    }

    hResult = mysql_store_result( poDS->GetConn() );
    if( hResult == NULL )
    {
        poDS->ReportError( "mysql_store_result() failed on DESCRIBE result." );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable );
    char           **papszRow;

    poDefn->Reference();

    while( (papszRow = mysql_fetch_row( hResult )) != NULL )
    {
        const char      *pszType;
        OGRFieldDefn    oField( papszRow[0], OFTString);

        pszType = papszRow[1];

        if( pszType == NULL )
            continue;

        if( EQUAL(pszType,"varbinary")
            || (strlen(pszType)>3 && EQUAL(pszType+strlen(pszType)-4,"blob")))
        {
            oField.SetType( OFTBinary );
        }
        else if( EQUAL(pszType,"varchar") 
                 || EQUAL(pszType+strlen(pszType)-4,"enum") 
                 || EQUAL(pszType+strlen(pszType)-4,"set") )
        {
            oField.SetType( OFTString );

        }
        else if( EQUALN(pszType,"char",4)  )
        {
            oField.SetType( OFTString );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            
            /* width is the second */
            oField.SetWidth(atoi(papszTokens[1]));

            CSLDestroy( papszTokens );
            oField.SetType( OFTString );

        }
        
        if(strlen(pszType)>3 && EQUAL(pszType+strlen(pszType)-4,"text"))
        {
            oField.SetType( OFTString );            
        }
        else if( EQUALN(pszType,"varchar",6)  )
        {
            /* 
               pszType is usually in the form "varchar(15)" 
               so we'll split it up and get the width and precision
            */
            
            oField.SetType( OFTString );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            
            /* width is the second */
            oField.SetWidth(atoi(papszTokens[1]));

            CSLDestroy( papszTokens );
            oField.SetType( OFTString );
        }
        else if( EQUALN(pszType,"int", 3) )
        {
            oField.SetType( OFTInteger );
        }
        else if( EQUALN(pszType,"tinyint", 7) )
        {
            oField.SetType( OFTInteger );
        }
        else if( EQUALN(pszType,"smallint", 8) )
        {
            oField.SetType( OFTInteger );
        }
        else if( EQUALN(pszType,"mediumint",9) )
        {
            oField.SetType( OFTInteger );
        }
        else if( EQUALN(pszType,"bigint",6) )
        {
            oField.SetType( OFTInteger );
        }
        else if( EQUALN(pszType,"decimal",7) )
        {
            /* 
               pszType is usually in the form "decimal(15,2)" 
               so we'll split it up and get the width and precision
            */
            oField.SetType( OFTReal );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            
            /* width is the second and precision is the third */
            oField.SetWidth(atoi(papszTokens[1]));
            oField.SetPrecision(atoi(papszTokens[2]));
            CSLDestroy( papszTokens );


        }
        else if( EQUALN(pszType,"float", 5) )
        {
            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType,"double") )
        {
            oField.SetType( OFTReal );
        }
        else if( EQUALN(pszType,"double",6) )
        {
            // double can also be double(15,2)
            // so we'll handle this case here after 
            // we check for just a regular double 
            // without a width and precision specified
            
            char ** papszTokens=NULL;
            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            /* width is the second and precision is the third */
            oField.SetWidth(atoi(papszTokens[1]));
            oField.SetPrecision(atoi(papszTokens[2]));
            CSLDestroy( papszTokens );  

            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType,"decimal") )
        {
            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType, "date") )
        {
            oField.SetType( OFTDate );
        }
        else if( EQUAL(pszType, "time") )
        {
            oField.SetType( OFTTime );
        }
        else if( EQUAL(pszType, "datetime") 
                 || EQUAL(pszType, "timestamp") )
        {
            oField.SetType( OFTDateTime );
        }
        else if( EQUAL(pszType, "year") )  
        {
            oField.SetType( OFTString );
            oField.SetWidth( 10 );
        }
        else if( EQUAL(pszType, "geometry") ) 
        {
            pszGeomColumn = CPLStrdup(papszRow[0]);
            continue;
        }
        // Is this an integer primary key field?
        if( !bHasFid && papszRow[3] != NULL && EQUAL(papszRow[3],"PRI") 
            && oField.GetType() == OFTInteger )
        {
            bHasFid = TRUE;
            pszFIDColumn = CPLStrdup(oField.GetNameRef());
            continue;
        }

        poDefn->AddFieldDefn( &oField );
    }

    // set to none for now... if we have a geometry column it will be set layer.
    poDefn->SetGeomType( wkbNone );

    if( hResult != NULL )
    {
        mysql_free_result( hResult );
        hResultSet = NULL;
    }

    if( bHasFid )
        CPLDebug( "MySQL", "table %s has FID column %s.",
                  pszTable, pszFIDColumn );
    else
        CPLDebug( "MySQL", 
                  "table %s has no FID column, FIDs will not be reliable!",
                  pszTable );

    if (pszGeomColumn) 
    {
        char*        pszType=NULL;
        
        // set to unknown first
        poDefn->SetGeomType( wkbUnknown );
        
        sprintf(szCommand, "SELECT type, coord_dimension FROM geometry_columns WHERE f_table_name='%s'",
                pszTable );
        
        hResult = NULL;
        if( !mysql_query( poDS->GetConn(), szCommand ) )
            hResult = mysql_store_result( poDS->GetConn() );

        papszRow = NULL;
        if( hResult != NULL )
            papszRow = mysql_fetch_row( hResult );

        if( papszRow != NULL && papszRow[0] != NULL )
        {

            pszType = papszRow[0];

            OGRwkbGeometryType nGeomType = wkbUnknown;

            // check only standard OGC geometry types
            if ( EQUAL(pszType, "POINT") )
                nGeomType = wkbPoint;
            else if ( EQUAL(pszType,"LINESTRING"))
                nGeomType = wkbLineString;
            else if ( EQUAL(pszType,"POLYGON"))
                nGeomType = wkbPolygon;
            else if ( EQUAL(pszType,"MULTIPOINT"))
                nGeomType = wkbMultiPoint;
            else if ( EQUAL(pszType,"MULTILINESTRING"))
                nGeomType = wkbMultiLineString;
            else if ( EQUAL(pszType,"MULTIPOLYGON"))
                nGeomType = wkbMultiPolygon;
            else if ( EQUAL(pszType,"GEOMETRYCOLLECTION"))
                nGeomType = wkbGeometryCollection;

            if( papszRow[1] != NULL && atoi(papszRow[1]) == 3 )
                nGeomType = (OGRwkbGeometryType) (nGeomType | wkb25DBit);

            poDefn->SetGeomType( nGeomType );

        } 

        if( hResult != NULL )
            mysql_free_result( hResult );   //Free our query results for finding type.
			hResult = NULL;
    } 
 
    // Fetch the SRID for this table now
    nSRSId = FetchSRSId(); 
    return poDefn;
}
예제 #14
0
OGRFeatureDefn *
OGROCISelectLayer::ReadTableDefinition( OGROCIStatement *poCommand )

{
    OGROCISession      *poSession = poDS->GetSession();

/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    for( int iParm = 0; TRUE; iParm++ )
    {                                                           
        OGRFieldDefn oField( "", OFTString );
        int          nStatus;
        OCIParam     *hParmDesc;
        ub2          nOCIType;
        ub4          nOCILen;

        nStatus = 
            OCIParamGet( poCommand->GetStatement(), OCI_HTYPE_STMT, 
                         poSession->hError, (dvoid**)&hParmDesc, 
                         (ub4) iParm+1 );

        if( nStatus == OCI_ERROR )
            break;

        if( poSession->GetParmInfo( hParmDesc, &oField, &nOCIType, &nOCILen )
            != CE_None )
            break;

        if( oField.GetType() == OFTBinary && nOCIType == 108 )
        {
            CPLFree( pszGeomName );
            pszGeomName = CPLStrdup( oField.GetNameRef() );
            iGeomColumn = iParm;
            break;
        }
    }

/* -------------------------------------------------------------------- */
/*      Use the schema off the statement.                               */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn;

    poDefn = poCommand->GetResultDefn();
    if( iGeomColumn >= 0 )
        poDefn->SetGeomType(wkbUnknown);
    poDefn->Reference();

/* -------------------------------------------------------------------- */
/*      Do we have an FID?                                              */
/* -------------------------------------------------------------------- */
    const char *pszExpectedFIDName = 
        CPLGetConfigOption( "OCI_FID", "OGR_FID" );
    if( poDefn->GetFieldIndex(pszExpectedFIDName) > -1 )
    {
        iFIDColumn = poDefn->GetFieldIndex(pszExpectedFIDName);
        pszFIDName = CPLStrdup(poDefn->GetFieldDefn(iFIDColumn)->GetNameRef());
    }

    if( EQUAL(pszExpectedFIDName, "OGR_FID") && pszFIDName )
    {
        for(int i=0;i<poDefn->GetFieldCount();i++)
        {
            // This is presumably a Integer since we always create Integer64 with a
            // defined precision
            if( poDefn->GetFieldDefn(i)->GetType() == OFTInteger64 &&
                poDefn->GetFieldDefn(i)->GetWidth() == 0 )
            {
                poDefn->GetFieldDefn(i)->SetType(OFTInteger);
            }
        }
    }

    return poDefn;
}
예제 #15
0
OGRFeatureDefn *OGRMySQLResultLayer::ReadResultDefinition()

{
/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn = new OGRFeatureDefn( "sql_statement" );
    SetDescription( poDefn->GetName() );

    poDefn->Reference();

    mysql_field_seek( hResultSet, 0 );
    for( int iRawField = 0;
         iRawField < (int) mysql_num_fields(hResultSet);
         iRawField++ )
    {
        MYSQL_FIELD *psMSField = mysql_fetch_field( hResultSet );
        OGRFieldDefn oField( psMSField->name, OFTString);

        switch( psMSField->type )
        {
          case FIELD_TYPE_TINY:
          case FIELD_TYPE_SHORT:
          case FIELD_TYPE_LONG:
          case FIELD_TYPE_INT24:
          case FIELD_TYPE_LONGLONG:
          {
            oField.SetType( OFTInteger );
            const int width = (int)psMSField->length;
            oField.SetWidth(width);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_DECIMAL:
#ifdef FIELD_TYPE_NEWDECIMAL
          case FIELD_TYPE_NEWDECIMAL:
#endif
          {
            oField.SetType( OFTReal );

            // a bunch of hackery to munge the widths that MySQL gives
            // us into corresponding widths and precisions for OGR
            const int precision = (int)psMSField->decimals;
            int width = (int)psMSField->length;
            if (!precision)
                width = width - 1;
            width = width - precision;

            oField.SetWidth(width);
            oField.SetPrecision(precision);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_FLOAT:
          case FIELD_TYPE_DOUBLE:
         /* MYSQL_FIELD is always reporting ->length = 22 and ->decimals = 31
            for double type regardless of the data it returned. In an example,
            the data it returned had only 5 or 6 decimal places which were
            exactly as entered into the database but reported the decimals
            as 31. */
         /* Assuming that a length of 22 means no particular width and 31
            decimals means no particular precision. */
          {
            const int width = (int)psMSField->length;
            const int precision = (int)psMSField->decimals;
            oField.SetType( OFTReal );
            if( width != 22 )
                oField.SetWidth(width);
            if( precision != 31 )
                oField.SetPrecision(precision);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_DATE:
          {
            oField.SetType( OFTDate );
            oField.SetWidth(0);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_TIME:
          {
            oField.SetType( OFTTime );
            oField.SetWidth(0);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_TIMESTAMP:
          case FIELD_TYPE_DATETIME:
          {
            oField.SetType( OFTDateTime );
            oField.SetWidth(0);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_YEAR:
          case FIELD_TYPE_STRING:
          case FIELD_TYPE_VAR_STRING:
          {
            oField.SetType( OFTString );
            oField.SetWidth((int)psMSField->length);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_TINY_BLOB:
          case FIELD_TYPE_MEDIUM_BLOB:
          case FIELD_TYPE_LONG_BLOB:
          case FIELD_TYPE_BLOB:
          {
            if( psMSField->charsetnr == 63 )
                oField.SetType( OFTBinary );
            else
                oField.SetType( OFTString );
            oField.SetWidth((int)psMSField->max_length);
            poDefn->AddFieldDefn( &oField );
            break;
          }
          case FIELD_TYPE_GEOMETRY:
          {
            if (pszGeomColumn == nullptr)
            {
                pszGeomColumnTable = CPLStrdup( psMSField->table);
                pszGeomColumn = CPLStrdup( psMSField->name);
            }
            break;
          }
          default:
            // any other field we ignore.
            break;
        }

        // assume a FID name first, and if it isn't there
        // take a field that is not null, a primary key,
        // and is an integer-like field
        if( EQUAL(psMSField->name,"ogc_fid") )
        {
            bHasFid = TRUE;
            pszFIDColumn = CPLStrdup(oField.GetNameRef());
            continue;
        } else
        if (IS_NOT_NULL(psMSField->flags)
            && IS_PRI_KEY(psMSField->flags)
            &&
                (
                    psMSField->type == FIELD_TYPE_TINY
                    || psMSField->type == FIELD_TYPE_SHORT
                    || psMSField->type == FIELD_TYPE_LONG
                    || psMSField->type == FIELD_TYPE_INT24
                    || psMSField->type == FIELD_TYPE_LONGLONG
                )
            )
        {
           bHasFid = TRUE;
           pszFIDColumn = CPLStrdup(oField.GetNameRef());
           continue;
        }
    }

    poDefn->SetGeomType( wkbNone );

    if (pszGeomColumn)
    {
        char*        pszType=nullptr;
        CPLString    osCommand;
        char           **papszRow;

        // set to unknown first
        poDefn->SetGeomType( wkbUnknown );
        poDefn->GetGeomFieldDefn(0)->SetName( pszGeomColumn );

        osCommand.Printf(
                "SELECT type FROM geometry_columns WHERE f_table_name='%s'",
                pszGeomColumnTable );

        if( hResultSet != nullptr )
            mysql_free_result( hResultSet );
        hResultSet = nullptr;

        if( !mysql_query( poDS->GetConn(), osCommand ) )
            hResultSet = mysql_store_result( poDS->GetConn() );

        papszRow = nullptr;
        if( hResultSet != nullptr )
            papszRow = mysql_fetch_row( hResultSet );

        if( papszRow != nullptr && papszRow[0] != nullptr )
        {
            pszType = papszRow[0];

            OGRwkbGeometryType l_nGeomType = OGRFromOGCGeomType(pszType);

            poDefn->SetGeomType( l_nGeomType );
        }

        nSRSId = FetchSRSId();
    }

    return poDefn;
}
예제 #16
0
OGRFeatureDefn *OGRMySQLTableLayer::ReadTableDefinition( const char *pszTable )

{
    MYSQL_RES    *hResult;
    CPLString     osCommand;

/* -------------------------------------------------------------------- */
/*      Fire off commands to get back the schema of the table.          */
/* -------------------------------------------------------------------- */
    osCommand.Printf("DESCRIBE `%s`", pszTable );
    pszGeomColumnTable = CPLStrdup(pszTable);
    if( mysql_query( poDS->GetConn(), osCommand ) )
    {
        poDS->ReportError( "DESCRIBE Failed" );
        return NULL;
    }

    hResult = mysql_store_result( poDS->GetConn() );
    if( hResult == NULL )
    {
        poDS->ReportError( "mysql_store_result() failed on DESCRIBE result." );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Parse the returned table information.                           */
/* -------------------------------------------------------------------- */
    OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable );
    char           **papszRow;
    OGRwkbGeometryType eForcedGeomType = wkbUnknown;
    int bGeomColumnNotNullable = FALSE;

    poDefn->Reference();

    while( (papszRow = mysql_fetch_row( hResult )) != NULL )
    {
        const char      *pszType;
        OGRFieldDefn    oField( papszRow[0], OFTString);
        int             nLenType;

        pszType = papszRow[1];

        if( pszType == NULL )
            continue;

        nLenType = (int)strlen(pszType);

        if( EQUAL(pszType,"varbinary")
            || (nLenType>=4 && EQUAL(pszType+nLenType-4,"blob")))
        {
            oField.SetType( OFTBinary );
        }
        else if( EQUAL(pszType,"varchar")
                 || (nLenType>=4 && EQUAL(pszType+nLenType-4,"enum"))
                 || (nLenType>=3 && EQUAL(pszType+nLenType-3,"set")) )
        {
            oField.SetType( OFTString );

        }
        else if( STARTS_WITH_CI(pszType, "char")  )
        {
            oField.SetType( OFTString );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            if (CSLCount(papszTokens) >= 2)
            {
                /* width is the second */
                oField.SetWidth(atoi(papszTokens[1]));
            }

            CSLDestroy( papszTokens );
            oField.SetType( OFTString );

        }

        if(nLenType>=4 && EQUAL(pszType+nLenType-4,"text"))
        {
            oField.SetType( OFTString );
        }
        else if( STARTS_WITH_CI(pszType,"varchar")  )
        {
            /*
               pszType is usually in the form "varchar(15)"
               so we'll split it up and get the width and precision
            */

            oField.SetType( OFTString );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            if (CSLCount(papszTokens) >= 2)
            {
                /* width is the second */
                oField.SetWidth(atoi(papszTokens[1]));
            }

            CSLDestroy( papszTokens );
            oField.SetType( OFTString );
        }
        else if( STARTS_WITH_CI(pszType, "int") )
        {
            oField.SetType( OFTInteger );
        }
        else if( STARTS_WITH_CI(pszType, "tinyint") )
        {
            oField.SetType( OFTInteger );
        }
        else if( STARTS_WITH_CI(pszType, "smallint") )
        {
            oField.SetType( OFTInteger );
        }
        else if( STARTS_WITH_CI(pszType, "mediumint") )
        {
            oField.SetType( OFTInteger );
        }
        else if( STARTS_WITH_CI(pszType, "bigint") )
        {
            oField.SetType( OFTInteger64 );
        }
        else if( STARTS_WITH_CI(pszType, "decimal") )
        {
            /*
               pszType is usually in the form "decimal(15,2)"
               so we'll split it up and get the width and precision
            */
            oField.SetType( OFTReal );
            char ** papszTokens;

            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            if (CSLCount(papszTokens) >= 3)
            {
                /* width is the second and precision is the third */
                oField.SetWidth(atoi(papszTokens[1]));
                oField.SetPrecision(atoi(papszTokens[2]));
            }
            CSLDestroy( papszTokens );


        }
        else if( STARTS_WITH_CI(pszType, "float") )
        {
            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType,"double") )
        {
            oField.SetType( OFTReal );
        }
        else if( STARTS_WITH_CI(pszType, "double") )
        {
            // double can also be double(15,2)
            // so we'll handle this case here after
            // we check for just a regular double
            // without a width and precision specified

            char ** papszTokens=NULL;
            papszTokens = CSLTokenizeString2(pszType,"(),",0);
            if (CSLCount(papszTokens) >= 3)
            {
                /* width is the second and precision is the third */
                oField.SetWidth(atoi(papszTokens[1]));
                oField.SetPrecision(atoi(papszTokens[2]));
            }
            CSLDestroy( papszTokens );

            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType,"decimal") )
        {
            oField.SetType( OFTReal );
        }
        else if( EQUAL(pszType, "date") )
        {
            oField.SetType( OFTDate );
        }
        else if( EQUAL(pszType, "time") )
        {
            oField.SetType( OFTTime );
        }
        else if( EQUAL(pszType, "datetime")
                 || EQUAL(pszType, "timestamp") )
        {
            oField.SetType( OFTDateTime );
        }
        else if( EQUAL(pszType, "year") )
        {
            oField.SetType( OFTString );
            oField.SetWidth( 10 );
        }
        else if( EQUAL(pszType, "geometry") ||
                 OGRFromOGCGeomType(pszType) != wkbUnknown)
        {
            if (pszGeomColumn == NULL)
            {
                pszGeomColumn = CPLStrdup(papszRow[0]);
                eForcedGeomType = OGRFromOGCGeomType(pszType);
                bGeomColumnNotNullable = ( papszRow[2] != NULL && EQUAL(papszRow[2], "NO") );
            }
            else
            {
                CPLDebug("MYSQL",
                         "Ignoring %s as geometry column. Another one(%s) has already been found before",
                         papszRow[0], pszGeomColumn);
            }
            continue;
        }
        // Is this an integer primary key field?
        if( !bHasFid && papszRow[3] != NULL && EQUAL(papszRow[3],"PRI")
            && (oField.GetType() == OFTInteger || oField.GetType() == OFTInteger64) )
        {
            bHasFid = TRUE;
            pszFIDColumn = CPLStrdup(oField.GetNameRef());
            if( oField.GetType() == OFTInteger64 )
                SetMetadataItem(OLMD_FID64, "YES");
            continue;
        }

        // Is not nullable ?
        if( papszRow[2] != NULL && EQUAL(papszRow[2], "NO") )
            oField.SetNullable(FALSE);

        // Has default ?
        const char* pszDefault = papszRow[4];
        if( pszDefault != NULL )
        {
            if( !EQUAL(pszDefault, "NULL") &&
                !STARTS_WITH_CI(pszDefault, "CURRENT_") &&
                pszDefault[0] != '(' &&
                pszDefault[0] != '\'' &&
                CPLGetValueType(pszDefault) == CPL_VALUE_STRING )
            {
                int nYear, nMonth, nDay, nHour, nMinute;
                float fSecond;
                if( oField.GetType() == OFTDateTime &&
                    sscanf(pszDefault, "%d-%d-%d %d:%d:%f", &nYear, &nMonth, &nDay,
                                &nHour, &nMinute, &fSecond) == 6 )
                {
                    oField.SetDefault(CPLSPrintf("'%04d/%02d/%02d %02d:%02d:%02d'",
                                            nYear, nMonth, nDay, nHour, nMinute, (int)(fSecond+0.5)));
                }
                else
                {
                    CPLString osDefault("'");
                    char* pszTmp = CPLEscapeString(pszDefault, -1, CPLES_SQL);
                    osDefault += pszTmp;
                    CPLFree(pszTmp);
                    osDefault += "'";
                    oField.SetDefault(osDefault);
                }
            }
            else
            {
                oField.SetDefault(pszDefault);
            }
        }

        poDefn->AddFieldDefn( &oField );
    }

    // set to none for now... if we have a geometry column it will be set layer.
    poDefn->SetGeomType( wkbNone );

    if( hResult != NULL )
    {
        mysql_free_result( hResult );
        hResultSet = NULL;
    }

    if( bHasFid )
        CPLDebug( "MySQL", "table %s has FID column %s.",
                  pszTable, pszFIDColumn );
    else
        CPLDebug( "MySQL",
                  "table %s has no FID column, FIDs will not be reliable!",
                  pszTable );

    if (pszGeomColumn)
    {
        char*        pszType=NULL;

        // set to unknown first
        poDefn->SetGeomType( wkbUnknown );

        osCommand = "SELECT type, coord_dimension FROM geometry_columns WHERE f_table_name='";
        osCommand += pszTable;
        osCommand += "'";

        hResult = NULL;
        if( !mysql_query( poDS->GetConn(), osCommand ) )
            hResult = mysql_store_result( poDS->GetConn() );

        papszRow = NULL;
        if( hResult != NULL )
            papszRow = mysql_fetch_row( hResult );

        if( papszRow != NULL && papszRow[0] != NULL )
        {

            pszType = papszRow[0];

            OGRwkbGeometryType l_nGeomType = OGRFromOGCGeomType(pszType);

            if( papszRow[1] != NULL && atoi(papszRow[1]) == 3 )
                l_nGeomType = wkbSetZ(l_nGeomType);

            poDefn->SetGeomType( l_nGeomType );

        }
        else if (eForcedGeomType != wkbUnknown)
            poDefn->SetGeomType(eForcedGeomType);

        if( bGeomColumnNotNullable )
            poDefn->GetGeomFieldDefn(0)->SetNullable(FALSE);

        if( hResult != NULL )
            mysql_free_result( hResult );   //Free our query results for finding type.
			hResult = NULL;
    }

    // Fetch the SRID for this table now
    nSRSId = FetchSRSId();
    return poDefn;
}