⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgsgrassprovider.cpp

📁 一个非常好的GIS开源新版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {      // the map is already opened, return map id#ifdef QGISDEBUG      std::cerr << "The map is already opened with ID = " << i << std::endl;#endif      mMaps[i].nUsers++;      return i;    }  }  GMAP map;  map.valid = false;  map.frozen = false;  map.gisdbase = gisdbase;  map.location = location;  map.mapset = mapset;  map.mapName = mapName;  map.path = tmpPath;  map.nUsers = 1;  map.version = 1;  map.update = 0;  map.map = (struct Map_info *) malloc ( sizeof(struct Map_info) );  // Set GRASS location  QgsGrass::setLocation ( gisdbase, location ); #ifdef QGISDEBUG  std::cerr << "Setting  gisdbase, location: " << gisdbase.toLocal8Bit().data() << ", " << location.toLocal8Bit().data() << std::endl;#endif  // Find the vector  char *ms = G_find_vector2 ( (char *) mapName.ascii(), (char *) mapset.ascii()) ;  if ( ms == NULL) {    std::cerr << "Cannot find GRASS vector" << std::endl;    return -1;  }  // Read the time of vector dir before Vect_open_old, because it may take long time (when the vector  // could be owerwritten)  QFileInfo di ( gisdbase + "/" + location + "/" + mapset + "/vector/" + mapName );  map.lastModified = di.lastModified();  di.setFile ( gisdbase + "/" + location + "/" + mapset + "/vector/" + mapName + "/dbln" );  map.lastAttributesModified = di.lastModified();  // Do we have topology and cidx (level2)  int level = 2;  QgsGrass::resetError();  Vect_set_open_level (2);  Vect_open_old_head ( map.map, (char *) mapName.ascii(), (char *) mapset.ascii());  if ( QgsGrass::getError() == QgsGrass::FATAL ) {    std::cerr << "Cannot open GRASS vector head on level2: "       << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl;    level = 1;  }  else  {    Vect_close ( map.map );  }  if ( level == 1 )  {    QMessageBox::StandardButton ret = QMessageBox::question ( 0, "Warning",      "GRASS vector map " + mapName +       + " does not have topology. Build topology?",      QMessageBox::Ok | QMessageBox::Cancel );    if ( ret == QMessageBox::Cancel ) return -1;  }  // Open vector  QgsGrass::resetError(); // to "catch" error after Vect_open_old()  Vect_set_open_level (level);  Vect_open_old ( map.map, (char *) mapName.ascii(), (char *) mapset.ascii());  if ( QgsGrass::getError() == QgsGrass::FATAL ) {    std::cerr << "Cannot open GRASS vector: " << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl;    return -1;  }  if ( level == 1 )  {    QgsGrass::resetError();    Vect_build ( map.map, stderr );    if ( QgsGrass::getError() == QgsGrass::FATAL ) {      std::cerr << "Cannot build topology: "         << QgsGrass::getErrorMessage().toLocal8Bit().data()         << std::endl;      return -1;    }  }#ifdef QGISDEBUG  std::cerr << "GRASS map successfully opened" << std::endl;#endif  map.valid = true;  // Add new map to maps  mMaps.push_back(map);  return mMaps.size() - 1; // map id }void QgsGrassProvider::updateMap ( int mapId ){#ifdef QGISDEBUG  std::cerr << "QgsGrassProvider::updateMap() mapId = " << mapId << std::endl;#endif  /* Close map */  GMAP *map = &(mMaps[mapId]);  bool closeMap = map->valid;  map->valid = false;  map->version++;  QgsGrass::setLocation ( (char *) map->gisdbase.ascii(), (char *) map->location.ascii() );   // TODO: Should be done better / in other place ?  // TODO: Is it necessary for close ?  G__setenv( (char *)"MAPSET", (char *) map->mapset.ascii() );  if ( closeMap ) Vect_close ( map->map );  QFileInfo di ( map->gisdbase + "/" + map->location + "/" + map->mapset + "/vector/" + map->mapName );  map->lastModified = di.lastModified();  di.setFile ( map->gisdbase + "/" + map->location + "/" + map->mapset + "/vector/" + map->mapName + "/dbln" );  map->lastAttributesModified = di.lastModified();  // Reopen vector  QgsGrass::resetError(); // to "catch" error after Vect_open_old()  Vect_set_open_level (2);  Vect_open_old ( map->map, (char *) map->mapName.ascii(), (char *) map->mapset.ascii());  if ( QgsGrass::getError() == QgsGrass::FATAL ) {    std::cerr << "Cannot reopen GRASS vector: " << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl;    // TODO if reopen fails, mLayers should be also updated    return;  }#ifdef QGISDEBUG  std::cerr << "GRASS map successfully reopened for reading." << std::endl;#endif  for ( unsigned int i = 0; i <  mLayers.size(); i++) {    // if ( !(mLayers[i].valid) ) continue; // ?    if  ( mLayers[i].mapId == mapId ) {      loadLayerSourcesFromMap ( mLayers[i] );    }  }  map->valid = true;}void QgsGrassProvider::closeMap( int mapId ){#ifdef QGISDEBUG  std::cerr << "Close map " << mapId << " nUsers = " << mMaps[mapId].nUsers << std::endl;#endif  // TODO: not tested because delete is never used for providers  mMaps[mapId].nUsers--;  if ( mMaps[mapId].nUsers == 0 ) { // No more users, free sources#ifdef QGISDEBUG    std::cerr << "No more users -> delete map" << std::endl;#endif    // TODO: do this better, probably maintain QgsGrassEdit as one user    if ( mMaps[mapId].update ) {      QMessageBox::warning( 0, "Warning", "The vector was currently edited, "        "you can expect crash soon." );    }    if ( mMaps[mapId].valid )    {      Vect_close ( mMaps[mapId].map );    }    mMaps[mapId].valid = false;  }}bool QgsGrassProvider::mapOutdated( int mapId ){#ifdef QGISDEBUG  std::cerr << "QgsGrassProvider::mapOutdated()" << std::endl;#endif  GMAP *map = &(mMaps[mapId]);  QString dp = map->gisdbase + "/" + map->location + "/" + map->mapset + "/vector/" + map->mapName;  QFileInfo di ( dp );  if ( map->lastModified < di.lastModified() ) {#ifdef QGISDEBUG    std::cerr << "**** The map " << mapId << " was modified ****" << std::endl;#endif    return true;  }  return false;}bool QgsGrassProvider::attributesOutdated( int mapId ){#ifdef QGISDEBUG  std::cerr << "QgsGrassProvider::attributesOutdated()" << std::endl;#endif  GMAP *map = &(mMaps[mapId]);  QString dp = map->gisdbase + "/" + map->location + "/" + map->mapset + "/vector/" + map->mapName + "/dbln";  QFileInfo di ( dp );  if ( map->lastAttributesModified < di.lastModified() ) {#ifdef QGISDEBUG    std::cerr << "**** The attributes of the map " << mapId << " were modified ****" << std::endl;#endif    return true;  }  return false;}/** Set feature attributes */void QgsGrassProvider::setFeatureAttributes ( int layerId, int cat, QgsFeature *feature ){#if QGISDEBUG > 3  std::cerr << "setFeatureAttributes cat = " << cat << std::endl;#endif  if ( mLayers[layerId].nColumns > 0 ) {    // find cat    GATT key;    key.cat = cat;    GATT *att = (GATT *) bsearch ( &key, mLayers[layerId].attributes, mLayers[layerId].nAttributes,      sizeof(GATT), cmpAtt);    for (int i = 0; i < mLayers[layerId].nColumns; i++) {      if ( att != NULL ) {        Q3CString cstr( att->values[i] );        feature->addAttribute (i, QVariant(mEncoding->toUnicode(cstr)) );      } else { /* it may happen that attributes are missing -> set to empty string */        feature->addAttribute (i, QVariant());      }    }  } else {     feature->addAttribute (0, QVariant(cat));  }}void QgsGrassProvider::setFeatureAttributes ( int layerId, int cat, QgsFeature *feature, const QgsAttributeList& attlist){#if QGISDEBUG > 3  std::cerr << "setFeatureAttributes cat = " << cat << std::endl;#endif  if ( mLayers[layerId].nColumns > 0 ) {    // find cat    GATT key;    key.cat = cat;    GATT *att = (GATT *) bsearch ( &key, mLayers[layerId].attributes, mLayers[layerId].nAttributes,      sizeof(GATT), cmpAtt);    for (QgsAttributeList::const_iterator iter=attlist.begin(); iter!=attlist.end();++iter) {      if ( att != NULL ) {        Q3CString cstr( att->values[*iter] );        feature->addAttribute (*iter, QVariant( mEncoding->toUnicode(cstr) ));      } else { /* it may happen that attributes are missing -> set to empty string */        feature->addAttribute (*iter, QVariant());      }     }  } else {     feature->addAttribute (0, QVariant(cat));  }}/** Get pointer to map */struct Map_info *QgsGrassProvider::layerMap ( int layerId ){  return ( mMaps[mLayers[layerId].mapId].map );}QgsSpatialRefSys QgsGrassProvider::getSRS(){  QString WKT;  struct Cell_head cellhd;  QgsGrass::setLocation ( mGisdbase, mLocation );   G_get_default_window(&cellhd);  if (cellhd.proj != PROJECTION_XY) {    struct Key_Value *projinfo = G_get_projinfo();    struct Key_Value *projunits = G_get_projunits();    char *wkt = GPJ_grass_to_wkt ( projinfo, projunits,  0, 0 );    WKT = QString(wkt);    free ( wkt);  }  QgsSpatialRefSys srs;  srs.createFromWkt(WKT);  return srs;}int QgsGrassProvider::grassLayer(){  return mLayerField;}int QgsGrassProvider::grassLayer(QString name){  // Get field number  int pos = name.find('_');  if ( pos == -1 ) {    return -1;  }  return name.left(pos).toInt();}int QgsGrassProvider::grassLayerType(QString name){  int pos = name.find('_');  if ( pos == -1 ) {    return -1;  }  QString ts = name.right( name.length() - pos - 1 );  if ( ts.compare("point") == 0 ) {    return GV_POINT; // ?! centroids may be points  } else if ( ts.compare("line") == 0 ) {    return GV_LINES;   } else if ( ts.compare("polygon") == 0 ) {    return GV_AREA;   }  return -1;}//-----------------------------------------  Edit -------------------------------------------------------bool QgsGrassProvider::isGrassEditable ( void ){#ifdef QGISDEBUG  std::cerr << "QgsGrassProvider::isGrassEditable" << std::endl;#endif  if ( !isValid() )     return false;  /* Check if current user is owner of mapset */  if ( G__mapset_permissions2((char*)mGisdbase.ascii(),(char*)mLocation.ascii(),(char*)mMapset.ascii()) != 1 )    return false;  // TODO: check format? (cannot edit OGR layers)  return true;}bool QgsGrassProvider::isEdited ( void ){#if QGISDEBUG > 3  std::cerr << "QgsGrassProvider::isEdited" << std::endl;#endif  GMAP *map = &(mMaps[mLayers[mLayerId].mapId]);  return (map->update);}bool QgsGrassProvider::isFrozen ( void ){#if QGISDEBUG > 3  std::cerr << "QgsGrassProvider::isFrozen" << std::endl;#endif  GMAP *map = &(mMaps[mLayers[mLayerId].mapId]);  return (map->frozen);}void QgsGrassProvider::freeze(){#ifdef QGISDEBUG  std::cerr << "QgsGrassProvider::freeze" << std::endl;#endif  if ( !isValid() ) return;  GMAP *map = &(mMaps[mLayers[mLayerId].mapId]);  if ( map->frozen ) return;  map->frozen = true;  Vect_close ( map->map );}void QgsGrassProvider::thaw(){#ifdef QGISDEBUG  std::cerr << "QgsGrassProvider::thaw" << std::endl;#endif  if ( !isValid() ) return;  GMAP *map = &(mMaps[mLayers[mLayerId].mapId]);  if ( !map->frozen ) return;  if ( reopenMap() )   {    map->frozen = false;  }}bool QgsGrassProvider::startEdit ( void ){#ifdef QGISDEBUG  std::cerr << "QgsGrassProvider::startEdit" << std::endl;  std::cerr << "  uri = " << dataSourceUri().toLocal8Bit().data() << std::endl;  std::cerr << "  mMaps.size() = " << mMaps.size() << std::endl;#endif  if ( !isGrassEditable() )    return false;  // Check number of maps (the problem may appear if static variables are not shared - runtime linker)  if ( mMaps.size() == 0 ) {    QMessageBox::warning( 0, "Warning", "No maps opened in mMaps, probably problem in runtime linking, "       "static variables are not shared by provider and plugin." );    return false;  }  /* Close map */  GMAP *map = &(mMaps[mLayers[mLayerId].mapId]);  map->valid = false;  QgsGrass::setLocation ( (char *) map->gisdbase.ascii(), (char *) map->location.ascii() );   // Set current mapset (mapset was previously checked by isGrassEditable() )  // TODO: Should be done better / in other place ?  G__setenv( (char *)"MAPSET", (char *) map->mapset.ascii() );  Vect_close ( map->map );  // TODO: Catch error   QgsGrass::resetError();  int level = Vect_open_update ( map->map, (char *) map->mapName.ascii(), (char *) map->mapset.ascii() );  if (  level < 2 ) {     if ( QgsGrass::getError() == QgsGrass::FATAL ) {      std::cerr << "Cannot open GRASS vector for update: " << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl;    } else {      std::cerr << "Cannot open GRASS vector for update on level 2." << std::endl;    }    // reopen vector for reading    QgsGrass::resetError();    Vect_set_open_level (2);    level = Vect_open_old ( map->map, (char *) map->mapName.ascii(), (char *) map->mapset.ascii() );    if ( level < 2 ) {      if ( QgsGrass::getError() == QgsGrass::FATAL ) {        std::cerr << "Cannot reopen GRASS vector: " << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl;      } else {        std::cerr << "Cannot reopen GRASS vector on level 2." << std::endl;      }    } else {      map->valid = true;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -