Projet

Général

Profil

0002-misc-use-new-Distance-criteria-in-distance-filter-61.patch

Frédéric Péters, 20 novembre 2022 19:34

Télécharger (3,64 ko)

Voir les différences:

Subject: [PATCH 2/2] misc: use new Distance criteria in distance filter
 (#61832)

This is less precise than the calculation using pyproj but good enough
for small distances.

(the change is required to tests as a computed distance changes from
199685 to 200577 and is thus no longer <200000).
 tests/test_formdata.py | 13 +++++++------
 wcs/variables.py       | 15 ++-------------
 2 files changed, 9 insertions(+), 19 deletions(-)
tests/test_formdata.py
1280 1280

  
1281 1281
    # compute distance against geolocation
1282 1282
    lazy_formdata._formdata.geolocations = {'base': {'lat': 2, 'lon': 2.5}}
1283
    lazy_formdata._formdata.store()
1283 1284
    nearby = lazy_formdata.objects.distance_filter(200000)
1284
    assert len(nearby) == 6
1285
    assert {x.number for x in nearby} == {'1-1', '1-4', '1-5', '1-9', '1-10', '1-11'}
1285
    assert len(nearby) == 5
1286
    assert {x.number for x in nearby} == {'1-1', '1-4', '1-5', '1-9', '1-10'}
1286 1287
    assert bool(nearby) is True
1287 1288
    nearby = lazy_carddata.objects.set_geo_center(lazy_formdata).distance_filter(200000)
1288
    assert len(nearby) == 6
1289
    assert {x.number for x in nearby} == {'1-1', '1-4', '1-5', '1-9', '1-10', '1-11'}
1289
    assert len(nearby) == 5
1290
    assert {x.number for x in nearby} == {'1-1', '1-4', '1-5', '1-9', '1-10'}
1290 1291
    assert bool(nearby) is True
1291 1292

  
1292 1293
    context = pub.substitutions.get_context_variables(mode='lazy')
1293 1294
    tmpl = Template('{{form_objects|distance_filter:200000|count}}')
1294
    assert tmpl.render(context) == '6'
1295
    assert tmpl.render(context) == '5'
1295 1296
    tmpl = Template('{{cards|objects:"items"|set_geo_center:form|distance_filter:200000|count}}')
1296
    assert tmpl.render(context) == '6'
1297
    assert tmpl.render(context) == '5'
1297 1298

  
1298 1299
    lazy_formdata._formdata.geolocations = {'base': {'lat': 7, 'lon': 7.5}}
1299 1300
    nearby = lazy_formdata.objects.distance_filter(200000)
wcs/variables.py
18 18

  
19 19
from django.utils.encoding import force_text
20 20
from django.utils.functional import SimpleLazyObject
21
from pyproj import Geod
22 21
from quixote import get_publisher, get_request
23 22

  
24 23
from .carddef import CardDef, CardDefDoesNotExist
......
29 28
from .qommon.storage import (
30 29
    And,
31 30
    Contains,
31
    Distance,
32 32
    Equal,
33 33
    Greater,
34 34
    GreaterOrEqual,
......
190 190
        return qs
191 191

  
192 192
    def distance_filter(self, distance):
193
        geod = Geod(ellps='WGS84')
194 193
        center = (self._geoloc_center_formdata or self._formdata).get_auto_geoloc()
195 194
        if center is None:
196 195
            return self.none()
197
        center_lon, center_lat = center['lon'], center['lat']
198

  
199
        def distance_check(obj):
200
            geoloc = obj.get_auto_geoloc()
201
            if not geoloc:
202
                return False
203
            # keep computed distance in object
204
            obj._distance = geod.inv(center_lon, center_lat, geoloc['lon'], geoloc['lat'])[2]
205
            return bool(obj._distance < distance)
206

  
207
        return self._clone(self._criterias + [distance_check])
196
        return self._clone(self._criterias + [Distance(center, distance)])
208 197

  
209 198
    def filter_by(self, attribute):
210 199
        qs = self._clone(self._criterias)
211
-