Skip to content

Commit

Permalink
Merge pull request #29 from PnX-SI/feat/de-activate-areas
Browse files Browse the repository at this point in the history
feat (commands) : activate/deactivate areas
  • Loading branch information
jacquesfize authored Jul 11, 2024
2 parents b24632f + c86a754 commit 620d5db
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 13 deletions.
25 changes: 13 additions & 12 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@ jobs:
strategy:
fail-fast: false
matrix:
debian-version: [ '11', '12' ]
sqlalchemy-version: [ '1.4' ]
debian-version: ['11', '12']
sqlalchemy-version: ['1.4']
include:
- debian-version: "11"
python-version: "3.9"
postgres-version: "13"
postgis-version: "3.2"
- debian-version: "12"
python-version: "3.11"
postgres-version: "15"
postgis-version: "3.3"
- debian-version: '11'
python-version: '3.9'
postgres-version: '13'
postgis-version: '3.2'
- debian-version: '12'
python-version: '3.11'
postgres-version: '15'
postgis-version: '3.3'

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

env:
REF_GEO_SQLALCHEMY_DATABASE_URI: "postgresql://geouser:[email protected]:5432/refgeo"
REF_GEO_SQLALCHEMY_DATABASE_URI: 'postgresql://geouser:[email protected]:5432/refgeo'

services:
postgres:
Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
cache: 'pip'
- name: Install GDAL
run: |
sudo apt update
Expand All @@ -85,6 +85,7 @@ jobs:
run: |
flask db upgrade ref_geo@head -x local-srid=2154
flask db upgrade ref_geo_fr_municipalities@head
flask db upgrade ref_geo_fr_departments@head
flask db upgrade ref_geo_inpn_grids_5@head
flask db upgrade ref_geo_inpn_grids_20@head
- name: Show database status
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ CHANGELOG
-----------------------------

- 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)
- Ajout des commandes `flask ref_geo activate` et `flask ref_geo deactivate` pour activer/desactiver des zonages dans le référentiel géographique:
- par type de zonage `flask ref_geo activate --area-type COM --area-type DEP`
- par nom de zonage `flask ref_geo activate --area-name Ain --area-name Hautes-Alpes`
- par code de zonage (voir `l_areas.area_code`): `flask ref_geo activate --area-code 01`
- 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))'`

**⚠️ Notes de version**

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



1.5.1 (2024-01-29)
------------------

Expand Down
95 changes: 95 additions & 0 deletions src/ref_geo/commands.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import click
from flask.cli import with_appcontext
from sqlalchemy import func, select
import sqlalchemy as sa

from ref_geo.env import db
from ref_geo.models import BibAreasTypes, LAreas
Expand All @@ -23,3 +24,97 @@ def info():
)
for area_type, count in db.session.scalars(q).unique().all():
click.echo("\t{}: {}".format(area_type.type_name, count))


def change_area_activation_status(
area_code=None, area_name=None, area_type=None, in_polygon=None, enable=True
):
"""
Change the activation status of areas in the geographical referential.
Parameters
----------
area_code : list of str
List of area codes to activate or deactivate.
area_name : list of str
List of area names to activate or deactivate.
area_type : list of str
List of area types to activate or deactivate. The type codes are
checked in the `bib_areas_types` table.
in_polygon : str
WKT polygon defined in WGS84 coordinate reference system. The
areas inside the polygon will be activated or deactivated.
enable : bool
If True, the areas will be activated, otherwise they will be
deactivated.
"""
str_ = "activated" if enable else "deactivated"
if area_code:
click.echo("The following area codes will be {}: {}".format(str_, ", ".join(area_code)))
q = sa.update(LAreas).where(LAreas.area_code.in_(area_code)).values(enable=enable)
db.session.execute(q)
if area_name:
click.echo("The following area names will be {}: {}".format(str_, ", ".join(area_name)))
q = sa.update(LAreas).where(LAreas.area_name.in_(area_name)).values(enable=enable)
db.session.execute(q)
if area_type:
click.echo("The following area types will be {}: {}".format(str_, ", ".join(area_type)))
area_type_ids = db.session.scalars(
select(BibAreasTypes.id_type).where(BibAreasTypes.type_code.in_(area_type))
).all()
q = sa.update(LAreas).where(LAreas.id_type.in_(area_type_ids)).values(enable=enable)
db.session.execute(q)
if in_polygon:
click.echo(
"The following areas will be {} in the following polygon: {}".format(str_, in_polygon)
)
in_polygon_cte = select(
LAreas.id_area, func.ST_Intersects(LAreas.geom_4326, func.ST_GeomFromText(in_polygon))
).cte("in_polygon")
q = (
sa.update(LAreas)
.where(in_polygon_cte.c.id_area == LAreas.id_area)
.values(enable=enable)
)
db.session.execute(q)
db.session.commit()


