From 9f7e427f00fee08e1f5bff656e71d39ad4832a13 Mon Sep 17 00:00:00 2001 From: Radim Blazek Date: Mon, 17 Dec 2012 21:40:34 +0100 Subject: [PATCH] More GRASS direct functions --- src/providers/grass/CMakeLists.txt | 41 ++++++++- src/providers/grass/qgsgrassgislib.cpp | 114 +++++++++++++++++++++++-- src/providers/grass/qgsgrassgislib.h | 5 +- 3 files changed, 145 insertions(+), 15 deletions(-) diff --git a/src/providers/grass/CMakeLists.txt b/src/providers/grass/CMakeLists.txt index 2630b4356700..5d4d3d24d646 100644 --- a/src/providers/grass/CMakeLists.txt +++ b/src/providers/grass/CMakeLists.txt @@ -83,6 +83,7 @@ SET ( FUNCTIONS "G_col_to_easting" "G_convert_dirseps_to_host" "G_copy" + "G_copy_file" "G_create_key_value" "G_database_projection_name" "G_date" @@ -105,6 +106,7 @@ SET ( FUNCTIONS "G_free_key_value" "G_free_raster_cats" "G_free_reclass" + "G_free_tokens" "G_fseek" "G_ftell" "G_get_cat" @@ -121,8 +123,11 @@ SET ( FUNCTIONS "G_get_set_window" "G_gettext" "G_get_window" + "G_gisbase" + "G_home" "G_incr_void_ptr" "G_index" + "G_info_format" "G_init_cats" "G_init_cell_stats" "G_init_colors" @@ -144,6 +149,7 @@ SET ( FUNCTIONS "G_make_gyr_fp_colors" "G_make_random_colors" "G_northing_to_row" + "G_number_of_tokens" "G__projection_name" "G_percent" "G_program_name" @@ -157,15 +163,19 @@ SET ( FUNCTIONS "G_raster_size" "G_read_key_value_file" "G__realloc" + "G_recreate_command" "G_rindex" "G_row_to_northing" "G_scan_easting" "G_scan_northing" + "G_set_cat" "G_set_c_null_value" "G_set_d_null_value" "G_set_d_raster_cat" + "G_set_color" "G_set_color_range" "G_setenv" + "G_setenv2" "G_set_f_null_value" "G_set_gisrc_mode" "G_set_key_value" @@ -191,11 +201,19 @@ SET ( FUNCTIONS "G_str_to_sql" "G_str_to_upper" "G_suppress_masking" + "G_tokenize" "G_trim_decimal" "G_update_fp_range" "G_update_key_value_file" "G_update_range" + "G_usage" + "G_verbose" + "G_verbose_min" + "G_verbose_max" + "G_wait" + "G_whoami" "G_window_cols" + "G_window_overlap" "G_window_rows" "G_write_key_value_file" "G_zero" @@ -219,6 +237,7 @@ IF(MSVC) SET ( FUNCTIONS ${FUNCTIONS} "G__getenv" + "G__getenv2" "G_get_gisrc_mode" ) ENDIF(MSVC) @@ -227,12 +246,14 @@ ENDIF(MSVC) # thus we only need prototype SET ( FUNCTION_PROTOTYPES "G_area_of_cell_at_row" + "G_area_of_polygon" "G_ask_cell_new" "G_ask_cell_old" "G_asprintf" "G_begin_cell_area_calculations" "G_begin_distance_calculations" "G_begin_geodesic_distance" + "G_begin_polygon_area_calculations" "G_check_input_output_name" "G_check_overwrite" "G_clear_screen" @@ -252,8 +273,12 @@ SET ( FUNCTION_PROTOTYPES "G_find_file_misc" "G_find_file2_misc" "G_find_vector" + "G_find_vector2" + "G_fopen_modify" + "G_fopen_old" "G_fully_qualified_name" "G_geodesic_distance_lon_to_lon" + "G_geodesic_distance" "G_get_cellhd" "G_get_c_raster_row" "G_get_c_raster_row_nomask" @@ -268,9 +293,13 @@ SET ( FUNCTION_PROTOTYPES "G_get_raster_row" "G_get_raster_row_nomask" "G__gisinit" + "G_important_message" "G_legal_filename" "G_location" + "G_location_path" + "G_lookup_key_value_from_file" "G_make_aspect_fp_colors" + "G__make_mapset_element" "G_mapset" "G_maskfd" "G_message" @@ -290,6 +319,7 @@ SET ( FUNCTION_PROTOTYPES "G_read_range" "G_read_raster_cats" "G_remove" + "G_rename" "G_set_cats_title" "G_set_error_routine" "G_set_geodesic_distance_lat1" @@ -322,10 +352,13 @@ FILE(READ "${GRASS_INCLUDE_DIR}/grass/gisdefs.h" HEADER_FILE) STRING(REGEX REPLACE "(/\\*([^*]|[\r\n]|(\\*+([^*/]|[\r\n])))*\\*+/)" "" HEADER_FILE "${HEADER_FILE}") STRING(REGEX REPLACE "#[^\r\n]*" "" HEADER_FILE "${HEADER_FILE}") -# Add G_gettext defined in glocale.h +# Add functions defined in glocale.h and spawn.h SET ( HEADER_FILE ${HEADER_FILE} "char *G_gettext(const char *, const char *);" + "int G_spawn(const char *, ...);" + "int G_spawn_ex(const char *, ...);" + "int G_wait(int);" ) SET ( PROTOTYPES "// Auto generated by cmake, do not edit\n" ) @@ -352,10 +385,10 @@ FOREACH( ROW ${HEADER_FILE} ) # \\*? and \\** patterns do not work, why? STRING( REGEX REPLACE "^[ \t]*(.*)G_.*" "\\1" FUNCTION_TYPE "${ROW}" ) STRING( REGEX REPLACE "\\*" "" FUNCTION_TYPE "${FUNCTION_TYPE}" ) - STRING( REGEX REPLACE ".*(\\*+) *G_.*" "\\1" POINTER "${ROW}" ) - IF ( NOT "${POINTER}" STREQUAL "*" ) + STRING( REGEX REPLACE "[^*]*(\\*+) *G_.*" "\\1" POINTER "${ROW}" ) + IF ( (NOT "${POINTER}" STREQUAL "*") AND (NOT "${POINTER}" STREQUAL "**") ) SET ( POINTER "" ) - ENDIF ( NOT "${POINTER}" STREQUAL "*" ) + ENDIF ( (NOT "${POINTER}" STREQUAL "*") AND (NOT "${POINTER}" STREQUAL "**") ) STRING( REGEX REPLACE ".*G_[^\\(]*\\((.*)\\).*" "\\1" PARAM_TYPES "${ROW}" ) SET ( PARAM_NAMES "" ) SET ( PARAMS "" ) diff --git a/src/providers/grass/qgsgrassgislib.cpp b/src/providers/grass/qgsgrassgislib.cpp index a24bb0d358e3..28cd6860fc8d 100644 --- a/src/providers/grass/qgsgrassgislib.cpp +++ b/src/providers/grass/qgsgrassgislib.cpp @@ -316,6 +316,16 @@ int GRASS_LIB_EXPORT G_warning( const char * msg, ... ) return ret; } +typedef void G_important_message_type( const char *msg, ... ); +void GRASS_LIB_EXPORT G_important_message( const char * msg, ... ) +{ + G_important_message_type* fn = ( G_important_message_type* ) cast_to_fptr( QgsGrassGisLib::instance()->resolve( "G_important_message" ) ); + va_list ap; + va_start( ap, msg ); + fn( msg, ap ); + va_end( ap ); +} + // G_fatal_error is declared in gisdefs.h as int but noreturn //typedef int G_fatal_error_type( const char *, ... ); int GRASS_LIB_EXPORT G_fatal_error( const char * msg, ... ) @@ -413,7 +423,7 @@ char GRASS_LIB_EXPORT *G_find_file_misc( const char *dir, const char *element, c return NULL; } -char GRASS_LIB_EXPORT *G_find_file2_misc( const char *dir, const char *element, char *name, const char *mapset ) +char GRASS_LIB_EXPORT *G_find_file2_misc( const char *dir, const char *element, const char *name, const char *mapset ) { Q_UNUSED( dir ); Q_UNUSED( element ); @@ -1050,25 +1060,50 @@ double GRASS_LIB_EXPORT G_area_of_cell_at_row( int row ) return QgsGrassGisLib::instance()->G_area_of_cell_at_row( row ); } +double QgsGrassGisLib::G_area_of_polygon( const double *x, const double *y, int n ) +{ + QgsPolyline polyline; + for ( int i = 0; i < n; i++ ) + { + polyline.append( QgsPoint( x[i], y[i] ) ); + } + QgsPolygon polygon; + polygon.append( polyline ); + QgsGeometry* geo = QgsGeometry::fromPolygon( polygon ); + double area = mDistanceArea.measure( geo ); + delete geo; + if ( !mCrs.geographicFlag() ) + { + area *= qPow( G_database_units_to_meters_factor(), 2 ); + } + return area; +} + +double GRASS_LIB_EXPORT G_area_of_polygon( const double *x, const double *y, int n ) +{ + return QgsGrassGisLib::instance()->G_area_of_polygon( x, y, n ); +} + double GRASS_LIB_EXPORT G_database_units_to_meters_factor( void ) { return QgsGrassGisLib::instance()->G_database_units_to_meters_factor(); } -int QgsGrassGisLib::G_begin_cell_area_calculations( void ) +int QgsGrassGisLib::beginCalculations( void ) { - if ( mCrs.geographicFlag() ) return 2; // non-planimetric - return 1; // planimetric + if ( !mCrs.isValid() ) return 0; + if ( !mCrs.geographicFlag() ) return 1; // planimetric + return 2; // non-planimetric } int GRASS_LIB_EXPORT G_begin_cell_area_calculations( void ) { - return QgsGrassGisLib::instance()->G_begin_cell_area_calculations(); + return QgsGrassGisLib::instance()->beginCalculations(); } int GRASS_LIB_EXPORT G_begin_distance_calculations( void ) { - return 1; // nothing to do + return QgsGrassGisLib::instance()->beginCalculations(); } int GRASS_LIB_EXPORT G_begin_geodesic_distance( double a, double e2 ) @@ -1078,8 +1113,13 @@ int GRASS_LIB_EXPORT G_begin_geodesic_distance( double a, double e2 ) return 0; // nothing to do } +int GRASS_LIB_EXPORT G_begin_polygon_area_calculations( void ) +{ + return QgsGrassGisLib::instance()->beginCalculations(); +} + // Distance in meters -double QgsGrassGisLib::G_distance( double e1, double n1, double e2, double n2 ) +double QgsGrassGisLib::distance( double e1, double n1, double e2, double n2 ) { // QgsDistanceArea states that results are in meters, but it does not // seem to be true, @@ -1094,7 +1134,14 @@ double QgsGrassGisLib::G_distance( double e1, double n1, double e2, double n2 ) double GRASS_LIB_EXPORT G_distance( double e1, double n1, double e2, double n2 ) { - return QgsGrassGisLib::instance()->G_distance( e1, n1, e2, n2 ); + return QgsGrassGisLib::instance()->distance( e1, n1, e2, n2 ); +} + +// TODO: verify if QgsGrassGisLib::distance is OK, in theory +// a module could call distance for latlong even if current projection is projected +double GRASS_LIB_EXPORT G_geodesic_distance( double lon1, double lat1, double lon2, double lat2 ) +{ + return QgsGrassGisLib::instance()->distance( lon1, lat1, lon2, lat2 ); } int GRASS_LIB_EXPORT G_legal_filename( const char *s ) @@ -1204,6 +1251,14 @@ int G_asprintf( char **out, const char *fmt, ... ) return ret; } +typedef int G_lookup_key_value_from_file_type( const char *, const char *, char [], int ); +int GRASS_LIB_EXPORT G_lookup_key_value_from_file( const char *file, const char *key, char value[], int n ) +{ + G_lookup_key_value_from_file_type *fn = ( G_lookup_key_value_from_file_type* ) cast_to_fptr( QgsGrassGisLib::instance()->resolve( "G_lookup_key_value_from_file" ) ); + return fn( file, key, value, n ); +} + + int GRASS_LIB_EXPORT G__temp_element( char *element ) { Q_UNUSED( element ); @@ -1358,7 +1413,15 @@ int GRASS_LIB_EXPORT G_remove( const char *element, const char *name ) { Q_UNUSED( element ); Q_UNUSED( name ); - return 1; + return -1; // error +} + +int GRASS_LIB_EXPORT G_rename( const char *element, const char *oldname, const char *newname ) +{ + Q_UNUSED( element ); + Q_UNUSED( oldname ); + Q_UNUSED( newname ); + return -1; // error } int G_put_cell_title( const char *name, const char *title ) @@ -1375,6 +1438,39 @@ int G_clear_screen( void ) char *G_find_vector( char *name, const char *mapset ) { + Q_UNUSED( name ); + Q_UNUSED( mapset ); + return qstrdup( "qgis" ); +} + +char *G_find_vector2( const char *name, const char *mapset ) +{ + Q_UNUSED( name ); + Q_UNUSED( mapset ); + return qstrdup( "qgis" ); +} + +int G__make_mapset_element( const char *p_element ) +{ + Q_UNUSED( p_element ); + return 1; // OK +} + +char *G_location_path( void ) +{ + return qstrdup( "qgis" ); +} + +FILE *G_fopen_modify( const char *element, const char *name ) +{ + Q_UNUSED( element ); + Q_UNUSED( name ); + return NULL; +} + +FILE *G_fopen_old( const char *element, const char *name, const char *mapset ) +{ + Q_UNUSED( element ); Q_UNUSED( name ); Q_UNUSED( mapset ); return NULL; diff --git a/src/providers/grass/qgsgrassgislib.h b/src/providers/grass/qgsgrassgislib.h index febddc486577..6427f3099a96 100644 --- a/src/providers/grass/qgsgrassgislib.h +++ b/src/providers/grass/qgsgrassgislib.h @@ -90,9 +90,10 @@ class GRASS_LIB_EXPORT QgsGrassGisLib int G_get_cellhd( const char *name, const char *mapset, struct Cell_head *cellhd ); double G_area_of_cell_at_row( int row ); + double G_area_of_polygon( const double *x, const double *y, int n ); double G_database_units_to_meters_factor( void ); - int G_begin_cell_area_calculations( void ); - double G_distance( double e1, double n1, double e2, double n2 ); + int beginCalculations( void ); + double distance( double e1, double n1, double e2, double n2 ); int G_set_geodesic_distance_lat1( double lat1 ); int G_set_geodesic_distance_lat2( double lat2 );