Example #1
0
    def overlapping(cls, klass, queryset):
        from .models import Path, Topology, PathAggregation

        all_objects = klass.objects.existing()
        is_generic = klass.KIND == Topology.KIND
        single_input = isinstance(queryset, QuerySet)

        if single_input:
            topology_pks = [
                str(pk) for pk in queryset.values_list('pk', flat=True)
            ]
        else:
            topology_pks = [str(queryset.pk)]

        if len(topology_pks) == 0:
            return all_objects.filter(pk__in=[])

        sql = """
        WITH topologies AS (SELECT id FROM %(topology_table)s WHERE id IN (%(topology_list)s)),
        -- Concerned aggregations
             aggregations AS (SELECT * FROM %(aggregations_table)s a, topologies t
                              WHERE a.evenement = t.id),
        -- Concerned paths along with (start, end)
             paths_aggr AS (SELECT a.pk_debut AS start, a.pk_fin AS end, p.id, a.ordre AS order
                            FROM %(paths_table)s p, aggregations a
                            WHERE a.troncon = p.id
                            ORDER BY a.ordre)
        -- Retrieve primary keys
        SELECT t.id
        FROM %(topology_table)s t, %(aggregations_table)s a, paths_aggr pa
        WHERE a.troncon = pa.id AND a.evenement = t.id
          AND least(a.pk_debut, a.pk_fin) <= greatest(pa.start, pa.end)
          AND greatest(a.pk_debut, a.pk_fin) >= least(pa.start, pa.end)
          AND %(extra_condition)s
        ORDER BY (pa.order + CASE WHEN pa.start > pa.end THEN (1 - a.pk_debut) ELSE a.pk_debut END);
        """ % {
            'topology_table': Topology._meta.db_table,
            'aggregations_table': PathAggregation._meta.db_table,
            'paths_table': Path._meta.db_table,
            'topology_list': ','.join(topology_pks),
            'extra_condition':
            'true' if is_generic else "kind = '%s'" % klass.KIND
        }

        cursor = connection.cursor()
        cursor.execute(sql)
        result = cursor.fetchall()
        pk_list = uniquify([row[0] for row in result])

        # Return a QuerySet and preserve pk list order
        # http://stackoverflow.com/a/1310188/141895
        ordering = 'CASE %s END' % ' '.join([
            'WHEN %s.id=%s THEN %s' % (Topology._meta.db_table, id_, i)
            for i, id_ in enumerate(pk_list)
        ])
        queryset = all_objects.filter(pk__in=pk_list).extra(
            select={'ordering': ordering}, order_by=('ordering', ))
        return queryset
Example #2
0
    def overlapping(cls, klass, queryset):
        from .models import Path, Topology, PathAggregation

        all_objects = klass.objects.existing()
        is_generic = klass.KIND == Topology.KIND
        single_input = isinstance(queryset, QuerySet)

        if single_input:
            topology_pks = [str(pk) for pk in queryset.values_list('pk', flat=True)]
        else:
            topology_pks = [str(queryset.pk)]

        if len(topology_pks) == 0:
            return all_objects.filter(pk__in=[])

        sql = """
        WITH topologies AS (SELECT id FROM %(topology_table)s WHERE id IN (%(topology_list)s)),
        -- Concerned aggregations
             aggregations AS (SELECT * FROM %(aggregations_table)s a, topologies t
                              WHERE a.evenement = t.id),
        -- Concerned paths along with (start, end)
             paths_aggr AS (SELECT a.pk_debut AS start, a.pk_fin AS end, p.id, a.ordre AS order
                            FROM %(paths_table)s p, aggregations a
                            WHERE a.troncon = p.id
                            ORDER BY a.ordre)
        -- Retrieve primary keys
        SELECT t.id
        FROM %(topology_table)s t, %(aggregations_table)s a, paths_aggr pa
        WHERE a.troncon = pa.id AND a.evenement = t.id
          AND least(a.pk_debut, a.pk_fin) <= greatest(pa.start, pa.end)
          AND greatest(a.pk_debut, a.pk_fin) >= least(pa.start, pa.end)
          AND %(extra_condition)s
        ORDER BY (pa.order + CASE WHEN pa.start > pa.end THEN (1 - a.pk_debut) ELSE a.pk_debut END);
        """ % {
            'topology_table': Topology._meta.db_table,
            'aggregations_table': PathAggregation._meta.db_table,
            'paths_table': Path._meta.db_table,
            'topology_list': ','.join(topology_pks),
            'extra_condition': 'true' if is_generic else "kind = '%s'" % klass.KIND
        }

        cursor = connection.cursor()
        cursor.execute(sql)
        result = cursor.fetchall()
        pk_list = uniquify([row[0] for row in result])

        # Return a QuerySet and preserve pk list order
        # http://stackoverflow.com/a/1310188/141895
        ordering = 'CASE %s END' % ' '.join(['WHEN %s.id=%s THEN %s' % (Topology._meta.db_table, id_, i)
                                             for i, id_ in enumerate(pk_list)])
        queryset = all_objects.filter(pk__in=pk_list).extra(
            select={'ordering': ordering}, order_by=('ordering',))
        return queryset
