Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Decouple topologies from the path network
- Modifications of the topology model (refs #5253)
- Update filters (refs #5259)
  • Loading branch information
justinefricou committed Feb 26, 2026
commit ab1164f61e5c9acca598e7f320d6a19bcc1f317a
75 changes: 35 additions & 40 deletions docs/advanced-configuration/interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"category",
"length",
"structure",
"coupled",
"min_elevation",
"max_elevation",
"date_update",
Expand All @@ -153,6 +154,7 @@ A complete list of attributes that can be used for displaying or exporting colum
]
COLUMNS_LISTS["landedge_view"] = [
"eid",
"coupled",
"min_elevation",
"max_elevation",
"date_update",
Expand All @@ -167,6 +169,7 @@ A complete list of attributes that can be used for displaying or exporting colum
]
COLUMNS_LISTS["circulationedge_view"] = [
"eid",
"coupled",
"min_elevation",
"max_elevation",
"date_update",
Expand All @@ -183,6 +186,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"date_update",
"length",
"length_2d",
"coupled",
"min_elevation",
"max_elevation",
"uuid",
Expand All @@ -196,6 +200,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"date_update",
"length",
"length_2d",
"coupled",
"min_elevation",
"max_elevation",
"uuid",
Expand All @@ -209,6 +214,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"structure",
"type",
"description",
"coupled",
"accessibility",
"date_update",
"date_insert",
Expand All @@ -235,6 +241,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"implantation_year",
"printed_elevation",
"coordinates",
"coupled",
"sealing",
"access",
"manager",
Expand Down Expand Up @@ -305,6 +312,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"public_transport",
"themes",
"practice",
"coupled",
"min_elevation",
"max_elevation",
"length_2d",
Expand Down Expand Up @@ -337,6 +345,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"structure",
"description",
"type",
"coupled",
"min_elevation",
"date_update",
"date_insert",
Expand All @@ -347,6 +356,7 @@ A complete list of attributes that can be used for displaying or exporting colum
]
COLUMNS_LISTS["service_view"] = [
"structure",
"coupled",
"min_elevation",
"type",
"length_2d",
Expand Down Expand Up @@ -570,6 +580,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"cities",
"districts",
"areas",
"coupled",
"length",
"ascent",
"descent",
Expand All @@ -583,41 +594,13 @@ A complete list of attributes that can be used for displaying or exporting colum
]
COLUMNS_LISTS["signagemanagementedge_export"] = [
"eid",
"date_insert",
"date_update",
"length",
"length_2d",
"min_elevation",
"max_elevation",
"uuid",
"provider",
"last_author",
"creator",
"authors",
]
COLUMNS_LISTS["workmanagementedge_export"] = [
"eid",
"date_insert",
"date_update",
"length",
"length_2d",
"min_elevation",
"max_elevation",
"uuid",
"last_author",
"creator",
"authors",
]
COLUMNS_LISTS["landedge_export"] = [
"eid",
"land_type",
"owner",
"agreement",
"organization",
"date_insert",
"date_update",
"cities",
"districts",
"areas",
"coupled",
"length",
"length_2d",
"ascent",
Expand All @@ -630,15 +613,15 @@ A complete list of attributes that can be used for displaying or exporting colum
"creator",
"authors",
]
COLUMNS_LISTS["circulationedge_export"] = [
COLUMNS_LISTS["workmanagementedge_export"] = [
"eid",
"circulation_type",
"authorization_type",
"organization",
"date_insert",
"date_update",
"cities",
"districts",
"areas",
"coupled",
"length",
"length_2d",
"ascent",
Expand All @@ -651,9 +634,12 @@ A complete list of attributes that can be used for displaying or exporting colum
"creator",
"authors",
]
COLUMNS_LISTS["physicaledge_export"] = [
COLUMNS_LISTS["landedge_export"] = [
"eid",
"physical_type",
"land_type",
"owner",
"agreement",
"coupled",
"date_insert",
"date_update",
"cities",
Expand All @@ -671,14 +657,16 @@ A complete list of attributes that can be used for displaying or exporting colum
"creator",
"authors",
]
COLUMNS_LISTS["competenceedge_export"] = [
COLUMNS_LISTS["circulationedge_export"] = [
"eid",
"organization",
"circulation_type",
"authorization_type",
"date_insert",
"date_update",
"cities",
"districts",
"areas",
"coupled",
"length",
"length_2d",
"ascent",
Expand All @@ -691,14 +679,15 @@ A complete list of attributes that can be used for displaying or exporting colum
"creator",
"authors",
]
COLUMNS_LISTS["signagemanagementedge_export"] = [
COLUMNS_LISTS["physicaledge_export"] = [
"eid",
"organization",
"physical_type",
"date_insert",
"date_update",
"cities",
"districts",
"areas",
"coupled",
"length",
"length_2d",
"ascent",
Expand All @@ -711,14 +700,15 @@ A complete list of attributes that can be used for displaying or exporting colum
"creator",
"authors",
]
COLUMNS_LISTS["workmanagementedge_export"] = [
COLUMNS_LISTS["competenceedge_export"] = [
"eid",
"organization",
"date_insert",
"date_update",
"cities",
"districts",
"areas",
"coupled",
"length",
"length_2d",
"ascent",
Expand Down Expand Up @@ -747,6 +737,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"cities",
"districts",
"areas",
"coupled",
"ascent",
"descent",
"min_elevation",
Expand Down Expand Up @@ -781,6 +772,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"sealing",
"access",
"manager",
"coupled",
"length",
"ascent",
"descent",
Expand Down Expand Up @@ -906,6 +898,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"areas",
"source",
"portal",
"coupled",
"length_2d",
"length",
"ascent",
Expand Down Expand Up @@ -935,6 +928,7 @@ A complete list of attributes that can be used for displaying or exporting colum
"cities",
"districts",
"areas",
"coupled",
"length",
"ascent",
"descent",
Expand All @@ -949,6 +943,7 @@ A complete list of attributes that can be used for displaying or exporting colum
COLUMNS_LISTS["service_export"] = [
"eid",
"type",
"coupled",
"length",
"ascent",
"descent",
Expand Down
10 changes: 10 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ CHANGELOG
2.124.1+dev (XXXX-XX-XX)
----------------------------

**Warnings**

* Topologies no longer need to depend on the path network: they can now exist independently or be based on paths, regardless of the dynamic segmentation setting.

**Improvements**

* Add a "Network-coupled" boolean field and its corresponding filter to the ``Topology`` model
* Strengthen the "invalid topology" filter criteria
* Remove the "invalid geometry" filter


2.124.1 (2026-02-17)
----------------------------
Expand Down
5 changes: 5 additions & 0 deletions geotrek/common/templatetags/geotrek_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,8 @@ def duration(value):
final_duration = _("%s min") % duration.minute

return final_duration


@register.filter
def model_class(obj):
return obj._meta.model
57 changes: 14 additions & 43 deletions geotrek/core/filters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from dal import autocomplete
from django.conf import settings
from django.db.models import Count, F, Q
from django.forms import widgets
from django.utils.translation import gettext_lazy as _
from django_filters import (
Expand All @@ -12,19 +11,22 @@
from geotrek.altimetry.filters import AltimetryAllGeometriesFilterSet
from geotrek.authent.filters import StructureRelatedFilterSet
from geotrek.common.filters import RightFilter
from geotrek.common.functions import GeometryType
from geotrek.common.models import Provider
from geotrek.maintenance import models as maintenance_models
from geotrek.maintenance.filters import InterventionFilterSet, ProjectFilterSet
from geotrek.zoning.filters import ZoningFilterSet

from .functions import TopologyIsValid
from .models import CertificationLabel, Comfort, Network, Path, Topology, Trail, Usage


class ValidTopologyFilterSet(FilterSet):
# Do not forget to add geometry_types_allowed on models if you add this filterset
# geometry_types_allowed = ["LINESTRING"] for example
# Types possible with topologies are linestring and points only
class Meta:
model = Topology
if settings.TREKKING_TOPOLOGY_ENABLED:
fields = ["coupled", "is_valid_topology"]
else:
fields = []

if settings.TREKKING_TOPOLOGY_ENABLED:
is_valid_topology = BooleanFilter(
Expand All @@ -34,46 +36,14 @@ class ValidTopologyFilterSet(FilterSet):
attrs={"class": "form-control form-control-sm"}
),
)
is_valid_geometry = BooleanFilter(
label=_("Valid geometry"),
method="filter_valid_geometry",
widget=widgets.NullBooleanSelect(
attrs={"class": "form-control form-control-sm"}
),
)

def filter_valid_topology(self, qs, name, value):
if value is not None:
qs = qs.annotate(
distinct_same_order=Count("aggregations__order", distinct=True),
same_order=Count("aggregations__order"),
)
if value is True:
qs = qs.filter(same_order__gt=0, same_order=F("distinct_same_order"))
elif value is False:
qs = qs.filter(
Q(same_order=0) | Q(distinct_same_order__lt=F("same_order"))
def filter_valid_topology(self, qs, name, value):
if value is not None:
id_column = "id" if qs.model == Topology else "topo_object_id"
qs = qs.alias(topology_is_valid=TopologyIsValid(id_column)).filter(
topology_is_valid=value
)
return qs

def filter_valid_geometry(self, qs, name, value):
if value is not None:
qs = qs.annotate(geometry_type=GeometryType("geom"))
if value is True:
qs = (
qs.filter(geom__isvalid=True)
.exclude(geom__isnull=True)
.exclude(geom__isempty=True)
.filter(geometry_type__in=qs.model.geometry_types_allowed)
)
elif value is False:
qs = qs.filter(
Q(geom__isnull=True)
| Q(geom__isvalid=False)
| Q(geom__isempty=True)
| ~Q(geometry_type__in=qs.model.geometry_types_allowed)
)
return qs
return qs


class TopologyFilter(RightFilter):
Expand Down Expand Up @@ -189,6 +159,7 @@ class Meta(StructureRelatedFilterSet.Meta):
model = Trail
fields = [
*StructureRelatedFilterSet.Meta.fields,
*ValidTopologyFilterSet.Meta.fields,
"name",
"category",
"departure",
Expand Down
8 changes: 8 additions & 0 deletions geotrek/core/functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.db.models import BooleanField
from django.db.models.expressions import Func


class TopologyIsValid(Func):
function = "TopologyIsValid"
arity = 1
output_field = BooleanField()
Loading