OGRwkbGeometryType OGRVRTGetGeometryType(const char* pszGType, int* pbError)
{
    int iType;
    OGRwkbGeometryType eGeomType = wkbUnknown;

    if (pbError)
        *pbError = FALSE;

    for( iType = 0; asGeomTypeNames[iType].pszName != NULL; iType++ )
    {
        if( EQUALN(pszGType, asGeomTypeNames[iType].pszName,
                strlen(asGeomTypeNames[iType].pszName)) )
        {
            eGeomType = asGeomTypeNames[iType].eType;

            if( strstr(pszGType,"25D") != NULL || strstr(pszGType,"Z") != NULL )
                eGeomType = wkbSetZ(eGeomType);
            break;
        }
    }

    if( asGeomTypeNames[iType].pszName == NULL )
    {
        if (pbError)
            *pbError = TRUE;
    }

    return eGeomType;
}
Beispiel #2
0
OGRwkbGeometryType OGRVRTGetGeometryType( const char *pszGType, int *pbError )
{
    if( pbError )
        *pbError = FALSE;

    for( const auto& entry: asGeomTypeNames )
    {
        if( EQUALN(pszGType, entry.pszName,
                   strlen(entry.pszName)) )
        {
            OGRwkbGeometryType eGeomType = entry.eType;

            if( strstr(pszGType, "25D") != nullptr ||
                strstr(pszGType, "Z") != nullptr )
                eGeomType = wkbSetZ(eGeomType);
            if( pszGType[strlen(pszGType) - 1] == 'M' ||
                pszGType[strlen(pszGType) - 2] == 'M' )
                eGeomType = wkbSetM(eGeomType);
            return eGeomType;
        }
    }

    if( pbError )
        *pbError = TRUE;
    return wkbUnknown;
}
int OGRKMLDataSource::Open( const char * pszNewName, int bTestOpen )
{
    CPLAssert( NULL != pszNewName );

    int nCount = 0;
    OGRKMLLayer *poLayer = NULL;
    OGRwkbGeometryType poGeotype;

/* -------------------------------------------------------------------- */
/*      Create a KML object and open the source file.                   */
/* -------------------------------------------------------------------- */
    poKMLFile_ = new KMLVector();

    if( !poKMLFile_->open( pszNewName ) )
    {
        delete poKMLFile_;
        poKMLFile_ = NULL;
        return FALSE;
    }

    pszName_ = CPLStrdup( pszNewName );

/* -------------------------------------------------------------------- */
/*      If we aren't sure it is KML, validate it by start parsing       */
/* -------------------------------------------------------------------- */
    if( bTestOpen && !poKMLFile_->isValid() )
    {
        delete poKMLFile_;
        poKMLFile_ = NULL;
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Prescan the KML file so we can later work with the structure    */
/* -------------------------------------------------------------------- */
    poKMLFile_->parse();

/* -------------------------------------------------------------------- */
/*      Classify the nodes                                              */
/* -------------------------------------------------------------------- */
    if( !poKMLFile_->classifyNodes() )
    {
        delete poKMLFile_;
        poKMLFile_ = NULL;
        return FALSE;
    }


/* -------------------------------------------------------------------- */
/*      Eliminate the empty containers (if there is at least one        */
/*      valid container !)                                              */
/* -------------------------------------------------------------------- */
    int bHasOnlyEmpty = poKMLFile_->hasOnlyEmpty();
    if (bHasOnlyEmpty)
        CPLDebug("KML", "Has only empty containers");
    else
        poKMLFile_->eliminateEmpty();

/* -------------------------------------------------------------------- */
/*      Find layers to use in the KML structure                         */
/* -------------------------------------------------------------------- */
    poKMLFile_->findLayers(NULL, bHasOnlyEmpty);

/* -------------------------------------------------------------------- */
/*      Print the structure                                             */
/* -------------------------------------------------------------------- */
    if( CPLGetConfigOption("KML_DEBUG",NULL) != NULL )
        poKMLFile_->print(3);

    nLayers_ = poKMLFile_->getNumLayers();

/* -------------------------------------------------------------------- */
/*      Allocate memory for the Layers                                  */
/* -------------------------------------------------------------------- */
    papoLayers_ = (OGRKMLLayer **)
        CPLMalloc( sizeof(OGRKMLLayer *) * nLayers_ );

    OGRSpatialReference *poSRS = new OGRSpatialReference("GEOGCS[\"WGS 84\", "
        "   DATUM[\"WGS_1984\","
        "       SPHEROID[\"WGS 84\",6378137,298.257223563,"
        "           AUTHORITY[\"EPSG\",\"7030\"]],"
        "           AUTHORITY[\"EPSG\",\"6326\"]],"
        "       PRIMEM[\"Greenwich\",0,"
        "           AUTHORITY[\"EPSG\",\"8901\"]],"
        "       UNIT[\"degree\",0.01745329251994328,"
        "           AUTHORITY[\"EPSG\",\"9122\"]],"
        "           AUTHORITY[\"EPSG\",\"4326\"]]");

/* -------------------------------------------------------------------- */
/*      Create the Layers and fill them                                 */
/* -------------------------------------------------------------------- */
    for( nCount = 0; nCount < nLayers_; nCount++ )
    {
        if( !poKMLFile_->selectLayer(nCount) )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "There are no layers or a layer can not be found!");
            break;
        }

        if( poKMLFile_->getCurrentType() == Point )
            poGeotype = wkbPoint;
        else if( poKMLFile_->getCurrentType() == LineString )
            poGeotype = wkbLineString;
        else if( poKMLFile_->getCurrentType() == Polygon )
            poGeotype = wkbPolygon;
        else if( poKMLFile_->getCurrentType() == MultiPoint )
            poGeotype = wkbMultiPoint;
        else if( poKMLFile_->getCurrentType() == MultiLineString )
            poGeotype = wkbMultiLineString;
        else if( poKMLFile_->getCurrentType() == MultiPolygon )
            poGeotype = wkbMultiPolygon;
        else if( poKMLFile_->getCurrentType() == MultiGeometry )
            poGeotype = wkbGeometryCollection;
        else
            poGeotype = wkbUnknown;
        
        if (poGeotype != wkbUnknown && poKMLFile_->is25D())
            poGeotype = wkbSetZ(poGeotype);

/* -------------------------------------------------------------------- */
/*      Create the layer object.                                        */
/* -------------------------------------------------------------------- */
        CPLString sName( poKMLFile_->getCurrentName() );

        if( sName.empty() )
        {
            sName.Printf( "Layer #%d", nCount );
        }

        poLayer = new OGRKMLLayer( sName.c_str(), poSRS, FALSE, poGeotype, this );

        poLayer->SetLayerNumber( nCount );

/* -------------------------------------------------------------------- */
/*      Add layer to data source layer list.                            */
/* -------------------------------------------------------------------- */
        papoLayers_[nCount] = poLayer;
    }
    
    poSRS->Release();
    
    return TRUE;	
}
CPLErr OGRPGeoTableLayer::Initialize( const char *pszTableName, 
                                      const char *pszGeomCol,
                                      int nShapeType, 
                                      double dfExtentLeft,
                                      double dfExtentRight,
                                      double dfExtentBottom,
                                      double dfExtentTop,
                                      int nSRID,
                                      int bHasZ )


