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