Projet

Général

Profil

0001-arcgis-create-a-general-request-system-63825.patch

Thomas Noël, 23 mai 2022 15:00

Télécharger (7,85 ko)

Voir les différences:

Subject: [PATCH 1/3] arcgis: create a general request system (#63825)

 passerelle/apps/arcgis/models.py | 149 ++++++++++++++++---------------
 1 file changed, 79 insertions(+), 70 deletions(-)
passerelle/apps/arcgis/models.py
45 45
    class Meta:
46 46
        verbose_name = _('ArcGIS REST API')
47 47

  
48
    @endpoint(
49
        name='mapservice-query',
50
        description=_('Map Service Query'),
51
        perm='can_access',
52
        parameters={
53
            'folder': {
54
                'description': _('Folder name'),
55
                'example_value': 'Specialty',
56
            },
57
            'service': {
58
                'description': _('Service name'),
59
                'example_value': 'ESRI_StateCityHighway_USA',
60
            },
61
            'layer': {
62
                'description': _('Layer or table name'),
63
                'example_value': '1',
64
            },
65
            'lat': {'description': _('Latitude')},
66
            'lon': {'description': _('Longitude')},
67
            'latmin': {'description': _('Minimal latitude (envelope)')},
68
            'lonmin': {'description': _('Minimal longitude (envelope)')},
69
            'latmax': {'description': _('Maximal latitude (envelope)')},
70
            'lonmax': {'description': _('Maximal longitude (envelope)')},
71
            'q': {'description': _('Search text in display field')},
72
            'template': {
73
                'description': _('Django template for text attribute'),
74
                'example_value': '{{ attributes.STATE_NAME }} ({{ attributes.STATE_ABBR }})',
75
            },
76
            'id_template': {
77
                'description': _('Django template for id attribute'),
78
            },
79
            'full': {
80
                'description': _('Returns all ArcGIS informations (geometry, metadata)'),
81
                'type': 'bool',
82
            },
83
        },
84
    )
85
    def mapservice_query(
86
        self,
87
        request,
88
        service,
89
        layer='0',
90
        folder='',
91
        lat=None,
92
        lon=None,
93
        latmin=None,
94
        lonmin=None,
95
        latmax=None,
96
        lonmax=None,
97
        q=None,
98
        template=None,
99
        id_template=None,
100
        full=False,
101
        **kwargs,
102
    ):
103
        url = urlparse.urljoin(self.base_url, 'services/')
104
        if folder:
105
            url = urlparse.urljoin(url, folder + '/')
106
        url = urlparse.urljoin(url, service + '/MapServer/' + layer + '/query')
107

  
108
        # build query params
109
        # cf https://developers.arcgis.com/rest/services-reference/query-map-service-layer-.htm
48
    def build_common_params(self, lat, lon, latmin, lonmin, latmax, lonmax, **kwargs):
49
        # build common query params, see:
50
        # https://developers.arcgis.com/rest/services-reference/query-map-service-layer-.htm
51
        # https://developers.arcgis.com/rest/services-reference/enterprise/query-feature-service-layer-.htm
110 52
        params = {
111 53
            'f': 'json',
112 54
            'inSR': '4326',
......
128 70
                raise APIError('<lonmin> <latmin> <lonmax> and <latmax> must be floats', http_status=400)
129 71
            params['geometry'] = '{},{},{},{}'.format(lonmin, latmin, lonmax, latmax)
130 72
            params['geometryType'] = 'esriGeometryEnvelope'
131
        if q is not None:
132
            params['text'] = q
133 73
        # consider all remaining parameters as ArcGIS ones
134 74
        params.update(kwargs)
135
        if 'where' not in params and 'text' not in params:
136
            params['where'] = '1=1'
137 75
        if 'distance' in params and 'units' not in params:
138 76
            params['units'] = 'esriSRUnit_Meter'
77
        return params
139 78

  
79
    def get_query_response(self, uri, params, id_template, text_template, full):
80
        url = urlparse.urljoin(self.base_url, uri)
140 81
        response = self.requests.get(url, params=params)
141 82

  
142
        # errors
143 83
        if response.status_code // 100 != 2:
144 84
            raise ArcGISError('ArcGIS returned status code %s' % response.status_code)
145 85
        try:
......
158 98
        else:
159 99
            aliases = {}
160 100

  
161
        # data is the features list, with 'id' and 'text' entries
162 101
        data = []
163 102

  
164 103
        def get_feature_attribute(feature, attribute):
......
172 111
                feature['text'] = '%s' % get_feature_attribute(feature, text_fieldname)
173 112
            else:
174 113
                feature['id'] = feature['text'] = '%d' % (n + 1)
175
            if template:
176
                feature['text'] = render_to_string(template, feature)
177 114
            if id_template:
178 115
                feature['id'] = render_to_string(id_template, feature)
116
            if text_template:
117
                feature['text'] = render_to_string(text_template, feature)
179 118
            if not full and 'geometry' in feature:
180 119
                del feature['geometry']
181 120
            data.append(feature)
......
184 123
            return {'data': data, 'metadata': infos}
185 124
        return {'data': data}
186 125

  
126
    @endpoint(
127
        name='mapservice-query',
128
        description=_('Map Service Query'),
129
        perm='can_access',
130
        parameters={
131
            'folder': {
132
                'description': _('Folder name'),
133
                'example_value': 'Specialty',
134
            },
135
            'service': {
136
                'description': _('Service name'),
137
                'example_value': 'ESRI_StateCityHighway_USA',
138
            },
139
            'layer': {
140
                'description': _('Layer or table name'),
141
                'example_value': '1',
142
            },
143
            'lat': {'description': _('Latitude')},
144
            'lon': {'description': _('Longitude')},
145
            'latmin': {'description': _('Minimal latitude (envelope)')},
146
            'lonmin': {'description': _('Minimal longitude (envelope)')},
147
            'latmax': {'description': _('Maximal latitude (envelope)')},
148
            'lonmax': {'description': _('Maximal longitude (envelope)')},
149
            'q': {'description': _('Search text in display field')},
150
            'template': {
151
                'description': _('Django template for text attribute'),
152
                'example_value': '{{ attributes.STATE_NAME }} ({{ attributes.STATE_ABBR }})',
153
            },
154
            'id_template': {
155
                'description': _('Django template for id attribute'),
156
            },
157
            'full': {
158
                'description': _('Returns all ArcGIS informations (geometry, metadata)'),
159
                'type': 'bool',
160
            },
161
        },
162
    )
163
    def mapservice_query(
164
        self,
165
        request,
166
        service,
167
        layer='0',
168
        folder='',
169
        lat=None,
170
        lon=None,
171
        latmin=None,
172
        lonmin=None,
173
        latmax=None,
174
        lonmax=None,
175
        q=None,
176
        template=None,
177
        id_template=None,
178
        full=False,
179
        **kwargs,
180
    ):
181
        uri = 'services/'
182
        if folder:
183
            uri += folder + '/'
184
        uri = uri + service + '/MapServer/' + layer + '/query'
185

  
186
        params = self.build_common_params(lat, lon, latmin, lonmin, latmax, lonmax, **kwargs)
187
        if q is not None and 'text' not in params:
188
            params['text'] = q
189
        if 'where' not in params and 'text' not in params:
190
            params['where'] = '1=1'
191

  
192
        return self.get_query_response(
193
            uri, params, id_template=id_template, text_template=template, full=full
194
        )
195

  
187 196
    @endpoint(
188 197
        name='tile',
189 198
        description=_('Tiles layer'),
190
-