Skip to content

Commit 620d5db

Browse files
authored
Merge pull request #29 from PnX-SI/feat/de-activate-areas
feat (commands) : activate/deactivate areas
2 parents b24632f + c86a754 commit 620d5db

File tree

4 files changed

+151
-13
lines changed

4 files changed

+151
-13
lines changed

.github/workflows/pytest.yml

+13-12
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@ jobs:
1717
strategy:
1818
fail-fast: false
1919
matrix:
20-
debian-version: [ '11', '12' ]
21-
sqlalchemy-version: [ '1.4' ]
20+
debian-version: ['11', '12']
21+
sqlalchemy-version: ['1.4']
2222
include:
23-
- debian-version: "11"
24-
python-version: "3.9"
25-
postgres-version: "13"
26-
postgis-version: "3.2"
27-
- debian-version: "12"
28-
python-version: "3.11"
29-
postgres-version: "15"
30-
postgis-version: "3.3"
23+
- debian-version: '11'
24+
python-version: '3.9'
25+
postgres-version: '13'
26+
postgis-version: '3.2'
27+
- debian-version: '12'
28+
python-version: '3.11'
29+
postgres-version: '15'
30+
postgis-version: '3.3'
3131

3232
name: Debian ${{ matrix.debian-version}} - SQLAlchemy ${{ matrix.sqlalchemy-version }}
3333

3434
env:
35-
REF_GEO_SQLALCHEMY_DATABASE_URI: "postgresql://geouser:[email protected]:5432/refgeo"
35+
REF_GEO_SQLALCHEMY_DATABASE_URI: 'postgresql://geouser:[email protected]:5432/refgeo'
3636

3737
services:
3838
postgres:
@@ -66,7 +66,7 @@ jobs:
6666
uses: actions/setup-python@v4
6767
with:
6868
python-version: ${{ matrix.python-version }}
69-
cache: "pip"
69+
cache: 'pip'
7070
- name: Install GDAL
7171
run: |
7272
sudo apt update
@@ -85,6 +85,7 @@ jobs:
8585
run: |
8686
flask db upgrade ref_geo@head -x local-srid=2154
8787
flask db upgrade ref_geo_fr_municipalities@head
88+
flask db upgrade ref_geo_fr_departments@head
8889
flask db upgrade ref_geo_inpn_grids_5@head
8990
flask db upgrade ref_geo_inpn_grids_20@head
9091
- name: Show database status

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ CHANGELOG
55
-----------------------------
66

77
- Ajout des nouvelles mailles officielles de l'INPN en métropole (2x2km, 20x20km, 50x50km), utilisées par la nouvelle version du référentiel de sensibilité (#24, par @lpofredc)
8+
- Ajout des commandes `flask ref_geo activate` et `flask ref_geo deactivate` pour activer/desactiver des zonages dans le référentiel géographique:
9+
- par type de zonage `flask ref_geo activate --area-type COM --area-type DEP`
10+
- par nom de zonage `flask ref_geo activate --area-name Ain --area-name Hautes-Alpes`
11+
- par code de zonage (voir `l_areas.area_code`): `flask ref_geo activate --area-code 01`
12+
- par géométrie : `flask ref_geo activate --area-type in-polygon 'POLYGON ((-1.653442 49.628504, -1.588898 49.628504, -1.588898 49.653849, -1.653442 49.653849, -1.653442 49.628504))'`
813

914
**⚠️ Notes de version**
1015

@@ -36,6 +41,7 @@ alembic upgrade ref_geo_inpn_grids_50@head # Insertion des mailles 50x50km mét
3641
- Possibilité d'appeler la route `GET/areas` sans retourner les géométries (#22)
3742

3843

44+
3945
1.5.1 (2024-01-29)
4046
------------------
4147

src/ref_geo/commands.py

+95
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import click
22
from flask.cli import with_appcontext
33
from sqlalchemy import func, select
4+
import sqlalchemy as sa
45

