diff --git a/.flake8 b/.flake8
index 3e7f6b97cbf..91af147aefb 100644
--- a/.flake8
+++ b/.flake8
@@ -20,7 +20,7 @@ per-file-ignores =
# E741 ambiguous variable name 'l'
man/build_html.py: E501
man/build_md.py: E501
- doc/python/m.distance.py: E501
+ doc/examples/python/m.distance.py: E501
gui/scripts/d.wms.py: E501
gui/wxpython/image2target/g.gui.image2target.py: E501
gui/wxpython/photo2image/g.gui.photo2image.py: E501
@@ -29,7 +29,6 @@ per-file-ignores =
gui/wxpython/animation/g.gui.animation.py: E501
gui/wxpython/tplot/g.gui.tplot.py: E501
gui/wxpython/iclass/g.gui.iclass.py: E501
- gui/wxpython/iclass/statistics.py: F841, F405, F403
gui/wxpython/location_wizard/wizard.py: E722
gui/wxpython/mapdisp/main.py: E722
gui/wxpython/mapdisp/test_mapdisp.py: E501
@@ -41,11 +40,8 @@ per-file-ignores =
gui/wxpython/menustrings.py: E501
# C wrappers call libgis.G_gisinit before importing other modules.
# TODO: Is this really needed?
+ python/grass/jupyter/__init__.py: E501
python/grass/pygrass/vector/__init__.py: E402
- python/grass/temporal/datetime_math.py: E722
- python/grass/temporal/spatial_topology_dataset_connector.py: E722
- python/grass/temporal/temporal_algebra.py: E722
- python/grass/temporal/temporal_granularity.py: E722
# Current benchmarks/tests are changing sys.path before import.
# Possibly, a different approach should be taken there anyway.
python/grass/pygrass/tests/benchmark.py: F821
diff --git a/.github/actions/create-upload-suggestions/action.yml b/.github/actions/create-upload-suggestions/action.yml
index 135aa41845c..fe6a111fcbe 100644
--- a/.github/actions/create-upload-suggestions/action.yml
+++ b/.github/actions/create-upload-suggestions/action.yml
@@ -177,7 +177,7 @@ runs:
echo "diff-file-name=${INPUT_DIFF_FILE_NAME}" >> "${GITHUB_OUTPUT}"
env:
INPUT_DIFF_FILE_NAME: ${{ steps.tool-name-safe.outputs.diff-file-name }}
- - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
id: upload-diff
if: >-
${{ (steps.files_changed.outputs.files_changed == 'true') &&
@@ -200,7 +200,7 @@ runs:
echo 'Suggestions can only be added near to lines changed in this PR.'
echo 'If any fixes can be added as code suggestions, they will be added shortly from another workflow.'
} >> "${GITHUB_STEP_SUMMARY}"
- - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
id: upload-changes
if: >-
${{ always() &&
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 464ccdce2b8..2120719f4f3 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -145,7 +145,7 @@ notebook:
- changed-files:
- any-glob-to-any-file:
- '**/*.ipynb'
- - doc/notebooks/**
+ - doc/examples/notebooks/**
- python/grass/jupyter/**
C:
- changed-files:
diff --git a/.github/workflows/additional_checks.yml b/.github/workflows/additional_checks.yml
index 76554f24db3..3ec9b1fd0ac 100644
--- a/.github/workflows/additional_checks.yml
+++ b/.github/workflows/additional_checks.yml
@@ -17,6 +17,8 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true
+permissions: {}
+
jobs:
additional-checks:
name: Additional checks
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 77ed085ad96..90ead51caf7 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -31,6 +31,7 @@ jobs:
language:
- c-cpp
- python
+ - actions
concurrency:
group: ${{ github.workflow }}-${{
@@ -56,7 +57,7 @@ jobs:
if: ${{ matrix.language == 'c-cpp' }}
- name: Initialize CodeQL
- uses: github/codeql-action/init@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
+ uses: github/codeql-action/init@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
@@ -81,6 +82,6 @@ jobs:
run: .github/workflows/build_ubuntu-22.04.sh "${HOME}/install"
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
+ uses: github/codeql-action/analyze@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
with:
category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/create_release_draft.yml b/.github/workflows/create_release_draft.yml
index 37585bb7ebb..b2158505e20 100644
--- a/.github/workflows/create_release_draft.yml
+++ b/.github/workflows/create_release_draft.yml
@@ -74,7 +74,7 @@ jobs:
sha256sum ${{ env.GRASS }}.tar.xz > ${{ env.GRASS }}.tar.xz.sha256
- name: Publish draft distribution to GitHub (for tags only)
if: startsWith(github.ref, 'refs/tags/')
- uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0
+ uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
name: GRASS GIS ${{ github.ref_name }}
body: |
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index a9279fede7b..0ef4ec2df2d 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -22,8 +22,9 @@ on:
release:
types: [published]
-jobs:
+permissions: {}
+jobs:
# Run for push to configured branches and all published releases.
# Take care of different os.
# For main branch, created tags are:
@@ -47,6 +48,10 @@ jobs:
- ubuntu_wxgui
fail-fast: false
+ permissions:
+ contents: read
+ packages: write
+
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -66,7 +71,7 @@ jobs:
latest=false
suffix=-${{ matrix.os }}
- name: Set up QEMU
- uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
+ uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- name: Login to DockerHub
@@ -76,7 +81,7 @@ jobs:
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
id: docker_build
- uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
+ uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
with:
push: true
pull: true
diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml
index 6b6286ef3f0..9e508baf81f 100644
--- a/.github/workflows/gcc.yml
+++ b/.github/workflows/gcc.yml
@@ -8,6 +8,8 @@ on:
- releasebranch_*
pull_request:
+permissions: {}
+
jobs:
build:
name: ${{ matrix.c }} & ${{ matrix.cpp }}
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 026a3675819..ed2132cc555 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -14,6 +14,9 @@ env:
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true
+
+permissions: {}
+
jobs:
macos_build:
name: macOS build
@@ -50,7 +53,7 @@ jobs:
# Year and week of year so cache key changes weekly
run: echo "date=$(date +%Y-%U)" >> "${GITHUB_OUTPUT}"
- name: Setup Mamba
- uses: mamba-org/setup-micromamba@068f1ab4b37ed9b3d9f73da7db90a0cda0a48d29 # v2.0.3
+ uses: mamba-org/setup-micromamba@0dea6379afdaffa5d528b3d1dabc45da37f443fc # v2.0.4
with:
init-shell: bash
environment-file: .github/workflows/macos_dependencies.txt
@@ -107,7 +110,7 @@ jobs:
nc_spm_full_v2alpha2.tar.gz"
- name: Make HTML test report available
if: ${{ !cancelled() }}
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: testreport-macOS
path: testreport
diff --git a/.github/workflows/milestones.yml b/.github/workflows/milestones.yml
index e2ade4eb091..4e9fa634a75 100644
--- a/.github/workflows/milestones.yml
+++ b/.github/workflows/milestones.yml
@@ -5,12 +5,17 @@ on:
pull_request_target:
types: [closed]
+permissions: {}
+
jobs:
assign-milestone:
runs-on: ubuntu-latest
if: github.event.pull_request.merged
+ permissions:
+ contents: read
+ pull-requests: write
steps:
- # Retreiving the current milestoone from API instead of github context,
+ # Retrieving the current milestone from API instead of github context,
# so up-to-date information is used when running after being queued or for reruns
# Otherwise, the information should be available using
# ${{ github.event.pull_request.milestone.title }}
diff --git a/.github/workflows/osgeo4w.yml b/.github/workflows/osgeo4w.yml
index 6931fd1f089..5eb97761c03 100644
--- a/.github/workflows/osgeo4w.yml
+++ b/.github/workflows/osgeo4w.yml
@@ -8,6 +8,8 @@ on:
- releasebranch_*
pull_request:
+permissions: {}
+
jobs:
build:
name: ${{ matrix.os }} build and tests
@@ -138,7 +140,7 @@ jobs:
- name: Make HTML test report available
if: ${{ always() }}
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: testreport-${{ matrix.os }}
path: testreport
diff --git a/.github/workflows/periodic_update.yml b/.github/workflows/periodic_update.yml
index 64887e51827..a60d8a8e159 100644
--- a/.github/workflows/periodic_update.yml
+++ b/.github/workflows/periodic_update.yml
@@ -10,12 +10,18 @@ on:
# See https://crontab.guru/#32_10_*/100,1-7_*_WED
- cron: "32 10 */100,1-7 * WED"
+permissions: {}
+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
update-configure:
# The type of runner that the job will run on
runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- name: Create URL to the run output
diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml
index d646c2e544b..be266a744cf 100644
--- a/.github/workflows/pytest.yml
+++ b/.github/workflows/pytest.yml
@@ -8,6 +8,8 @@ on:
- releasebranch_*
pull_request:
+permissions: {}
+
jobs:
pytest:
concurrency:
@@ -123,7 +125,7 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Make python-only code coverage test report available
if: ${{ !cancelled() }}
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: python-codecoverage-report-${{ matrix.os }}-${{ matrix.python-version }}
path: coverage_html_report
diff --git a/.github/workflows/python-code-quality.yml b/.github/workflows/python-code-quality.yml
index b3c2918f2b7..627dbfc13f3 100644
--- a/.github/workflows/python-code-quality.yml
+++ b/.github/workflows/python-code-quality.yml
@@ -8,6 +8,8 @@ on:
- releasebranch_*
pull_request:
+permissions: {}
+
jobs:
python-checks:
name: Python Code Quality Checks
@@ -34,9 +36,9 @@ jobs:
# renovate: datasource=pypi depName=pylint
PYLINT_VERSION: "3.3.3"
# renovate: datasource=pypi depName=bandit
- BANDIT_VERSION: "1.8.0"
+ BANDIT_VERSION: "1.8.2"
# renovate: datasource=pypi depName=ruff
- RUFF_VERSION: "0.8.6"
+ RUFF_VERSION: "0.9.1"
runs-on: ${{ matrix.os }}
permissions:
@@ -129,13 +131,13 @@ jobs:
bandit -c pyproject.toml -iii -r . -f sarif -o bandit.sarif --exit-zero
- name: Upload Bandit Scan Results
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bandit.sarif
path: bandit.sarif
- name: Upload SARIF File into Security Tab
- uses: github/codeql-action/upload-sarif@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
+ uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
with:
sarif_file: bandit.sarif
@@ -192,8 +194,8 @@ jobs:
- name: Test compiling example modules
run: |
- ( cd doc/raster/r.example/ && make )
- ( cd doc/vector/v.example/ && make )
+ ( cd doc/examples/raster/r.example/ && make )
+ ( cd doc/examples/vector/v.example/ && make )
- name: Run Sphinx to check API documentation build
run: |
@@ -203,7 +205,7 @@ jobs:
cp -rp dist.$ARCH/docs/html/libpython sphinx-grass
- name: Make Sphinx documentation available
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: sphinx-grass
path: sphinx-grass
diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml
index 01a22f99edf..3138da70dda 100644
--- a/.github/workflows/super-linter.yml
+++ b/.github/workflows/super-linter.yml
@@ -12,6 +12,8 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true
+permissions: {}
+
jobs:
super-linter:
name: GitHub Super Linter
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index 5cb1c6a3122..5f130a00812 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -10,6 +10,8 @@ on:
- releasebranch_*
pull_request:
+permissions: {}
+
jobs:
ubuntu:
concurrency:
@@ -149,7 +151,7 @@ jobs:
- name: Make HTML test report available
if: ${{ always() }}
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
+ uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: testreport-${{ matrix.os }}-${{ matrix.config }}-${{ matrix.extra-include }}
path: testreport
diff --git a/.github/workflows/verify-success.yml b/.github/workflows/verify-success.yml
index 237c239f576..92fff2e1d12 100644
--- a/.github/workflows/verify-success.yml
+++ b/.github/workflows/verify-success.yml
@@ -45,34 +45,36 @@ on:
type: string
required: true
# Can't escape the handlebars in the description
- description:
+ description: >-
In the calling job that defines all the needed jobs,
send `toJson(needs)` inside `$` followed by `{{ }}`
fail_if_failure:
type: boolean
default: true
- description:
+ description: >-
If true, this workflow will fail if any job from 'needs_context was
failed
fail_if_cancelled:
type: boolean
default: true
- description:
+ description: >-
If true, this workflow will fail if any job from 'needs_context' was
cancelled
fail_if_skipped:
type: boolean
default: false
- description:
+ description: >-
If true, this workflow will fail if any job from 'needs_context' was
skipped
require_success:
type: boolean
default: true
- description:
+ description: >-
If true, this workflow will fail if no job from 'needs_context' was
successful
+permissions: {}
+
jobs:
verify-success:
name: Success
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 5b8c902d98b..211739a30c3 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -37,7 +37,7 @@ repos:
)
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
- rev: v0.8.6
+ rev: v0.9.1
hooks:
# Run the linter.
- id: ruff
diff --git a/Makefile b/Makefile
index 8b32a149a5a..a3f533c7d07 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@
# PURPOSE: It provides the commands necessary to compile, install,
# clean, and uninstall GRASS
# See INSTALL.md file for usage.
-# COPYRIGHT: (C) 2002-2024 by the GRASS Development Team
+# COPYRIGHT: (C) 2002-2025 by the GRASS Development Team
#
# This program is free software under the GNU General Public
# License (>=v2). Read the file COPYING that comes with GRASS
@@ -46,7 +46,6 @@ DIRS = \
visualization \
locale \
man \
- macosx \
mswindows
SUBDIRS = $(DIRS)
diff --git a/README.md b/README.md
index 7dfdb49df82..ef39e640721 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ visualization.
Launch this repository in Binder and experiment with GRASS's Python API in
Jupyter Notebooks by clicking the button below:
-[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/OSGeo/grass/main?labpath=doc%2Fnotebooks%2Fjupyter_example.ipynb)
+[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/OSGeo/grass/main?labpath=doc%2Fexamples%2Fnotebooks%2Fjupyter_example.ipynb)
## Contributing
diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md
index ff13e49331e..4d61c80e323 100644
--- a/REQUIREMENTS.md
+++ b/REQUIREMENTS.md
@@ -137,7 +137,7 @@ MacOSX users may go here to download precompiled libraries etc.:
---
-© _GRASS Development Team 1997-2024_
+© _GRASS Development Team 1997-2025_
Please report bugs here:
[https://grass.osgeo.org/contribute/](https://grass.osgeo.org/contribute/)
diff --git a/configure.ac b/configure.ac
index 0aeef9efc05..47d78b469b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@
# PURPOSE: This configure runs all the tests to determine what components
# are installed on the current system. It also defines certain
# configuration variables for compilation and installation.
-# COPYRIGHT: (C) 2000-2024 by the GRASS Development Team
+# COPYRIGHT: (C) 2000-2025 by the GRASS Development Team
#
# This program is free software under the GNU General
# Public License (>=v2). Read the file COPYING that
diff --git a/doc/gui/wxpython/example/Makefile b/doc/examples/gui/wxpython/Makefile
similarity index 100%
rename from doc/gui/wxpython/example/Makefile
rename to doc/examples/gui/wxpython/Makefile
diff --git a/doc/gui/wxpython/example/README b/doc/examples/gui/wxpython/README
similarity index 96%
rename from doc/gui/wxpython/example/README
rename to doc/examples/gui/wxpython/README
index 1e619486943..c615ed57452 100644
--- a/doc/gui/wxpython/example/README
+++ b/doc/examples/gui/wxpython/README
@@ -20,7 +20,7 @@ or it can be launched from the console.
1. Go to GRASS root directory
-2. Copy directory ./doc/gui/wxpython/example to ./gui/wxpython/example
+2. Copy directory ./doc/examples/gui/wxpython to ./gui/wxpython
3. Edit ./gui/wxpython/Makefile:
diff --git a/doc/gui/wxpython/example/dialogs.py b/doc/examples/gui/wxpython/dialogs.py
similarity index 100%
rename from doc/gui/wxpython/example/dialogs.py
rename to doc/examples/gui/wxpython/dialogs.py
diff --git a/doc/gui/wxpython/example/frame.py b/doc/examples/gui/wxpython/frame.py
similarity index 99%
rename from doc/gui/wxpython/example/frame.py
rename to doc/examples/gui/wxpython/frame.py
index 7f68642de9f..e947ee1a6b3 100644
--- a/doc/gui/wxpython/example/frame.py
+++ b/doc/examples/gui/wxpython/frame.py
@@ -41,8 +41,8 @@
from example.dialogs import ExampleMapDialog
# It is possible to call grass library functions (in C) directly via ctypes
-# however this is less stable. Example is available in trunk/doc/python/, ctypes
-# are used in nviz, vdigit, iclass gui modules.
+# however this is less stable. Example is available in trunk/doc/examples/python/,
+# ctypes are used in nviz, vdigit, iclass gui modules.
# from ctypes import *
# try:
diff --git a/doc/examples/gui/wxpython/g.gui.example.html b/doc/examples/gui/wxpython/g.gui.example.html
new file mode 100644
index 00000000000..c11ec5b2b8b
--- /dev/null
+++ b/doc/examples/gui/wxpython/g.gui.example.html
@@ -0,0 +1,66 @@
+
+
+
DESCRIPTION
+
+
+The purpose of the Example Tool is to make life easier
+for new wxGUI developers. It can serve as a basic template when
+creating standalone GRASS GUI-based application. Example tool
+can display one raster map a show information about it.
+
+
+
+Following topics are covered:
+
+
+
+ - creating standalone window
+ - adding toolbars, statusbar
+ - displaying raster map
+ - running GRASS modules from application
+ - creating dialog for element (raster, vector, ...) selection
+ - using temporary region
+ - access from main menu
+ - writing programmer documentation
+ - writing user documentation
+
+
+NOTE
+
+See README to learn how to get Example Tool to work.
+
+
+
+EXAMPLE TOOL TOOLBAR
+
+
+ -
+ Select raster layer
+ - Select raster layer and compute statistics related to this layer.
+
+
+SEE ALSO
+
+
+ wxGUI,
+ wxGUI components
+
+
+
+
+AUTHOR
+
+Anna Kratochvilova,
+Czech Technical University in Prague, Czech Republic
diff --git a/doc/gui/wxpython/example/g.gui.example.py b/doc/examples/gui/wxpython/g.gui.example.py
similarity index 100%
rename from doc/gui/wxpython/example/g.gui.example.py
rename to doc/examples/gui/wxpython/g.gui.example.py
diff --git a/doc/gui/wxpython/example/toolbars.py b/doc/examples/gui/wxpython/toolbars.py
similarity index 100%
rename from doc/gui/wxpython/example/toolbars.py
rename to doc/examples/gui/wxpython/toolbars.py
diff --git a/doc/notebooks/README.md b/doc/examples/notebooks/README.md
similarity index 88%
rename from doc/notebooks/README.md
rename to doc/examples/notebooks/README.md
index d07b8f826bb..9aaf8e5d226 100644
--- a/doc/notebooks/README.md
+++ b/doc/examples/notebooks/README.md
@@ -5,8 +5,8 @@
### Using the notebooks locally
Clone this repository with `git clone` first. Then, locally start the Jupyter
-notebook server from the command line in the `doc/notebooks/` directory
-containing the `*.ipynb` files with: `jupyter notebook`
+notebook server from the command line in the `doc/examples/notebooks/`
+directory containing the `*.ipynb` files with: `jupyter notebook`
This will open a new browser tab or window with a list of the contents of the
current working directory. Clicking on one of the `*.ipynb` files will start
diff --git a/doc/notebooks/hydrology.ipynb b/doc/examples/notebooks/hydrology.ipynb
similarity index 100%
rename from doc/notebooks/hydrology.ipynb
rename to doc/examples/notebooks/hydrology.ipynb
diff --git a/doc/notebooks/jupyter_example.ipynb b/doc/examples/notebooks/jupyter_example.ipynb
similarity index 100%
rename from doc/notebooks/jupyter_example.ipynb
rename to doc/examples/notebooks/jupyter_example.ipynb
diff --git a/doc/notebooks/jupyter_tutorial.ipynb b/doc/examples/notebooks/jupyter_tutorial.ipynb
similarity index 100%
rename from doc/notebooks/jupyter_tutorial.ipynb
rename to doc/examples/notebooks/jupyter_tutorial.ipynb
diff --git a/doc/notebooks/parallelization_tutorial.ipynb b/doc/examples/notebooks/parallelization_tutorial.ipynb
similarity index 100%
rename from doc/notebooks/parallelization_tutorial.ipynb
rename to doc/examples/notebooks/parallelization_tutorial.ipynb
diff --git a/doc/notebooks/scripting_example.ipynb b/doc/examples/notebooks/scripting_example.ipynb
similarity index 100%
rename from doc/notebooks/scripting_example.ipynb
rename to doc/examples/notebooks/scripting_example.ipynb
diff --git a/doc/notebooks/solar_potential.ipynb b/doc/examples/notebooks/solar_potential.ipynb
similarity index 100%
rename from doc/notebooks/solar_potential.ipynb
rename to doc/examples/notebooks/solar_potential.ipynb
diff --git a/doc/notebooks/temporal.ipynb b/doc/examples/notebooks/temporal.ipynb
similarity index 100%
rename from doc/notebooks/temporal.ipynb
rename to doc/examples/notebooks/temporal.ipynb
diff --git a/doc/notebooks/viewshed_analysis.ipynb b/doc/examples/notebooks/viewshed_analysis.ipynb
similarity index 100%
rename from doc/notebooks/viewshed_analysis.ipynb
rename to doc/examples/notebooks/viewshed_analysis.ipynb
diff --git a/doc/python/README b/doc/examples/python/README
similarity index 88%
rename from doc/python/README
rename to doc/examples/python/README
index e5f48fad99e..51c5c1ce9dc 100644
--- a/doc/python/README
+++ b/doc/examples/python/README
@@ -7,7 +7,7 @@ There are two ways of using Python to run GRASS commands:
- Module creation using hooks into the C library functions using ctypes.
- The scripts in the doc/python/examples/ directory will describe this.
+ The scripts in the doc/examples/python/ directory will describe this.
(Ctypes is standard in Python 2.5 and newer; replaces the SWIG
implementation in GRASS)
diff --git a/doc/python/m.distance.py b/doc/examples/python/m.distance.py
similarity index 100%
rename from doc/python/m.distance.py
rename to doc/examples/python/m.distance.py
diff --git a/doc/python/raster_example_ctypes.py b/doc/examples/python/raster_example_ctypes.py
similarity index 100%
rename from doc/python/raster_example_ctypes.py
rename to doc/examples/python/raster_example_ctypes.py
diff --git a/doc/python/script/Makefile b/doc/examples/python/script/Makefile
similarity index 100%
rename from doc/python/script/Makefile
rename to doc/examples/python/script/Makefile
diff --git a/doc/python/script/r.example.html b/doc/examples/python/script/r.example.html
similarity index 100%
rename from doc/python/script/r.example.html
rename to doc/examples/python/script/r.example.html
diff --git a/doc/python/script/r.example.py b/doc/examples/python/script/r.example.py
similarity index 100%
rename from doc/python/script/r.example.py
rename to doc/examples/python/script/r.example.py
diff --git a/doc/python/vector_example_ctypes.py b/doc/examples/python/vector_example_ctypes.py
similarity index 100%
rename from doc/python/vector_example_ctypes.py
rename to doc/examples/python/vector_example_ctypes.py
diff --git a/doc/raster/r.example/COMMENTS b/doc/examples/raster/r.example/COMMENTS
similarity index 100%
rename from doc/raster/r.example/COMMENTS
rename to doc/examples/raster/r.example/COMMENTS
diff --git a/doc/raster/r.example/Makefile b/doc/examples/raster/r.example/Makefile
similarity index 89%
rename from doc/raster/r.example/Makefile
rename to doc/examples/raster/r.example/Makefile
index 8636720f1df..f6061377f78 100644
--- a/doc/raster/r.example/Makefile
+++ b/doc/examples/raster/r.example/Makefile
@@ -1,6 +1,6 @@
# fix this relative to include/
# or use absolute path to the GRASS source code
-MODULE_TOPDIR = ../../..
+MODULE_TOPDIR = ../../../..
PGM = r.example
diff --git a/doc/raster/r.example/main.c b/doc/examples/raster/r.example/main.c
similarity index 100%
rename from doc/raster/r.example/main.c
rename to doc/examples/raster/r.example/main.c
diff --git a/doc/raster/r.example/r.example.html b/doc/examples/raster/r.example/r.example.html
similarity index 100%
rename from doc/raster/r.example/r.example.html
rename to doc/examples/raster/r.example/r.example.html
diff --git a/doc/examples/vector/TODO b/doc/examples/vector/TODO
new file mode 100644
index 00000000000..d43bffca15d
--- /dev/null
+++ b/doc/examples/vector/TODO
@@ -0,0 +1,258 @@
+ GRASS 6 vector TODO
+ ---------------------
+ (Radim Blazek, May 2006)
+
+This document is summary of my ideas on how vector part of GRASS GIS
+could be improved.
+
+It can be that you come to conclusion that vectors in GRASS are bad
+and it is necessary to start from scratch. In that case I would
+recommend to leave current library and modules intact and start the
+new work in parallel (the new modules could start with w.* or v2.*). I
+was thinking for example about completely new vector library based on
+OGC standard, using either OGR directly or an abstraction layer and
+OGR as an option (driver). That does not mean that I prefer simple
+feature specification over current GRASS implementation, I am not sure
+which one is better. In any case it would be pity to drop current
+topological format with all its flexibility. Each approach has
+advantages and disadvantages. I think that it the best to have in OS
+GIS all alternatives file/database and topology/simple feature.
+
+
+
+Historical notes
+----------------
+The current implementation of vectors is based on previous work which
+was present in GRASS5 (the vector library and modules and DBMI
+library). We started this work together with David D. Gray in autumn
+2000 (IIRC) but David had to leave GRASS project soon so that I almost
+all responsibility for vector development in GRASS6 and its results is
+mine.
+
+The current design of GRASS vectors is result of these factor:
++ very limited resources for development (necessity to use existing
+ free code/libraries/applications whenever possible)
++ relatively little experience with development of GIS application
++ respect for certain features of GRASS5 vector model and for existing
+ community which is using it
++ bad experience with quality of data produced in simple feature based
+ applications (ArcView)
+
+
+1. Library
+----------
+
+1.1 Geometry
+------------
+
+Keep topology and spatial index in file instead of in memory
+------------------------------------------------------------
+Scalability seems to be currently the biggest problem of GRASS
+vectors. The geometry of GRASS vectors (coor file) is never loaded
+whole to the memory. OTOH the support structures (topology and spatial
+index) are loaded to memory on runtime. It should be possible to use
+files for topology and spatial index also on runtime and that way
+decrease the memory occupied by running module (practically to
+zero). The speed will decrease a bit but not significantly because
+files are usually cached by system.
+
+* Update: implemented in r38385 (2009/07) by Markus Metz
+
+Temporary vector
+----------------
+Analytical modules process data in the output vector (for example
+v.overlay and v.buffer). Because many lines can be deleted (broken
+lines for example) and new lines are written at the end of coor file
+the output file can contain many 'dead' lines (not used space). It
+would be better to do processing in a temporary vector and copy only
+alive lines to the output when processing finished. That means
+implement Vect_open_temporary() which will work like Vect_open_new()
+but the files will be opened in temporary directory (it should not
+write to $MAPSET/vector).
+
+
+Recycle deleted lines
+---------------------
+The space which was occupied by a line in coor file is lost after call
+to Vect_delete_line(). A list of the free positions be kept and
+Vect_write_line() should write in that free space if possible instead
+of to append a new line to the end of the file. There is already empty
+structure 'recycle' in 'dig_head' where the list could be implemented
+(without changing 'dig_head' size, to keep binary compatibility).
+
+* Note: currently wxGUI vector digitizer 'undo' depends on this 'feature'
+
+Vect_rewrite_line
+-----------------
+Implement properly Vect_rewrite_line(). Currently it simply calls
+Vect_delete_line() and Vect_write_line(). It should be implemented so
+that if the new size of the line is the same as the old size it will
+be written in the same place in the coor file where the original line
+existed.
+
+* Note: see above
+
+Remove bounding box from support structures (?)
+-----------------------------------------------
+The vector structures (P_line, P_area, P_isle) store bounding box in
+N,S,E,W,T,B (doubles). Especially in case of element type GV_POINT the
+bounding box occupies a lot of space (2-3 times more than the point
+itself). I am not sure if this is really good idea, it is necesssary to
+valutate also how often Vect_line_box() is called and the impact of
+the necessity to calculate always the box on the fly (when it is not
+stored in the structure) which can be time consuming for example for
+areas or long lines.
+
+* See also https://trac.osgeo.org/grass/ticket/542
+* Update: implemented in r46898 (2011/07) by Markus Metz
+
+Switching to update mode
+------------------------
+It would be useful to have a possibility to switch to 'update' mode a
+map which was opened by Vect_open_old/new() and similarly to switch
+back to 'normal' mode. Currently it is necessary to call Vect_close()
+and Vect_open_update().
+
+Layer names
+-----------
+The layers are currently identified only by numbers but it is possible
+to assign to each layer number a name. The library can read these
+names but it is not possible to use the name as parameter for
+modules. It is necessary to write int Vect_get_layer_by_name ( struct
+Map_info *map, char *name) which will accept both names and numbers
+and use this function in vector modules. This is also important for
+OGR interface improvements (see below).
+
+* Update: implemented in r38548 (2009/07) by Martin Landa
+
+OGR interface
+-------------
+It is important to enable direct access to OGR data sources without
+v.external and without necessity to store anything in files. The
+problem of v.external is that topology is stored in file that means it
+can be wrong when the source is opened next time. It should be
+relatively easy to call Vect_build_ogr() whenever an OGR vector is
+opened with level2 (topology) requested and topology will be built on
+the fly. OGR vectors would be specified by virtual mapset name
+'OGR'. Each OGR datasource will be equivalent to GRASS vector and each
+OGR layer will be equivalent to GRASS layer (it is necessary to
+implement layer names, see above). It would be for example possible to
+display a shapefile or PostGIS layers directly:
+
+ d.vect map=./shapefiles/@OGR layer=roads # display shapefile ./shapefiles/roads.shp
+ d.vect map=PG:dbname=test@OGR layer=roads # display table roads from database test
+
+* Update: in progress,
+ see https://trac.osgeo.org/grass/wiki/Grass7/VectorLib/OGRInterface#DirectOGRreadaccess
+
+Simple feature API and sequential reading
+-----------------------------------------
+Most GRASS modules are currently using random access to the data which
+reflects GRASS format. This works well with GRASS data but it can
+become very slow or even impossible with OGR data sources because some
+OGR drivers don't support random access or random access is very
+slow. Because conversion from topological format to simple feature is
+very simple and sequential reading of GRASS vectors is not problem it
+would be desirable to implement in GRASS vector library 'simple
+feature' API to GRASS vectors and map it directly to OGR API in case
+of OGR data sources. Then many GRASS modules can be modified to use
+sequentil reading and simple feature API and that will make more
+efficient processing of data directly read from OGR data sources.
+
+
+1.2 Attributes
+--------------
+
+In general I found the use of true RDBMS for attributes as a
+problem. The data are stored in two distinct places (vector files +
+database) and it makes it difficult to keep them consistent and manage
+(move, backup). Another problem is random access to the data in RDBMS
+from an application which is terribly slow (due to communication with
+server). RDBMS is not bad, bad is the combination of files and
+RDBMS. I think that either everything must be stored in RDBMS
+(PostGIS) or nothing. Eric G. Miller (IIRC) was right when he said
+that data are 'too distant' when RDBMS is used with geometry in file.
+
+I think that more work should be done on the drivers which are using
+embedded databases stored in files (SQLite,MySQL,DBF) with scope to
+reach similar functionality (functions, queries) which are in true
+RDBMS without penalty of communication with server. It should be also
+considered the possibility to change the default location of database
+files to vector directory ($MAPSET/vector/test). That means to keep
+all the data of one vector in a single directory. It is already
+possible but it is not the default settings, for example:
+
+ db.connect driver=dbf database='$GISDBASE/$LOCATION_NAME/$MAPSET/vector/$MAP/'
+ db.connect driver=sqlite database='$GISDBASE/$LOCATION_NAME/$MAPSET/vector/$MAP/db.sqlite'
+ db.connect driver=mesql database='$GISDBASE/$LOCATION_NAME/$MAPSET/vector/$MAP/'
+
+Implement insert/update cursors
+-------------------------------
+GRASS modules are currently sending all data to database drivers as
+individual SQL insert/update statements. This makes the update process
+slow (cunstructing and parsing queries) and number precision can be
+lost. The solution is to implement db_open_insert/update_cursor() and
+db_insert/update() in database drivers and use these functions in
+modules. The drivers should then use precompiled statements
+(e.g. SQLite) or they could update the database directly (DBF).
+
+Note that it is not necessary to implement these functions in all
+drivers at the same time. You can implement lib/db/stubs functions
+which will create SQL statement and send it to db_execute() which is
+implemented in all drivers until the functions are properly
+implemented in all drivers.
+
+SQLite driver
+-------------
+Current implementation is very slow with large updates/inserts. I
+think that it is because all statements are parsed and it should be
+possible to improve by insert/update cursors (see above).
+
+DBF driver
+----------
+Add on the fly index for select/update.
+
+Implement db_copy_table() in drivers
+----------------------------------
+db_copy_table() is implement in client library and it always reads and
+writes all the data which is slow. It would be better to send this
+request to the driver (if possible, i.e. input and output driver are
+the same) which can copy tables much faster. For example true RDBMS
+can use 'create table new as select * from old' and DBF driver can
+simply copy files.
+
+Load drivers as dynamic libraries
+---------------------------------
+Database drivers are implemented as executables which communicate with
+modules via pipes. This implementation creates some problems with
+portability (especially on Windows) and it makes communication slow (I
+am not sure how much). It would be probably desirable to implement
+drivers as loadable modules (dlopen() and equivalents).
+
+
+2. Modules
+----------
+
+v.overlay
+---------
+Select only relevant features which will be written to the output if
+'and,not,nor' operators are used. An inspiration is available in
+v.select.
+
+v.pack/v.unpack
+---------------
+Write it. New modules to pack/unpack a vector to/from single file
+(probably tar). I am not sure about format. Originally I was thinking
+about ASCII+DBF as it can be read also without GRASS but ASCII and DBF
+can lose precision and DBF has other limitations. It would be
+probably better to use copy of 'coor' file and attributes written to
+SQLite database.
+
+Update: see
+ https://trac.osgeo.org/grass/browser/grass-addons/grass7/vector/v.pack
+ and
+ https://trac.osgeo.org/grass/browser/grass-addons/grass7/vector/v.unpack
+ by Luca Delucchi
+
+1/2009: Other suggestions moved to
+ https://trac.osgeo.org/grass/
diff --git a/doc/vector/grass51atts.fig b/doc/examples/vector/grass51atts.fig
similarity index 100%
rename from doc/vector/grass51atts.fig
rename to doc/examples/vector/grass51atts.fig
diff --git a/doc/vector/grass51atts.png b/doc/examples/vector/grass51atts.png
similarity index 100%
rename from doc/vector/grass51atts.png
rename to doc/examples/vector/grass51atts.png
diff --git a/doc/vector/grass51concept.fig b/doc/examples/vector/grass51concept.fig
similarity index 100%
rename from doc/vector/grass51concept.fig
rename to doc/examples/vector/grass51concept.fig
diff --git a/doc/vector/grass51concept.png b/doc/examples/vector/grass51concept.png
similarity index 100%
rename from doc/vector/grass51concept.png
rename to doc/examples/vector/grass51concept.png
diff --git a/doc/vector/v.example/Makefile b/doc/examples/vector/v.example/Makefile
similarity index 91%
rename from doc/vector/v.example/Makefile
rename to doc/examples/vector/v.example/Makefile
index 9516d79b855..0197d49271d 100644
--- a/doc/vector/v.example/Makefile
+++ b/doc/examples/vector/v.example/Makefile
@@ -1,6 +1,6 @@
# fix this relative to include/
# or use absolute path to the GRASS source code
-MODULE_TOPDIR = ../../..
+MODULE_TOPDIR = ../../../..
PGM = v.example
diff --git a/doc/vector/v.example/main.c b/doc/examples/vector/v.example/main.c
similarity index 100%
rename from doc/vector/v.example/main.c
rename to doc/examples/vector/v.example/main.c
diff --git a/doc/vector/v.example/v.example.html b/doc/examples/vector/v.example/v.example.html
similarity index 100%
rename from doc/vector/v.example/v.example.html
rename to doc/examples/vector/v.example/v.example.html
diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile
index f8b2dace916..a552a744a8a 100644
--- a/docker/alpine/Dockerfile
+++ b/docker/alpine/Dockerfile
@@ -1,4 +1,4 @@
-FROM alpine:3.21@sha256:21dc6063fd678b478f57c0e13f47560d0ea4eeba26dfc947b2a4f81f686b9f45 as common
+FROM alpine:3.21@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099 as common
# Based on:
# https://github.com/mundialis/docker-grass-gis/blob/master/Dockerfile
diff --git a/flake.lock b/flake.lock
index 84919cd4eff..94f4784f626 100644
--- a/flake.lock
+++ b/flake.lock
@@ -5,11 +5,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
- "lastModified": 1733312601,
- "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
+ "lastModified": 1736143030,
+ "narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=",
"owner": "hercules-ci",
"repo": "flake-parts",
- "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
+ "rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de",
"type": "github"
},
"original": {
@@ -19,11 +19,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1735523292,
- "narHash": "sha256-opBsbR/nrGxiiF6XzlVluiHYb6yN/hEwv+lBWTy9xoM=",
+ "lastModified": 1736693123,
+ "narHash": "sha256-9lIfXCaBPwUA7FnfDnoH4gxxdOvXG78k6UlUw0+ZDxc=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "6d97d419e5a9b36e6293887a89a078cf85f5a61b",
+ "rev": "2fdec2c2e68b7b7845d1ea4e0894c63143e3261b",
"type": "github"
},
"original": {
@@ -35,14 +35,14 @@
},
"nixpkgs-lib": {
"locked": {
- "lastModified": 1733096140,
- "narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=",
+ "lastModified": 1735774519,
+ "narHash": "sha256-CewEm1o2eVAnoqb6Ml+Qi9Gg/EfNAxbRx1lANGVyoLI=",
"type": "tarball",
- "url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
+ "url": "https://github.com/NixOS/nixpkgs/archive/e9b51731911566bbf7e4895475a87fe06961de0b.tar.gz"
},
"original": {
"type": "tarball",
- "url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
+ "url": "https://github.com/NixOS/nixpkgs/archive/e9b51731911566bbf7e4895475a87fe06961de0b.tar.gz"
}
},
"root": {
diff --git a/grasslib.dox b/grasslib.dox
index dd5de826cfe..1dd0bce6a00 100644
--- a/grasslib.dox
+++ b/grasslib.dox
@@ -1,7 +1,7 @@
/*! \mainpage GRASS GIS 8 Programmer's Manual
GRASS GIS (Geographic
@@ -23,7 +23,7 @@ Team, an international team of programmers, GRASS module authors
are cited within their module's source code and the contributed manual
pages.
-© 2000-2024 by the GRASS Development Team
+© 2000-2025 by the GRASS Development Team
This manual is published under GNU Free Documentation
diff --git a/gui/wxpython/core/layerlist.py b/gui/wxpython/core/layerlist.py
index c09ea203326..43b1a4d118d 100644
--- a/gui/wxpython/core/layerlist.py
+++ b/gui/wxpython/core/layerlist.py
@@ -38,8 +38,9 @@ def GetSelectedLayers(self, activeOnly=True):
layers = []
for layer in self._list:
if layer.IsSelected():
- if activeOnly and layer.IsActive():
- layers.append(layer)
+ if activeOnly:
+ if layer.IsActive():
+ layers.append(layer)
else:
layers.append(layer)
return layers
diff --git a/gui/wxpython/history/tree.py b/gui/wxpython/history/tree.py
index 3701fefb001..b5488c23d0e 100644
--- a/gui/wxpython/history/tree.py
+++ b/gui/wxpython/history/tree.py
@@ -216,6 +216,10 @@ def _popupMenuCommand(self):
"""Create popup menu for commands"""
menu = Menu()
+ copyItem = wx.MenuItem(menu, wx.ID_ANY, _("&Copy"))
+ menu.AppendItem(copyItem)
+ self.Bind(wx.EVT_MENU, self.OnCopyCmd, copyItem)
+
item = wx.MenuItem(menu, wx.ID_ANY, _("&Remove"))
menu.AppendItem(item)
self.Bind(wx.EVT_MENU, self.OnRemoveCmd, item)
@@ -658,3 +662,25 @@ def OnDoubleClick(self, node):
self.CollapseNode(node, recursive=False)
else:
self.ExpandNode(node, recursive=False)
+
+ def OnCopyCmd(self, event):
+ """Copy selected cmd to clipboard"""
+ self.DefineItems(self.GetSelected())
+ if not self.selected_command:
+ return
+
+ selected_command = self.selected_command[0]
+ command = selected_command.data["name"]
+
+ # Copy selected command to clipboard
+ try:
+ if wx.TheClipboard.Open():
+ try:
+ wx.TheClipboard.SetData(wx.TextDataObject(command))
+ self.showNotification.emit(
+ message=_("Command <{}> copied to clipboard").format(command)
+ )
+ finally:
+ wx.TheClipboard.Close()
+ except wx.PyWidgetError:
+ self.showNotification.emit(message=_("Failed to copy command to clipboard"))
diff --git a/gui/wxpython/iclass/statistics.py b/gui/wxpython/iclass/statistics.py
index 059ce5e6b03..c1727bc1676 100644
--- a/gui/wxpython/iclass/statistics.py
+++ b/gui/wxpython/iclass/statistics.py
@@ -18,13 +18,28 @@
"""
import os
-from ctypes import *
+import sys
+from ctypes import byref, c_char_p, c_float, c_int
import grass.script as gs
try:
- from grass.lib.imagery import *
-except ImportError as e:
+ from grass.lib.imagery import (
+ I_iclass_statistics_get_cat,
+ I_iclass_statistics_get_color,
+ I_iclass_statistics_get_histo,
+ I_iclass_statistics_get_max,
+ I_iclass_statistics_get_mean,
+ I_iclass_statistics_get_min,
+ I_iclass_statistics_get_name,
+ I_iclass_statistics_get_nbands,
+ I_iclass_statistics_get_ncells,
+ I_iclass_statistics_get_nstd,
+ I_iclass_statistics_get_range_max,
+ I_iclass_statistics_get_range_min,
+ I_iclass_statistics_get_stddev,
+ )
+except ImportError:
sys.stderr.write(_("Loading imagery lib failed"))
from grass.pydispatch.signal import Signal
diff --git a/gui/wxpython/vdigit/dialogs.py b/gui/wxpython/vdigit/dialogs.py
index 27d34601459..369855c94fc 100644
--- a/gui/wxpython/vdigit/dialogs.py
+++ b/gui/wxpython/vdigit/dialogs.py
@@ -252,7 +252,7 @@ def OnEndEdit(self, event):
self.cats[self.fid][layerNew] = []
self.cats[self.fid][layerNew].append(catNew)
self.cats[self.fid][layerOld].remove(catOld)
- except:
+ except (KeyError, ValueError, AttributeError):
event.Veto()
self.list.SetItem(itemIndex, 0, str(layerNew))
self.list.SetItem(itemIndex, 1, str(catNew))
diff --git a/gui/wxpython/vdigit/mapwindow.py b/gui/wxpython/vdigit/mapwindow.py
index d3c8882354a..81421027feb 100644
--- a/gui/wxpython/vdigit/mapwindow.py
+++ b/gui/wxpython/vdigit/mapwindow.py
@@ -290,7 +290,7 @@ def OnLeftDownAddLine(self, event):
"""Left mouse button pressed - add new feature"""
try:
mapLayer = self.toolbar.GetLayer().GetName()
- except:
+ except AttributeError:
return
if self.toolbar.GetAction("type") in {"point", "centroid"}:
@@ -479,7 +479,7 @@ def OnLeftDownDisplayCA(self, event):
"""
try:
mapLayer = self.toolbar.GetLayer().GetName()
- except:
+ except AttributeError:
return
coords = self.Pixel2Cell(self.mouse["begin"])
@@ -621,8 +621,7 @@ def OnLeftDownUndo(self, event):
removed,
],
)
- # self.mouse['begin'] = self.Cell2Pixel(self.polycoords[-1])
- except:
+ except IndexError:
pass
if action == "editLine":
@@ -688,7 +687,7 @@ def _onLeftDown(self, event):
"""Left mouse button donw - vector digitizer various actions"""
try:
self.toolbar.GetLayer().GetName()
- except:
+ except AttributeError:
GMessage(parent=self, message=_("No vector map selected for editing."))
event.Skip()
return
@@ -1092,7 +1091,7 @@ def _onRightUp(self, event):
# -> add new line / boundary
try:
mapName = self.toolbar.GetLayer().GetName()
- except:
+ except AttributeError:
mapName = None
GError(parent=self, message=_("No vector map selected for editing."))
diff --git a/gui/wxpython/vdigit/preferences.py b/gui/wxpython/vdigit/preferences.py
index 949b4e5ccae..6174a4d6680 100644
--- a/gui/wxpython/vdigit/preferences.py
+++ b/gui/wxpython/vdigit/preferences.py
@@ -199,7 +199,7 @@ def _createGeneralPage(self, notebook):
self.snappingUnit.SetSelection(
UserSettings.Get(group="vdigit", key="snapping", subkey="unit")
)
- except:
+ except KeyError:
self.snappingUnit.SetSelection(0)
self.snappingUnit.Bind(wx.EVT_CHOICE, self.OnChangeSnappingUnits)
flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
diff --git a/imagery/i.fft/testsuite/test_i_fft.py b/imagery/i.fft/testsuite/test_i_fft.py
new file mode 100644
index 00000000000..b5c86a3c621
--- /dev/null
+++ b/imagery/i.fft/testsuite/test_i_fft.py
@@ -0,0 +1,216 @@
+import numpy as np
+from grass.script import array
+from grass.gunittest.case import TestCase
+from grass.gunittest.main import test
+
+
+class TestIFFT(TestCase):
+ """Regression tests for the i.fft GRASS GIS module."""
+
+ input_raster = "test_input"
+ real_output = "fft_real"
+ imag_output = "fft_imag"
+
+ @classmethod
+ def setUpClass(cls):
+ """Set up an input raster and configure test environment."""
+ cls.use_temp_region()
+ cls.runModule("g.region", n=10, s=0, e=10, w=0, rows=10, cols=10)
+ cls.runModule(
+ "r.mapcalc", expression=f"{cls.input_raster} = col()", overwrite=True
+ )
+
+ @classmethod
+ def tearDownClass(cls):
+ """Clean up generated data and reset the region."""
+ rasters_to_remove = [
+ cls.input_raster,
+ cls.real_output,
+ cls.imag_output,
+ "reconstructed",
+ "input_2",
+ "combined",
+ "real_1",
+ "imag_1",
+ "real_2",
+ "imag_2",
+ "combined_real",
+ "combined_imag",
+ ]
+ cls.runModule(
+ "g.remove",
+ type="raster",
+ name=",".join(rasters_to_remove),
+ flags="f",
+ quiet=True,
+ )
+ cls.del_temp_region()
+
+ def test_linearity_property(self):
+ """Test linearity of the FFT by combining two rasters."""
+ self.runModule("r.mapcalc", expression="input_2 = row()", overwrite=True)
+ self.runModule(
+ "r.mapcalc", expression="combined = test_input + input_2", overwrite=True
+ )
+
+ self.assertModule(
+ "i.fft",
+ input=self.input_raster,
+ real="real_1",
+ imaginary="imag_1",
+ overwrite=True,
+ )
+ self.assertRasterExists("real_1")
+ self.assertRasterExists("imag_1")
+
+ self.assertModule(
+ "i.fft", input="input_2", real="real_2", imaginary="imag_2", overwrite=True
+ )
+ self.assertRasterExists("real_2")
+ self.assertRasterExists("imag_2")
+
+ self.assertModule(
+ "i.fft",
+ input="combined",
+ real="combined_real",
+ imaginary="combined_imag",
+ overwrite=True,
+ )
+
+ self.assertRasterExists("combined_real")
+ self.assertRasterExists("combined_imag")
+
+ real_combined = array.array("combined_real")
+ imag_combined = array.array("combined_imag")
+ real_sum = array.array("real_1") + array.array("real_2")
+ imag_sum = array.array("imag_1") + array.array("imag_2")
+
+ self.assertTrue(
+ np.allclose(real_combined, real_sum, atol=1e-5),
+ "Linearity failed for real component",
+ )
+ self.assertTrue(
+ np.allclose(imag_combined, imag_sum, atol=1e-5),
+ "Linearity failed for imaginary component",
+ )
+
+ def test_energy_conservation_theorem(self):
+ """Validate energy conservation theorem."""
+ self.assertModule(
+ "i.fft",
+ input=self.input_raster,
+ real=self.real_output,
+ imaginary=self.imag_output,
+ overwrite=True,
+ )
+
+ self.assertRasterExists(self.real_output)
+ self.assertRasterExists(self.imag_output)
+
+ spatial_energy = np.sum(array.array(self.input_raster) ** 2)
+ freq_energy = np.sum(
+ array.array(self.real_output) ** 2 + array.array(self.imag_output) ** 2
+ )
+ self.assertAlmostEqual(
+ spatial_energy, freq_energy, places=5, msg="Energy conservation failed"
+ )
+
+ def test_inverse_fft(self):
+ """Check that inverse FFT reconstructs the original raster."""
+ self.assertModule(
+ "i.fft",
+ input=self.input_raster,
+ real=self.real_output,
+ imaginary=self.imag_output,
+ overwrite=True,
+ )
+
+ self.assertRasterExists(self.real_output)
+ self.assertRasterExists(self.imag_output)
+
+ self.assertModule(
+ "i.ifft",
+ real=self.real_output,
+ imaginary=self.imag_output,
+ output="reconstructed",
+ overwrite=True,
+ )
+
+ original_values = array.array(self.input_raster)
+ reconstructed_values = array.array("reconstructed")
+
+ self.assertTrue(
+ np.allclose(original_values, reconstructed_values, atol=1e-5),
+ "Reconstructed raster does not match the original",
+ )
+
+ def test_all_zero_raster(self):
+ """Test FFT behavior with an all-zero raster."""
+ self.runModule(
+ "r.mapcalc", expression=f"{self.input_raster} = 0", overwrite=True
+ )
+ self.assertModule(
+ "i.fft",
+ input=self.input_raster,
+ real=self.real_output,
+ imaginary=self.imag_output,
+ overwrite=True,
+ )
+ self.assertRasterExists(self.real_output)
+ self.assertRasterExists(self.imag_output)
+
+ real_values = array.array(self.real_output)
+ imag_values = array.array(self.imag_output)
+ self.assertTrue(
+ np.allclose(real_values, 0), "Real component should be all zeros"
+ )
+ self.assertTrue(
+ np.allclose(imag_values, 0), "Imaginary component should be all zeros"
+ )
+
+ def test_all_one_raster(self):
+ """Test FFT behavior with an all-one raster."""
+ self.runModule(
+ "r.mapcalc", expression=f"{self.input_raster} = 1", overwrite=True
+ )
+ self.assertModule(
+ "i.fft",
+ input=self.input_raster,
+ real=self.real_output,
+ imaginary=self.imag_output,
+ overwrite=True,
+ )
+ self.assertRasterExists(self.real_output)
+ self.assertRasterExists(self.imag_output)
+
+ real_values = array.array(self.real_output)
+ imag_values = array.array(self.imag_output)
+ self.assertTrue(
+ np.all(np.isfinite(real_values)), "Real component should have valid values"
+ )
+ self.assertTrue(
+ np.all(np.isfinite(imag_values)),
+ "Imaginary component should have valid values",
+ )
+
+ def test_large_raster_performance(self):
+ """Assess performance with a larger raster."""
+ self.runModule("g.region", n=90, s=-90, e=180, w=-180, rows=1000, cols=1000)
+ self.runModule(
+ "r.mapcalc", expression=f"{self.input_raster} = col()", overwrite=True
+ )
+
+ self.assertModule(
+ "i.fft",
+ input=self.input_raster,
+ real=self.real_output,
+ imaginary=self.imag_output,
+ overwrite=True,
+ )
+
+ self.assertRasterExists(self.real_output)
+ self.assertRasterExists(self.imag_output)
+
+
+if __name__ == "__main__":
+ test()
diff --git a/include/VERSION b/include/VERSION
index c4ace75dbf6..97aca63225c 100644
--- a/include/VERSION
+++ b/include/VERSION
@@ -1,4 +1,4 @@
8
5
0dev
-2024
+2025
diff --git a/include/grass/gis.h b/include/grass/gis.h
index fcc53535f47..e6b818135e4 100644
--- a/include/grass/gis.h
+++ b/include/grass/gis.h
@@ -6,7 +6,7 @@
* PURPOSE: This file contains definitions of variables and data types
* for use with most, if not all, Grass programs. This file is
* usually included in every Grass program.
- * COPYRIGHT: (C) 2000-2024 by the GRASS Development Team
+ * COPYRIGHT: (C) 2000-2025 by the GRASS Development Team
*
* This program is free software under the GNU General Public
* License (>=v2). Read the file COPYING that comes with GRASS
diff --git a/lib/Makefile b/lib/Makefile
index 91c38f5c73b..96a23af2069 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -31,6 +31,7 @@ SUBDIRS = \
lidar \
raster3d \
raster3d/test \
+ external/parson/test \
gpde \
dspf \
symbol \
diff --git a/lib/external/parson/Makefile b/lib/external/parson/Makefile
index 43aca3bc351..fa6cda3efa1 100644
--- a/lib/external/parson/Makefile
+++ b/lib/external/parson/Makefile
@@ -7,7 +7,7 @@ include $(MODULE_TOPDIR)/include/Make/Lib.make
default: headers
$(MAKE) lib
-headers: $(ARCH_INCDIR)/parson.h
+headers: $(ARCH_INCDIR)/parson.h $(ARCH_INCDIR)/gjson.h
$(ARCH_INCDIR)/%.h: %.h
$(INSTALL_DATA) $< $@
diff --git a/lib/external/parson/gjson.c b/lib/external/parson/gjson.c
new file mode 100644
index 00000000000..54740fa6df8
--- /dev/null
+++ b/lib/external/parson/gjson.c
@@ -0,0 +1,155 @@
+/*****************************************************************************
+ *
+ * MODULE: GRASS json output interface
+ *
+ * AUTHOR: Nishant Bansal (nishant.bansal.282003@gmail.com)
+ *
+ * PURPOSE: parson library function wrapper
+ * part of the gjson library
+ *
+ * COPYRIGHT: (C) 2024 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ *****************************************************************************/
+
+#include "gjson.h"
+
+/* *************************************************************** */
+/* ***** WRAPPER FOR PARSON FUNCTIONS USED IN GRASS ************** */
+/* *************************************************************** */
+
+JSON_Value *G_json_value_init_object(void)
+{
+ return json_value_init_object();
+}
+
+JSON_Value *G_json_value_init_array(void)
+{
+ return json_value_init_array();
+}
+
+JSON_Object *G_json_value_get_object(const JSON_Value *value)
+{
+ return json_value_get_object(value);
+}
+
+JSON_Object *G_json_object(const JSON_Value *value)
+{
+ return json_object(value);
+}
+JSON_Object *G_json_object_get_object(const JSON_Object *object,
+ const char *name)
+{
+ return json_object_get_object(object, name);
+}
+JSON_Array *G_json_object_get_array(const JSON_Object *object, const char *name)
+{
+ return json_object_get_array(object, name);
+}
+JSON_Value *G_json_object_get_value(const JSON_Object *object, const char *name)
+{
+ return json_object_get_value(object, name);
+}
+const char *G_json_object_get_string(const JSON_Object *object,
+ const char *name)
+{
+ return json_object_get_string(object, name);
+}
+double G_json_object_get_number(const JSON_Object *object, const char *name)
+{
+ return json_object_get_number(object, name);
+}
+int G_json_object_get_boolean(const JSON_Object *object, const char *name)
+{
+ return json_object_get_boolean(object, name);
+}
+JSON_Value *G_json_object_get_wrapping_value(const JSON_Object *object)
+{
+ return json_object_get_wrapping_value(object);
+}
+JSON_Status G_json_object_set_value(JSON_Object *object, const char *name,
+ JSON_Value *value)
+{
+ return json_object_set_value(object, name, value);
+}
+JSON_Status G_json_object_set_string(JSON_Object *object, const char *name,
+ const char *string)
+{
+ return json_object_set_string(object, name, string);
+}
+JSON_Status G_json_object_set_number(JSON_Object *object, const char *name,
+ double number)
+{
+ return json_object_set_number(object, name, number);
+}
+JSON_Status G_json_object_set_boolean(JSON_Object *object, const char *name,
+ int boolean)
+{
+ return json_object_set_boolean(object, name, boolean);
+}
+JSON_Status G_json_object_set_null(JSON_Object *object, const char *name)
+{
+ return json_object_set_null(object, name);
+}
+JSON_Array *G_json_array(const JSON_Value *value)
+{
+ return json_array(value);
+}
+JSON_Value *G_json_array_get_value(const JSON_Array *array, size_t index)
+{
+ return json_array_get_value(array, index);
+}
+const char *G_json_array_get_string(const JSON_Array *array, size_t index)
+{
+ return json_array_get_string(array, index);
+}
+double G_json_array_get_number(const JSON_Array *array, size_t index)
+{
+ return json_array_get_number(array, index);
+}
+int G_json_array_get_boolean(const JSON_Array *array, size_t index)
+{
+ return json_array_get_boolean(array, index);
+}
+
+JSON_Status G_json_array_append_value(JSON_Array *array, JSON_Value *value)
+{
+ return json_array_append_value(array, value);
+}
+
+JSON_Status G_json_array_append_string(JSON_Array *array, const char *string)
+{
+ return json_array_append_string(array, string);
+}
+
+JSON_Status G_json_array_append_number(JSON_Array *array, double number)
+{
+ return json_array_append_number(array, number);
+}
+
+JSON_Status G_json_array_append_boolean(JSON_Array *array, int boolean)
+{
+ return json_array_append_boolean(array, boolean);
+}
+
+JSON_Status G_json_array_append_null(JSON_Array *array)
+{
+ return json_array_append_null(array);
+}
+
+char *G_json_serialize_to_string_pretty(const JSON_Value *value)
+{
+ return json_serialize_to_string_pretty(value);
+}
+
+void G_json_free_serialized_string(char *string)
+{
+ json_free_serialized_string(string);
+}
+void G_json_value_free(JSON_Value *value)
+{
+ json_value_free(value);
+}
diff --git a/lib/external/parson/gjson.h b/lib/external/parson/gjson.h
new file mode 100644
index 00000000000..0e9cb345123
--- /dev/null
+++ b/lib/external/parson/gjson.h
@@ -0,0 +1,48 @@
+#ifndef GRASS_GJSON_H
+#define GRASS_GJSON_H
+
+#include "parson.h"
+
+/* *************************************************************** */
+/* ***** WRAPPER FOR PARSON FUNCTIONS USED IN GRASS ************** */
+/* *************************************************************** */
+
+extern JSON_Value *G_json_value_init_object(void);
+extern JSON_Value *G_json_value_init_array(void);
+
+extern JSON_Object *G_json_value_get_object(const JSON_Value *);
+extern JSON_Object *G_json_object(const JSON_Value *);
+extern JSON_Object *G_json_object_get_object(const JSON_Object *, const char *);
+extern JSON_Array *G_json_object_get_array(const JSON_Object *, const char *);
+extern JSON_Value *G_json_object_get_value(const JSON_Object *, const char *);
+extern const char *G_json_object_get_string(const JSON_Object *, const char *);
+extern double G_json_object_get_number(const JSON_Object *, const char *);
+extern int G_json_object_get_boolean(const JSON_Object *, const char *);
+extern JSON_Value *G_json_object_get_wrapping_value(const JSON_Object *);
+
+extern JSON_Status G_json_object_set_value(JSON_Object *, const char *,
+ JSON_Value *);
+extern JSON_Status G_json_object_set_string(JSON_Object *, const char *,
+ const char *);
+extern JSON_Status G_json_object_set_number(JSON_Object *, const char *,
+ double);
+extern JSON_Status G_json_object_set_boolean(JSON_Object *, const char *, int);
+extern JSON_Status G_json_object_set_null(JSON_Object *, const char *);
+
+extern JSON_Array *G_json_array(const JSON_Value *);
+extern JSON_Value *G_json_array_get_value(const JSON_Array *, size_t);
+extern const char *G_json_array_get_string(const JSON_Array *, size_t);
+extern double G_json_array_get_number(const JSON_Array *, size_t);
+extern int G_json_array_get_boolean(const JSON_Array *, size_t);
+
+extern JSON_Status G_json_array_append_value(JSON_Array *, JSON_Value *);
+extern JSON_Status G_json_array_append_string(JSON_Array *, const char *);
+extern JSON_Status G_json_array_append_number(JSON_Array *, double);
+extern JSON_Status G_json_array_append_boolean(JSON_Array *, int);
+extern JSON_Status G_json_array_append_null(JSON_Array *);
+
+extern char *G_json_serialize_to_string_pretty(const JSON_Value *);
+extern void G_json_free_serialized_string(char *);
+extern void G_json_value_free(JSON_Value *);
+
+#endif /* GRASS_GJSON_H */
diff --git a/lib/external/parson/test/Makefile b/lib/external/parson/test/Makefile
new file mode 100644
index 00000000000..893b3e59bc3
--- /dev/null
+++ b/lib/external/parson/test/Makefile
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../../../..
+
+PGM=test.gjson.lib
+
+LIBES = $(PARSONLIB) $(GISLIB)
+DEPENDENCIES = $(PARSONDEP) $(GISDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
diff --git a/lib/external/parson/test/test.gjson.lib.html b/lib/external/parson/test/test.gjson.lib.html
new file mode 100644
index 00000000000..1d399f9eafa
--- /dev/null
+++ b/lib/external/parson/test/test.gjson.lib.html
@@ -0,0 +1,9 @@
+DESCRIPTION
+
+test.gjson.lib
+is a module dedicated for testing the gjson library.
+This module is used by the testing framework to perform library tests.
+
+AUTHOR
+
+Nishant Bansal
diff --git a/lib/external/parson/test/test_gjson_lib.h b/lib/external/parson/test/test_gjson_lib.h
new file mode 100644
index 00000000000..0cf9bde0ee6
--- /dev/null
+++ b/lib/external/parson/test/test_gjson_lib.h
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ *
+ * MODULE: GRASS gjson Library
+ *
+ * AUTHOR: Nishant Bansal (nishant.bansal.282003@gmail.com)
+ *
+ * PURPOSE: Unit tests
+ *
+ * COPYRIGHT: (C) 2024 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ *****************************************************************************/
+
+#ifndef _TEST_GJSON_LIB_H_
+#define _TEST_GJSON_LIB_H_
+
+#include
+
+#define TEST_OBJECT_KEY "key"
+#define TEST_OBJECT_VALUE "value"
+#define TEST_ARRAY_STRING "array"
+#define TEST_NUMBER 123.45
+#define TEST_BOOLEAN 1
+
+/* parson wrapper tests */
+int unit_test_parson_wrapper(void);
+
+#endif
diff --git a/lib/external/parson/test/test_main.c b/lib/external/parson/test/test_main.c
new file mode 100644
index 00000000000..2a2a28b7169
--- /dev/null
+++ b/lib/external/parson/test/test_main.c
@@ -0,0 +1,78 @@
+/****************************************************************************
+ *
+ * MODULE: test.gjson.lib
+ *
+ * AUTHOR: Nishant Bansal (nishant.bansal.282003@gmail.com)
+ *
+ * PURPOSE: Unit tests for the gjson library
+ *
+ * COPYRIGHT: (C) 2024 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with
+ * GRASS for details.
+ *
+ *****************************************************************************/
+
+#include
+#include
+#include
+#include
+#include "test_gjson_lib.h"
+
+/*- Parameters and global variables -----------------------------------------*/
+typedef struct {
+ struct Flag *testunit;
+} paramType;
+
+paramType param; /*Parameters */
+
+/*- prototypes --------------------------------------------------------------*/
+static void set_params(void); /*Fill the paramType structure */
+
+/* ************************************************************************* */
+/* Set up the arguments we are expecting ********************************** */
+
+/* ************************************************************************* */
+void set_params(void)
+{
+ param.testunit = G_define_flag();
+ param.testunit->key = 'u';
+ param.testunit->description = "Run all unit tests";
+}
+/* ************************************************************************* */
+/* ************************************************************************* */
+
+/* ************************************************************************* */
+int main(int argc, char *argv[])
+{
+ struct GModule *module;
+ int returnstat = 0;
+
+ /* Initialize GRASS */
+ G_gisinit(argv[0]);
+
+ module = G_define_module();
+ G_add_keyword(_("gjson"));
+ G_add_keyword(_("unit test"));
+ module->description = _("Performs unit tests "
+ "for the gjson library");
+
+ /* Get parameters from user */
+ set_params();
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ /*Run the unit tests */
+ if (param.testunit->answer) {
+ returnstat += unit_test_parson_wrapper();
+ }
+
+ if (returnstat != 0)
+ G_warning("Errors detected while testing the gjson lib");
+ else
+ G_message("\n-- gjson lib tests finished successfully --");
+
+ return (returnstat);
+}
diff --git a/lib/external/parson/test/test_parson_wrapper.c b/lib/external/parson/test/test_parson_wrapper.c
new file mode 100644
index 00000000000..ed4a229d7cc
--- /dev/null
+++ b/lib/external/parson/test/test_parson_wrapper.c
@@ -0,0 +1,265 @@
+/*****************************************************************************
+ *
+ * MODULE: GRASS Parson Output Library
+ *
+ * AUTHOR: Nishant Bansal (nishant.bansal.282003@gmail.com)
+ *
+ * PURPOSE: Unit tests for parson wrapper
+ *
+ * COPYRIGHT: (C) 2024 by the GRASS Development Team
+ *
+ * This program is free software under the GNU General Public
+ * License (>=v2). Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ *****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include "test_gjson_lib.h"
+
+static int test_parson_wrapper(void);
+
+/* ************************************************************************* */
+/* Perform the JSON function unit tests *************************** */
+/* ************************************************************************* */
+int unit_test_parson_wrapper(void)
+{
+ int sum = 0;
+
+ G_message(_("\n++ Running gjson wrapper unit tests ++"));
+
+ sum += test_parson_wrapper();
+
+ if (sum > 0)
+ G_warning(_("\n-- gjson wrapper unit tests failure --"));
+ else
+ G_message(_("\n-- gjson wrapper unit tests finished successfully --"));
+
+ return sum;
+}
+
+/* *************************************************************** */
+/* Test all implemented parson wrapper **************** */
+/* *************************************************************** */
+int test_parson_wrapper(void)
+{
+ int sum = 0;
+ JSON_Value *value = NULL;
+ JSON_Object *object = NULL;
+ JSON_Array *array = NULL;
+ char *serialized_string;
+
+ G_message("\t * testing JSON object initialization\n");
+ value = G_json_value_init_object();
+ if (value == NULL) {
+ G_warning("Error in G_json_value_init_object");
+ sum++;
+ }
+ else {
+ G_json_value_free(value);
+ }
+
+ G_message("\t * testing JSON array initialization\n");
+ value = G_json_value_init_array();
+ if (value == NULL) {
+ G_warning("Error in G_json_value_init_array");
+ sum++;
+ }
+ else {
+ G_json_value_free(value);
+ }
+
+ G_message("\t * testing JSON object set and get string\n");
+ value = G_json_value_init_object();
+ object = G_json_value_get_object(value);
+ if (object == NULL) {
+ G_warning("Error in G_json_value_get_object");
+ sum++;
+ }
+ if (G_json_object_set_string(object, TEST_OBJECT_KEY, TEST_OBJECT_VALUE) !=
+ JSONSuccess) {
+ G_warning("Error in G_json_object_set_string");
+ sum++;
+ }
+ const char *retrieved = G_json_object_get_string(object, TEST_OBJECT_KEY);
+ if (strcmp(retrieved, TEST_OBJECT_VALUE) != 0) {
+ G_warning("Error in G_json_object_get_string %s != %s",
+ TEST_OBJECT_VALUE, retrieved);
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON object get wrapping value");
+ value = G_json_value_init_object();
+ object = G_json_value_get_object(value);
+ if (G_json_object_get_wrapping_value(object) != value) {
+ G_warning("Error in G_json_object_get_wrapping_value");
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON object set null\n");
+ value = G_json_value_init_object();
+ object = G_json_value_get_object(value);
+ if (G_json_object_set_null(object, TEST_OBJECT_KEY) != JSONSuccess) {
+ G_warning("Error in G_json_object_set_null");
+ sum++;
+ }
+ if (json_value_get_type(G_json_object_get_value(object, TEST_OBJECT_KEY)) !=
+ JSONNull) {
+ G_warning("Error: G_json_object_set_null failed, the value type is not "
+ "null.");
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON object set and get array\n");
+ value = G_json_value_init_object();
+ object = G_json_value_get_object(value);
+ if (G_json_object_set_value(object, TEST_OBJECT_KEY,
+ G_json_value_init_array()) != JSONSuccess) {
+ G_warning("Error in G_json_object_set_value for array");
+ sum++;
+ }
+ array = G_json_object_get_array(object, TEST_OBJECT_KEY);
+ if (!array) {
+ G_warning("Error in G_json_object_get_array");
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON object get object\n");
+ value = G_json_value_init_object();
+ object = G_json_value_get_object(value);
+ if (G_json_object_set_value(object, TEST_OBJECT_KEY,
+ G_json_value_init_object()) != JSONSuccess) {
+ G_warning("Error in G_json_object_set_value for nested object");
+ sum++;
+ }
+ JSON_Object *nested_object =
+ G_json_object_get_object(object, TEST_OBJECT_KEY);
+ if (!nested_object) {
+ G_warning("Error in G_json_object_get_object");
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON array append value\n");
+ value = G_json_value_init_array();
+ array = G_json_array(value);
+ if (G_json_array_append_value(array, G_json_value_init_object()) !=
+ JSONSuccess) {
+ G_warning("Error in G_json_array_append_value");
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON array append number\n");
+ value = G_json_value_init_array();
+ array = G_json_array(value);
+ if (G_json_array_append_number(array, TEST_NUMBER) != JSONSuccess) {
+ G_warning("Error in G_json_array_append_number");
+ sum++;
+ }
+ if (G_json_array_get_number(array, 0) != TEST_NUMBER) {
+ G_warning("Error in G_json_array_append_number %f != %f", TEST_NUMBER,
+ G_json_array_get_number(array, 0));
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON array append boolean\n");
+ value = G_json_value_init_array();
+ array = G_json_array(value);
+ if (G_json_array_append_boolean(array, TEST_BOOLEAN) != JSONSuccess) {
+ G_warning("Error in G_json_array_append_boolean");
+ sum++;
+ }
+ if (G_json_array_get_boolean(array, 0) != TEST_BOOLEAN) {
+ G_warning("Error in G_json_array_append_boolean %i != %i", TEST_BOOLEAN,
+ G_json_array_get_boolean(array, 0));
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON array append null\n");
+ value = G_json_value_init_array();
+ array = G_json_array(value);
+ if (G_json_array_append_null(array) != JSONSuccess) {
+ G_warning("Error in G_json_array_append_null");
+ sum++;
+ }
+ if (json_value_get_type(G_json_array_get_value(array, 0)) != JSONNull) {
+ G_warning("Error in G_json_array_append_null, the value type is not "
+ "null.");
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON array append string\n");
+ value = G_json_value_init_array();
+ array = G_json_array(value);
+ if (G_json_array_append_string(array, TEST_ARRAY_STRING) != JSONSuccess) {
+ G_warning("Error in G_json_array_append_string");
+ sum++;
+ }
+ if (strcmp(G_json_array_get_string(array, 0), TEST_ARRAY_STRING) != 0) {
+ G_warning("Error in G_json_array_append_string %s != %s",
+ TEST_ARRAY_STRING, G_json_array_get_string(array, 0));
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON object set and get number\n");
+ value = G_json_value_init_object();
+ object = G_json_value_get_object(value);
+ if (G_json_object_set_number(object, TEST_OBJECT_KEY, TEST_NUMBER) !=
+ JSONSuccess) {
+ G_warning("Error in G_json_object_set_number");
+ sum++;
+ }
+ double number = G_json_object_get_number(object, TEST_OBJECT_KEY);
+ if (number != TEST_NUMBER) {
+ G_warning("Error in G_json_object_get_number %f != %f", TEST_NUMBER,
+ number);
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON object set and get boolean\n");
+ value = G_json_value_init_object();
+ object = G_json_value_get_object(value);
+ if (G_json_object_set_boolean(object, TEST_OBJECT_KEY, TEST_BOOLEAN) !=
+ JSONSuccess) {
+ G_warning("Error in G_json_object_set_boolean");
+ sum++;
+ }
+ int boolean_value = G_json_object_get_boolean(object, TEST_OBJECT_KEY);
+ if (boolean_value != TEST_BOOLEAN) {
+ G_warning("Error in G_json_object_get_boolean %i != %i", TEST_BOOLEAN,
+ boolean_value);
+ sum++;
+ }
+ G_json_value_free(value);
+
+ G_message("\t * testing JSON serialization\n");
+ value = G_json_value_init_object();
+ object = G_json_value_get_object(value);
+ G_json_object_set_string(object, TEST_OBJECT_KEY, TEST_OBJECT_VALUE);
+ serialized_string = G_json_serialize_to_string_pretty(value);
+ if (!serialized_string ||
+ strstr(serialized_string, TEST_OBJECT_VALUE) == NULL) {
+ G_warning("Error in G_json_serialize_to_string_pretty");
+ sum++;
+ }
+ G_json_free_serialized_string(serialized_string);
+ G_json_value_free(value);
+
+ return sum;
+}
diff --git a/lib/external/parson/testsuite/gjson_lib_test.py b/lib/external/parson/testsuite/gjson_lib_test.py
new file mode 100644
index 00000000000..b0352c406d7
--- /dev/null
+++ b/lib/external/parson/testsuite/gjson_lib_test.py
@@ -0,0 +1,18 @@
+"""Test of gjson library
+
+@author Nishant Bansal
+"""
+
+from grass.gunittest.case import TestCase
+
+
+class GjsonLibraryTest(TestCase):
+
+ def test_wrapper(self):
+ self.assertModule("test.gjson.lib", flags="u")
+
+
+if __name__ == "__main__":
+ from grass.gunittest.main import test
+
+ test()
diff --git a/lib/gis/env.c b/lib/gis/env.c
index e35da07b999..fdb52b5d592 100644
--- a/lib/gis/env.c
+++ b/lib/gis/env.c
@@ -3,7 +3,7 @@
\brief GIS library - environment routines
- (C) 2001-2024 by the GRASS Development Team
+ (C) 2001-2025 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
diff --git a/lib/gis/gislib_cmdline_parsing.dox b/lib/gis/gislib_cmdline_parsing.dox
index 2c21811ea03..60be9c3a392 100644
--- a/lib/gis/gislib_cmdline_parsing.dox
+++ b/lib/gis/gislib_cmdline_parsing.dox
@@ -4,7 +4,7 @@
diff --git a/lib/gis/parser_html.c b/lib/gis/parser_html.c
index 581eaab2625..313b1e00748 100644
--- a/lib/gis/parser_html.c
+++ b/lib/gis/parser_html.c
@@ -3,7 +3,7 @@
\brief GIS Library - Argument parsing functions (HTML output)
- (C) 2001-2024 by the GRASS Development Team
+ (C) 2001-2025 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
diff --git a/lib/init/grass.py b/lib/init/grass.py
index 5a2102ed3ec..c2ac803e6a2 100755
--- a/lib/init/grass.py
+++ b/lib/init/grass.py
@@ -18,7 +18,7 @@
# command line options for setting the GISDBASE, LOCATION,
# and/or MAPSET. Finally it starts GRASS with the appropriate
# user interface and cleans up after it is finished.
-# COPYRIGHT: (C) 2000-2024 by the GRASS Development Team
+# COPYRIGHT: (C) 2000-2025 by the GRASS Development Team
#
# This program is free software under the GNU General
# Public License (>=v2). Read the file COPYING that
diff --git a/lib/init/grass.sh b/lib/init/grass.sh
index 2a83e7448c3..33630b14362 100755
--- a/lib/init/grass.sh
+++ b/lib/init/grass.sh
@@ -13,7 +13,7 @@
# setting the GISDBASE, LOCATION, and/or MAPSET.
# Finally it starts GRASS with the appropriate user
# interface and cleans up after it is finished.
-# COPYRIGHT: (C) 2000-2024 by the GRASS Development Team
+# COPYRIGHT: (C) 2000-2025 by the GRASS Development Team
#
# This program is free software under the GNU General
# Public License (>=v2). Read the file COPYING that
diff --git a/locale/po/grassmods_ar.po b/locale/po/grassmods_ar.po
index 87ec29f267c..412f7783428 100644
--- a/locale/po/grassmods_ar.po
+++ b/locale/po/grassmods_ar.po
@@ -261,7 +261,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -553,20 +553,20 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
#, fuzzy
msgid "My first raster module"
msgstr "اسم الخريطة الراسترية الموجودة"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -620,7 +620,7 @@ msgstr "اسم الخريطة الراسترية الموجودة"
msgid "Raster map <%s> not found"
msgstr "غير موجودة <%s> الخريطة الراسترية "
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -805,12 +805,12 @@ msgstr "غير موجودة <%s> الخريطة الراسترية "
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
#, fuzzy
msgid "My first vector module"
msgstr "اسم الخريطة الراسترية الموجودة"
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -832,13 +832,13 @@ msgstr "اسم الخريطة الراسترية الموجودة"
msgid "Vector map <%s> not found"
msgstr "لم توجد<%s>الخريطة الفيكتورية"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
#, fuzzy
msgid "Unable to set predetermined vector open level"
msgstr "اسم خريطة النقط الفيكتورية المخرجة"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -910,7 +910,7 @@ msgstr "اسم خريطة النقط الفيكتورية المخرجة"
msgid "Unable to open vector map <%s>"
msgstr "[%s]لم يتم فتح ملف الخلية ل "
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -965,7 +965,7 @@ msgstr "[%s]لم يتم فتح ملف الخلية ل "
msgid "Unable to create vector map <%s>"
msgstr "اسم الخريطة الراسترية الناتجة"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -981,7 +981,7 @@ msgstr "اسم الخريطة الراسترية الناتجة"
msgid "Database connection not defined for layer %d"
msgstr "لم يتم الإتصال بقاعدة البيانات\n"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -995,7 +995,7 @@ msgstr "لم يتم الإتصال بقاعدة البيانات\n"
msgid "Unable to start driver <%s>"
msgstr "'%s'لم يمكن بدء المشغل"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1046,7 +1046,7 @@ msgstr "'%s'لم يمكن بدء المشغل"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "%s بالمشغل %s لم يمكن فتح قاعدة البيانات"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1061,17 +1061,17 @@ msgstr "%s بالمشغل %s لم يمكن فتح قاعدة البيانات"
msgid "Unable to describe table <%s>"
msgstr "لم يمكن وصف الجدول"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, fuzzy, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "لم يمكن اختيار البيانات من الجدول"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, fuzzy, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "cat = %d لا يوجد تسجيل للخط"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, fuzzy, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "[%s]لم يتم فتح ملف الخلية ل "
diff --git a/locale/po/grassmods_bn.po b/locale/po/grassmods_bn.po
index 53b06dd272f..9e4c7bb8280 100644
--- a/locale/po/grassmods_bn.po
+++ b/locale/po/grassmods_bn.po
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_cs.po b/locale/po/grassmods_cs.po
index d48ba2bd1e1..8968a2270cf 100644
--- a/locale/po/grassmods_cs.po
+++ b/locale/po/grassmods_cs.po
@@ -264,7 +264,7 @@ msgstr ""
"ovladač: %s\n"
"databáze: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -556,19 +556,19 @@ msgstr ""
msgid "raster"
msgstr "rastr"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "Můj první modul pro zpracování rastrových dat"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -622,7 +622,7 @@ msgstr "Můj první modul pro zpracování rastrových dat"
msgid "Raster map <%s> not found"
msgstr "Rastrová mapa <%s> nenalezena"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -807,11 +807,11 @@ msgstr "Rastrová mapa <%s> nenalezena"
msgid "vector"
msgstr "vektor"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "Můj první modul pro zpracování vektorových dat"
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -833,12 +833,12 @@ msgstr "Můj první modul pro zpracování vektorových dat"
msgid "Vector map <%s> not found"
msgstr "Vektorová mapa <%s> nebyla nalezena"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr "Nelze nastavit předvybranou vektorovou mapu na úrovni otevření"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -910,7 +910,7 @@ msgstr "Nelze nastavit předvybranou vektorovou mapu na úrovni otevření"
msgid "Unable to open vector map <%s>"
msgstr "Nelze otevřít vektorovou mapu <%s>"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -965,7 +965,7 @@ msgstr "Nelze otevřít vektorovou mapu <%s>"
msgid "Unable to create vector map <%s>"
msgstr "Nelze vytvořit vektorovou mapu <%s>"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -981,7 +981,7 @@ msgstr "Nelze vytvořit vektorovou mapu <%s>"
msgid "Database connection not defined for layer %d"
msgstr "Spojení s databází nebylo definováno pro vrstvu %d "
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -995,7 +995,7 @@ msgstr "Spojení s databází nebylo definováno pro vrstvu %d "
msgid "Unable to start driver <%s>"
msgstr "Nelze spustit ovladač <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1046,7 +1046,7 @@ msgstr "Nelze spustit ovladač <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Nelze otevřít databázi <%s> ovladačem <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1061,17 +1061,17 @@ msgstr "Nelze otevřít databázi <%s> ovladačem <%s>"
msgid "Unable to describe table <%s>"
msgstr "Nelze popsat tabulku <%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Nelze získat atributová data pro cat= %d"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "Chyba během získání záznamu databáze pro kategorii %d"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "Nelze kopírovat atributovou tabulku do vektorové mapy <%s>"
diff --git a/locale/po/grassmods_de.po b/locale/po/grassmods_de.po
index 206bd448858..48ffaefbcb6 100644
--- a/locale/po/grassmods_de.po
+++ b/locale/po/grassmods_de.po
@@ -259,7 +259,7 @@ msgstr ""
"Treiber: %s\n"
"Datenbank: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -551,19 +551,19 @@ msgstr ""
msgid "raster"
msgstr "Raster"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr "Schlagwort2"
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr "Schlagwort3"
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "Mein erstes Rastermodul."
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -617,7 +617,7 @@ msgstr "Mein erstes Rastermodul."
msgid "Raster map <%s> not found"
msgstr "Rasterkarte <%s> konnte nicht gefunden werden."
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -802,11 +802,11 @@ msgstr "Rasterkarte <%s> konnte nicht gefunden werden."
msgid "vector"
msgstr "Vektor"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "Mein erstes Vektormodul."
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -828,12 +828,12 @@ msgstr "Mein erstes Vektormodul."
msgid "Vector map <%s> not found"
msgstr "Vektorkarte <%s> nicht gefunden."
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr "Kann das vorherbestimmte Vektoröffnungslevel nicht setzen."
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -905,7 +905,7 @@ msgstr "Kann das vorherbestimmte Vektoröffnungslevel nicht setzen."
msgid "Unable to open vector map <%s>"
msgstr "Kann die Vektorkarte <%s> nicht öffnen."
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -960,7 +960,7 @@ msgstr "Kann die Vektorkarte <%s> nicht öffnen."
msgid "Unable to create vector map <%s>"
msgstr "Kann die Vektorkarte <%s> nicht erzeugen."
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -976,7 +976,7 @@ msgstr "Kann die Vektorkarte <%s> nicht erzeugen."
msgid "Database connection not defined for layer %d"
msgstr "Die Datenbankverbindung für den Layer<%d> ist nicht definiert."
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -990,7 +990,7 @@ msgstr "Die Datenbankverbindung für den Layer<%d> ist nicht definiert."
msgid "Unable to start driver <%s>"
msgstr "Kann den Treiber <%s> nicht starten."
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1041,7 +1041,7 @@ msgstr "Kann den Treiber <%s> nicht starten."
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Kann Datenbank <%s> nicht mit dem Treiber <%s> öffnen."
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1056,17 +1056,17 @@ msgstr "Kann Datenbank <%s> nicht mit dem Treiber <%s> öffnen."
msgid "Unable to describe table <%s>"
msgstr "Kann Tabelle <%s> nicht beschreiben."
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Kann die Attribute für cat %d nicht bekommen."
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "Fehler beim Abfragen des Datenbankeintrags für cat %d"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "Kann die Attributtabelle nicht in die Vektorkarte <%s> kopieren."
diff --git a/locale/po/grassmods_el.po b/locale/po/grassmods_el.po
index c285d2d7d10..45b4e6e66e5 100644
--- a/locale/po/grassmods_el.po
+++ b/locale/po/grassmods_el.po
@@ -258,7 +258,7 @@ msgstr ""
"driver: %s\n"
"database: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -550,19 +550,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -616,7 +616,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr "Ο χάρτης raster <%s> δεν βρέθηκε."
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -801,11 +801,11 @@ msgstr "Ο χάρτης raster <%s> δεν βρέθηκε."
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -827,12 +827,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -904,7 +904,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -959,7 +959,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -975,7 +975,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -989,7 +989,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr "Αδυναμία εκκίνησης του οδηγού <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1040,7 +1040,7 @@ msgstr "Αδυναμία εκκίνησης του οδηγού <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1055,17 +1055,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr "Αδυναμία περιγραφής πίνακα <%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_es.po b/locale/po/grassmods_es.po
index 837ca2af9a2..dcd927332fa 100644
--- a/locale/po/grassmods_es.po
+++ b/locale/po/grassmods_es.po
@@ -271,7 +271,7 @@ msgstr ""
"driver: %s\n"
"base de datos: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -563,19 +563,19 @@ msgstr ""
msgid "raster"
msgstr "ráster"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr "palabra clave 2 "
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr "palabra clave 3"
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "Mi primer módulo ráster"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -629,7 +629,7 @@ msgstr "Mi primer módulo ráster"
msgid "Raster map <%s> not found"
msgstr "Mapa ráster <%s> no encontrado"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -814,11 +814,11 @@ msgstr "Mapa ráster <%s> no encontrado"
msgid "vector"
msgstr "vectorial"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "Mi primer módulo vectorial"
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -840,13 +840,13 @@ msgstr "Mi primer módulo vectorial"
msgid "Vector map <%s> not found"
msgstr "Mapa vectorial <%s> no encontrado"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
"No ha sido posible establecer nivel predeterminado de apertura de vectorial"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -918,7 +918,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr "No se puede abrir el mapa vectorial <%s>"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -973,7 +973,7 @@ msgstr "No se puede abrir el mapa vectorial <%s>"
msgid "Unable to create vector map <%s>"
msgstr "No se puede crear el mapa vectorial <%s>"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -989,7 +989,7 @@ msgstr "No se puede crear el mapa vectorial <%s>"
msgid "Database connection not defined for layer %d"
msgstr "La conexión a la base de datos no ha sido definida para la capa %d"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -1003,7 +1003,7 @@ msgstr "La conexión a la base de datos no ha sido definida para la capa %d"
msgid "Unable to start driver <%s>"
msgstr "No se puede iniciar el controlador <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1054,7 +1054,7 @@ msgstr "No se puede iniciar el controlador <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "No se puede abrir la base de datos <%s> por el controlador <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1069,17 +1069,17 @@ msgstr "No se puede abrir la base de datos <%s> por el controlador <%s>"
msgid "Unable to describe table <%s>"
msgstr "No se puede describir la tabla<%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "No ha sido posible obtener datos para categoría %d"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "Error al recuperar registro de base de datos para categoría %d"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "No es posible copiar tabla de atributos al mapa vectorial <%s>"
diff --git a/locale/po/grassmods_fi.po b/locale/po/grassmods_fi.po
index be1a87cd456..dba5dfc58ea 100644
--- a/locale/po/grassmods_fi.po
+++ b/locale/po/grassmods_fi.po
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_fr.po b/locale/po/grassmods_fr.po
index 3225a9d712b..ba09f1d912c 100644
--- a/locale/po/grassmods_fr.po
+++ b/locale/po/grassmods_fr.po
@@ -267,7 +267,7 @@ msgstr ""
"pilote : %s\n"
"base : %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -559,19 +559,19 @@ msgstr ""
msgid "raster"
msgstr "raster"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "Mon module raster de départ"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -625,7 +625,7 @@ msgstr "Mon module raster de départ"
msgid "Raster map <%s> not found"
msgstr "Carte raster <%s> non trouvée"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -810,11 +810,11 @@ msgstr "Carte raster <%s> non trouvée"
msgid "vector"
msgstr "vecteur"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "Mon module vecteur de départ."
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -836,12 +836,12 @@ msgstr "Mon module vecteur de départ."
msgid "Vector map <%s> not found"
msgstr "Carte vecteur <%s> non trouvée"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -913,7 +913,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr "Impossible d'ouvrir la carte vecteur <%s>"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -968,7 +968,7 @@ msgstr "Impossible d'ouvrir la carte vecteur <%s>"
msgid "Unable to create vector map <%s>"
msgstr "Impossible de créer la carte vecteur <%s>"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -985,7 +985,7 @@ msgid "Database connection not defined for layer %d"
msgstr ""
"La connexion à la base de données n'a pas été définie pour la couche %d"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -999,7 +999,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr "Impossible de lancer le pilote <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1050,7 +1050,7 @@ msgstr "Impossible de lancer le pilote <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Impossible d'ouvrir la base de données <%s> avec le pilote <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1065,17 +1065,17 @@ msgstr "Impossible d'ouvrir la base de données <%s> avec le pilote <%s>"
msgid "Unable to describe table <%s>"
msgstr "Impossible de décrire la table <%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Impossible de sélectionner les attributs pour cat = %d"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "Aucun enregistrement pour la catégorie cat = %d"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "Impossible de copier la table d'attributs vers la carte vecteur <%s>"
diff --git a/locale/po/grassmods_hu.po b/locale/po/grassmods_hu.po
index 0cad5773fea..1833a1717a2 100644
--- a/locale/po/grassmods_hu.po
+++ b/locale/po/grassmods_hu.po
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr "raszter"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr "Nem tudom elindítani a <%s> meghajtót"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr "Nem tudom elindítani a <%s> meghajtót"
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_id_ID.po b/locale/po/grassmods_id_ID.po
index df950915b12..ab373e47cd5 100644
--- a/locale/po/grassmods_id_ID.po
+++ b/locale/po/grassmods_id_ID.po
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_it.po b/locale/po/grassmods_it.po
index bb84b42a1c3..2ee80f9be6d 100644
--- a/locale/po/grassmods_it.po
+++ b/locale/po/grassmods_it.po
@@ -265,7 +265,7 @@ msgstr ""
"driver: %s\n"
"database: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -557,19 +557,19 @@ msgstr ""
msgid "raster"
msgstr "raster"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "Il mio primo modulo raster"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -623,7 +623,7 @@ msgstr "Il mio primo modulo raster"
msgid "Raster map <%s> not found"
msgstr "Mappa raster <%s> non trovata"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -808,11 +808,11 @@ msgstr "Mappa raster <%s> non trovata"
msgid "vector"
msgstr "vettoriale"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "Il mio primo modulo vettoriale"
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -834,12 +834,12 @@ msgstr "Il mio primo modulo vettoriale"
msgid "Vector map <%s> not found"
msgstr "Mappa vettoriale <%s> non trovata"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr "Impossibile impostare il predeterminato livello del vettoriale aperto"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -911,7 +911,7 @@ msgstr "Impossibile impostare il predeterminato livello del vettoriale aperto"
msgid "Unable to open vector map <%s>"
msgstr "Impossibile aprire la mappa vettoriale <%s>"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -966,7 +966,7 @@ msgstr "Impossibile aprire la mappa vettoriale <%s>"
msgid "Unable to create vector map <%s>"
msgstr "Non è possibile creare la mappa vettoriale <%s>"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -982,7 +982,7 @@ msgstr "Non è possibile creare la mappa vettoriale <%s>"
msgid "Database connection not defined for layer %d"
msgstr "Connessione al database non definita per il layer %d"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -996,7 +996,7 @@ msgstr "Connessione al database non definita per il layer %d"
msgid "Unable to start driver <%s>"
msgstr "Impossibile avviare il driver <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1047,7 +1047,7 @@ msgstr "Impossibile avviare il driver <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Impossibile aprire il database <%s> col driver <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1062,17 +1062,17 @@ msgstr "Impossibile aprire il database <%s> col driver <%s>"
msgid "Unable to describe table <%s>"
msgstr "Impossibile descrivere la tabella <%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Impossibile ottenere gli attributi per la categoria %d"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "Errore ricevendo il record del database per la categoria %d"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_ja.po b/locale/po/grassmods_ja.po
index 39bcbe7402b..236287ce5e5 100644
--- a/locale/po/grassmods_ja.po
+++ b/locale/po/grassmods_ja.po
@@ -259,7 +259,7 @@ msgstr ""
"ドライバー: %s\n"
"データベース: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -551,19 +551,19 @@ msgstr ""
msgid "raster"
msgstr "ラスター"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "自分の最初のラスターモジュール"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -617,7 +617,7 @@ msgstr "自分の最初のラスターモジュール"
msgid "Raster map <%s> not found"
msgstr "ラスタマップ <%s> が見つかりません"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -802,11 +802,11 @@ msgstr "ラスタマップ <%s> が見つかりません"
msgid "vector"
msgstr "ベクトル"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "自分の最初のベクトルモジュール"
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -828,12 +828,12 @@ msgstr "自分の最初のベクトルモジュール"
msgid "Vector map <%s> not found"
msgstr "ベクトルマップ <%s> が見つかりません"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr "既設のベクトル オープン レベルを設定できません"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -905,7 +905,7 @@ msgstr "既設のベクトル オープン レベルを設定できません"
msgid "Unable to open vector map <%s>"
msgstr "ベクトルマップ <%s> を開けません"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -960,7 +960,7 @@ msgstr "ベクトルマップ <%s> を開けません"
msgid "Unable to create vector map <%s>"
msgstr "ベクトルマップ <%s> を作成できません"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -976,7 +976,7 @@ msgstr "ベクトルマップ <%s> を作成できません"
msgid "Database connection not defined for layer %d"
msgstr "データベース接続はレイヤー %d に定義されていません"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -990,7 +990,7 @@ msgstr "データベース接続はレイヤー %d に定義されていませ
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1041,7 +1041,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr "ドライバー <%s> でデータベース <%s> を開けません"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1056,17 +1056,17 @@ msgstr "ドライバー <%s> でデータベース <%s> を開けません"
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "カテゴリー %d の属性データを取得できません"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "カテゴリー %d のデータベース レコード取得中にエラー"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "属性テーブルをベクトルマップ <%s> へコピーできません"
diff --git a/locale/po/grassmods_ko.po b/locale/po/grassmods_ko.po
index 09064eb9df8..ac9b25d1df9 100644
--- a/locale/po/grassmods_ko.po
+++ b/locale/po/grassmods_ko.po
@@ -250,7 +250,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -542,19 +542,19 @@ msgstr ""
msgid "raster"
msgstr "래스터"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -608,7 +608,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr "래스터 지도 <%s>를 찾을 수 없습니다"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -793,11 +793,11 @@ msgstr "래스터 지도 <%s>를 찾을 수 없습니다"
msgid "vector"
msgstr "벡터"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -819,12 +819,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr "미리 결정된 벡터 열기 단계를 설정할 수 없습니다"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -896,7 +896,7 @@ msgstr "미리 결정된 벡터 열기 단계를 설정할 수 없습니다"
msgid "Unable to open vector map <%s>"
msgstr "벡터 지도 <%s>를 열 수 없습니다"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -951,7 +951,7 @@ msgstr "벡터 지도 <%s>를 열 수 없습니다"
msgid "Unable to create vector map <%s>"
msgstr "벡터 지도 <%s>를 생성할 수 없습니다"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -967,7 +967,7 @@ msgstr "벡터 지도 <%s>를 생성할 수 없습니다"
msgid "Database connection not defined for layer %d"
msgstr "레이어 %d를 위한 데이터베이스 연결이 정의되지 않았습니다"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -981,7 +981,7 @@ msgstr "레이어 %d를 위한 데이터베이스 연결이 정의되지 않았
msgid "Unable to start driver <%s>"
msgstr "드라이버 <%s>를 시작할 수 없습니다"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1032,7 +1032,7 @@ msgstr "드라이버 <%s>를 시작할 수 없습니다"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "데이터베이스 <%s>를 드라이버 <%s>로 열 수 없습니다"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1047,17 +1047,17 @@ msgstr "데이터베이스 <%s>를 드라이버 <%s>로 열 수 없습니다"
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "cat %d를 위한 속성 자료를 얻을 수 없습니다"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "속성 테이블을 벡터 지도 <%s>로 복사할 수 없습니다"
diff --git a/locale/po/grassmods_lv.po b/locale/po/grassmods_lv.po
index f185b50eebc..2fb56f36516 100644
--- a/locale/po/grassmods_lv.po
+++ b/locale/po/grassmods_lv.po
@@ -254,7 +254,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -546,19 +546,19 @@ msgstr ""
msgid "raster"
msgstr "rastrs"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -612,7 +612,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -797,11 +797,11 @@ msgstr ""
msgid "vector"
msgstr "vektors"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -823,12 +823,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -900,7 +900,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -955,7 +955,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -971,7 +971,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -985,7 +985,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1036,7 +1036,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1051,17 +1051,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, fuzzy, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Nevar iatlasīt datus no tabulas"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_ml.po b/locale/po/grassmods_ml.po
index cfe442a427e..e03bdff269f 100644
--- a/locale/po/grassmods_ml.po
+++ b/locale/po/grassmods_ml.po
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_pl.po b/locale/po/grassmods_pl.po
index 9bd71b3b945..7d966975e22 100644
--- a/locale/po/grassmods_pl.po
+++ b/locale/po/grassmods_pl.po
@@ -257,7 +257,7 @@ msgstr ""
"sterownik: %s\n"
"baza danych: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -549,19 +549,19 @@ msgstr ""
msgid "raster"
msgstr "raster"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "Mój pierwszy moduł rastrowy"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -615,7 +615,7 @@ msgstr "Mój pierwszy moduł rastrowy"
msgid "Raster map <%s> not found"
msgstr "Mapa rastrowa <%s> nie została znaleziona"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -800,11 +800,11 @@ msgstr "Mapa rastrowa <%s> nie została znaleziona"
msgid "vector"
msgstr "wektor"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "Mój pierwszy moduł wektorowy"
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -826,12 +826,12 @@ msgstr "Mój pierwszy moduł wektorowy"
msgid "Vector map <%s> not found"
msgstr "Nie znaleziono mapy wektorowej <%s>"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -903,7 +903,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr "Nie można otworzyć mapy wektorowej <%s>"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -958,7 +958,7 @@ msgstr "Nie można otworzyć mapy wektorowej <%s>"
msgid "Unable to create vector map <%s>"
msgstr "Nie można utworzyć mapy wektorowej <%s>"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -974,7 +974,7 @@ msgstr "Nie można utworzyć mapy wektorowej <%s>"
msgid "Database connection not defined for layer %d"
msgstr "Połączenie z bazą danych nie zostało zdefiniowane dla warstwy %d"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -988,7 +988,7 @@ msgstr "Połączenie z bazą danych nie zostało zdefiniowane dla warstwy %d"
msgid "Unable to start driver <%s>"
msgstr "Nie można uruchomić sterownika <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1039,7 +1039,7 @@ msgstr "Nie można uruchomić sterownika <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Nie można otworzyć bazy danych <%s> za pomocą sterownika <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1054,17 +1054,17 @@ msgstr "Nie można otworzyć bazy danych <%s> za pomocą sterownika <%s>"
msgid "Unable to describe table <%s>"
msgstr "Nie można opisać tabeli <%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Nie można wybrać atrybutów dla cat %d"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "Nie można skopiować tabeli atrybutów do mapy wektorowej <%s>"
diff --git a/locale/po/grassmods_pt.po b/locale/po/grassmods_pt.po
index a22f945601b..8f06bf66795 100644
--- a/locale/po/grassmods_pt.po
+++ b/locale/po/grassmods_pt.po
@@ -255,7 +255,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -547,19 +547,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -613,7 +613,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -798,11 +798,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -824,12 +824,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -901,7 +901,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -956,7 +956,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -972,7 +972,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -986,7 +986,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1037,7 +1037,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1052,17 +1052,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_pt_BR.po b/locale/po/grassmods_pt_BR.po
index a40e9100d63..285fc19148c 100644
--- a/locale/po/grassmods_pt_BR.po
+++ b/locale/po/grassmods_pt_BR.po
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr "raster"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr "palavra-chave2"
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr "palavra-chave3"
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "Meu primeiro módulo raster"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr "Meu primeiro módulo raster"
msgid "Raster map <%s> not found"
msgstr "Mapa raster <%s> não encontrado"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr "Mapa raster <%s> não encontrado"
msgid "vector"
msgstr "vetor"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "Meu primeiro módulo vetorial"
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr "Meu primeiro módulo vetorial"
msgid "Vector map <%s> not found"
msgstr "Mapa vetorial <%s> não encontrado"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr "Não foi possível definir o nível vetorial aberto pré-determinado"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr "Não foi possível definir o nível vetorial aberto pré-determinado"
msgid "Unable to open vector map <%s>"
msgstr "Não foi possível abrir mapa vetorial <%s>"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr "Não foi possível abrir mapa vetorial <%s>"
msgid "Unable to create vector map <%s>"
msgstr "Não foi possível criar mapa vetorial <%s>"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr "Não foi possível criar mapa vetorial <%s>"
msgid "Database connection not defined for layer %d"
msgstr "Conexão do banco de dados não definida para camada %d"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr "Conexão do banco de dados não definida para camada %d"
msgid "Unable to start driver <%s>"
msgstr "Não foi possível iniciar o driver <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr "Não foi possível iniciar o driver <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Não foi possível abrir banco de dados <%s> com driver <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr "Não foi possível abrir banco de dados <%s> com driver <%s>"
msgid "Unable to describe table <%s>"
msgstr "Não foi possível descrever a tabela <%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Não foi possível obter dados de atributo para categoria %d"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "Erro ao recuperar o registro do banco de dados para categoria %d"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_ro.po b/locale/po/grassmods_ro.po
index 4f49bec89f3..381049e994b 100644
--- a/locale/po/grassmods_ro.po
+++ b/locale/po/grassmods_ro.po
@@ -255,7 +255,7 @@ msgstr ""
"driver: %s\n"
"baza de date: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -547,19 +547,19 @@ msgstr ""
msgid "raster"
msgstr "raster"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr "cuvânt cheie 2"
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr "cuvânt cheie 3"
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -613,7 +613,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr "Harta raster <%s> nu este găsită"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -798,11 +798,11 @@ msgstr "Harta raster <%s> nu este găsită"
msgid "vector"
msgstr "vector"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -824,12 +824,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr "Harta vectorială <%s> nu a fost găsită"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -901,7 +901,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr "Imposibil de deschis harta vectorială <%s>"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -956,7 +956,7 @@ msgstr "Imposibil de deschis harta vectorială <%s>"
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -972,7 +972,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr "Conexiunea bazei de date nu este definită pentru stratul %d"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -986,7 +986,7 @@ msgstr "Conexiunea bazei de date nu este definită pentru stratul %d"
msgid "Unable to start driver <%s>"
msgstr "Imposibil de pornit driver-ul<%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1037,7 +1037,7 @@ msgstr "Imposibil de pornit driver-ul<%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Imposibil de deschis baza de date <%s> cu driverl <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1052,17 +1052,17 @@ msgstr "Imposibil de deschis baza de date <%s> cu driverl <%s>"
msgid "Unable to describe table <%s>"
msgstr "Nu s-a putut descrie tabelul<%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Imposibil de obținut datele atribut pentru cat %d"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "Imposibil de copiat tabela de atribute la harta vectorială <%s>"
diff --git a/locale/po/grassmods_ru.po b/locale/po/grassmods_ru.po
index 87d6bbad54e..35bc5c306c4 100644
--- a/locale/po/grassmods_ru.po
+++ b/locale/po/grassmods_ru.po
@@ -255,7 +255,7 @@ msgstr ""
"драйвер: %s\n"
"база данных: %s"
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -547,19 +547,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -613,7 +613,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr "Растровая карта <%s> не найдена"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -798,11 +798,11 @@ msgstr "Растровая карта <%s> не найдена"
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -824,12 +824,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr "Векторная карта <%s> не найдена"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -901,7 +901,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr "Не удалось открыть векторную карту <%s>"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -956,7 +956,7 @@ msgstr "Не удалось открыть векторную карту <%s>"
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -972,7 +972,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr "Не определено соединение с базой данных для слоя %d"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -986,7 +986,7 @@ msgstr "Не определено соединение с базой данны
msgid "Unable to start driver <%s>"
msgstr "Не удалось запустить драйвер <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1037,7 +1037,7 @@ msgstr "Не удалось запустить драйвер <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Не удалось открыть базу данных <%s> с помощью драйвера <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1052,17 +1052,17 @@ msgstr "Не удалось открыть базу данных <%s> с пом
msgid "Unable to describe table <%s>"
msgstr "Невозможно описать таблицу <%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_si.po b/locale/po/grassmods_si.po
index 2acdb89fbfe..d6aa6cebc6c 100644
--- a/locale/po/grassmods_si.po
+++ b/locale/po/grassmods_si.po
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_sl.po b/locale/po/grassmods_sl.po
index 84ae7a95b4d..981de091d76 100644
--- a/locale/po/grassmods_sl.po
+++ b/locale/po/grassmods_sl.po
@@ -264,7 +264,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -556,20 +556,20 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
#, fuzzy
msgid "My first raster module"
msgstr "Ime obstoječega rastrskega sloja."
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -623,7 +623,7 @@ msgstr "Ime obstoječega rastrskega sloja."
msgid "Raster map <%s> not found"
msgstr "Ne najdem vhodnega rastrskega sloja <%s>."
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -808,12 +808,12 @@ msgstr "Ne najdem vhodnega rastrskega sloja <%s>."
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
#, fuzzy
msgid "My first vector module"
msgstr "Ime obstoječega rastrskega sloja."
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -835,13 +835,13 @@ msgstr "Ime obstoječega rastrskega sloja."
msgid "Vector map <%s> not found"
msgstr "Ne najdem vhodnega vektorja <%s>"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
#, fuzzy
msgid "Unable to set predetermined vector open level"
msgstr "Ime izhodnega vektorskega točkovnega sloja"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -913,7 +913,7 @@ msgstr "Ime izhodnega vektorskega točkovnega sloja"
msgid "Unable to open vector map <%s>"
msgstr "Ime izhodnega rastrskega sloja"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -968,7 +968,7 @@ msgstr "Ime izhodnega rastrskega sloja"
msgid "Unable to create vector map <%s>"
msgstr "Ime izhodnega rastrskega sloja"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -984,7 +984,7 @@ msgstr "Ime izhodnega rastrskega sloja"
msgid "Database connection not defined for layer %d"
msgstr "Povezava z bazo podatkov ni definirana\n"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -998,7 +998,7 @@ msgstr "Povezava z bazo podatkov ni definirana\n"
msgid "Unable to start driver <%s>"
msgstr "Ne morem zagnati gonilnika '%s'."
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1049,7 +1049,7 @@ msgstr "Ne morem zagnati gonilnika '%s'."
msgid "Unable to open database <%s> by driver <%s>"
msgstr "Ne morem odpreti baze podatkov %s z gonilnikom %s"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1064,17 +1064,17 @@ msgstr "Ne morem odpreti baze podatkov %s z gonilnikom %s"
msgid "Unable to describe table <%s>"
msgstr "Ne morem opisati tabele"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, fuzzy, c-format
msgid "Unable to get attribute data for cat %d"
msgstr "Ne morem izbrati (select) podatkov iz tabele"
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, fuzzy, c-format
msgid "Error while retrieving database record for cat %d"
msgstr "Za vrstico (cat = %d) ni zapisa (record)<"
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, fuzzy, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr "Ime izhodnega rastrskega sloja"
diff --git a/locale/po/grassmods_ta.po b/locale/po/grassmods_ta.po
index 05719977a92..2cc76db5743 100644
--- a/locale/po/grassmods_ta.po
+++ b/locale/po/grassmods_ta.po
@@ -252,7 +252,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -544,19 +544,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -610,7 +610,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -795,11 +795,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -821,12 +821,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -898,7 +898,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -953,7 +953,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -969,7 +969,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -983,7 +983,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1034,7 +1034,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1049,17 +1049,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_th.po b/locale/po/grassmods_th.po
index 65e557c85d9..4f763f25733 100644
--- a/locale/po/grassmods_th.po
+++ b/locale/po/grassmods_th.po
@@ -252,7 +252,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -544,19 +544,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -610,7 +610,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -795,11 +795,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -821,12 +821,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -898,7 +898,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -953,7 +953,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -969,7 +969,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -983,7 +983,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1034,7 +1034,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1049,17 +1049,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_tr.po b/locale/po/grassmods_tr.po
index dad3e4285c7..3ca146dfced 100644
--- a/locale/po/grassmods_tr.po
+++ b/locale/po/grassmods_tr.po
@@ -254,7 +254,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -546,19 +546,19 @@ msgstr ""
msgid "raster"
msgstr "raster"
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr "İlk raster modülüm"
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -612,7 +612,7 @@ msgstr "İlk raster modülüm"
msgid "Raster map <%s> not found"
msgstr "<%s> raster haritası bulunamadı"
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -797,11 +797,11 @@ msgstr "<%s> raster haritası bulunamadı"
msgid "vector"
msgstr "vektör"
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr "İlk vektör modülüm"
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -823,12 +823,12 @@ msgstr "İlk vektör modülüm"
msgid "Vector map <%s> not found"
msgstr "<%s> vektör haritası bulunamadı"
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr "Önceden belirlenen vektör açma katmanı ayarlanamıyor"
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -900,7 +900,7 @@ msgstr "Önceden belirlenen vektör açma katmanı ayarlanamıyor"
msgid "Unable to open vector map <%s>"
msgstr "<%s> vektör haritası açılamıyor"
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -955,7 +955,7 @@ msgstr "<%s> vektör haritası açılamıyor"
msgid "Unable to create vector map <%s>"
msgstr "<%s> vektör haritası oluşturulamıyor"
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -971,7 +971,7 @@ msgstr "<%s> vektör haritası oluşturulamıyor"
msgid "Database connection not defined for layer %d"
msgstr "%d katmanının veritabanı bağlantısı belirlenmedi"
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -985,7 +985,7 @@ msgstr "%d katmanının veritabanı bağlantısı belirlenmedi"
msgid "Unable to start driver <%s>"
msgstr "Sürücü başlatılamıyor<%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1036,7 +1036,7 @@ msgstr "Sürücü başlatılamıyor<%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "<%s> sürücüsüyle <%s> veritabanı açılamıyor"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1051,17 +1051,17 @@ msgstr "<%s> sürücüsüyle <%s> veritabanı açılamıyor"
msgid "Unable to describe table <%s>"
msgstr "<%s> tablosu tanımlanamıyor"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_uk.po b/locale/po/grassmods_uk.po
index 65b9178e653..7403997e3ba 100644
--- a/locale/po/grassmods_uk.po
+++ b/locale/po/grassmods_uk.po
@@ -252,7 +252,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -544,19 +544,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -610,7 +610,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -795,11 +795,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -821,12 +821,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -898,7 +898,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -953,7 +953,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -969,7 +969,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -983,7 +983,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1034,7 +1034,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1049,17 +1049,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_vi.po b/locale/po/grassmods_vi.po
index 49b0683b187..7002874a944 100644
--- a/locale/po/grassmods_vi.po
+++ b/locale/po/grassmods_vi.po
@@ -252,7 +252,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -544,19 +544,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -610,7 +610,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -795,11 +795,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -821,12 +821,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -898,7 +898,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -953,7 +953,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -969,7 +969,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -983,7 +983,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1034,7 +1034,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1049,17 +1049,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_zh.po b/locale/po/grassmods_zh.po
index cccf638e84a..0be17badee4 100644
--- a/locale/po/grassmods_zh.po
+++ b/locale/po/grassmods_zh.po
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr "无法启动驱动 <%s>"
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr "无法启动驱动 <%s>"
msgid "Unable to open database <%s> by driver <%s>"
msgstr "无法由驱动<%s>打开数据库 <%s>"
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr "无法由驱动<%s>打开数据库 <%s>"
msgid "Unable to describe table <%s>"
msgstr "无法描述表 <%s>"
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/po/grassmods_zh_CN.po b/locale/po/grassmods_zh_CN.po
index 455581b506d..87e296038ea 100644
--- a/locale/po/grassmods_zh_CN.po
+++ b/locale/po/grassmods_zh_CN.po
@@ -252,7 +252,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -544,19 +544,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -610,7 +610,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -795,11 +795,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -821,12 +821,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -898,7 +898,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -953,7 +953,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -969,7 +969,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -983,7 +983,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1034,7 +1034,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1049,17 +1049,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/locale/templates/grassmods.pot b/locale/templates/grassmods.pot
index 30b09b22a2b..2648cf1de3b 100644
--- a/locale/templates/grassmods.pot
+++ b/locale/templates/grassmods.pot
@@ -251,7 +251,7 @@ msgid ""
"database: %s"
msgstr ""
-#: ../doc/raster/r.example/main.c:83 ../raster/r.external/main.c:57
+#: ../doc/examples/raster/r.example/main.c:83 ../raster/r.external/main.c:57
#: ../raster/r.quantile/main.c:297 ../raster/r.terraflow/main.cpp:457
#: ../raster/r.info/main.c:71 ../raster/r.patch/main.c:68
#: ../raster/r.support.stats/main.c:35 ../raster/r.what.color/main.c:88
@@ -543,19 +543,19 @@ msgstr ""
msgid "raster"
msgstr ""
-#: ../doc/raster/r.example/main.c:84 ../doc/vector/v.example/main.c:50
+#: ../doc/examples/raster/r.example/main.c:84 ../doc/examples/vector/v.example/main.c:50
msgid "keyword2"
msgstr ""
-#: ../doc/raster/r.example/main.c:85 ../doc/vector/v.example/main.c:51
+#: ../doc/examples/raster/r.example/main.c:85 ../doc/examples/vector/v.example/main.c:51
msgid "keyword3"
msgstr ""
-#: ../doc/raster/r.example/main.c:86
+#: ../doc/examples/raster/r.example/main.c:86
msgid "My first raster module"
msgstr ""
-#: ../doc/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
+#: ../doc/examples/raster/r.example/main.c:105 ../raster/r.terraflow/main.cpp:207
#: ../raster/r.terraflow/main.cpp:354 ../raster/r.terraflow/main.cpp:390
#: ../raster/r.info/main.c:111 ../raster/r.cost/main.c:364
#: ../raster/r.cost/main.c:391 ../raster/r.cost/main.c:711
@@ -609,7 +609,7 @@ msgstr ""
msgid "Raster map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
+#: ../doc/examples/vector/v.example/main.c:49 ../raster/r.contour/main.c:90
#: ../raster/r.random/main.c:55 ../misc/m.nviz.script/main.c:71
#: ../misc/m.nviz.image/main.c:52
#: ../locale/scriptstrings/v.clip_to_translate.c:2
@@ -794,11 +794,11 @@ msgstr ""
msgid "vector"
msgstr ""
-#: ../doc/vector/v.example/main.c:52
+#: ../doc/examples/vector/v.example/main.c:52
msgid "My first vector module"
msgstr ""
-#: ../doc/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
+#: ../doc/examples/vector/v.example/main.c:76 ../raster/r.cost/main.c:357
#: ../raster/r.walk/main.c:460 ../raster/r.carve/main.c:153
#: ../misc/m.nviz.image/vector.c:82 ../general/g.region/main.c:505
#: ../vector/v.lidar.edgedetection/main.c:181 ../vector/v.profile/main.c:371
@@ -820,12 +820,12 @@ msgstr ""
msgid "Vector map <%s> not found"
msgstr ""
-#: ../doc/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
+#: ../doc/examples/vector/v.example/main.c:82 ../vector/v.profile/main.c:378
#: ../vector/v.cluster/main.c:137
msgid "Unable to set predetermined vector open level"
msgstr ""
-#: ../doc/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
+#: ../doc/examples/vector/v.example/main.c:88 ../raster/r.cost/main.c:599
#: ../raster/r.cost/main.c:666 ../raster/r.drain/main.c:277
#: ../raster/r.walk/main.c:760 ../raster/r.walk/main.c:827
#: ../raster/r.region/main.c:172 ../raster/r.sim/simlib/observation_points.c:40
@@ -897,7 +897,7 @@ msgstr ""
msgid "Unable to open vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
+#: ../doc/examples/vector/v.example/main.c:101 ../raster/r.to.vect/main.c:159
#: ../raster/r.drain/main.c:204 ../raster/r.resamp.bspline/main.c:484
#: ../raster/r.sim/simlib/output.c:49 ../raster/r.sim/simlib/output.c:56
#: ../raster/r.flow/flow_io.c:181 ../raster/r.contour/main.c:155
@@ -952,7 +952,7 @@ msgstr ""
msgid "Unable to create vector map <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
+#: ../doc/examples/vector/v.example/main.c:110 ../vector/v.generalize/misc.c:167
#: ../vector/v.to.rast/support.c:101 ../vector/v.to.rast/support.c:271
#: ../vector/v.to.rast/support.c:499 ../vector/v.distance/main.c:563
#: ../vector/v.buffer/main.c:422 ../vector/v.univar/main.c:236
@@ -968,7 +968,7 @@ msgstr ""
msgid "Database connection not defined for layer %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
+#: ../doc/examples/vector/v.example/main.c:130 ../raster/r.stream.extract/close.c:176
#: ../db/db.execute/main.c:68 ../db/db.createdb/main.c:38
#: ../db/db.columns/main.c:47 ../db/db.dropdb/main.c:39
#: ../db/db.databases/main.c:47 ../db/db.describe/main.c:51
@@ -982,7 +982,7 @@ msgstr ""
msgid "Unable to start driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
+#: ../doc/examples/vector/v.example/main.c:138 ../raster/r.to.vect/main.c:189
#: ../raster/r.contour/main.c:170 ../raster/r.volume/main.c:248
#: ../raster/r.random/random.c:67 ../misc/m.nviz.image/vector.c:301
#: ../raster3d/r3.flow/main.c:46 ../ps/ps.map/catval.c:53
@@ -1033,7 +1033,7 @@ msgstr ""
msgid "Unable to open database <%s> by driver <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:143 ../db/db.columns/main.c:58
+#: ../doc/examples/vector/v.example/main.c:143 ../db/db.columns/main.c:58
#: ../db/db.describe/main.c:62 ../vector/v.db.connect/main.c:229
#: ../vector/v.out.vtk/writeVTK.c:651 ../vector/v.out.postgis/table.c:41
#: ../vector/v.reclass/main.c:189 ../vector/v.in.ascii/main.c:446
@@ -1048,17 +1048,17 @@ msgstr ""
msgid "Unable to describe table <%s>"
msgstr ""
-#: ../doc/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
+#: ../doc/examples/vector/v.example/main.c:176 ../vector/v.profile/main.c:708
#, c-format
msgid "Unable to get attribute data for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
+#: ../doc/examples/vector/v.example/main.c:185 ../vector/v.profile/main.c:717
#, c-format
msgid "Error while retrieving database record for cat %d"
msgstr ""
-#: ../doc/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
+#: ../doc/examples/vector/v.example/main.c:220 ../vector/v.fill.holes/main.c:196
#, c-format
msgid "Unable to copy attribute table to vector map <%s>"
msgstr ""
diff --git a/macosx/Makefile b/macos/Makefile
similarity index 100%
rename from macosx/Makefile
rename to macos/Makefile
diff --git a/macosx/ReadMe.md b/macos/ReadMe.md
similarity index 100%
rename from macosx/ReadMe.md
rename to macos/ReadMe.md
diff --git a/macosx/bundle.make b/macos/bundle.make
similarity index 100%
rename from macosx/bundle.make
rename to macos/bundle.make
diff --git a/macosx/app/AppIcon.icns b/macos/files/AppIcon.icns
similarity index 100%
rename from macosx/app/AppIcon.icns
rename to macos/files/AppIcon.icns
diff --git a/macosx/app/English.lproj/MainMenu.nib/classes.nib b/macos/files/English.lproj/MainMenu.nib/classes.nib
similarity index 100%
rename from macosx/app/English.lproj/MainMenu.nib/classes.nib
rename to macos/files/English.lproj/MainMenu.nib/classes.nib
diff --git a/macosx/app/English.lproj/MainMenu.nib/data.dependency b/macos/files/English.lproj/MainMenu.nib/data.dependency
similarity index 100%
rename from macosx/app/English.lproj/MainMenu.nib/data.dependency
rename to macos/files/English.lproj/MainMenu.nib/data.dependency
diff --git a/macosx/app/English.lproj/MainMenu.nib/info.nib b/macos/files/English.lproj/MainMenu.nib/info.nib
similarity index 100%
rename from macosx/app/English.lproj/MainMenu.nib/info.nib
rename to macos/files/English.lproj/MainMenu.nib/info.nib
diff --git a/macosx/app/English.lproj/MainMenu.nib/keyedobjects.nib b/macos/files/English.lproj/MainMenu.nib/keyedobjects.nib
similarity index 100%
rename from macosx/app/English.lproj/MainMenu.nib/keyedobjects.nib
rename to macos/files/English.lproj/MainMenu.nib/keyedobjects.nib
diff --git a/macosx/app/GRASS.applescript b/macos/files/GRASS.applescript
similarity index 100%
rename from macosx/app/GRASS.applescript
rename to macos/files/GRASS.applescript
diff --git a/macosx/app/GRASSDocument_gxw.icns b/macos/files/GRASSDocument_gxw.icns
similarity index 100%
rename from macosx/app/GRASSDocument_gxw.icns
rename to macos/files/GRASSDocument_gxw.icns
diff --git a/macosx/app/GRASSDocument_gxw.svg b/macos/files/GRASSDocument_gxw.svg
similarity index 100%
rename from macosx/app/GRASSDocument_gxw.svg
rename to macos/files/GRASSDocument_gxw.svg
diff --git a/macosx/app/Info.plist.in b/macos/files/Info.plist.in
similarity index 100%
rename from macosx/app/Info.plist.in
rename to macos/files/Info.plist.in
diff --git a/macosx/app/Makefile b/macos/files/Makefile
similarity index 100%
rename from macosx/app/Makefile
rename to macos/files/Makefile
diff --git a/macosx/app/PkgInfo b/macos/files/PkgInfo
similarity index 100%
rename from macosx/app/PkgInfo
rename to macos/files/PkgInfo
diff --git a/macosx/app/build_gui_user_menu.sh b/macos/files/build_gui_user_menu.sh
similarity index 100%
rename from macosx/app/build_gui_user_menu.sh
rename to macos/files/build_gui_user_menu.sh
diff --git a/macosx/app/build_html_user_index.sh b/macos/files/build_html_user_index.sh
similarity index 100%
rename from macosx/app/build_html_user_index.sh
rename to macos/files/build_html_user_index.sh
diff --git a/macosx/app/grass.sh.in b/macos/files/grass.sh.in
similarity index 100%
rename from macosx/app/grass.sh.in
rename to macos/files/grass.sh.in
diff --git a/macosx/app/main.m b/macos/files/main.m
similarity index 100%
rename from macosx/app/main.m
rename to macos/files/main.m
diff --git a/macosx/app/python_wrapper b/macos/files/python_wrapper
similarity index 100%
rename from macosx/app/python_wrapper
rename to macos/files/python_wrapper
diff --git a/macosx/pkg/resources/Description.plist.in b/macos/pkg/resources/Description.plist.in
similarity index 100%
rename from macosx/pkg/resources/Description.plist.in
rename to macos/pkg/resources/Description.plist.in
diff --git a/macosx/pkg/resources/Info.plist.in b/macos/pkg/resources/Info.plist.in
similarity index 100%
rename from macosx/pkg/resources/Info.plist.in
rename to macos/pkg/resources/Info.plist.in
diff --git a/macosx/pkg/resources/License.rtf b/macos/pkg/resources/License.rtf
similarity index 100%
rename from macosx/pkg/resources/License.rtf
rename to macos/pkg/resources/License.rtf
diff --git a/macosx/pkg/resources/ReadMe.rtf b/macos/pkg/resources/ReadMe.rtf
similarity index 100%
rename from macosx/pkg/resources/ReadMe.rtf
rename to macos/pkg/resources/ReadMe.rtf
diff --git a/macosx/pkg/resources/postflight.in b/macos/pkg/resources/postflight.in
similarity index 100%
rename from macosx/pkg/resources/postflight.in
rename to macos/pkg/resources/postflight.in
diff --git a/man/build.py b/man/build.py
index 9c394a8749d..9cc47446a2a 100644
--- a/man/build.py
+++ b/man/build.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# utilities for generating HTML indices
-# (C) 2003-2024 Markus Neteler and the GRASS Development Team
+# (C) 2003-2025 Markus Neteler and the GRASS Development Team
# Authors:
# Markus Neteler
# Glynn Clements
diff --git a/man/build_graphical_index.py b/man/build_graphical_index.py
index d46574af0a8..bc7dd5299d9 100755
--- a/man/build_graphical_index.py
+++ b/man/build_graphical_index.py
@@ -5,7 +5,7 @@
# MODULE: build_graphical_index
# AUTHOR(S): Vaclav Petras
# PURPOSE: Build graphical index
-# COPYRIGHT: (C) 2015-2024 by Vaclav Petras and the GRASS Development Team
+# COPYRIGHT: (C) 2015-2025 by Vaclav Petras and the GRASS Development Team
#
# This program is free software under the GNU General Public
# License (>=v2). Read the file COPYING that comes with GRASS
diff --git a/man/build_rest.py b/man/build_rest.py
index 168a5ba6127..18554ad5216 100644
--- a/man/build_rest.py
+++ b/man/build_rest.py
@@ -9,7 +9,7 @@
"""
# utilities for generating REST indices
# utilities for generating HTML indices
-# (C) 2003-2024 by Luca Delucchi and the GRASS Development Team
+# (C) 2003-2025 by Luca Delucchi and the GRASS Development Team
import os
import string
@@ -171,7 +171,7 @@
--------------
:doc:`Manual main page ` \| :doc:`Full Index `
- 2003-2024 `GRASS Development Team `_, GRASS GIS ${grass_version} Reference Manual
+ 2003-2025 `GRASS Development Team `_, GRASS GIS ${grass_version} Reference Manual
""" # noqa: E501
)
diff --git a/man/build_topics.py b/man/build_topics.py
index 484f093cc3e..2ef3e8c57df 100644
--- a/man/build_topics.py
+++ b/man/build_topics.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# generates topics.html and topic_*.html
-# (c) 2012-2024 by the GRASS Development Team
+# (c) 2012-2025 by the GRASS Development Team
import os
import glob
diff --git a/man/sphinx/conf.py b/man/sphinx/conf.py
index dbe8fb9022b..16f67074a80 100644
--- a/man/sphinx/conf.py
+++ b/man/sphinx/conf.py
@@ -38,7 +38,7 @@
# General information about the project.
project = "GRASS GIS"
-copyright = "2024, GRASS Development Team"
+copyright = "2025, GRASS Development Team"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/pyproject.toml b/pyproject.toml
index f9712ce2582..dc37688511e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -318,7 +318,6 @@ ignore = [
"python/grass/gunittest/multireport.py" = ["PYI024"]
"python/grass/gunittest/testsu*/d*/s*/s*/subsub*/t*/test_segfaut.py" = ["B018"]
"python/grass/gunittest/testsuite/test_assertions_rast3d.py" = ["FLY002"]
-"python/grass/imaging/images2*.py" = ["SIM115"]
"python/grass/imaging/images2ims.py" = ["PTH208"]
"python/grass/jupyter/testsuite/interactivemap_test.py" = ["PGH004"]
"python/grass/jupyter/testsuite/map_test.py" = ["PGH004"]
@@ -337,9 +336,7 @@ ignore = [
"python/grass/pygrass/vector/testsuite/test_table.py" = ["PLW0108"]
"python/grass/script/array.py" = ["A005"]
"python/grass/script/core.py" = ["PTH208"]
-"python/grass/script/db.py" = ["SIM115"]
-"python/grass/script/raster.py" = ["SIM115"]
-"python/grass/script/utils.py" = ["FURB189", "SIM115"]
+"python/grass/script/utils.py" = ["FURB189"]
"python/grass/temporal/aggregation.py" = ["SIM115"]
"python/grass/temporal/register.py" = ["SIM115"]
"python/grass/temporal/stds_export.py" = ["SIM115"]
@@ -384,8 +381,8 @@ ignore = [
"temporal/t.register/testsuite/test_t_register_raster.py" = ["FLY002"]
"temporal/t.register/testsuite/test_t_register_raster_file.py" = ["FLY002"]
"temporal/t.remove/t.remove.py" = ["SIM115"]
-"utils/**.py" = ["SIM115"]
"utils/generate_release_notes.py" = ["PGH004"]
+"utils/gitlog2changelog.py" = ["SIM115"]
"utils/thumbnails.py" = ["PTH208"]
"vector/v.fill.holes/examples.ipynb" = ["PTH201"]
diff --git a/python/grass/docs/conf.py b/python/grass/docs/conf.py
index 2d6a564cac0..cccd2e213ac 100644
--- a/python/grass/docs/conf.py
+++ b/python/grass/docs/conf.py
@@ -128,7 +128,7 @@
# General information about the project.
project = "Python library documentation"
-copyright = "2024, GRASS Development Team"
+copyright = "2025, GRASS Development Team"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/python/grass/gunittest/multirunner.py b/python/grass/gunittest/multirunner.py
index ebb9e80049a..dd5411d66fc 100644
--- a/python/grass/gunittest/multirunner.py
+++ b/python/grass/gunittest/multirunner.py
@@ -111,16 +111,16 @@ def main():
# we assume that the start script is available and in the PATH
# the shell=True is here because of MS Windows? (code taken from wiki)
startcmd = grass_executable + " --config path"
- p = subprocess.Popen(
+ with subprocess.Popen(
startcmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
- )
- out, err = p.communicate()
- if p.returncode != 0:
- print(
- "ERROR: Cannot find GRASS GIS start script (%s):\n%s" % (startcmd, err),
- file=sys.stderr,
- )
- return 1
+ ) as p:
+ out, err = p.communicate()
+ if p.returncode != 0:
+ print(
+ "ERROR: Cannot find GRASS GIS start script (%s):\n%s" % (startcmd, err),
+ file=sys.stderr,
+ )
+ return 1
gisbase = decode(out.strip())
# set GISBASE environment variable
@@ -151,7 +151,7 @@ def main():
# including also type to make it unique and preserve it for sure
report = "report_for_" + location + "_" + location_type
absreport = os.path.abspath(report)
- p = subprocess.Popen(
+ with subprocess.Popen(
[
sys.executable,
"-tt",
@@ -167,23 +167,24 @@ def main():
absreport,
],
cwd=grasssrc,
- )
- returncode = p.wait()
- reports.append(report)
+ ) as p2:
+ returncode = p2.wait()
+ reports.append(report)
if main_report:
# TODO: solve the path to source code (work now only for grass source code)
arguments = [
sys.executable,
- grasssrc + "/python/grass/gunittest/" + "multireport.py",
- "--timestapms",
+ grasssrc + "/python/grass/gunittest/multireport.py",
+ "--timestamps",
+ *reports,
]
- arguments.extend(reports)
- p = subprocess.Popen(arguments)
- returncode = p.wait()
- if returncode != 0:
- print("ERROR: Creation of main report failed.", file=sys.stderr)
- return 1
+
+ with subprocess.Popen(arguments) as p3:
+ returncode = p3.wait()
+ if returncode != 0:
+ print("ERROR: Creation of main report failed.", file=sys.stderr)
+ return 1
return 0
diff --git a/python/grass/gunittest/reporters.py b/python/grass/gunittest/reporters.py
index 5b468ac1d91..767678416d1 100644
--- a/python/grass/gunittest/reporters.py
+++ b/python/grass/gunittest/reporters.py
@@ -160,19 +160,19 @@ def get_svn_revision():
"""
# TODO: here should be starting directory
# but now we are using current as starting
- p = subprocess.Popen(
+ with subprocess.Popen(
["svnversion", "."], stdout=subprocess.PIPE, stderr=subprocess.PIPE
- )
- stdout, stderr = p.communicate()
- rc = p.poll()
- if not rc:
+ ) as p:
+ stdout, stderr = p.communicate()
+ rc = p.poll()
+ if rc:
+ return None
stdout = stdout.strip()
stdout = stdout.removesuffix("M")
if ":" in stdout:
# the first one is the one of source code
stdout = stdout.split(":")[0]
return stdout
- return None
def get_svn_info():
diff --git a/python/grass/imaging/images2avi.py b/python/grass/imaging/images2avi.py
index 2dda32e142d..27bdd2c15ca 100644
--- a/python/grass/imaging/images2avi.py
+++ b/python/grass/imaging/images2avi.py
@@ -180,22 +180,22 @@ def readAvi(filename, asNumpy=True):
# Run ffmpeg
command = "ffmpeg -i input.avi im%d.jpg"
- S = subprocess.Popen(
- command, shell=True, cwd=tempDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE
- )
-
- # Show what mencodec has to say
- outPut = S.stdout.read()
-
- if S.wait():
- # An error occurred, show
- print(outPut)
- print(S.stderr.read())
- # Clean up
- _cleanDir(tempDir)
- msg = "Could not read avi."
- raise RuntimeError(msg)
-
+ with subprocess.Popen(
+ command,
+ cwd=tempDir,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ ) as S:
+ # Show what mencodec has to say
+ outPut = S.stdout.read()
+ if S.wait():
+ # An error occurred, show
+ print(outPut)
+ print(S.stderr.read())
+ # Clean up
+ _cleanDir(tempDir)
+ msg = "Could not read avi."
+ raise RuntimeError(msg)
# Read images
images = images2ims.readIms(os.path.join(tempDir, "im*.jpg"), asNumpy)
# Clean up
diff --git a/python/grass/imaging/images2gif.py b/python/grass/imaging/images2gif.py
index 5c4e9dec3cb..63435297927 100644
--- a/python/grass/imaging/images2gif.py
+++ b/python/grass/imaging/images2gif.py
@@ -229,9 +229,9 @@ def getGraphicsControlExt(self, duration=0.1, dispose=2):
* 0 - No disposal specified.
* 1 - Do not dispose. The graphic is to be left in place.
- * 2 - Restore to background color. The area used by the graphic
+ * 2 - Restore to background color. The area used by the graphic
must be restored to the background color.
- * 3 - Restore to previous. The decoder is required to restore the
+ * 3 - Restore to previous. The decoder is required to restore the
area overwritten by the graphic with what was there prior to
rendering the graphic.
* 4-7 -To be defined.
@@ -253,7 +253,6 @@ def handleSubRectangles(self, images, subRectangles):
"""Handle the sub-rectangle stuff. If the rectangles are given by the
user, the values are checked. Otherwise the subrectangles are
calculated automatically.
-
"""
if isinstance(subRectangles, (tuple, list)):
@@ -400,9 +399,7 @@ def writeGifToFile(self, fp, images, durations, loops, xys, disposes):
Requires different handling of palette for PIL and Pillow:
based on https://github.com/rec/echomesh/blob/master/
code/python/external/images2gif.py
-
"""
-
# Obtain palette for all images and count each occurrence
palettes, occur = ([], [])
for im in images:
@@ -538,7 +535,7 @@ def writeGifVisvis(
integer types, and between 0 and 1 for float types.
:param duration: scalar or list of scalars The duration for all frames, or
(if a list) for each frame.
- :param repeat: bool or integer The amount of loops. If True, loops infinitetely.
+ :param repeat: bool or integer The amount of loops. If True, loops infinitely.
:param bool dither: whether to apply dithering
:param int nq: If nonzero, applies the NeuQuant quantization algorithm to
create the color palette. This algorithm is superior, but
@@ -615,11 +612,8 @@ def writeGifVisvis(
images = gifWriter.convertImagesToPIL(images, dither, nq)
# Write
- fp = open(filename, "wb")
- try:
+ with open(filename, "wb") as fp:
gifWriter.writeGifToFile(fp, images, duration, loops, xy, dispose)
- finally:
- fp.close()
def readGif(filename, asNumpy=True):
diff --git a/python/grass/imaging/images2swf.py b/python/grass/imaging/images2swf.py
index 1ea1a4e8413..9fcd2da6447 100644
--- a/python/grass/imaging/images2swf.py
+++ b/python/grass/imaging/images2swf.py
@@ -69,6 +69,7 @@
import os
import zlib
+from pathlib import Path
try:
import numpy as np
@@ -838,11 +839,8 @@ def writeSwf(filename, images, duration=0.1, repeat=True):
taglist.append(DoActionTag("stop"))
# Build file
- fp = open(filename, "wb")
- try:
+ with open(filename, "wb") as fp:
buildFile(fp, taglist, nframes=nframes, framesize=wh, fps=fps)
- finally:
- fp.close()
def _readPixels(bb, i, tagType, L1):
@@ -923,67 +921,60 @@ def readSwf(filename, asNumpy=True):
images = []
# Open file and read all
- fp = open(filename, "rb")
- bb = fp.read()
-
- try:
- # Check opening tag
- tmp = bb[0:3].decode("ascii", "ignore")
- if tmp.upper() == "FWS":
- pass # ok
- elif tmp.upper() == "CWS":
- # Decompress movie
- bb = bb[:8] + zlib.decompress(bb[8:])
+ bb = Path(filename).read_bytes()
+ # Check opening tag
+ tmp = bb[0:3].decode("ascii", "ignore")
+ if tmp.upper() == "FWS":
+ pass # ok
+ elif tmp.upper() == "CWS":
+ # Decompress movie
+ bb = bb[:8] + zlib.decompress(bb[8:])
+ else:
+ raise OSError("Not a valid SWF file: " + str(filename))
+
+ # Set filepointer at first tag (skipping framesize RECT and two uin16's
+ i = 8
+ nbits = bitsToInt(bb[i : i + 1], 5) # skip FrameSize
+ nbits = 5 + nbits * 4
+ Lrect = nbits / 8.0
+ if Lrect % 1:
+ Lrect += 1
+ Lrect = int(Lrect)
+ i += Lrect + 4
+
+ # Iterate over the tags
+ counter = 0
+ while True:
+ counter += 1
+
+ # Get tag header
+ head = bb[i : i + 6]
+ if not head:
+ break # Done (we missed end tag)
+
+ # Determine type and length
+ T, L1, L2 = getTypeAndLen(head)
+ if not L2:
+ print("Invalid tag length, could not proceed")
+ break
+ # print(T, L2)
+
+ # Read image if we can
+ if T in {20, 36}:
+ im = _readPixels(bb, i + 6, T, L1)
+ if im is not None:
+ images.append(im)
+ elif T in {6, 21, 35, 90}:
+ print("Ignoring JPEG image: cannot read JPEG.")
else:
- raise OSError("Not a valid SWF file: " + str(filename))
-
- # Set filepointer at first tag (skipping framesize RECT and two uin16's
- i = 8
- nbits = bitsToInt(bb[i : i + 1], 5) # skip FrameSize
- nbits = 5 + nbits * 4
- Lrect = nbits / 8.0
- if Lrect % 1:
- Lrect += 1
- Lrect = int(Lrect)
- i += Lrect + 4
-
- # Iterate over the tags
- counter = 0
- while True:
- counter += 1
-
- # Get tag header
- head = bb[i : i + 6]
- if not head:
- break # Done (we missed end tag)
-
- # Determine type and length
- T, L1, L2 = getTypeAndLen(head)
- if not L2:
- print("Invalid tag length, could not proceed")
- break
- # print(T, L2)
-
- # Read image if we can
- if T in [20, 36]:
- im = _readPixels(bb, i + 6, T, L1)
- if im is not None:
- images.append(im)
- elif T in [6, 21, 35, 90]:
- print("Ignoring JPEG image: cannot read JPEG.")
- else:
- pass # Not an image tag
-
- # Detect end tag
- if T == 0:
- break
-
- # Next tag!
- i += L2
+ pass # Not an image tag
- finally:
- fp.close()
+ # Detect end tag
+ if T == 0:
+ break
+ # Next tag!
+ i += L2
# Convert to normal PIL images if needed
if not asNumpy:
images2 = images
diff --git a/python/grass/jupyter/__init__.py b/python/grass/jupyter/__init__.py
index 21223c2cd47..0db59ca2ea7 100644
--- a/python/grass/jupyter/__init__.py
+++ b/python/grass/jupyter/__init__.py
@@ -13,7 +13,7 @@
# License (>=v2). Read the file COPYING that comes with GRASS
# for details.
-"""The *grass.jupyter* is a convenient GRASS GIS interface for Jupyter notebooks.
+"""A convenient GRASS GIS interface for Jupyter notebooks.
Python is a great tool for data science and scientific computing. Jupyter_ is an
environment with computational notebooks which makes it even better tool for
@@ -72,7 +72,7 @@
.. image:: https://mybinder.org/badge_logo.svg
:target:
- https://mybinder.org/v2/gh/OSGeo/grass/main?urlpath=lab%2Ftree%2Fdoc%2Fnotebooks%2Fjupyter_example.ipynb
+ https://mybinder.org/v2/gh/OSGeo/grass/main?urlpath=lab%2Ftree%2Fdoc%2Fexamples%2Fnotebooks%2Fjupyter_example.ipynb
There are also internal classes and functions which are not guaranteed to have
as stable API, although they are available through their specific submodules.
@@ -103,7 +103,7 @@
.. _Jupyter: https://jupyter.org/
.. _wiki: https://grasswiki.osgeo.org/wiki/GRASS_GIS_Jupyter_notebooks
-.. _GitHub: https://github.com/OSGeo/grass/blob/main/doc/notebooks/jupyter_example.ipynb
+.. _GitHub: https://github.com/OSGeo/grass/blob/main/doc/examples/notebooks/jupyter_example.ipynb
"""
from .interactivemap import InteractiveMap, Raster, Vector
diff --git a/python/grass/jupyter/utils.py b/python/grass/jupyter/utils.py
index c443d2590f2..e3be2e7da87 100644
--- a/python/grass/jupyter/utils.py
+++ b/python/grass/jupyter/utils.py
@@ -309,14 +309,13 @@ def estimate_resolution(
) -> float:
"""Estimates resolution of reprojected raster.
- :param str raster: name of raster
- :param str mapset: mapset of raster
- :param str location: name of source location
- :param str dbase: path to source database
+ :param raster: name of raster
+ :param mapset: mapset of raster
+ :param location: name of source location
+ :param dbase: path to source database
:param dict env: target environment
- :return float estimate: estimated resolution of raster in destination
- environment
+ :return estimate: estimated resolution of raster in destination environment
"""
output = gs.read_command(
"r.proj",
diff --git a/python/grass/pygrass/modules/grid/grid.py b/python/grass/pygrass/modules/grid/grid.py
index 5df1cb3aca7..be2c2c971c2 100644
--- a/python/grass/pygrass/modules/grid/grid.py
+++ b/python/grass/pygrass/modules/grid/grid.py
@@ -163,8 +163,7 @@ def copy_groups(groups, gisrc_src, gisrc_dst, region=None):
:param gisrc_dst: path of the GISRC file where the groups will be created
:type gisrc_dst: str
:param region: a region like object or a dictionary with the region
- parameters that will be used to crop the rasters of the
- groups
+ parameters that will be used to crop the rasters of the groups
:type region: Region object or dictionary
:returns: None
@@ -204,8 +203,7 @@ def set_region(region, gisrc_src, gisrc_dst, env):
"""Set a region into two different mapsets.
:param region: a region like object or a dictionary with the region
- parameters that will be used to crop the rasters of the
- groups
+ parameters that will be used to crop the rasters of the groups
:type region: Region object or dictionary
:param gisrc_src: path of the GISRC file from where we want to copy the groups
:type gisrc_src: str
@@ -238,8 +236,7 @@ def copy_rasters(rasters, gisrc_src, gisrc_dst, region=None):
:param gisrc_dst: path of the GISRC file where the groups will be created
:type gisrc_dst: str
:param region: a region like object or a dictionary with the region
- parameters that will be used to crop the rasters of the
- groups
+ parameters that will be used to crop the rasters of the groups
:type region: Region object or dictionary
:returns: None
"""
@@ -401,7 +398,7 @@ class GridModule:
:param overlap: overlap between tiles, in pixel.
:type overlap: int
:param processes: number of threads, default value is equal to the number
- of processor available.
+ of processors available.
:param split: if True use r.tile to split all the inputs.
:type split: bool
:param mapset_prefix: if specified created mapsets start with this prefix
diff --git a/python/grass/pygrass/vector/__init__.py b/python/grass/pygrass/vector/__init__.py
index 696abb84532..90a8d2acfbe 100644
--- a/python/grass/pygrass/vector/__init__.py
+++ b/python/grass/pygrass/vector/__init__.py
@@ -127,7 +127,7 @@ def write(self, geo_obj, cat=None, attrs=None):
:param geo_obj: a geometry grass object define in
grass.pygrass.vector.geometry
:type geo_obj: geometry GRASS object
- :param attrs: a list with the values that will be insert in the
+ :param attrs: a list with the values that will be inserted in the
attribute table.
:type attrs: list
:param cat: The category of the geometry feature, otherwise the
diff --git a/python/grass/pygrass/vector/abstract.py b/python/grass/pygrass/vector/abstract.py
index 00bef3997f2..304b45e3a04 100644
--- a/python/grass/pygrass/vector/abstract.py
+++ b/python/grass/pygrass/vector/abstract.py
@@ -337,12 +337,11 @@ def open(
:param tab_name: define the name of the table that will be generate
:type tab_name: str
:param tab_cols: define the name and type of the columns of the
- attribute table of the vecto map
+ attribute table of the vector map
:type tab_cols: list of pairs
- :param link_name: define the name of the link connection with the
- database
+ :param link_name: define the name of the link connection with the database
:type link_name: str
- :param link_key: define the nema of the column that will be use as
+ :param link_key: define the name of the column that will be use as
vector category
:type link_key: str
:param link_db: define the database connection parameters
diff --git a/python/grass/pygrass/vector/geometry.py b/python/grass/pygrass/vector/geometry.py
index e0cae2c4fc0..b08ac76fc6b 100644
--- a/python/grass/pygrass/vector/geometry.py
+++ b/python/grass/pygrass/vector/geometry.py
@@ -591,8 +591,7 @@ def buffer(
:type angle: num
:param round_: to make corners round
:type round_: bool
- :param tol: fix the maximum distance between theoretical arc and
- output segments
+ :param tol: fix the maximum distance between theoretical arc and output segments
:type tol: float
:returns: the buffer as Area object
@@ -1048,11 +1047,9 @@ def reverse(self):
def segment(self, start, end):
"""Create line segment. using the ``Vect_line_segment`` C function.
- :param start: distance from the beginning of the line where
- the segment start
+ :param start: distance from the beginning of the line where the segment starts
:type start: float
- :param end: distance from the beginning of the line where
- the segment end
+ :param end: distance from the beginning of the line where the segment ends
:type end: float
::
@@ -1155,8 +1152,7 @@ def buffer(
:type angle: num
:param round_: to make corners round
:type round_: bool
- :param tol: fix the maximum distance between theoretical arc and
- output segments
+ :param tol: fix the maximum distance between theoretical arc and output segments
:type tol: float
:returns: the buffer as Area object
@@ -1717,8 +1713,7 @@ def buffer(
:type angle: num
:param round_: to make corners round
:type round_: bool
- :param tol: fix the maximum distance between theoretical arc and
- output segments
+ :param tol: fix the maximum distance between theoretical arc and output segments
:type tol: float
:returns: the buffer as line, centroid, isles object tuple
diff --git a/python/grass/pygrass/vector/table.py b/python/grass/pygrass/vector/table.py
index ac52d31baad..d259db0b006 100644
--- a/python/grass/pygrass/vector/table.py
+++ b/python/grass/pygrass/vector/table.py
@@ -1121,8 +1121,7 @@ def drop(self, cursor=None, force=False):
:param cursor: the cursor to connect, if None it use the cursor
of connection table object
:type cursor: Cursor object
- :param force: True to remove the table, by default False to print
- advice
+ :param force: True to remove the table, by default False to print advice
:type force: bool
"""
@@ -1161,8 +1160,7 @@ def execute(self, sql_code=None, cursor=None, many=False, values=None):
"""Execute SQL code from a given string or build with filters and
return a cursor object.
- :param sql_code: the SQL code to execute, if not pass it use filters
- variable
+ :param sql_code: the SQL code to execute, if not pass it use filters variable
:type sql_code: str
:param cursor: the cursor to connect, if None it use the cursor
of connection table object
diff --git a/python/grass/script/core.py b/python/grass/script/core.py
index b1c12ed37b9..0c9d3726697 100644
--- a/python/grass/script/core.py
+++ b/python/grass/script/core.py
@@ -8,7 +8,7 @@
from grass.script import core as grass
grass.parser()
-(C) 2008-2024 by the GRASS Development Team
+(C) 2008-2025 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
@@ -933,15 +933,14 @@ def parser() -> tuple[dict[str, str], dict[str, bool]]:
argv[0] = os.path.join(sys.path[0], name)
prog = "g.parser.exe" if sys.platform == "win32" else "g.parser"
- p = subprocess.Popen([prog, "-n"] + argv, stdout=subprocess.PIPE)
- s = p.communicate()[0]
- lines = s.split(b"\0")
-
- if not lines or lines[0] != b"@ARGS_PARSED@":
- stdout = os.fdopen(sys.stdout.fileno(), "wb")
- stdout.write(s)
- sys.exit(p.returncode)
- return _parse_opts(lines[1:])
+ with subprocess.Popen([prog, "-n"] + argv, stdout=subprocess.PIPE) as p:
+ s = p.communicate()[0]
+ lines = s.split(b"\0")
+ if not lines or lines[0] != b"@ARGS_PARSED@":
+ stdout = os.fdopen(sys.stdout.fileno(), "wb")
+ stdout.write(s)
+ sys.exit(p.returncode)
+ return _parse_opts(lines[1:])
# interface to g.tempfile
diff --git a/python/grass/script/db.py b/python/grass/script/db.py
index 0ae4fe6b53f..46b4753bf42 100644
--- a/python/grass/script/db.py
+++ b/python/grass/script/db.py
@@ -94,23 +94,20 @@ def db_table_exist(table, env=None, **args):
:return: True for success, False otherwise
"""
- nuldev = open(os.devnull, "w+")
ok = True
- try:
- run_command(
- "db.describe",
- flags="c",
- table=table,
- stdout=nuldev,
- stderr=nuldev,
- env=env,
- **args,
- )
- except CalledModuleError:
- ok = False
- finally:
- nuldev.close()
-
+ with open(os.devnull, "w+") as nuldev:
+ try:
+ run_command(
+ "db.describe",
+ flags="c",
+ table=table,
+ stdout=nuldev,
+ stderr=nuldev,
+ env=env,
+ **args,
+ )
+ except CalledModuleError:
+ ok = False
return ok
@@ -190,9 +187,8 @@ def db_select(sql=None, filename=None, table=None, env=None, **args):
except CalledModuleError:
fatal(_("Fetching data failed"), env=env)
- ofile = open(fname)
- result = [tuple(x.rstrip(os.linesep).split(args["sep"])) for x in ofile]
- ofile.close()
+ with open(fname) as ofile:
+ result = [tuple(x.rstrip(os.linesep).split(args["sep"])) for x in ofile]
try_remove(fname)
return tuple(result)
@@ -217,16 +213,16 @@ def db_table_in_vector(table, mapset=".", env=None):
"""
from .vector import vector_db
- nuldev = open(os.devnull, "w")
used = []
vects = list_strings("vector", mapset=mapset, env=env)
- for vect in vects:
- for f in vector_db(vect, stderr=nuldev, env=env).values():
- if not f:
- continue
- if f["table"] == table:
- used.append(vect)
- break
+ with open(os.devnull, "w") as nuldev:
+ for vect in vects:
+ for f in vector_db(vect, stderr=nuldev, env=env).values():
+ if not f:
+ continue
+ if f["table"] == table:
+ used.append(vect)
+ break
if len(used) > 0:
return used
return None
diff --git a/python/grass/script/raster.py b/python/grass/script/raster.py
index f3507cd48b0..73c555a67f0 100644
--- a/python/grass/script/raster.py
+++ b/python/grass/script/raster.py
@@ -21,6 +21,8 @@
import os
import string
import time
+from pathlib import Path
+
from .core import (
gisenv,
@@ -49,27 +51,25 @@ def raster_history(map, overwrite=False, env=None):
"""
current_mapset = gisenv(env)["MAPSET"]
- if find_file(name=map, env=env)["mapset"] == current_mapset:
- if overwrite is True:
- historyfile = tempfile(env=env)
- f = open(historyfile, "w")
- f.write(os.environ["CMDLINE"])
- f.close()
- run_command("r.support", map=map, loadhistory=historyfile, env=env)
- try_remove(historyfile)
- else:
- run_command("r.support", map=map, history=os.environ["CMDLINE"], env=env)
- return True
-
- warning(
- _(
- "Unable to write history for <%(map)s>. "
- "Raster map <%(map)s> not found in current mapset."
+ if find_file(name=map, env=env)["mapset"] != current_mapset:
+ warning(
+ _(
+ "Unable to write history for <%(map)s>. "
+ "Raster map <%(map)s> not found in current mapset."
+ )
+ % {"map": map},
+ env=env,
)
- % {"map": map},
- env=env,
- )
- return False
+ return False
+
+ if overwrite is True:
+ historyfile = tempfile(env=env)
+ Path(historyfile).write_text(os.environ["CMDLINE"])
+ run_command("r.support", map=map, loadhistory=historyfile, env=env)
+ try_remove(historyfile)
+ else:
+ run_command("r.support", map=map, history=os.environ["CMDLINE"], env=env)
+ return True
def raster_info(map, env=None):
@@ -218,8 +218,7 @@ def raster_what(map, coord, env=None, localized=False):
[{'elevation': {'color': '255:214:000', 'label': '', 'value': '102.479'}}]
:param str map: the map name
- :param list coord: a list of list containing all the point that you want
- query
+ :param list coord: a list of list containing all the point that you want to query
:param env:
"""
map_list = [map] if isinstance(map, (bytes, str)) else map
diff --git a/python/grass/script/setup.py b/python/grass/script/setup.py
index bb10c03cbfb..e57c6e81668 100644
--- a/python/grass/script/setup.py
+++ b/python/grass/script/setup.py
@@ -65,7 +65,7 @@
session.finish()
-(C) 2010-2024 by the GRASS Development Team
+(C) 2010-2025 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
diff --git a/python/grass/script/utils.py b/python/grass/script/utils.py
index 64677731835..3684091ba73 100644
--- a/python/grass/script/utils.py
+++ b/python/grass/script/utils.py
@@ -105,9 +105,8 @@ def diff_files(
import difflib
differ = difflib.Differ()
- fh_a = open(filename_a)
- fh_b = open(filename_b)
- return list(differ.compare(fh_a.readlines(), fh_b.readlines()))
+ with open(filename_a) as fh_a, open(filename_b) as fh_b:
+ return list(differ.compare(fh_a.readlines(), fh_b.readlines()))
def try_remove(path: StrOrBytesPath) -> None:
diff --git a/python/grass/temporal/abstract_dataset.py b/python/grass/temporal/abstract_dataset.py
index b8e0856ca77..4e8cf294105 100644
--- a/python/grass/temporal/abstract_dataset.py
+++ b/python/grass/temporal/abstract_dataset.py
@@ -74,7 +74,7 @@ def get_number_of_relations(self):
topologies must be build first using the SpatioTemporalTopologyBuilder.
:return: The dictionary with relations as keys and number as values or
- None in case the topology wasn't build
+ None in case the topology wasn't built
"""
if self.is_temporal_topology_build() and not self.is_spatial_topology_build():
return self.get_number_of_temporal_relations()
@@ -341,8 +341,7 @@ def get_spatial_extent_as_tuple(self):
Top and bottom are set to 0 in case of a two dimensional spatial
extent.
- :return: A the spatial extent as tuple (north, south, east, west,
- top, bottom)
+ :return: A the spatial extent as tuple (north, south, east, west, top, bottom)
"""
return self.spatial_extent.get_spatial_extent_as_tuple()
diff --git a/python/grass/temporal/abstract_map_dataset.py b/python/grass/temporal/abstract_map_dataset.py
index 3b9cf272f0c..17a2b36a8d7 100644
--- a/python/grass/temporal/abstract_map_dataset.py
+++ b/python/grass/temporal/abstract_map_dataset.py
@@ -176,8 +176,7 @@ def split_name(name: str, layer=None, mapset=None):
the keyword arguments.
:param name: The name of the map
- :param layer: The layer of the vector map, use None in case no
- layer exists
+ :param layer: The layer of the vector map, use None in case no layer exists
:param mapset: The mapset in which the map is located
:return: tuple of three elements name, layer, mapset e(:layer)@mapset" while
@@ -244,11 +243,9 @@ def build_id(name: str, mapset, layer=None) -> str:
:param name: The name of the map
:param mapset: The mapset in which the map is located
- :param layer: The layer of the vector map, use None in case no
- layer exists
+ :param layer: The layer of the vector map, use None in case no layer exists
- :return: the id of the map as "name(:layer)@mapset" where layer is
- optional
+ :return: the id of the map as "name(:layer)@mapset" where layer is optional
"""
# Split given name into relevant parts
@@ -421,8 +418,7 @@ def set_absolute_time(self, start_time, end_time=None) -> bool:
This method only modifies this object and does not commit
the modifications to the temporal database.
- :param start_time: A datetime object specifying the start time of
- the map
+ :param start_time: A datetime object specifying the start time of the map
:param end_time: A datetime object specifying the end time of the
map, None in case or time instance
@@ -512,8 +508,7 @@ def update_absolute_time(self, start_time, end_time=None, dbif=None) -> None:
grass file system based database in addition to the temporal
database entry.
- :param start_time: A datetime object specifying the start time of
- the map
+ :param start_time: A datetime object specifying the start time of the map
:param end_time: A datetime object specifying the end time of the
map, None in case or time instance
:param dbif: The database interface to be used
@@ -669,8 +664,7 @@ def set_temporal_extent(self, extent) -> None:
"""Convenient method to set the temporal extent from a temporal extent
object
- :param extent: The temporal extent that should be set for
- this object
+ :param extent: The temporal extent that should be set for this object
.. code-block: : python
@@ -853,8 +847,7 @@ def set_spatial_extent(self, spatial_extent) -> None:
This method only modifies this object and does not commit
the modifications to the temporal database.
- :param spatial_extent: An object of type SpatialExtent or its
- subclasses
+ :param spatial_extent: An object of type SpatialExtent or its subclasses
.. code-block: : python
diff --git a/python/grass/temporal/aggregation.py b/python/grass/temporal/aggregation.py
index 69537ab0e49..bd4c7eb7b8f 100644
--- a/python/grass/temporal/aggregation.py
+++ b/python/grass/temporal/aggregation.py
@@ -166,13 +166,11 @@ def aggregate_raster_maps(
# Create the r.series input file
filename = gs.tempfile(True)
- file = open(filename, "w")
+ with open(filename, "w") as out_file:
+ for name in inputs:
+ string = "%s\n" % (name)
+ out_file.write(string)
- for name in inputs:
- string = "%s\n" % (name)
- file.write(string)
-
- file.close()
# Run r.series
try:
if len(inputs) > 1000:
@@ -364,11 +362,10 @@ def aggregate_by_topology(
if len(aggregation_list) > 1:
# Create the r.series input file
filename = gs.tempfile(True)
- file = open(filename, "w")
- for name in aggregation_list:
- string = "%s\n" % (name)
- file.write(string)
- file.close()
+ with open(filename, "w") as out_file:
+ for name in aggregation_list:
+ string = "%s\n" % (name)
+ out_file.write(string)
mod = copy.deepcopy(r_series)
mod(file=filename, output=output_name)
diff --git a/python/grass/temporal/datetime_math.py b/python/grass/temporal/datetime_math.py
index 9104ab4b689..a40be0aea16 100644
--- a/python/grass/temporal/datetime_math.py
+++ b/python/grass/temporal/datetime_math.py
@@ -1,7 +1,7 @@
"""
Functions for mathematical datetime operations
-(C) 2011-2013 by the GRASS Development Team
+(C) 2011-2024 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.
@@ -13,6 +13,7 @@
import copy
from datetime import datetime, timedelta
+from typing import TypedDict
from .core import get_tgis_message_interface
@@ -20,7 +21,7 @@
from dateutil import parser
has_dateutil = True
-except:
+except (ImportError, ModuleNotFoundError):
has_dateutil = False
@@ -490,7 +491,20 @@ def adjust_datetime_to_granularity(mydate: datetime, granularity):
###############################################################################
-def compute_datetime_delta(start, end):
+class datetime_delta(TypedDict):
+ """Typed dictionary to return the accumulated delta in year, month, day,
+ hour, minute and second as well as max_days. At runtime, it is a plain dict."""
+
+ year: int
+ month: int
+ day: int
+ hour: int
+ minute: int
+ second: int
+ max_days: int
+
+
+def compute_datetime_delta(start: datetime, end: datetime) -> datetime_delta:
"""Return a dictionary with the accumulated delta in year, month, day,
hour, minute and second
@@ -501,136 +515,137 @@ def compute_datetime_delta(start, end):
>>> start = datetime(2001, 1, 1, 0, 0, 0)
>>> end = datetime(2001, 1, 1, 0, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 0, 'second': 0, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 0}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 0, 'minute': 0, 'second': 0, 'max_days': 0}
>>> start = datetime(2001, 1, 1, 0, 0, 14)
>>> end = datetime(2001, 1, 1, 0, 0, 44)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 0, 'second': 30, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 0}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 0, 'minute': 0, 'second': 30, 'max_days': 0}
>>> start = datetime(2001, 1, 1, 0, 0, 44)
>>> end = datetime(2001, 1, 1, 0, 1, 14)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 0, 'second': 30, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 1}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 0, 'minute': 1, 'second': 30, 'max_days': 0}
>>> start = datetime(2001, 1, 1, 0, 0, 30)
>>> end = datetime(2001, 1, 1, 0, 5, 30)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 0, 'second': 300, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 5}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 0, 'minute': 5, 'second': 300, 'max_days': 0}
>>> start = datetime(2001, 1, 1, 0, 0, 0)
>>> end = datetime(2001, 1, 1, 0, 1, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 0, 'second': 0, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 1}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 0, 'minute': 1, 'second': 0, 'max_days': 0}
>>> start = datetime(2011, 10, 31, 0, 45, 0)
>>> end = datetime(2011, 10, 31, 1, 45, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 1, 'second': 0, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 60}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 1, 'minute': 60, 'second': 0, 'max_days': 0}
>>> start = datetime(2011, 10, 31, 0, 45, 0)
>>> end = datetime(2011, 10, 31, 1, 15, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 1, 'second': 0, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 30}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 1, 'minute': 30, 'second': 0, 'max_days': 0}
>>> start = datetime(2011, 10, 31, 0, 45, 0)
>>> end = datetime(2011, 10, 31, 12, 15, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 12, 'second': 0, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 690}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 12, 'minute': 690, 'second': 0, 'max_days': 0}
>>> start = datetime(2011, 10, 31, 0, 0, 0)
>>> end = datetime(2011, 10, 31, 1, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 1, 'second': 0, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 0}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 1, 'minute': 0, 'second': 0, 'max_days': 0}
>>> start = datetime(2011, 10, 31, 0, 0, 0)
>>> end = datetime(2011, 11, 1, 1, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 25, 'second': 0, 'max_days': 1, 'year': 0, 'day': 1, 'minute': 0}
+ {'year': 0, 'month': 0, 'day': 1, 'hour': 25, 'minute': 0, 'second': 0, 'max_days': 1}
>>> start = datetime(2011, 10, 31, 12, 0, 0)
>>> end = datetime(2011, 11, 1, 6, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 18, 'second': 0, 'max_days': 0, 'year': 0, 'day': 0, 'minute': 0}
+ {'year': 0, 'month': 0, 'day': 0, 'hour': 18, 'minute': 0, 'second': 0, 'max_days': 0}
>>> start = datetime(2011, 11, 1, 0, 0, 0)
>>> end = datetime(2011, 12, 1, 1, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 721, 'month': 1, 'second': 0, 'max_days': 30, 'year': 0, 'day': 0, 'minute': 0}
+ {'year': 0, 'month': 1, 'day': 0, 'hour': 721, 'minute': 0, 'second': 0, 'max_days': 30}
>>> start = datetime(2011, 11, 1, 0, 0, 0)
>>> end = datetime(2011, 11, 5, 0, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'second': 0, 'max_days': 4, 'year': 0, 'day': 4, 'minute': 0}
+ {'year': 0, 'month': 0, 'day': 4, 'hour': 0, 'minute': 0, 'second': 0, 'max_days': 4}
>>> start = datetime(2011, 10, 6, 0, 0, 0)
>>> end = datetime(2011, 11, 5, 0, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'second': 0, 'max_days': 30, 'year': 0, 'day': 30, 'minute': 0}
+ {'year': 0, 'month': 0, 'day': 30, 'hour': 0, 'minute': 0, 'second': 0, 'max_days': 30}
>>> start = datetime(2011, 12, 2, 0, 0, 0)
>>> end = datetime(2012, 1, 1, 0, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'second': 0, 'max_days': 30, 'year': 1, 'day': 30, 'minute': 0}
+ {'year': 1, 'month': 0, 'day': 30, 'hour': 0, 'minute': 0, 'second': 0, 'max_days': 30}
>>> start = datetime(2011, 1, 1, 0, 0, 0)
>>> end = datetime(2011, 2, 1, 0, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 1, 'second': 0, 'max_days': 31, 'year': 0, 'day': 0, 'minute': 0}
+ {'year': 0, 'month': 1, 'day': 0, 'hour': 0, 'minute': 0, 'second': 0, 'max_days': 31}
>>> start = datetime(2011, 12, 1, 0, 0, 0)
>>> end = datetime(2012, 1, 1, 0, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 1, 'second': 0, 'max_days': 31, 'year': 1, 'day': 0, 'minute': 0}
+ {'year': 1, 'month': 1, 'day': 0, 'hour': 0, 'minute': 0, 'second': 0, 'max_days': 31}
>>> start = datetime(2011, 12, 1, 0, 0, 0)
>>> end = datetime(2012, 6, 1, 0, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 6, 'second': 0, 'max_days': 183, 'year': 1, 'day': 0, 'minute': 0}
+ {'year': 1, 'month': 6, 'day': 0, 'hour': 0, 'minute': 0, 'second': 0, 'max_days': 183}
>>> start = datetime(2011, 6, 1, 0, 0, 0)
>>> end = datetime(2021, 6, 1, 0, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 120, 'second': 0, 'max_days': 3653, 'year': 10, 'day': 0, 'minute': 0}
+ {'year': 10, 'month': 120, 'day': 0, 'hour': 0, 'minute': 0, 'second': 0, 'max_days': 3653}
>>> start = datetime(2011, 6, 1, 0, 0, 0)
>>> end = datetime(2012, 6, 1, 12, 0, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 8796, 'month': 12, 'second': 0, 'max_days': 366, 'year': 1, 'day': 0, 'minute': 0}
+ {'year': 1, 'month': 12, 'day': 0, 'hour': 8796, 'minute': 0, 'second': 0, 'max_days': 366}
>>> start = datetime(2011, 6, 1, 0, 0, 0)
>>> end = datetime(2012, 6, 1, 12, 30, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 8796, 'month': 12, 'second': 0, 'max_days': 366, 'year': 1, 'day': 0, 'minute': 527790}
+ {'year': 1, 'month': 12, 'day': 0, 'hour': 8796, 'minute': 527790, 'second': 0, 'max_days': 366}
>>> start = datetime(2011, 6, 1, 0, 0, 0)
>>> end = datetime(2012, 6, 1, 12, 0, 5)
>>> compute_datetime_delta(start, end)
- {'hour': 8796, 'month': 12, 'second': 31665605, 'max_days': 366, 'year': 1, 'day': 0, 'minute': 0}
+ {'year': 1, 'month': 12, 'day': 0, 'hour': 8796, 'minute': 0, 'second': 31665605, 'max_days': 366}
>>> start = datetime(2011, 6, 1, 0, 0, 0)
>>> end = datetime(2012, 6, 1, 0, 30, 0)
>>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 12, 'second': 0, 'max_days': 366, 'year': 1, 'day': 0, 'minute': 527070}
-
- >>> start = datetime(2011, 12, 1, 0, 0, 0)
- >>> end = datetime(2012, 6, 1, 0, 0, 0)
- >>> compute_datetime_delta(start, end)
- {'hour': 0, 'month': 12, 'second': 31622405, 'max_days': 366, 'year': 1, 'day': 0, 'minute': 0}
+ {'year': 1, 'month': 12, 'day': 0, 'hour': 0, 'minute': 527070, 'second': 0, 'max_days': 366}
- :return: A dictionary with year, month, day, hour, minute and second as
- keys()
+ :return: A dictionary with year, month, day, hour, minute, second and max_days as keys()
""" # noqa: E501
- comp = {}
-
- day_diff = (end - start).days
+ # TODO: set default values here, and ensure processing below covers all situations,
+ # not leaking these default values
+ comp = datetime_delta(
+ year=0,
+ month=0,
+ day=0,
+ hour=0,
+ minute=0,
+ second=0,
+ max_days=(end - start).days,
+ )
- comp["max_days"] = day_diff
+ day_diff = comp["max_days"]
# Date
# Count full years
- d = end.year - start.year
- comp["year"] = d
+ comp["year"] = end.year - start.year
# Count full months
if start.month == 1 and end.month == 1:
@@ -644,10 +659,7 @@ def compute_datetime_delta(start, end):
comp["month"] = d
# Count full days
- if start.day == 1 and end.day == 1:
- comp["day"] = 0
- else:
- comp["day"] = day_diff
+ comp["day"] = 0 if start.day == 1 and end.day == 1 else day_diff
# Time
# Hours
@@ -799,7 +811,7 @@ def check_datetime_string(time_string: str, use_dateutil: bool = True):
try:
return datetime.strptime(time_string, time_format)
- except:
+ except (ValueError, TypeError):
return _("Unable to parse time string: %s") % time_string
diff --git a/python/grass/temporal/list_stds.py b/python/grass/temporal/list_stds.py
index 9a62a420930..0153c317053 100644
--- a/python/grass/temporal/list_stds.py
+++ b/python/grass/temporal/list_stds.py
@@ -496,7 +496,7 @@ def list_maps_of_stds(
e.g: start_time < "2001-01-01" and end_time > "2001-01-01"
:param separator: The field separator character between the columns
:param method: String identifier to select a method out of cols,
- comma,delta or deltagaps
+ comma, delta or deltagaps
:param dbif: The database interface to be used
- "cols" Print preselected columns specified by columns
diff --git a/python/grass/temporal/mapcalc.py b/python/grass/temporal/mapcalc.py
index 68b2918170c..51610aedbb1 100644
--- a/python/grass/temporal/mapcalc.py
+++ b/python/grass/temporal/mapcalc.py
@@ -90,7 +90,7 @@ def dataset_mapcalculator(
:param type: The type of the dataset: "raster" or "raster3d"
:param expression: The r(3).mapcalc expression
:param base: The base name of the new created maps in case a
- mapclac expression is provided
+ mapcalc expression is provided
:param method: The method to be used for temporal sampling
:param nprocs: The number of parallel processes to be used for
mapcalc processing
diff --git a/python/grass/temporal/sampling.py b/python/grass/temporal/sampling.py
index 5730901590a..2b7ca0880e9 100644
--- a/python/grass/temporal/sampling.py
+++ b/python/grass/temporal/sampling.py
@@ -49,10 +49,8 @@ def sample_stds_by_stds_topology(
Attention: Do not use the comma as separator for printing
- :param intype: Type of the input space time dataset (strds, stvds or
- str3ds)
- :param sampletype: Type of the sample space time datasets (strds,
- stvds or str3ds)
+ :param intype: Type of the input space time dataset (strds, stvds or str3ds)
+ :param sampletype: Type of the sample space time datasets (strds, stvds or str3ds)
:param inputs: Name or comma separated names of space time datasets or
a list of map names
:param sampler: Name of a space time dataset used for temporal sampling
diff --git a/python/grass/temporal/spatial_extent.py b/python/grass/temporal/spatial_extent.py
index 8154a02805b..fc2a058132d 100644
--- a/python/grass/temporal/spatial_extent.py
+++ b/python/grass/temporal/spatial_extent.py
@@ -1712,8 +1712,7 @@ def set_spatial_extent_from_values(
def set_spatial_extent(self, spatial_extent) -> None:
"""Set the three dimensional spatial extent
- :param spatial_extent: An object of type SpatialExtent or its
- subclasses
+ :param spatial_extent: An object of type SpatialExtent or its subclasses
"""
self.set_north(spatial_extent.get_north())
@@ -1749,8 +1748,7 @@ def set_spatial_extent_from_values_2d(self, north, south, east, west) -> None:
def set_spatial_extent_2d(self, spatial_extent) -> None:
"""Set the three dimensional spatial extent
- :param spatial_extent: An object of type SpatialExtent or its
- subclasses
+ :param spatial_extent: An object of type SpatialExtent or its subclasses
"""
self.set_north(spatial_extent.north)
diff --git a/python/grass/temporal/spatial_topology_dataset_connector.py b/python/grass/temporal/spatial_topology_dataset_connector.py
index 7bd8d836f7b..f7d535e2816 100644
--- a/python/grass/temporal/spatial_topology_dataset_connector.py
+++ b/python/grass/temporal/spatial_topology_dataset_connector.py
@@ -118,31 +118,31 @@ def get_number_of_spatial_relations(self):
relations = {}
try:
relations["equivalent"] = len(self._spatial_topology["EQUIVALENT"])
- except:
+ except KeyError:
relations["equivalent"] = 0
try:
relations["overlap"] = len(self._spatial_topology["OVERLAP"])
- except:
+ except KeyError:
relations["overlap"] = 0
try:
relations["in"] = len(self._spatial_topology["IN"])
- except:
+ except KeyError:
relations["in"] = 0
try:
relations["contain"] = len(self._spatial_topology["CONTAIN"])
- except:
+ except KeyError:
relations["contain"] = 0
try:
relations["meet"] = len(self._spatial_topology["MEET"])
- except:
+ except KeyError:
relations["meet"] = 0
try:
relations["cover"] = len(self._spatial_topology["COVER"])
- except:
+ except KeyError:
relations["cover"] = 0
try:
relations["covered"] = len(self._spatial_topology["COVERED"])
- except:
+ except KeyError:
relations["covered"] = 0
return relations
diff --git a/python/grass/temporal/spatio_temporal_relationships.py b/python/grass/temporal/spatio_temporal_relationships.py
index 25b666e1968..acdbb72a400 100644
--- a/python/grass/temporal/spatio_temporal_relationships.py
+++ b/python/grass/temporal/spatio_temporal_relationships.py
@@ -417,7 +417,7 @@ def _build_internal_iteratable(self, maps, spatial) -> None:
The maps will be added to the object, so they can be
accessed using the iterator of this class
- :param maps: A sorted (by start_time)list of abstract_dataset
+ :param maps: A sorted (by start_time) list of abstract_dataset
objects with initiated temporal extent
"""
self._build_iteratable(maps, spatial)
diff --git a/python/grass/temporal/stds_export.py b/python/grass/temporal/stds_export.py
index c5f546aa3a4..c5a68bb9d88 100644
--- a/python/grass/temporal/stds_export.py
+++ b/python/grass/temporal/stds_export.py
@@ -373,36 +373,31 @@ def export_stds(
# Open the tar archive to add the files
tar = tarfile.open(tmp_tar_file_name, flag)
- list_file = open(list_file_name, "w")
-
fs = "|"
-
- if rows:
- if type_ == "strds":
- if format_ in {"GTiff", "AAIGrid"}:
- _export_raster_maps_as_gdal(
- rows, tar, list_file, new_cwd, fs, format_, datatype, **kwargs
- )
- else:
- _export_raster_maps(rows, tar, list_file, new_cwd, fs)
- elif type_ == "stvds":
- if format_ == "GML":
- _export_vector_maps_as_gml(rows, tar, list_file, new_cwd, fs)
- elif format_ == "GPKG":
- _export_vector_maps_as_gpkg(rows, tar, list_file, new_cwd, fs)
- else:
- _export_vector_maps(rows, tar, list_file, new_cwd, fs)
- elif type_ == "str3ds":
- _export_raster3d_maps(rows, tar, list_file, new_cwd, fs)
-
- list_file.close()
+ with open(list_file_name, "w") as list_file:
+ if rows:
+ if type_ == "strds":
+ if format_ in {"GTiff", "AAIGrid"}:
+ _export_raster_maps_as_gdal(
+ rows, tar, list_file, new_cwd, fs, format_, datatype, **kwargs
+ )
+ else:
+ _export_raster_maps(rows, tar, list_file, new_cwd, fs)
+ elif type_ == "stvds":
+ if format_ == "GML":
+ _export_vector_maps_as_gml(rows, tar, list_file, new_cwd, fs)
+ elif format_ == "GPKG":
+ _export_vector_maps_as_gpkg(rows, tar, list_file, new_cwd, fs)
+ else:
+ _export_vector_maps(rows, tar, list_file, new_cwd, fs)
+ elif type_ == "str3ds":
+ _export_raster3d_maps(rows, tar, list_file, new_cwd, fs)
# Write projection and metadata
proj = gs.read_command("g.proj", flags="j")
Path(proj_file_name).write_text(proj)
- init_file = open(init_file_name, "w")
# Create the init string
string = ""
# This is optional, if not present strds will be assumed for backward
@@ -423,62 +418,66 @@ def export_stds(
string += "%s=%s\n" % ("south", south)
string += "%s=%s\n" % ("east", east)
string += "%s=%s\n" % ("west", west)
- init_file.write(string)
- init_file.close()
+ Path(init_file_name).write_text(string)
metadata = gs.read_command("t.info", type=type_, input=sp.get_id())
Path(metadata_file_name).write_text(metadata)
- read_file = open(read_file_name, "w")
- if type_ == "strds":
+ with open(read_file_name, "w") as read_file:
+ if type_ == "strds":
+ read_file.write(
+ "This space time raster dataset was exported with "
+ "t.rast.export of GRASS GIS 8\n"
+ )
+ elif type_ == "stvds":
+ read_file.write(
+ "This space time vector dataset was exported with "
+ "t.vect.export of GRASS GIS 8\n"
+ )
+ elif type_ == "str3ds":
+ read_file.write(
+ "This space time 3D raster dataset was exported "
+ "with t.rast3d.export of GRASS GIS 8\n"
+ )
+ read_file.write("\n")
+ read_file.write("Files:\n")
+ if type_ == "strds":
+ if format_ == "GTiff":
+ # 123456789012345678901234567890
+ read_file.write(" *.tif -- GeoTIFF raster files\n")
+ read_file.write(" *.color -- GRASS GIS raster color rules\n")
+ elif format_ == "pack":
+ read_file.write(
+ " *.pack -- GRASS raster files packed with r.pack\n"
+ )
+ elif type_ == "stvds":
+ # 123456789012345678901234567890
+ if format_ == "GML":
+ read_file.write(" *.xml -- Vector GML files\n")
+ else:
+ read_file.write(
+ " *.pack -- GRASS vector files packed with v.pack\n"
+ )
+ elif type_ == "str3ds":
+ read_file.write(
+ " *.pack -- GRASS 3D raster files packed with r3.pack\n"
+ )
read_file.write(
- "This space time raster dataset was exported with "
- "t.rast.export of GRASS GIS 8\n"
+ "%13s -- Projection information in PROJ.4 format\n" % (proj_file_name)
)
- elif type_ == "stvds":
read_file.write(
- "This space time vector dataset was exported with "
- "t.vect.export of GRASS GIS 8\n"
+ "%13s -- GRASS GIS space time %s dataset information\n"
+ % (init_file_name, sp.get_new_map_instance(None).get_type())
)
- elif type_ == "str3ds":
read_file.write(
- "This space time 3D raster dataset was exported "
- "with t.rast3d.export of GRASS GIS 8\n"
+ "%13s -- Time series file, lists all maps by name "
+ "with interval\n" % (list_file_name)
)
- read_file.write("\n")
- read_file.write("Files:\n")
- if type_ == "strds":
- if format_ == "GTiff":
- # 123456789012345678901234567890
- read_file.write(" *.tif -- GeoTIFF raster files\n")
- read_file.write(" *.color -- GRASS GIS raster color rules\n")
- elif format_ == "pack":
- read_file.write(" *.pack -- GRASS raster files packed with r.pack\n")
- elif type_ == "stvds":
- # 123456789012345678901234567890
- if format_ == "GML":
- read_file.write(" *.xml -- Vector GML files\n")
- else:
- read_file.write(" *.pack -- GRASS vector files packed with v.pack\n")
- elif type_ == "str3ds":
- read_file.write(" *.pack -- GRASS 3D raster files packed with r3.pack\n")
- read_file.write(
- "%13s -- Projection information in PROJ.4 format\n" % (proj_file_name)
- )
- read_file.write(
- "%13s -- GRASS GIS space time %s dataset information\n"
- % (init_file_name, sp.get_new_map_instance(None).get_type())
- )
- read_file.write(
- "%13s -- Time series file, lists all maps by name "
- "with interval\n" % (list_file_name)
- )
- read_file.write(
- " time stamps in ISO-Format. Field separator is |\n"
- )
- read_file.write("%13s -- The output of t.info\n" % (metadata_file_name))
- read_file.write("%13s -- This file\n" % (read_file_name))
- read_file.close()
+ read_file.write(
+ " time stamps in ISO-Format. Field separator is |\n"
+ )
+ read_file.write("%13s -- The output of t.info\n" % (metadata_file_name))
+ read_file.write("%13s -- This file\n" % (read_file_name))
# Append the file list
tar.add(list_file_name)
diff --git a/python/grass/temporal/stds_import.py b/python/grass/temporal/stds_import.py
index 6cf64ac6012..d401aceea55 100644
--- a/python/grass/temporal/stds_import.py
+++ b/python/grass/temporal/stds_import.py
@@ -230,8 +230,7 @@ def import_stds(
:param output: The name of the output space time dataset
:param directory: The extraction directory
:param title: The title of the new created space time dataset
- :param descr: The description of the new created
- space time dataset
+ :param descr: The description of the new created space time dataset
:param location: The name of the location that should be created,
maps are imported into this location
:param link: Switch to link raster maps instead importing them
@@ -240,8 +239,7 @@ def import_stds(
:param create: Create the location specified by the "location"
parameter and exit.
Do not import the space time datasets.
- :param stds_type: The type of the space time dataset that
- should be imported
+ :param stds_type: The type of the space time dataset that should be imported
:param base: The base name of the new imported maps, it will be
extended using a numerical index.
:param memory: Cache size for raster rows, used in r.in.gdal
@@ -301,7 +299,6 @@ def import_stds(
# Check projection information
if not location:
temp_name = gs.tempfile()
- temp_file = open(temp_name, "w")
proj_name = os.path.abspath(proj_file_name)
# We need to convert projection strings generated
@@ -315,9 +312,9 @@ def import_stds(
proj_name_tmp = f"{temp_name}_in_projection"
Path(proj_name_tmp).write_text(proj_content)
- p = gs.start_command("g.proj", flags="j", stdout=temp_file)
- p.communicate()
- temp_file.close()
+ with open(temp_name, "w") as temp_file:
+ p = gs.start_command("g.proj", flags="j", stdout=temp_file)
+ p.communicate()
if not gs.compare_key_value_text_files(temp_name, proj_name_tmp, sep="="):
if overr:
diff --git a/python/grass/temporal/temporal_algebra.py b/python/grass/temporal/temporal_algebra.py
index 6c110205d3c..9c33faa98f3 100644
--- a/python/grass/temporal/temporal_algebra.py
+++ b/python/grass/temporal/temporal_algebra.py
@@ -445,7 +445,7 @@
try:
from ply import lex, yacc
-except:
+except ImportError:
pass
import copy
@@ -2857,7 +2857,7 @@ def p_t_var_expr_td_hash(self, t) -> None:
map_i.condition_value.append(boolname)
else:
map_i.condition_value = boolname
- except:
+ except (IndexError, AttributeError, SyntaxError):
self.msgr.fatal(
"Error: the given expression does not contain a correct time "
"difference object."
diff --git a/python/grass/temporal/temporal_granularity.py b/python/grass/temporal/temporal_granularity.py
index 537868eee31..830950e40b2 100644
--- a/python/grass/temporal/temporal_granularity.py
+++ b/python/grass/temporal/temporal_granularity.py
@@ -90,19 +90,19 @@ def check_granularity_string(granularity, temporal_type) -> bool:
if temporal_type == "absolute":
try:
num, unit = granularity.split(" ")
- except:
+ except (ValueError, AttributeError):
return False
if unit not in SUPPORTED_GRAN:
return False
try:
int(num)
- except:
+ except ValueError:
return False
elif temporal_type == "relative":
try:
int(granularity)
- except:
+ except ValueError:
return False
else:
return False
diff --git a/python/grass/temporal/temporal_raster_base_algebra.py b/python/grass/temporal/temporal_raster_base_algebra.py
index b533d96e6f6..1bd3ff7cc46 100644
--- a/python/grass/temporal/temporal_raster_base_algebra.py
+++ b/python/grass/temporal/temporal_raster_base_algebra.py
@@ -227,9 +227,9 @@ def build_spatio_temporal_topology_list(
:param count_map: Boolean if the number of topological related maps
should be returned.
:param compare_bool: Boolean for comparing boolean map values based on
- related map list and compariosn operator.
+ related map list and comparison operator.
:param compare_cmd: Boolean for comparing command list values based on
- related map list and compariosn operator.
+ related map list and comparison operator.
:param compop: Comparison operator, && or ||.
:param aggregate: Aggregation operator for relation map list, & or |.
:param new: Boolean if new temporary maps should be created.
diff --git a/python/grass/temporal/temporal_vector_algebra.py b/python/grass/temporal/temporal_vector_algebra.py
index 1cf981324f2..8f511a21197 100644
--- a/python/grass/temporal/temporal_vector_algebra.py
+++ b/python/grass/temporal/temporal_vector_algebra.py
@@ -297,7 +297,7 @@ def overlay_cmd_value(self, map_i, tbrelations, function, topolist=["EQUAL"]):
:param function: Overlay operator, &|+^~.
:return: Map object with command list with operators that has been
- evaluated by implicit aggregration.
+ evaluated by implicit aggregation.
"""
# Build comandlist list with elements from related maps and given relation
# operator.
diff --git a/python/grass/temporal/tests/test_datetime_math_compute_datetime_delta_test.py b/python/grass/temporal/tests/test_datetime_math_compute_datetime_delta_test.py
new file mode 100644
index 00000000000..dbcbaa2830f
--- /dev/null
+++ b/python/grass/temporal/tests/test_datetime_math_compute_datetime_delta_test.py
@@ -0,0 +1,289 @@
+from datetime import datetime
+from grass.temporal.datetime_math import compute_datetime_delta, datetime_delta
+
+
+def test_datetime_delta_typeddict_dict() -> None:
+ assert datetime_delta(
+ month=3, day=2, minute=5, year=1, hour=8, max_days=455, second=30
+ ) == dict( # noqa: C408
+ month=3, day=2, minute=5, year=1, hour=8, max_days=455, second=30
+ )
+
+
+def test_datetime_delta_typeddict_dict_literal() -> None:
+ assert datetime_delta(
+ month=3, day=2, minute=5, year=1, hour=8, max_days=455, second=30
+ ) == {
+ "month": 3,
+ "day": 2,
+ "minute": 5,
+ "year": 1,
+ "hour": 8,
+ "max_days": 455,
+ "second": 30,
+ }
+
+
+def test_datetime_delta_typeddict_dict_different_order() -> None:
+ assert datetime_delta(
+ month=3, day=2, minute=5, year=1, hour=8, max_days=455, second=30
+ ) == {
+ "max_days": 455,
+ "month": 3,
+ "minute": 5,
+ "year": 1,
+ "day": 2,
+ "hour": 8,
+ "second": 30,
+ }
+
+
+def test_datetime_delta_typeddict_typeddict_different_order() -> None:
+ assert datetime_delta(
+ year=1,
+ month=3,
+ day=2,
+ hour=8,
+ minute=5,
+ second=30,
+ max_days=455,
+ ) == datetime_delta(
+ month=3,
+ day=2,
+ minute=5,
+ year=1,
+ hour=8,
+ max_days=455,
+ second=30,
+ )
+
+
+def test_datetime_delta_typeddict_dict_missing() -> None:
+ assert datetime_delta(
+ month=3, day=2, minute=5, year=1, hour=8, max_days=455, second=30
+ ) != {"month": 3, "day": 2, "minute": 5, "hour": 8, "max_days": 455}
+
+
+def test_compute_datetime_delta_same_date() -> None:
+ start = datetime(2001, 1, 1, 0, 0, 0)
+ end = datetime(2001, 1, 1, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=0, minute=0, second=0, max_days=0
+ )
+
+
+def test_compute_datetime_delta_seconds_only() -> None:
+ start = datetime(2001, 1, 1, 0, 0, 14)
+ end = datetime(2001, 1, 1, 0, 0, 44)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=0, minute=0, second=30, max_days=0
+ )
+
+
+def test_compute_datetime_delta_minute_seconds() -> None:
+ start = datetime(2001, 1, 1, 0, 0, 44)
+ end = datetime(2001, 1, 1, 0, 1, 14)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=0, minute=1, second=30, max_days=0
+ )
+
+
+def test_compute_datetime_delta_minutes_seconds_same() -> None:
+ start = datetime(2001, 1, 1, 0, 0, 30)
+ end = datetime(2001, 1, 1, 0, 5, 30)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=0, minute=5, second=300, max_days=0
+ )
+
+
+def test_compute_datetime_delta_minute_only() -> None:
+ start = datetime(2001, 1, 1, 0, 0, 0)
+ end = datetime(2001, 1, 1, 0, 1, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=0, minute=1, second=0, max_days=0
+ )
+
+
+def test_compute_datetime_delta_hour_minutes_same() -> None:
+ start = datetime(2011, 10, 31, 0, 45, 0)
+ end = datetime(2011, 10, 31, 1, 45, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=1, minute=60, second=0, max_days=0
+ )
+
+
+def test_compute_datetime_delta_hour_minutes() -> None:
+ start = datetime(2011, 10, 31, 0, 45, 0)
+ end = datetime(2011, 10, 31, 1, 15, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=1, minute=30, second=0, max_days=0
+ )
+
+
+def test_compute_datetime_delta_hours_minutes() -> None:
+ start = datetime(2011, 10, 31, 0, 45, 0)
+ end = datetime(2011, 10, 31, 12, 15, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=12, minute=690, second=0, max_days=0
+ )
+
+
+def test_compute_datetime_delta_hour_only() -> None:
+ start = datetime(2011, 10, 31, 0, 0, 0)
+ end = datetime(2011, 10, 31, 1, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=1, minute=0, second=0, max_days=0
+ )
+
+
+def test_compute_datetime_delta_month_day_hour() -> None:
+ start = datetime(2011, 10, 31, 0, 0, 0)
+ end = datetime(2011, 11, 1, 1, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=1, hour=25, minute=0, second=0, max_days=1
+ )
+
+
+def test_compute_datetime_delta_month_day_hours() -> None:
+ start = datetime(2011, 10, 31, 12, 0, 0)
+ end = datetime(2011, 11, 1, 6, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=0, hour=18, minute=0, second=0, max_days=0
+ )
+
+
+def test_compute_datetime_delta_month_hour() -> None:
+ start = datetime(2011, 11, 1, 0, 0, 0)
+ end = datetime(2011, 12, 1, 1, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=1, day=0, hour=721, minute=0, second=0, max_days=30
+ )
+
+
+def test_compute_datetime_delta_days_only() -> None:
+ start = datetime(2011, 11, 1, 0, 0, 0)
+ end = datetime(2011, 11, 5, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=4, hour=0, minute=0, second=0, max_days=4
+ )
+
+
+def test_compute_datetime_delta_month_days_less_than_month() -> None:
+ start = datetime(2011, 10, 6, 0, 0, 0)
+ end = datetime(2011, 11, 5, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=30, hour=0, minute=0, second=0, max_days=30
+ )
+
+
+def test_compute_datetime_delta_year_month_days_less_than_month() -> None:
+ start = datetime(2011, 12, 2, 0, 0, 0)
+ end = datetime(2012, 1, 1, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=1, month=0, day=30, hour=0, minute=0, second=0, max_days=30
+ )
+
+
+def test_compute_datetime_delta_month_only() -> None:
+ start = datetime(2011, 1, 1, 0, 0, 0)
+ end = datetime(2011, 2, 1, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=1, day=0, hour=0, minute=0, second=0, max_days=31
+ )
+
+
+def test_compute_datetime_delta_year_month() -> None:
+ start = datetime(2011, 12, 1, 0, 0, 0)
+ end = datetime(2012, 1, 1, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=1, month=1, day=0, hour=0, minute=0, second=0, max_days=31
+ )
+
+
+def test_compute_datetime_delta_year_months() -> None:
+ start = datetime(2011, 12, 1, 0, 0, 0)
+ end = datetime(2012, 6, 1, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=1, month=6, day=0, hour=0, minute=0, second=0, max_days=183
+ )
+
+
+def test_compute_datetime_delta_years_only() -> None:
+ start = datetime(2011, 6, 1, 0, 0, 0)
+ end = datetime(2021, 6, 1, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=10, month=120, day=0, hour=0, minute=0, second=0, max_days=3653
+ )
+
+
+def test_compute_datetime_delta_year_hours() -> None:
+ start = datetime(2011, 6, 1, 0, 0, 0)
+ end = datetime(2012, 6, 1, 12, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=1, month=12, day=0, hour=8796, minute=0, second=0, max_days=366
+ )
+
+
+def test_compute_datetime_delta_year_hours_minutes() -> None:
+ start = datetime(2011, 6, 1, 0, 0, 0)
+ end = datetime(2012, 6, 1, 12, 30, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=1, month=12, day=0, hour=8796, minute=527790, second=0, max_days=366
+ )
+
+
+def test_compute_datetime_delta_year_hours_seconds() -> None:
+ start = datetime(2011, 6, 1, 0, 0, 0)
+ end = datetime(2012, 6, 1, 12, 0, 5)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=1, month=12, day=0, hour=8796, minute=0, second=31665605, max_days=366
+ )
+
+
+def test_compute_datetime_delta_year_minutes() -> None:
+ start = datetime(2011, 6, 1, 0, 0, 0)
+ end = datetime(2012, 6, 1, 0, 30, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=1, month=12, day=0, hour=0, minute=527070, second=0, max_days=366
+ )
+
+
+def test_compute_datetime_delta_year_seconds() -> None:
+ start = datetime(2011, 6, 1, 0, 0, 0)
+ end = datetime(2012, 6, 1, 0, 0, 5)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=1, month=12, day=0, hour=0, minute=0, second=31622405, max_days=366
+ )
+
+
+def test_compute_datetime_delta_month_full() -> None:
+ start = datetime(2011, 7, 3, 0, 0, 0)
+ end = datetime(2011, 8, 2, 0, 0, 0)
+ comp: datetime_delta = compute_datetime_delta(start, end)
+ assert comp == datetime_delta(
+ year=0, month=0, day=30, hour=0, minute=0, second=0, max_days=30
+ )
diff --git a/python/grass/temporal/unit_tests.py b/python/grass/temporal/unit_tests.py
index 8275e012f25..63ff4a0778d 100644
--- a/python/grass/temporal/unit_tests.py
+++ b/python/grass/temporal/unit_tests.py
@@ -21,7 +21,7 @@
AbstractDatasetComparisonKeyStartTime,
)
from .core import init
-from .datetime_math import compute_datetime_delta, increment_datetime_by_string
+from .datetime_math import increment_datetime_by_string
from .space_time_datasets import RasterDataset
from .spatial_extent import SpatialExtent
from .spatio_temporal_relationships import SpatioTemporalTopologyBuilder
@@ -223,349 +223,6 @@ def test_adjust_datetime_to_granularity() -> None:
###############################################################################
-def test_compute_datetime_delta() -> None:
- print("Test 1")
- start = datetime(2001, 1, 1, 0, 0, 0)
- end = datetime(2001, 1, 1, 0, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["second"]
- correct = 0
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 2")
- start = datetime(2001, 1, 1, 0, 0, 14)
- end = datetime(2001, 1, 1, 0, 0, 44)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["second"]
- correct = 30
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 3")
- start = datetime(2001, 1, 1, 0, 0, 44)
- end = datetime(2001, 1, 1, 0, 1, 14)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["second"]
- correct = 30
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 4")
- start = datetime(2001, 1, 1, 0, 0, 30)
- end = datetime(2001, 1, 1, 0, 5, 30)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["second"]
- correct = 300
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 5")
- start = datetime(2001, 1, 1, 0, 0, 0)
- end = datetime(2001, 1, 1, 0, 1, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["minute"]
- correct = 1
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 6")
- start = datetime(2011, 10, 31, 0, 45, 0)
- end = datetime(2011, 10, 31, 1, 45, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["minute"]
- correct = 60
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 7")
- start = datetime(2011, 10, 31, 0, 45, 0)
- end = datetime(2011, 10, 31, 1, 15, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["minute"]
- correct = 30
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 8")
- start = datetime(2011, 10, 31, 0, 45, 0)
- end = datetime(2011, 10, 31, 12, 15, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["minute"]
- correct = 690
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 9")
- start = datetime(2011, 10, 31, 0, 0, 0)
- end = datetime(2011, 10, 31, 1, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["hour"]
- correct = 1
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 10")
- start = datetime(2011, 10, 31, 0, 0, 0)
- end = datetime(2011, 11, 1, 1, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["hour"]
- correct = 25
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 11")
- start = datetime(2011, 10, 31, 12, 0, 0)
- end = datetime(2011, 11, 1, 6, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["hour"]
- correct = 18
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 12")
- start = datetime(2011, 11, 1, 0, 0, 0)
- end = datetime(2011, 12, 1, 1, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["hour"]
- correct = 30 * 24 + 1
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 13")
- start = datetime(2011, 11, 1, 0, 0, 0)
- end = datetime(2011, 11, 5, 0, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["day"]
- correct = 4
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 14")
- start = datetime(2011, 10, 6, 0, 0, 0)
- end = datetime(2011, 11, 5, 0, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["day"]
- correct = 30
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 15")
- start = datetime(2011, 12, 2, 0, 0, 0)
- end = datetime(2012, 1, 1, 0, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["day"]
- correct = 30
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 16")
- start = datetime(2011, 1, 1, 0, 0, 0)
- end = datetime(2011, 2, 1, 0, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["month"]
- correct = 1
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 17")
- start = datetime(2011, 12, 1, 0, 0, 0)
- end = datetime(2012, 1, 1, 0, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["month"]
- correct = 1
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 18")
- start = datetime(2011, 12, 1, 0, 0, 0)
- end = datetime(2012, 6, 1, 0, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["month"]
- correct = 6
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 19")
- start = datetime(2011, 6, 1, 0, 0, 0)
- end = datetime(2021, 6, 1, 0, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["year"]
- correct = 10
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 20")
- start = datetime(2011, 6, 1, 0, 0, 0)
- end = datetime(2012, 6, 1, 12, 0, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["hour"]
- d = end - start
- correct = 12 + d.days * 24
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 21")
- start = datetime(2011, 6, 1, 0, 0, 0)
- end = datetime(2012, 6, 1, 12, 30, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["minute"]
- d = end - start
- correct = d.days * 24 * 60 + 12 * 60 + 30
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 22")
- start = datetime(2011, 6, 1, 0, 0, 0)
- end = datetime(2012, 6, 1, 12, 0, 5)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["second"]
- d = end - start
- correct = 5 + 60 * 60 * 12 + d.days * 24 * 60 * 60
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 23")
- start = datetime(2011, 6, 1, 0, 0, 0)
- end = datetime(2012, 6, 1, 0, 30, 0)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["minute"]
- d = end - start
- correct = 30 + d.days * 24 * 60
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
- print("Test 24")
- start = datetime(2011, 6, 1, 0, 0, 0)
- end = datetime(2012, 6, 1, 0, 0, 5)
-
- comp = compute_datetime_delta(start, end)
-
- result = comp["second"]
- d = end - start
- correct = 5 + d.days * 24 * 60 * 60
-
- delta = correct - result
-
- if delta != 0:
- core.fatal("Compute datetime delta is wrong %s" % (delta))
-
-
def test_compute_absolute_time_granularity() -> None:
# First we test intervals
print("Test 1")
@@ -1669,7 +1326,6 @@ def test_4d_rtree() -> None:
test_adjust_datetime_to_granularity()
test_spatial_extent_intersection()
test_compute_absolute_time_granularity()
- test_compute_datetime_delta()
test_spatial_extent_intersection()
test_spatial_relations()
test_temporal_topology_builder()
diff --git a/raster/r.info/main.c b/raster/r.info/main.c
index ed06f72eba7..ad40ea6b3e9 100644
--- a/raster/r.info/main.c
+++ b/raster/r.info/main.c
@@ -40,6 +40,7 @@ enum OutputFormat { PLAIN, JSON };
/* local prototypes */
static void format_double(const double, char *);
static void compose_line(FILE *, const char *, ...);
+static char *history_as_string(struct History *hist);
int main(int argc, char **argv)
{
@@ -773,16 +774,14 @@ int main(int argc, char **argv)
json_object_set_string(
root_object, "description",
Rast_get_history(&hist, HIST_KEYWRD));
- JSON_Value *comments_value = json_value_init_array();
- JSON_Array *comments = json_array(comments_value);
- if (Rast_history_length(&hist)) {
- for (i = 0; i < Rast_history_length(&hist); i++) {
- json_array_append_string(
- comments, Rast_history_line(&hist, i));
- }
+ char *buffer = history_as_string(&hist);
+ if (buffer) {
+ json_object_set_string(root_object, "comments", buffer);
+ G_free(buffer);
+ }
+ else {
+ json_object_set_null(root_object, "comments");
}
- json_object_set_value(root_object, "comments",
- comments_value);
}
else {
json_object_set_null(root_object, "source1");
@@ -794,7 +793,7 @@ int main(int argc, char **argv)
}
}
- if (hflag->answer || format == JSON) {
+ if (hflag->answer) {
if (hist_ok) {
switch (format) {
case PLAIN:
@@ -823,16 +822,15 @@ int main(int argc, char **argv)
json_object_set_string(
root_object, "description",
Rast_get_history(&hist, HIST_KEYWRD));
- JSON_Value *comments_value = json_value_init_array();
- JSON_Array *comments = json_array(comments_value);
- if (Rast_history_length(&hist)) {
- for (i = 0; i < Rast_history_length(&hist); i++) {
- json_array_append_string(
- comments, Rast_history_line(&hist, i));
- }
+ char *buffer = history_as_string(&hist);
+ if (buffer) {
+ json_object_set_string(root_object, "comments", buffer);
+ G_free(buffer);
+ }
+ else {
+ json_object_set_null(root_object, "comments");
}
- json_object_set_value(root_object, "comments",
- comments_value);
+
break;
}
}
@@ -874,3 +872,46 @@ static void compose_line(FILE *out, const char *fmt, ...)
printline(line);
G_free(line);
}
+
+static char *history_as_string(struct History *hist)
+{
+ int history_length = Rast_history_length(hist);
+ char *buffer = NULL;
+ if (history_length) {
+ size_t buffer_size = 0;
+ size_t total_length = 0;
+ for (int i = 0; i < history_length; i++) {
+ const char *line = Rast_history_line(hist, i);
+ size_t line_length = strlen(line);
+
+ // +1 for the null character
+ size_t required_size = total_length + line_length + 1;
+ if (required_size > buffer_size) {
+ // This is heuristic for reallocation based on remaining
+ // iterations and current size which is a good estimate for the
+ // first iteration and possible overshoot later on reducing the
+ // number of reallocations.
+ buffer_size = required_size * (history_length - i);
+ buffer = (char *)G_realloc(buffer, buffer_size);
+ if (total_length == 0)
+ buffer[0] = '\0';
+ }
+ if (line_length >= 1 && line[line_length - 1] == '\\') {
+ // Ending backslash is line continuation.
+ strncat(buffer, line, line_length - 1);
+ total_length += line_length - 1;
+ }
+ else {
+ strncat(buffer, line, line_length);
+ total_length += line_length;
+ if (i < history_length - 1) {
+ // Add newline to separate lines, but don't and newline at
+ // the end of last (or only) line.
+ strcat(buffer, "\n");
+ ++total_length;
+ }
+ }
+ }
+ }
+ return buffer;
+}
diff --git a/raster/r.info/testsuite/test_r_info.py b/raster/r.info/testsuite/test_r_info.py
index 49f91a5723f..a793c5ab2ae 100644
--- a/raster/r.info/testsuite/test_r_info.py
+++ b/raster/r.info/testsuite/test_r_info.py
@@ -47,7 +47,7 @@ def setUpClass(cls):
"source1": "",
"source2": "",
"description": "generated by r.mapcalc",
- "comments": ["1 * lakes_large"],
+ "comments": "1 * lakes_large",
}
@classmethod
@@ -136,6 +136,51 @@ def test_sflag_format_json(self):
self._test_format_json_helper(module, expected_json_with_stats)
+class TestComments(TestCase):
+ """Check printing of comments"""
+
+ def test_comments_one_line(self):
+ """Check that one line is text without any newlines"""
+ module = SimpleModule("r.info", map="lakes", format="json")
+ self.runModule(module)
+ result = json.loads(module.outputs.stdout)
+ self.assertFalse(result["comments"].endswith("\n"))
+ self.assertEqual(result["comments"], "1 * lakes_large")
+
+ def test_comments_continued_line(self):
+ """Check that continued lines are merged"""
+ module = SimpleModule("r.info", map="elevation", format="json")
+ self.runModule(module)
+ result = json.loads(module.outputs.stdout)
+ self.assertFalse(result["comments"].endswith("\n"))
+ self.assertEqual(
+ result["comments"],
+ 'r.proj input="ned03arcsec" location="northcarolina_latlong" '
+ 'mapset="helena" output="elev_ned10m" method="cubic" resolution=10',
+ )
+
+ def test_comments_multiple_lines(self):
+ """Check multiple lines are preserved"""
+ module = SimpleModule("r.info", map="lsat7_2002_30", format="json")
+ self.runModule(module)
+ result = json.loads(module.outputs.stdout)
+ self.assertFalse(result["comments"].endswith("\n"))
+
+ lines = result["comments"].splitlines()
+ self.assertEqual(
+ len(lines),
+ 31,
+ )
+ self.assertEqual(
+ lines[0],
+ 'r.in.gdal input="p016r035_7t20020524_z17_nn30_nc_spm_wake.tif" output="lsat7_2002_30"',
+ )
+ self.assertEqual(
+ lines[-1],
+ 'i.landsat.rgb "b=lsat7_2002_10" "g=lsat7_2002_20" "r=lsat7_2002_30"',
+ )
+
+
if __name__ == "__main__":
from grass.gunittest.main import test
diff --git a/raster/r.path/main.c b/raster/r.path/main.c
index 5edcdfa1d95..eee5c33b97a 100644
--- a/raster/r.path/main.c
+++ b/raster/r.path/main.c
@@ -122,6 +122,8 @@ int main(int argc, char **argv)
struct Option *vect;
} opt;
struct {
+ struct Flag *east;
+ struct Flag *brk;
struct Flag *copy;
struct Flag *accum;
struct Flag *count;
@@ -196,6 +198,18 @@ int main(int argc, char **argv)
opt.vpoint->label = _("Name of starting vector points map(s)");
opt.vpoint->guisection = _("Start");
+ flag.east = G_define_flag();
+ flag.east->key = 'e';
+ flag.east->description =
+ _("Start bitmask encoded directions from East (e.g., r.terraflow)");
+ flag.east->guisection = _("Direction settings");
+
+ flag.brk = G_define_flag();
+ flag.brk->key = 'b';
+ flag.brk->description =
+ _("Do not break lines (faster for single-direction bitmask encoding)");
+ flag.brk->guisection = _("Direction settings");
+
flag.copy = G_define_flag();
flag.copy->key = 'c';
flag.copy->description = _("Copy input cell values on output");
@@ -216,6 +230,7 @@ int main(int argc, char **argv)
G_option_requires_all(flag.copy, opt.rast, opt.val, NULL);
G_option_requires_all(flag.accum, opt.rast, opt.val, NULL);
G_option_requires_all(flag.count, opt.rast, NULL);
+ G_option_requires(flag.brk, opt.vect, NULL);
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
@@ -457,6 +472,13 @@ int main(int argc, char **argv)
dir_buf = Rast_allocate_c_buf();
for (i = 0; i < nrows; i++) {
Rast_get_c_row(dir_id, dir_buf, i);
+ if (flag.east->answer) {
+ CELL *p;
+
+ p = (CELL *)dir_buf;
+ for (j = 0; j < ncols; j++, p++)
+ *p = pow(2, ((int)log2(*p) + 1) % 8);
+ }
if (write(dir_fd, dir_buf, ncols * sizeof(CELL)) !=
ncols * (int)sizeof(CELL)) {
G_fatal_error(_("Unable to write to tempfile"));
@@ -503,7 +525,7 @@ int main(int argc, char **argv)
if (dir_format == DIR_BIT) {
struct Map_info Tmp;
- if (pvout) {
+ if (!flag.brk->answer && pvout) {
if (Vect_open_tmp_new(&Tmp, NULL, 0) < 0)
G_fatal_error(_("Unable to create temporary vector map"));
pvout = &Tmp;
@@ -514,7 +536,7 @@ int main(int argc, char **argv)
G_warning(_("No path at row %d, col %d"), next_start_pt->row,
next_start_pt->col);
}
- if (pvout) {
+ if (!flag.brk->answer && pvout) {
Vect_build_partial(&Tmp, GV_BUILD_BASE);
G_message(_("Breaking lines..."));
Vect_break_lines(&Tmp, GV_LINE, NULL);
@@ -711,8 +733,8 @@ int dir_bitmask(int dir_fd, int val_fd, struct point *startp,
struct ppoint pp;
int is_stack;
int cur_dir, i, npaths;
- struct line_pnts *Points;
- struct line_cats *Cats;
+ struct line_pnts *Points = NULL;
+ struct line_cats *Cats = NULL;
double x, y;
double value;
diff --git a/raster3d/r3.out.v5d/main.c b/raster3d/r3.out.v5d/main.c
index 7d47041996b..681a24a2e65 100644
--- a/raster3d/r3.out.v5d/main.c
+++ b/raster3d/r3.out.v5d/main.c
@@ -262,6 +262,7 @@ void convert(char *fileout, int rows, int cols, int depths, int trueCoords)
/* Close the v5d file */
v5dClose();
+ G_free(g);
}
/*---------------------------------------------------------------------------*/
diff --git a/temporal/t.rast.what/t.rast.what.py b/temporal/t.rast.what/t.rast.what.py
index 24190a6a716..32a719fa4f5 100755
--- a/temporal/t.rast.what/t.rast.what.py
+++ b/temporal/t.rast.what/t.rast.what.py
@@ -105,6 +105,7 @@
import copy
import sys
+from contextlib import nullcontext
import grass.script as gs
@@ -357,75 +358,71 @@ def one_point_per_row_output(
output is of type: x,y,start,end,value
"""
# open the output file for writing
- out_file = open(output, "w") if output != "-" else sys.stdout
-
- if write_header is True:
- out_str = ""
- if vcat:
- out_str += "cat{sep}"
- if site_input:
- out_str += "x{sep}y{sep}site{sep}start{sep}end{sep}value\n"
- else:
- out_str += "x{sep}y{sep}start{sep}end{sep}value\n"
- out_file.write(out_str.format(sep=separator))
-
- for count in range(len(output_files)):
- file_name = output_files[count]
- gs.verbose(_("Transforming r.what output file %s") % (file_name))
- map_list = output_time_list[count]
- in_file = open(file_name)
- for line in in_file:
- line = line.split(separator)
+ with open(output, "w") if output != "-" else nullcontext(sys.stdout) as out_file:
+ if write_header is True:
+ out_str = ""
if vcat:
- cat = line[0]
- x = line[1]
- y = line[2]
- values = line[4:]
- if site_input:
- site = line[3]
- values = line[5:]
-
+ out_str += "cat{sep}"
+ if site_input:
+ out_str += "x{sep}y{sep}site{sep}start{sep}end{sep}value\n"
else:
- x = line[0]
- y = line[1]
- if site_input:
- site = line[2]
- values = line[3:]
+ out_str += "x{sep}y{sep}start{sep}end{sep}value\n"
+ out_file.write(out_str.format(sep=separator))
+
+ for count in range(len(output_files)):
+ file_name = output_files[count]
+ gs.verbose(_("Transforming r.what output file %s") % (file_name))
+ map_list = output_time_list[count]
+ with open(file_name) as in_file:
+ for line in in_file:
+ line = line.split(separator)
+ if vcat:
+ cat = line[0]
+ x = line[1]
+ y = line[2]
+ values = line[4:]
+ if site_input:
+ site = line[3]
+ values = line[5:]
- for i in range(len(values)):
- start, end = map_list[i].get_temporal_extent_as_tuple()
- cat_str = "{ca}{sep}".format(ca=cat, sep=separator) if vcat else ""
- if site_input:
- coor_string = (
- "%(x)10.10f%(sep)s%(y)10.10f%(sep)s%(site_name)s%(sep)s"
- % (
+ else:
+ x = line[0]
+ y = line[1]
+ if site_input:
+ site = line[2]
+ values = line[3:]
+
+ for i in range(len(values)):
+ start, end = map_list[i].get_temporal_extent_as_tuple()
+ cat_str = (
+ "{ca}{sep}".format(ca=cat, sep=separator) if vcat else ""
+ )
+ if site_input:
+ coor_string = (
+ "%(x)10.10f%(sep)s%(y)10.10f%(sep)s%(site_name)s%(sep)s"
+ % (
+ {
+ "x": float(x),
+ "y": float(y),
+ "site_name": str(site),
+ "sep": separator,
+ }
+ )
+ )
+ else:
+ coor_string = "%(x)10.10f%(sep)s%(y)10.10f%(sep)s" % (
+ {"x": float(x), "y": float(y), "sep": separator}
+ )
+ time_string = "%(start)s%(sep)s%(end)s%(sep)s%(val)s\n" % (
{
- "x": float(x),
- "y": float(y),
- "site_name": str(site),
+ "start": str(start),
+ "end": str(end),
+ "val": (values[i].strip()),
"sep": separator,
}
)
- )
- else:
- coor_string = "%(x)10.10f%(sep)s%(y)10.10f%(sep)s" % (
- {"x": float(x), "y": float(y), "sep": separator}
- )
- time_string = "%(start)s%(sep)s%(end)s%(sep)s%(val)s\n" % (
- {
- "start": str(start),
- "end": str(end),
- "val": (values[i].strip()),
- "sep": separator,
- }
- )
-
- out_file.write(cat_str + coor_string + time_string)
-
- in_file.close()
- if out_file is not sys.stdout:
- out_file.close()
+ out_file.write(cat_str + coor_string + time_string)
############################################################################
@@ -441,77 +438,74 @@ def one_point_per_col_output(
Each row represents a single raster map, hence a single time stamp
"""
# open the output file for writing
- out_file = open(output, "w") if output != "-" else sys.stdout
first = True
- for count in range(len(output_files)):
- file_name = output_files[count]
- gs.verbose(_("Transforming r.what output file %s") % (file_name))
- in_file = open(file_name)
- lines = in_file.readlines()
-
- matrix = []
- for line in lines:
- matrix.append(line.split(separator))
+ with open(output, "w") if output != "-" else nullcontext(sys.stdout) as out_file:
+ for count in range(len(output_files)):
+ file_name = output_files[count]
+ gs.verbose(_("Transforming r.what output file %s") % (file_name))
+ with open(file_name) as in_file:
+ lines = in_file.readlines()
- num_cols = len(matrix[0])
+ matrix = []
+ for line in lines:
+ matrix.append(line.split(separator))
- if first is True:
- if write_header is True:
- out_str = "start%(sep)send" % ({"sep": separator})
-
- # Define different separator for coordinates and sites
- coor_sep = ";" if separator == "," else ","
+ num_cols = len(matrix[0])
- for row in matrix:
- if vcat:
- cat = row[0]
- x = row[1]
- y = row[2]
- out_str += (
- "{sep}{cat}{csep}{x:10.10f}{csep}"
- "{y:10.10f}".format(
- cat=cat,
- x=float(x),
- y=float(y),
- sep=separator,
- csep=coor_sep,
+ if first is True:
+ if write_header is True:
+ out_str = "start%(sep)send" % ({"sep": separator})
+
+ # Define different separator for coordinates and sites
+ coor_sep = ";" if separator == "," else ","
+
+ for row in matrix:
+ if vcat:
+ cat = row[0]
+ x = row[1]
+ y = row[2]
+ out_str += (
+ "{sep}{cat}{csep}{x:10.10f}{csep}"
+ "{y:10.10f}".format(
+ cat=cat,
+ x=float(x),
+ y=float(y),
+ sep=separator,
+ csep=coor_sep,
+ )
)
- )
- if site_input:
- site = row[3]
- out_str += "{sep}{site}".format(sep=coor_sep, site=site)
- else:
- x = row[0]
- y = row[1]
- out_str += "{sep}{x:10.10f}{csep}{y:10.10f}".format(
- x=float(x), y=float(y), sep=separator, csep=coor_sep
- )
- if site_input:
- site = row[2]
- out_str += "{sep}{site}".format(sep=coor_sep, site=site)
+ if site_input:
+ site = row[3]
+ out_str += "{sep}{site}".format(sep=coor_sep, site=site)
+ else:
+ x = row[0]
+ y = row[1]
+ out_str += "{sep}{x:10.10f}{csep}{y:10.10f}".format(
+ x=float(x), y=float(y), sep=separator, csep=coor_sep
+ )
+ if site_input:
+ site = row[2]
+ out_str += "{sep}{site}".format(sep=coor_sep, site=site)
- out_file.write(out_str + "\n")
+ out_file.write(out_str + "\n")
- first = False
+ first = False
- ncol = 4 if vcat else 3
- for col in range(num_cols - ncol):
- start, end = output_time_list[count][col].get_temporal_extent_as_tuple()
- time_string = "%(start)s%(sep)s%(end)s" % (
- {"start": str(start), "end": str(end), "sep": separator}
- )
- out_file.write(time_string)
- for row in range(len(matrix)):
- value = matrix[row][col + ncol]
- out_file.write(
- "%(sep)s%(value)s" % ({"sep": separator, "value": value.strip()})
+ ncol = 4 if vcat else 3
+ for col in range(num_cols - ncol):
+ start, end = output_time_list[count][col].get_temporal_extent_as_tuple()
+ time_string = "%(start)s%(sep)s%(end)s" % (
+ {"start": str(start), "end": str(end), "sep": separator}
)
- out_file.write("\n")
-
- in_file.close()
- if out_file is not sys.stdout:
- out_file.close()
+ out_file.write(time_string)
+ for row in range(len(matrix)):
+ value = matrix[row][col + ncol]
+ out_file.write(
+ "%(sep)s%(value)s"
+ % ({"sep": separator, "value": value.strip()})
+ )
+ out_file.write("\n")
############################################################################
@@ -528,7 +522,6 @@ def one_point_per_timerow_output(
3730731.49590371|5642483.51236521|6|8|7|7
3581249.04638104|5634411.97526282|5|8|7|7
""" # noqa: E501
- out_file = open(output, "w") if output != "-" else sys.stdout
matrix = []
header = ""
@@ -538,7 +531,6 @@ def one_point_per_timerow_output(
file_name = output_files[count]
gs.verbose("Transforming r.what output file %s" % (file_name))
map_list = output_time_list[count]
- in_file = open(file_name)
if write_header:
if first is True:
@@ -554,7 +546,8 @@ def one_point_per_timerow_output(
)
header += time_string
- lines = in_file.readlines()
+ with open(file_name) as in_file:
+ lines = in_file.readlines()
for i in range(len(lines)):
cols = lines[i].split(separator)
@@ -574,26 +567,23 @@ def one_point_per_timerow_output(
first = False
- in_file.close()
-
- if write_header:
- out_file.write(header + "\n")
+ with open(output, "w") if output != "-" else nullcontext(sys.stdout) as out_file:
+ if write_header:
+ out_file.write(header + "\n")
- gs.verbose(_("Writing the output file <%s>") % (output))
- for row in matrix:
- first = True
- for col in row:
- value = col.strip()
+ gs.verbose(_("Writing the output file <%s>") % (output))
+ for row in matrix:
+ first = True
+ for col in row:
+ value = col.strip()
- if first is False:
- out_file.write("%s" % (separator))
- out_file.write(value)
+ if first is False:
+ out_file.write("%s" % (separator))
+ out_file.write(value)
- first = False
+ first = False
- out_file.write("\n")
- if out_file is not sys.stdout:
- out_file.close()
+ out_file.write("\n")
############################################################################
diff --git a/temporal/t.remove/t.remove.py b/temporal/t.remove/t.remove.py
index 91fa58dde7a..a5bb3d85fd8 100755
--- a/temporal/t.remove/t.remove.py
+++ b/temporal/t.remove/t.remove.py
@@ -100,19 +100,17 @@ def main():
else:
dataset_list = tuple(datasets.split(","))
- # Read the dataset list from file
if file:
- fd = open(file)
-
line = True
- while True:
- line = fd.readline()
- if not line:
- break
-
- line_list = line.split("\n")
- dataset_name = line_list[0]
- dataset_list.append(dataset_name)
+ with open(file) as fd:
+ while True:
+ line = fd.readline()
+ if not line:
+ break
+
+ line_list = line.split("\n")
+ dataset_name = line_list[0]
+ dataset_list.append(dataset_name)
statement = ""
diff --git a/utils/create_python_init_file.py b/utils/create_python_init_file.py
index ff4b0f18255..567c8b95bba 100755
--- a/utils/create_python_init_file.py
+++ b/utils/create_python_init_file.py
@@ -32,15 +32,11 @@ def main(path):
continue
modules.append(os.path.splitext(os.path.basename(f))[0])
- fd = open(os.path.join(path, "__init__.py"), "w")
- try:
+ with open(os.path.join(path, "__init__.py"), "w") as fd:
fd.write("all = [%s" % os.linesep)
for m in modules:
fd.write(" '%s',%s" % (m, os.linesep))
fd.write(" ]%s" % os.linesep)
- finally:
- fd.close()
-
return 0
diff --git a/utils/fix_typos.sh b/utils/fix_typos.sh
index 68185b6b897..dab54f107a1 100755
--- a/utils/fix_typos.sh
+++ b/utils/fix_typos.sh
@@ -57,7 +57,7 @@ EXCLUDED_FILES="*/.svn*,configure,config.status,config.sub,*/autom4te.cache/*"
EXCLUDED_FILES="$EXCLUDED_FILES,*/lib/cdhc/doc/goodness.ps,*/lib/cdhc/doc/goodness.tex,*/macosx/pkg/resources/ReadMe.rtf"
EXCLUDED_FILES="$EXCLUDED_FILES,*/lib/gis/FIPS.code,*/lib/gis/projection,*/lib/proj/parms.table,*/lib/proj/units.table,*/lib/proj/desc.table"
EXCLUDED_FILES="$EXCLUDED_FILES,*/locale/po/*.po"
-EXCLUDED_FILES="$EXCLUDED_FILES,*/doc/notebooks/*.ipynb,*/*/*/*.ipynb"
+EXCLUDED_FILES="$EXCLUDED_FILES,*/*/*/*.ipynb"
EXCLUDED_FILES="$EXCLUDED_FILES,*/doc/*.svg,*/gui/icons/grass/*.svg,*/gui/images/*.svg,*/macosx/app/*.svg,*/man/*.svg,*/raster/*/*.svg"
EXCLUDED_FILES="$EXCLUDED_FILES,*/fix_typos/*,fix_typos.sh,*.eps,geopackage_aspatial.html"
EXCLUDED_FILES="$EXCLUDED_FILES,PROVENANCE.TXT,libtool,ltmain.sh,libtool.m4"
diff --git a/utils/g.html2man/g.html2man.py b/utils/g.html2man/g.html2man.py
index 46a749ae5d3..f8d5b0a89b4 100755
--- a/utils/g.html2man/g.html2man.py
+++ b/utils/g.html2man/g.html2man.py
@@ -26,18 +26,17 @@ def fix(content):
def main():
# parse HTML
infile = sys.argv[1]
- inf = open(infile)
- p = HTMLParser(entities)
- for n, line in enumerate(inf):
- try:
- p.feed(line)
- except Exception as err:
- sys.stderr.write(
- "%s:%d:0: Error (%s): %s\n" % (infile, n + 1, repr(err), line)
- )
- sys.exit(1)
- p.close()
- inf.close()
+ with open(infile) as inf:
+ p = HTMLParser(entities)
+ for n, line in enumerate(inf):
+ try:
+ p.feed(line)
+ except Exception as err:
+ sys.stderr.write(
+ "%s:%d:0: Error (%s): %s\n" % (infile, n + 1, repr(err), line)
+ )
+ sys.exit(1)
+ p.close()
# generate groff
sf = StringIO()
diff --git a/utils/generate_release_notes.py b/utils/generate_release_notes.py
index a6c9c1485f4..fb3fb7c2813 100755
--- a/utils/generate_release_notes.py
+++ b/utils/generate_release_notes.py
@@ -125,7 +125,7 @@ def print_by_category(changes, categories, file=None):
def binder_badge(tag):
"""Get mybinder Binder badge from a given tag, hash, or branch"""
binder_image_url = "https://mybinder.org/badge_logo.svg"
- binder_url = f"https://mybinder.org/v2/gh/OSGeo/grass/{tag}?urlpath=lab%2Ftree%2Fdoc%2Fnotebooks%2Fjupyter_example.ipynb" # noqa
+ binder_url = f"https://mybinder.org/v2/gh/OSGeo/grass/{tag}?urlpath=lab%2Ftree%2Fdoc%2Fexamples%2Fnotebooks%2Fjupyter_example.ipynb" # noqa
return f"[![Binder]({binder_image_url})]({binder_url})"
diff --git a/utils/md_isvalid.py b/utils/md_isvalid.py
index 8b963bb953b..0eb9c228376 100644
--- a/utils/md_isvalid.py
+++ b/utils/md_isvalid.py
@@ -14,8 +14,8 @@
def check_md(filename):
- p = subprocess.Popen(["mdl", filename])
- p.wait()
+ with subprocess.Popen(["mdl", filename]) as p:
+ p.wait()
def print_line():
@@ -27,20 +27,18 @@ def check_module(module):
print(module)
tmp_file = gs.tempfile()
with open(tmp_file, "w") as fp:
- p = subprocess.Popen([module, "--md-description"], stdout=fp)
- p.wait()
-
- p = subprocess.Popen(
+ with subprocess.Popen([module, "--md-description"], stdout=fp) as p:
+ p.wait()
+ with subprocess.Popen(
[
"mdl",
"--style",
os.path.join(os.path.dirname(__file__), "mdl_style.rb"),
fp.name,
]
- )
- p.wait()
-
- return p.returncode
+ ) as p:
+ p.wait()
+ return p.returncode
if __name__ == "__main__":
diff --git a/utils/mkhtml.py b/utils/mkhtml.py
index c01ab0534cb..0864356889c 100644
--- a/utils/mkhtml.py
+++ b/utils/mkhtml.py
@@ -7,7 +7,7 @@
# Glynn Clements
# Martin Landa
# PURPOSE: Create HTML manual page snippets
-# COPYRIGHT: (C) 2007-2024 by Glynn Clements
+# COPYRIGHT: (C) 2007-2025 by Glynn Clements
# and the GRASS Development Team
#
# This program is free software under the GNU General
diff --git a/utils/mkrest.py b/utils/mkrest.py
index 6270b78c6b2..1cc51c72b8a 100755
--- a/utils/mkrest.py
+++ b/utils/mkrest.py
@@ -19,6 +19,7 @@
import re
import subprocess
from datetime import datetime
+from pathlib import Path
pgm = sys.argv[1]
year = sys.argv[2] if len(sys.argv) > 1 else str(datetime.now().year)
@@ -47,10 +48,7 @@
def read_file(name):
try:
- f = open(name, "rb")
- s = f.read()
- f.close()
- return s
+ return Path(name).read_bytes()
except OSError:
return ""
@@ -79,8 +77,9 @@ def read_file(name):
sys.stdout.write(tmp_data)
arguments = ["pandoc", "-s", "-r", "html", src_file, "-w", "rst"]
-process = subprocess.Popen(arguments, stdout=subprocess.PIPE)
-html_text = process.communicate()[0]
+with subprocess.Popen(arguments, stdout=subprocess.PIPE) as process:
+ html_text = process.communicate()[0]
+
if html_text:
for k, v in replacement.iteritems():
html_text = html_text.replace(k, v)
diff --git a/utils/ppmrotate.py b/utils/ppmrotate.py
index acceba64368..28bfee13141 100755
--- a/utils/ppmrotate.py
+++ b/utils/ppmrotate.py
@@ -17,6 +17,8 @@
import os
import atexit
import array
+from pathlib import Path
+
import grass.script as gs
tmp_img = None
@@ -36,10 +38,8 @@ def cleanup():
def read_ppm(src):
global width, height
+ text = Path(src).read_bytes()
- fh = open(src, "rb")
- text = fh.read()
- fh.close()
i = 0
j = text.find("\n", i)
if text[i:j] != "P6":
@@ -62,10 +62,9 @@ def read_ppm(src):
def write_ppm(dst, data):
w = height
h = width
- fh = open(dst, "wb")
- fh.write("P6\n%d %d\n%d\n" % (w, h, 255))
- data.tofile(fh)
- fh.close()
+ with open(dst, "wb") as fh:
+ fh.write("P6\n%d %d\n%d\n" % (w, h, 255))
+ data.tofile(fh)
def rotate_ppm(srcd):
@@ -92,9 +91,8 @@ def ppmtopng(dst, src):
if gs.find_program("g.ppmtopng", "--help"):
gs.run_command("g.ppmtopng", input=src, output=dst, quiet=True)
elif gs.find_program("pnmtopng"):
- fh = open(dst, "wb")
- gs.call(["pnmtopng", src], stdout=fh)
- fh.close()
+ with open(dst, "wb") as fh:
+ gs.call(["pnmtopng", src], stdout=fh)
elif gs.find_program("convert"):
gs.call(["convert", src, dst])
else:
diff --git a/utils/thumbnails.py b/utils/thumbnails.py
index 181a16aa666..2eab7319f52 100755
--- a/utils/thumbnails.py
+++ b/utils/thumbnails.py
@@ -15,6 +15,8 @@
import os
import atexit
+from pathlib import Path
+
import grass.script as gs
@@ -35,10 +37,7 @@ def cleanup():
def make_gradient(path):
- fh = open(path)
- text = fh.read()
- fh.close()
-
+ text = Path(path).read_text()
lines = text.splitlines()
records = []
for line in lines:
diff --git a/vector/v.generalize/network.c b/vector/v.generalize/network.c
index 9c4cf5adeb5..62c6a8454c3 100644
--- a/vector/v.generalize/network.c
+++ b/vector/v.generalize/network.c
@@ -258,5 +258,7 @@ int graph_generalization(struct Map_info *In, struct Map_info *Out,
Vect_destroy_list(prev[i]);
G_free(prev);
graph_free(&g);
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
return output;
}
diff --git a/vector/v.to.rast/do_areas.c b/vector/v.to.rast/do_areas.c
index c3be7f5c18d..413ab8346d4 100644
--- a/vector/v.to.rast/do_areas.c
+++ b/vector/v.to.rast/do_areas.c
@@ -94,13 +94,14 @@ int sort_areas(struct Map_info *Map, struct line_pnts *Points, int field,
CELL cat;
G_begin_polygon_area_calculations();
- Cats = Vect_new_cats_struct();
/* first count valid areas */
nareas = Vect_get_num_areas(Map);
if (nareas == 0)
return 0;
+ Cats = Vect_new_cats_struct();
+
/* allocate list to hold valid area info */
list = (struct list *)G_calloc(nareas * sizeof(char), sizeof(struct list));
@@ -155,6 +156,7 @@ int sort_areas(struct Map_info *Map, struct line_pnts *Points, int field,
/* sort the list by size */
qsort(list, nareas * sizeof(char), sizeof(struct list), compare);
}
+ Vect_destroy_cats_struct(Cats);
return nareas_selected;
}