@ref_geo.command()
@click.option("--area-code", "-a", multiple=True, help="Areas' code to deactivate")
@click.option("--area-name", "-n", multiple=True, help="Areas' name to deactivate")
@click.option(
"--area-type",
"-t",
multiple=True,
help="Area type to deactivate (check `type_code` in `bib_areas_types` table)",
)
@click.option(
"--in-polygon",
"-p",
help="Indicate a polygon in which areas will be deactivated. Must be in WKT format (SRID 4326)",
)
@with_appcontext
def deactivate(area_code, area_name, area_type, in_polygon):
click.echo("RefGeo : deactivating areas...")
change_area_activation_status(area_code, area_name, area_type, in_polygon, False)


@ref_geo.command()
@click.option("--area-code", "-a", multiple=True, help="Areas' code to activate")
@click.option("--area-name", "-n", multiple=True, help="Areas' name to activate")
@click.option(
"--area-type",
"-t",
multiple=True,
help="Area type to activate (check `type_code` in `bib_areas_types` table)",
)
@click.option(
"--in-polygon",
"-p",
help="Indicate a polygon in which areas will be activated. Must be in WKT format (SRID 4326)",
)
@with_appcontext
def activate(area_code, area_name, area_type, in_polygon):
click.echo("RefGeo : activating areas...")
change_area_activation_status(area_code, area_name, area_type, in_polygon, True)
38 changes: 37 additions & 1 deletion src/ref_geo/tests/test_ref_geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

from flask import url_for, current_app
from flask_migrate import Migrate
from ref_geo.commands import change_area_activation_status
from werkzeug.exceptions import Unauthorized, BadRequest
from jsonschema import validate as validate_json
from alembic.migration import MigrationContext
from alembic.script import ScriptDirectory

from ref_geo.env import db
from ref_geo.models import BibAreasTypes, LAreas
from sqlalchemy import select
from sqlalchemy import select, update


polygon = {
Expand All @@ -29,6 +30,17 @@
}

CITY = "La Motte-en-Champsaur"
PARAMETER_ENABLE = [
(dict(area_code=["50120"]), "50120"),
(dict(area_name=["Ain"]), "01"),
(dict(area_type=["COM"]), "01005"),
(
dict(
in_polygon="POLYGON ((-1.653442 49.628504, -1.588898 49.628504, -1.588898 49.653849, -1.653442 49.653849, -1.653442 49.628504))"
),
"50129",
),
]


def has_french_dem():
Expand Down Expand Up @@ -436,3 +448,27 @@ def test_get_types_by_name(self, area_commune):
)
assert response.status_code == 200
assert len(response.json) > 0

@pytest.mark.parametrize(
"parameters,expected_area_code",
PARAMETER_ENABLE,
)
def test_activate_areas(self, parameters, expected_area_code):
db.session.execute(
update(LAreas).where(LAreas.area_code == expected_area_code).values(enable=False)
)
change_area_activation_status(**parameters, enable=True)
q = select(LAreas.enable).where(LAreas.area_code == expected_area_code)
assert db.session.scalar(q) == True

@pytest.mark.parametrize(
"parameters,expected_area_code",
PARAMETER_ENABLE,
)
def test_deactivate_areas(self, parameters, expected_area_code):
db.session.execute(
update(LAreas).where(LAreas.area_code == expected_area_code).values(enable=True)
)
change_area_activation_status(**parameters, enable=False)
q = select(LAreas.enable).where(LAreas.area_code == expected_area_code)
assert db.session.scalar(q) == False

0 comments on commit 620d5db

Please sign in to comment.