56
from ref_geo.env import db
67
from ref_geo.models import BibAreasTypes, LAreas
@@ -23,3 +24,97 @@ def info():
2324
)
2425
for area_type, count in db.session.scalars(q).unique().all():
2526
click.echo("\t{}: {}".format(area_type.type_name, count))
27+
28+
29+
def change_area_activation_status(
30+
area_code=None, area_name=None, area_type=None, in_polygon=None, enable=True
31+
):
32+
"""
33+
Change the activation status of areas in the geographical referential.
34+
35+
Parameters
36+
----------
37+
area_code : list of str
38+
List of area codes to activate or deactivate.
39+
area_name : list of str
40+
List of area names to activate or deactivate.
41+
area_type : list of str
42+
List of area types to activate or deactivate. The type codes are
43+
checked in the `bib_areas_types` table.
44+
in_polygon : str
45+
WKT polygon defined in WGS84 coordinate reference system. The
46+
areas inside the polygon will be activated or deactivated.
47+
enable : bool
48+
If True, the areas will be activated, otherwise they will be
49+
deactivated.
50+
"""
51+
str_ = "activated" if enable else "deactivated"
52+
if area_code:
53+
click.echo("The following area codes will be {}: {}".format(str_, ", ".join(area_code)))
54+
q = sa.update(LAreas).where(LAreas.area_code.in_(area_code)).values(enable=enable)
55+
db.session.execute(q)
56+
if area_name:
57+
click.echo("The following area names will be {}: {}".format(str_, ", ".join(area_name)))
58+
q = sa.update(LAreas).where(LAreas.area_name.in_(area_name)).values(enable=enable)
59+
db.session.execute(q)
60+
if area_type:
61+
click.echo("The following area types will be {}: {}".format(str_, ", ".join(area_type)))
62+
area_type_ids = db.session.scalars(
63+
select(BibAreasTypes.id_type).where(BibAreasTypes.type_code.in_(area_type))
64+
).all()
65+
q = sa.update(LAreas).where(LAreas.id_type.in_(area_type_ids)).values(enable=enable)
66+
db.session.execute(q)
67+
if in_polygon:
68+
click.echo(
69+
"The following areas will be {} in the following polygon: {}".format(str_, in_polygon)
70+
)
71+
in_polygon_cte = select(
72+
LAreas.id_area, func.ST_Intersects(LAreas.geom_4326, func.ST_GeomFromText(in_polygon))
73+
).cte("in_polygon")
74+
q = (
75+
sa.update(LAreas)
76+
.where(in_polygon_cte.c.id_area == LAreas.id_area)
77+
.values(enable=enable)
78+
)
79+
db.session.execute(q)
80+
db.session.commit()
81+
82+
83+
@ref_geo.command()
84+
@click.option("--area-code", "-a", multiple=True, help="Areas' code to deactivate")
85+
@click.option("--area-name", "-n", multiple=True, help="Areas' name to deactivate")
86+
@click.option(
87+
"--area-type",
88+
"-t",
89+
multiple=True,
90+
help="Area type to deactivate (check `type_code` in `bib_areas_types` table)",
91+
)
92+
@click.option(
93+
"--in-polygon",
94+
"-p",
95+
help="Indicate a polygon in which areas will be deactivated. Must be in WKT format (SRID 4326)",
96+
)
97+
@with_appcontext
98+
def deactivate(area_code, area_name, area_type, in_polygon):
99+
click.echo("RefGeo : deactivating areas...")
100+
change_area_activation_status(area_code, area_name, area_type, in_polygon, False)
101+
102+
103+
@ref_geo.command()
104+
@click.option("--area-code", "-a", multiple=True, help="Areas' code to activate")
105+
@click.option("--area-name", "-n", multiple=True, help="Areas' name to activate")
106+
@click.option(
107+
"--area-type",
108+
"-t",
109+
multiple=True,
110+
help="Area type to activate (check `type_code` in `bib_areas_types` table)",
111+
)
112+
@click.option(
113+
"--in-polygon",
114+
"-p",
115+
help="Indicate a polygon in which areas will be activated. Must be in WKT format (SRID 4326)",
116+
)
117+
@with_appcontext
118+
def activate(area_code, area_name, area_type, in_polygon):
119+
click.echo("RefGeo : activating areas...")
120+
change_area_activation_status(area_code, area_name, area_type, in_polygon, True)

src/ref_geo/tests/test_ref_geo.py

+37-1
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33

44
from flask import url_for, current_app
55
from flask_migrate import Migrate
6+
from ref_geo.commands import change_area_activation_status
67
from werkzeug.exceptions import Unauthorized, BadRequest
78
from jsonschema import validate as validate_json
89
from alembic.migration import MigrationContext
910
from alembic.script import ScriptDirectory
1011

1112
from ref_geo.env import db
1213
from ref_geo.models import BibAreasTypes, LAreas
13-
from sqlalchemy import select
14+
from sqlalchemy import select, update
1415

1516

1617
polygon = {
@@ -29,6 +30,17 @@
2930
}
3031

3132
CITY = "La Motte-en-Champsaur"
33+
PARAMETER_ENABLE = [
34+
(dict(area_code=["50120"]), "50120"),
35+
(dict(area_name=["Ain"]), "01"),
36+
(dict(area_type=["COM"]), "01005"),
37+
(
38+
dict(
39+
in_polygon="POLYGON ((-1.653442 49.628504, -1.588898 49.628504, -1.588898 49.653849, -1.653442 49.653849, -1.653442 49.628504))"
40+
),
41+
"50129",
42+
),
43+
]
3244

3345

3446
def has_french_dem():
@@ -436,3 +448,27 @@ def test_get_types_by_name(self, area_commune):
436448
)
437449
assert response.status_code == 200
438450
assert len(response.json) > 0
451+
452+
@pytest.mark.parametrize(
453+
"parameters,expected_area_code",
454+
PARAMETER_ENABLE,
455+
)
456+
def test_activate_areas(self, parameters, expected_area_code):
457+
db.session.execute(
458+
update(LAreas).where(LAreas.area_code == expected_area_code).values(enable=False)
459+
)
460+
change_area_activation_status(**parameters, enable=True)
461+
q = select(LAreas.enable).where(LAreas.area_code == expected_area_code)
462+
assert db.session.scalar(q) == True
463+
464+
@pytest.mark.parametrize(
465+
"parameters,expected_area_code",
466+
PARAMETER_ENABLE,
467+
)
468+
def test_deactivate_areas(self, parameters, expected_area_code):
469+
db.session.execute(
470+
update(LAreas).where(LAreas.area_code == expected_area_code).values(enable=True)
471+
)
472+
change_area_activation_status(**parameters, enable=False)
473+
q = select(LAreas.enable).where(LAreas.area_code == expected_area_code)
474+
assert db.session.scalar(q) == False

0 commit comments

Comments
 (0)