Example #3
0
    def path_area_edges(cls, path):
        return cls.objects.existing()\
                          .select_related('restricted_area')\
                          .select_related('restricted_area__area_type')\
                          .filter(aggregations__path=path).distinct('pk')

    @classmethod
    def topology_area_edges(cls, topology):
        return cls.overlapping(topology)\
                  .select_related('restricted_area')\
                  .select_related('restricted_area__area_type')


if settings.TREKKING_TOPOLOGY_ENABLED:
    Path.add_property('area_edges', RestrictedAreaEdge.path_area_edges)
    Path.add_property('areas', lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)))
    Topology.add_property('area_edges', RestrictedAreaEdge.topology_area_edges)
    Topology.add_property('areas', lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)))
    Intervention.add_property('area_edges', lambda self: self.topology.area_edges if self.topology else [])
    Intervention.add_property('areas', lambda self: self.topology.areas if self.topology else [])
    Project.add_property('area_edges', lambda self: self.edges_by_attr('area_edges'))
    Project.add_property('areas', lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)))
else:
    Topology.add_property('areas', lambda self: intersecting(RestrictedArea, self))

TouristicContent.add_property('areas', lambda self: intersecting(RestrictedArea, self))
TouristicEvent.add_property('areas', lambda self: intersecting(RestrictedArea, self))


class City(models.Model):
    code = models.CharField(primary_key=True, max_length=6, db_column='insee')
Example #4
0
 def cities(self):
     return uniquify(intersecting(City, self.zoning_property, distance=0))
Example #5
0
 def districts(self):
     return uniquify(intersecting(District, self.zoning_property, distance=0))
Example #6
0
 def areas(self):
     return uniquify(intersecting(RestrictedArea, self.zoning_property, distance=0))
Example #7
0
    def path_area_edges(cls, path):
        return cls.objects.existing()\
                          .select_related('restricted_area')\
                          .select_related('restricted_area__area_type')\
                          .filter(aggregations__path=path).distinct('pk')

    @classmethod
    def topology_area_edges(cls, topology):
        return cls.overlapping(topology)\
                  .select_related('restricted_area')\
                  .select_related('restricted_area__area_type')


if settings.TREKKING_TOPOLOGY_ENABLED:
    Path.add_property('area_edges', RestrictedAreaEdge.path_area_edges, _("Restricted area edges"))
    Path.add_property('areas', lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)),
                      _("Restricted areas"))
    Topology.add_property('area_edges', RestrictedAreaEdge.topology_area_edges, _("Restricted area edges"))
    Topology.add_property('areas', lambda self: uniquify(
        intersecting(RestrictedArea, self)) if self.ispoint() else uniquify(
        map(attrgetter('restricted_area'), self.area_edges)), _("Restricted areas"))
    Intervention.add_property('area_edges', lambda self: self.topology.area_edges if self.topology else [],
                              _("Restricted area edges"))
    Intervention.add_property('areas', lambda self: self.topology.areas if self.topology else [],
                              _("Restricted areas"))
    Project.add_property('area_edges', lambda self: self.edges_by_attr('area_edges'), _("Restricted area edges"))
    Project.add_property('areas', lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)),
                         _("Restricted areas"))
