📄 qgsgrassprovider.cpp
字号:
Vect_append_point( Polygon, rect.xMin(), rect.yMax(), 0); Vect_append_point( Polygon, rect.xMin(), rect.yMin(), 0); if ( mLayerType == POINT || mLayerType == CENTROID || mLayerType == LINE || mLayerType == BOUNDARY ) { Vect_select_lines_by_polygon ( mMap, Polygon, 0, NULL, mGrassType, mList); } else if ( mLayerType == POLYGON ) { Vect_select_areas_by_polygon ( mMap, Polygon, 0, NULL, mList); } Vect_destroy_line_struct (Polygon); } for ( int i = 0; i < mList->n_values; i++ ) { if ( mList->value[i] <= mSelectionSize ) { mSelection[mList->value[i]] = 1; } else { std::cerr << "Selected element out of range" << std::endl; } } }QgsRect QgsGrassProvider::extent(){ BOUND_BOX box; Vect_get_map_box ( mMap, &box ); return QgsRect( box.W, box.S, box.E, box.N);}/** * Return the feature type*/QGis::WKBTYPE QgsGrassProvider::geometryType() const{ return mQgisType;}/** * Return the feature type*/long QgsGrassProvider::featureCount() const { return mNumberFeatures;}/*** Return the number of fields*/uint QgsGrassProvider::fieldCount() const{#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::fieldCount() return:" << mLayers[mLayerId].fields.size() << std::endl;#endif return mLayers[mLayerId].fields.size();}/*** Return fields*/const QgsFieldMap & QgsGrassProvider::fields() const{ return mLayers[mLayerId].fields;}int QgsGrassProvider::keyField(){ return mLayers[mLayerId].keyColumn;}void QgsGrassProvider::reset(){ if ( isEdited() || isFrozen() || !mValid ) return; int mapId = mLayers[mLayerId].mapId; if ( mapOutdated(mapId) ) { updateMap ( mapId ); } if ( mMapVersion < mMaps[mapId].version ) { update(); } if ( attributesOutdated(mapId) ) { loadAttributes (mLayers[mLayerId]); } mNextCidx = 0;}QVariant QgsGrassProvider::minValue(int index){ if (!fields().contains(index)) { QgsDebugMsg("Warning: access requested to invalid field index: " + QString::number(index)); return QVariant(); } return QVariant(mLayers[mLayerId].minmax[index][0]);} QVariant QgsGrassProvider::maxValue(int index){ if (!fields().contains(index)) { QgsDebugMsg("Warning: access requested to invalid field index: " + QString::number(index)); return QVariant(); } return QVariant(mLayers[mLayerId].minmax[index][1]);}bool QgsGrassProvider::isValid(){#ifdef QGISDEBUG QString validString = mValid?"true":"false"; std::cerr << "QgsGrassProvider::isValid() returned: " << validString.toLocal8Bit().data() << std::endl;#endif return mValid;}// ------------------------------------------------------------------------------------------------------// Compare categories in GATTstatic int cmpAtt ( const void *a, const void *b ){ GATT *p1 = (GATT *) a; GATT *p2 = (GATT *) b; return (p1->cat - p2->cat);}/* returns layerId or -1 on error */int QgsGrassProvider::openLayer(QString gisdbase, QString location, QString mapset, QString mapName, int field){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::openLayer()" << std::endl; std::cerr << "gisdbase: " << gisdbase.toLocal8Bit().data() << std::endl; std::cerr << "location: " << location.toLocal8Bit().data() << std::endl; std::cerr << "mapset: " << mapset.toLocal8Bit().data() << std::endl; std::cerr << "mapName: " << mapName.toLocal8Bit().data() << std::endl; std::cerr << "field: " << field << std::endl;#endif // Check if this layer is already opened for ( unsigned int i = 0; i < mLayers.size(); i++) { if ( !(mLayers[i].valid) ) continue; GMAP *mp = &(mMaps[mLayers[i].mapId]); if ( mp->gisdbase == gisdbase && mp->location == location && mp->mapset == mapset && mp->mapName == mapName && mLayers[i].field == field ) { // the layer already exists, return layer id#ifdef QGISDEBUG std::cerr << "The layer is already opened with ID = " << i << std::endl;#endif mLayers[i].nUsers++; return i; } } // Create a new layer GLAYER layer; layer.valid = false; layer.field = field; layer.nUsers = 1; // Open map layer.mapId = openMap ( gisdbase, location, mapset, mapName ); if ( layer.mapId < 0 ) { std::cerr << "Cannot open vector map" << std::endl; return -1; }#ifdef QGISDEBUG std::cerr << "layer.mapId = " << layer.mapId << std::endl;#endif layer.map = mMaps[layer.mapId].map; layer.attributes = 0; // because loadLayerSourcesFromMap will release old loadLayerSourcesFromMap ( layer ); layer.valid = true; // Add new layer to layers mLayers.push_back(layer);#ifdef QGISDEBUG std::cerr << "New layer successfully opened" << layer.nAttributes << std::endl;#endif return mLayers.size() - 1; }void QgsGrassProvider::loadLayerSourcesFromMap ( GLAYER &layer ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::loadLayerSourcesFromMap" << std::endl;#endif // Reset and free layer.fields.clear(); if ( layer.attributes ) { for ( int i = 0; i < layer.nAttributes; i ++ ) { for ( int j = 0; j < layer.nColumns; j ++ ) { if ( layer.attributes[i].values[j] ) free ( layer.attributes[i].values[j] ); } free ( layer.attributes[i].values ); } free ( layer.attributes ); } loadAttributes ( layer );} void QgsGrassProvider::loadAttributes ( GLAYER &layer ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::loadLayerSourcesFromMap" << std::endl;#endif // TODO: free old attributes if ( !layer.map ) return; // Get field info layer.fieldInfo = Vect_get_field( layer.map, layer.field); // should work also with field = 0 // Read attributes layer.nColumns = 0; layer.nAttributes = 0; layer.attributes = 0; layer.fields.clear(); layer.keyColumn = -1; if ( layer.fieldInfo == NULL ) {#ifdef QGISDEBUG std::cerr << "No field info -> no attribute table" << std::endl;#endif } else { #ifdef QGISDEBUG std::cerr << "Field info found -> open database" << std::endl;#endif dbDriver *databaseDriver = db_start_driver_open_database ( layer.fieldInfo->driver, layer.fieldInfo->database ); if ( databaseDriver == NULL ) { std::cerr << "Cannot open database " << layer.fieldInfo->database << " by driver " << layer.fieldInfo->driver << std::endl; } else {#ifdef QGISDEBUG std::cerr << "Database opened -> open select cursor" << std::endl;#endif dbString dbstr; db_init_string (&dbstr); db_set_string (&dbstr, (char *)"select * from "); db_append_string (&dbstr, layer.fieldInfo->table);#ifdef QGISDEBUG std::cerr << "SQL: " << db_get_string(&dbstr) << std::endl;#endif dbCursor databaseCursor; if ( db_open_select_cursor(databaseDriver, &dbstr, &databaseCursor, DB_SCROLL) != DB_OK ){ layer.nColumns = 0; db_close_database_shutdown_driver ( databaseDriver ); QMessageBox::warning( 0, "Warning", "Cannot select attributes from table '" + QString(layer.fieldInfo->table) + "'" ); } else { int nRecords = db_get_num_rows ( &databaseCursor );#ifdef QGISDEBUG std::cerr << "Number of records: " << nRecords << std::endl;#endif dbTable *databaseTable = db_get_cursor_table (&databaseCursor); layer.nColumns = db_get_table_number_of_columns(databaseTable); layer.minmax = new double[layer.nColumns][2]; // Read columns' description for (int i = 0; i < layer.nColumns; i++) { layer.minmax[i][0] = DBL_MAX; layer.minmax[i][1] = -DBL_MAX; dbColumn *column = db_get_table_column (databaseTable, i); int ctype = db_sqltype_to_Ctype ( db_get_column_sqltype(column) ); QVariant::Type qtype = QVariant::String; //default to string#ifdef QGISDEBUG std::cerr << "column = " << db_get_column_name(column) << " ctype = " << ctype << std::endl;#endif QString ctypeStr; switch ( ctype ) { case DB_C_TYPE_INT: ctypeStr = "integer"; qtype = QVariant::Int; break; case DB_C_TYPE_DOUBLE: ctypeStr = "double"; qtype = QVariant::Double; break; case DB_C_TYPE_STRING: ctypeStr = "string"; qtype = QVariant::String; break; case DB_C_TYPE_DATETIME: ctypeStr = "datetime"; qtype = QVariant::String; break; } layer.fields[i] = QgsField( db_get_column_name(column), qtype, ctypeStr, db_get_column_length(column), db_get_column_precision(column) ); if ( G_strcasecmp ( db_get_column_name(column), layer.fieldInfo->key) == 0 ) { layer.keyColumn = i; } } if ( layer.keyColumn < 0 ) { layer.fields.clear(); layer.nColumns = 0; QMessageBox::warning( 0, "Warning", "Key column '" + QString(layer.fieldInfo->key) + "' not found in the table '" + QString(layer.fieldInfo->table) + "'" ); } else { // Read attributes to the memory layer.attributes = (GATT *) malloc ( nRecords * sizeof(GATT) ); while ( 1 ) { int more; if ( db_fetch (&databaseCursor, DB_NEXT, &more) != DB_OK ) { std::cout << "Cannot fetch DB record" << std::endl; break; } if ( !more ) break; // no more records // Check cat value dbColumn *column = db_get_table_column (databaseTable, layer.keyColumn); dbValue *value = db_get_column_value(column); if ( db_test_value_isnull(value) ) continue; layer.attributes[layer.nAttributes].cat = db_get_value_int (value); if ( layer.attributes[layer.nAttributes].cat < 0 ) continue; layer.attributes[layer.nAttributes].values = (char **) malloc ( layer.nColumns * sizeof(char*) ); for (int i = 0; i < layer.nColumns; i++) { column = db_get_table_column (databaseTable, i); int sqltype = db_get_column_sqltype(column); int ctype = db_sqltype_to_Ctype ( sqltype ); value = db_get_column_value(column); db_convert_value_to_string ( value, sqltype, &dbstr);#if QGISDEBUG > 3 std::cout << "column: " << db_get_column_name(column) << std::endl; std::cout << "value: " << db_get_string(&dbstr) << std::endl;#endif layer.attributes[layer.nAttributes].values[i] = strdup ( db_get_string(&dbstr) ); if ( !db_test_value_isnull(value) ) { double dbl; if ( ctype == DB_C_TYPE_INT ) { dbl = db_get_value_int ( value ); } else if ( ctype == DB_C_TYPE_DOUBLE ) { dbl = db_get_value_double ( value ); } else { dbl = 0; } if ( dbl < layer.minmax[i][0] ) { layer.minmax[i][0] = dbl; } if ( dbl > layer.minmax[i][1] ) { layer.minmax[i][1] = dbl; } } } layer.nAttributes++; } // Sort attributes by category qsort ( layer.attributes, layer.nAttributes, sizeof(GATT), cmpAtt ); } db_close_cursor (&databaseCursor); db_close_database_shutdown_driver ( databaseDriver ); db_free_string(&dbstr);#ifdef QGISDEBUG std::cerr << "fields.size = " << layer.fields.size() << std::endl; std::cerr << "number of attributes = " << layer.nAttributes << std::endl;#endif } } } // Add cat if no attribute fields exist (otherwise qgis crashes) if ( layer.nColumns == 0 ) { layer.keyColumn = 0; layer.fields[0] = ( QgsField( "cat", QVariant::Int, "integer") ); layer.minmax = new double[1][2]; layer.minmax[0][0] = 0; layer.minmax[0][1] = 0; int cidx = Vect_cidx_get_field_index ( layer.map, layer.field ); if ( cidx >= 0 ) { int ncats, cat, type, id; ncats = Vect_cidx_get_num_cats_by_index ( layer.map, cidx ); if ( ncats > 0 ) { Vect_cidx_get_cat_by_index ( layer.map, cidx, 0, &cat, &type, &id ); layer.minmax[0][0] = cat; Vect_cidx_get_cat_by_index ( layer.map, cidx, ncats-1, &cat, &type, &id ); layer.minmax[0][1] = cat; } } } GMAP *map = &(mMaps[layer.mapId]); QFileInfo di ( map->gisdbase + "/" + map->location + "/" + map->mapset + "/vector/" + map->mapName + "/dbln" ); map->lastAttributesModified = di.lastModified();}void QgsGrassProvider::closeLayer( int layerId ){#ifdef QGISDEBUG std::cerr << "Close layer " << layerId << " nUsers = " << mLayers[layerId].nUsers << std::endl;#endif // TODO: not tested because delete is never used for providers mLayers[layerId].nUsers--; if ( mLayers[layerId].nUsers == 0 ) { // No more users, free sources#ifdef QGISDEBUG std::cerr << "No more users -> delete layer" << std::endl;#endif mLayers[layerId].valid = false; // Column names/types mLayers[layerId].fields.clear(); // Attributes#ifdef QGISDEBUG std::cerr << "Delete attribute values" << std::endl;#endif for ( int i = 0; i < mLayers[layerId].nAttributes; i++ ) { free ( mLayers[layerId].attributes[i].values ); } free ( mLayers[layerId].attributes ); delete[] mLayers[layerId].minmax; // Field info free ( mLayers[layerId].fieldInfo ); closeMap ( mLayers[layerId].mapId ); }}/* returns mapId or -1 on error */int QgsGrassProvider::openMap(QString gisdbase, QString location, QString mapset, QString mapName){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::openMap()" << std::endl;#endif QString tmpPath = gisdbase + "/" + location + "/" + mapset + "/" + mapName; // Check if this map is already opened for ( unsigned int i = 0; i < mMaps.size(); i++) { if ( mMaps[i].valid && mMaps[i].path == tmpPath )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -