Projet

Général

Profil

0001-arcgis-tile-endpoint-17762.patch

Lauréline Guérin, 23 mars 2020 15:37

Télécharger (5,01 ko)

Voir les différences:

Subject: [PATCH] arcgis: tile endpoint (#17762)

 passerelle/apps/arcgis/models.py | 37 ++++++++++++++++++++++++++++
 tests/test_arcgis.py             | 41 ++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)
passerelle/apps/arcgis/models.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import math
17 18
import string
18 19

  
19 20
from django.core.exceptions import ValidationError
20 21
from django.core.urlresolvers import reverse
21 22
from django.db import models
23
from django.http import HttpResponse
22 24
from django.shortcuts import get_object_or_404
23 25
from django.utils.six.moves.urllib import parse as urlparse
24 26
from django.utils import six
......
191 193
            return {'data': features[0]}
192 194
        return {'data': features}
193 195

  
196
    @endpoint(
197
        name='tile',
198
        description=_('Tiles layer'),
199
        pattern=r'^(?P<layer>[\w/]+)/(?P<zoom>\d+)/(?P<tile_x>\d+)/(?P<tile_y>\d+)\.png$')
200
    def tile(self, request, layer, zoom, tile_x, tile_y):
201
        zoom = int(zoom)
202
        tile_x = int(tile_x)
203
        tile_y = int(tile_y)
204

  
205
        def num2deg(xtile, ytile, zoom):
206
            # http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Python
207
            n = 2.0 ** zoom
208
            lon_deg = xtile / n * 360.0 - 180.0
209
            lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
210
            lat_deg = math.degrees(lat_rad)
211
            return (lon_deg, lat_deg)
212

  
213
        bbox = '%s,%s,%s,%s' % (
214
            num2deg(tile_x, tile_y, zoom) +
215
            num2deg(tile_x+1, tile_y+1, zoom))
216

  
217
        # imageSR=3857: default projection for leaflet
218
        base_url = self.base_url
219
        if not base_url.endswith('/'):
220
            base_url += '/'
221
        return HttpResponse(
222
            self.requests.get(
223
                base_url +
224
                '%s/MapServer/export' % layer +
225
                '?dpi=96&format=png24&bboxSR=4326&imageSR=3857&' +
226
                'transparent=true&size=256,256&f=image&' +
227
                'bbox=%s' % bbox
228
            ).content,
229
            content_type='image/png')
230

  
194 231
    @endpoint(name='q',
195 232
              description=_('Query'),
196 233
              pattern=r'^(?P<query_slug>[\w:_-]+)/$',
tests/test_arcgis.py
338 338
        }
339 339

  
340 340

  
341
def test_tile_endpoint(arcgis, app):
342
    assert arcgis.base_url == 'https://arcgis.example.net/'
343

  
344
    with mock.patch('passerelle.utils.Request.get') as requests_get:
345
        requests_get.return_value = utils.FakedResponse(content='', status_code=200)
346

  
347
        resp = app.get('/arcgis/test/tile/layer1/13/4258/2991.png')
348
        assert requests_get.call_count == 1
349
        assert requests_get.call_args[0][0] == (
350
            'https://arcgis.example.net/layer1/MapServer/export'
351
            '?dpi=96&format=png24&bboxSR=4326&imageSR=3857&transparent=true&size=256,256&f=image'
352
            '&bbox=7.119140625,43.6122167682,7.1630859375,43.5803908556')
353
        assert resp.content_type == 'image/png'
354

  
355
    # test layer and folders
356
    with mock.patch('passerelle.utils.Request.get') as requests_get:
357
        requests_get.return_value = utils.FakedResponse(content='', status_code=200)
358

  
359
        resp = app.get('/arcgis/test/tile/layer1/foo/bar/13/4258/2991.png')
360
        assert requests_get.call_count == 1
361
        assert requests_get.call_args[0][0] == (
362
            'https://arcgis.example.net/layer1/foo/bar/MapServer/export'
363
            '?dpi=96&format=png24&bboxSR=4326&imageSR=3857&transparent=true&size=256,256&f=image'
364
            '&bbox=7.119140625,43.6122167682,7.1630859375,43.5803908556')
365
        assert resp.content_type == 'image/png'
366

  
367
    # test missing trailing slash
368
    arcgis.base_url = 'https://arcgis.example.net'
369
    arcgis.save()
370
    with mock.patch('passerelle.utils.Request.get') as requests_get:
371
        requests_get.return_value = utils.FakedResponse(content='', status_code=200)
372

  
373
        resp = app.get('/arcgis/test/tile/layer1/13/4258/2991.png')
374
        assert requests_get.call_count == 1
375
        assert requests_get.call_args[0][0] == (
376
            'https://arcgis.example.net/layer1/MapServer/export'
377
            '?dpi=96&format=png24&bboxSR=4326&imageSR=3857&transparent=true&size=256,256&f=image'
378
            '&bbox=7.119140625,43.6122167682,7.1630859375,43.5803908556')
379
        assert resp.content_type == 'image/png'
380

  
381

  
341 382
def test_export_import(query):
342 383
    assert ArcGIS.objects.count() == 1
343 384
    assert Query.objects.count() == 1
344
-