/*! \brief Write (dump) category index in text form to file \param Map pointer to Map_info structure \param[out] out output file \return 1 on success \return 0 on error */ int Vect_cidx_dump(const struct Map_info *Map, FILE * out) { int i, field, nfields, ntypes; G_debug(2, "Vect_cidx_dump()"); check_status(Map); nfields = Vect_cidx_get_num_fields(Map); fprintf(out, "---------- CATEGORY INDEX DUMP: Number of layers: %d " "--------------------------------------\n", nfields); for (i = 0; i < nfields; i++) { int j, nucats, ncats; field = Vect_cidx_get_field_number(Map, i); nucats = Vect_cidx_get_num_unique_cats_by_index(Map, i); ncats = Vect_cidx_get_num_cats_by_index(Map, i); ntypes = Vect_cidx_get_num_types_by_index(Map, i); fprintf(out, "Layer %6d number of unique cats: %7d number of " "cats: %7d number of types: %d\n", field, nucats, ncats, ntypes); fprintf(out, SEP); fprintf(out, " type | count\n"); for (j = 0; j < ntypes; j++) { int type, count; Vect_cidx_get_type_count_by_index(Map, i, j, &type, &count); fprintf(out, " %5d | %9d\n", type, count); } fprintf(out, " category | type | line/area\n"); for (j = 0; j < ncats; j++) { int cat, type, id; Vect_cidx_get_cat_by_index(Map, i, j, &cat, &type, &id); fprintf(out, "%9d | %4d | %9d\n", cat, type, id); } fprintf(out, SEP); } return 1; }
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); } }