Пример #1
0
class FillTilesCacheTestCase(TestCase):

    def setUp(self):
        self.layer = LayerFactory(name="layerLine")
        self.group = LayerGroup.objects.create(name='mygroup', slug='mygroup')
        self.group.layers.add(self.layer)
        self.layer.from_geojson(
            geojson_data='''
            {
            "type": "FeatureCollection",
            "features": [
                {
                "type": "Feature",
                "properties": {
                    "foo": "bar",
                    "baba": "fifi"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                    [
                        1.3700294494628906,
                        43.603640347220924
                    ],
                    [
                        1.2984466552734375,
                        43.57902295875415
                    ]
                    ]
                }
                }
            ]
            }
        ''')

    def test_cache_filled(self):
        tile = VectorTile(self.layer)
        cache_version = get_cache_version(self.layer)

        x, y, z = 515, 373, 10
        query_count_before = len(connection.queries)

        call_command('fill_tiles_cache', stdout=StringIO())

        query_count_after = len(connection.queries)
        self.assertLess(query_count_before, query_count_after)

        tile.get_tile(x, y, z)

        self.assertIsNotNone(
            cache.get(
                tile.get_tile_cache_key(x, y, z),
                version=cache_version,
            )
        )

        self.assertEqual(len(connection.queries), query_count_after + 1)
Пример #2
0
class LayerFromGeojsonTestCase(TestCase):
    def setUp(self):
        self.layer = LayerFactory()
        self.user = UserFactory()
        self.client.force_login(self.user)

    def test_import_geojson_with_projection(self):
        with_projection = """{"type": "FeatureCollection", "crs":
                             { "type": "name", "properties": { "name":
                             "urn:ogc:def:crs:OGC:1.3:CRS84" } },
                             "features": []}"""
        self.layer.from_geojson(with_projection, "01-01", "01-01")

    def test_import_geojson_withtout_projection(self):
        without_projection = """{"type": "FeatureCollection",
                                "features": []}"""
        self.layer.from_geojson(without_projection, "01-01", "01-01")

        with_bad_projection = """{"type": "FeatureCollection", "crs":
                                 { "type": "name", "properties": { "name":
                                 "BADPROJECTION" } }, "features": []}"""
        with self.assertRaises(GEOSException):
            self.layer.from_geojson(with_bad_projection, "01-01", "01-01")
