mirror of
https://gitlab.com/pamhyr/pamhyr2.git
synced 2026-10-30 03:20:41 +01:00
Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
815716da07 | ||
|
|
c288a390b5 | ||
|
|
f1377f6336 | ||
|
|
6ac808d842 | ||
|
|
b6aa0afdc7 | ||
|
|
03da38eeb0 | ||
|
|
e970b2c07a | ||
|
|
8d336b888a | ||
|
|
f4b7131b98 | ||
|
|
07cdf72528 | ||
|
|
7d235fdcc2 | ||
|
|
45d6f228cf | ||
|
|
31974bc7b6 | ||
|
|
e87db62dce | ||
|
|
1eec6ffc85 | ||
|
|
35dd851e08 |
No files matched your search
@@ -30,6 +30,7 @@ stages:
|
|||||||
|
|
||||||
variables:
|
variables:
|
||||||
MAGE_8_VERSION: "v8.3.6"
|
MAGE_8_VERSION: "v8.3.6"
|
||||||
|
CUSTOM_PYTHON_VERSION: "3.10.14-build2"
|
||||||
|
|
||||||
dl-mage8-doc:
|
dl-mage8-doc:
|
||||||
stage: downloads
|
stage: downloads
|
||||||
@@ -83,6 +84,21 @@ dl-mage8-windows:
|
|||||||
- mage8-windows/mailleurTT.exe
|
- mage8-windows/mailleurTT.exe
|
||||||
- mage8-windows/libbief.dll
|
- mage8-windows/libbief.dll
|
||||||
|
|
||||||
|
dl-python-linux:
|
||||||
|
stage: downloads
|
||||||
|
tags:
|
||||||
|
- linux
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == 'setup.py' || $CI_COMMIT_TAG
|
||||||
|
script:
|
||||||
|
- curl -L -o python.tar.xz https://gitlab.irstea.fr/parouby/custom-python-build/-/releases/$CUSTOM_PYTHON_VERSION/downloads/python.tar.xz
|
||||||
|
- mkdir -p linux-python/
|
||||||
|
- cd linux-python
|
||||||
|
- tar xvf ../python.tar.xz
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- linux-python
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# CONFIGURE #
|
# CONFIGURE #
|
||||||
#############
|
#############
|
||||||
@@ -408,6 +424,41 @@ windows-package-exe:
|
|||||||
- copy ..\packages\pamhyr.nsi pamhyr.nsi
|
- copy ..\packages\pamhyr.nsi pamhyr.nsi
|
||||||
- .\make-windows-exe.bat
|
- .\make-windows-exe.bat
|
||||||
|
|
||||||
|
linux-python-with-sources:
|
||||||
|
stage: package
|
||||||
|
tags:
|
||||||
|
- release
|
||||||
|
- linux
|
||||||
|
needs:
|
||||||
|
- job: dl-python-linux
|
||||||
|
artifacts: true
|
||||||
|
- job: set-version
|
||||||
|
artifacts: true
|
||||||
|
- job: build-lang
|
||||||
|
artifacts: true
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_BRANCH == 'setup.py' || $CI_COMMIT_TAG
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- linux-sources-with-python.tar.xz
|
||||||
|
script:
|
||||||
|
- git archive --format=tar.gz --output=src.tar.gz origin/$CI_COMMIT_BRANCH
|
||||||
|
- cd linux-python
|
||||||
|
- mkdir -p pamhyr
|
||||||
|
- cd pamhyr
|
||||||
|
- tar xvf ../../src.tar.gz
|
||||||
|
- cp -v ../../VERSION ./
|
||||||
|
- cp -v ../../src/lang/*.qm ./src/lang/
|
||||||
|
- cd ..
|
||||||
|
- cp ../packages/setup.sh ./setup.sh
|
||||||
|
- sed -i 's|python3|$(dirname $0)/python/python|' setup.sh
|
||||||
|
- sed -i 's|.pamhyr-env|$(dirname $0)/.pamhyr-env|' setup.sh
|
||||||
|
- sed -i 's|./pamhyr|$(dirname $0)/pamhyr|' setup.sh
|
||||||
|
- cd ..
|
||||||
|
- mv linux-python pamhyr
|
||||||
|
- tar cf linux-sources-with-python.tar.xz pamhyr
|
||||||
|
- mv pamhyr linux-python # Keep 'pamhyr' path avalaible
|
||||||
|
|
||||||
########
|
########
|
||||||
# HASH #
|
# HASH #
|
||||||
########
|
########
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
guix shell --manifest=manifest.scm -- python3 ./src/pamhyr.py $@
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
;; manifest.scm -- Pamhyr
|
||||||
|
;; Copyright (C) 2024 INRAE
|
||||||
|
;;
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
;;
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
;;
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
(specifications->manifest
|
||||||
|
(list "python" "zlib" "python-platformdirs" "python-lxml"
|
||||||
|
"python-pyqt@5" "python-pyqt5-sip"
|
||||||
|
"python-pyqtgraph" "python-qscintilla"
|
||||||
|
"python-numpy" "python-shapely" "python-pyshp"
|
||||||
|
"python-matplotlib"))
|
||||||
Executable
+54
@@ -0,0 +1,54 @@
|
|||||||
|
#! /usr/bin/env bash
|
||||||
|
# setup.sh -- Pamhyr
|
||||||
|
# Copyright (C) 2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
function perr() {
|
||||||
|
>&2 echo $1
|
||||||
|
}
|
||||||
|
|
||||||
|
function try() {
|
||||||
|
echo "$1"
|
||||||
|
res=$($1)
|
||||||
|
if [ $? -ne 0 ];
|
||||||
|
then
|
||||||
|
perr " !!! Command failed with exit value $?: '$1'"
|
||||||
|
perr " - $res"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -ne 0 ];
|
||||||
|
then
|
||||||
|
perr "usage: $0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
OLD_PWD=$PWD
|
||||||
|
|
||||||
|
try "python3 -m venv .pamhyr-env"
|
||||||
|
try "source .pamhyr-env/bin/activate"
|
||||||
|
try "python3 -m pip install -r ./pamhyr/requirements.txt"
|
||||||
|
|
||||||
|
echo '#! /usr/bin/env bash' > run-pamhyr
|
||||||
|
echo 'source .pamhyr-env/bin/activate' >> run-pamhyr
|
||||||
|
echo 'if [ $XDG_SESSION_TYPE == wayland ]; then' >> run-pamhyr
|
||||||
|
echo ' export QT_QPA_PLATFORM=wayland' >> run-pamhyr
|
||||||
|
echo 'fi' >> run-pamhyr
|
||||||
|
echo 'python3 ./pamhyr/src/pamhyr.py $@' >> run-pamhyr
|
||||||
|
|
||||||
|
try "chmod +x run-pamhyr"
|
||||||
|
|
||||||
|
cd $OLD_PWD
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from setuptools import find_packages, setup
|
||||||
|
|
||||||
|
def read_requirements():
|
||||||
|
req = []
|
||||||
|
|
||||||
|
with open("requirements.txt", "r") as f:
|
||||||
|
for line in f:
|
||||||
|
if line[0] == "#":
|
||||||
|
continue
|
||||||
|
|
||||||
|
req.append(line)
|
||||||
|
|
||||||
|
return req
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="Pamhyr2",
|
||||||
|
version="0.0.8",
|
||||||
|
description='River 1D modelling interface',
|
||||||
|
maintainer='INRAE',
|
||||||
|
maintainer_email='pierre-antoine.rouby@inrae.fr',
|
||||||
|
url='https://gitlab.irstea.fr/theophile.terraz/pamhyr',
|
||||||
|
packages=find_packages("."),
|
||||||
|
package_dir={"Pamhyr2": "Pamhyr2"},
|
||||||
|
scripts=[os.path.join("src", "pamhyr.py")],
|
||||||
|
install_requires=read_requirements(),
|
||||||
|
)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
+3
-4
@@ -371,8 +371,7 @@ class MeshingWithMageMailleurTT(AMeshingTool):
|
|||||||
lplan: bool = False,
|
lplan: bool = False,
|
||||||
lm: int = 3,
|
lm: int = 3,
|
||||||
linear: bool = False,
|
linear: bool = False,
|
||||||
origin_value=0.0,
|
origin_value=0.0):
|
||||||
orientation=0):
|
|
||||||
if reach is None or len(reach.profiles) == 0:
|
if reach is None or len(reach.profiles) == 0:
|
||||||
return reach
|
return reach
|
||||||
|
|
||||||
@@ -401,7 +400,7 @@ class MeshingWithMageMailleurTT(AMeshingTool):
|
|||||||
f"{str(step)} " +
|
f"{str(step)} " +
|
||||||
f"{limites[0]} {limites[1]} " +
|
f"{limites[0]} {limites[1]} " +
|
||||||
f"{directrices[0]} {directrices[1]} " +
|
f"{directrices[0]} {directrices[1]} " +
|
||||||
f"{orientation} {lm} {linear} " +
|
f"{lplan} {lm} {linear} " +
|
||||||
f"{origin} "
|
f"{origin} "
|
||||||
)
|
)
|
||||||
proc.start(
|
proc.start(
|
||||||
@@ -414,7 +413,7 @@ class MeshingWithMageMailleurTT(AMeshingTool):
|
|||||||
"update_kp", step,
|
"update_kp", step,
|
||||||
limites[0], limites[1],
|
limites[0], limites[1],
|
||||||
directrices[0], directrices[1],
|
directrices[0], directrices[1],
|
||||||
orientation, lm, linear, origin, origin_value
|
lplan, lm, linear, origin, origin_value
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -315,9 +315,6 @@ class BoundaryCondition(SQLSubModel):
|
|||||||
self._data.sort(reverse=_reverse, key=key)
|
self._data.sort(reverse=_reverse, key=key)
|
||||||
self._status.modified()
|
self._status.modified()
|
||||||
|
|
||||||
def index(self, bc):
|
|
||||||
self._data.index(bc)
|
|
||||||
|
|
||||||
def get_i(self, index):
|
def get_i(self, index):
|
||||||
return self.data[index]
|
return self.data[index]
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -140,6 +140,7 @@ class Data(SQLSubModel):
|
|||||||
reach=self._reach,
|
reach=self._reach,
|
||||||
status=self._status,
|
status=self._status,
|
||||||
)
|
)
|
||||||
|
|
||||||
return new
|
return new
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -367,33 +368,19 @@ class InitialConditions(SQLSubModel):
|
|||||||
key=lambda p: p.kp
|
key=lambda p: p.kp
|
||||||
)
|
)
|
||||||
|
|
||||||
def generate_growing_constante_height(self, height: float,
|
def generate_growing_constante_height(self, height: float):
|
||||||
compute_discharge: bool):
|
self._data = []
|
||||||
|
|
||||||
profiles = self._reach.reach.profiles.copy()
|
profiles = self._reach.reach.profiles.copy()
|
||||||
self._sort_by_z_and_kp(profiles)
|
self._sort_by_z_and_kp(profiles)
|
||||||
|
|
||||||
previous_elevation = -99999.99
|
|
||||||
|
|
||||||
data_discharge = {}
|
|
||||||
if not compute_discharge:
|
|
||||||
if len(self._data) == 0:
|
|
||||||
for profile in profiles:
|
|
||||||
data_discharge[profile.kp] = 0.0
|
|
||||||
else:
|
|
||||||
for data in self._data:
|
|
||||||
data_discharge[data["kp"]] = data["discharge"]
|
|
||||||
|
|
||||||
incline = self._reach.reach.get_incline_median_mean()
|
incline = self._reach.reach.get_incline_median_mean()
|
||||||
logger.debug(f"incline = {incline}")
|
logger.debug(f"incline = {incline}")
|
||||||
self._data = []
|
|
||||||
|
previous_elevation = -99999.99
|
||||||
for profile in profiles:
|
for profile in profiles:
|
||||||
width = profile.width_approximation()
|
width = profile.width_approximation()
|
||||||
strickler = 25
|
strickler = 25
|
||||||
|
|
||||||
if not compute_discharge:
|
|
||||||
discharge = data_discharge[profile.kp]
|
|
||||||
else:
|
|
||||||
discharge = (
|
discharge = (
|
||||||
((width * 0.8)
|
((width * 0.8)
|
||||||
* strickler
|
* strickler
|
||||||
@@ -414,39 +401,33 @@ class InitialConditions(SQLSubModel):
|
|||||||
new = Data(reach=self._reach, status=self._status)
|
new = Data(reach=self._reach, status=self._status)
|
||||||
new["kp"] = profile.kp
|
new["kp"] = profile.kp
|
||||||
new["discharge"] = discharge
|
new["discharge"] = discharge
|
||||||
|
|
||||||
new["elevation"] = elevation
|
new["elevation"] = elevation
|
||||||
|
|
||||||
previous_elevation = elevation
|
|
||||||
self._data.append(new)
|
self._data.append(new)
|
||||||
|
previous_elevation = elevation
|
||||||
|
|
||||||
self._generate_resort_data(profiles)
|
self._generate_resort_data(profiles)
|
||||||
|
|
||||||
def generate_discharge(self, discharge: float, compute_height: bool):
|
def generate_discharge(self, discharge: float):
|
||||||
|
self._data = []
|
||||||
|
|
||||||
|
self._generate_height_estimation_from_discharge(
|
||||||
|
discharge
|
||||||
|
)
|
||||||
|
|
||||||
|
def _generate_height_estimation_from_discharge(self, discharge: float):
|
||||||
profiles = self._reach.reach.profiles.copy()
|
profiles = self._reach.reach.profiles.copy()
|
||||||
self._sort_by_z_and_kp(profiles)
|
self._sort_by_z_and_kp(profiles)
|
||||||
|
|
||||||
previous_elevation = -99999.99
|
previous_elevation = -99999.99
|
||||||
|
|
||||||
data_height = {}
|
|
||||||
if not compute_height:
|
|
||||||
if len(self._data) == 0:
|
|
||||||
for profile in profiles:
|
|
||||||
data_height[profile.kp] = 0.0
|
|
||||||
else:
|
|
||||||
for data in self._data:
|
|
||||||
data_height[data["kp"]] = data["height"]
|
|
||||||
|
|
||||||
incline = self._reach.reach.get_incline_median_mean()
|
incline = self._reach.reach.get_incline_median_mean()
|
||||||
logger.debug(f"incline = {incline}")
|
logger.debug(f"incline = {incline}")
|
||||||
self._data = []
|
|
||||||
for profile in profiles:
|
for profile in profiles:
|
||||||
width = profile.width_approximation()
|
width = profile.width_approximation()
|
||||||
strickler = 25
|
strickler = 25
|
||||||
|
|
||||||
if not compute_height:
|
|
||||||
height = data_height[profile.kp]
|
|
||||||
else:
|
|
||||||
height = (
|
height = (
|
||||||
discharge
|
discharge
|
||||||
/
|
/
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
+2
-17
@@ -22,19 +22,10 @@ logger = logging.getLogger()
|
|||||||
|
|
||||||
|
|
||||||
class SavedStatus(object):
|
class SavedStatus(object):
|
||||||
def __init__(self, version=0):
|
def __init__(self):
|
||||||
super(SavedStatus, self).__init__()
|
super(SavedStatus, self).__init__()
|
||||||
self._version = version
|
|
||||||
self._saved = True
|
self._saved = True
|
||||||
|
|
||||||
@property
|
|
||||||
def version(self):
|
|
||||||
return self._version
|
|
||||||
|
|
||||||
@version.setter
|
|
||||||
def version(self, version):
|
|
||||||
self._version = version
|
|
||||||
|
|
||||||
def is_saved(self):
|
def is_saved(self):
|
||||||
return self._saved
|
return self._saved
|
||||||
|
|
||||||
@@ -43,11 +34,5 @@ class SavedStatus(object):
|
|||||||
self._saved = True
|
self._saved = True
|
||||||
|
|
||||||
def modified(self):
|
def modified(self):
|
||||||
if self._saved:
|
# logger.debug("model status set as modified")
|
||||||
self._version += 1
|
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
"STATUS: Model status set as modified " +
|
|
||||||
f"at version {self._version}"
|
|
||||||
)
|
|
||||||
self._saved = False
|
self._saved = False
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
+9
-34
@@ -41,7 +41,7 @@ class Study(SQLModel):
|
|||||||
|
|
||||||
def __init__(self, filename=None, init_new=True):
|
def __init__(self, filename=None, init_new=True):
|
||||||
# Metadata
|
# Metadata
|
||||||
self._version = "0.0.10"
|
self._version = "0.0.9"
|
||||||
self.creation_date = datetime.now()
|
self.creation_date = datetime.now()
|
||||||
self.last_modification_date = datetime.now()
|
self.last_modification_date = datetime.now()
|
||||||
self.last_save_date = datetime.now()
|
self.last_save_date = datetime.now()
|
||||||
@@ -117,9 +117,6 @@ class Study(SQLModel):
|
|||||||
if ".backup" in self.filename:
|
if ".backup" in self.filename:
|
||||||
is_new = True
|
is_new = True
|
||||||
|
|
||||||
if not os.path.exists(self.filename):
|
|
||||||
is_new = True
|
|
||||||
|
|
||||||
self._init_db_file(self.filename, is_new=is_new)
|
self._init_db_file(self.filename, is_new=is_new)
|
||||||
self.commit()
|
self.commit()
|
||||||
|
|
||||||
@@ -212,12 +209,7 @@ class Study(SQLModel):
|
|||||||
def _create(self):
|
def _create(self):
|
||||||
# Info (metadata)
|
# Info (metadata)
|
||||||
self.execute(
|
self.execute(
|
||||||
"INSERT INTO info VALUES ('study_release', '0')"
|
"CREATE TABLE info(key TEXT NOT NULL UNIQUE, value TEXT NOT NULL)")
|
||||||
)
|
|
||||||
|
|
||||||
self.execute(
|
|
||||||
"CREATE TABLE info(key TEXT NOT NULL UNIQUE, value TEXT NOT NULL)"
|
|
||||||
)
|
|
||||||
self.execute(
|
self.execute(
|
||||||
"INSERT INTO info VALUES ('version', " +
|
"INSERT INTO info VALUES ('version', " +
|
||||||
f"'{self._db_format(self._version)}')",
|
f"'{self._db_format(self._version)}')",
|
||||||
@@ -226,20 +218,19 @@ class Study(SQLModel):
|
|||||||
self.execute("INSERT INTO info VALUES ('name', '')")
|
self.execute("INSERT INTO info VALUES ('name', '')")
|
||||||
self.execute("INSERT INTO info VALUES ('description', '')")
|
self.execute("INSERT INTO info VALUES ('description', '')")
|
||||||
self.execute(
|
self.execute(
|
||||||
f"INSERT INTO info VALUES ('time_system', '{self._time_system}')"
|
f"INSERT INTO info VALUES ('time_system', '{self._time_system}')")
|
||||||
)
|
|
||||||
self.execute(
|
self.execute(
|
||||||
"INSERT INTO info VALUES ('date', " +
|
f"INSERT INTO info VALUES ('date', " +
|
||||||
f"'{self._date.timestamp()}')"
|
"'{self._date.timestamp()}')"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.execute(
|
self.execute(
|
||||||
"INSERT INTO info VALUES ('creation_date', " +
|
f"INSERT INTO info VALUES ('creation_date', " +
|
||||||
f"'{self.creation_date.timestamp()}')"
|
"'{self.creation_time.timestamp()}')"
|
||||||
)
|
)
|
||||||
self.execute(
|
self.execute(
|
||||||
"INSERT INTO info VALUES ('last_save_date', " +
|
f"INSERT INTO info VALUES ('last_save_date', " +
|
||||||
f"'{self.last_save_date.timestamp()}')"
|
"'{self.last_save_time.timestamp()}')"
|
||||||
)
|
)
|
||||||
|
|
||||||
self._create_submodel()
|
self._create_submodel()
|
||||||
@@ -254,12 +245,6 @@ class Study(SQLModel):
|
|||||||
|
|
||||||
logger.debug("Update database")
|
logger.debug("Update database")
|
||||||
|
|
||||||
major, minor, release = version[0].split('.')
|
|
||||||
if major == "0" and minor == "0" and int(release) < 10:
|
|
||||||
self.execute(
|
|
||||||
"INSERT INTO info VALUES ('study_release', '0')"
|
|
||||||
)
|
|
||||||
|
|
||||||
if self._update_submodel(version[0]):
|
if self._update_submodel(version[0]):
|
||||||
self.execute(
|
self.execute(
|
||||||
f"UPDATE info SET value='{self._version}' WHERE key='version'"
|
f"UPDATE info SET value='{self._version}' WHERE key='version'"
|
||||||
@@ -273,11 +258,6 @@ class Study(SQLModel):
|
|||||||
def _load(cls, filename):
|
def _load(cls, filename):
|
||||||
new = cls(init_new=False, filename=filename)
|
new = cls(init_new=False, filename=filename)
|
||||||
|
|
||||||
version = new.execute(
|
|
||||||
"SELECT value FROM info WHERE key='study_release'"
|
|
||||||
)
|
|
||||||
new.status.version = int(version[0])
|
|
||||||
|
|
||||||
# TODO: Load metadata
|
# TODO: Load metadata
|
||||||
new.name = new.execute("SELECT value FROM info WHERE key='name'")[0]
|
new.name = new.execute("SELECT value FROM info WHERE key='name'")[0]
|
||||||
new.description = new.execute(
|
new.description = new.execute(
|
||||||
@@ -312,11 +292,6 @@ class Study(SQLModel):
|
|||||||
def _save(self, progress=None):
|
def _save(self, progress=None):
|
||||||
progress = progress if progress is not None else lambda: None
|
progress = progress if progress is not None else lambda: None
|
||||||
|
|
||||||
self.execute(
|
|
||||||
"INSERT INTO info VALUES ('study_release', " +
|
|
||||||
f"'{self.status.version}')"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.execute(
|
self.execute(
|
||||||
f"UPDATE info SET " +
|
f"UPDATE info SET " +
|
||||||
f"value='{self._db_format(self.name)}' WHERE key='name'"
|
f"value='{self._db_format(self.name)}' WHERE key='name'"
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -99,7 +99,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
logger.info(e)
|
logger.info(e)
|
||||||
logger.debug(traceback.format_exc())
|
logger.debug(traceback.format_exc())
|
||||||
|
|
||||||
self.update()
|
self.dataChanged.emit(index, index)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def add(self, row, parent=QModelIndex()):
|
def add(self, row, parent=QModelIndex()):
|
||||||
@@ -112,7 +112,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.endInsertRows()
|
self.endInsertRows()
|
||||||
self.update()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def delete(self, rows, parent=QModelIndex()):
|
def delete(self, rows, parent=QModelIndex()):
|
||||||
self.beginRemoveRows(parent, rows[0], rows[-1])
|
self.beginRemoveRows(parent, rows[0], rows[-1])
|
||||||
@@ -135,7 +135,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
self.update()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_up(self, row, parent=QModelIndex()):
|
def move_up(self, row, parent=QModelIndex()):
|
||||||
if row <= 0:
|
if row <= 0:
|
||||||
@@ -152,7 +152,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.endMoveRows()
|
self.endMoveRows()
|
||||||
self.update()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_down(self, index, parent=QModelIndex()):
|
def move_down(self, index, parent=QModelIndex()):
|
||||||
if row > len(self._data):
|
if row > len(self._data):
|
||||||
@@ -169,7 +169,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.endMoveRows()
|
self.endMoveRows()
|
||||||
self.update()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def paste(self, row, header, data):
|
def paste(self, row, header, data):
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
@@ -190,13 +190,4 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
self.update()
|
|
||||||
|
|
||||||
def auto_sort(self):
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
|
||||||
self._data.sort(key=lambda x: x[0])
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
# self.auto_sort()
|
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
@@ -195,7 +195,6 @@ class EditBoundaryConditionWindow(PamhyrWindow):
|
|||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
|
|
||||||
self._table.dataChanged.connect(self.update)
|
self._table.dataChanged.connect(self.update)
|
||||||
self._table.layoutChanged.connect(self.update)
|
|
||||||
|
|
||||||
if self._is_solid:
|
if self._is_solid:
|
||||||
self._d50sigma.d50Changed.connect(self.d50_changed)
|
self._d50sigma.d50Changed.connect(self.d50_changed)
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
# PlotKPC.py -- Pamhyr
|
|
||||||
# Copyright (C) 2023-2024 INRAE
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from PyQt5.QtCore import QCoreApplication
|
|
||||||
from View.HydraulicStructures.PlotKPC import PlotKPC
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
|
||||||
|
|
||||||
|
|
||||||
class PlotKPZ(PlotKPC):
|
|
||||||
def __init__(self, canvas=None, trad=None, toolbar=None,
|
|
||||||
river=None, reach=None, profile=None,
|
|
||||||
parent=None):
|
|
||||||
super(PlotKPC, self).__init__(
|
|
||||||
canvas=canvas,
|
|
||||||
trad=trad,
|
|
||||||
data=river,
|
|
||||||
toolbar=toolbar,
|
|
||||||
parent=parent
|
|
||||||
)
|
|
||||||
|
|
||||||
self._current_reach = reach
|
|
||||||
self._current_profile = profile
|
|
||||||
|
|
||||||
self.label_x = self._trad["unit_kp"]
|
|
||||||
self.label_y = self._trad["unit_elevation"]
|
|
||||||
|
|
||||||
self._isometric_axis = False
|
|
||||||
|
|
||||||
self._auto_relim_update = True
|
|
||||||
self._autoscale_update = True
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
def onpick(self, event):
|
|
||||||
return
|
|
||||||
@@ -50,7 +50,7 @@ from View.Frictions.Table import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Frictions.PlotKPZ import PlotKPZ
|
from View.Geometry.PlotKPZ import PlotKPZ
|
||||||
from View.Frictions.PlotStricklers import PlotStricklers
|
from View.Frictions.PlotStricklers import PlotStricklers
|
||||||
from View.Frictions.translate import FrictionsTranslate
|
from View.Frictions.translate import FrictionsTranslate
|
||||||
|
|
||||||
@@ -135,11 +135,10 @@ class FrictionsWindow(PamhyrWindow):
|
|||||||
|
|
||||||
self.plot = PlotKPZ(
|
self.plot = PlotKPZ(
|
||||||
canvas=self.canvas,
|
canvas=self.canvas,
|
||||||
reach=self._reach,
|
data=self._reach.reach,
|
||||||
river=self._study.river,
|
study=self._study,
|
||||||
trad=self._trad,
|
trad=self._trad,
|
||||||
toolbar=None,
|
toolbar=None,
|
||||||
parent=self
|
|
||||||
)
|
)
|
||||||
self.plot.draw()
|
self.plot.draw()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
+116
-182
@@ -20,11 +20,6 @@ import logging
|
|||||||
|
|
||||||
from tools import timer
|
from tools import timer
|
||||||
from View.Tools.PamhyrPlot import PamhyrPlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
from PyQt5.QtWidgets import QApplication
|
|
||||||
from PyQt5.QtCore import (
|
|
||||||
Qt, QItemSelectionModel,
|
|
||||||
QItemSelection, QItemSelectionRange,
|
|
||||||
)
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
@@ -32,7 +27,7 @@ logger = logging.getLogger()
|
|||||||
class PlotKPZ(PamhyrPlot):
|
class PlotKPZ(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, trad=None,
|
def __init__(self, canvas=None, trad=None,
|
||||||
study=None, data=None, toolbar=None,
|
study=None, data=None, toolbar=None,
|
||||||
table=None, parent=None):
|
parent=None):
|
||||||
self._study = study
|
self._study = study
|
||||||
|
|
||||||
super(PlotKPZ, self).__init__(
|
super(PlotKPZ, self).__init__(
|
||||||
@@ -40,7 +35,6 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
trad=trad,
|
trad=trad,
|
||||||
data=data,
|
data=data,
|
||||||
toolbar=toolbar,
|
toolbar=toolbar,
|
||||||
table=table,
|
|
||||||
parent=parent
|
parent=parent
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -57,111 +51,6 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
self.before_plot_selected = None
|
self.before_plot_selected = None
|
||||||
self.plot_selected = None
|
self.plot_selected = None
|
||||||
self.after_plot_selected = None
|
self.after_plot_selected = None
|
||||||
self.parent = parent
|
|
||||||
self._table = table
|
|
||||||
self._colors = []
|
|
||||||
|
|
||||||
def onpick(self, event):
|
|
||||||
if event.mouseevent.inaxes != self.canvas.axes:
|
|
||||||
return
|
|
||||||
if event.mouseevent.button.value != 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
modifiers = QApplication.keyboardModifiers()
|
|
||||||
if modifiers not in [Qt.ControlModifier,
|
|
||||||
Qt.NoModifier,
|
|
||||||
Qt.ShiftModifier]:
|
|
||||||
return
|
|
||||||
|
|
||||||
ind, point = self._closest_kp(event)
|
|
||||||
if self.parent._table is None:
|
|
||||||
return
|
|
||||||
self.parent._table.blockSignals(True)
|
|
||||||
if modifiers == Qt.ControlModifier:
|
|
||||||
rows = list(
|
|
||||||
set(
|
|
||||||
(i.row() for i in self.parent.tableView.selectedIndexes())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if ind in rows:
|
|
||||||
rows.remove(ind)
|
|
||||||
else:
|
|
||||||
rows.append(ind)
|
|
||||||
self._select_in_table(rows)
|
|
||||||
elif modifiers == Qt.ShiftModifier:
|
|
||||||
rows = sorted(list(
|
|
||||||
set(
|
|
||||||
(i.row() for i in self.parent.tableView.selectedIndexes())
|
|
||||||
)
|
|
||||||
))
|
|
||||||
if len(rows) > 0:
|
|
||||||
i1 = min(rows[0], rows[-1], ind)
|
|
||||||
i2 = max(rows[0], rows[-1], ind)
|
|
||||||
else:
|
|
||||||
i1 = ind
|
|
||||||
i2 = ind
|
|
||||||
self._select_range_in_table(i1, i2)
|
|
||||||
else:
|
|
||||||
self._select_in_table([ind])
|
|
||||||
self.parent._table.blockSignals(False)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _closest_kp(self, event):
|
|
||||||
|
|
||||||
s = event.artist.get_segments()
|
|
||||||
x = [i[0, 0] for i in s]
|
|
||||||
mx = event.mouseevent.xdata
|
|
||||||
points = enumerate(x)
|
|
||||||
|
|
||||||
def dist_mouse(point):
|
|
||||||
x = point[1]
|
|
||||||
d = abs(mx - x)
|
|
||||||
return d
|
|
||||||
|
|
||||||
closest = min(
|
|
||||||
points, key=dist_mouse
|
|
||||||
)
|
|
||||||
|
|
||||||
return closest
|
|
||||||
|
|
||||||
def _select_in_table(self, ind):
|
|
||||||
if self._table is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
self._table.setFocus()
|
|
||||||
selection = self._table.selectionModel()
|
|
||||||
index = QItemSelection()
|
|
||||||
|
|
||||||
if len(ind) == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
for i in ind:
|
|
||||||
index.append(QItemSelectionRange(self._table.model().index(i, 0)))
|
|
||||||
|
|
||||||
selection.select(
|
|
||||||
index,
|
|
||||||
QItemSelectionModel.Rows |
|
|
||||||
QItemSelectionModel.ClearAndSelect |
|
|
||||||
QItemSelectionModel.Select
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(ind) > 0:
|
|
||||||
self._table.scrollTo(self._table.model().index(ind[-1], 0))
|
|
||||||
|
|
||||||
def _select_range_in_table(self, ind1, ind2):
|
|
||||||
if self._table is not None:
|
|
||||||
self._table.setFocus()
|
|
||||||
selection = self._table.selectionModel()
|
|
||||||
index = QItemSelection(self._table.model().index(ind1, 0),
|
|
||||||
self._table.model().index(ind2, 0))
|
|
||||||
selection.select(
|
|
||||||
index,
|
|
||||||
QItemSelectionModel.Rows |
|
|
||||||
QItemSelectionModel.ClearAndSelect |
|
|
||||||
QItemSelectionModel.Select
|
|
||||||
)
|
|
||||||
self._table.scrollTo(self._table.model().index(ind2, 0))
|
|
||||||
|
|
||||||
@timer
|
@timer
|
||||||
def draw(self):
|
def draw(self):
|
||||||
@@ -185,7 +74,8 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.draw_z_line()
|
self.draw_z_line()
|
||||||
self.draw_lr()
|
self.draw_z_line_highlight()
|
||||||
|
self.draw_current()
|
||||||
self.draw_gl()
|
self.draw_gl()
|
||||||
self.draw_bottom()
|
self.draw_bottom()
|
||||||
self.draw_profiles_hs(self._data)
|
self.draw_profiles_hs(self._data)
|
||||||
@@ -198,60 +88,76 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
z_min = self.data.get_z_min()
|
z_min = self.data.get_z_min()
|
||||||
z_max = self.data.get_z_max()
|
z_max = self.data.get_z_max()
|
||||||
|
|
||||||
self._colors, self._style = self.color_hightlight()
|
|
||||||
|
|
||||||
self.line_kp_zmin_zmax = self.canvas.axes.vlines(
|
self.line_kp_zmin_zmax = self.canvas.axes.vlines(
|
||||||
x=kp, ymin=z_min, ymax=z_max,
|
x=kp, ymin=z_min, ymax=z_max,
|
||||||
color=self._colors,
|
color=self.color_plot,
|
||||||
linestyle=self._style,
|
lw=1.
|
||||||
lw=1.,
|
|
||||||
picker=10,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def color_hightlight(self):
|
def draw_z_line_highlight(self):
|
||||||
rows = sorted(list(
|
if self._highlight_data is not None:
|
||||||
set(
|
|
||||||
(i.row() for i in self.parent.tableView.selectedIndexes())
|
|
||||||
)
|
|
||||||
))
|
|
||||||
colors = [self.color_plot for row in range(len(self._data))]
|
|
||||||
style = ["-" for row in range(len(self._data))]
|
|
||||||
if len(rows) > 0:
|
|
||||||
for row in rows:
|
|
||||||
colors[row] = self.color_plot_current
|
|
||||||
if rows[0] > 0:
|
|
||||||
colors[rows[0]-1] = self.color_plot_previous
|
|
||||||
style[rows[0]-1] = "--"
|
|
||||||
if rows[-1] < len(self._data)-1:
|
|
||||||
colors[rows[-1]+1] = self.color_plot_next
|
|
||||||
style[rows[-1]+1] = "--"
|
|
||||||
return colors, style
|
|
||||||
|
|
||||||
def draw_lr(self):
|
|
||||||
kp = self.data.get_kp_complete_profiles()
|
kp = self.data.get_kp_complete_profiles()
|
||||||
lz = []
|
z_min = self.data.get_z_min()
|
||||||
rz = []
|
z_max = self.data.get_z_max()
|
||||||
|
|
||||||
self.line_lr = []
|
kp_min, kp_max = self._highlight_data
|
||||||
for z in self.data.get_z():
|
|
||||||
lz.append(z[0])
|
|
||||||
rz.append(z[-1])
|
|
||||||
|
|
||||||
line = self.canvas.axes.plot(
|
indexes = list(
|
||||||
kp, lz,
|
map(
|
||||||
color=self.color_plot_river_bottom,
|
lambda x: x[0],
|
||||||
linestyle="dotted",
|
filter(
|
||||||
lw=1.,
|
lambda x: kp_min <= x[1] <= kp_max,
|
||||||
|
enumerate(kp)
|
||||||
)
|
)
|
||||||
self.line_lr.append(line)
|
|
||||||
|
|
||||||
line = self.canvas.axes.plot(
|
|
||||||
kp, rz,
|
|
||||||
color=self.color_plot_river_bottom,
|
|
||||||
linestyle="dotted",
|
|
||||||
lw=1.,
|
|
||||||
)
|
)
|
||||||
self.line_lr.append(line)
|
)
|
||||||
|
|
||||||
|
def indexes_filter(data): return list(
|
||||||
|
map(
|
||||||
|
lambda x: x[1],
|
||||||
|
filter(
|
||||||
|
lambda x: x[0] in indexes,
|
||||||
|
enumerate(data)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
ikp = indexes_filter(kp)
|
||||||
|
imin = indexes_filter(z_min)
|
||||||
|
imax = indexes_filter(z_max)
|
||||||
|
|
||||||
|
self.line_kp_zmin_zmax_highlight = self.canvas.axes.vlines(
|
||||||
|
x=ikp,
|
||||||
|
ymin=imin, ymax=imax,
|
||||||
|
color=self.color_plot_highlight,
|
||||||
|
lw=1.
|
||||||
|
)
|
||||||
|
|
||||||
|
def draw_current(self):
|
||||||
|
kp = self.data.get_kp_complete_profiles()
|
||||||
|
z_min = self.data.get_z_min()
|
||||||
|
z_max = self.data.get_z_max()
|
||||||
|
|
||||||
|
self.plot_selected, = self.canvas.axes.plot(
|
||||||
|
(kp[0], kp[0]),
|
||||||
|
(z_min[0], z_max[0]),
|
||||||
|
color=self.color_plot_current, lw=1.5
|
||||||
|
)
|
||||||
|
self.plot_selected.set_visible(False)
|
||||||
|
|
||||||
|
self.before_plot_selected, = self.canvas.axes.plot(
|
||||||
|
(kp[0], kp[0]),
|
||||||
|
(z_min[0], z_max[0]),
|
||||||
|
color=self.color_plot_previous, lw=1.5, linestyle='--'
|
||||||
|
)
|
||||||
|
self.before_plot_selected.set_visible(False)
|
||||||
|
|
||||||
|
self.after_plot_selected, = self.canvas.axes.plot(
|
||||||
|
(kp[0], kp[0]),
|
||||||
|
(z_min[0], z_max[0]),
|
||||||
|
color=self.color_plot_next, lw=1.5, linestyle='--'
|
||||||
|
)
|
||||||
|
self.after_plot_selected.set_visible(False)
|
||||||
|
|
||||||
def draw_gl(self):
|
def draw_gl(self):
|
||||||
kp = self.data.get_kp_complete_profiles()
|
kp = self.data.get_kp_complete_profiles()
|
||||||
@@ -293,7 +199,6 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
|
|
||||||
for hs in lhs:
|
for hs in lhs:
|
||||||
x = hs.input_kp
|
x = hs.input_kp
|
||||||
if x is not None:
|
|
||||||
z_min = reach.get_z_min()
|
z_min = reach.get_z_min()
|
||||||
z_max = reach.get_z_max()
|
z_max = reach.get_z_max()
|
||||||
|
|
||||||
@@ -320,7 +225,6 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
self.draw()
|
self.draw()
|
||||||
return
|
return
|
||||||
|
|
||||||
self.update_lr()
|
|
||||||
self.update_gl()
|
self.update_gl()
|
||||||
self.update_current()
|
self.update_current()
|
||||||
|
|
||||||
@@ -328,9 +232,52 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
|
|
||||||
def update_current(self):
|
def update_current(self):
|
||||||
if self._current_data_update:
|
if self._current_data_update:
|
||||||
self._colors, self._style = self.color_hightlight()
|
ind = self._current_data
|
||||||
self.line_kp_zmin_zmax.set_colors(self._colors)
|
before = ind - 1
|
||||||
self.line_kp_zmin_zmax.set_linestyle(self._style)
|
after = ind + 1
|
||||||
|
|
||||||
|
self.before_plot_selected.set_visible(False)
|
||||||
|
self.plot_selected.set_visible(False)
|
||||||
|
self.after_plot_selected.set_visible(False)
|
||||||
|
|
||||||
|
if 0 <= before < self.data.number_profiles:
|
||||||
|
profile = self.data.profile(before)
|
||||||
|
if len(profile) > 0:
|
||||||
|
kp_i = profile.kp
|
||||||
|
z_min_i = profile.z_min()
|
||||||
|
z_max_i = profile.z_max()
|
||||||
|
|
||||||
|
self.before_plot_selected.set_data(
|
||||||
|
(kp_i, kp_i),
|
||||||
|
(z_min_i, z_max_i)
|
||||||
|
)
|
||||||
|
self.before_plot_selected.set_visible(True)
|
||||||
|
|
||||||
|
if 0 <= ind < self.data.number_profiles:
|
||||||
|
profile = self.data.profile(ind)
|
||||||
|
if len(profile) > 0:
|
||||||
|
kp_i = profile.kp
|
||||||
|
z_min_i = profile.z_min()
|
||||||
|
z_max_i = profile.z_max()
|
||||||
|
|
||||||
|
self.plot_selected.set_data(
|
||||||
|
(kp_i, kp_i),
|
||||||
|
(z_min_i, z_max_i)
|
||||||
|
)
|
||||||
|
self.plot_selected.set_visible(True)
|
||||||
|
|
||||||
|
if 0 <= after < self.data.number_profiles:
|
||||||
|
profile = self.data.profile(after)
|
||||||
|
if len(profile) > 0:
|
||||||
|
kp_i = profile.kp
|
||||||
|
z_min_i = profile.z_min()
|
||||||
|
z_max_i = profile.z_max()
|
||||||
|
|
||||||
|
self.after_plot_selected.set_data(
|
||||||
|
(kp_i, kp_i),
|
||||||
|
(z_min_i, z_max_i)
|
||||||
|
)
|
||||||
|
self.after_plot_selected.set_visible(True)
|
||||||
|
|
||||||
def update_gl(self):
|
def update_gl(self):
|
||||||
if self._current_data_update:
|
if self._current_data_update:
|
||||||
@@ -342,19 +289,12 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
|
|
||||||
self.line_kp_zmin.set_data(kp, z_min)
|
self.line_kp_zmin.set_data(kp, z_min)
|
||||||
|
|
||||||
# TODO comprendre à quoi sert ce bout de code
|
self.line_kp_zmin_zmax.remove()
|
||||||
# ========>
|
self.line_kp_zmin_zmax = self.canvas.axes.vlines(
|
||||||
# self.line_kp_zmin_zmax.remove()
|
x=kp,
|
||||||
# self._colors, self._style = self.color_hightlight()
|
ymin=z_min, ymax=z_max,
|
||||||
# self.line_kp_zmin_zmax = self.canvas.axes.vlines(
|
color='r', lw=1.
|
||||||
# x=kp,
|
)
|
||||||
# ymin=z_min,
|
|
||||||
# ymax=z_max,
|
|
||||||
# color=self._colors,
|
|
||||||
# linestyle = self._style,
|
|
||||||
# lw=1.
|
|
||||||
# )
|
|
||||||
# <========
|
|
||||||
|
|
||||||
z_complete = self.data.get_guidelines_z()
|
z_complete = self.data.get_guidelines_z()
|
||||||
try:
|
try:
|
||||||
@@ -364,9 +304,3 @@ class PlotKPZ(PamhyrPlot):
|
|||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Failed to update graphic KPZ: {e}")
|
logger.warning(f"Failed to update graphic KPZ: {e}")
|
||||||
|
|
||||||
def update_lr(self):
|
|
||||||
for line in self.line_lr:
|
|
||||||
line[0].remove()
|
|
||||||
|
|
||||||
self.draw_lr()
|
|
||||||
+90
-167
@@ -18,27 +18,22 @@
|
|||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
from View.Tools.PamhyrPlot import PamhyrPlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
from matplotlib import collections
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication, Qt, QItemSelectionModel,
|
QCoreApplication
|
||||||
QItemSelection, QItemSelectionRange,
|
|
||||||
)
|
)
|
||||||
from PyQt5.QtWidgets import QApplication
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
|
|
||||||
class PlotXY(PamhyrPlot):
|
class PlotXY(PamhyrPlot):
|
||||||
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
||||||
table=None, parent=None):
|
parent=None):
|
||||||
super(PlotXY, self).__init__(
|
super(PlotXY, self).__init__(
|
||||||
canvas=canvas,
|
canvas=canvas,
|
||||||
trad=trad,
|
trad=trad,
|
||||||
data=data,
|
data=data,
|
||||||
toolbar=toolbar,
|
toolbar=toolbar,
|
||||||
table=table,
|
|
||||||
parent=parent
|
parent=parent
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,116 +46,6 @@ class PlotXY(PamhyrPlot):
|
|||||||
self.before_plot_selected = None
|
self.before_plot_selected = None
|
||||||
self.plot_selected = None
|
self.plot_selected = None
|
||||||
self.after_plot_selected = None
|
self.after_plot_selected = None
|
||||||
self.parent = parent
|
|
||||||
self.line_xy_collection = None
|
|
||||||
self._table = table
|
|
||||||
self._colors = []
|
|
||||||
self._style = []
|
|
||||||
|
|
||||||
def onpick(self, event):
|
|
||||||
if event.mouseevent.inaxes != self.canvas.axes:
|
|
||||||
return
|
|
||||||
if event.mouseevent.button.value != 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
modifiers = QApplication.keyboardModifiers()
|
|
||||||
if modifiers not in [Qt.ControlModifier,
|
|
||||||
Qt.NoModifier,
|
|
||||||
Qt.ShiftModifier]:
|
|
||||||
return
|
|
||||||
|
|
||||||
ind, point = self._closest_section(event)
|
|
||||||
if self._table is None:
|
|
||||||
return
|
|
||||||
self._table.blockSignals(True)
|
|
||||||
if modifiers == Qt.ControlModifier:
|
|
||||||
rows = list(
|
|
||||||
set(
|
|
||||||
(i.row() for i in self.parent.tableView.selectedIndexes())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if ind in rows:
|
|
||||||
rows.remove(ind)
|
|
||||||
self._select_in_table(rows)
|
|
||||||
else:
|
|
||||||
self._select_in_table(rows + [ind])
|
|
||||||
elif modifiers == Qt.ShiftModifier:
|
|
||||||
rows = list(
|
|
||||||
set(
|
|
||||||
(i.row() for i in self.parent.tableView.selectedIndexes())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if len(rows) > 0:
|
|
||||||
i1 = min(rows[0], rows[-1], ind)
|
|
||||||
i2 = max(rows[0], rows[-1], ind)
|
|
||||||
else:
|
|
||||||
i1 = ind
|
|
||||||
i2 = ind
|
|
||||||
self._select_range_in_table(i1, i2)
|
|
||||||
else:
|
|
||||||
self._select_in_table([ind])
|
|
||||||
self._table.blockSignals(False)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _closest_section(self, event):
|
|
||||||
axes = self.canvas.axes
|
|
||||||
mx = event.mouseevent.xdata
|
|
||||||
my = event.mouseevent.ydata
|
|
||||||
bx, by = axes.get_xlim(), axes.get_ylim()
|
|
||||||
ratio = (bx[0] - bx[1]) / (by[0] - by[1])
|
|
||||||
|
|
||||||
segments = event.artist.get_segments()
|
|
||||||
ind = event.ind
|
|
||||||
|
|
||||||
points = []
|
|
||||||
for i in ind:
|
|
||||||
points = points + [[i, j] for j in segments[i]]
|
|
||||||
|
|
||||||
def dist_mouse(point):
|
|
||||||
x, y = point[1]
|
|
||||||
d2 = (((mx - x) / ratio) ** 2) + ((my - y) ** 2)
|
|
||||||
return d2
|
|
||||||
|
|
||||||
closest = min(
|
|
||||||
points, key=dist_mouse
|
|
||||||
)
|
|
||||||
|
|
||||||
return closest
|
|
||||||
|
|
||||||
def _select_in_table(self, ind):
|
|
||||||
if self._table is None:
|
|
||||||
return
|
|
||||||
self._table.setFocus()
|
|
||||||
selection = self._table.selectionModel()
|
|
||||||
index = QItemSelection()
|
|
||||||
if len(ind) == 0:
|
|
||||||
return
|
|
||||||
for i in ind:
|
|
||||||
index.append(QItemSelectionRange(self._table.model().index(i, 0)))
|
|
||||||
selection.select(
|
|
||||||
index,
|
|
||||||
QItemSelectionModel.Rows |
|
|
||||||
QItemSelectionModel.ClearAndSelect |
|
|
||||||
QItemSelectionModel.Select
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(ind) > 0:
|
|
||||||
self._table.scrollTo(self._table.model().index(ind[-1], 0))
|
|
||||||
|
|
||||||
def _select_range_in_table(self, ind1, ind2):
|
|
||||||
if self._table is not None:
|
|
||||||
self._table.setFocus()
|
|
||||||
selection = self._table.selectionModel()
|
|
||||||
index = QItemSelection(self._table.model().index(ind1, 0),
|
|
||||||
self._table.model().index(ind2, 0))
|
|
||||||
selection.select(
|
|
||||||
index,
|
|
||||||
QItemSelectionModel.Rows |
|
|
||||||
QItemSelectionModel.ClearAndSelect |
|
|
||||||
QItemSelectionModel.Select
|
|
||||||
)
|
|
||||||
self._table.scrollTo(self._table.model().index(ind2, 0))
|
|
||||||
|
|
||||||
@timer
|
@timer
|
||||||
def draw(self):
|
def draw(self):
|
||||||
@@ -178,42 +63,33 @@ class PlotXY(PamhyrPlot):
|
|||||||
self.draw_xy()
|
self.draw_xy()
|
||||||
self.draw_lr()
|
self.draw_lr()
|
||||||
self.draw_gl()
|
self.draw_gl()
|
||||||
|
self.draw_current()
|
||||||
|
|
||||||
self.idle()
|
self.idle()
|
||||||
self._init = True
|
self._init = True
|
||||||
|
|
||||||
def draw_xy(self):
|
def draw_xy(self):
|
||||||
|
kp = self.data.get_kp_complete_profiles()
|
||||||
|
|
||||||
|
kp_min, kp_max = (-1, -1)
|
||||||
|
if self._highlight_data is not None:
|
||||||
|
kp_min, kp_max = self._highlight_data
|
||||||
|
|
||||||
|
def color_hightlight(kp):
|
||||||
|
if kp_min <= kp <= kp_max:
|
||||||
|
return self.color_plot_highlight
|
||||||
|
return self.color_plot
|
||||||
|
|
||||||
self.line_xy = []
|
self.line_xy = []
|
||||||
for xy in zip(self.data.get_x(), self.data.get_y()):
|
for x, y, kp in zip(self.data.get_x(),
|
||||||
self.line_xy.append(np.column_stack(xy))
|
self.data.get_y(),
|
||||||
|
kp):
|
||||||
self._colors, self._style = self.color_hightlight()
|
line = self.canvas.axes.plot(
|
||||||
self.line_xy_collection = collections.LineCollection(
|
x, y,
|
||||||
self.line_xy,
|
color=color_hightlight(kp),
|
||||||
colors=self._colors,
|
**self.plot_default_kargs
|
||||||
linestyle=self._style,
|
|
||||||
picker=10
|
|
||||||
)
|
)
|
||||||
self.canvas.axes.add_collection(self.line_xy_collection)
|
self.line_xy.append(line)
|
||||||
|
|
||||||
def color_hightlight(self):
|
|
||||||
rows = sorted(list(
|
|
||||||
set(
|
|
||||||
(i.row() for i in self.parent.tableView.selectedIndexes())
|
|
||||||
)
|
|
||||||
))
|
|
||||||
colors = [self.color_plot for row in range(len(self._data))]
|
|
||||||
style = ["-" for row in range(len(self._data))]
|
|
||||||
if len(rows) > 0:
|
|
||||||
for row in rows:
|
|
||||||
colors[row] = self.color_plot_current
|
|
||||||
if rows[0] > 0:
|
|
||||||
colors[rows[0]-1] = self.color_plot_previous
|
|
||||||
style[rows[0]-1] = "--"
|
|
||||||
if rows[-1] < len(self._data)-1:
|
|
||||||
colors[rows[-1]+1] = self.color_plot_next
|
|
||||||
style[rows[-1]+1] = "--"
|
|
||||||
return colors, style
|
|
||||||
|
|
||||||
def draw_lr(self):
|
def draw_lr(self):
|
||||||
lx = []
|
lx = []
|
||||||
@@ -260,6 +136,33 @@ class PlotXY(PamhyrPlot):
|
|||||||
self.line_gl.append(line)
|
self.line_gl.append(line)
|
||||||
ind += 1
|
ind += 1
|
||||||
|
|
||||||
|
def draw_current(self):
|
||||||
|
# Previous profile
|
||||||
|
self.before_plot_selected, = self.canvas.axes.plot(
|
||||||
|
self.data.profile(0).x(),
|
||||||
|
self.data.profile(0).y(),
|
||||||
|
color=self.color_plot_previous, linestyle="--",
|
||||||
|
**self.plot_default_kargs
|
||||||
|
)
|
||||||
|
self.before_plot_selected.set_visible(False)
|
||||||
|
|
||||||
|
# Current profile
|
||||||
|
self.plot_selected, = self.canvas.axes.plot(
|
||||||
|
self.data.profile(0).x(),
|
||||||
|
self.data.profile(0).y(),
|
||||||
|
color=self.color_plot_current, **self.plot_default_kargs
|
||||||
|
)
|
||||||
|
self.plot_selected.set_visible(False)
|
||||||
|
|
||||||
|
# Next profile
|
||||||
|
self.after_plot_selected, = self.canvas.axes.plot(
|
||||||
|
self.data.profile(0).x(),
|
||||||
|
self.data.profile(0).y(),
|
||||||
|
color=self.color_plot_next, linestyle='--',
|
||||||
|
**self.plot_default_kargs
|
||||||
|
)
|
||||||
|
self.after_plot_selected.set_visible(False)
|
||||||
|
|
||||||
@timer
|
@timer
|
||||||
def update(self):
|
def update(self):
|
||||||
if not self._init:
|
if not self._init:
|
||||||
@@ -280,24 +183,21 @@ class PlotXY(PamhyrPlot):
|
|||||||
x_complete = list(self.data.get_guidelines_x())
|
x_complete = list(self.data.get_guidelines_x())
|
||||||
y_complete = list(self.data.get_guidelines_y())
|
y_complete = list(self.data.get_guidelines_y())
|
||||||
|
|
||||||
# TODO comprendre à quoi sert ce bout de code
|
for i in range(self.data.number_profiles):
|
||||||
# ========>
|
if i < len(self.line_xy):
|
||||||
# for i in range(self.data.number_profiles):
|
self.line_xy[i][0].set_data(
|
||||||
# if i < len(self.line_xy):
|
self.data.profile(i).x(),
|
||||||
# self.line_xy[i][0].set_data(
|
self.data.profile(i).y()
|
||||||
# self.data.profile(i).x(),
|
)
|
||||||
# self.data.profile(i).y()
|
else:
|
||||||
# )
|
self.line_xy.append(
|
||||||
# else:
|
self.canvas.axes.plot(
|
||||||
# self.line_xy.append(
|
self.data.profile(i).x(),
|
||||||
# self.canvas.axes.plot(
|
self.data.profile(i).y(),
|
||||||
# self.data.profile(i).x(),
|
color='r',
|
||||||
# self.data.profile(i).y(),
|
**self.plot_default_kargs
|
||||||
# color='r',
|
)
|
||||||
# **self.plot_default_kargs
|
)
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# <========
|
|
||||||
|
|
||||||
for i in range(len(x_complete)):
|
for i in range(len(x_complete)):
|
||||||
if i < len(self.line_gl):
|
if i < len(self.line_gl):
|
||||||
@@ -315,9 +215,32 @@ class PlotXY(PamhyrPlot):
|
|||||||
|
|
||||||
def update_current(self):
|
def update_current(self):
|
||||||
if self._current_data_update:
|
if self._current_data_update:
|
||||||
self._colors, self._style = self.color_hightlight()
|
ind = self._current_data
|
||||||
self.line_xy_collection.set_colors(self._colors)
|
before = ind - 1
|
||||||
self.line_xy_collection.set_linestyle(self._style)
|
after = ind + 1
|
||||||
|
|
||||||
|
self.before_plot_selected.set_visible(False)
|
||||||
|
self.plot_selected.set_visible(False)
|
||||||
|
self.after_plot_selected.set_visible(False)
|
||||||
|
|
||||||
|
if 0 <= before < self.data.number_profiles:
|
||||||
|
self.before_plot_selected.set_data(
|
||||||
|
self.data.profile(before).x(),
|
||||||
|
self.data.profile(before).y()
|
||||||
|
)
|
||||||
|
self.before_plot_selected.set_visible(True)
|
||||||
|
|
||||||
|
if 0 <= ind < self.data.number_profiles:
|
||||||
|
self.plot_selected.set_data(self.data.profile(ind).x(),
|
||||||
|
self.data.profile(ind).y())
|
||||||
|
self.plot_selected.set_visible(True)
|
||||||
|
|
||||||
|
if 0 <= after < self.data.number_profiles:
|
||||||
|
self.after_plot_selected.set_data(
|
||||||
|
self.data.profile(after).x(),
|
||||||
|
self.data.profile(after).y()
|
||||||
|
)
|
||||||
|
self.after_plot_selected.set_visible(True)
|
||||||
|
|
||||||
def update_lr(self):
|
def update_lr(self):
|
||||||
for line in self.line_lr:
|
for line in self.line_lr:
|
||||||
|
|||||||
@@ -24,12 +24,10 @@ from tools import timer, trace
|
|||||||
from View.Tools.PamhyrPlot import PamhyrPlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
Qt, QCoreApplication, QItemSelectionModel,
|
Qt, QCoreApplication, QItemSelectionModel
|
||||||
QItemSelection, QItemSelectionRange,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
from matplotlib.widgets import RectangleSelector
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
@@ -48,7 +46,6 @@ class Plot(PamhyrPlot):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self._table = table
|
self._table = table
|
||||||
self._parent = parent
|
|
||||||
self._z_note = None
|
self._z_note = None
|
||||||
self._z_line = None
|
self._z_line = None
|
||||||
self._z_fill_between = None
|
self._z_fill_between = None
|
||||||
@@ -71,86 +68,40 @@ class Plot(PamhyrPlot):
|
|||||||
None # Hydrolic values (z, wet_area,
|
None # Hydrolic values (z, wet_area,
|
||||||
# wet_preimeter, water_width)
|
# wet_preimeter, water_width)
|
||||||
)
|
)
|
||||||
self._onpickevent = None
|
|
||||||
self._rect_select = RectangleSelector(
|
|
||||||
ax=self.canvas.axes,
|
|
||||||
onselect=self.rect_select_callback,
|
|
||||||
useblit=True,
|
|
||||||
button=[1], # don't use middle nor right button
|
|
||||||
minspanx=2.0,
|
|
||||||
minspany=2.0,
|
|
||||||
spancoords='pixels',
|
|
||||||
interactive=False
|
|
||||||
)
|
|
||||||
|
|
||||||
def onrelease(self, event):
|
|
||||||
# we need to do that to prevent conflicst
|
|
||||||
# between onpick and rect_select_callback
|
|
||||||
modifiers = QApplication.keyboardModifiers()
|
|
||||||
points, hyd = self.highlight
|
|
||||||
if self._onpickevent is not None:
|
|
||||||
ind, point = self._closest_point(self._onpickevent)
|
|
||||||
if modifiers == Qt.ControlModifier:
|
|
||||||
rows = self._parent.index_selected_rows()
|
|
||||||
if ind in rows:
|
|
||||||
rows.remove(ind)
|
|
||||||
del (points[ind])
|
|
||||||
self.highlight = (points, hyd)
|
|
||||||
self._select_in_table(rows)
|
|
||||||
else:
|
|
||||||
self.highlight = (points+[point], hyd)
|
|
||||||
self._select_in_table(rows+[ind])
|
|
||||||
elif modifiers == Qt.ShiftModifier:
|
|
||||||
rows = self._parent.index_selected_rows()
|
|
||||||
if len(rows) > 0:
|
|
||||||
i1 = min(rows[0], rows[-1], ind)
|
|
||||||
i2 = max(rows[0], rows[-1], ind)
|
|
||||||
p = [
|
|
||||||
[self.data.points[i].x, self.data.points[i].y]
|
|
||||||
for i in range(i1, i2)
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
i1 = ind
|
|
||||||
i2 = ind
|
|
||||||
p = [point]
|
|
||||||
self.highlight = (p, hyd)
|
|
||||||
self._select_range_in_table(i1, i2)
|
|
||||||
else:
|
|
||||||
self.highlight = ([point], hyd)
|
|
||||||
self._select_in_table([ind])
|
|
||||||
|
|
||||||
self._onpickevent = None
|
|
||||||
|
|
||||||
def onpick(self, event):
|
def onpick(self, event):
|
||||||
if event.mouseevent.inaxes != self.canvas.axes:
|
if event.mouseevent.inaxes != self.canvas.axes:
|
||||||
return
|
return
|
||||||
if event.mouseevent.button.value != 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
modifiers = QApplication.keyboardModifiers()
|
modifiers = QApplication.keyboardModifiers()
|
||||||
if modifiers not in [Qt.ControlModifier,
|
if modifiers != Qt.ControlModifier:
|
||||||
Qt.NoModifier,
|
|
||||||
Qt.ShiftModifier]:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
self._onpickevent = event
|
_, hyd = self.highlight
|
||||||
|
|
||||||
|
ind, point = self._closer_point(event)
|
||||||
|
|
||||||
|
self.highlight = ([point], hyd)
|
||||||
|
self._select_in_table(ind)
|
||||||
|
|
||||||
|
self.update()
|
||||||
return
|
return
|
||||||
|
|
||||||
def onclick(self, event):
|
def onclick(self, event):
|
||||||
if event.inaxes != self.canvas.axes:
|
if event.inaxes != self.canvas.axes:
|
||||||
return
|
return
|
||||||
if event.button.value == 1:
|
|
||||||
|
modifiers = QApplication.keyboardModifiers()
|
||||||
|
if modifiers != Qt.ShiftModifier:
|
||||||
return
|
return
|
||||||
|
|
||||||
points, _ = self.highlight
|
points, _ = self.highlight
|
||||||
|
|
||||||
z = self._get_z_from_click(event)
|
z = self._get_z_from_click(event)
|
||||||
if z < self.data.z_min() or event.button.value == 2:
|
if z < self.data.z_min():
|
||||||
self.highlight = (points, None)
|
|
||||||
self.update()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
a, p, w = self._compute_hydraulics(z)
|
a, p, w = self._compute_hydrolics(z)
|
||||||
|
|
||||||
logger.debug(f"{z, a, p, w}")
|
logger.debug(f"{z, a, p, w}")
|
||||||
|
|
||||||
@@ -159,7 +110,7 @@ class Plot(PamhyrPlot):
|
|||||||
self.update()
|
self.update()
|
||||||
return
|
return
|
||||||
|
|
||||||
def select_points_from_indices(self, indices):
|
def select_points_from_indexes(self, indexes):
|
||||||
data = self.data
|
data = self.data
|
||||||
_, hyd = self.highlight
|
_, hyd = self.highlight
|
||||||
|
|
||||||
@@ -167,7 +118,7 @@ class Plot(PamhyrPlot):
|
|||||||
map(
|
map(
|
||||||
lambda e: e[1],
|
lambda e: e[1],
|
||||||
filter(
|
filter(
|
||||||
lambda e: e[0] in indices,
|
lambda e: e[0] in indexes,
|
||||||
enumerate(
|
enumerate(
|
||||||
zip(data.get_station(), data.z())
|
zip(data.get_station(), data.z())
|
||||||
)
|
)
|
||||||
@@ -182,13 +133,9 @@ class Plot(PamhyrPlot):
|
|||||||
if self._table is not None:
|
if self._table is not None:
|
||||||
self._table.blockSignals(True)
|
self._table.blockSignals(True)
|
||||||
self._table.setFocus()
|
self._table.setFocus()
|
||||||
|
|
||||||
selection = self._table.selectionModel()
|
selection = self._table.selectionModel()
|
||||||
index = QItemSelection()
|
index = self._table.model().index(ind, 0)
|
||||||
if len(ind) > 0:
|
|
||||||
for i in ind:
|
|
||||||
index.append(QItemSelectionRange(
|
|
||||||
self._table.model().index(i, 0))
|
|
||||||
)
|
|
||||||
selection.select(
|
selection.select(
|
||||||
index,
|
index,
|
||||||
QItemSelectionModel.Rows |
|
QItemSelectionModel.Rows |
|
||||||
@@ -196,27 +143,10 @@ class Plot(PamhyrPlot):
|
|||||||
QItemSelectionModel.Select
|
QItemSelectionModel.Select
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(ind) > 0:
|
self._table.scrollTo(index)
|
||||||
self._table.scrollTo(self._table.model().index(ind[-1], 0))
|
|
||||||
self._table.blockSignals(False)
|
self._table.blockSignals(False)
|
||||||
|
|
||||||
def _select_range_in_table(self, ind1, ind2):
|
def _closer_point(self, event):
|
||||||
if self._table is not None:
|
|
||||||
self._table.blockSignals(True)
|
|
||||||
self._table.setFocus()
|
|
||||||
selection = self._table.selectionModel()
|
|
||||||
index = QItemSelection(self._table.model().index(ind1, 0),
|
|
||||||
self._table.model().index(ind2, 0))
|
|
||||||
selection.select(
|
|
||||||
index,
|
|
||||||
QItemSelectionModel.Rows |
|
|
||||||
QItemSelectionModel.ClearAndSelect |
|
|
||||||
QItemSelectionModel.Select
|
|
||||||
)
|
|
||||||
self._table.scrollTo(self._table.model().index(ind2, 0))
|
|
||||||
self._table.blockSignals(False)
|
|
||||||
|
|
||||||
def _closest_point(self, event):
|
|
||||||
points_ind = event.ind
|
points_ind = event.ind
|
||||||
axes = self.canvas.axes
|
axes = self.canvas.axes
|
||||||
bx, by = axes.get_xlim(), axes.get_ylim()
|
bx, by = axes.get_xlim(), axes.get_ylim()
|
||||||
@@ -236,62 +166,22 @@ class Plot(PamhyrPlot):
|
|||||||
|
|
||||||
def dist_mouse(point):
|
def dist_mouse(point):
|
||||||
x, y = point[1]
|
x, y = point[1]
|
||||||
d2 = ((mx - x) / ratio) ** 2 + ((my - y) ** 2)
|
d = sqrt(
|
||||||
return d2
|
(((mx - x) / ratio) ** 2) +
|
||||||
|
((my - y) ** 2)
|
||||||
|
)
|
||||||
|
return d
|
||||||
|
|
||||||
closest = min(
|
closer = min(
|
||||||
points, key=dist_mouse
|
points, key=dist_mouse
|
||||||
)
|
)
|
||||||
|
|
||||||
return closest
|
return closer
|
||||||
|
|
||||||
def _get_z_from_click(self, event):
|
def _get_z_from_click(self, event):
|
||||||
return event.ydata
|
return event.ydata
|
||||||
|
|
||||||
def rect_select_callback(self, eclick, erelease):
|
def _compute_hydrolics(self, z):
|
||||||
|
|
||||||
points, hyd = self.highlight
|
|
||||||
x1, y1 = eclick.xdata, eclick.ydata
|
|
||||||
x2, y2 = erelease.xdata, erelease.ydata
|
|
||||||
|
|
||||||
if (max(abs(x1-x2), abs(y1-y2)) < 0.001):
|
|
||||||
return
|
|
||||||
modifiers = QApplication.keyboardModifiers()
|
|
||||||
|
|
||||||
x1, y1 = eclick.xdata, eclick.ydata
|
|
||||||
x2, y2 = erelease.xdata, erelease.ydata
|
|
||||||
|
|
||||||
inds, points2 = self._points_in_rectangle(x1, y1, x2, y2)
|
|
||||||
self._onclickevent = None
|
|
||||||
if modifiers == Qt.ControlModifier:
|
|
||||||
rows = self._parent.index_selected_rows()
|
|
||||||
if all(i in rows for i in inds):
|
|
||||||
for ind in sorted(inds, reverse=True):
|
|
||||||
rows.remove(ind)
|
|
||||||
del (points[ind])
|
|
||||||
self.highlight = (points, hyd)
|
|
||||||
self._select_in_table(rows)
|
|
||||||
else:
|
|
||||||
self.highlight = (points+points2, hyd)
|
|
||||||
self._select_in_table(rows+inds)
|
|
||||||
else:
|
|
||||||
self.highlight = (points2, hyd)
|
|
||||||
self._select_in_table(inds)
|
|
||||||
return
|
|
||||||
|
|
||||||
def _points_in_rectangle(self, x1, y1, x2, y2):
|
|
||||||
# TODO: use lambdas
|
|
||||||
listi = []
|
|
||||||
listp = []
|
|
||||||
station = self.data._get_station(self.data.points)
|
|
||||||
for i, p in enumerate(self.data.points):
|
|
||||||
if (min(x1, x2) < station[i] < max(x1, x2)
|
|
||||||
and min(y1, y2) < p.z < max(y1, y2)):
|
|
||||||
listi.append(i)
|
|
||||||
listp.append((station[i], p.z))
|
|
||||||
return listi, listp
|
|
||||||
|
|
||||||
def _compute_hydraulics(self, z):
|
|
||||||
profile = self.data
|
profile = self.data
|
||||||
|
|
||||||
points = profile.wet_points(z)
|
points = profile.wet_points(z)
|
||||||
@@ -320,7 +210,7 @@ class Plot(PamhyrPlot):
|
|||||||
self.profile_line2D, = self.canvas.axes.plot(
|
self.profile_line2D, = self.canvas.axes.plot(
|
||||||
x, y, color=self.color_plot,
|
x, y, color=self.color_plot,
|
||||||
lw=1.5, markersize=7, marker='+',
|
lw=1.5, markersize=7, marker='+',
|
||||||
picker=10
|
picker=30
|
||||||
)
|
)
|
||||||
|
|
||||||
self.draw_annotation(x, y)
|
self.draw_annotation(x, y)
|
||||||
@@ -379,16 +269,12 @@ class Plot(PamhyrPlot):
|
|||||||
x, y,
|
x, y,
|
||||||
color=self.color_plot_highlight,
|
color=self.color_plot_highlight,
|
||||||
lw=1.5, markersize=7, marker='+',
|
lw=1.5, markersize=7, marker='+',
|
||||||
|
picker=30
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if hyd is not None:
|
if hyd is not None:
|
||||||
self.draw_highligth_z_line(*hyd)
|
self.draw_highligth_z_line(*hyd)
|
||||||
else:
|
|
||||||
if self._z_note is not None:
|
|
||||||
self._z_note.set_visible(False)
|
|
||||||
self._z_line[0].set_visible(False)
|
|
||||||
self._z_fill_between.set_visible(False)
|
|
||||||
|
|
||||||
def draw_highligth_z_line(self, z, a, p, w):
|
def draw_highligth_z_line(self, z, a, p, w):
|
||||||
text = (
|
text = (
|
||||||
@@ -413,7 +299,6 @@ class Plot(PamhyrPlot):
|
|||||||
xlim, [z, z],
|
xlim, [z, z],
|
||||||
color=self.color_plot_river_water
|
color=self.color_plot_river_water
|
||||||
)
|
)
|
||||||
self._z_line[0].set_visible(True)
|
|
||||||
|
|
||||||
self._z_note = self.canvas.axes.annotate(
|
self._z_note = self.canvas.axes.annotate(
|
||||||
text, pos,
|
text, pos,
|
||||||
@@ -425,15 +310,12 @@ class Plot(PamhyrPlot):
|
|||||||
fontweight='bold',
|
fontweight='bold',
|
||||||
alpha=0.7
|
alpha=0.7
|
||||||
)
|
)
|
||||||
self._z_note.set_visible(True)
|
|
||||||
else:
|
else:
|
||||||
self.draw_highligth_z_line_fill(x, y, z)
|
self.draw_highligth_z_line_fill(x, y, z)
|
||||||
|
|
||||||
self._z_line[0].set_data(xlim, [z, z])
|
self._z_line[0].set_data(xlim, [z, z])
|
||||||
self._z_note.set_position(pos)
|
self._z_note.set_position(pos)
|
||||||
self._z_note.set_text(text)
|
self._z_note.set_text(text)
|
||||||
self._z_line[0].set_visible(True)
|
|
||||||
self._z_note.set_visible(True)
|
|
||||||
|
|
||||||
def draw_highligth_z_line_fill(self, x, y, z):
|
def draw_highligth_z_line_fill(self, x, y, z):
|
||||||
if self._z_fill_between is not None:
|
if self._z_fill_between is not None:
|
||||||
|
|||||||
@@ -115,8 +115,7 @@ class ProfileWindow(PamhyrWindow):
|
|||||||
data=self._profile,
|
data=self._profile,
|
||||||
trad=self._trad,
|
trad=self._trad,
|
||||||
toolbar=self._toolbar,
|
toolbar=self._toolbar,
|
||||||
table=self.find(QTableView, "tableView"),
|
table=self.find(QTableView, "tableView")
|
||||||
parent=self
|
|
||||||
)
|
)
|
||||||
self._plot.draw()
|
self._plot.draw()
|
||||||
|
|
||||||
@@ -147,7 +146,7 @@ class ProfileWindow(PamhyrWindow):
|
|||||||
|
|
||||||
def update_points_selection(self):
|
def update_points_selection(self):
|
||||||
rows = self.index_selected_rows()
|
rows = self.index_selected_rows()
|
||||||
self._plot.select_points_from_indices(rows)
|
self._plot.select_points_from_indexes(rows)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.update_plot()
|
self.update_plot()
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -28,7 +28,7 @@ from PyQt5.QtCore import (
|
|||||||
|
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
|
QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
|
||||||
QDoubleSpinBox, QButtonGroup,
|
QDoubleSpinBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -50,20 +50,14 @@ class UpdateKPDialog(PamhyrDialog):
|
|||||||
self._init_default_values()
|
self._init_default_values()
|
||||||
|
|
||||||
def _init_default_values(self):
|
def _init_default_values(self):
|
||||||
gl, _ = self._reach.compute_guidelines()
|
self._space_step = 50.0
|
||||||
self._gl = list(gl)
|
self._lplan = False
|
||||||
|
self._lm = "3"
|
||||||
|
self._linear = False
|
||||||
|
self._begin_cs = -1
|
||||||
|
self._end_cs = -1
|
||||||
self._begin_dir = "un"
|
self._begin_dir = "un"
|
||||||
self._end_dir = "np"
|
self._end_dir = "np"
|
||||||
|
|
||||||
lower_gl = list(map(str.lower, self._gl))
|
|
||||||
for i, gl in enumerate(lower_gl):
|
|
||||||
if gl == "rd":
|
|
||||||
self._begin_dir = self._gl[i]
|
|
||||||
elif gl == "rg":
|
|
||||||
self._end_dir = self._gl[i]
|
|
||||||
|
|
||||||
self._orientation = 0
|
|
||||||
self._origin = self._reach.profile(0)
|
self._origin = self._reach.profile(0)
|
||||||
self._origin_value = self._reach.profile(0).kp
|
self._origin_value = self._reach.profile(0).kp
|
||||||
|
|
||||||
@@ -75,19 +69,8 @@ class UpdateKPDialog(PamhyrDialog):
|
|||||||
|
|
||||||
self.combobox_add_items("comboBox_origin", profiles)
|
self.combobox_add_items("comboBox_origin", profiles)
|
||||||
|
|
||||||
self.find(QComboBox, "comboBox_origin")\
|
self.find(QComboBox, "comboBox_origin").currentIndexChanged.connect(
|
||||||
.currentIndexChanged\
|
self.changed_profile)
|
||||||
.connect(
|
|
||||||
self.changed_profile
|
|
||||||
)
|
|
||||||
|
|
||||||
buttonbox = self.find(QButtonGroup, "buttonGroup_orientation")
|
|
||||||
|
|
||||||
for button in buttonbox.buttons():
|
|
||||||
name = button.objectName()
|
|
||||||
i = int(name.split('_')[-1])
|
|
||||||
|
|
||||||
buttonbox.setId(button, i)
|
|
||||||
|
|
||||||
def changed_profile(self):
|
def changed_profile(self):
|
||||||
origin = self.get_combobox_text("comboBox_origin")
|
origin = self.get_combobox_text("comboBox_origin")
|
||||||
@@ -119,8 +102,11 @@ class UpdateKPDialog(PamhyrDialog):
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
def _init_default_values_guidelines(self):
|
def _init_default_values_guidelines(self):
|
||||||
bgl = ['un'] + self._gl + ['np']
|
gl, _ = self._reach.compute_guidelines()
|
||||||
egl = ['un'] + self._gl + ['np']
|
gl = list(gl)
|
||||||
|
|
||||||
|
bgl = ['un'] + gl + ['np']
|
||||||
|
egl = ['un'] + gl + ['np']
|
||||||
|
|
||||||
self.combobox_add_items("comboBox_begin_gl", bgl)
|
self.combobox_add_items("comboBox_begin_gl", bgl)
|
||||||
self.combobox_add_items("comboBox_end_gl", egl)
|
self.combobox_add_items("comboBox_end_gl", egl)
|
||||||
@@ -128,10 +114,6 @@ class UpdateKPDialog(PamhyrDialog):
|
|||||||
self.set_combobox_text("comboBox_begin_gl", self._begin_dir)
|
self.set_combobox_text("comboBox_begin_gl", self._begin_dir)
|
||||||
self.set_combobox_text("comboBox_end_gl", self._end_dir)
|
self.set_combobox_text("comboBox_end_gl", self._end_dir)
|
||||||
|
|
||||||
@property
|
|
||||||
def orientation(self):
|
|
||||||
return self._orientation
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def origin(self):
|
def origin(self):
|
||||||
return self._origin
|
return self._origin
|
||||||
@@ -151,12 +133,11 @@ class UpdateKPDialog(PamhyrDialog):
|
|||||||
def accept(self):
|
def accept(self):
|
||||||
origin = self.get_combobox_text("comboBox_origin")
|
origin = self.get_combobox_text("comboBox_origin")
|
||||||
self._origin = self.profiles.index(origin)
|
self._origin = self.profiles.index(origin)
|
||||||
|
|
||||||
self._origin_value = self.get_double_spin_box("doubleSpinBox_origin")
|
self._origin_value = self.get_double_spin_box("doubleSpinBox_origin")
|
||||||
|
|
||||||
self._begin_dir = self.get_combobox_text("comboBox_begin_gl")
|
self._begin_dir = self.get_combobox_text("comboBox_begin_gl")
|
||||||
self._end_dir = self.get_combobox_text("comboBox_end_gl")
|
self._end_dir = self.get_combobox_text("comboBox_end_gl")
|
||||||
self._orientation = self.get_checked_id_button_group(
|
|
||||||
"buttonGroup_orientation"
|
|
||||||
)
|
|
||||||
|
|
||||||
super().accept()
|
super().accept()
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ from PyQt5.QtCore import (
|
|||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QApplication, QMainWindow, QFileDialog, QCheckBox,
|
QApplication, QMainWindow, QFileDialog, QCheckBox,
|
||||||
QUndoStack, QShortcut, QTableView, QHeaderView,
|
QUndoStack, QShortcut, QTableView, QHeaderView,
|
||||||
QAction, QPushButton, QVBoxLayout,
|
QAction, QSlider, QPushButton, QVBoxLayout,
|
||||||
QLabel, QAbstractItemView,
|
QLabel, QAbstractItemView,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -97,6 +97,7 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
self.setup_plots()
|
self.setup_plots()
|
||||||
self.setup_statusbar()
|
self.setup_statusbar()
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
self.changed_slider_value()
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
table_headers = self._trad.get_dict("table_headers")
|
table_headers = self._trad.get_dict("table_headers")
|
||||||
@@ -200,6 +201,13 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
self.find(QAction, action)\
|
self.find(QAction, action)\
|
||||||
.triggered.connect(actions[action])
|
.triggered.connect(actions[action])
|
||||||
|
|
||||||
|
self.find(QSlider, "verticalSlider").valueChanged.connect(
|
||||||
|
self.changed_slider_value)
|
||||||
|
self.find(QPushButton, "pushButton_up").clicked.connect(
|
||||||
|
self.decrement_value_slider)
|
||||||
|
self.find(QPushButton, "pushButton_down").clicked.connect(
|
||||||
|
self.increment_value_slider)
|
||||||
|
|
||||||
# Profile selection when line change in table
|
# Profile selection when line change in table
|
||||||
self.find(QTableView, "tableView").selectionModel()\
|
self.find(QTableView, "tableView").selectionModel()\
|
||||||
.selectionChanged\
|
.selectionChanged\
|
||||||
@@ -220,6 +228,7 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
self._plot_ac.draw()
|
self._plot_ac.draw()
|
||||||
|
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
|
self.changed_slider_value()
|
||||||
|
|
||||||
if propagate:
|
if propagate:
|
||||||
self._propagate_update(key=Modules.GEOMETRY)
|
self._propagate_update(key=Modules.GEOMETRY)
|
||||||
@@ -327,7 +336,6 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
"origin": dlg.origin,
|
"origin": dlg.origin,
|
||||||
"directrices": [dlg.begin_dir, dlg.end_dir],
|
"directrices": [dlg.begin_dir, dlg.end_dir],
|
||||||
"origin_value": dlg.origin_value,
|
"origin_value": dlg.origin_value,
|
||||||
"orientation": dlg.orientation,
|
|
||||||
}
|
}
|
||||||
self._update_kp(data)
|
self._update_kp(data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -354,9 +362,7 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
canvas=self._canvas_xy,
|
canvas=self._canvas_xy,
|
||||||
data=self._reach,
|
data=self._reach,
|
||||||
trad=self._trad,
|
trad=self._trad,
|
||||||
toolbar=self._toolbar_xy,
|
toolbar=self._toolbar_xy
|
||||||
table=self.find(QTableView, "tableView"),
|
|
||||||
parent=self
|
|
||||||
)
|
)
|
||||||
self._plot_xy.draw()
|
self._plot_xy.draw()
|
||||||
|
|
||||||
@@ -375,9 +381,7 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
study=self._study,
|
study=self._study,
|
||||||
data=self._reach,
|
data=self._reach,
|
||||||
trad=self._trad,
|
trad=self._trad,
|
||||||
toolbar=self._toolbar_kpc,
|
toolbar=self._toolbar_kpc
|
||||||
table=self.find(QTableView, "tableView"),
|
|
||||||
parent=self
|
|
||||||
)
|
)
|
||||||
self._plot_kpc.draw()
|
self._plot_kpc.draw()
|
||||||
|
|
||||||
@@ -430,11 +434,26 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
self._plot_ac.update()
|
self._plot_ac.update()
|
||||||
self.tableView.model().blockSignals(False)
|
self.tableView.model().blockSignals(False)
|
||||||
|
|
||||||
|
def select_row_profile_slider(self, ind: int = 0):
|
||||||
|
if self.tableView is not None:
|
||||||
|
selectionModel = self.tableView.selectionModel()
|
||||||
|
index = self.tableView.model().index(ind, 0)
|
||||||
|
|
||||||
|
selectionModel.select(
|
||||||
|
index,
|
||||||
|
QItemSelectionModel.Rows |
|
||||||
|
QItemSelectionModel.ClearAndSelect |
|
||||||
|
QItemSelectionModel.Select
|
||||||
|
)
|
||||||
|
|
||||||
|
self.tableView.scrollTo(index)
|
||||||
|
|
||||||
def select_current_profile(self):
|
def select_current_profile(self):
|
||||||
self.tableView.model().blockSignals(True)
|
self.tableView.model().blockSignals(True)
|
||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
|
|
||||||
if row is not None:
|
if row is not None:
|
||||||
|
self.find(QSlider, "verticalSlider").setValue(row)
|
||||||
self.select_plot_xy(row)
|
self.select_plot_xy(row)
|
||||||
self.select_plot_kpc(row)
|
self.select_plot_kpc(row)
|
||||||
self.select_plot_ac(row)
|
self.select_plot_ac(row)
|
||||||
@@ -445,6 +464,33 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
|
|
||||||
self.tableView.model().blockSignals(False)
|
self.tableView.model().blockSignals(False)
|
||||||
|
|
||||||
|
def changed_slider_value(self):
|
||||||
|
self.tableView.model().blockSignals(True)
|
||||||
|
|
||||||
|
if self._table.rowCount() != 0:
|
||||||
|
slider = self.find(QSlider, "verticalSlider")
|
||||||
|
slider.setMaximum(self._table.rowCount() - 1)
|
||||||
|
|
||||||
|
slider_value = slider.value()
|
||||||
|
kp = self._reach.profile(slider_value).kp
|
||||||
|
|
||||||
|
self.select_plot_xy(slider_value)
|
||||||
|
self.select_plot_kpc(slider_value)
|
||||||
|
self.select_row_profile_slider(slider_value)
|
||||||
|
self.update_statusbar()
|
||||||
|
|
||||||
|
self.tableView.model().blockSignals(False)
|
||||||
|
|
||||||
|
def increment_value_slider(self):
|
||||||
|
slider = self.find(QSlider, "verticalSlider")
|
||||||
|
if 0 <= slider.value() < self._table.rowCount() - 1:
|
||||||
|
slider.setValue(slider.value() + 1)
|
||||||
|
|
||||||
|
def decrement_value_slider(self):
|
||||||
|
slider = self.find(QSlider, "verticalSlider")
|
||||||
|
if 0 < slider.value() < self._table.rowCount():
|
||||||
|
slider.setValue(slider.value() - 1)
|
||||||
|
|
||||||
def add(self):
|
def add(self):
|
||||||
if len(self.tableView.selectedIndexes()) == 0:
|
if len(self.tableView.selectedIndexes()) == 0:
|
||||||
self._table.add(self._table.rowCount())
|
self._table.add(self._table.rowCount())
|
||||||
@@ -469,7 +515,7 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
.selectionModel()\
|
.selectionModel()\
|
||||||
.selectedRows()
|
.selectedRows()
|
||||||
|
|
||||||
if len(r) == 1:
|
if len(r) > 0:
|
||||||
return r[0].row()
|
return r[0].row()
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
@@ -477,11 +523,13 @@ class GeometryWindow(PamhyrWindow):
|
|||||||
def sort_ascending(self):
|
def sort_ascending(self):
|
||||||
self._table.sort_profiles(False)
|
self._table.sort_profiles(False)
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
|
self.changed_slider_value()
|
||||||
|
|
||||||
def sort_descending(self):
|
def sort_descending(self):
|
||||||
self._table.sort_profiles(True)
|
self._table.sort_profiles(True)
|
||||||
|
|
||||||
self.select_current_profile()
|
self.select_current_profile()
|
||||||
|
self.changed_slider_value()
|
||||||
|
|
||||||
def move_up(self):
|
def move_up(self):
|
||||||
row = self.index_selected_row()
|
row = self.index_selected_row()
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -20,9 +20,8 @@ from tools import timer
|
|||||||
from View.Tools.PamhyrPlot import PamhyrPlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication, Qt,
|
QCoreApplication
|
||||||
)
|
)
|
||||||
from PyQt5.QtWidgets import QApplication
|
|
||||||
|
|
||||||
from matplotlib.collections import LineCollection
|
from matplotlib.collections import LineCollection
|
||||||
|
|
||||||
@@ -51,7 +50,6 @@ class PlotKPC(PamhyrPlot):
|
|||||||
|
|
||||||
self._auto_relim_update = True
|
self._auto_relim_update = True
|
||||||
self._autoscale_update = True
|
self._autoscale_update = True
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def river(self):
|
def river(self):
|
||||||
@@ -93,14 +91,7 @@ class PlotKPC(PamhyrPlot):
|
|||||||
self.line_kp_zmin, = self.canvas.axes.plot(
|
self.line_kp_zmin, = self.canvas.axes.plot(
|
||||||
kp, z_min,
|
kp, z_min,
|
||||||
color=self.color_plot_river_bottom,
|
color=self.color_plot_river_bottom,
|
||||||
lw=1.,
|
lw=1.
|
||||||
)
|
|
||||||
|
|
||||||
self.line_kp_zmax, = self.canvas.axes.plot(
|
|
||||||
kp, z_max,
|
|
||||||
color=self.color_plot_river_bottom,
|
|
||||||
lw=1.,
|
|
||||||
alpha=0.0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(kp) != 0:
|
if len(kp) != 0:
|
||||||
@@ -108,8 +99,7 @@ class PlotKPC(PamhyrPlot):
|
|||||||
x=kp,
|
x=kp,
|
||||||
ymin=z_min, ymax=z_max,
|
ymin=z_min, ymax=z_max,
|
||||||
color=self.color_plot,
|
color=self.color_plot,
|
||||||
lw=1.,
|
lw=1.
|
||||||
picker=10
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def draw_current(self):
|
def draw_current(self):
|
||||||
@@ -173,40 +163,3 @@ class PlotKPC(PamhyrPlot):
|
|||||||
self.profile.set_data([], [])
|
self.profile.set_data([], [])
|
||||||
|
|
||||||
self.canvas.figure.canvas.draw_idle()
|
self.canvas.figure.canvas.draw_idle()
|
||||||
|
|
||||||
def onpick(self, event):
|
|
||||||
if event.mouseevent.inaxes != self.canvas.axes:
|
|
||||||
return
|
|
||||||
if event.mouseevent.button.value != 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
modifiers = QApplication.keyboardModifiers()
|
|
||||||
if modifiers not in [Qt.ControlModifier,
|
|
||||||
Qt.NoModifier,
|
|
||||||
Qt.ShiftModifier]:
|
|
||||||
return
|
|
||||||
|
|
||||||
closest = self._closest_profile(event)
|
|
||||||
index = self.parent.tableView.selectedIndexes()
|
|
||||||
if self.parent._table is not None:
|
|
||||||
self.parent._table.setData(index[2], closest)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _closest_profile(self, event):
|
|
||||||
|
|
||||||
s = event.artist.get_segments()
|
|
||||||
x = [i[0, 0] for i in s]
|
|
||||||
mx = event.mouseevent.xdata
|
|
||||||
points = enumerate(x)
|
|
||||||
|
|
||||||
def dist_mouse(point):
|
|
||||||
x = point[1]
|
|
||||||
d = abs(mx - x)
|
|
||||||
return d
|
|
||||||
|
|
||||||
closest = min(
|
|
||||||
points, key=dist_mouse
|
|
||||||
)
|
|
||||||
|
|
||||||
return closest[1]
|
|
||||||
@@ -141,8 +141,7 @@ class HydraulicStructuresWindow(PamhyrWindow):
|
|||||||
reach=None,
|
reach=None,
|
||||||
profile=None,
|
profile=None,
|
||||||
trad=self._trad,
|
trad=self._trad,
|
||||||
toolbar=self.toolbar,
|
toolbar=self.toolbar
|
||||||
parent=self
|
|
||||||
)
|
)
|
||||||
self.plot_kpc.draw()
|
self.plot_kpc.draw()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -28,7 +28,7 @@ from PyQt5.QtCore import (
|
|||||||
|
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
|
QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
|
||||||
QDoubleSpinBox, QCheckBox,
|
QDoubleSpinBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -45,11 +45,9 @@ class DischargeDialog(PamhyrDialog):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.value = None
|
self.value = None
|
||||||
self.option = None
|
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
self.value = self.find(QDoubleSpinBox, "doubleSpinBox").value()
|
self.value = self.find(QDoubleSpinBox, "doubleSpinBox").value()
|
||||||
self.option = self.find(QCheckBox, "checkBox").isChecked()
|
|
||||||
super().accept()
|
super().accept()
|
||||||
|
|
||||||
def reject(self):
|
def reject(self):
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from PyQt5.QtCore import (
|
|||||||
|
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
|
QDialogButtonBox, QComboBox, QUndoStack, QShortcut,
|
||||||
QDoubleSpinBox, QCheckBox,
|
QDoubleSpinBox,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -45,11 +45,9 @@ class HeightDialog(PamhyrDialog):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.value = None
|
self.value = None
|
||||||
self.option = None
|
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
self.value = self.find(QDoubleSpinBox, "doubleSpinBox").value()
|
self.value = self.find(QDoubleSpinBox, "doubleSpinBox").value()
|
||||||
self.option = self.find(QCheckBox, "checkBox").isChecked()
|
|
||||||
super().accept()
|
super().accept()
|
||||||
|
|
||||||
def reject(self):
|
def reject(self):
|
||||||
|
|||||||
@@ -289,10 +289,10 @@ class InitialConditionTableModel(PamhyrTableModel):
|
|||||||
self._undo.redo()
|
self._undo.redo()
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def generate(self, generator, param, option):
|
def generate(self, generator, param):
|
||||||
self._undo.push(
|
self._undo.push(
|
||||||
GenerateCommand(
|
GenerateCommand(
|
||||||
self._lst, generator, param, option
|
self._lst, generator, param
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
@@ -174,12 +174,11 @@ class DuplicateCommand(QUndoCommand):
|
|||||||
|
|
||||||
|
|
||||||
class GenerateCommand(QUndoCommand):
|
class GenerateCommand(QUndoCommand):
|
||||||
def __init__(self, ics, generator, param, option):
|
def __init__(self, ics, generator, param):
|
||||||
QUndoCommand.__init__(self)
|
QUndoCommand.__init__(self)
|
||||||
|
|
||||||
self._ics = ics
|
self._ics = ics
|
||||||
self._param = param
|
self._param = param
|
||||||
self._option = option
|
|
||||||
self._copy = self._ics.data
|
self._copy = self._ics.data
|
||||||
self._generator = generator
|
self._generator = generator
|
||||||
|
|
||||||
@@ -188,8 +187,6 @@ class GenerateCommand(QUndoCommand):
|
|||||||
|
|
||||||
def redo(self):
|
def redo(self):
|
||||||
if self._generator == "growing":
|
if self._generator == "growing":
|
||||||
self._ics.generate_growing_constante_height(self._param,
|
self._ics.generate_growing_constante_height(self._param)
|
||||||
self._option)
|
|
||||||
elif self._generator == "discharge":
|
elif self._generator == "discharge":
|
||||||
self._ics.generate_discharge(self._param,
|
self._ics.generate_discharge(self._param)
|
||||||
self._option)
|
|
||||||
@@ -349,14 +349,12 @@ class InitialConditionsWindow(PamhyrWindow):
|
|||||||
dlg = HeightDialog(trad=self._trad, parent=self)
|
dlg = HeightDialog(trad=self._trad, parent=self)
|
||||||
if dlg.exec():
|
if dlg.exec():
|
||||||
value = dlg.value
|
value = dlg.value
|
||||||
compute_discharge = dlg.option
|
self._table.generate("growing", value)
|
||||||
self._table.generate("growing", value, compute_discharge)
|
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
def generate_discharge(self):
|
def generate_discharge(self):
|
||||||
dlg = DischargeDialog(trad=self._trad, parent=self)
|
dlg = DischargeDialog(trad=self._trad, parent=self)
|
||||||
if dlg.exec():
|
if dlg.exec():
|
||||||
value = dlg.value
|
value = dlg.value
|
||||||
compute_height = dlg.option
|
self._table.generate("discharge", value)
|
||||||
self._table.generate("discharge", value, compute_height)
|
|
||||||
self._update()
|
self._update()
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -99,7 +99,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
logger.info(e)
|
logger.info(e)
|
||||||
logger.debug(traceback.format_exc())
|
logger.debug(traceback.format_exc())
|
||||||
|
|
||||||
self.update()
|
self.dataChanged.emit(index, index)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def add(self, row, parent=QModelIndex()):
|
def add(self, row, parent=QModelIndex()):
|
||||||
@@ -112,7 +112,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.endInsertRows()
|
self.endInsertRows()
|
||||||
self.update()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def delete(self, rows, parent=QModelIndex()):
|
def delete(self, rows, parent=QModelIndex()):
|
||||||
self.beginRemoveRows(parent, rows[0], rows[-1])
|
self.beginRemoveRows(parent, rows[0], rows[-1])
|
||||||
@@ -135,7 +135,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
self.update()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_up(self, row, parent=QModelIndex()):
|
def move_up(self, row, parent=QModelIndex()):
|
||||||
if row <= 0:
|
if row <= 0:
|
||||||
@@ -152,7 +152,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.endMoveRows()
|
self.endMoveRows()
|
||||||
self.update()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def move_down(self, index, parent=QModelIndex()):
|
def move_down(self, index, parent=QModelIndex()):
|
||||||
if row > len(self._data):
|
if row > len(self._data):
|
||||||
@@ -169,7 +169,7 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.endMoveRows()
|
self.endMoveRows()
|
||||||
self.update()
|
self.layoutChanged.emit()
|
||||||
|
|
||||||
def paste(self, row, header, data):
|
def paste(self, row, header, data):
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
@@ -190,13 +190,4 @@ class TableModel(PamhyrTableModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
self.layoutAboutToBeChanged.emit()
|
||||||
self.update()
|
|
||||||
|
|
||||||
def auto_sort(self):
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
|
||||||
self._data.sort(key=lambda x: x[0])
|
|
||||||
self.layoutAboutToBeChanged.emit()
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
# self.auto_sort()
|
|
||||||
self.layoutChanged.emit()
|
self.layoutChanged.emit()
|
||||||
@@ -137,7 +137,6 @@ class EditLateralContributionWindow(PamhyrWindow):
|
|||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
|
|
||||||
self._table.dataChanged.connect(self.update)
|
self._table.dataChanged.connect(self.update)
|
||||||
self._table.layoutChanged.connect(self.update)
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -1,260 +0,0 @@
|
|||||||
# PlotXY.py -- Pamhyr
|
|
||||||
# Copyright (C) 2023-2024 INRAE
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from tools import timer, trace
|
|
||||||
from View.Tools.PamhyrPlot import PamhyrPlot
|
|
||||||
from matplotlib import collections
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
|
||||||
QCoreApplication, Qt, QItemSelectionModel,
|
|
||||||
QItemSelection, QItemSelectionRange,
|
|
||||||
)
|
|
||||||
from PyQt5.QtWidgets import QApplication, QTableView
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
|
||||||
|
|
||||||
|
|
||||||
class PlotXY(PamhyrPlot):
|
|
||||||
def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
|
|
||||||
table=None, parent=None):
|
|
||||||
super(PlotXY, self).__init__(
|
|
||||||
canvas=canvas,
|
|
||||||
trad=trad,
|
|
||||||
data=data,
|
|
||||||
toolbar=toolbar,
|
|
||||||
table=table,
|
|
||||||
parent=parent
|
|
||||||
)
|
|
||||||
|
|
||||||
self.line_xy = []
|
|
||||||
self.line_gl = []
|
|
||||||
|
|
||||||
self.label_x = self._trad["x"]
|
|
||||||
self.label_y = self._trad["y"]
|
|
||||||
|
|
||||||
self.before_plot_selected = None
|
|
||||||
self.plot_selected = None
|
|
||||||
self.after_plot_selected = None
|
|
||||||
self.parent = parent
|
|
||||||
self.line_xy_collection = None
|
|
||||||
self._table = table
|
|
||||||
self._colors = []
|
|
||||||
self._style = []
|
|
||||||
|
|
||||||
def onpick(self, event):
|
|
||||||
if event.mouseevent.inaxes != self.canvas.axes:
|
|
||||||
return
|
|
||||||
if event.mouseevent.button.value not in [1, 3]:
|
|
||||||
return
|
|
||||||
|
|
||||||
closest = self._closest_section(event)
|
|
||||||
t = self.parent.current_tab()
|
|
||||||
tableView = self.parent.find(QTableView, f"tableView_{t}")
|
|
||||||
table = self.parent._table[t]
|
|
||||||
index = tableView.selectedIndexes()
|
|
||||||
kp = self.data.get_kp()
|
|
||||||
if self.parent._table is not None:
|
|
||||||
if event.mouseevent.button.value == 1:
|
|
||||||
table.setData(index[3], kp[closest[0]])
|
|
||||||
if event.mouseevent.button.value == 3:
|
|
||||||
table.setData(index[4], kp[closest[0]])
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _closest_section(self, event):
|
|
||||||
axes = self.canvas.axes
|
|
||||||
mx = event.mouseevent.xdata
|
|
||||||
my = event.mouseevent.ydata
|
|
||||||
bx, by = axes.get_xlim(), axes.get_ylim()
|
|
||||||
ratio = (bx[0] - bx[1]) / (by[0] - by[1])
|
|
||||||
|
|
||||||
segments = event.artist.get_segments()
|
|
||||||
ind = event.ind
|
|
||||||
|
|
||||||
points = []
|
|
||||||
for i in ind:
|
|
||||||
points = points + [[i, j] for j in segments[i]]
|
|
||||||
|
|
||||||
def dist_mouse(point):
|
|
||||||
x, y = point[1]
|
|
||||||
d2 = (((mx - x) / ratio) ** 2) + ((my - y) ** 2)
|
|
||||||
return d2
|
|
||||||
|
|
||||||
closest = min(
|
|
||||||
points, key=dist_mouse
|
|
||||||
)
|
|
||||||
|
|
||||||
return closest
|
|
||||||
|
|
||||||
@timer
|
|
||||||
def draw(self):
|
|
||||||
self.init_axes()
|
|
||||||
|
|
||||||
if self.data is None:
|
|
||||||
self.idle()
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.data.number_profiles == 0:
|
|
||||||
self._init = False
|
|
||||||
self.idle()
|
|
||||||
return
|
|
||||||
|
|
||||||
self.draw_xy()
|
|
||||||
self.draw_lr()
|
|
||||||
self.draw_gl()
|
|
||||||
|
|
||||||
self.idle()
|
|
||||||
self._init = True
|
|
||||||
|
|
||||||
def draw_xy(self):
|
|
||||||
self.line_xy = []
|
|
||||||
for xy in zip(self.data.get_x(), self.data.get_y()):
|
|
||||||
self.line_xy.append(np.column_stack(xy))
|
|
||||||
|
|
||||||
self._colors, self._style = self.color_hightlight()
|
|
||||||
self.line_xy_collection = collections.LineCollection(
|
|
||||||
self.line_xy,
|
|
||||||
colors=self._colors,
|
|
||||||
linestyle=self._style,
|
|
||||||
picker=10
|
|
||||||
)
|
|
||||||
self.canvas.axes.add_collection(self.line_xy_collection)
|
|
||||||
|
|
||||||
def color_hightlight(self):
|
|
||||||
kp_min, kp_max = (-1, -1)
|
|
||||||
if self._highlight_data is not None:
|
|
||||||
kp_min, kp_max = self._highlight_data
|
|
||||||
|
|
||||||
colors = [self.color_plot for row in range(len(self._data))]
|
|
||||||
for i, kp in enumerate(self.data.get_kp_complete_profiles()):
|
|
||||||
if kp_min <= kp <= kp_max:
|
|
||||||
colors[i] = self.color_plot_current
|
|
||||||
style = ["-" for row in range(len(self._data))]
|
|
||||||
|
|
||||||
return colors, style
|
|
||||||
|
|
||||||
def draw_lr(self):
|
|
||||||
lx = []
|
|
||||||
ly = []
|
|
||||||
rx = []
|
|
||||||
ry = []
|
|
||||||
|
|
||||||
self.line_lr = []
|
|
||||||
for x, y in zip(self.data.get_x(),
|
|
||||||
self.data.get_y()):
|
|
||||||
lx.append(x[0])
|
|
||||||
ly.append(y[0])
|
|
||||||
|
|
||||||
rx.append(x[-1])
|
|
||||||
ry.append(y[-1])
|
|
||||||
|
|
||||||
line = self.canvas.axes.plot(
|
|
||||||
lx, ly,
|
|
||||||
color=self.color_plot_river_bottom,
|
|
||||||
linestyle="dotted",
|
|
||||||
lw=1.,
|
|
||||||
)
|
|
||||||
self.line_lr.append(line)
|
|
||||||
|
|
||||||
line = self.canvas.axes.plot(
|
|
||||||
rx, ry,
|
|
||||||
color=self.color_plot_river_bottom,
|
|
||||||
linestyle="dotted",
|
|
||||||
lw=1.,
|
|
||||||
)
|
|
||||||
self.line_lr.append(line)
|
|
||||||
|
|
||||||
def draw_gl(self):
|
|
||||||
x_complete = self.data.get_guidelines_x()
|
|
||||||
y_complete = self.data.get_guidelines_y()
|
|
||||||
|
|
||||||
ind = 0
|
|
||||||
self.line_gl = []
|
|
||||||
for x, y in zip(x_complete, y_complete):
|
|
||||||
line = self.canvas.axes.plot(
|
|
||||||
x, y, color=self.colors[ind % len(self.colors)],
|
|
||||||
linestyle=self.linestyle[ind // len(self.colors)]
|
|
||||||
)
|
|
||||||
self.line_gl.append(line)
|
|
||||||
ind += 1
|
|
||||||
|
|
||||||
@timer
|
|
||||||
def update(self):
|
|
||||||
if not self._init:
|
|
||||||
self.draw()
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.data is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
self.update_lr()
|
|
||||||
self.update_gl()
|
|
||||||
self.update_current()
|
|
||||||
|
|
||||||
self.update_idle()
|
|
||||||
|
|
||||||
def update_gl(self):
|
|
||||||
self.data.compute_guidelines()
|
|
||||||
x_complete = list(self.data.get_guidelines_x())
|
|
||||||
y_complete = list(self.data.get_guidelines_y())
|
|
||||||
|
|
||||||
# TODO comprendre à quoi sert ce bout de code
|
|
||||||
# ========>
|
|
||||||
# for i in range(self.data.number_profiles):
|
|
||||||
# if i < len(self.line_xy):
|
|
||||||
# self.line_xy[i][0].set_data(
|
|
||||||
# self.data.profile(i).x(),
|
|
||||||
# self.data.profile(i).y()
|
|
||||||
# )
|
|
||||||
# else:
|
|
||||||
# self.line_xy.append(
|
|
||||||
# self.canvas.axes.plot(
|
|
||||||
# self.data.profile(i).x(),
|
|
||||||
# self.data.profile(i).y(),
|
|
||||||
# color='r',
|
|
||||||
# **self.plot_default_kargs
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# <========
|
|
||||||
|
|
||||||
for i in range(len(x_complete)):
|
|
||||||
if i < len(self.line_gl):
|
|
||||||
self.line_gl[i][0].set_data(
|
|
||||||
x_complete[i],
|
|
||||||
y_complete[i]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.line_gl.append(
|
|
||||||
self.canvas.axes.plot(
|
|
||||||
x_complete[i],
|
|
||||||
y_complete[i]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def update_current(self):
|
|
||||||
if self._current_data_update:
|
|
||||||
self._colors, self._style = self.color_hightlight()
|
|
||||||
self.line_xy_collection.set_colors(self._colors)
|
|
||||||
self.line_xy_collection.set_linestyle(self._style)
|
|
||||||
|
|
||||||
def update_lr(self):
|
|
||||||
for line in self.line_lr:
|
|
||||||
line[0].remove()
|
|
||||||
|
|
||||||
self.draw_lr()
|
|
||||||
@@ -54,7 +54,7 @@ from View.LateralContribution.Table import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.LateralContribution.PlotXY import PlotXY
|
from View.Geometry.PlotXY import PlotXY
|
||||||
from View.LateralContribution.translate import (
|
from View.LateralContribution.translate import (
|
||||||
LC_types, LCTranslate,
|
LC_types, LCTranslate,
|
||||||
)
|
)
|
||||||
@@ -83,7 +83,6 @@ class LateralContributionWindow(PamhyrWindow):
|
|||||||
|
|
||||||
self.setup_table()
|
self.setup_table()
|
||||||
self.setup_graph()
|
self.setup_graph()
|
||||||
self.tabs = self.find(QTabWidget, "tabWidget")
|
|
||||||
self.setup_connections()
|
self.setup_connections()
|
||||||
|
|
||||||
def setup_table(self):
|
def setup_table(self):
|
||||||
@@ -149,7 +148,6 @@ class LateralContributionWindow(PamhyrWindow):
|
|||||||
data=None,
|
data=None,
|
||||||
trad=self._trad,
|
trad=self._trad,
|
||||||
toolbar=None,
|
toolbar=None,
|
||||||
parent=self
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def setup_connections(self):
|
def setup_connections(self):
|
||||||
@@ -158,8 +156,6 @@ class LateralContributionWindow(PamhyrWindow):
|
|||||||
self.find(QAction, "action_edit").triggered.connect(self.edit)
|
self.find(QAction, "action_edit").triggered.connect(self.edit)
|
||||||
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
self.find(QAction, "action_sort").triggered.connect(self.sort)
|
||||||
|
|
||||||
self.tabs.currentChanged.connect(self._set_current_reach)
|
|
||||||
|
|
||||||
for t in ["liquid", "solid", "suspenssion"]:
|
for t in ["liquid", "solid", "suspenssion"]:
|
||||||
table = self.find(QTableView, f"tableView_{t}")
|
table = self.find(QTableView, f"tableView_{t}")
|
||||||
table.selectionModel()\
|
table.selectionModel()\
|
||||||
@@ -220,7 +216,6 @@ class LateralContributionWindow(PamhyrWindow):
|
|||||||
data=data,
|
data=data,
|
||||||
trad=self._trad,
|
trad=self._trad,
|
||||||
toolbar=None,
|
toolbar=None,
|
||||||
parent=self
|
|
||||||
)
|
)
|
||||||
self.plot.highlight = highlight
|
self.plot.highlight = highlight
|
||||||
self.plot.update()
|
self.plot.update()
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
+2
-10
@@ -579,13 +579,9 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
if self._study.filename is None or self._study.filename == "":
|
if self._study.filename is None or self._study.filename == "":
|
||||||
options = QFileDialog.Options()
|
|
||||||
options |= QFileDialog.DontUseNativeDialog
|
|
||||||
|
|
||||||
file_name, _ = QFileDialog.getSaveFileName(
|
file_name, _ = QFileDialog.getSaveFileName(
|
||||||
self, "Save File",
|
self, "Save File",
|
||||||
"", "Pamhyr(*.pamhyr)",
|
"", "Pamhyr(*.pamhyr)"
|
||||||
options=options,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if file_name.rsplit(".", 1)[-1] == "pamhyr":
|
if file_name.rsplit(".", 1)[-1] == "pamhyr":
|
||||||
@@ -634,13 +630,9 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit):
|
|||||||
Returns:
|
Returns:
|
||||||
Nothing
|
Nothing
|
||||||
"""
|
"""
|
||||||
options = QFileDialog.Options()
|
|
||||||
options |= QFileDialog.DontUseNativeDialog
|
|
||||||
|
|
||||||
file_name, _ = QFileDialog.getSaveFileName(
|
file_name, _ = QFileDialog.getSaveFileName(
|
||||||
self, "Save File",
|
self, "Save File",
|
||||||
"", "Pamhyr(*.pamhyr)",
|
"", "Pamhyr(*.pamhyr)"
|
||||||
options=options,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(f"Save study as : {repr(file_name)}")
|
logger.debug(f"Save study as : {repr(file_name)}")
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -54,12 +54,10 @@ class NetworkTranslate(MainTranslate):
|
|||||||
self._sub_dict["table_headers_node"] = {
|
self._sub_dict["table_headers_node"] = {
|
||||||
"name": self._dict['name'],
|
"name": self._dict['name'],
|
||||||
"type": self._dict['type'],
|
"type": self._dict['type'],
|
||||||
"id": _translate("Network", "Index"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self._sub_dict["table_headers_edge"] = {
|
self._sub_dict["table_headers_edge"] = {
|
||||||
"name": self._dict['name'],
|
"name": self._dict['name'],
|
||||||
"node1": _translate("Network", "Source node"),
|
"node1": _translate("Network", "Source node"),
|
||||||
"node2": _translate("Network", "Destination node"),
|
"node2": _translate("Network", "Destination node"),
|
||||||
"id": _translate("Network", "Index"),
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
+12
-101
@@ -22,14 +22,10 @@ from functools import reduce
|
|||||||
|
|
||||||
from tools import timer, trace
|
from tools import timer, trace
|
||||||
from View.Tools.PamhyrPlot import PamhyrPlot
|
from View.Tools.PamhyrPlot import PamhyrPlot
|
||||||
import numpy as np
|
|
||||||
from matplotlib import collections
|
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QCoreApplication, Qt, QItemSelectionModel,
|
QCoreApplication
|
||||||
QItemSelection, QItemSelectionRange
|
|
||||||
)
|
)
|
||||||
from PyQt5.QtWidgets import QApplication, QTableView
|
|
||||||
|
|
||||||
_translate = QCoreApplication.translate
|
_translate = QCoreApplication.translate
|
||||||
|
|
||||||
@@ -61,73 +57,6 @@ class PlotXY(PamhyrPlot):
|
|||||||
self.label_y = _translate("Results", "Y (m)")
|
self.label_y = _translate("Results", "Y (m)")
|
||||||
|
|
||||||
self._isometric_axis = True
|
self._isometric_axis = True
|
||||||
self._tablemodel = parent._table["profile"]
|
|
||||||
self._table = parent.find(QTableView, f"tableView_profile")
|
|
||||||
|
|
||||||
def onpick(self, event):
|
|
||||||
if event.mouseevent.inaxes != self.canvas.axes:
|
|
||||||
return
|
|
||||||
if event.mouseevent.button.value != 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
modifiers = QApplication.keyboardModifiers()
|
|
||||||
if modifiers not in [Qt.ControlModifier,
|
|
||||||
Qt.NoModifier,
|
|
||||||
Qt.ShiftModifier]:
|
|
||||||
return
|
|
||||||
|
|
||||||
ind, point = self._closest_section(event)
|
|
||||||
if self._table is None:
|
|
||||||
return
|
|
||||||
self._select_in_table([ind])
|
|
||||||
self._table.blockSignals(False)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _closest_section(self, event):
|
|
||||||
axes = self.canvas.axes
|
|
||||||
mx = event.mouseevent.xdata
|
|
||||||
my = event.mouseevent.ydata
|
|
||||||
bx, by = axes.get_xlim(), axes.get_ylim()
|
|
||||||
ratio = (bx[0] - bx[1]) / (by[0] - by[1])
|
|
||||||
|
|
||||||
segments = event.artist.get_segments()
|
|
||||||
ind = event.ind
|
|
||||||
|
|
||||||
points = []
|
|
||||||
for i in ind:
|
|
||||||
points = points + [[i, j] for j in segments[i]]
|
|
||||||
|
|
||||||
def dist_mouse(point):
|
|
||||||
x, y = point[1]
|
|
||||||
d2 = (((mx - x) / ratio) ** 2) + ((my - y) ** 2)
|
|
||||||
return d2
|
|
||||||
|
|
||||||
closest = min(
|
|
||||||
points, key=dist_mouse
|
|
||||||
)
|
|
||||||
|
|
||||||
return closest
|
|
||||||
|
|
||||||
def _select_in_table(self, ind):
|
|
||||||
if self._table is None:
|
|
||||||
return
|
|
||||||
self._table.setFocus()
|
|
||||||
selection = self._table.selectionModel()
|
|
||||||
index = QItemSelection()
|
|
||||||
if len(ind) == 0:
|
|
||||||
return
|
|
||||||
for i in ind:
|
|
||||||
index.append(QItemSelectionRange(self._table.model().index(i, 0)))
|
|
||||||
selection.select(
|
|
||||||
index,
|
|
||||||
QItemSelectionModel.Rows |
|
|
||||||
QItemSelectionModel.ClearAndSelect |
|
|
||||||
QItemSelectionModel.Select
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(ind) > 0:
|
|
||||||
self._table.scrollTo(self._table.model().index(ind[-1], 0))
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def results(self):
|
def results(self):
|
||||||
@@ -161,36 +90,18 @@ class PlotXY(PamhyrPlot):
|
|||||||
self._init = False
|
self._init = False
|
||||||
return
|
return
|
||||||
|
|
||||||
self.line_xy = []
|
self.line_xy = [
|
||||||
for xy in zip(reach.geometry.get_x(),
|
self.canvas.axes.plot(
|
||||||
reach.geometry.get_y()):
|
x, y,
|
||||||
self.line_xy.append(np.column_stack(xy))
|
color=self.color_plot_river_bottom,
|
||||||
|
**self.plot_default_kargs
|
||||||
self._colors, self._style = self.color_hightlight()
|
|
||||||
self.line_xy_collection = collections.LineCollection(
|
|
||||||
self.line_xy,
|
|
||||||
colors=self._colors,
|
|
||||||
linestyle=self._style,
|
|
||||||
picker=10
|
|
||||||
)
|
)
|
||||||
self.canvas.axes.add_collection(self.line_xy_collection)
|
for x, y, kp in zip(
|
||||||
|
reach.geometry.get_x(),
|
||||||
def color_hightlight(self):
|
reach.geometry.get_y(),
|
||||||
reach = self.results.river.reach(self._current_reach_id)
|
reach.geometry.get_kp()
|
||||||
rows = [self._current_profile_id]
|
)
|
||||||
colors = [self.color_plot
|
]
|
||||||
for row in range(reach.geometry.number_profiles)]
|
|
||||||
style = ["-" for row in range(reach.geometry.number_profiles)]
|
|
||||||
if len(rows) > 0:
|
|
||||||
for row in rows:
|
|
||||||
colors[row] = self.color_plot_current
|
|
||||||
if rows[0] > 0:
|
|
||||||
colors[rows[0]-1] = self.color_plot_previous
|
|
||||||
style[rows[0]-1] = "--"
|
|
||||||
if rows[-1] < reach.geometry.number_profiles-1:
|
|
||||||
colors[rows[-1]+1] = self.color_plot_next
|
|
||||||
style[rows[-1]+1] = "--"
|
|
||||||
return colors, style
|
|
||||||
|
|
||||||
def draw_guide_lines(self, reach):
|
def draw_guide_lines(self, reach):
|
||||||
x_complete = reach.geometry.get_guidelines_x()
|
x_complete = reach.geometry.get_guidelines_x()
|
||||||
|
|||||||
@@ -176,8 +176,7 @@ class ResultsWindow(PamhyrWindow):
|
|||||||
profile_id=0,
|
profile_id=0,
|
||||||
trad=self._trad,
|
trad=self._trad,
|
||||||
toolbar=self.toolbar,
|
toolbar=self.toolbar,
|
||||||
display_current=True,
|
display_current=True
|
||||||
parent=self
|
|
||||||
)
|
)
|
||||||
self.plot_xy.draw()
|
self.plot_xy.draw()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -35,7 +35,7 @@ from PyQt5.QtWidgets import (
|
|||||||
QRadioButton, QComboBox, QFileDialog,
|
QRadioButton, QComboBox, QFileDialog,
|
||||||
QMessageBox, QTableView, QAction,
|
QMessageBox, QTableView, QAction,
|
||||||
QDateTimeEdit, QWidget, QPlainTextEdit,
|
QDateTimeEdit, QWidget, QPlainTextEdit,
|
||||||
QLabel, QDoubleSpinBox, QButtonGroup,
|
QLabel, QDoubleSpinBox,
|
||||||
)
|
)
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QTime, QDateTime,
|
QTime, QDateTime,
|
||||||
@@ -501,17 +501,6 @@ class ASubWindowFeatures(object):
|
|||||||
qdate = QDateTime.fromString(date.isoformat(), "yyyy-MM-ddThh:mm:ss")
|
qdate = QDateTime.fromString(date.isoformat(), "yyyy-MM-ddThh:mm:ss")
|
||||||
self.find(QDateTimeEdit, name).setDateTime(qdate)
|
self.find(QDateTimeEdit, name).setDateTime(qdate)
|
||||||
|
|
||||||
def get_checked_id_button_group(self, name: str):
|
|
||||||
"""Get current checked button id in a buttonGroup
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name: The buttonGroup component name
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Current checked id
|
|
||||||
"""
|
|
||||||
return self.find(QButtonGroup, name).checkedId()
|
|
||||||
|
|
||||||
|
|
||||||
# Top level interface
|
# Top level interface
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import matplotlib.colors as mplcolors
|
import matplotlib.colors as mplcolors
|
||||||
from matplotlib import ticker
|
from matplotlib import ticker
|
||||||
|
|
||||||
@@ -27,8 +25,6 @@ from View.Tools.Plot.APlot import APlot
|
|||||||
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
from View.Tools.Plot.PamhyrCanvas import MplCanvas
|
||||||
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
|
||||||
|
|
||||||
logger = logging.getLogger()
|
|
||||||
|
|
||||||
|
|
||||||
class PamhyrPlot(APlot):
|
class PamhyrPlot(APlot):
|
||||||
color_axes = "black"
|
color_axes = "black"
|
||||||
@@ -42,6 +38,7 @@ class PamhyrPlot(APlot):
|
|||||||
color_plot_river_bottom = "grey"
|
color_plot_river_bottom = "grey"
|
||||||
color_plot_river_water = "blue"
|
color_plot_river_water = "blue"
|
||||||
color_plot_river_water_zone = "skyblue"
|
color_plot_river_water_zone = "skyblue"
|
||||||
|
|
||||||
colors = list(mplcolors.TABLEAU_COLORS)
|
colors = list(mplcolors.TABLEAU_COLORS)
|
||||||
linestyle = ['solid', 'dashed', 'dashdot', 'dotted']
|
linestyle = ['solid', 'dashed', 'dashdot', 'dotted']
|
||||||
|
|
||||||
@@ -80,7 +77,6 @@ class PamhyrPlot(APlot):
|
|||||||
connector = {
|
connector = {
|
||||||
'pick_event': self.onpick,
|
'pick_event': self.onpick,
|
||||||
'button_press_event': self.onclick,
|
'button_press_event': self.onclick,
|
||||||
'button_release_event': self.onrelease,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in connector:
|
for event in connector:
|
||||||
@@ -104,7 +100,6 @@ class PamhyrPlot(APlot):
|
|||||||
self._highlight_data_update = False
|
self._highlight_data_update = False
|
||||||
self._current_data = None #: Current data identifier
|
self._current_data = None #: Current data identifier
|
||||||
self._current_data_update = False
|
self._current_data_update = False
|
||||||
self._rect_select = None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def canvas(self):
|
def canvas(self):
|
||||||
@@ -236,13 +231,3 @@ class PamhyrPlot(APlot):
|
|||||||
|
|
||||||
def onclick(self, event):
|
def onclick(self, event):
|
||||||
return
|
return
|
||||||
|
|
||||||
def onrelease(self, event):
|
|
||||||
return
|
|
||||||
|
|
||||||
def rect_select_callback(self, eclick, erelease):
|
|
||||||
'eclick and erelease are the press and release events'
|
|
||||||
x1, y1 = eclick.xdata, eclick.ydata
|
|
||||||
x2, y2 = erelease.xdata, erelease.ydata
|
|
||||||
logging.debug("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
|
|
||||||
return
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -28,6 +28,49 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTableView" name="tableView"/>
|
<widget class="QTableView" name="tableView"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_up">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>ressources/up.png</normaloff>ressources/up.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="verticalSlider">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="invertedAppearance">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="invertedControls">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_down">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>ressources/down.png</normaloff>ressources/down.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QSplitter" name="splitter_2">
|
<widget class="QSplitter" name="splitter_2">
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>284</width>
|
<width>284</width>
|
||||||
<height>107</height>
|
<height>80</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -17,16 +17,6 @@
|
|||||||
<locale language="English" country="Europe"/>
|
<locale language="English" country="Europe"/>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
@@ -49,12 +39,12 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="text">
|
<property name="orientation">
|
||||||
<string>Generate height</string>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="standardButtons">
|
||||||
<bool>true</bool>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -17,16 +17,6 @@
|
|||||||
<locale language="English" country="Europe"/>
|
<locale language="English" country="Europe"/>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
@@ -39,19 +29,19 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox">
|
<widget class="QDoubleSpinBox" name="doubleSpinBox">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>1000000.000000000000000</double>
|
<double>999999.998999999952503</double>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="text">
|
<property name="orientation">
|
||||||
<string>Generate discharge</string>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="standardButtons">
|
||||||
<bool>true</bool>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -6,23 +6,37 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>381</width>
|
<width>340</width>
|
||||||
<height>302</height>
|
<height>204</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Dialog</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="layoutDirection">
|
|
||||||
<enum>Qt::LeftToRight</enum>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Distance computation</string>
|
<string>Distance computation</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QComboBox" name="comboBox_end_gl">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_6">
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
@@ -33,17 +47,11 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QRadioButton" name="radioButton_1">
|
<widget class="QComboBox" name="comboBox_begin_gl">
|
||||||
<property name="text">
|
<property name="enabled">
|
||||||
<string>Upstream to downstream</string>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">buttonGroup_orientation</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
@@ -59,6 +67,20 @@
|
|||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QComboBox" name="comboBox_origin"/>
|
<widget class="QComboBox" name="comboBox_origin"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Origin</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Origin value</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_origin">
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_origin">
|
||||||
<property name="decimals">
|
<property name="decimals">
|
||||||
@@ -72,80 +94,9 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Origin</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QComboBox" name="comboBox_begin_gl">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Origin value</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
|
||||||
<widget class="QRadioButton" name="radioButton_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Downstream to upstream</string>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">buttonGroup_orientation</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QComboBox" name="comboBox_end_gl">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="text">
|
|
||||||
<string>Orientation</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QRadioButton" name="radioButton_0">
|
|
||||||
<property name="layoutDirection">
|
|
||||||
<enum>Qt::LeftToRight</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Keep current</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="buttonGroup">
|
|
||||||
<string notr="true">buttonGroup_orientation</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
@@ -183,7 +134,4 @@
|
|||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<buttongroups>
|
|
||||||
<buttongroup name="buttonGroup_orientation"/>
|
|
||||||
</buttongroups>
|
|
||||||
</ui>
|
</ui>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# __init__.py -- Pamhyr
|
||||||
|
# Copyright (C) 2023-2024 INRAE
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
@@ -302,7 +302,10 @@ def timestamp_to_old_pamhyr_date(time: int):
|
|||||||
|
|
||||||
def get_user_name():
|
def get_user_name():
|
||||||
if with_pwd:
|
if with_pwd:
|
||||||
|
try:
|
||||||
return pwd.getpwuid(os.getuid()).pw_gecos
|
return pwd.getpwuid(os.getuid()).pw_gecos
|
||||||
|
except:
|
||||||
|
return "Me"
|
||||||
else:
|
else:
|
||||||
return "Me"
|
return "Me"
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user