diff -Nru libgdal-grass-3.0.4/debian/changelog libgdal-grass-3.4.3/debian/changelog --- libgdal-grass-3.0.4/debian/changelog 2020-02-08 11:29:45.000000000 +0000 +++ libgdal-grass-3.4.3/debian/changelog 2022-06-10 11:00:00.000000000 +0000 @@ -1,8 +1,342 @@ -libgdal-grass (3.0.4-1build1) focal; urgency=medium +libgdal-grass (3.4.3-2~focal1) focal; urgency=medium - * No-change rebuild with fixed binutils on arm64. + * No change rebuild for grass 8.2 - -- Matthias Klose Sat, 08 Feb 2020 11:29:45 +0000 + -- Angelos Tzotsos Fri, 10 Jun 2022 14:00:00 +0300 + +libgdal-grass (3.4.3-2~focal0) focal; urgency=medium + + * No change rebuild for focal. + + -- Angelos Tzotsos Sun, 29 May 2022 12:00:00 +0300 + +libgdal-grass (3.4.3-2) unstable; urgency=medium + + * Update packaging for GRASS 8.0.2. + + -- Bas Couwenberg Thu, 12 May 2022 16:59:05 +0200 + +libgdal-grass (3.4.3-1) unstable; urgency=medium + + * New upstream release. + * Move from experimental to unstable. + + -- Bas Couwenberg Wed, 04 May 2022 11:38:40 +0200 + +libgdal-grass (3.4.3~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + * Drop Ubuntu PIE changes. + * Update watch file to match only 3.4.x releases. + + -- Bas Couwenberg Fri, 22 Apr 2022 13:31:26 +0200 + +libgdal-grass (3.4.2-2) unstable; urgency=medium + + * Update packaging for GRASS 8.0.1. + + -- Bas Couwenberg Sun, 20 Mar 2022 07:17:56 +0100 + +libgdal-grass (3.4.2-1) unstable; urgency=medium + + * New upstream release. + * Revert GRASS 8 changes. + * Move from experimental to unstable. + + -- Bas Couwenberg Mon, 14 Mar 2022 13:00:03 +0100 + +libgdal-grass (3.4.2~rc2-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Tue, 08 Mar 2022 18:22:04 +0100 + +libgdal-grass (3.4.1-4~exp1) experimental; urgency=medium + + * Update packaging for GRASS 8.0.1. + + -- Bas Couwenberg Sat, 05 Mar 2022 20:05:50 +0100 + +libgdal-grass (3.4.1-3) unstable; urgency=medium + + * Update packaging for GRASS 7.8.7. + + -- Bas Couwenberg Wed, 23 Feb 2022 19:34:26 +0100 + +libgdal-grass (3.4.1-2) unstable; urgency=medium + + * Move from experimental to unstable. + + -- Bas Couwenberg Tue, 04 Jan 2022 14:45:30 +0100 + +libgdal-grass (3.4.1-1) experimental; urgency=medium + + * New upstream release. + + -- Bas Couwenberg Tue, 04 Jan 2022 12:31:31 +0100 + +libgdal-grass (3.4.1~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Tue, 28 Dec 2021 06:07:16 +0100 + +libgdal-grass (3.4.0-1) unstable; urgency=medium + + * Update lintian overrides. + * Move from experimental to unstable. + + -- Bas Couwenberg Wed, 08 Dec 2021 13:40:46 +0100 + +libgdal-grass (3.4.0-1~exp1) experimental; urgency=medium + + * New upstream release. + + -- Bas Couwenberg Mon, 08 Nov 2021 16:09:34 +0100 + +libgdal-grass (3.4.0~rc3-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Sat, 06 Nov 2021 15:07:27 +0100 + +libgdal-grass (3.3.3-1) unstable; urgency=medium + + * New upstream release. + * Move from experimental to unstable. + + -- Bas Couwenberg Fri, 29 Oct 2021 17:28:47 +0200 + +libgdal-grass (3.3.3~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Mon, 25 Oct 2021 16:11:34 +0200 + +libgdal-grass (3.3.2-2) unstable; urgency=medium + + * Bump debhelper compat to 12, no changes. + * Update packaging for GRASS 7.8.6. + * Update lintian overrides. + + -- Bas Couwenberg Sun, 10 Oct 2021 17:00:19 +0200 + +libgdal-grass (3.3.2-1) unstable; urgency=medium + + * New upstream release. + * Bump Standards-Version to 4.6.0, no changes. + * Update watch file to handle pre-releases in dirversion. + * Move from experimental to unstable. + + -- Bas Couwenberg Tue, 07 Sep 2021 13:28:26 +0200 + +libgdal-grass (3.3.2~rc3-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Wed, 01 Sep 2021 17:50:47 +0200 + +libgdal-grass (3.3.1-1~exp1) experimental; urgency=medium + + * New upstream release. + + -- Bas Couwenberg Mon, 05 Jul 2021 15:03:01 +0200 + +libgdal-grass (3.3.1~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Mon, 28 Jun 2021 14:18:15 +0200 + +libgdal-grass (3.3.0-1~exp1) experimental; urgency=medium + + * New upstream release. + + -- Bas Couwenberg Mon, 03 May 2021 15:04:00 +0200 + +libgdal-grass (3.3.0~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Mon, 26 Apr 2021 15:16:11 +0200 + +libgdal-grass (3.3.0~beta1-1~exp1) experimental; urgency=medium + + * New upstream beta release. + + -- Bas Couwenberg Tue, 20 Apr 2021 08:11:34 +0200 + +libgdal-grass (3.2.2-1) unstable; urgency=medium + + * New upstream release. + * Move from experimental to unstable. + + -- Bas Couwenberg Wed, 10 Mar 2021 15:11:25 +0100 + +libgdal-grass (3.2.2~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Fri, 05 Mar 2021 14:19:36 +0100 + +libgdal-grass (3.2.1-1) unstable; urgency=medium + + * New upstream release. + * Move from experimental to unstable. + + -- Bas Couwenberg Mon, 04 Jan 2021 13:53:03 +0100 + +libgdal-grass (3.2.1~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Tue, 29 Dec 2020 16:28:30 +0100 + +libgdal-grass (3.2.0-2) unstable; urgency=medium + + * Update packaging for GRASS 7.8.5. + * Move from experimental to unstable. + + -- Bas Couwenberg Mon, 21 Dec 2020 21:03:16 +0100 + +libgdal-grass (3.2.0-2~exp1) experimental; urgency=medium + + * Update packaging for GRASS 7.8.5-rc1. + + -- Bas Couwenberg Mon, 07 Dec 2020 16:27:23 +0100 + +libgdal-grass (3.2.0-1) unstable; urgency=medium + + * Bump watch file version to 4. + * Bump Standards-Version to 4.5.1, no changes. + * Move from experimental to unstable. + + -- Bas Couwenberg Sun, 06 Dec 2020 13:04:29 +0100 + +libgdal-grass (3.2.0-1~exp1) experimental; urgency=medium + + * New upstream release. + + -- Bas Couwenberg Mon, 02 Nov 2020 11:07:32 +0100 + +libgdal-grass (3.2.0~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + * Update copyright file. + * Refresh patches. + + -- Bas Couwenberg Mon, 26 Oct 2020 15:21:53 +0100 + +libgdal-grass (3.1.4-1) unstable; urgency=medium + + * New upstream release. + * Move from experimental to unstable. + + -- Bas Couwenberg Sat, 24 Oct 2020 07:09:09 +0200 + +libgdal-grass (3.1.4~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Mon, 19 Oct 2020 18:24:52 +0200 + +libgdal-grass (3.1.3-3) unstable; urgency=medium + + * Update packaging for GRASS 7.8.4. + * Update lintian overrides. + + -- Bas Couwenberg Mon, 05 Oct 2020 09:22:39 +0200 + +libgdal-grass (3.1.3-2) unstable; urgency=medium + + * Move from experimental to unstable. + + -- Bas Couwenberg Mon, 07 Sep 2020 15:06:04 +0200 + +libgdal-grass (3.1.3-1) experimental; urgency=medium + + * New upstream release. + + -- Bas Couwenberg Mon, 07 Sep 2020 12:52:41 +0200 + +libgdal-grass (3.1.3~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + * Update lintian overrides for renamed tags. + + -- Bas Couwenberg Tue, 01 Sep 2020 11:57:35 +0200 + +libgdal-grass (3.1.2-1) unstable; urgency=medium + + * New upstream release. + + -- Bas Couwenberg Tue, 07 Jul 2020 15:17:33 +0200 + +libgdal-grass (3.1.1-1) unstable; urgency=medium + + * New upstream release. + * Move from experimental to unstable. + + -- Bas Couwenberg Mon, 29 Jun 2020 15:31:56 +0200 + +libgdal-grass (3.1.1~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Mon, 22 Jun 2020 12:55:38 +0200 + +libgdal-grass (3.1.0-1) unstable; urgency=medium + + * Move from experimental to unstable. + + -- Bas Couwenberg Thu, 11 Jun 2020 12:19:39 +0200 + +libgdal-grass (3.1.0-1~exp1) experimental; urgency=medium + + * New upstream release. + + -- Bas Couwenberg Mon, 11 May 2020 12:08:49 +0200 + +libgdal-grass (3.1.0~rc3-1~exp2) experimental; urgency=medium + + * Update packaging for GRASS 7.8.3. + * Update libgdal-dev build dependency to not required rc3. + + -- Bas Couwenberg Tue, 05 May 2020 12:59:56 +0200 + +libgdal-grass (3.1.0~rc3-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + * Drop d-shlibs build dependency. + + -- Bas Couwenberg Mon, 04 May 2020 14:53:32 +0200 + +libgdal-grass (3.1.0~rc2-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + + -- Bas Couwenberg Wed, 29 Apr 2020 06:11:29 +0200 + +libgdal-grass (3.1.0~rc1-1~exp1) experimental; urgency=medium + + * New upstream release candidate. + * Bump debhelper compat to 10, changes: + - Drop --parallel option, enabled by default + - Don't explicitly enable autoreconf, enabled by default + - Drop dh-autoreconf build dependency + * Update email address for Even Rouault. + + -- Bas Couwenberg Mon, 27 Apr 2020 19:12:00 +0200 + +libgdal-grass (3.0.4-2) unstable; urgency=medium + + * Bump debhelper compat to 10, changes: + - Drop --parallel option, enabled by default + - Don't explicitly enable autoreconf, enabled by default + - Drop dh-autoreconf build dependency + * Update packaging for GRASS 7.8.3. + + -- Bas Couwenberg Tue, 05 May 2020 12:43:43 +0200 libgdal-grass (3.0.4-1) unstable; urgency=medium diff -Nru libgdal-grass-3.0.4/debian/compat libgdal-grass-3.4.3/debian/compat --- libgdal-grass-3.0.4/debian/compat 2019-07-07 12:24:01.000000000 +0000 +++ libgdal-grass-3.4.3/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -9 diff -Nru libgdal-grass-3.0.4/debian/control libgdal-grass-3.4.3/debian/control --- libgdal-grass-3.0.4/debian/control 2020-01-30 13:31:46.000000000 +0000 +++ libgdal-grass-3.4.3/debian/control 2022-05-12 14:58:25.000000000 +0000 @@ -4,16 +4,13 @@ Bas Couwenberg Section: science Priority: optional -Build-Depends: debhelper (>= 9), - dh-autoreconf, - d-shlibs, - grass (>= 7.8.2), - grass-dev (>= 7.8.2), - libgdal-dev (>= 3.0.4), +Build-Depends: debhelper-compat (= 12), + grass (>= 8.0.2), + grass-dev (>= 8.0.2), + libgdal-dev (>= 3.4.3), libpq-dev, - lsb-release, pkg-config -Standards-Version: 4.5.0 +Standards-Version: 4.6.0 Vcs-Browser: https://salsa.debian.org/debian-gis-team/gdal-grass Vcs-Git: https://salsa.debian.org/debian-gis-team/gdal-grass.git Homepage: http://www.gdal.org/ diff -Nru libgdal-grass-3.0.4/debian/copyright libgdal-grass-3.4.3/debian/copyright --- libgdal-grass-3.0.4/debian/copyright 2019-07-07 12:24:01.000000000 +0000 +++ libgdal-grass-3.4.3/debian/copyright 2022-05-12 14:58:17.000000000 +0000 @@ -8,8 +8,8 @@ from http://www.gdal.org/ Files: * -Copyright: 1998-2013, Frank Warmerdam - 2007-2010, Even Rouault +Copyright: 2007-2020, Even Rouault + 1998-2013, Frank Warmerdam 2005, Radim Blazek License: MIT diff -Nru libgdal-grass-3.0.4/debian/lintian-overrides libgdal-grass-3.4.3/debian/lintian-overrides --- libgdal-grass-3.0.4/debian/lintian-overrides 2019-07-07 12:24:01.000000000 +0000 +++ libgdal-grass-3.4.3/debian/lintian-overrides 2022-05-12 14:58:17.000000000 +0000 @@ -1,4 +1,3 @@ # The run path has been added to get GRASS internal library -binary-or-shlib-defines-rpath usr/lib/gdalplugins/gdal_GRASS.so /usr/lib/grass*/lib -binary-or-shlib-defines-rpath usr/lib/gdalplugins/ogr_GRASS.so /usr/lib/grass*/lib +custom-library-search-path RUNPATH /usr/lib/grass*/lib [usr/lib/gdalplugins/*_GRASS.so] diff -Nru libgdal-grass-3.0.4/debian/patches/rpath libgdal-grass-3.4.3/debian/patches/rpath --- libgdal-grass-3.0.4/debian/patches/rpath 2019-09-07 07:33:59.000000000 +0000 +++ libgdal-grass-3.4.3/debian/patches/rpath 2022-05-12 14:58:17.000000000 +0000 @@ -7,13 +7,13 @@ @@ -34,10 +34,10 @@ distclean: clean - $(GLIBNAME): grass57dataset.o -- $(LD_SHARED) $(LDFLAGS) grass57dataset.o $(LIBS) -o $(GLIBNAME) -+ $(LD_SHARED) $(LDFLAGS) grass57dataset.o $(LIBS) -o $(GLIBNAME) -Wl,-rpath,/usr/lib/grass78/lib + $(GLIBNAME): grass.o +- $(LD_SHARED) $(LDFLAGS) grass.o $(LIBS) -o $(GLIBNAME) ++ $(LD_SHARED) $(LDFLAGS) grass.o $(LIBS) -o $(GLIBNAME) -Wl,-rpath,/usr/lib/grass80/lib $(OLIBNAME): ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o - $(LD_SHARED) $(LDFLAGS) ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o $(LIBS) -o $(OLIBNAME) -+ $(LD_SHARED) $(LDFLAGS) ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o $(LIBS) -o $(OLIBNAME) -Wl,-rpath,/usr/lib/grass78/lib ++ $(LD_SHARED) $(LDFLAGS) ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o $(LIBS) -o $(OLIBNAME) -Wl,-rpath,/usr/lib/grass80/lib %.o: %.cpp $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< diff -Nru libgdal-grass-3.0.4/debian/rules libgdal-grass-3.4.3/debian/rules --- libgdal-grass-3.0.4/debian/rules 2019-11-11 17:00:50.000000000 +0000 +++ libgdal-grass-3.4.3/debian/rules 2022-05-12 14:58:17.000000000 +0000 @@ -10,22 +10,12 @@ # Don't link with as-needed to prevent missing libraries export DEB_LDFLAGS_MAINT_APPEND=-Wl,--no-as-needed -# Disable PIE on Ubuntu where it's still problematic -VENDOR_DERIVES_FROM_UBUNTU ?= $(shell dpkg-vendor --derives-from Ubuntu && echo yes) -DISTRIBUTION_RELEASE := $(shell lsb_release -cs) - -ifeq ($(VENDOR_DERIVES_FROM_UBUNTU),yes) - ifneq (,$(filter $(DISTRIBUTION_RELEASE),xenial bionic)) - export DEB_BUILD_MAINT_OPTIONS=hardening=+all,-pie - endif -endif - PKGNAME=$(shell grep Package: debian/control | head -1 | cut -d' ' -f2) GRASS=grass$(subst .,,$(shell pkg-config --modversion grass | cut -d. -f1,2)) GRASS_ABI=grass$(subst .,,$(shell pkg-config --modversion grass | cut -d. -f1,2,3 | sed -e 's/RC/-/')) %: - dh $@ --with autoreconf --parallel + dh $@ override_dh_autoreconf: mv configure configure.pre-autoreconf diff -Nru libgdal-grass-3.0.4/debian/source/lintian-overrides libgdal-grass-3.4.3/debian/source/lintian-overrides --- libgdal-grass-3.0.4/debian/source/lintian-overrides 2019-07-07 12:24:01.000000000 +0000 +++ libgdal-grass-3.4.3/debian/source/lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# Not worth the effort -testsuite-autopkgtest-missing - diff -Nru libgdal-grass-3.0.4/debian/watch libgdal-grass-3.4.3/debian/watch --- libgdal-grass-3.0.4/debian/watch 2019-09-07 08:10:57.000000000 +0000 +++ libgdal-grass-3.4.3/debian/watch 2022-05-12 14:58:17.000000000 +0000 @@ -1,6 +1,7 @@ -version=3 +version=4 opts=\ dversionmangle=s/\+(debian|dfsg|ds|deb)\d*$//,\ -uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)\d*)$/$1~$2/;s/RC/rc/ \ -https://download.osgeo.org/gdal/(\d+\.\d+\.\d+)/ \ +uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)\d*)$/$1~$2/;s/RC/rc/,\ +dirversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)\d*)$/$1~$2/;s/RC/rc/ \ +https://download.osgeo.org/gdal/(3\.4\.\d+\w*)/ \ (?:|.*/)gdal(?:[_\-]v?|)(\d\S*)\.(?:tar\.xz|txz|tar\.bz2|tbz2|tar\.gz|tgz) diff -Nru libgdal-grass-3.0.4/grass57dataset.cpp libgdal-grass-3.4.3/grass57dataset.cpp --- libgdal-grass-3.0.4/grass57dataset.cpp 2020-01-28 11:01:41.000000000 +0000 +++ libgdal-grass-3.4.3/grass57dataset.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,1061 +0,0 @@ -/****************************************************************************** - * - * Project: GRASS Driver - * Purpose: Implement GRASS raster read/write support - * This version is for GRASS 5.7+ and uses GRASS libraries - * directly instead of using libgrass. - * Author: Frank Warmerdam - * Radim Blazek - * - ****************************************************************************** - * Copyright (c) 2000 Frank Warmerdam - * Copyright (c) 2007-2010, Even Rouault - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************/ - -#include - -#include "cpl_string.h" -#include "gdal_frmts.h" -#include "gdal_priv.h" -#include "ogr_spatialref.h" - -extern "C" { -#ifdef __cplusplus -#define class _class -#endif -#include -#ifdef __cplusplus -#undef class -#endif - -#include -#include -#include - -#if GRASS_VERSION_MAJOR >= 7 -char *GPJ_grass_to_wkt( const struct Key_Value *, - const struct Key_Value *, - int, int ); -#else -char *GPJ_grass_to_wkt( struct Key_Value *, - struct Key_Value *, - int, int ); -#endif -} - -#define GRASS_MAX_COLORS 100000 // what is the right value - -CPL_CVSID("$Id: grass57dataset.cpp 8e5eeb35bf76390e3134a4ea7076dab7d478ea0e 2018-11-14 22:55:13 +0100 Even Rouault $") - -#if GRASS_VERSION_MAJOR >= 7 -#define G_get_cellhd Rast_get_cellhd -#define G_get_window Rast_get_window -#define G_set_window Rast_set_window -#define G_raster_map_type Rast_map_type -#define G_read_fp_range Rast_read_fp_range -#define G_get_fp_range_min_max Rast_get_fp_range_min_max -#define G_set_c_null_value Rast_set_c_null_value -#define G_set_f_null_value Rast_set_f_null_value -#define G_set_d_null_value Rast_set_d_null_value -#define G_open_cell_old Rast_open_old -#define G_copy memcpy -#define G_read_colors Rast_read_colors -#define G_get_color_range Rast_get_c_color_range -#define G_colors_count Rast_colors_count -#define G_get_f_color_rule Rast_get_fp_color_rule -#define G_free_colors Rast_free_colors -#define G_close_cell Rast_close -#define G_allocate_c_raster_buf Rast_allocate_c_buf -#define G_get_c_raster_row Rast_get_c_row -#define G_is_c_null_value Rast_is_c_null_value -#define G_get_f_raster_row Rast_get_f_row -#define G_get_d_raster_row Rast_get_d_row -#define G_allocate_f_raster_buf Rast_allocate_f_buf -#define G_allocate_d_raster_buf Rast_allocate_d_buf -#define G__setenv G_setenv_nogisrc -#endif - -/************************************************************************/ -/* Grass2CPLErrorHook() */ -/************************************************************************/ - -static int Grass2CPLErrorHook( char * pszMessage, int bFatal ) - -{ - if( !bFatal ) - //CPLDebug( "GRASS", "%s", pszMessage ); - CPLError( CE_Warning, CPLE_AppDefined, "GRASS warning: %s", pszMessage ); - else - CPLError( CE_Warning, CPLE_AppDefined, "GRASS fatal error: %s", pszMessage ); - - return 0; -} - -/************************************************************************/ -/* ==================================================================== */ -/* GRASSDataset */ -/* ==================================================================== */ -/************************************************************************/ - -class GRASSRasterBand; - -class GRASSDataset : public GDALDataset -{ - friend class GRASSRasterBand; - - char *pszGisdbase; - char *pszLocation; /* LOCATION_NAME */ - char *pszElement; /* cellhd or group */ - - struct Cell_head sCellInfo; /* raster region */ - - char *pszProjection; - - double adfGeoTransform[6]; - - public: - GRASSDataset(); - ~GRASSDataset() override; - - const char *_GetProjectionRef(void) override; - const OGRSpatialReference* GetSpatialRef() const override { - return GetSpatialRefFromOldGetProjectionRef(); - } - CPLErr GetGeoTransform( double * ) override; - - static GDALDataset *Open( GDALOpenInfo * ); - - private: - static bool SplitPath ( char *, char **, char **, char **, char **, char ** ); -}; - -/************************************************************************/ -/* ==================================================================== */ -/* GRASSRasterBand */ -/* ==================================================================== */ -/************************************************************************/ - -class GRASSRasterBand : public GDALRasterBand -{ - friend class GRASSDataset; - - char *pszCellName; - char *pszMapset; - int hCell; - int nGRSType; // GRASS raster type: CELL_TYPE, FCELL_TYPE, DCELL_TYPE - bool nativeNulls; // use GRASS native NULL values - - struct Colors sGrassColors; - GDALColorTable *poCT; - - struct Cell_head sOpenWindow; /* the region when the raster was opened */ - - int bHaveMinMax; - double dfCellMin; - double dfCellMax; - - double dfNoData; - - bool valid; - - public: - GRASSRasterBand( GRASSDataset *, int, const char *, const char * ); - ~GRASSRasterBand() override; - - CPLErr IReadBlock( int, int, void * ) override; - CPLErr IRasterIO ( GDALRWFlag, int, int, int, int, - void *, int, int, GDALDataType, - GSpacing nPixelSpace, - GSpacing nLineSpace, - GDALRasterIOExtraArg* psExtraArg) override; - GDALColorInterp GetColorInterpretation() override; - GDALColorTable *GetColorTable() override; - double GetMinimum( int *pbSuccess = NULL ) override; - double GetMaximum( int *pbSuccess = NULL ) override; - double GetNoDataValue( int *pbSuccess = NULL ) override; - - private: - CPLErr ResetReading( struct Cell_head * ); -}; - -/************************************************************************/ -/* GRASSRasterBand() */ -/************************************************************************/ - -GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDSIn, int nBandIn, - const char * pszMapsetIn, - const char * pszCellNameIn ) - -{ - struct Cell_head sCellInfo; - - // Note: GISDBASE, LOCATION_NAME ans MAPSET was set in GRASSDataset::Open - - this->poDS = poDSIn; - this->nBand = nBandIn; - this->valid = false; - - this->pszCellName = G_store ( (char *) pszCellNameIn ); - this->pszMapset = G_store ( (char *) pszMapsetIn ); - - G_get_cellhd( (char *) pszCellName, (char *) pszMapset, &sCellInfo ); - nGRSType = G_raster_map_type( (char *) pszCellName, (char *) pszMapset ); - -/* -------------------------------------------------------------------- */ -/* Get min/max values. */ -/* -------------------------------------------------------------------- */ - struct FPRange sRange; - - if( G_read_fp_range( (char *) pszCellName, (char *) pszMapset, - &sRange ) == -1 ) - { - bHaveMinMax = FALSE; - } - else - { - bHaveMinMax = TRUE; - G_get_fp_range_min_max( &sRange, &dfCellMin, &dfCellMax ); - } - -/* -------------------------------------------------------------------- */ -/* Setup band type, and preferred nodata value. */ -/* -------------------------------------------------------------------- */ - // Negative values are also (?) stored as 4 bytes (format = 3) - // => raster with format < 3 has only positive values - - // GRASS modules usually do not waste space and only the format necessary to keep - // full raster values range is used -> no checks if shorter type could be used - - if( nGRSType == CELL_TYPE ) { - if ( sCellInfo.format == 0 ) { // 1 byte / cell -> possible range 0,255 - if ( bHaveMinMax && dfCellMin > 0 ) { - this->eDataType = GDT_Byte; - dfNoData = 0.0; - } else if ( bHaveMinMax && dfCellMax < 255 ) { - this->eDataType = GDT_Byte; - dfNoData = 255.0; - } else { // maximum is not known or full range is used - this->eDataType = GDT_UInt16; - dfNoData = 256.0; - } - nativeNulls = false; - } else if ( sCellInfo.format == 1 ) { // 2 bytes / cell -> possible range 0,65535 - if ( bHaveMinMax && dfCellMin > 0 ) { - this->eDataType = GDT_UInt16; - dfNoData = 0.0; - } else if ( bHaveMinMax && dfCellMax < 65535 ) { - this->eDataType = GDT_UInt16; - dfNoData = 65535; - } else { // maximum is not known or full range is used - CELL cval; - this->eDataType = GDT_Int32; - G_set_c_null_value ( &cval, 1); - dfNoData = (double) cval; - nativeNulls = true; - } - nativeNulls = false; - } else { // 3-4 bytes - CELL cval; - this->eDataType = GDT_Int32; - G_set_c_null_value ( &cval, 1); - dfNoData = (double) cval; - nativeNulls = true; - } - } - else if( nGRSType == FCELL_TYPE ) { - FCELL fval; - this->eDataType = GDT_Float32; - G_set_f_null_value ( &fval, 1); - dfNoData = (double) fval; - nativeNulls = true; - } - else if( nGRSType == DCELL_TYPE ) - { - DCELL dval; - this->eDataType = GDT_Float64; - G_set_d_null_value ( &dval, 1); - dfNoData = (double) dval; - nativeNulls = true; - } - - nBlockXSize = poDSIn->nRasterXSize; - nBlockYSize = 1; - - G_set_window( &(poDSIn->sCellInfo) ); - if ( (hCell = G_open_cell_old((char *) pszCellName, (char *) pszMapset)) < 0 ) { - CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster '%s'", pszCellName ); - return; - } - G_copy((void *) &sOpenWindow, (void *) &(poDSIn->sCellInfo), sizeof(struct Cell_head)); - -/* -------------------------------------------------------------------- */ -/* Do we have a color table? */ -/* -------------------------------------------------------------------- */ - poCT = NULL; - if( G_read_colors( (char *) pszCellName, (char *) pszMapset, &sGrassColors ) == 1 ) - { - int maxcolor; - CELL min, max; - - G_get_color_range ( &min, &max, &sGrassColors); - - if ( bHaveMinMax ) { - if ( max < dfCellMax ) { - maxcolor = max; - } else { - maxcolor = (int) ceil ( dfCellMax ); - } - if ( maxcolor > GRASS_MAX_COLORS ) { - maxcolor = GRASS_MAX_COLORS; - CPLDebug( "GRASS", "Too many values, color table cut to %d entries.", maxcolor ); - } - } else { - if ( max < GRASS_MAX_COLORS ) { - maxcolor = max; - } else { - maxcolor = GRASS_MAX_COLORS; - CPLDebug( "GRASS", "Too many values, color table set to %d entries.", maxcolor ); - } - } - - poCT = new GDALColorTable(); - for( int iColor = 0; iColor <= maxcolor; iColor++ ) - { - int nRed, nGreen, nBlue; - GDALColorEntry sColor; - -#if GRASS_VERSION_MAJOR >= 7 - if( Rast_get_c_color( &iColor, &nRed, &nGreen, &nBlue, &sGrassColors ) ) -#else - if( G_get_color( iColor, &nRed, &nGreen, &nBlue, &sGrassColors ) ) -#endif - { - sColor.c1 = nRed; - sColor.c2 = nGreen; - sColor.c3 = nBlue; - sColor.c4 = 255; - - poCT->SetColorEntry( iColor, &sColor ); - } - else - { - sColor.c1 = 0; - sColor.c2 = 0; - sColor.c3 = 0; - sColor.c4 = 0; - - poCT->SetColorEntry( iColor, &sColor ); - } - } - - /* Create metadata entries for color table rules */ - char key[200], value[200]; - int rcount = G_colors_count ( &sGrassColors ); - - snprintf ( value, sizeof(value), "%d", rcount ); - this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", value ); - - /* Add the rules in reverse order */ - for ( int i = rcount-1; i >= 0; i-- ) { - DCELL val1, val2; - unsigned char r1, g1, b1, r2, g2, b2; - - G_get_f_color_rule ( &val1, &r1, &g1, &b1, &val2, &r2, &g2, &b2, &sGrassColors, i ); - - snprintf ( key, sizeof(key), "COLOR_TABLE_RULE_RGB_%d", rcount-i-1 ); - snprintf ( value, sizeof(value), "%e %e %d %d %d %d %d %d", val1, val2, r1, g1, b1, r2, g2, b2 ); - this->SetMetadataItem( key, value ); - } - } else { - this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", "0" ); - } - - this->valid = true; -} - -/************************************************************************/ -/* ~GRASSRasterBand() */ -/************************************************************************/ - -GRASSRasterBand::~GRASSRasterBand() -{ - if( poCT != NULL ) { - G_free_colors( &sGrassColors ); - delete poCT; - } - - if( hCell >= 0 ) - G_close_cell( hCell ); - - if ( pszCellName ) - G_free ( pszCellName ); - - if ( pszMapset ) - G_free ( pszMapset ); -} - -/************************************************************************/ -/* ResetReading */ -/* */ -/* Reset current window and reopen cell if the window has changed, */ -/* reset GRASS variables */ -/* */ -/* Returns CE_Failure if fails, otherwise CE_None */ -/************************************************************************/ -CPLErr GRASSRasterBand::ResetReading ( struct Cell_head *sNewWindow ) -{ - - /* Check if the window has changed */ - if ( sNewWindow->north != sOpenWindow.north || sNewWindow->south != sOpenWindow.south || - sNewWindow->east != sOpenWindow.east || sNewWindow->west != sOpenWindow.west || - sNewWindow->ew_res != sOpenWindow.ew_res || sNewWindow->ns_res != sOpenWindow.ns_res || - sNewWindow->rows != sOpenWindow.rows || sNewWindow->cols != sOpenWindow.cols ) - { - if( hCell >= 0 ) { - G_close_cell( hCell ); - hCell = -1; - } - - /* Set window */ - G_set_window( sNewWindow ); - - /* Open raster */ - G__setenv( "GISDBASE", ((GRASSDataset *)poDS)->pszGisdbase ); - G__setenv( "LOCATION_NAME", ((GRASSDataset *)poDS)->pszLocation ); - G__setenv( "MAPSET", pszMapset); - G_reset_mapsets(); - G_add_mapset_to_search_path ( pszMapset ); - - if ( (hCell = G_open_cell_old( pszCellName, pszMapset)) < 0 ) { - CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster '%s'", pszCellName ); - this->valid = false; - return CE_Failure; - } - - G_copy((void *) &sOpenWindow, (void *) sNewWindow, sizeof(struct Cell_head)); - } - else - { - /* The windows are identical, check current window */ - struct Cell_head sCurrentWindow; - - G_get_window ( &sCurrentWindow ); - - if ( sNewWindow->north != sCurrentWindow.north || sNewWindow->south != sCurrentWindow.south || - sNewWindow->east != sCurrentWindow.east || sNewWindow->west != sCurrentWindow.west || - sNewWindow->ew_res != sCurrentWindow.ew_res || sNewWindow->ns_res != sCurrentWindow.ns_res || - sNewWindow->rows != sCurrentWindow.rows || sNewWindow->cols != sCurrentWindow.cols - ) - { - /* Reset window */ - G_set_window( sNewWindow ); - } - } - - return CE_None; -} - -/************************************************************************/ -/* IReadBlock() */ -/* */ -/************************************************************************/ - -CPLErr GRASSRasterBand::IReadBlock( int /*nBlockXOff*/, int nBlockYOff, - void *pImage ) - -{ - if ( ! this->valid ) return CE_Failure; - - // Reset window because IRasterIO could be previously called. - if ( ResetReading ( &(((GRASSDataset *)poDS)->sCellInfo) ) != CE_None ) { - return CE_Failure; - } - - if ( eDataType == GDT_Byte || eDataType == GDT_UInt16 ) { - CELL *cbuf = G_allocate_c_raster_buf(); - G_get_c_raster_row ( hCell, cbuf, nBlockYOff ); - - /* Reset NULLs */ - for ( int col = 0; col < nBlockXSize; col++ ) { - if ( G_is_c_null_value(&(cbuf[col])) ) - cbuf[col] = (CELL) dfNoData; - } - - GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL), - pImage, eDataType, GDALGetDataTypeSize(eDataType)/8, - nBlockXSize ); - - G_free ( cbuf ); - } - else if ( eDataType == GDT_Int32 ) - { - G_get_c_raster_row ( hCell, (CELL *) pImage, nBlockYOff ); - } - else if ( eDataType == GDT_Float32 ) - { - G_get_f_raster_row ( hCell, (FCELL *) pImage, nBlockYOff ); - } - else if ( eDataType == GDT_Float64 ) - { - G_get_d_raster_row ( hCell, (DCELL *) pImage, nBlockYOff ); - } - - return CE_None; -} - -/************************************************************************/ -/* IRasterIO() */ -/* */ -/************************************************************************/ - -CPLErr GRASSRasterBand::IRasterIO ( GDALRWFlag eRWFlag, - int nXOff, int nYOff, int nXSize, int nYSize, - void * pData, int nBufXSize, int nBufYSize, - GDALDataType eBufType, - GSpacing nPixelSpace, - GSpacing nLineSpace, - GDALRasterIOExtraArg* /*psExtraArg*/ ) -{ - /* GRASS library does that, we have only calculate and reset the region in map units - * and if the region has changed, reopen the raster */ - - /* Calculate the region */ - struct Cell_head sWindow; - struct Cell_head *psDsWindow; - - if( eRWFlag != GF_Read ) return CE_Failure; - if ( ! this->valid ) return CE_Failure; - - psDsWindow = &(((GRASSDataset *)poDS)->sCellInfo); - - sWindow.north = psDsWindow->north - nYOff * psDsWindow->ns_res; - sWindow.south = sWindow.north - nYSize * psDsWindow->ns_res; - sWindow.west = psDsWindow->west + nXOff * psDsWindow->ew_res; - sWindow.east = sWindow.west + nXSize * psDsWindow->ew_res; - sWindow.proj = psDsWindow->proj; - sWindow.zone = psDsWindow->zone; - - sWindow.cols = nBufXSize; - sWindow.rows = nBufYSize; - - /* Reset resolution */ - G_adjust_Cell_head ( &sWindow, 1, 1); - - if ( ResetReading ( &sWindow ) != CE_None ) - { - return CE_Failure; - } - - /* Read Data */ - CELL *cbuf = NULL; - FCELL *fbuf = NULL; - DCELL *dbuf = NULL; - bool direct = false; - - /* Reset space if default (0) */ - if ( nPixelSpace == 0 ) - nPixelSpace = GDALGetDataTypeSize ( eBufType ) / 8; - - if ( nLineSpace == 0 ) - nLineSpace = nBufXSize * nPixelSpace; - - if ( nGRSType == CELL_TYPE && ( !nativeNulls || eBufType != GDT_Int32 || sizeof(CELL) != 4 || - nPixelSpace != sizeof(CELL) ) ) - { - cbuf = G_allocate_c_raster_buf(); - } else if( nGRSType == FCELL_TYPE && ( eBufType != GDT_Float32 || nPixelSpace != sizeof(FCELL) ) ) { - fbuf = G_allocate_f_raster_buf(); - } else if( nGRSType == DCELL_TYPE && ( eBufType != GDT_Float64 || nPixelSpace != sizeof(DCELL) ) ) { - dbuf = G_allocate_d_raster_buf(); - } else { - direct = true; - } - - for ( int row = 0; row < nBufYSize; row++ ) { - char *pnt = (char *)pData + row * nLineSpace; - - if ( nGRSType == CELL_TYPE ) { - if ( direct ) { - G_get_c_raster_row ( hCell, (CELL *) pnt, row ); - } else { - G_get_c_raster_row ( hCell, cbuf, row ); - - /* Reset NULLs */ - for ( int col = 0; col < nBufXSize; col++ ) { - if ( G_is_c_null_value(&(cbuf[col])) ) - cbuf[col] = (CELL) dfNoData; - } - - GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL), - (void *) pnt, eBufType, nPixelSpace, - nBufXSize ); - } - } else if( nGRSType == FCELL_TYPE ) { - if ( direct ) { - G_get_f_raster_row ( hCell, (FCELL *) pnt, row ); - } else { - G_get_f_raster_row ( hCell, fbuf, row ); - - GDALCopyWords ( (void *) fbuf, GDT_Float32, sizeof(FCELL), - (void *) pnt, eBufType, nPixelSpace, - nBufXSize ); - } - } else if( nGRSType == DCELL_TYPE ) { - if ( direct ) { - G_get_d_raster_row ( hCell, (DCELL *) pnt, row ); - } else { - G_get_d_raster_row ( hCell, dbuf, row ); - - GDALCopyWords ( (void *) dbuf, GDT_Float64, sizeof(DCELL), - (void *) pnt, eBufType, nPixelSpace, - nBufXSize ); - } - } - } - - if ( cbuf ) G_free ( cbuf ); - if ( fbuf ) G_free ( fbuf ); - if ( dbuf ) G_free ( dbuf ); - - return CE_None; -} - -/************************************************************************/ -/* GetColorInterpretation() */ -/************************************************************************/ - -GDALColorInterp GRASSRasterBand::GetColorInterpretation() - -{ - if( poCT != NULL ) - return GCI_PaletteIndex; - else - return GCI_GrayIndex; -} - -/************************************************************************/ -/* GetColorTable() */ -/************************************************************************/ - -GDALColorTable *GRASSRasterBand::GetColorTable() - -{ - return poCT; -} - -/************************************************************************/ -/* GetMinimum() */ -/************************************************************************/ - -double GRASSRasterBand::GetMinimum( int *pbSuccess ) - -{ - if( pbSuccess ) - *pbSuccess = bHaveMinMax; - - if( bHaveMinMax ) - return dfCellMin; - - else if( eDataType == GDT_Float32 || eDataType == GDT_Float64 ) - return -4294967295.0; - else - return 0; -} - -/************************************************************************/ -/* GetMaximum() */ -/************************************************************************/ - -double GRASSRasterBand::GetMaximum( int *pbSuccess ) - -{ - if( pbSuccess ) - *pbSuccess = bHaveMinMax; - - if( bHaveMinMax ) - return dfCellMax; - - else if( eDataType == GDT_Float32 || eDataType == GDT_Float64 ) - return 4294967295.0; - else if( eDataType == GDT_UInt32 ) - return 4294967295.0; - else if( eDataType == GDT_UInt16 ) - return 65535; - else - return 255; -} - -/************************************************************************/ -/* GetNoDataValue() */ -/************************************************************************/ - -double GRASSRasterBand::GetNoDataValue( int *pbSuccess ) - -{ - if( pbSuccess ) - *pbSuccess = TRUE; - - return dfNoData; -} - -/************************************************************************/ -/* ==================================================================== */ -/* GRASSDataset */ -/* ==================================================================== */ -/************************************************************************/ - -/************************************************************************/ -/* GRASSDataset() */ -/************************************************************************/ - -GRASSDataset::GRASSDataset() -{ - pszProjection = NULL; - - adfGeoTransform[0] = 0.0; - adfGeoTransform[1] = 1.0; - adfGeoTransform[2] = 0.0; - adfGeoTransform[3] = 0.0; - adfGeoTransform[4] = 0.0; - adfGeoTransform[5] = 1.0; - pszGisdbase = NULL; - pszLocation = NULL; - pszElement = NULL; -} - -/************************************************************************/ -/* ~GRASSDataset() */ -/************************************************************************/ - -GRASSDataset::~GRASSDataset() -{ - - if ( pszGisdbase ) - G_free ( pszGisdbase ); - - if ( pszLocation ) - G_free ( pszLocation ); - - if ( pszElement ) - G_free ( pszElement ); - - G_free( pszProjection ); -} - -/************************************************************************/ -/* GetProjectionRef() */ -/************************************************************************/ - -const char *GRASSDataset::_GetProjectionRef() -{ - if( pszProjection == NULL ) - return ""; - else - return pszProjection; -} - -/************************************************************************/ -/* GetGeoTransform() */ -/************************************************************************/ - -CPLErr GRASSDataset::GetGeoTransform( double * padfGeoTransform ) -{ - memcpy( padfGeoTransform, adfGeoTransform, sizeof(double) * 6 ); - - return CE_None; -} - -/************************************************************************/ -/* SplitPath() */ -/* Split full path to cell or group to: */ -/* gisdbase, location, mapset, element, name */ -/* New string are allocated and should be freed when no longer needed. */ -/* */ -/* Returns: true - OK */ -/* false - failed */ -/************************************************************************/ -bool GRASSDataset::SplitPath( char *path, char **gisdbase, char **location, - char **mapset, char **element, char **name ) -{ - char *p; - char *ptr[5]; - char *tmp; - int i = 0; - - *gisdbase = NULL; - *location = NULL; - *mapset = NULL; - *element = NULL; - *name = NULL; - - if ( !path || strlen(path) == 0 ) - return false; - - tmp = G_store ( path ); - - while ( (p = strrchr(tmp,'/')) != NULL && i < 4 ) { - *p = '\0'; - - if ( strlen(p+1) == 0 ) /* repeated '/' */ - continue; - - ptr[i++] = p+1; - } - - /* Note: empty GISDBASE == 0 is not accepted (relative path) */ - if ( i != 4 ) { - G_free ( tmp ); - return false; - } - - *gisdbase = G_store ( tmp ); - *location = G_store ( ptr[3] ); - *mapset = G_store ( ptr[2] ); - *element = G_store ( ptr[1] ); - *name = G_store ( ptr[0] ); - - G_free ( tmp ); - return true; -} - -/************************************************************************/ -/* Open() */ -/************************************************************************/ - -#if (GRASS_VERSION_MAJOR >= 6 && GRASS_VERSION_MINOR >= 3) || GRASS_VERSION_MAJOR >= 7 -typedef int (*GrassErrorHandler)(const char *, int); -#else -typedef int (*GrassErrorHandler)(char *, int); -#endif - -GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo ) - -{ - char *pszGisdb = NULL, *pszLoc = NULL; - char *pszMapset = NULL, *pszElem = NULL, *pszName = NULL; - char **papszCells = NULL; - char **papszMapsets = NULL; - -/* -------------------------------------------------------------------- */ -/* Does this even look like a grass file path? */ -/* -------------------------------------------------------------------- */ - if( strstr(poOpenInfo->pszFilename,"/cellhd/") == NULL - && strstr(poOpenInfo->pszFilename,"/group/") == NULL ) - return NULL; - - /* Always init, if no rasters are opened G_no_gisinit resets the projection and - * rasters in different projection may be then opened */ - - // Don't use GISRC file and read/write GRASS variables (from location G_VAR_GISRC) to memory only. - G_set_gisrc_mode ( G_GISRC_MODE_MEMORY ); - - // Init GRASS libraries (required) - G_no_gisinit(); // Doesn't check write permissions for mapset compare to G_gisinit - - // Set error function - G_set_error_routine ( (GrassErrorHandler) Grass2CPLErrorHook ); - - // GISBASE is path to the directory where GRASS is installed, - if ( !getenv( "GISBASE" ) ) { - static char* gisbaseEnv = NULL; - const char *gisbase = GRASS_GISBASE; - CPLError( CE_Warning, CPLE_AppDefined, "GRASS warning: GISBASE " - "environment variable was not set, using:\n%s", gisbase ); - char buf[2000]; - snprintf ( buf, sizeof(buf), "GISBASE=%s", gisbase ); - buf[sizeof(buf)-1] = '\0'; - - CPLFree(gisbaseEnv); - gisbaseEnv = CPLStrdup ( buf ); - putenv( gisbaseEnv ); - } - - if ( !SplitPath( poOpenInfo->pszFilename, &pszGisdb, &pszLoc, &pszMapset, - &pszElem, &pszName) ) { - return NULL; - } - -/* -------------------------------------------------------------------- */ -/* Check element name */ -/* -------------------------------------------------------------------- */ - if ( strcmp(pszElem,"cellhd") != 0 && strcmp(pszElem,"group") != 0 ) { - G_free(pszGisdb); - G_free(pszLoc); - G_free(pszMapset); - G_free(pszElem); - G_free(pszName); - return NULL; - } - -/* -------------------------------------------------------------------- */ -/* Set GRASS variables */ -/* -------------------------------------------------------------------- */ - - G__setenv( "GISDBASE", pszGisdb ); - G__setenv( "LOCATION_NAME", pszLoc ); - G__setenv( "MAPSET", pszMapset); // group is searched only in current mapset - G_reset_mapsets(); - G_add_mapset_to_search_path ( pszMapset ); - -/* -------------------------------------------------------------------- */ -/* Check if this is a valid grass cell. */ -/* -------------------------------------------------------------------- */ - if ( strcmp(pszElem,"cellhd") == 0 ) { - - if ( G_find_file2("cell", pszName, pszMapset) == NULL ) { - G_free(pszGisdb); G_free(pszLoc); G_free(pszMapset); G_free(pszElem); G_free(pszName); - return NULL; - } - - papszMapsets = CSLAddString( papszMapsets, pszMapset ); - papszCells = CSLAddString( papszCells, pszName ); - } -/* -------------------------------------------------------------------- */ -/* Check if this is a valid GRASS imagery group. */ -/* -------------------------------------------------------------------- */ - else { - struct Ref ref; - - I_init_group_ref( &ref ); - if ( I_get_group_ref( pszName, &ref ) == 0 ) { - G_free(pszGisdb); G_free(pszLoc); G_free(pszMapset); G_free(pszElem); G_free(pszName); - return NULL; - } - - for( int iRef = 0; iRef < ref.nfiles; iRef++ ) - { - papszCells = CSLAddString( papszCells, ref.file[iRef].name ); - papszMapsets = CSLAddString( papszMapsets, ref.file[iRef].mapset ); - G_add_mapset_to_search_path ( ref.file[iRef].mapset ); - } - - I_free_group_ref( &ref ); - } - - G_free( pszMapset ); - G_free( pszName ); - -/* -------------------------------------------------------------------- */ -/* Create a corresponding GDALDataset. */ -/* -------------------------------------------------------------------- */ - GRASSDataset*poDS = new GRASSDataset(); - - /* notdef: should only allow read access to an existing cell, right? */ - poDS->eAccess = poOpenInfo->eAccess; - - poDS->pszGisdbase = pszGisdb; - poDS->pszLocation = pszLoc; - poDS->pszElement = pszElem; - -/* -------------------------------------------------------------------- */ -/* Capture some information from the file that is of interest. */ -/* -------------------------------------------------------------------- */ - -#if GRASS_VERSION_MAJOR >= 7 - Rast_get_cellhd( papszCells[0], papszMapsets[0], &(poDS->sCellInfo) ); -#else - if( G_get_cellhd( papszCells[0], papszMapsets[0], &(poDS->sCellInfo) ) != 0 ) { - CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster header"); - delete poDS; - return NULL; - } -#endif - - poDS->nRasterXSize = poDS->sCellInfo.cols; - poDS->nRasterYSize = poDS->sCellInfo.rows; - - poDS->adfGeoTransform[0] = poDS->sCellInfo.west; - poDS->adfGeoTransform[1] = poDS->sCellInfo.ew_res; - poDS->adfGeoTransform[2] = 0.0; - poDS->adfGeoTransform[3] = poDS->sCellInfo.north; - poDS->adfGeoTransform[4] = 0.0; - poDS->adfGeoTransform[5] = -1 * poDS->sCellInfo.ns_res; - -/* -------------------------------------------------------------------- */ -/* Try to get a projection definition. */ -/* -------------------------------------------------------------------- */ - struct Key_Value *projinfo, *projunits; - - projinfo = G_get_projinfo(); - projunits = G_get_projunits(); - poDS->pszProjection = GPJ_grass_to_wkt ( projinfo, projunits, 0, 0); - if (projinfo) G_free_key_value(projinfo); - if (projunits) G_free_key_value(projunits); - -/* -------------------------------------------------------------------- */ -/* Create band information objects. */ -/* -------------------------------------------------------------------- */ - for( int iBand = 0; papszCells[iBand] != NULL; iBand++ ) - { - GRASSRasterBand *rb = new GRASSRasterBand( poDS, iBand+1, papszMapsets[iBand], - papszCells[iBand] ); - - if ( !rb->valid ) { - CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster band %d", iBand); - delete rb; - delete poDS; - return NULL; - } - - poDS->SetBand( iBand+1, rb ); - } - - CSLDestroy(papszCells); - CSLDestroy(papszMapsets); - -/* -------------------------------------------------------------------- */ -/* Confirm the requested access is supported. */ -/* -------------------------------------------------------------------- */ - if( poOpenInfo->eAccess == GA_Update ) - { - delete poDS; - CPLError( CE_Failure, CPLE_NotSupported, - "The GRASS driver does not support update access to existing" - " datasets.\n" ); - return NULL; - } - - return poDS; -} - -/************************************************************************/ -/* GDALRegister_GRASS() */ -/************************************************************************/ - -void GDALRegister_GRASS() -{ - if( !GDAL_CHECK_VERSION( "GDAL/GRASS57 driver" ) ) - return; - - if( GDALGetDriverByName( "GRASS" ) != NULL ) - return; - - GDALDriver *poDriver = new GDALDriver(); - - poDriver->SetDescription( "GRASS" ); - poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" ); - poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "GRASS Rasters (5.7+)" ); - poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "frmt_grass.html" ); - - poDriver->pfnOpen = GRASSDataset::Open; - - GetGDALDriverManager()->RegisterDriver( poDriver ); -} diff -Nru libgdal-grass-3.0.4/grass.cpp libgdal-grass-3.4.3/grass.cpp --- libgdal-grass-3.0.4/grass.cpp 1970-01-01 00:00:00.000000000 +0000 +++ libgdal-grass-3.4.3/grass.cpp 2022-04-22 11:30:01.000000000 +0000 @@ -0,0 +1,1037 @@ +/****************************************************************************** + * + * Project: GRASS Driver + * Purpose: Implement GRASS raster read/write support + * This version is for GRASS GIS 7+ and uses GRASS libraries + * directly instead of using libgrass. + * Author: Frank Warmerdam + * Radim Blazek + * + ****************************************************************************** + * Copyright (c) 2000 Frank Warmerdam + * Copyright (c) 2007-2020, Even Rouault + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************/ + +#include + +#include "cpl_string.h" +#include "gdal_frmts.h" +#include "gdal_priv.h" +#include "ogr_spatialref.h" + +extern "C" { +#ifdef __cplusplus +#define class _class +#endif +#include +#ifdef __cplusplus +#undef class +#endif + +#include +#include +#include + +char *GPJ_grass_to_wkt( const struct Key_Value *, + const struct Key_Value *, + int, int ); +} + +#define GRASS_MAX_COLORS 100000 // what is the right value + +CPL_CVSID("$Id: grass.cpp a832da5b936bac8438f9c50e7c20e563fd94c9ff 2020-09-22 13:06:27 +0200 Markus Neteler $") + +/************************************************************************/ +/* Grass2CPLErrorHook() */ +/************************************************************************/ + +static int Grass2CPLErrorHook( char * pszMessage, int bFatal ) + +{ + if( !bFatal ) + //CPLDebug( "GRASS", "%s", pszMessage ); + CPLError( CE_Warning, CPLE_AppDefined, "GRASS warning: %s", pszMessage ); + else + CPLError( CE_Warning, CPLE_AppDefined, "GRASS fatal error: %s", pszMessage ); + + return 0; +} + +/************************************************************************/ +/* ==================================================================== */ +/* GRASSDataset */ +/* ==================================================================== */ +/************************************************************************/ + +class GRASSRasterBand; + +class GRASSDataset final: public GDALDataset +{ + friend class GRASSRasterBand; + + char *pszGisdbase; + char *pszLocation; /* LOCATION_NAME */ + char *pszElement; /* cellhd or group */ + + struct Cell_head sCellInfo; /* raster region */ + + char *pszProjection; + + double adfGeoTransform[6]; + + public: + GRASSDataset(); + ~GRASSDataset() override; + + const char *_GetProjectionRef(void) override; + const OGRSpatialReference* GetSpatialRef() const override { + return GetSpatialRefFromOldGetProjectionRef(); + } + CPLErr GetGeoTransform( double * ) override; + + static GDALDataset *Open( GDALOpenInfo * ); + + private: + static bool SplitPath ( char *, char **, char **, char **, char **, char ** ); +}; + +/************************************************************************/ +/* ==================================================================== */ +/* GRASSRasterBand */ +/* ==================================================================== */ +/************************************************************************/ + +class GRASSRasterBand final: public GDALRasterBand +{ + friend class GRASSDataset; + + char *pszCellName; + char *pszMapset; + int hCell; + int nGRSType; // GRASS raster type: CELL_TYPE, FCELL_TYPE, DCELL_TYPE + bool nativeNulls; // use GRASS native NULL values + + struct Colors sGrassColors; + GDALColorTable *poCT; + + struct Cell_head sOpenWindow; /* the region when the raster was opened */ + + int bHaveMinMax; + double dfCellMin; + double dfCellMax; + + double dfNoData; + + bool valid; + + public: + GRASSRasterBand( GRASSDataset *, int, const char *, const char * ); + ~GRASSRasterBand() override; + + CPLErr IReadBlock( int, int, void * ) override; + CPLErr IRasterIO ( GDALRWFlag, int, int, int, int, + void *, int, int, GDALDataType, + GSpacing nPixelSpace, + GSpacing nLineSpace, + GDALRasterIOExtraArg* psExtraArg) override; + GDALColorInterp GetColorInterpretation() override; + GDALColorTable *GetColorTable() override; + double GetMinimum( int *pbSuccess = NULL ) override; + double GetMaximum( int *pbSuccess = NULL ) override; + double GetNoDataValue( int *pbSuccess = NULL ) override; + + private: + void SetWindow( struct Cell_head * ); + CPLErr ResetReading( struct Cell_head * ); +}; + +/************************************************************************/ +/* GRASSRasterBand() */ +/************************************************************************/ + +GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDSIn, int nBandIn, + const char * pszMapsetIn, + const char * pszCellNameIn ) + +{ + struct Cell_head sCellInfo; + + // Note: GISDBASE, LOCATION_NAME ans MAPSET was set in GRASSDataset::Open + + this->poDS = poDSIn; + this->nBand = nBandIn; + this->valid = false; + + this->pszCellName = G_store ( (char *) pszCellNameIn ); + this->pszMapset = G_store ( (char *) pszMapsetIn ); + + Rast_get_cellhd( (char *) pszCellName, (char *) pszMapset, &sCellInfo ); + nGRSType = Rast_map_type( (char *) pszCellName, (char *) pszMapset ); + +/* -------------------------------------------------------------------- */ +/* Get min/max values. */ +/* -------------------------------------------------------------------- */ + struct FPRange sRange; + + if( Rast_read_fp_range( (char *) pszCellName, (char *) pszMapset, + &sRange ) == -1 ) + { + bHaveMinMax = FALSE; + } + else + { + bHaveMinMax = TRUE; + Rast_get_fp_range_min_max( &sRange, &dfCellMin, &dfCellMax ); + } + +/* -------------------------------------------------------------------- */ +/* Setup band type, and preferred nodata value. */ +/* -------------------------------------------------------------------- */ + // Negative values are also (?) stored as 4 bytes (format = 3) + // => raster with format < 3 has only positive values + + // GRASS modules usually do not waste space and only the format necessary to keep + // full raster values range is used -> no checks if shorter type could be used + + if( nGRSType == CELL_TYPE ) { + if ( sCellInfo.format == 0 ) { // 1 byte / cell -> possible range 0,255 + if ( bHaveMinMax && dfCellMin > 0 ) { + this->eDataType = GDT_Byte; + dfNoData = 0.0; + } else if ( bHaveMinMax && dfCellMax < 255 ) { + this->eDataType = GDT_Byte; + dfNoData = 255.0; + } else { // maximum is not known or full range is used + this->eDataType = GDT_UInt16; + dfNoData = 256.0; + } + nativeNulls = false; + } else if ( sCellInfo.format == 1 ) { // 2 bytes / cell -> possible range 0,65535 + if ( bHaveMinMax && dfCellMin > 0 ) { + this->eDataType = GDT_UInt16; + dfNoData = 0.0; + } else if ( bHaveMinMax && dfCellMax < 65535 ) { + this->eDataType = GDT_UInt16; + dfNoData = 65535; + } else { // maximum is not known or full range is used + CELL cval; + this->eDataType = GDT_Int32; + Rast_set_c_null_value ( &cval, 1); + dfNoData = (double) cval; + } + nativeNulls = false; + } else { // 3-4 bytes + CELL cval; + this->eDataType = GDT_Int32; + Rast_set_c_null_value ( &cval, 1); + dfNoData = (double) cval; + nativeNulls = true; + } + } + else if( nGRSType == FCELL_TYPE ) { + FCELL fval; + this->eDataType = GDT_Float32; + Rast_set_f_null_value ( &fval, 1); + dfNoData = (double) fval; + nativeNulls = true; + } + else if( nGRSType == DCELL_TYPE ) + { + DCELL dval; + this->eDataType = GDT_Float64; + Rast_set_d_null_value ( &dval, 1); + dfNoData = (double) dval; + nativeNulls = true; + } + + nBlockXSize = poDSIn->nRasterXSize; + nBlockYSize = 1; + + Rast_set_window ( &(poDSIn->sCellInfo) ); + // open the raster only for actual reading + hCell = -1; + memcpy((void *) &sOpenWindow, (void *) &(poDSIn->sCellInfo), sizeof(struct Cell_head)); + +/* -------------------------------------------------------------------- */ +/* Do we have a color table? */ +/* -------------------------------------------------------------------- */ + poCT = NULL; + if( Rast_read_colors( (char *) pszCellName, (char *) pszMapset, &sGrassColors ) == 1 ) + { + int maxcolor; + CELL min, max; + + Rast_get_c_color_range ( &min, &max, &sGrassColors); + + if ( bHaveMinMax ) { + if ( max < dfCellMax ) { + maxcolor = max; + } else { + maxcolor = (int) ceil ( dfCellMax ); + } + if ( maxcolor > GRASS_MAX_COLORS ) { + maxcolor = GRASS_MAX_COLORS; + CPLDebug( "GRASS", "Too many values, color table cut to %d entries.", maxcolor ); + } + } else { + if ( max < GRASS_MAX_COLORS ) { + maxcolor = max; + } else { + maxcolor = GRASS_MAX_COLORS; + CPLDebug( "GRASS", "Too many values, color table set to %d entries.", maxcolor ); + } + } + + poCT = new GDALColorTable(); + for( int iColor = 0; iColor <= maxcolor; iColor++ ) + { + int nRed, nGreen, nBlue; + GDALColorEntry sColor; + + if( Rast_get_c_color( &iColor, &nRed, &nGreen, &nBlue, &sGrassColors ) ) + { + sColor.c1 = nRed; + sColor.c2 = nGreen; + sColor.c3 = nBlue; + sColor.c4 = 255; + + poCT->SetColorEntry( iColor, &sColor ); + } + else + { + sColor.c1 = 0; + sColor.c2 = 0; + sColor.c3 = 0; + sColor.c4 = 0; + + poCT->SetColorEntry( iColor, &sColor ); + } + } + + /* Create metadata entries for color table rules */ + char key[200], value[200]; + int rcount = Rast_colors_count ( &sGrassColors ); + + snprintf ( value, sizeof(value), "%d", rcount ); + this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", value ); + + /* Add the rules in reverse order */ + for ( int i = rcount-1; i >= 0; i-- ) { + DCELL val1, val2; + unsigned char r1, g1, b1, r2, g2, b2; + + Rast_get_fp_color_rule ( &val1, &r1, &g1, &b1, &val2, &r2, &g2, &b2, &sGrassColors, i ); + + snprintf ( key, sizeof(key), "COLOR_TABLE_RULE_RGB_%d", rcount-i-1 ); + snprintf ( value, sizeof(value), "%e %e %d %d %d %d %d %d", val1, val2, r1, g1, b1, r2, g2, b2 ); + this->SetMetadataItem( key, value ); + } + } else { + this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", "0" ); + } + + this->valid = true; +} + +/************************************************************************/ +/* ~GRASSRasterBand() */ +/************************************************************************/ + +GRASSRasterBand::~GRASSRasterBand() +{ + if( poCT != NULL ) { + Rast_free_colors( &sGrassColors ); + delete poCT; + } + + if( hCell >= 0 ) + Rast_close( hCell ); + + if ( pszCellName ) + G_free ( pszCellName ); + + if ( pszMapset ) + G_free ( pszMapset ); +} + +/************************************************************************/ +/* SetWindow */ +/* */ +/* Helper for ResetReading */ +/* close the current GRASS raster band, actually set the new window, */ +/* reset GRASS variables */ +/* */ +/* Returns nothing */ +/************************************************************************/ +void GRASSRasterBand::SetWindow ( struct Cell_head *sNewWindow ) +{ + if( hCell >= 0 ) { + Rast_close( hCell ); + hCell = -1; + } + + /* Set window */ + Rast_set_window( sNewWindow ); + + /* Set GRASS env to the current raster, don't open the raster */ + G_setenv_nogisrc( "GISDBASE", ((GRASSDataset *)poDS)->pszGisdbase ); + G_setenv_nogisrc( "LOCATION_NAME", ((GRASSDataset *)poDS)->pszLocation ); + G_setenv_nogisrc( "MAPSET", pszMapset); + G_reset_mapsets(); + G_add_mapset_to_search_path ( pszMapset ); +} + +/************************************************************************/ +/* ResetReading */ +/* */ +/* Reset current window for a new reading request, */ +/* close the current GRASS raster band, reset GRASS variables */ +/* */ +/* Returns CE_Failure if fails, otherwise CE_None */ +/************************************************************************/ +CPLErr GRASSRasterBand::ResetReading ( struct Cell_head *sNewWindow ) +{ + + /* Check if the window has changed */ + if ( sNewWindow->north != sOpenWindow.north || sNewWindow->south != sOpenWindow.south || + sNewWindow->east != sOpenWindow.east || sNewWindow->west != sOpenWindow.west || + sNewWindow->ew_res != sOpenWindow.ew_res || sNewWindow->ns_res != sOpenWindow.ns_res || + sNewWindow->rows != sOpenWindow.rows || sNewWindow->cols != sOpenWindow.cols ) + { + SetWindow ( sNewWindow ); + memcpy((void *) &sOpenWindow, (void *) sNewWindow, sizeof(struct Cell_head)); + } + else + { + /* The windows are identical, check current window */ + struct Cell_head sCurrentWindow; + + Rast_get_window ( &sCurrentWindow ); + + if ( sNewWindow->north != sCurrentWindow.north || sNewWindow->south != sCurrentWindow.south || + sNewWindow->east != sCurrentWindow.east || sNewWindow->west != sCurrentWindow.west || + sNewWindow->ew_res != sCurrentWindow.ew_res || sNewWindow->ns_res != sCurrentWindow.ns_res || + sNewWindow->rows != sCurrentWindow.rows || sNewWindow->cols != sCurrentWindow.cols + ) + { + SetWindow ( sNewWindow ); + } + } + + return CE_None; +} + +/************************************************************************/ +/* IReadBlock() */ +/* */ +/************************************************************************/ + +CPLErr GRASSRasterBand::IReadBlock( int /*nBlockXOff*/, int nBlockYOff, + void *pImage ) + +{ + if ( ! this->valid ) return CE_Failure; + + // Reset window because IRasterIO could be previously called. + if ( ResetReading ( &(((GRASSDataset *)poDS)->sCellInfo) ) != CE_None ) { + return CE_Failure; + } + // open for reading + if (hCell < 0) { + if ( (hCell = Rast_open_old((char *) pszCellName, (char *) pszMapset)) < 0 ) { + CPLError( CE_Failure, CPLE_AppDefined, "GRASS: Cannot open raster '%s'", pszCellName ); + return CE_Failure; + } + } + + if ( eDataType == GDT_Byte || eDataType == GDT_UInt16 ) { + CELL *cbuf = Rast_allocate_c_buf(); + Rast_get_c_row ( hCell, cbuf, nBlockYOff ); + + /* Reset NULLs */ + for ( int col = 0; col < nBlockXSize; col++ ) { + if ( Rast_is_c_null_value(&(cbuf[col])) ) + cbuf[col] = (CELL) dfNoData; + } + + GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL), + pImage, eDataType, GDALGetDataTypeSize(eDataType)/8, + nBlockXSize ); + + G_free ( cbuf ); + } + else if ( eDataType == GDT_Int32 ) + { + Rast_get_c_row ( hCell, (CELL *) pImage, nBlockYOff ); + } + else if ( eDataType == GDT_Float32 ) + { + Rast_get_f_row ( hCell, (FCELL *) pImage, nBlockYOff ); + } + else if ( eDataType == GDT_Float64 ) + { + Rast_get_d_row ( hCell, (DCELL *) pImage, nBlockYOff ); + } + + // close to avoid confusion with other GRASS raster bands + Rast_close( hCell ); + hCell = -1; + + return CE_None; +} + +/************************************************************************/ +/* IRasterIO() */ +/* */ +/************************************************************************/ + +CPLErr GRASSRasterBand::IRasterIO ( GDALRWFlag eRWFlag, + int nXOff, int nYOff, int nXSize, int nYSize, + void * pData, int nBufXSize, int nBufYSize, + GDALDataType eBufType, + GSpacing nPixelSpace, + GSpacing nLineSpace, + GDALRasterIOExtraArg* /*psExtraArg*/ ) +{ + /* GRASS library does that, we have only calculate and reset the region in map units + * and if the region has changed, reopen the raster */ + + /* Calculate the region */ + struct Cell_head sWindow; + struct Cell_head *psDsWindow; + + if( eRWFlag != GF_Read ) return CE_Failure; + if ( ! this->valid ) return CE_Failure; + + psDsWindow = &(((GRASSDataset *)poDS)->sCellInfo); + + sWindow.north = psDsWindow->north - nYOff * psDsWindow->ns_res; + sWindow.south = sWindow.north - nYSize * psDsWindow->ns_res; + sWindow.west = psDsWindow->west + nXOff * psDsWindow->ew_res; + sWindow.east = sWindow.west + nXSize * psDsWindow->ew_res; + sWindow.proj = psDsWindow->proj; + sWindow.zone = psDsWindow->zone; + + sWindow.cols = nBufXSize; + sWindow.rows = nBufYSize; + + /* Reset resolution */ + G_adjust_Cell_head ( &sWindow, 1, 1); + + if ( ResetReading ( &sWindow ) != CE_None ) + { + return CE_Failure; + } + // open for reading + if (hCell < 0) { + if ( (hCell = Rast_open_old((char *) pszCellName, (char *) pszMapset)) < 0 ) { + CPLError( CE_Failure, CPLE_AppDefined, "GRASS: Cannot open raster '%s'", pszCellName ); + return CE_Failure; + } + } + + /* Read Data */ + CELL *cbuf = NULL; + FCELL *fbuf = NULL; + DCELL *dbuf = NULL; + bool direct = false; + + /* Reset space if default (0) */ + if ( nPixelSpace == 0 ) + nPixelSpace = GDALGetDataTypeSize ( eBufType ) / 8; + + if ( nLineSpace == 0 ) + nLineSpace = nBufXSize * nPixelSpace; + + if ( nGRSType == CELL_TYPE && ( !nativeNulls || eBufType != GDT_Int32 || sizeof(CELL) != 4 || + nPixelSpace != sizeof(CELL) ) ) + { + cbuf = Rast_allocate_c_buf(); + } else if( nGRSType == FCELL_TYPE && ( eBufType != GDT_Float32 || nPixelSpace != sizeof(FCELL) ) ) { + fbuf = Rast_allocate_f_buf(); + } else if( nGRSType == DCELL_TYPE && ( eBufType != GDT_Float64 || nPixelSpace != sizeof(DCELL) ) ) { + dbuf = Rast_allocate_d_buf(); + } else { + direct = true; + } + + for ( int row = 0; row < nBufYSize; row++ ) { + char *pnt = (char *)pData + row * nLineSpace; + + if ( nGRSType == CELL_TYPE ) { + if ( direct ) { + Rast_get_c_row ( hCell, (CELL *) pnt, row ); + } else { + Rast_get_c_row ( hCell, cbuf, row ); + + /* Reset NULLs */ + for ( int col = 0; col < nBufXSize; col++ ) { + if ( Rast_is_c_null_value(&(cbuf[col])) ) + cbuf[col] = (CELL) dfNoData; + } + + GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL), + (void *) pnt, eBufType, nPixelSpace, + nBufXSize ); + } + } else if( nGRSType == FCELL_TYPE ) { + if ( direct ) { + Rast_get_f_row ( hCell, (FCELL *) pnt, row ); + } else { + Rast_get_f_row ( hCell, fbuf, row ); + + GDALCopyWords ( (void *) fbuf, GDT_Float32, sizeof(FCELL), + (void *) pnt, eBufType, nPixelSpace, + nBufXSize ); + } + } else if( nGRSType == DCELL_TYPE ) { + if ( direct ) { + Rast_get_d_row ( hCell, (DCELL *) pnt, row ); + } else { + Rast_get_d_row ( hCell, dbuf, row ); + + GDALCopyWords ( (void *) dbuf, GDT_Float64, sizeof(DCELL), + (void *) pnt, eBufType, nPixelSpace, + nBufXSize ); + } + } + } + + if ( cbuf ) G_free ( cbuf ); + if ( fbuf ) G_free ( fbuf ); + if ( dbuf ) G_free ( dbuf ); + + // close to avoid confusion with other GRASS raster bands + Rast_close( hCell ); + hCell = -1; + + return CE_None; +} + +/************************************************************************/ +/* GetColorInterpretation() */ +/************************************************************************/ + +GDALColorInterp GRASSRasterBand::GetColorInterpretation() + +{ + if( poCT != NULL ) + return GCI_PaletteIndex; + else + return GCI_GrayIndex; +} + +/************************************************************************/ +/* GetColorTable() */ +/************************************************************************/ + +GDALColorTable *GRASSRasterBand::GetColorTable() + +{ + return poCT; +} + +/************************************************************************/ +/* GetMinimum() */ +/************************************************************************/ + +double GRASSRasterBand::GetMinimum( int *pbSuccess ) + +{ + if( pbSuccess ) + *pbSuccess = bHaveMinMax; + + if( bHaveMinMax ) + return dfCellMin; + + else if( eDataType == GDT_Float32 || eDataType == GDT_Float64 ) + return -4294967295.0; + else + return 0; +} + +/************************************************************************/ +/* GetMaximum() */ +/************************************************************************/ + +double GRASSRasterBand::GetMaximum( int *pbSuccess ) + +{ + if( pbSuccess ) + *pbSuccess = bHaveMinMax; + + if( bHaveMinMax ) + return dfCellMax; + + else if( eDataType == GDT_Float32 || eDataType == GDT_Float64 ) + return 4294967295.0; + else if( eDataType == GDT_UInt32 ) + return 4294967295.0; + else if( eDataType == GDT_UInt16 ) + return 65535; + else + return 255; +} + +/************************************************************************/ +/* GetNoDataValue() */ +/************************************************************************/ + +double GRASSRasterBand::GetNoDataValue( int *pbSuccess ) + +{ + if( pbSuccess ) + *pbSuccess = TRUE; + + return dfNoData; +} + +/************************************************************************/ +/* ==================================================================== */ +/* GRASSDataset */ +/* ==================================================================== */ +/************************************************************************/ + +/************************************************************************/ +/* GRASSDataset() */ +/************************************************************************/ + +GRASSDataset::GRASSDataset() +{ + pszProjection = NULL; + + adfGeoTransform[0] = 0.0; + adfGeoTransform[1] = 1.0; + adfGeoTransform[2] = 0.0; + adfGeoTransform[3] = 0.0; + adfGeoTransform[4] = 0.0; + adfGeoTransform[5] = 1.0; + pszGisdbase = NULL; + pszLocation = NULL; + pszElement = NULL; +} + +/************************************************************************/ +/* ~GRASSDataset() */ +/************************************************************************/ + +GRASSDataset::~GRASSDataset() +{ + + if ( pszGisdbase ) + G_free ( pszGisdbase ); + + if ( pszLocation ) + G_free ( pszLocation ); + + if ( pszElement ) + G_free ( pszElement ); + + G_free( pszProjection ); +} + +/************************************************************************/ +/* GetProjectionRef() */ +/************************************************************************/ + +const char *GRASSDataset::_GetProjectionRef() +{ + if( pszProjection == NULL ) + return ""; + else + return pszProjection; +} + +/************************************************************************/ +/* GetGeoTransform() */ +/************************************************************************/ + +CPLErr GRASSDataset::GetGeoTransform( double * padfGeoTransform ) +{ + memcpy( padfGeoTransform, adfGeoTransform, sizeof(double) * 6 ); + + return CE_None; +} + +/************************************************************************/ +/* SplitPath() */ +/* Split full path to cell or group to: */ +/* gisdbase, location, mapset, element, name */ +/* New string are allocated and should be freed when no longer needed. */ +/* */ +/* Returns: true - OK */ +/* false - failed */ +/************************************************************************/ +bool GRASSDataset::SplitPath( char *path, char **gisdbase, char **location, + char **mapset, char **element, char **name ) +{ + char *p; + char *ptr[5]; + char *tmp; + int i = 0; + + *gisdbase = NULL; + *location = NULL; + *mapset = NULL; + *element = NULL; + *name = NULL; + + if ( !path || strlen(path) == 0 ) + return false; + + tmp = G_store ( path ); + + while ( (p = strrchr(tmp,'/')) != NULL && i < 4 ) { + *p = '\0'; + + if ( strlen(p+1) == 0 ) /* repeated '/' */ + continue; + + ptr[i++] = p+1; + } + + /* Note: empty GISDBASE == 0 is not accepted (relative path) */ + if ( i != 4 ) { + G_free ( tmp ); + return false; + } + + *gisdbase = G_store ( tmp ); + *location = G_store ( ptr[3] ); + *mapset = G_store ( ptr[2] ); + *element = G_store ( ptr[1] ); + *name = G_store ( ptr[0] ); + + G_free ( tmp ); + return true; +} + +/************************************************************************/ +/* Open() */ +/************************************************************************/ + +typedef int (*GrassErrorHandler)(const char *, int); + +GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo ) + +{ + char *pszGisdb = NULL, *pszLoc = NULL; + char *pszMapset = NULL, *pszElem = NULL, *pszName = NULL; + char **papszCells = NULL; + char **papszMapsets = NULL; + +/* -------------------------------------------------------------------- */ +/* Does this even look like a grass file path? */ +/* -------------------------------------------------------------------- */ + if( strstr(poOpenInfo->pszFilename,"/cellhd/") == NULL + && strstr(poOpenInfo->pszFilename,"/group/") == NULL ) + return NULL; + + /* Always init, if no rasters are opened G_no_gisinit resets the projection and + * rasters in different projection may be then opened */ + + // Don't use GISRC file and read/write GRASS variables (from location G_VAR_GISRC) to memory only. + G_set_gisrc_mode ( G_GISRC_MODE_MEMORY ); + + // Init GRASS libraries (required) + G_no_gisinit(); // Doesn't check write permissions for mapset compare to G_gisinit + + // Set error function + G_set_error_routine ( (GrassErrorHandler) Grass2CPLErrorHook ); + + // GISBASE is path to the directory where GRASS is installed, + if ( !getenv( "GISBASE" ) ) { + static char* gisbaseEnv = NULL; + const char *gisbase = GRASS_GISBASE; + CPLError( CE_Warning, CPLE_AppDefined, "GRASS warning: GISBASE " + "environment variable was not set, using:\n%s", gisbase ); + char buf[2000]; + snprintf ( buf, sizeof(buf), "GISBASE=%s", gisbase ); + buf[sizeof(buf)-1] = '\0'; + + CPLFree(gisbaseEnv); + gisbaseEnv = CPLStrdup ( buf ); + putenv( gisbaseEnv ); + } + + if ( !SplitPath( poOpenInfo->pszFilename, &pszGisdb, &pszLoc, &pszMapset, + &pszElem, &pszName) ) { + return NULL; + } + +/* -------------------------------------------------------------------- */ +/* Check element name */ +/* -------------------------------------------------------------------- */ + if ( strcmp(pszElem,"cellhd") != 0 && strcmp(pszElem,"group") != 0 ) { + G_free(pszGisdb); + G_free(pszLoc); + G_free(pszMapset); + G_free(pszElem); + G_free(pszName); + return NULL; + } + +/* -------------------------------------------------------------------- */ +/* Set GRASS variables */ +/* -------------------------------------------------------------------- */ + + G_setenv_nogisrc( "GISDBASE", pszGisdb ); + G_setenv_nogisrc( "LOCATION_NAME", pszLoc ); + G_setenv_nogisrc( "MAPSET", pszMapset); // group is searched only in current mapset + G_reset_mapsets(); + G_add_mapset_to_search_path ( pszMapset ); + +/* -------------------------------------------------------------------- */ +/* Check if this is a valid grass cell. */ +/* -------------------------------------------------------------------- */ + if ( strcmp(pszElem,"cellhd") == 0 ) { + + if ( G_find_file2("cell", pszName, pszMapset) == NULL ) { + G_free(pszGisdb); G_free(pszLoc); G_free(pszMapset); G_free(pszElem); G_free(pszName); + return NULL; + } + + papszMapsets = CSLAddString( papszMapsets, pszMapset ); + papszCells = CSLAddString( papszCells, pszName ); + } +/* -------------------------------------------------------------------- */ +/* Check if this is a valid GRASS imagery group. */ +/* -------------------------------------------------------------------- */ + else { + struct Ref ref; + + I_init_group_ref( &ref ); + if ( I_get_group_ref( pszName, &ref ) == 0 ) { + G_free(pszGisdb); G_free(pszLoc); G_free(pszMapset); G_free(pszElem); G_free(pszName); + return NULL; + } + + for( int iRef = 0; iRef < ref.nfiles; iRef++ ) + { + papszCells = CSLAddString( papszCells, ref.file[iRef].name ); + papszMapsets = CSLAddString( papszMapsets, ref.file[iRef].mapset ); + G_add_mapset_to_search_path ( ref.file[iRef].mapset ); + } + + I_free_group_ref( &ref ); + } + + G_free( pszMapset ); + G_free( pszName ); + +/* -------------------------------------------------------------------- */ +/* Create a corresponding GDALDataset. */ +/* -------------------------------------------------------------------- */ + GRASSDataset*poDS = new GRASSDataset(); + + /* notdef: should only allow read access to an existing cell, right? */ + poDS->eAccess = poOpenInfo->eAccess; + + poDS->pszGisdbase = pszGisdb; + poDS->pszLocation = pszLoc; + poDS->pszElement = pszElem; + +/* -------------------------------------------------------------------- */ +/* Capture some information from the file that is of interest. */ +/* -------------------------------------------------------------------- */ + + Rast_get_cellhd( papszCells[0], papszMapsets[0], &(poDS->sCellInfo) ); + + poDS->nRasterXSize = poDS->sCellInfo.cols; + poDS->nRasterYSize = poDS->sCellInfo.rows; + + poDS->adfGeoTransform[0] = poDS->sCellInfo.west; + poDS->adfGeoTransform[1] = poDS->sCellInfo.ew_res; + poDS->adfGeoTransform[2] = 0.0; + poDS->adfGeoTransform[3] = poDS->sCellInfo.north; + poDS->adfGeoTransform[4] = 0.0; + poDS->adfGeoTransform[5] = -1 * poDS->sCellInfo.ns_res; + +/* -------------------------------------------------------------------- */ +/* Try to get a projection definition. */ +/* -------------------------------------------------------------------- */ + struct Key_Value *projinfo, *projunits; + + projinfo = G_get_projinfo(); + projunits = G_get_projunits(); + poDS->pszProjection = GPJ_grass_to_wkt ( projinfo, projunits, 0, 0); + if (projinfo) G_free_key_value(projinfo); + if (projunits) G_free_key_value(projunits); + +/* -------------------------------------------------------------------- */ +/* Create band information objects. */ +/* -------------------------------------------------------------------- */ + for( int iBand = 0; papszCells[iBand] != NULL; iBand++ ) + { + GRASSRasterBand *rb = new GRASSRasterBand( poDS, iBand+1, papszMapsets[iBand], + papszCells[iBand] ); + + if ( !rb->valid ) { + CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster band %d", iBand); + delete rb; + delete poDS; + return NULL; + } + + poDS->SetBand( iBand+1, rb ); + } + + CSLDestroy(papszCells); + CSLDestroy(papszMapsets); + +/* -------------------------------------------------------------------- */ +/* Confirm the requested access is supported. */ +/* -------------------------------------------------------------------- */ + if( poOpenInfo->eAccess == GA_Update ) + { + delete poDS; + CPLError( CE_Failure, CPLE_NotSupported, + "The GRASS driver does not support update access to existing" + " datasets.\n" ); + return NULL; + } + + return poDS; +} + +/************************************************************************/ +/* GDALRegister_GRASS() */ +/************************************************************************/ + +void GDALRegister_GRASS() +{ + if( !GDAL_CHECK_VERSION( "GDAL/GRASS driver" ) ) + return; + + if( GDALGetDriverByName( "GRASS" ) != NULL ) + return; + + GDALDriver *poDriver = new GDALDriver(); + + poDriver->SetDescription( "GRASS" ); + poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" ); + poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "GRASS Rasters (7+)" ); + poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "drivers/raster/grass.html" ); + + poDriver->pfnOpen = GRASSDataset::Open; + + GetGDALDriverManager()->RegisterDriver( poDriver ); +} diff -Nru libgdal-grass-3.0.4/Makefile.in libgdal-grass-3.4.3/Makefile.in --- libgdal-grass-3.0.4/Makefile.in 2020-01-28 11:01:41.000000000 +0000 +++ libgdal-grass-3.4.3/Makefile.in 2022-04-22 11:30:01.000000000 +0000 @@ -33,8 +33,8 @@ rm -fr Makefile config.status config.log autom*.cache -$(GLIBNAME): grass57dataset.o - $(LD_SHARED) $(LDFLAGS) grass57dataset.o $(LIBS) -o $(GLIBNAME) +$(GLIBNAME): grass.o + $(LD_SHARED) $(LDFLAGS) grass.o $(LIBS) -o $(GLIBNAME) $(OLIBNAME): ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o $(LD_SHARED) $(LDFLAGS) ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o $(LIBS) -o $(OLIBNAME) diff -Nru libgdal-grass-3.0.4/ogrgrassdatasource.cpp libgdal-grass-3.4.3/ogrgrassdatasource.cpp --- libgdal-grass-3.0.4/ogrgrassdatasource.cpp 2020-01-28 11:01:41.000000000 +0000 +++ libgdal-grass-3.4.3/ogrgrassdatasource.cpp 2022-04-22 11:30:01.000000000 +0000 @@ -6,7 +6,7 @@ * ****************************************************************************** * Copyright (c) 2005, Radim Blazek - * Copyright (c) 2008-2010, Even Rouault + * Copyright (c) 2008-2020, Even Rouault * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -31,11 +31,8 @@ #include "cpl_conv.h" #include "cpl_string.h" -CPL_CVSID("$Id: ogrgrassdatasource.cpp ff8146d84de7cba8e09d212d5481ea7d2ede3e98 2017-06-27 20:47:31Z Even Rouault $") +CPL_CVSID("$Id: ogrgrassdatasource.cpp a832da5b936bac8438f9c50e7c20e563fd94c9ff 2020-09-22 13:06:27 +0200 Markus Neteler $") -#if GRASS_VERSION_MAJOR >= 7 -#define G__setenv G_setenv_nogisrc -#endif /************************************************************************/ /* Grass2CPLErrorHook() */ @@ -88,11 +85,7 @@ /* Open() */ /************************************************************************/ -#if (GRASS_VERSION_MAJOR >= 6 && GRASS_VERSION_MINOR >= 3) || GRASS_VERSION_MAJOR >= 7 typedef int (*GrassErrorHandler)(const char *, int); -#else -typedef int (*GrassErrorHandler)(char *, int); -#endif int OGRGRASSDataSource::Open( const char * pszNewName, int /*bUpdate*/, int bTestOpen, int /*bSingleNewFileIn*/ ) @@ -183,18 +176,15 @@ /* -------------------------------------------------------------------- */ /* Set GRASS variables */ /* -------------------------------------------------------------------- */ - G__setenv( "GISDBASE", pszGisdbase ); - G__setenv( "LOCATION_NAME", pszLocation ); - G__setenv( "MAPSET", pszMapset); + G_setenv_nogisrc( "GISDBASE", pszGisdbase ); + G_setenv_nogisrc( "LOCATION_NAME", pszLocation ); + G_setenv_nogisrc( "MAPSET", pszMapset); G_reset_mapsets(); G_add_mapset_to_search_path ( pszMapset ); /* -------------------------------------------------------------------- */ /* Open GRASS vector map */ /* -------------------------------------------------------------------- */ -#if GRASS_VERSION_MAJOR < 7 - Vect_set_fatal_error ( GV_FATAL_PRINT ); // Print error and continue -#endif Vect_set_open_level (2); int level = Vect_open_old ( &map, pszMap, pszMapset); diff -Nru libgdal-grass-3.0.4/ogrgrassdriver.cpp libgdal-grass-3.4.3/ogrgrassdriver.cpp --- libgdal-grass-3.0.4/ogrgrassdriver.cpp 2020-01-28 11:01:41.000000000 +0000 +++ libgdal-grass-3.4.3/ogrgrassdriver.cpp 2022-04-22 11:30:01.000000000 +0000 @@ -30,7 +30,7 @@ #include "cpl_conv.h" #include "cpl_string.h" -CPL_CVSID("$Id: ogrgrassdriver.cpp ff8146d84de7cba8e09d212d5481ea7d2ede3e98 2017-06-27 20:47:31Z Even Rouault $") +CPL_CVSID("$Id: ogrgrassdriver.cpp 1761acd90777d5bcc49eddbc13c193098f0ed40b 2020-10-01 12:12:00 +0200 Even Rouault $") /************************************************************************/ /* ~OGRGRASSDriver() */ @@ -90,7 +90,7 @@ poDriver->SetDescription( "GRASS" ); poDriver->SetMetadataItem( GDAL_DCAP_VECTOR, "YES" ); poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "GRASS Vectors (5.7+)" ); - poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "drv_grass.html" ); + poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "drivers/vector/grass.html" ); OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( poDriver ); } diff -Nru libgdal-grass-3.0.4/ogrgrass.h libgdal-grass-3.4.3/ogrgrass.h --- libgdal-grass-3.0.4/ogrgrass.h 2020-01-28 11:01:41.000000000 +0000 +++ libgdal-grass-3.4.3/ogrgrass.h 2022-04-22 11:30:01.000000000 +0000 @@ -1,5 +1,5 @@ /****************************************************************************** - * $Id: ogrgrass.h 2c3d60220a2d6b41496ded571e231b96435bffa0 2016-11-25 14:09:24Z Even Rouault $ + * $Id: ogrgrass.h a832da5b936bac8438f9c50e7c20e563fd94c9ff 2020-09-22 13:06:27 +0200 Markus Neteler $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Private definitions for OGR/GRASS driver. @@ -37,17 +37,13 @@ #include #include #include -#if GRASS_VERSION_MAJOR >= 7 #include -#else - #include -#endif } /************************************************************************/ /* OGRGRASSLayer */ /************************************************************************/ -class OGRGRASSLayer : public OGRLayer +class OGRGRASSLayer final: public OGRLayer { public: OGRGRASSLayer( int layer, struct Map_info * map ); @@ -125,7 +121,7 @@ /************************************************************************/ /* OGRGRASSDataSource */ /************************************************************************/ -class OGRGRASSDataSource : public OGRDataSource +class OGRGRASSDataSource final: public OGRDataSource { public: OGRGRASSDataSource(); @@ -159,7 +155,7 @@ /************************************************************************/ /* OGRGRASSDriver */ /************************************************************************/ -class OGRGRASSDriver : public OGRSFDriver +class OGRGRASSDriver final: public OGRSFDriver { public: virtual ~OGRGRASSDriver(); diff -Nru libgdal-grass-3.0.4/ogrgrasslayer.cpp libgdal-grass-3.4.3/ogrgrasslayer.cpp --- libgdal-grass-3.0.4/ogrgrasslayer.cpp 2020-01-28 11:01:41.000000000 +0000 +++ libgdal-grass-3.4.3/ogrgrasslayer.cpp 2022-04-22 11:30:01.000000000 +0000 @@ -6,7 +6,7 @@ * ****************************************************************************** * Copyright (c) 2005, Radim Blazek - * Copyright (c) 2008-2010, Even Rouault + * Copyright (c) 2008-2020, Even Rouault * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -31,7 +31,7 @@ #include "ogrgrass.h" #include "cpl_conv.h" -CPL_CVSID("$Id: ogrgrasslayer.cpp 8e5eeb35bf76390e3134a4ea7076dab7d478ea0e 2018-11-14 22:55:13 +0100 Even Rouault $") +CPL_CVSID("$Id: ogrgrasslayer.cpp 5163a8056bee931f5bc8e72676d90092cdd1d760 2021-08-12 22:25:24 +0200 Even Rouault $") /************************************************************************/ /* OGRGRASSLayer() */ @@ -486,8 +486,10 @@ // Go through category index until first record of current category // is found or a category > current is found - int cidxcat, type, id; + int id = -1; while ( cidx < ncats ) { + int cidxcat = 0; + int type = 0; Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx, &cidxcat, &type, &id ); @@ -641,11 +643,7 @@ Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx, &cat, &type, &id ); -#if GRASS_VERSION_MAJOR >= 7 - struct bound_box box; -#else - BOUND_BOX box; -#endif + struct bound_box box; switch ( type ) { @@ -1013,11 +1011,7 @@ /************************************************************************/ OGRErr OGRGRASSLayer::GetExtent (OGREnvelope *psExtent, int /*bForce*/) { -#if GRASS_VERSION_MAJOR >= 7 struct bound_box box; -#else - BOUND_BOX box; -#endif Vect_get_map_box ( poMap, &box ); diff -Nru libgdal-grass-3.0.4/README libgdal-grass-3.4.3/README --- libgdal-grass-3.0.4/README 2020-01-28 11:01:41.000000000 +0000 +++ libgdal-grass-3.4.3/README 2022-04-22 11:30:01.000000000 +0000 @@ -13,14 +13,14 @@ To build this driver it is necessary for it to find GDAL and GRASS support files. Typically the configure and build process would look something like: -./configure --with-gdal=/usr/local/bin/gdal-config --with-grass=/usr/local/grass-7.0.0 +./configure --with-gdal=/usr/local/bin/gdal-config --with-grass=/usr/local/grass-7.0.1 make sudo make install See also: - http://www.gdal.org/ - http://grass.osgeo.org + https://gdal.org/ + https://grass.osgeo.org --- @@ -31,22 +31,22 @@ Question: -I am trying to install gdal-grass 1.3.1 on Red hat enterprise linux -advanced server 3.0. I have previously installed gdal 1.3.1 without- -grass, and Grass 6.0.1 with-gdal. I have tried to configure gdal-grass +I am trying to install gdal-grass 3.1.3 on RedHat Enterprise Linux +advanced server 3.0. I have previously installed gdal 3.1.3 --without-grass, +and GRASS 7.0.1 with GDAL. I have tried to configure gdal-grass with: -./configure --with-gdal=/usr/local/gdal/bin/gdal-config --with- -grass=/usr/local/grass-6.0.1 +./configure --with-gdal=/usr/local/bin/gdal-config \ + --with-grass=/usr/local/grass-7.0.1 It seems to find gdal alright, but then balks at the Grass location. The Grass location specified above is indeed the correct location. I have -also tried adding --with-grass=/usr/local/grass-6.0.1/lib, but with no +also tried adding --with-grass=/usr/local/grass-7.0.1/lib, but with no success. My error is: ... checking for G_asprintf in -lgrass_gis ... no -configure: error: --with-grass=/usr/local/grass-6.0.1 requested, but +configure: error: --with-grass=/usr/local/grass-7.0.1 requested, but libraries not found? @@ -55,8 +55,8 @@ Your problem is likely to be solved by editing /etc/ld.so.conf to include the locations of proj, gdal, grass, and geos. Specifically, the full path to both gdal-config and geos-config, and the full paths -to the library locations of proj (often /usr/local/lib) and grass (/ -usr/local/grass-6.0.1/lib). After editing ld.so.conf, run ldconfig, +to the library locations of proj (often /usr/local/lib) and grass +(/usr/local/grass-7.0.1/lib). After editing ld.so.conf, run ldconfig, and you should be good to go. I ran into this problem this weekend (and posted for help to this diff -Nru libgdal-grass-3.0.4/VERSION libgdal-grass-3.4.3/VERSION --- libgdal-grass-3.0.4/VERSION 2020-01-28 11:01:41.000000000 +0000 +++ libgdal-grass-3.4.3/VERSION 2022-04-22 11:30:01.000000000 +0000 @@ -1 +1 @@ -3.0.4 +3.4.3