diff --git a/envergo/geodata/admin.py b/envergo/geodata/admin.py index 87115898e..c7bb60c34 100644 --- a/envergo/geodata/admin.py +++ b/envergo/geodata/admin.py @@ -9,7 +9,7 @@ from envergo.geodata.forms import DepartmentForm from envergo.geodata.models import Department, Map, Parcel, Zone -from envergo.geodata.tasks import process_shapefile_map +from envergo.geodata.tasks import generate_map_preview, process_shapefile_map from envergo.geodata.utils import count_features, extract_shapefile @@ -60,7 +60,7 @@ def queryset(self, request, queryset): @admin.register(Map) -class MapAdmin(admin.ModelAdmin): +class MapAdmin(gis_admin.GISModelAdmin): form = MapForm list_display = [ "name", @@ -80,7 +80,7 @@ class MapAdmin(admin.ModelAdmin): "task_status", "import_error_msg", ] - actions = ["process"] + actions = ["process", "generate_preview"] exclude = ["task_id"] search_fields = ["name", "display_name"] list_filter = ["import_status", "map_type", "data_type", DepartmentsListFilter] @@ -161,6 +161,18 @@ def process(self, request, queryset): ) self.message_user(request, msg, level=messages.INFO) + @admin.action(description=_("Generate the simplified preview geometry")) + def generate_preview(self, request, queryset): + if queryset.count() > 1: + error = _("Please only select one map for this action.") + self.message_user(request, error, level=messages.ERROR) + return + + map = queryset[0] + generate_map_preview.delay(map.id) + msg = _("The map preview will be updated soon.") + self.message_user(request, msg, level=messages.INFO) + @admin.display(description=_("Extracted zones")) def zone_count(self, obj): count = Zone.objects.filter(map=obj).count() diff --git a/envergo/geodata/migrations/0003_map_geometry.py b/envergo/geodata/migrations/0003_map_geometry.py new file mode 100644 index 000000000..05b9b09b8 --- /dev/null +++ b/envergo/geodata/migrations/0003_map_geometry.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2 on 2023-06-16 12:36 + +import django.contrib.gis.db.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("geodata", "0002_map_imported_zones"), + ] + + operations = [ + migrations.AddField( + model_name="map", + name="geometry", + field=django.contrib.gis.db.models.fields.MultiPolygonField( + geography=True, null=True, srid=4326, verbose_name="Simplified geometry" + ), + ), + ] diff --git a/envergo/geodata/models.py b/envergo/geodata/models.py index d364a663a..4a6affd95 100644 --- a/envergo/geodata/models.py +++ b/envergo/geodata/models.py @@ -180,7 +180,9 @@ class Map(models.Model): choices=DEPARTMENT_CHOICES, ), ) - + geometry = gis_models.MultiPolygonField( + _("Simplified geometry"), geography=True, null=True + ) created_at = models.DateTimeField(_("Date created"), default=timezone.now) expected_zones = models.IntegerField(_("Expected zones"), default=0) imported_zones = models.IntegerField(_("Imported zones"), null=True, blank=True) diff --git a/envergo/geodata/tasks.py b/envergo/geodata/tasks.py index 8a1e00c49..f4caa57ee 100644 --- a/envergo/geodata/tasks.py +++ b/envergo/geodata/tasks.py @@ -4,29 +4,36 @@ from config.celery_app import app from envergo.geodata.models import STATUSES, Map -from envergo.geodata.utils import process_shapefile +from envergo.geodata.utils import process_shapefile, simplify_map logger = logging.getLogger(__name__) @app.task(bind=True) +@transaction.atomic def process_shapefile_map(task, map_id): logger.info(f"Starting import on map {map_id}") map = Map.objects.get(pk=map_id) + + # Store the task data in the model, so we can display progression + # in the admin page. map.task_id = task.request.id map.import_error_msg = "" map.import_status = None map.save() - map.zones.all().delete() + # Proceed with the map import try: with transaction.atomic(): + map.zones.all().delete() process_shapefile(map, map.file, task) + map.geometry = simplify_map(map) except Exception as e: map.import_error_msg = f"Erreur d'import ({e})" logger.error(map.import_error_msg) + # Update the map status and metadata nb_imported_zones = map.zones.all().count() if map.expected_zones == nb_imported_zones: map.import_status = STATUSES.success @@ -38,3 +45,12 @@ def process_shapefile_map(task, map_id): map.task_id = None map.imported_zones = nb_imported_zones map.save() + + +@app.task(bind=True) +def generate_map_preview(task, map_id): + logger.info(f"Starting preview generation on map {map_id}") + + map = Map.objects.get(pk=map_id) + map.geometry = simplify_map(map) + map.save() diff --git a/envergo/geodata/utils.py b/envergo/geodata/utils.py index 7644336be..ae4be5032 100644 --- a/envergo/geodata/utils.py +++ b/envergo/geodata/utils.py @@ -9,9 +9,10 @@ import requests from django.contrib.gis.gdal import DataSource -from django.contrib.gis.geos import GEOSGeometry +from django.contrib.gis.geos import GEOSGeometry, MultiPolygon, Polygon from django.contrib.gis.utils.layermapping import LayerMapping from django.core.serializers import serialize +from django.db import connection from django.db.models import QuerySet from django.utils.translation import gettext_lazy as _ @@ -19,6 +20,8 @@ logger = logging.getLogger(__name__) +EPSG_WGS84 = 4326 + class CeleryDebugStream: """A sys.stdout proxy that also updates the celery task states. @@ -49,6 +52,8 @@ def write(self, msg): class CustomMapping(LayerMapping): + """A custom LayerMapping that allows to pass extra arguments to the generated model.""" + def __init__(self, *args, **kwargs): self.extra_kwargs = kwargs.pop("extra_kwargs") super().__init__(*args, **kwargs) @@ -127,8 +132,6 @@ def to_geojson(obj, geometry_field="geometry"): srid. """ - EPSG_WGS84 = 4326 - if isinstance(obj, (QuerySet, list)): geojson = serialize("geojson", obj, geometry_field=geometry_field) elif hasattr(obj, "geojson"): @@ -191,3 +194,47 @@ def merge_geometries(polygons): pass return merged + + +def simplify_map(map): + """Generates a simplified geometry for the entire map. + + This methods takes a map and generates a single polygon that is the union + of all the polygons in the map. + + We also simplify the polygon because this is for display purpose only. + + We use native postgis methods those operations, because it's way faster. + + As for simplification, we don't preserve topology (ST_Simplify instead of + ST_SimplifyPreserveTopology) because we want to be able to drop small + holes in the polygon. + + Because of that, we also have to call ST_MakeValid to avoid returning invalid + polygons.""" + + with connection.cursor() as cursor: + cursor.execute( + """ + SELECT + ST_AsText( + ST_MakeValid( + ST_Simplify( + ST_Union(z.geometry::geometry), + 0.0001 + ), + 'method=structure keepcollapsed=false' + ) + ) + AS polygon + FROM geodata_zone as z + WHERE z.map_id = %s + """, + [map.id], + ) + row = cursor.fetchone() + + polygon = GEOSGeometry(row[0], srid=EPSG_WGS84) + if isinstance(polygon, Polygon): + polygon = MultiPolygon(polygon) + return polygon diff --git a/envergo/moulinette/migrations/0005_contact_regulation_url.py b/envergo/moulinette/migrations/0005_contact_regulation_url.py new file mode 100644 index 000000000..ecd09307d --- /dev/null +++ b/envergo/moulinette/migrations/0005_contact_regulation_url.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2 on 2023-06-22 12:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("moulinette", "0004_alter_contact_options"), + ] + + operations = [ + migrations.AddField( + model_name="contact", + name="regulation_url", + field=models.URLField(blank=True, verbose_name="Regulation URL"), + ), + ] diff --git a/envergo/moulinette/models.py b/envergo/moulinette/models.py index f25c9158e..3ed842e05 100644 --- a/envergo/moulinette/models.py +++ b/envergo/moulinette/models.py @@ -3,7 +3,7 @@ from django.contrib.gis.geos import Point from django.contrib.gis.measure import Distance as D from django.db import models -from django.db.models import F +from django.db.models import Case, F, When from django.db.models.functions import Cast from django.utils.translation import gettext_lazy as _ @@ -158,7 +158,7 @@ def __init__(self, data, raw_data): self.catalog["config"] = self.department.moulinette_config self.perimeters = self.get_perimeters() - self.criterions = self.get_criterions() + self.criterions_classes = self.get_criterions() # This is a clear case of circular references, since the Moulinette # holds references to the regulations it's computing, but regulations and @@ -251,7 +251,12 @@ def get_perimeters(self): Perimeter.objects.filter( map__zones__geometry__dwithin=(coords, F("activation_distance")) ) - .annotate(geometry=F("map__zones__geometry")) + .annotate( + geometry=Case( + When(map__geometry__isnull=False, then=F("map__geometry")), + default=F("map__zones__geometry"), + ) + ) .annotate(distance=Distance("map__zones__geometry", coords)) .order_by("distance", "map__name") .select_related("map", "contact") @@ -449,6 +454,7 @@ class Contact(models.Model): ) name = models.CharField(_("Name"), max_length=256) url = models.URLField(_("URL"), blank=True) + regulation_url = models.URLField(_("Regulation URL"), blank=True) address_md = models.TextField(_("Address")) address_html = models.TextField(_("Address HTML"), blank=True) diff --git a/envergo/moulinette/regulations/__init__.py b/envergo/moulinette/regulations/__init__.py index e1418ce9a..34be51392 100644 --- a/envergo/moulinette/regulations/__init__.py +++ b/envergo/moulinette/regulations/__init__.py @@ -1,4 +1,5 @@ import json +from abc import ABC from dataclasses import dataclass from enum import Enum from functools import cached_property @@ -21,18 +22,24 @@ def __str__(self): return self.text -class MoulinetteRegulation: - """Run the moulinette for a single regulation (e.g Loi sur l'eau).""" +class MoulinetteRegulation(ABC): + """Run the moulinette for a single regulation (e.g Loi sur l'eau). + This class is meant to be inherited to implement actual regulations. + """ + + # Implement this in subclasses criterion_classes = [] def __init__(self, moulinette): self.moulinette = moulinette self.moulinette.catalog.update(self.get_catalog_data()) + + # Instanciate the criterions self.criterions = [ - Criterion(moulinette) - for Criterion in self.criterion_classes - if Criterion in moulinette.criterions + perimeter.criterion(moulinette, perimeter) + for perimeter in moulinette.perimeters + if perimeter.criterion in self.criterion_classes ] def get_catalog_data(self): @@ -119,7 +126,11 @@ def _get_map(self): @dataclass class MapPolygon: - """Data that can be displayed and labeled on a leaflet map as a polygon.""" + """Data that can be displayed and labeled on a leaflet map as a polygon. + + A `MapPolygon is meant to represent a single entry on a map: + a polygon with a given color and label. + """ perimeters: list # List of `envergo.geofr.Perimeter` objects color: str @@ -185,7 +196,7 @@ def sources(self): return maps -class MoulinetteCriterion: +class MoulinetteCriterion(ABC): """Run a single moulinette check.""" # Prevent template engine to instanciate the class since we sometimes want @@ -198,9 +209,10 @@ class MoulinetteCriterion: # "Nomenclature réglementations & critères" document. CODES = ["soumis", "non_soumis", "action_requise", "non_concerne"] - def __init__(self, moulinette): + def __init__(self, moulinette, perimeter): self.moulinette = moulinette self.moulinette.catalog.update(self.get_catalog_data()) + self.perimeter = perimeter def get_catalog_data(self): """Get data to inject to the global catalog.""" diff --git a/envergo/moulinette/regulations/sage.py b/envergo/moulinette/regulations/sage.py index 3d014aeb3..850130111 100644 --- a/envergo/moulinette/regulations/sage.py +++ b/envergo/moulinette/regulations/sage.py @@ -368,3 +368,30 @@ def result(self): result = RESULTS.non_disponible return result + + def _get_map(self): + # Let's find the first map that we can display + perimeter = next( + ( + criterion.perimeter + for criterion in self.criterions + if criterion.perimeter.map.display_for_user + and criterion.perimeter.map.geometry + ), + None, + ) + if not perimeter: + return None + + map_polygons = [MapPolygon([perimeter], "red", "Sage")] + caption = "Le projet se situe dans le périmètre du Sage." + + map = Map( + center=self.catalog["coords"], + entries=map_polygons, + caption=caption, + truncate=False, + zoom=None, + ) + + return map diff --git a/envergo/pages/admin.py b/envergo/pages/admin.py index e69de29bb..bdb96777d 100644 --- a/envergo/pages/admin.py +++ b/envergo/pages/admin.py @@ -0,0 +1,10 @@ +from django.contrib import admin + +from envergo.pages.models import NewsItem + + +@admin.register(NewsItem) +class NewsItemAdmin(admin.ModelAdmin): + list_display = ["title", "created_at"] + search_fields = ["title", "content_md"] + fields = ["title", "content_md", "created_at"] diff --git a/envergo/pages/migrations/0001_initial.py b/envergo/pages/migrations/0001_initial.py new file mode 100644 index 000000000..6e181db26 --- /dev/null +++ b/envergo/pages/migrations/0001_initial.py @@ -0,0 +1,39 @@ +# Generated by Django 4.2 on 2023-04-25 08:29 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="NewsItem", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("content_md", models.TextField(verbose_name="Content")), + ("content_html", models.TextField(verbose_name="Content HTML")), + ( + "created_at", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="Date created" + ), + ), + ], + options={ + "verbose_name": "News item", + "verbose_name_plural": "News items", + }, + ), + ] diff --git a/envergo/pages/migrations/0002_newsitem_title.py b/envergo/pages/migrations/0002_newsitem_title.py new file mode 100644 index 000000000..5deec9eb2 --- /dev/null +++ b/envergo/pages/migrations/0002_newsitem_title.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2 on 2023-05-22 08:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("pages", "0001_initial"), + ] + + operations = [ + migrations.AddField( + model_name="newsitem", + name="title", + field=models.CharField(default="", max_length=255, verbose_name="Title"), + preserve_default=False, + ), + ] diff --git a/envergo/pages/models.py b/envergo/pages/models.py index e69de29bb..7b2f7c8f1 100644 --- a/envergo/pages/models.py +++ b/envergo/pages/models.py @@ -0,0 +1,25 @@ +from django.db import models +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ + +from envergo.utils.markdown import markdown_to_html + + +class NewsItem(models.Model): + """A news item to be displayed on the FAQ page.""" + + title = models.CharField(_("Title"), max_length=255) + content_md = models.TextField(_("Content")) + content_html = models.TextField(_("Content HTML")) + created_at = models.DateTimeField(_("Date created"), default=timezone.now) + + class Meta: + verbose_name = _("News item") + verbose_name_plural = _("News items") + + def __str__(self): + return self.title + + def save(self, *args, **kwargs): + self.content_html = markdown_to_html(self.content_md) + super().save(*args, **kwargs) diff --git a/envergo/pages/templatetags/pages.py b/envergo/pages/templatetags/pages.py index 3f5956dc8..7882d9831 100644 --- a/envergo/pages/templatetags/pages.py +++ b/envergo/pages/templatetags/pages.py @@ -16,39 +16,71 @@ def nav_link(route, label, aria_current=False): @register.simple_tag(takes_context=True) -def menu_item(context, route, label): - """Generate html for a main menu item.""" +def menu_item(context, route, label, subroutes=[]): + """Generate html for a main menu item. + + If you pass a list of subroutes, the menu item will be highlighted + if the current url is any on the main route or subroutes. + """ try: current_route = context.request.resolver_match.url_name except AttributeError: current_route = "" - aria_current = route == current_route + aria_current = route == current_route or current_route in subroutes return nav_link(route, label, aria_current) @register.simple_tag(takes_context=True) -def evalreq_menu(context): - """Generate html for the "Demander une évaluation" collapsible menu.""" - - link_route = "request_evaluation" - link_label = "Demander une évaluation manuelle" - +def sidemenu_item(context, route, label): try: current_route = context.request.resolver_match.url_name except AttributeError: current_route = "" - routes = [ + aria_current = route == current_route + url = reverse(route) + sidemenu_class = "fr-sidemenu__item--current" if aria_current else "" + aria_attr = 'aria-current="page"' if aria_current else "" + return mark_safe( + f""" +
- Consultez notre page d'information sur la Loi sur l'eau + Consultez notre page d'information ou contactez l'équipe EnvErgo.
diff --git a/envergo/templates/moulinette/base_result.html b/envergo/templates/moulinette/base_result.html index 1c9efdc9f..ec1ecae7b 100644 --- a/envergo/templates/moulinette/base_result.html +++ b/envergo/templates/moulinette/base_result.html @@ -36,7 +36,7 @@- Consultez notre page d'information sur la Loi sur l'eau + Consultez notre page d'information ou contactez l'équipe EnvErgo.
{% endblock %} diff --git a/envergo/templates/moulinette/eval_body_action_requise.html b/envergo/templates/moulinette/eval_body_action_requise.html index 99deeaa25..841ab77aa 100644 --- a/envergo/templates/moulinette/eval_body_action_requise.html +++ b/envergo/templates/moulinette/eval_body_action_requise.html @@ -54,6 +54,10 @@+ Consultez notre article décrivant l'instruction Loi sur l'eau. +
+Consultez notre article décrivant l'instruction Loi sur l'eau.
diff --git a/envergo/templates/moulinette/loi_sur_leau/result_action_requise.html b/envergo/templates/moulinette/loi_sur_leau/result_action_requise.html index 618e9a6f1..094ba3a41 100644 --- a/envergo/templates/moulinette/loi_sur_leau/result_action_requise.html +++ b/envergo/templates/moulinette/loi_sur_leau/result_action_requise.html @@ -65,6 +65,10 @@+ Consultez notre article décrivant l'instruction Loi sur l'eau. +
+Consultez notre article décrivant l'instruction Loi sur l'eau.
diff --git a/envergo/templates/moulinette/loi_sur_leau/result_non_soumis.html b/envergo/templates/moulinette/loi_sur_leau/result_non_soumis.html index fd8c54eaa..14e461a1f 100644 --- a/envergo/templates/moulinette/loi_sur_leau/result_non_soumis.html +++ b/envergo/templates/moulinette/loi_sur_leau/result_non_soumis.html @@ -1,5 +1,5 @@Le projet n’est pas soumis à la Loi sur l’eau.
- Consultez notre page d'information sur la Loi sur l'eau. + Consultez notre page d'information sur la Loi sur l'eau.
diff --git a/envergo/templates/moulinette/loi_sur_leau/result_soumis.html b/envergo/templates/moulinette/loi_sur_leau/result_soumis.html index 1bfc81c38..3e6994b09 100644 --- a/envergo/templates/moulinette/loi_sur_leau/result_soumis.html +++ b/envergo/templates/moulinette/loi_sur_leau/result_soumis.html @@ -53,6 +53,10 @@+ Consultez notre article décrivant l'instruction Loi sur l'eau. +
+Consultez notre article décrivant l'instruction Loi sur l'eau.
diff --git a/envergo/templates/moulinette/natura2000/result_iota_a_verifier.html b/envergo/templates/moulinette/natura2000/result_iota_a_verifier.html index a1bd95b00..623e1db67 100644 --- a/envergo/templates/moulinette/natura2000/result_iota_a_verifier.html +++ b/envergo/templates/moulinette/natura2000/result_iota_a_verifier.html @@ -49,7 +49,7 @@- Consultez notre article décrivant l'instruction Loi sur l'eau. + Consultez notre article décrivant l'instruction Loi sur l'eau.
- Consultez notre article décrivant l'instruction Loi sur l'eau. + Consultez notre article décrivant l'instruction Loi sur l'eau.
{% elif moulinette.loi_sur_leau.result == 'action_requise' %} diff --git a/envergo/templates/pages/faq/eval_env.html b/envergo/templates/pages/faq/eval_env.html new file mode 100644 index 000000000..504934ae4 --- /dev/null +++ b/envergo/templates/pages/faq/eval_env.html @@ -0,0 +1,41 @@ +{% extends "pages/faq/index.html" %} + +{% load static %} + +{% block title %}Questions fréquentes : Évaluation environnementale{% endblock %} + +{% block faq_content %} +Évaluation environnementale
+ +Bla bla bla
++ Consultez les réponses aux questions fréquentes sur les réglementations environnementales prises en compte par EnvErgo. +
+ ++ La loi sur l'eau encadre tous les projets + qui risquent d'impacter l'eau et les milieux aquatiques. +
++ Natura 2000 est un dispositif visant la protection d'espèces animales et végétales fragiles et de leur habitat. +
+- La Loi sur l'eau encadre tous les projets qui risquent d'impacter l'eau et les milieux aquatiques. + La Loi sur l'eau encadre tous les projets qui risquent d'impacter l'eau et les + milieux aquatiques. Retrouvez ici les questions les plus fréquemment posées + quant à l'application de la Loi sur l'eau aux projets de construction et d'aménagement.
-La Loi sur l'eau encadre tous les projets qui risquent d'impacter les milieux aquatiques.
@@ -31,27 +28,22 @@
- La liste décrivant les projets soumis à la Loi sur l'eau se situe dans - - l'article R.214-1 du Code de l'Environnement - , aussi appelée - - nomenclature « IOTA » (pour Installations, Ouvrages, Travaux, Activités) - . + La liste décrivant les projets soumis à la Loi sur l'eau se situe dans l'article R.214-1 du + Code de + l'Environnement, aussi appelée nomenclature + « IOTA » (pour Installations, Ouvrages, Travaux, Activités).
Les impacts sur les milieux aquatiques y sont répartis en plusieurs rubriques :
-Pour chaque rubrique il y a deux seuils d'impact :
- En première approche, le simulateur EnvErgo vous permet en quelques clics de vérifier si votre projet est soumis à la Loi sur l'eau, ainsi qu'à d'autres réglementations environnementales (Natura 2000…). + S’il s’agit d’un projet d’aménagement ou de construction, le simulateur EnvErgo vous permet en quelques clics de vérifier si le projet est soumis à la Loi sur l'eau — ainsi qu’aux autres réglementations environnementales (Natura 2000, évaluation environnementale…). C'est un service public numérique gratuit, fourni par le Ministère de la Transition Écologique. Il fonctionne pour l'instant en Loire-Atlantique, dans le Morbihan et en Vendée, et sera prochainement étendu à un territoire plus large.
-Pour déterminer avec certitude si votre projet est soumis à la Loi sur l'eau, il est conseillé :
-De se rapprocher d'un bureau d'études disposant d'une expertise « dossier Loi sur l'eau ».
-- Les échanges vous permettront de confirmer si votre projet de construction est soumis à la Loi sur l'eau, - et s'il y a lieu de constituer un dossier à déposer à l'administration. -
+Le bureau d’études environnemental vous permet :
+De demander une évaluation Loi sur l'eau au service EnvErgo
-Vous pouvez demander une évaluation de votre projet, qui sera réalisée manuellement par l'équipe d'EnvErgo — disponible sur la totalité du territoire français.
-Enfin, n'hésitez pas à contacter l'équipe EnvErgo pour toute question complémentaire.
- +De se rapprocher du service qui instruit les dossiers Loi sur l'eau
Pour cela, contactez la DDT(M) (Direction Départementale des Territoires et de la Mer) de votre département.
Vous devez obligatoirement déposer un dossier de déclaration Loi sur l'eau, en plus de la demande de permis de - construire. + construire ou d'aménager.
@@ -145,40 +129,31 @@
- Il est à déposer au guichet unique de l'environnement du département où se situe le projet. - - Le dépôt peut se faire numériquement, via une procédure en ligne. - + Il est à déposer au guichet unique de l'environnement du département où + se situe le projet. Le dépôt peut se faire numériquement, via une procédure en ligne.
-Il suit une procédure d'instruction spécifique, distincte de la demande de permis de construire, avec ses délais propres.
-Son appellation « Déclaration » ne signifie pas qu'il s'agit d'une procédure déclarative sans obligation associée. Au contraire, elle déclenche une véritable instruction sur le fond du projet, qui peut aboutir :
-Les procédures Loi sur l'eau sont des procédures spécifiques, à effectuer en plus de la demande de permis de construire ou d'aménager.
-Si votre projet est soumis à la Loi sur l'eau, il vous faut donc bien articuler les deux procédures d'instruction (Permis de construire ou d'aménager / Loi sur l'eau) qui peuvent s'influencer l'une l'autre.
-- Dans le formulaire de demande de permis de construire hors maison individuelle ou permis d'aménager - ( - - Cerfa 13409 - - ), le + Dans le formulaire de demande de permis de construire hors maison individuelle ou permis d'aménager (Cerfa + 13409), le cadre n°8 sert à informer le service urbanisme des démarches menées au titre de la Loi sur l'eau.
-Le service urbanisme qui étudie votre demande est en droit de vous demander des pièces complémentaires, pour déterminer si vous avez déposé ou non un dossier Loi sur l'eau pour votre projet.
-Vous ne pouvez pas démarrer les travaux avant d'avoir reçu une réponse de la préfecture.
S'il s'avère que le projet est réalisé sans autorisation du préfet, le responsable s'expose à des sanctions administratives et pénales pouvant comprendre une - obligation de remettre le terrain en son état initial, avec une astreinte jusqu'à 1500 € par + obligation de remettre le terrain en son état initial, avec une astreinte jusqu'à 1 500 € par jour.
-Toutefois, dans certains cas, le récepissé de déclaration mentionne explicitement la possibilité de démarrer les travaux. @@ -325,7 +282,6 @@
Votre demande de permis de construire peut être rejetée si vous n'avez pas déposé de dossier Loi sur
@@ -344,24 +300,23 @@
S'il s'avère que le projet est réalisé sans autorisation du préfet, le responsable s'expose à des sanctions
administratives et pénales, qui peuvent aller jusqu'à :
@@ -381,34 +335,26 @@ Une procédure d’Autorisation Environnementale dure en moyenne de 9 à 12 mois.
La demande est à déposer au guichet unique de l'environnement du département où
- se situe le projet.
-
- Le dépôt peut se faire numériquement, via une procédure en ligne.
-
+ se situe le projet. Le dépôt peut se faire numériquement, via une procédure en ligne.
- Retrouvez plus d’informations sur la procédure à ce lien.
-
+ rel="noopener">Retrouvez plus d’informations sur la procédure à ce lien.
+ Natura 2000 est un dispositif réglementaire visant la protection d'espèces animales et végétales fragiles, et de leur habitat. + Retrouvez ici les questions les plus fréquemment posées quant à l'application du dispositif Natura 2000 aux projets de construction et d'aménagement. +
++ Natura 2000 est un dispositif européen visant à la protection d’espèces animales et végétales fragiles, + et de leurs habitats. +
+En France, il consiste en :
+La France compte près de 1 800 sites Natura 2000, couvrant près de 13 % du territoire terrestre métropolitain.
+Ces sites Natura 2000 sont répartis en deux catégories :
++ Les textes réglementaires Natura 2000 sont conçus pour que les projets menés dans ces sites garantissent la préservation à long terme des espèces et des habitats. +
++ Les projets concernés par le dispositif Natura 2000 sont listés dans plusieurs textes réglementaires s’appliquant au niveau national, départemental, ou à l’échelle d’une façade maritime. +
+Ces textes sont les suivants :
+
+ à l’échelle nationale, la « liste nationale » fixée par l'article R.414-19 du code de l'environnement.
+
+ Elle concerne les projets déjà encadrés administrativement. Par exemple, tout projet soumis à la Loi sur l’eau, à examen au cas par cas, ou à étude d’impact, est concerné.
+
+ Elle s’applique à ces projets même s’ils se situent hors d’un site Natura 2000.
+
+ une « liste locale 1 » à l’échelle du département ou de la région, fixée par arrêté préfectoral.
+
+ Elle reprend les points de la liste nationale, mais prend en compte les spécificités locales et s’applique uniquement à des projets qui se situent à l’intérieur ou à proximité d’un site Natura 2000.
+
+ une « liste locale 2 », à l’échelle départementale ou régionale également.
+
+ Cette liste concerne des types de projets qui peuvent être très variés, différentes des listes nationale et locale 1 ;
+ elle est établie selon les spécificités des sites Natura 2000 du territoire.
+
+ Cette liste établit ce qu’on appelle le « régime propre » de Natura 2000, qui est plus restrictif que les listes ci-dessus.
+
+ Si un projet est concerné par l’une des listes Natura 2000, il lui est imposé de mener une étude préalable + — l’évaluation des incidences Natura 2000 — et de la soumettre à l’administration. +
++ S’il s’agit d’un projet d’aménagement ou de construction, le simulateur EnvErgo vous permet en quelques clics de vérifier si le projet est soumis à Natura 2000 — ainsi qu’aux autres réglementations environnementales (Loi sur l’eau, évaluation environnementale…). + C'est un service public numérique gratuit, fourni par le Ministère de la Transition Écologique. + Il fonctionne pour l'instant en Loire-Atlantique, dans le Morbihan et en Vendée, et sera prochainement étendu à un territoire plus large. +
+De façon générale, un projet peut être soumis à EIN :
++ Pour déterminer avec certitude si votre projet est soumis à évaluation des incidences Natura 2000 (EIN), il est conseillé : +
++ De contacter l’animateur du site Natura 2000 concerné, dès la conception du projet +
++ Chaque site Natura 2000 dispose d’une structure en charge de son « animation », + dont le rôle est de vous informer quant aux obligations de protection du lieu, + et de vous accompagner pour concilier les exigences du projet avec la minimisation de ses impacts sur le site. +
++ La liste des animateurs est publiée sur les sites internet des préfectures dans chaque département. +
+En l’absence d’un animateur, vous pouvez vous rapprocher de la DDT(M) du site concerné.
++ D’avoir recours aux formulaires simplifiés d’évaluation des incidences +
++ Ces formulaires sont élaborés dans chaque département pour accompagner la réflexion du porteur + sur les impacts du projet mentionnés dans les listes locales Natura 2000. + Ils sont disponibles sur les sites internet des préfectures. +
++ Ils permettent d’évaluer, le plus tôt possible dans la conception de son projet, + si certains impacts devront faire l’objet d’une évaluation avancée, + et d’un travail rapproché entre le porteur et ses maîtres d’œuvre, l’animateur du site, et les services de l’État. +
++ De se rapprocher d'un bureau d'études disposant d'une expertise environnementale +
+Le bureau d’études environnemental vous permet :
++ Oui. Si le projet est déjà soumis à une procédure administrative, par exemple Loi sur l’eau, examen au cas par cas, déclaration au titre des installations classées (ICPE), + l’EIN est obligatoire, même si le projet est hors d’un site Natura 2000. +
++ Par ailleurs, dans certains départements, la seule proximité à un site est motif d’entrée en procédure. + En effet, des impacts sur un site protégé peuvent être induits par le projet (bruit, effluents, activité humaine…), même s’il n’est pas strictement dans le périmètre. +
++ Le simulateur EnvErgo, pour déterminer si un projet de construction ou d’aménagement est soumis à Natura 2000, + prend en compte les listes locales et la doctrine DDT(M) de chaque département. +
++ + + Vous devez obligatoirement déposer une évaluation des incidences Natura 2000, + en plus de la demande de permis de construire ou d’aménager. + +
+L’administration à qui déposer le dossier d’EIN dépend des autres procédures auxquelles est soumis le dossier :
++ Le simulateur EnvErgo permet de déterminer à la fois si votre projet est soumis à EIN, + et la procédure associée pour déposer le dossier. +
++ Quand l’évaluation des incidences Natura 2000 est jointe à une demande d’autorisation (dossier Loi sur l'eau ou demande de PC ou de PA), + ce qui est le cas le plus fréquent pour un projet de construction ou d'aménagement, + l'EIN est instruite en même temps que celle-ci, de façon transparente pour le porteur de projet. +
+La présence d'une EIN ne modifie pas le délai de la demande de rattachement :
++ De façon transparente pour le porteur de projet, l’EIN est transmise au service en charge de la biodiversité, au sein de la DDT(M) du département concerné ; + c’est lui qui en mène l’instruction. +
++ Le service instructeur peut vous demander des compléments + si le dossier n’apparaît pas suffisamment explicite ou si des mesures d’atténuation des incidences semblent manquer. +
++ Votre demande de permis de construire ou d’aménager peut être rejetée + si vous n'avez pas réalisé et déposé d’évaluation des incidences Natura 2000 et que vous y étiez tenu. +
++ Un contrôle par la police de l’environnement peut avoir lieu avant, pendant les travaux, ou après la réalisation du projet. + Une tierce partie (riverain, association, collectivité) peut déclencher un recours auprès de l’administration. +
+S'il s'avère que le projet est réalisé :
+le responsable s'expose à des sanctions administratives et pénales, qui peuvent aller jusqu'à :
+Suivez ici l'actualité du projet EnvErgo.
+ + {% for item in news_items %} + +