{
    CPLODBCSession *poSession = poDS->GetSession();
    
    SetDescription( pszTableName );

    CPLFree( pszGeomColumn );
    if( pszGeomCol == NULL )
        pszGeomColumn = NULL;
    else
        pszGeomColumn = CPLStrdup( pszGeomCol );

    CPLFree( pszFIDColumn );
    pszFIDColumn = NULL;

    sExtent.MinX = dfExtentLeft;
    sExtent.MaxX = dfExtentRight;
    sExtent.MinY = dfExtentBottom;
    sExtent.MaxY = dfExtentTop;

    LookupSRID( nSRID );

/* -------------------------------------------------------------------- */
/*      Setup geometry type.                                            */
/* -------------------------------------------------------------------- */
    OGRwkbGeometryType  eOGRType;

    switch( nShapeType )
    {
        case ESRI_LAYERGEOMTYPE_NULL:
            eOGRType = wkbNone;
            break;

        case ESRI_LAYERGEOMTYPE_POINT:
            eOGRType = wkbPoint;
            break;

        case ESRI_LAYERGEOMTYPE_MULTIPOINT:
            eOGRType = wkbMultiPoint;
            break;

        case ESRI_LAYERGEOMTYPE_POLYLINE:
            eOGRType = wkbLineString;
            break;

        case ESRI_LAYERGEOMTYPE_POLYGON:
        case ESRI_LAYERGEOMTYPE_MULTIPATCH:
            eOGRType = wkbPolygon;
            break;

        default:
            CPLDebug("PGeo", "Unexpected value for shape type : %d", nShapeType);
            eOGRType = wkbUnknown;
            break;
    }

    if( eOGRType != wkbUnknown && eOGRType != wkbNone && bHasZ )
        eOGRType = wkbSetZ(eOGRType);

/* -------------------------------------------------------------------- */
/*      Do we have a simple primary key?                                */
/* -------------------------------------------------------------------- */
    CPLODBCStatement oGetKey( poSession );
    
    if( oGetKey.GetPrimaryKeys( pszTableName ) && oGetKey.Fetch() )
    {
        pszFIDColumn = CPLStrdup(oGetKey.GetColData( 3 ));
        
        if( oGetKey.Fetch() ) // more than one field in key! 
        {
            CPLFree( pszFIDColumn );
            pszFIDColumn = NULL;
            CPLDebug( "PGeo", "%s: Compound primary key, ignoring.",
                      pszTableName );
        }
        else
            CPLDebug( "PGeo", 
                      "%s: Got primary key %s.",
                      pszTableName, pszFIDColumn );
    }
    else
        CPLDebug( "PGeo", "%s: no primary key", pszTableName );

/* -------------------------------------------------------------------- */
/*      Get the column definitions for this table.                      */
/* -------------------------------------------------------------------- */
    CPLODBCStatement oGetCol( poSession );
    CPLErr eErr;

    if( !oGetCol.GetColumns( pszTableName ) )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "GetColumns() failed on %s.\n%s",
                  pszTableName, poSession->GetLastError() );
        return CE_Failure;
    }

    eErr = BuildFeatureDefn( pszTableName, &oGetCol );
    if( eErr != CE_None )
        return eErr;

    if( poFeatureDefn->GetFieldCount() == 0 )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "No column definitions found for table '%s', layer not usable.", 
                  pszTableName );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Set geometry type.                                              */