else:
    Topology.add_property('areas', lambda self: uniquify(intersecting(RestrictedArea, self, distance=0)),
                          _("Restricted areas"))
Example #8
0
    def path_area_edges(cls, path):
        return cls.objects.existing()\
                          .select_related('restricted_area')\
                          .select_related('restricted_area__area_type')\
                          .filter(aggregations__path=path).distinct('pk')

    @classmethod
    def topology_area_edges(cls, topology):
        return cls.overlapping(topology)\
                  .select_related('restricted_area')\
                  .select_related('restricted_area__area_type')


if settings.TREKKING_TOPOLOGY_ENABLED:
    Path.add_property('area_edges', RestrictedAreaEdge.path_area_edges, _(u"Restricted area edges"))
    Path.add_property('areas', lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)),
                      _(u"Restricted areas"))
    Topology.add_property('area_edges', RestrictedAreaEdge.topology_area_edges, _(u"Restricted area edges"))
    Topology.add_property('areas', lambda self: uniquify(
        intersecting(RestrictedArea, self)) if self.ispoint() else uniquify(
        map(attrgetter('restricted_area'), self.area_edges)), _(u"Restricted areas"))
    Intervention.add_property('area_edges', lambda self: self.topology.area_edges if self.topology else [],
                              _(u"Restricted area edges"))
    Intervention.add_property('areas', lambda self: self.topology.areas if self.topology else [],
                              _(u"Restricted areas"))
    Project.add_property('area_edges', lambda self: self.edges_by_attr('area_edges'), _(u"Restricted area edges"))
    Project.add_property('areas', lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)),
                         _(u"Restricted areas"))
else:
    Topology.add_property('areas', lambda self: uniquify(intersecting(RestrictedArea, self, distance=0)),
                          _(u"Restricted areas"))
Example #9
0
                          .filter(aggregations__path=path).distinct('pk')

    @classmethod
    def topology_area_edges(cls, topology):
        if settings.TREKKING_TOPOLOGY_ENABLED:
            qs = cls.overlapping(topology)
        else:
            qs = cls.objects.filter(geom__intersects=topology.geom)
        return qs.select_related('restricted_area')\
                 .select_related('restricted_area__area_type')


Path.add_property('area_edges', RestrictedAreaEdge.path_area_edges)
Path.add_property(
    'areas',
    lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)))
Topology.add_property('area_edges', RestrictedAreaEdge.topology_area_edges)
Topology.add_property(
    'areas',
    lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)))
Intervention.add_property(
    'area_edges', lambda self: self.topology.area_edges
    if self.topology else [])
Intervention.add_property(
    'areas', lambda self: self.topology.areas if self.topology else [])
Project.add_property('area_edges',
                     lambda self: self.edges_by_attr('area_edges'))
Project.add_property(
    'areas',
    lambda self: uniquify(map(attrgetter('restricted_area'), self.area_edges)))
Example #10
0
                          .select_related('restricted_area')\
                          .select_related('restricted_area__area_type')\
                          .filter(aggregations__path=path).distinct('pk')

    @classmethod
    def topology_area_edges(cls, topology):
        return cls.overlapping(topology)\
                  .select_related('restricted_area')\
                  .select_related('restricted_area__area_type')


if settings.TREKKING_TOPOLOGY_ENABLED:
    Path.add_property('area_edges', RestrictedAreaEdge.path_area_edges,
                      _("Restricted area edges"))
    Path.add_property(
        'areas', lambda self: uniquify(
            map(attrgetter('restricted_area'), self.area_edges)),
        _("Restricted areas"))
    Path.add_property(
        'published_areas',
        lambda self: [area for area in self.areas if area.published],
        _("Published areas"))
    Topology.add_property('area_edges', RestrictedAreaEdge.topology_area_edges,
                          _("Restricted area edges"))
    Topology.add_property(
        'areas', lambda self: uniquify(intersecting(RestrictedArea, self))
        if self.ispoint() else uniquify(
            map(attrgetter('restricted_area'), self.area_edges)),
        _("Restricted areas"))
    Intervention.add_property(
        'area_edges', lambda self: self.target.area_edges
        if self.target and self.target else [], _("Restricted area edges"))