Esempio n. 1
0
QStringList QgsGrassSelect::vectorLayers( QString gisdbase,
    QString location, QString mapset, QString mapName )
{
  QStringList list;

  // Set location
  QgsGrass::setLocation( gisdbase, location );

  /* Open vector */
  QgsGrass::resetError();
  //Vect_set_open_level( 2 );
  struct Map_info map;
  int level = -1;

  try
  {
    level = Vect_open_old_head( &map, ( char * ) mapName.toUtf8().data(), ( char * ) mapset.toUtf8().data() );
  }
  catch ( QgsGrass::Exception &e )
  {
    Q_UNUSED( e );
    QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) );
    return list;
  }

  if ( level == 1 )
  {
    QgsDebugMsg( "Cannot open vector on level 2" );
    QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector %1 in mapset %2 on level 2 (topology not available, try to rebuild topology using v.build module)." ).arg( mapName ).arg( mapset ) );
    // Vect_close here is correct, it should work, but it seems to cause
    // crash on win http://trac.osgeo.org/qgis/ticket/2003
    // disabled on win test it
#if !defined(WIN32)
    Vect_close( &map );
#endif
    return list;
  }
  else if ( level < 1 )
  {
    QgsDebugMsg( "Cannot open vector" );
    QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector %1 in mapset %2" ).arg( mapName ).arg( mapset ) );
    return list;
  }

  QgsDebugMsg( "GRASS vector successfully opened" );


  // Get layers
  int ncidx = Vect_cidx_get_num_fields( &map );

  for ( int i = 0; i < ncidx; i++ )
  {
    int field = Vect_cidx_get_field_number( &map, i );
    QString fs;
    fs.sprintf( "%d", field );

    QgsDebugMsg( QString( "i = %1 layer = %2" ).arg( i ).arg( field ) );

    /* Points */
    int npoints = Vect_cidx_get_type_count( &map, field, GV_POINT );
    if ( npoints > 0 )
    {
      QString l = fs + "_point";
      list.append( l );
    }

    /* Lines */
    /* Lines without category appears in layer 0, but not boundaries */
    int tp;
    if ( field == 0 )
      tp = GV_LINE;
    else
      tp = GV_LINE | GV_BOUNDARY;

    int nlines = Vect_cidx_get_type_count( &map, field, tp );
    if ( nlines > 0 )
    {
      QString l = fs + "_line";
      list.append( l );
    }

    /* Polygons */
    int nareas = Vect_cidx_get_type_count( &map, field, GV_AREA );
    if ( nareas > 0 )
    {
      QString l = fs + "_polygon";
      list.append( l );
    }
  }
  Vect_close( &map );

  return list;
}
Esempio n. 2
0
// Slot called when the "Add GRASS vector layer" menu item is triggered
void QgsGrassPlugin::addVector()
{
// QgsDebugMsg("entered.");
  QString uri;

  QgsGrassSelect *sel = new QgsGrassSelect( qGisInterface->mainWindow(), QgsGrassSelect::VECTOR );
  if ( sel->exec() )
  {
    uri = sel->gisdbase + "/" + sel->location + "/" + sel->mapset + "/" + sel->map + "/" + sel->layer;
  }
// QgsDebugMsg(QString("plugin URI: %1").arg(uri));
  if ( uri.length() == 0 )
  {
// QgsDebugMsg("Nothing was selected");
    return;
  }
  else
  {
// QgsDebugMsg("Add new vector layer");

    // create vector name: vector layer
    QString name = sel->map;

    QString field;
    QString type;

    if ( !sel->layer.startsWith( "topo_" ) )
    {
      QRegExp rx( "(\\d+)_(.+)" );
      if ( rx.indexIn( sel->layer ) != -1 )
      {
        field = rx.cap( 1 );
        type = rx.cap( 2 );
      }
    }

    // Set location
    QgsGrass::setLocation( sel->gisdbase, sel->location );

    /* Open vector */
    try
    {
      //Vect_set_open_level( 2 );
      struct Map_info map;
      int level = Vect_open_old_head( &map, sel->map.toUtf8().data(),
                                      sel->mapset.toUtf8().data() );

      if ( level == 1 )
      {
        QgsDebugMsg( "Cannot open vector on level 2" );
        QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector %1 in mapset %2 on level 2 (topology not available, try to rebuild topology using v.build module)." ).arg( sel->map ).arg( sel->mapset ) );
        Vect_close( &map );
        return;
      }
      else if ( level < 1 )
      {
        QgsDebugMsg( "Cannot open vector" );
        QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector %1 in mapset %2" ).arg( sel->map ).arg( sel->mapset ) );
        return;
      }

      if ( level >= 2 )
      {
        if ( !sel->layer.startsWith( "topo_" ) )
        {
          // Count layers
          int cnt = 0;
          int ncidx = Vect_cidx_get_num_fields( &map );

          for ( int i = 0; i < ncidx; i++ )
          {
            int field = Vect_cidx_get_field_number( &map, i );

            if ( Vect_cidx_get_type_count( &map, field, GV_POINT | GV_LINE | GV_AREA ) > 0 ||
                 ( field > 1 && Vect_cidx_get_type_count( &map, field, GV_BOUNDARY ) ) )
            {
              cnt++;
            }
          }

          if ( cnt > 1 )
          {
            name.append( " " + field );

            // No need to ad type, the type is obvious from the legend
          }
        }
        else
        {
          name.append( " " + sel->layer );
        }
      }

      Vect_close( &map );
    }
    catch ( QgsGrass::Exception &e )
    {
      QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open GRASS vector:\n %1" ).arg( e.what() ) );
    }

    qGisInterface->addVectorLayer( uri, name, "grass" );
  }
}
OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
{
    CPLDebug ( "GRASS", "OGRGRASSLayer::OGRGRASSLayer layerIndex = %d", layerIndex );
    
    iLayerIndex = layerIndex;
    poMap = map; 
    poSRS = NULL;
    iNextId = 0;
    poPoints = Vect_new_line_struct();
    poCats = Vect_new_cats_struct();
    pszQuery = NULL;
    paQueryMatch = NULL;
    paSpatialMatch = NULL;

    iLayer = Vect_cidx_get_field_number ( poMap, iLayerIndex);
    CPLDebug ( "GRASS", "iLayer = %d", iLayer );
    
    poLink = Vect_get_field ( poMap, iLayer ); // May be NULL if not defined

    // Layer name
    if ( poLink && poLink->name )
    {
	pszName = CPLStrdup( poLink->name );	
    }
    else
    {	
	char buf[20]; 
	sprintf ( buf, "%d", iLayer ); 
	pszName = CPLStrdup( buf );
    }

    // Because we don't represent centroids as any simple feature, we have to scan
    // category index and create index of feature IDs pointing to category index
    nTotalCount = Vect_cidx_get_type_count(poMap,iLayer, GV_POINT|GV_LINES|GV_AREA);
    CPLDebug ( "GRASS", "nTotalCount = %d", nTotalCount );
    paFeatureIndex = (int *) CPLMalloc ( nTotalCount * sizeof(int) );
    
    int n = Vect_cidx_get_type_count(poMap,iLayer, GV_POINTS|GV_LINES|GV_AREA);
    int cnt = 0;
    for ( int i = 0; i < n; i++ ) 
    {
	int cat,type, id;
	
	Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, i, &cat, &type, &id );
    
	if ( !( type & (GV_POINT|GV_LINES|GV_AREA) ) ) continue;
	paFeatureIndex[cnt++] = i;
    }

    poFeatureDefn = new OGRFeatureDefn( pszName );
    poFeatureDefn->Reference();

    // Get type definition
    int nTypes = Vect_cidx_get_num_types_by_index ( poMap, iLayerIndex );
    int types = 0;
    for ( int i = 0; i < nTypes; i++ ) {
	int type, count;
	Vect_cidx_get_type_count_by_index ( poMap, iLayerIndex, i, &type, &count);
	if ( !(type & (GV_POINT|GV_LINES|GV_AREA) ) ) continue;
	types |= type;
        CPLDebug ( "GRASS", "type = %d types = %d", type, types );
    }
    
    OGRwkbGeometryType eGeomType = wkbUnknown;
    if ( types == GV_LINE || types == GV_BOUNDARY || types == GV_LINES ) 
    {
        eGeomType = wkbLineString;
    } 
    else if ( types == GV_POINT )
    {
        eGeomType = wkbPoint;
    }
    else if ( types == GV_AREA )
    {
        CPLDebug ( "GRASS", "set wkbPolygon" );
        eGeomType = wkbPolygon;
    }

    if (Vect_is_3d(poMap))
        poFeatureDefn->SetGeomType ( (OGRwkbGeometryType)(eGeomType | wkb25DBit) );
    else
        poFeatureDefn->SetGeomType ( eGeomType );

    // Get attributes definition
    poDbString = (dbString*) CPLMalloc ( sizeof(dbString) );
    poCursor = (dbCursor*) CPLMalloc ( sizeof(dbCursor) );
    bCursorOpened = FALSE;

    poDriver = NULL;
    bHaveAttributes = false;
    db_init_string ( poDbString );
    if ( poLink ) 
    {
	if ( StartDbDriver() ) 
	{
	    db_set_string ( poDbString, poLink->table );
	    dbTable *table;
	    if ( db_describe_table ( poDriver, poDbString, &table) == DB_OK )
	    {
		nFields = db_get_table_number_of_columns ( table );
		iCatField = -1;
		for ( int i = 0; i < nFields; i++) 
		{
		    dbColumn *column = db_get_table_column ( table, i );
		    int ctype = db_sqltype_to_Ctype ( db_get_column_sqltype(column) );
    
		    OGRFieldType ogrFtype = OFTInteger;
 	     	    switch ( ctype ) {
			 case DB_C_TYPE_INT:
			    ogrFtype = OFTInteger;
			    break; 
			 case DB_C_TYPE_DOUBLE:
			    ogrFtype = OFTReal;
			    break; 
			 case DB_C_TYPE_STRING:
			    ogrFtype = OFTString;
			    break; 
			 case DB_C_TYPE_DATETIME:
			    ogrFtype = OFTDateTime;
			    break; 
		    }

		    CPLDebug ( "GRASS", "column = %s type = %d", 
			       db_get_column_name(column), ctype );
		    
		    OGRFieldDefn oField ( db_get_column_name(column), ogrFtype );
		    poFeatureDefn->AddFieldDefn( &oField );

		    if ( G_strcasecmp(db_get_column_name(column),poLink->key) == 0 )
		    {
			iCatField = i;
		    }
		}
		if ( iCatField >= 0  ) 
		{
    		    bHaveAttributes = true;
		}
		else
		{
		    CPLError( CE_Failure, CPLE_AppDefined, "Cannot find key field" );
		    db_close_database_shutdown_driver ( poDriver );
		    poDriver = NULL;
		}
	    }
	    else
	    {
		CPLError( CE_Failure, CPLE_AppDefined, "Cannot describe table %s", 
			  poLink->table );

	    }
	    db_close_database_shutdown_driver ( poDriver );
	    poDriver = NULL;
	}
    } 
	
    if ( !bHaveAttributes && iLayer > 0 ) // Because features in layer 0 have no cats  
    {
	OGRFieldDefn oField("cat", OFTInteger);
	poFeatureDefn->AddFieldDefn( &oField );
    }

    if ( getenv("GISBASE") )  // We have some projection info in GISBASE
    {
        struct Key_Value *projinfo, *projunits;

	// Note: we dont have to reset GISDBASE and LOCATION_NAME because 
	// OGRGRASSLayer constructor is called from OGRGRASSDataSource::Open
	// where those variables are set

        projinfo = G_get_projinfo();
	projunits = G_get_projunits();

	char *srsWkt = GPJ_grass_to_wkt ( projinfo, projunits, 0, 0);
	if ( srsWkt ) 
	{
	    poSRS = new OGRSpatialReference ( srsWkt );
	    CPLFree ( srsWkt );
	}

        G_free_key_value(projinfo);
        G_free_key_value(projunits);
    }
}