Skip to content

Commit

Permalink
fix(gpu): remove static maps and replace explorer
Browse files Browse the repository at this point in the history
  • Loading branch information
alexisig committed Nov 21, 2024
1 parent 0a7fe33 commit e9ceb64
Show file tree
Hide file tree
Showing 11 changed files with 420 additions and 163 deletions.
7 changes: 7 additions & 0 deletions carto/templates/carto/map_libre.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
{% load highcharts_tags %}
{% load sri %}

{% block top_navigation %}
{% endblock top_navigation %}

{% block title %}
{{ map_name }}
{% endblock title %}

{% block pagetitle %}
{{ map_name }}
{% endblock pagetitle %}
Expand Down
4 changes: 4 additions & 0 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -661,3 +661,7 @@ def show_toolbar(request):
# CRISP

CRISP_WEBHOOK_SECRET_KEY = env.str("CRISP_WEBHOOK_SECRET_KEY")

X_FRAME_OPTIONS = "SAMEORIGIN"

XS_SHARING_ALLOWED_METHODS = ["POST", "GET", "OPTIONS", "PUT", "DELETE"]
5 changes: 0 additions & 5 deletions project/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,6 @@ def response_change(self, request, obj):
messages.add_message(request, messages.INFO, msg)
return HttpResponseRedirect(".")

elif "_generate-gpu" in request.POST:
tasks.generate_theme_map_gpu.delay(obj.id)
messages.add_message(request, messages.INFO, "Génération de l'image des zonages d'urbanismes en cours")
return HttpResponseRedirect(".")

elif "_generate-fill-gpu" in request.POST:
tasks.generate_theme_map_fill_gpu.delay(obj.id)
messages.add_message(
Expand Down
3 changes: 1 addition & 2 deletions project/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

def pre_create_historical_record_callback(sender, **kwargs):
project_history = kwargs["history_instance"]
if project_history.async_theme_map_gpu_done is None:
project_history.async_theme_map_gpu_done = False
if project_history.async_theme_map_fill_gpu_done is None:
project_history.generate_theme_map_fill_gpu = False


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.13 on 2024-11-21 10:31

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("public_data", "0191_landconso_landconsocomparison_landconsostats_landpop_and_more"),
("project", "0101_remove_projectcommune_commune_insee"),
]

operations = [
migrations.RemoveField(
model_name="historicalproject",
name="async_theme_map_gpu_done",
),
migrations.RemoveField(
model_name="historicalproject",
name="theme_map_gpu",
),
migrations.RemoveField(
model_name="project",
name="async_theme_map_gpu_done",
),
migrations.RemoveField(
model_name="project",
name="theme_map_gpu",
),
]
2 changes: 0 additions & 2 deletions project/models/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ def map_tasks(project_id: str) -> List[celery.Task]: # noqa: C901
map_tasks.append(tasks.generate_theme_map_understand_artif.si(project.id))

if project.has_complete_uniform_ocsge_coverage and project.has_zonage_urbanisme:
if not project.async_theme_map_gpu_done:
map_tasks.append(tasks.generate_theme_map_gpu.si(project.id))
if not project.async_theme_map_fill_gpu_done:
map_tasks.append(tasks.generate_theme_map_fill_gpu.si(project.id))

Expand Down
12 changes: 1 addition & 11 deletions project/models/project_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,6 @@ def get_public_key(self) -> str:
storage=PublicMediaStorage(),
)

theme_map_gpu = models.ImageField(
upload_to=upload_in_project_folder,
blank=True,
null=True,
storage=PublicMediaStorage(),
)

