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