/*                                                                      */
/*      NOTE: per reports from Craig Miller, it seems we cannot really  */
/*      trust the ShapeType value.  At the very least "line" tables     */
/*      sometimes have multilinestrings.  So for now we just always     */
/*      return wkbUnknown.                                              */
/*                                                                      */
/*      TODO - mloskot: Similar issue has been reported in Ticket #1484 */
/* -------------------------------------------------------------------- */
#ifdef notdef
    poFeatureDefn->SetGeomType( eOGRType );
#endif

    return CE_None;
}
void OGRCloudantTableLayer::LoadMetadata()
{
    if( bHasLoadedMetadata )
        return;

    bHasLoadedMetadata = true;

    if (pszSpatialDDoc == nullptr)
        GetSpatialView();
    if( pszSpatialDDoc == nullptr )
        return;

    CPLString osURI("/");
    osURI += osEscapedName;
    osURI += "/";
    osURI += pszSpatialDDoc;

    json_object* poAnswerObj = poDS->GET(osURI);
    if (poAnswerObj == nullptr)
        return;

    if ( !json_object_is_type(poAnswerObj, json_type_object) )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "LoadMetadata() failed");
        json_object_put(poAnswerObj);
        return;
    }

    json_object* poRev = CPL_json_object_object_get(poAnswerObj, "_rev");
    const char* pszRev = json_object_get_string(poRev);
    if (pszRev)
        osMetadataRev = pszRev;

    json_object* poError = CPL_json_object_object_get(poAnswerObj, "error");
    const char* pszError = json_object_get_string(poError);
    if (pszError && strcmp(pszError, "not_found") == 0)
    {
        json_object_put(poAnswerObj);
        return;
    }

    if (poDS->IsError(poAnswerObj, "LoadMetadata() failed"))
    {
        json_object_put(poAnswerObj);
        return;
    }

    json_object* poJsonSRS = CPL_json_object_object_get(poAnswerObj, "srsid");
    const char* pszSRS = json_object_get_string(poJsonSRS);
    if (pszSRS != nullptr)
    {
        poSRS = new OGRSpatialReference();
        if (poSRS->importFromURN(pszSRS) != OGRERR_NONE)
        {
            delete poSRS;
            poSRS = nullptr;
        }
    }

    json_object* poGeomType = CPL_json_object_object_get(poAnswerObj, "geomtype");
    const char* pszGeomType = json_object_get_string(poGeomType);

     if (pszGeomType)
    {
        if (EQUAL(pszGeomType, "NONE"))
        {
            eGeomType = wkbNone;
            bExtentValid = true;
        }
        else
        {
            eGeomType = OGRFromOGCGeomType(pszGeomType);

            json_object* poIs25D = CPL_json_object_object_get(poAnswerObj, "is_25D");
            if (poIs25D && json_object_get_boolean(poIs25D))
                eGeomType = wkbSetZ(eGeomType);

            json_object* poExtent = CPL_json_object_object_get(poAnswerObj, "extent");
            if (poExtent && json_object_get_type(poExtent) == json_type_object)
            {
                json_object* poBbox = CPL_json_object_object_get(poExtent, "bbox");
                if (poBbox &&
                    json_object_get_type(poBbox) == json_type_array &&
                    json_object_array_length(poBbox) == 4 &&
                    OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 0)) &&
                    OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 1)) &&
                    OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 2)) &&
                    OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 3)))
                {
                    dfMinX = json_object_get_double(json_object_array_get_idx(poBbox, 0));
                    dfMinY = json_object_get_double(json_object_array_get_idx(poBbox, 1));
                    dfMaxX = json_object_get_double(json_object_array_get_idx(poBbox, 2));
                    dfMaxY = json_object_get_double(json_object_array_get_idx(poBbox, 3));
                    bExtentValid = true;
                    bExtentSet = true;
                }
            }
        }
    }

    json_object* poGeoJSON = CPL_json_object_object_get(poAnswerObj, "geojson_documents");
    if (poGeoJSON && json_object_is_type(poGeoJSON, json_type_boolean))
        bGeoJSONDocument = CPL_TO_BOOL(json_object_get_boolean(poGeoJSON));

    json_object* poFields = CPL_json_object_object_get(poAnswerObj, "fields");
    if (poFields && json_object_is_type(poFields, json_type_array))
    {
        poFeatureDefn = new OGRFeatureDefn( osName );
        poFeatureDefn->Reference();

        poFeatureDefn->SetGeomType(eGeomType);
        if( poFeatureDefn->GetGeomFieldCount() != 0 )
            poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);

        OGRFieldDefn oFieldId("_id", OFTString);
        poFeatureDefn->AddFieldDefn(&oFieldId);

        OGRFieldDefn oFieldRev("_rev", OFTString);
        poFeatureDefn->AddFieldDefn(&oFieldRev);

        int nFields = json_object_array_length(poFields);
        for(int i=0;i<nFields;i++)
        {
            json_object* poField = json_object_array_get_idx(poFields, i);
            if (poField && json_object_is_type(poField, json_type_object))
            {
                json_object* poName = CPL_json_object_object_get(poField, "name");
                const char* pszName = json_object_get_string(poName);
                if (pszName)
                {
                    json_object* poType = CPL_json_object_object_get(poField, "type");
                    const char* pszType = json_object_get_string(poType);
                    OGRFieldType eType = OFTString;
                    if (pszType)
                    {
                        if (strcmp(pszType, "integer") == 0)
                            eType = OFTInteger;
                        else if (strcmp(pszType, "integerlist") == 0)
                            eType = OFTIntegerList;
                        else if (strcmp(pszType, "real") == 0)
                            eType = OFTReal;
                        else if (strcmp(pszType, "reallist") == 0)
                            eType = OFTRealList;
                        else if (strcmp(pszType, "string") == 0)
                            eType = OFTString;
                        else if (strcmp(pszType, "stringlist") == 0)
                            eType = OFTStringList;
                    }

                    OGRFieldDefn oField(pszName, eType);
                    poFeatureDefn->AddFieldDefn(&oField);
                }
            }
        }
    }

    std::sort(aosIdsToFetch.begin(), aosIdsToFetch.end());

    json_object_put(poAnswerObj);

    return;
}
OGRFeatureDefn * OGRCARTODBTableLayer::GetLayerDefnInternal(CPL_UNUSED json_object* poObjIn)
{
    if( poFeatureDefn != NULL )
        return poFeatureDefn;

    CPLString osCommand;
    if( poDS->IsAuthenticatedConnection() )
    {
        // Get everything !
        osCommand.Printf(
                 "SELECT a.attname, t.typname, a.attlen, "
                        "format_type(a.atttypid,a.atttypmod), "
                        "a.attnum, "
                        "a.attnotnull, "
                        "i.indisprimary, "
                        "pg_get_expr(def.adbin, c.oid) AS defaultexpr, "
                        "postgis_typmod_dims(a.atttypmod) dim, "
                        "postgis_typmod_srid(a.atttypmod) srid, "
                        "postgis_typmod_type(a.atttypmod)::text geomtyp, "
                        "srtext "
                 "FROM pg_class c "
                 "JOIN pg_attribute a ON a.attnum > 0 AND "
                                        "a.attrelid = c.oid AND c.relname = '%s' "
                 "JOIN pg_type t ON a.atttypid = t.oid "
                 "JOIN pg_namespace n ON c.relnamespace=n.oid AND n.nspname= '%s' "
                 "LEFT JOIN pg_index i ON c.oid = i.indrelid AND "
                                         "i.indisprimary = 't' AND a.attnum = ANY(i.indkey) "
                 "LEFT JOIN pg_attrdef def ON def.adrelid = c.oid AND "
                                              "def.adnum = a.attnum "
                 "LEFT JOIN spatial_ref_sys srs ON srs.srid = postgis_typmod_srid(a.atttypmod) "
                 "ORDER BY a.attnum",
                 OGRCARTODBEscapeLiteral(osName).c_str(),
                 OGRCARTODBEscapeLiteral(poDS->GetCurrentSchema()).c_str());
    }
    else if( poDS->HasOGRMetadataFunction() != FALSE )
    {
        osCommand.Printf( "SELECT * FROM ogr_table_metadata('%s', '%s')",
                          OGRCARTODBEscapeLiteral(poDS->GetCurrentSchema()).c_str(),
                          OGRCARTODBEscapeLiteral(osName).c_str() );
    }

    if( osCommand.size() )
    {
        if( !poDS->IsAuthenticatedConnection() && poDS->HasOGRMetadataFunction() < 0 )
            CPLPushErrorHandler(CPLQuietErrorHandler);
        OGRLayer* poLyr = poDS->ExecuteSQLInternal(osCommand);
        if( !poDS->IsAuthenticatedConnection() && poDS->HasOGRMetadataFunction() < 0 )
        {
            CPLPopErrorHandler();
            if( poLyr == NULL )
            {
                CPLDebug("CARTODB", "ogr_table_metadata(text, text) not available");
                CPLErrorReset();
            }
            else if( poLyr->GetLayerDefn()->GetFieldCount() != 12 )
            {
                CPLDebug("CARTODB", "ogr_table_metadata(text, text) has unexpected column count");
                poDS->ReleaseResultSet(poLyr);
                poLyr = NULL;
            }
            poDS->SetOGRMetadataFunction(poLyr != NULL);
        }
        if( poLyr )
        {
            OGRFeature* poFeat;
            while( (poFeat = poLyr->GetNextFeature()) != NULL )
            {
                if( poFeatureDefn == NULL )
                {
                    // We could do that outside of the while() loop, but
                    // by doing that here, we are somewhat robust to
                    // ogr_table_metadata() returning suddenly an empty result set
                    // for example if CDB_UserTables() no longer works
                    poFeatureDefn = new OGRFeatureDefn(osName);
                    poFeatureDefn->Reference();
                    poFeatureDefn->SetGeomType(wkbNone);
                }

                const char* pszAttname = poFeat->GetFieldAsString("attname");
                const char* pszType = poFeat->GetFieldAsString("typname");
                int nWidth = poFeat->GetFieldAsInteger("attlen");
                const char* pszFormatType = poFeat->GetFieldAsString("format_type");
                int bNotNull = poFeat->GetFieldAsInteger("attnotnull");
                int bIsPrimary = poFeat->GetFieldAsInteger("indisprimary");
                int iDefaultExpr = poLyr->GetLayerDefn()->GetFieldIndex("defaultexpr");
                const char* pszDefault = (iDefaultExpr >= 0 && poFeat->IsFieldSet(iDefaultExpr)) ?
                            poFeat->GetFieldAsString(iDefaultExpr) : NULL;

                if( bIsPrimary &&
                    (EQUAL(pszType, "int2") ||
                     EQUAL(pszType, "int4") ||
                     EQUAL(pszType, "int8") ||
                     EQUAL(pszType, "serial") ||
                     EQUAL(pszType, "bigserial")) )
                {
                    osFIDColName = pszAttname;
                }
                else if( strcmp(pszAttname, "created_at") == 0 ||
                         strcmp(pszAttname, "updated_at") == 0 ||
                         strcmp(pszAttname, "the_geom_webmercator") == 0)
                {
                    /* ignored */
                }
                else
                {
                    if( EQUAL(pszType,"geometry") )
                    {
                        int nDim = poFeat->GetFieldAsInteger("dim");
                        int nSRID = poFeat->GetFieldAsInteger("srid");
                        const char* pszGeomType = poFeat->GetFieldAsString("geomtyp");
                        const char* pszSRText = (poFeat->IsFieldSet(
                            poLyr->GetLayerDefn()->GetFieldIndex("srtext"))) ?
                                    poFeat->GetFieldAsString("srtext") : NULL;
                        OGRwkbGeometryType eType = OGRFromOGCGeomType(pszGeomType);
                        if( nDim == 3 )
                            eType = wkbSetZ(eType);
                        OGRCartoDBGeomFieldDefn *poFieldDefn =
                            new OGRCartoDBGeomFieldDefn(pszAttname, eType);
                        if( bNotNull )
                            poFieldDefn->SetNullable(FALSE);
                        OGRSpatialReference* poSRS = NULL;
                        if( pszSRText != NULL )
                        {
                            poSRS = new OGRSpatialReference();
                            char* pszTmp = (char* )pszSRText;
                            if( poSRS->importFromWkt(&pszTmp) != OGRERR_NONE )
                            {
                                delete poSRS;
                                poSRS = NULL;
                            }
                            if( poSRS != NULL )
                            {
                                poFieldDefn->SetSpatialRef(poSRS);
                                poSRS->Release();
                            }
                        }
                        poFieldDefn->nSRID = nSRID;
                        poFeatureDefn->AddGeomFieldDefn(poFieldDefn, FALSE);
                    }
                    else
                    {
                        OGRFieldDefn oField(pszAttname, OFTString);
                        if( bNotNull )
                            oField.SetNullable(FALSE);
                        OGRPGCommonLayerSetType(oField, pszType, pszFormatType, nWidth);
                        if( pszDefault )
                            OGRPGCommonLayerNormalizeDefault(&oField, pszDefault);

                        poFeatureDefn->AddFieldDefn( &oField );
                    }
                }
                delete poFeat;
            }

            poDS->ReleaseResultSet(poLyr);
        }
    }

    if( poFeatureDefn == NULL )
    {
        osBaseSQL.Printf("SELECT * FROM %s", OGRCARTODBEscapeIdentifier(osName).c_str());
        EstablishLayerDefn(osName, NULL);
        osBaseSQL = "";
    }

    if( osFIDColName.size() > 0 )
    {
        osBaseSQL = "SELECT ";
        osBaseSQL += OGRCARTODBEscapeIdentifier(osFIDColName);
    }
    for(int i=0; i<poFeatureDefn->GetGeomFieldCount(); i++)
    {
        if( osBaseSQL.size() == 0 )
            osBaseSQL = "SELECT ";
        else
            osBaseSQL += ", ";
        osBaseSQL += OGRCARTODBEscapeIdentifier(poFeatureDefn->GetGeomFieldDefn(i)->GetNameRef());
    }
    for(int i=0; i<poFeatureDefn->GetFieldCount(); i++)
    {
        if( osBaseSQL.size() == 0 )
            osBaseSQL = "SELECT ";
        else
            osBaseSQL += ", ";
        osBaseSQL += OGRCARTODBEscapeIdentifier(poFeatureDefn->GetFieldDefn(i)->GetNameRef());
    }
    if( osBaseSQL.size() == 0 )
        osBaseSQL = "SELECT *";
    osBaseSQL += " FROM ";
    osBaseSQL += OGRCARTODBEscapeIdentifier(osName);

    osSELECTWithoutWHERE = osBaseSQL;

    return poFeatureDefn;
}
Beispiel #7
0
CPLErr OGRMDBLayer::Initialize( CPL_UNUSED const char *pszTableName,
                                const char *pszGeomCol,
                                int nShapeType,
                                double dfExtentLeft,
                                double dfExtentRight,
                                double dfExtentBottom,
                                double dfExtentTop,
                                int nSRID,
                                int bHasZ )