Пример #3
0
class VectorTilesTestCase(TestCase):
    group_name = 'mygroup'

    def setUp(self):
        settings = {'metadata': {'attribution': 'plop'}}

        self.layer = LayerFactory(name="layerLine", settings=settings)
        self.layer_extra_geom = LayerExtraGeom.objects.create(
            layer=self.layer,
            geom_type=GeometryTypes.LineString,
            title='Extra geometry')
        self.layer_relation = LayerSchemaFactory(
            name='layer_relation', geom_type=GeometryTypes.Polygon)
        self.feature_cover = FeatureFactory(
            layer=self.layer_relation,
            geom='POLYGON((0 0, 0 44, 3 44, 3 0, 0 0))')
        self.feature_not_cover = FeatureFactory(
            layer=self.layer_relation,
            geom='POLYGON((0 0, 0 43.579, 3 43.579, 3 0, 0 0))')

        self.mygroup = LayerGroup.objects.create(name='mygroup',
                                                 slug='mygroup')
        self.mygroup.layers.add(self.layer)
        self.layer.from_geojson(geojson_data='''
            {
            "type": "FeatureCollection",
            "features": [
                {
                "type": "Feature",
                "properties": {
                    "foo": "bar",
                    "baba": "fifi"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                    [
                        1.3700294494628906,
                        43.603640347220924
                    ],
                    [
                        1.2984466552734375,
                        43.57902295875415
                    ]
                    ]
                }
                }
            ]
            }
        ''')

        self.layerPoint = LayerFactory(name="layerPoint", settings=settings)
        self.yourgroup = LayerGroup.objects.create(name='yourgroup',
                                                   slug='yourgroup')
        self.yourgroup.layers.add(self.layerPoint)
        self.layerPoint.from_geojson(geojson_data='''
            {
            "type": "FeatureCollection",
            "features": [
                {
                "type": "Feature",
                "properties": {
                    "foo": "bar"
                },
                "geometry": {
                    "type": "Point",
                    "coordinates": [
                        1.3700294494628906,
                        43.603640347220924
                    ]
                }
                }
            ]
            }
        ''')

    def test_group_tilejson(self):
        response = self.client.get(
            reverse('group-tilejson', args=[self.mygroup.slug]),
            # HTTP_HOST required to build the tilejson descriptor
            HTTP_HOST='localhost')
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertGreater(len(response.content), 0)

        tile_json = response.json()

        self.assertTrue(tile_json['attribution'])
        self.assertTrue(tile_json['description'] is None)
        self.assertGreater(len(tile_json['vector_layers']), 0)
        self.assertGreater(len(tile_json['vector_layers'][0]['fields']), 0)
        self.assertEqual(
            tile_json['tiles'][0],
            unquote(
                urljoin(
                    "http://localhost",
                    reverse('group-tiles-pattern', args=[self.mygroup.slug]))))

    def test_layer_tilejson(self):
        LayerRelation.objects.create(
            name="Polygon",
            relation_type='intersects',
            origin=self.layer,
            destination=self.layer_relation,
        )
        response = self.client.get(
            reverse('layer-tilejson', args=[self.layer.pk]),
            # HTTP_HOST required to build the tilejson descriptor
            HTTP_HOST='localhost')
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertGreater(len(response.content), 0)

        tilejson = response.json()
        self.assertTrue(tilejson['attribution'])
        self.assertTrue(tilejson['description'] is None)
        self.assertGreater(len(tilejson['vector_layers']), 0)
        self.assertGreater(len(tilejson['vector_layers'][0]['fields']), 0)
        self.assertEqual(
            tilejson['tiles'][0],
            unquote(
                urljoin("http://localhost",
                        reverse('layer-tiles-pattern', args=[self.layer.pk]))))
        self.assertEqual(tilejson['vector_layers'], [{
            'description': 'Layerline',
            'fields': {
                'baba': '',
                'foo': ''
            },
            'id': 'layerLine',
            'maxzoom': 10,
            'minzoom': 10
        }, {
            'description': 'Extra Geometry',
            'fields': {},
            'id': 'layerline-extra-geometry',
            'maxzoom': 10,
            'minzoom': 10
        }, {
            'description': 'Polygon',
            'fields': {},
            'id': 'relation-layerline-polygon',
            'maxzoom': 22,
            'minzoom': 0
        }])

    @skipIf(not app_settings.TERRA_TILES_HOSTNAMES,
            'Test with custom tile hostnames only')
    def test_layer_tilejson_with_custom_hostnames(self):
        unquoted_reverse = unquote(
            reverse('layer-tiles-pattern', args=[self.layer.pk]))
        response = self.client.get(
            reverse('layer-tilejson', args=[self.layer.pk]))
        self.assertEqual(HTTP_200_OK, response.status_code)
        tilejson = response.json()
        self.assertListEqual(tilejson['tiles'], [
            urljoin(host, unquoted_reverse)
            for host in app_settings.TERRA_TILES_HOSTNAMES
        ])

    def test_layer_tilejson_without_features(self):
        self.layer.features.all().delete()
        response = self.client.get(
            reverse('layer-tilejson', args=[self.layer.pk]),
            # HTTP_HOST required to build the tilejson descriptor
            HTTP_HOST='localhost')
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertGreater(len(response.content), 0)

        tilejson = response.json()
        self.assertTrue(tilejson['attribution'])
        self.assertTrue(tilejson['description'] is None)

    def test_404_tile_pattern(self):
        response = self.client.get(
            reverse('layer-tiles-pattern', kwargs={'pk': self.layer.pk}))
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

    def test_vector_group_tiles_view(self):
        # first query that generate the cache
        response = self.client.get(
            reverse('group-tiles',
                    kwargs={
                        'slug': self.mygroup.slug,
                        'z': 10,
                        'x': 515,
                        'y': 373
                    }))
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertGreater(len(response.content), 0)
        query_count = len(connection.queries)
        original_content = response.content

        # verify data is cached
        response = self.client.get(
            reverse('group-tiles',
                    kwargs={
                        'slug': self.mygroup.slug,
                        'z': 10,
                        'x': 515,
                        'y': 373
                    }))
        self.assertEqual(len(connection.queries), query_count - 3)
        self.assertEqual(original_content, response.content)

        response = self.client.get(
            reverse('group-tiles', args=[self.group_name, 10, 1, 1]))

        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertFalse(len(response.content))

    def test_vector_layer_tiles_view(self):
        # first query that generate the cache
        FeatureExtraGeom.objects.create(layer_extra_geom=self.layer_extra_geom,
                                        feature=self.layer.features.first(),
                                        geom=LineString(
                                            (1.370029449462, 43.60364034724),
                                            (1.4, 43.61)))
        layer_relation = LayerRelation.objects.create(
            name="Polygon",
            relation_type='intersects',
            origin=self.layer,
            destination=self.layer_relation,
        )
        self.layer.features.first().sync_relations(layer_relation.pk)

        response = self.client.get(
            reverse('layer-tiles',
                    kwargs={
                        'pk': self.layer.pk,
                        'z': 10,
                        'x': 515,
                        'y': 373
                    }))
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertGreater(len(response.content), 0)
        self.assertIn(b'layerLine', response.content)
        self.assertIn(b'layerline-extra-geometry', response.content)
        self.assertIn(b'relation-layerline-polygon', response.content)
        query_count = len(connection.queries)
        original_content = response.content
        # verify data is cached
        response = self.client.get(
            reverse('layer-tiles',
                    kwargs={
                        'pk': self.layer.pk,
                        'z': 10,
                        'x': 515,
                        'y': 373
                    }))
        self.assertEqual(len(connection.queries), query_count - 5)
        self.assertEqual(original_content, response.content)

        response = self.client.get(
            reverse('layer-tiles',
                    kwargs={
                        'pk': self.layer.pk,
                        'z': 10,
                        'x': 1,
                        'y': 1
                    }))

        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertEqual(b'', response.content)

    @override_settings(MAX_TILE_ZOOM=9)
    def test_vector_group_tiles_view_max_tile_zoom_lower_actual_zoom(self):
        # first query that generate the cache
        response = self.client.get(
            reverse('group-tiles', args=[self.mygroup.slug, 10, 515, 373]))
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertEqual(len(response.content), 113)

    @override_settings(MAX_TILE_ZOOM=9)
    def test_vector_layer_tiles_view_max_tile_zoom_lower_actual_zoom(self):
        # first query that generate the cache
        response = self.client.get(
            reverse('layer-tiles', args=[self.layer.pk, 10, 515, 373]))
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertEqual(len(response.content), 113)

    def test_filtering(self):
        tile = VectorTile(self.layer, "CACHINGCACHE")
        x, y, z = 16506, 11966, 15

        tile = tile.get_tile(x, y, z)
        self.assertGreater(len(tile), 0)

    def test_guess_maxzoom(self):
        # guess_maxzoom returning -1 when TypeError is raised14)
        self.assertEqual(guess_maxzoom(self.layerPoint), 14)

        self.assertEqual(guess_maxzoom(self.layer) is not None, True)

        # test guess_maxzoom returns sensible value from OSM Fontainebleau paths&tracks
        chunk_fontainebleau_geojson = get_files_tests(
            'chunk_fontainebleau.geojson')

        call_command('import_geojson',
                     chunk_fontainebleau_geojson,
                     '-gr',
                     'maxzoom_test',
                     '-ln',
                     'chunk_fontainebleau',
                     verbosity=0)

        layer_chunk_fontainebleau = Layer.objects.get(
            name='chunk_fontainebleau')

        self.assertEqual(guess_maxzoom(layer_chunk_fontainebleau), 13)

    def test_guess_minzoom(self):
        self.assertEqual(guess_minzoom(self.layerPoint), 0)

        self.assertTrue(isinstance(guess_minzoom(self.layer), int))