theme_map_fill_gpu = models.ImageField(
upload_to=upload_in_project_folder,
blank=True,
Expand All @@ -308,7 +301,6 @@ def get_public_key(self) -> str:
async_generate_theme_map_conso_done = models.BooleanField(default=False)
async_generate_theme_map_artif_done = models.BooleanField(default=False)
async_theme_map_understand_artif_done = models.BooleanField(default=False)
async_theme_map_gpu_done = models.BooleanField(default=False)
async_theme_map_fill_gpu_done = models.BooleanField(default=False)
async_ocsge_coverage_status_done = models.BooleanField(default=False)

Expand Down Expand Up @@ -349,9 +341,7 @@ def async_complete(self) -> bool:
static_maps_ready = static_maps_ready and self.async_theme_map_understand_artif_done

if self.has_zonage_urbanisme and self.has_complete_uniform_ocsge_coverage:
static_maps_ready = (
static_maps_ready and self.async_theme_map_gpu_done and self.async_theme_map_fill_gpu_done
)
static_maps_ready = static_maps_ready and self.async_theme_map_fill_gpu_done

return calculations_and_extend_ready and static_maps_ready

Expand Down
59 changes: 0 additions & 59 deletions project/tasks/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,65 +695,6 @@ def generate_theme_map_understand_artif(self, project_id) -> None:
logger.info("End generate_theme_map_understand_artif, project_id=%d", project_id)


@shared_task(bind=True, max_retries=5)
def generate_theme_map_gpu(self, project_id) -> None:
logger.info("Start generate_theme_map_gpu, project_id=%d", project_id)
try:
diagnostic = Project.objects.get(id=int(project_id))

geom = diagnostic.combined_emprise.transform("3857", clone=True)
srid, wkt = geom.ewkt.split(";")
polygons = shapely.wkt.loads(wkt)
gdf_emprise = geopandas.GeoDataFrame({"geometry": [polygons]}, crs="EPSG:3857")

data = {"color": [], "geometry": []}

for zone_urba in ZoneUrba.objects.intersect(diagnostic.combined_emprise):
srid, wkt = zone_urba.intersection.ewkt.split(";")
polygons = shapely.wkt.loads(wkt)
data["geometry"].append(polygons)
data["color"].append((*[_ / 255 for _ in zone_urba.get_color()], 0.9))

zone_urba_gdf = geopandas.GeoDataFrame(data, crs="EPSG:4326").to_crs(epsg=3857)

fig, ax = plt.subplots(figsize=(15, 10))
plt.axis("off")
fig.set_dpi(150)

zone_urba_gdf.plot(ax=ax, color=zone_urba_gdf["color"])
gdf_emprise.plot(ax=ax, facecolor="none", edgecolor="black")
ax.add_artist(ScaleBar(1))
ax.set_title(
f"Les zones d'urbanisme du territoire «{diagnostic.territory_name}» en {diagnostic.analyse_end_date}"
)
cx.add_basemap(ax, source=settings.OPENSTREETMAP_URL)
cx.add_attribution(ax, text=settings.OPENSTREETMAP_ATTRIBUTION)

img_data = io.BytesIO()
plt.savefig(img_data, bbox_inches="tight", format="jpg")
plt.close()
img_data.seek(0)

race_protection_save_map(
diagnostic.pk,
"async_theme_map_gpu_done",
"theme_map_gpu",
f"theme_map_gpu_{project_id}.jpg",
img_data,
)

except Project.DoesNotExist:
logger.error(f"project_id={project_id} does not exist")

except Exception as exc:
logger.error(exc)
logger.exception(exc)
self.retry(exc=exc, countdown=300)

finally:
logger.info("End generate_theme_map_gpu, project_id=%d", project_id)


@shared_task(bind=True, max_retries=5)
def generate_theme_map_fill_gpu(self, project_id) -> None:
logger.info("Start generate_theme_map_fill_gpu, project_id=%d", project_id)
Expand Down
159 changes: 76 additions & 83 deletions project/templates/project/components/dashboard/gpu.html
Original file line number Diff line number Diff line change
@@ -1,97 +1,90 @@
<div class="fr-callout bg-white fr-fi-information-line">
<h3 class="fr-callout__title">Découvrez notre explorateur des zonages d'urbanisme</h3>
<p class="fr-callout__text">
Croisez les zonages d'urbanisme avec les données de l'OCS GE afin de comprendre l'artificialisation de votre territoire.
</p>
<a href="{% url 'project:map-urban-zones' project.pk %}" class="fr-link--text-decoration-none" target="_blank" rel="noopener noreferrer">
<button class="fr-btn">
Explorer les zonages d'urbanisme
</button>
</a>
</div>

<div class="fr-mt-7w">
<h3>Synthèse des zonages d'urbanisme</h3>
<h3>Synthèse</h3>

<div class="fr-grid-row fr-grid-row--gutters">
<div class="fr-col-12 fr-col-lg-8">
<div class="bg-white fr-p-2w h-100">
<div class="fr-table fr-table--bordered">
<div class="fr-table__wrapper">
<div class="fr-table__container">
<div class="fr-table__content">
<table>
<caption>
Données synthèse des zonages d'urbanisme
</caption>
<thead>
<tr>
<th scope="col" class="fr-cell--fixed">Type de<br/>zone</th>
<th scope="col" class="fr-cell--right">Nombre<br/>de zones</th>
<th scope="col" class="fr-cell--right">Surface<br/>totale</th>
<th scope="col" class="fr-cell--right">Surface<br/>artificielle ({{ last_year_ocsge }})</th>
<th scope="col" class="fr-cell--right">Taux d'artificialisation<br/> ({{ last_year_ocsge }})</th>
<th scope="col" class="fr-cell--right">Artificialisation<br/>({{ first_year_ocsge }} à {{ last_year_ocsge }})</th>
</tr>
</thead>
<tbody>
{% for zone_type, zone in zone_list.items %}
<tr>
<th scope="row" class="fr-cell--fixed">{{ zone_type }}</th>
<td class="fr-cell--right">{{ zone.nb_zones }}</td>
<td class="fr-cell--right">{{ zone.total_area|floatformat:1 }} ha</td>
<td class="fr-cell--right">{{ zone.last_artif_area|floatformat:1 }} ha</td>
<td class="fr-cell--right">
<div class="progress-bar-container">
<div class="progress-bar-indicator w-{{ zone.fill_up_rate|floatformat:0 }}"></div>
<div class="progress-bar-value">{{ zone.fill_up_rate|floatformat:1 }}%</div>
</div>
</td>
<td class="fr-cell--right">{{ zone.new_artif|floatformat:1 }} ha</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="fr-grid-row fr-grid-row--gutters">
<div class="fr-col-12">
<div class="bg-white fr-p-2w h-100">
<div class="fr-table fr-table--bordered">
<div class="fr-table__wrapper">
<div class="fr-table__container">
<div class="fr-table__content">
<table>
<thead>
<tr>
<th scope="col" class="fr-cell--fixed">Type de<br/>zone</th>
<th scope="col" class="fr-cell--right">Nombre<br/>de zones</th>
<th scope="col" class="fr-cell--right">Surface<br/>totale</th>
<th scope="col" class="fr-cell--right">Surface<br/>artificielle ({{ last_year_ocsge }})</th>
<th scope="col" class="fr-cell--right">Taux d'artificialisation<br/> ({{ last_year_ocsge }})</th>
<th scope="col" class="fr-cell--right">Artificialisation<br/>({{ first_year_ocsge }} à {{ last_year_ocsge }})</th>
</tr>
</thead>
<tbody>
{% for zone_type, zone in zone_list.items %}
<tr>
<th scope="row" class="fr-cell--fixed">{{ zone_type }}</th>
<td class="fr-cell--right">{{ zone.nb_zones }}</td>
<td class="fr-cell--right">{{ zone.total_area|floatformat:1 }} ha</td>
<td class="fr-cell--right">{{ zone.last_artif_area|floatformat:1 }} ha</td>
<td class="fr-cell--right">
<div class="progress-bar-container">
<div class="progress-bar-indicator w-{{ zone.fill_up_rate|floatformat:0 }}"></div>
<div class="progress-bar-value">{{ zone.fill_up_rate|floatformat:1 }}%</div>
</div>
</td>
<td class="fr-cell--right">{{ zone.new_artif|floatformat:1 }} ha</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>

<p class="my-3">Les types de zone d'après le Standard CNIG PLU v2022 - rev. octobre 2022:
<br/><span class="fw-bold">U</span> : zone urbaine
<br/><span class="fw-bold">AUc</span> : zone à urbaniser
<br/><span class="fw-bold">AUs</span> : zone à urbaniser bloquée
<br/><span class="fw-bold">A</span> : zone agricole
<br/><span class="fw-bold">N</span> : zone naturelle
</p>
</div>
</div>



</div>

<p class="my-3">Les types de zone d'après le Standard CNIG PLU v2022 - rev. octobre 2022:
<br/><span class="fw-bold">U</span> : zone urbaine
<br/><span class="fw-bold">AUc</span> : zone à urbaniser
<br/><span class="fw-bold">AUs</span> : zone à urbaniser bloquée
<br/><span class="fw-bold">A</span> : zone agricole
<br/><span class="fw-bold">N</span> : zone naturelle
<div class="fr-notice bg-white fr-mt-4w fr-mb-4w">
<div class="fr-px-2w">
<div class="d-flex align-items-center justify-content-between">
<div>
<span class="fr-icon-information-line" aria-hidden="true"></span>
<span class="fr-text--xs fr-mr-1w">Source de données: </span>
<p class="fr-tag fr-tag--sm fr-tag--success">
<strong>OCS GE</strong>
</p>
</div>
<button class="fr-btn fr-btn--secondary fr-btn--sm fr-btn--icon-right fr-icon-arrow-down-s-fill mt-0" aria-expanded="false" aria-controls="target-data-aggregated-table">Détails données et calcul</button>
</div>
<div class="fr-collapse" id="target-data-aggregated-table">
<h6 class="fr-mt-2w">Source</h6>
<p class="fr-text--sm">Données d'OCcupation des Sols à Grande Echelle (OCS GE) de l'IGN, sur la période d'analyse. Zonages d'Urbanisme issus du Géoportail de l'Urbanisme (GPU) en date de juin 2023: <a href="https://www.geoportail-urbanisme.gouv.fr/" target="_blank" rel="noopener">https://www.geoportail-urbanisme.gouv.fr/</a></p>

<div class="fr-col-12 fr-col-lg-4">
{% include "project/components/widgets/static_map.html" with static_map=diagnostic.theme_map_gpu title="Carte présentant les zonages d'urbanisme du territoire" %}
<h6 class="fr-mt-2w">Calcul</h6>
<p class="fr-text--sm">Qualifier l'artificialisation de chaque parcelle OCS GE via la matrice d'artficialisation (<a href="{% url 'public_data:matrix' %}">consulter</a>). Puis comparer la surface totale des parcelles artificialisées dans chaque zonage d'urbanisme à la surface de la zone pour connaître le taux d'occupation.</p>
</div>

</div>
</div>

<div class="fr-notice bg-white fr-mt-4w">
<div class="fr-px-2w">
<div class="d-flex align-items-center justify-content-between">
<div>
<span class="fr-icon-information-line" aria-hidden="true"></span>
<span class="fr-text--xs fr-mr-1w">Source de données: </span>
<p class="fr-tag fr-tag--sm fr-tag--success">
<strong>OCS GE</strong>
</p>
</div>
<button class="fr-btn fr-btn--secondary fr-btn--sm fr-btn--icon-right fr-icon-arrow-down-s-fill mt-0" aria-expanded="false" aria-controls="target-data-aggregated-table">Détails données et calcul</button>
</div>
<div class="fr-collapse" id="target-data-aggregated-table">
<h6 class="fr-mt-2w">Source</h6>
<p class="fr-text--sm">Données d'OCcupation des Sols à Grande Echelle (OCS GE) de l'IGN, sur la période d'analyse. Zonages d'Urbanisme issus du Géoportail de l'Urbanisme (GPU) en date de juin 2023: <a href="https://www.geoportail-urbanisme.gouv.fr/" target="_blank" rel="noopener">https://www.geoportail-urbanisme.gouv.fr/</a></p>

<h6 class="fr-mt-2w">Calcul</h6>
<p class="fr-text--sm">Qualifier l'artificialisation de chaque parcelle OCS GE via la matrice d'artficialisation (<a href="{% url 'public_data:matrix' %}">consulter</a>). Puis comparer la surface totale des parcelles artificialisées dans chaque zonage d'urbanisme à la surface de la zone pour connaître le taux d'occupation.</p>
</div>
<h3>Explorateur</h3>


<div class="fr-grid-row fr-grid-row--gutters">
<div class="fr-col-12">
<div class="bg-white fr-p-2w h-100">
<iframe style="height:50vh" src="{% url 'project:map-urban-zones' project.pk %}" width="100%" frameborder="0"></iframe>
</div>
</div>
</div>

</div>
Loading

0 comments on commit e9ceb64

Please sign in to comment.