{
    CPLFree( pszGeomColumn );

    if( pszGeomCol == NULL )
        pszGeomColumn = NULL;
    else
    {
        pszGeomColumn = CPLStrdup( pszGeomCol );
        iGeomColumn = poMDBTable->GetColumnIndex( pszGeomColumn );
    }

    CPLFree( pszFIDColumn );
    pszFIDColumn = NULL;

    bHasExtent = TRUE;
    sExtent.MinX = dfExtentLeft;
    sExtent.MaxX = dfExtentRight;
    sExtent.MinY = dfExtentBottom;
    sExtent.MaxY = dfExtentTop;

    LookupSRID( nSRID );

    eGeometryType = MDB_GEOM_PGEO;

    CPLErr eErr;
    eErr = BuildFeatureDefn();
    if( eErr != CE_None )
        return eErr;

/* -------------------------------------------------------------------- */
/*      Setup geometry type.                                            */
/* -------------------------------------------------------------------- */
    OGRwkbGeometryType  eOGRType;

    switch( nShapeType )
    {
        case ESRI_LAYERGEOMTYPE_NULL:
            eOGRType = wkbNone;
            break;

        case ESRI_LAYERGEOMTYPE_POINT:
            eOGRType = wkbPoint;
            break;

        case ESRI_LAYERGEOMTYPE_MULTIPOINT:
            eOGRType = wkbMultiPoint;
            break;

        case ESRI_LAYERGEOMTYPE_POLYLINE:
            eOGRType = wkbLineString;
            break;

        case ESRI_LAYERGEOMTYPE_POLYGON:
        case ESRI_LAYERGEOMTYPE_MULTIPATCH:
            eOGRType = wkbPolygon;
            break;

        default:
            CPLDebug("MDB", "Unexpected value for shape type : %d", nShapeType);
            eOGRType = wkbUnknown;
            break;
    }

    if( eOGRType != wkbUnknown && eOGRType != wkbNone && bHasZ )
        eOGRType = wkbSetZ(eOGRType);

    poFeatureDefn->SetGeomType(eOGRType);

    return CE_None;
}
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;
}