Projet

Général

Profil

0001-misc-add-distance-criteria-61832.patch

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

Télécharger (3,9 ko)

Voir les différences:

Subject: [PATCH 1/2] misc: add distance criteria (#61832)

 wcs/qommon/storage.py |  9 +++++++++
 wcs/sql.py            | 25 +++++++++++++++++++++++--
 2 files changed, 32 insertions(+), 2 deletions(-)
wcs/qommon/storage.py
403 403
        return lambda x: False
404 404

  
405 405

  
406
class Distance(Criteria):
407
    def __init__(self, point, distance):
408
        self.point = point  # {'lat': ..., 'lon': ...}
409
        self.distance = distance  # in meters
410

  
411
    def build_lambda(self):
412
        raise NotImplementedError()
413

  
414

  
406 415
def parse_clause(clause):
407 416
    # creates a callable out of a clause
408 417
    #  (attribute, operator, value)
wcs/sql.py
478 478
        return {}
479 479

  
480 480

  
481
class Distance(wcs.qommon.storage.Distance):
482
    def as_sql(self):
483
        # simplest distance approximation <https://www.mkompf.com/gps/distcalc.html>
484
        return f'''(111300 * SQRT(POWER((auto_geoloc[0] - {self.point['lon']}) *
485
                                         COS((auto_geoloc[1] + {self.point['lat']}) / 2 * 0.01745), 2)
486
                                  + POWER(auto_geoloc[1] - {self.point['lat']}, 2)))
487
                    < {self.distance}'''
488

  
489
    def as_sql_param(self):
490
        return {}
491

  
492

  
481 493
def get_name_as_sql_identifier(name):
482 494
    name = qommon.misc.simplify(name)
483 495
    for char in '<>|{}!?^*+/=\'':  # forbidden chars
......
787 799
        'digests',
788 800
        'user_label',
789 801
        'prefilling_data',
802
        'auto_geoloc',
790 803
    }
791 804

  
792 805
    # migrations
......
843 856
    if 'prefilling_data' not in existing_fields:
844 857
        cur.execute('''ALTER TABLE %s ADD COLUMN prefilling_data bytea''' % table_name)
845 858

  
859
    if 'auto_geoloc' not in existing_fields:
860
        cur.execute('''ALTER TABLE %s ADD COLUMN auto_geoloc POINT''' % table_name)
861

  
846 862
    # add new fields
847 863
    for field in formdef.get_all_fields():
848 864
        assert field.id is not None
......
2754 2770

  
2755 2771
        sql_dict['concerned_roles_array'] = [str(x) for x in self.concerned_roles if x]
2756 2772
        sql_dict['actions_roles_array'] = [str(x) for x in self.actions_roles if x]
2773
        auto_geoloc_value = self.get_auto_geoloc()
2774
        if auto_geoloc_value:
2775
            auto_geoloc_value = '(%.6f, %.6f)' % (auto_geoloc_value.get('lon'), auto_geoloc_value.get('lat'))
2776
        sql_dict['auto_geoloc'] = auto_geoloc_value
2757 2777

  
2758 2778
        sql_dict.update(self.get_sql_dict_from_data(self.data, self._formdef))
2759 2779
        conn, cur = get_connection_and_cursor()
......
4569 4589
# latest migration, number + description (description is not used
4570 4590
# programmaticaly but will make sure git conflicts if two migrations are
4571 4591
# separately added with the same number)
4572
SQL_LEVEL = (68, 'multilinguism')
4592
SQL_LEVEL = (69, 'add auto_geoloc field')
4573 4593

  
4574 4594

  
4575 4595
def migrate_global_views(conn, cur):
......
4833 4853
                continue
4834 4854
            for formdata in formdef.data_class().select_iterator():
4835 4855
                formdata._set_auto_fields(cur)  # build digests
4836
    if sql_level < 58:
4856
    if sql_level < 69:
4837 4857
        # 58: add workflow_merged_roles_dict as a jsonb column with
4838 4858
        #     combined formdef and formdata value.
4859
        # 69: add auto_geoloc field to form/card tables
4839 4860
        from wcs.carddef import CardDef
4840 4861
        from wcs.formdef import FormDef
4841 4862

  
4842
-