Пример #4
0
class VectorTilesSpecialTestCase(TestCase):
    group_name = 'mygroup'

    def setUp(self):
        # Same as default with properties filter not None
        settings = {
            'metadata': {
                'attribution': 'plop'
            },
            'tiles': {
                'minzoom': 0,
                'maxzoom': 22,
                'pixel_buffer': 4,
                'features_filter': None,  # Json
                'properties_filter': [
                    'Test',
                ],  # Array of string
                'features_limit': 10000,
            }
        }

        self.layer = LayerFactory(name="layerLine", settings=settings)
        self.group = LayerGroup.objects.create(name='mygroup', slug='mygroup')
        self.group.layers.add(self.layer)

        self.geojson_data = '''
            {
            "type": "FeatureCollection",
            "features": [
                {
                "type": "Feature",
                "properties": {
                    "foo": "bar",
                    "baba": "fifi"
                },
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                    [
                        1.3700294494628906,
                        43.603640347220924
                    ],
                    [
                        1.2984466552734375,
                        43.57902295875415
                    ]
                    ]
                }
                }
            ]
            }
        '''
        self.layer.from_geojson(geojson_data=self.geojson_data)

    def test_group_tilejson_with_properties(self):
        response = self.client.get(
            reverse('group-tilejson', args=[self.group_name]),
            # HTTP_HOST required to build the tilejson descriptor
            HTTP_HOST='localhost')
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertGreater(len(response.content), 0)

        tilejson = response.json()
        self.assertTrue(tilejson['attribution'])
        self.assertTrue(tilejson['description'] is None)
        self.assertGreater(len(tilejson['vector_layers']), 0)
        self.assertGreater(len(tilejson['vector_layers'][0]['fields']), 0)

    def test_layer_tilejson_with_properties(self):
        response = self.client.get(
            reverse('layer-tilejson', args=[self.layer.pk]),
            # HTTP_HOST required to build the tilejson descriptor
            HTTP_HOST='localhost')
        self.assertEqual(HTTP_200_OK, response.status_code)
        self.assertGreater(len(response.content), 0)

        tilejson = json.loads(response.content)
        self.assertTrue(tilejson['attribution'])
        self.assertTrue(tilejson['description'] is None)
        self.assertGreater(len(tilejson['vector_layers']), 0)
        self.assertGreater(len(tilejson['vector_layers'][0]['fields']), 0)