Esempio n. 1
0
def test_get_bbox_test_cases(tile_generator: TileGenerator,
                             tile_test_cases: Dict[str, dict]):
    """
    test get_bbox for cases and all tiles between zoomlevel 0 to 10

    Arguments:
        tile_generator {TileGenerator} -- default TileGenerator
        tile_test_cases {Dict[str, dict]} -- tile test cases
    """
    # test special cases
    for test_case in tile_test_cases:
        tile_generator.zoom = tile_test_cases[test_case]["zoom"]
        tile_generator.x_pixel = tile_test_cases[test_case]["x"]
        tile_generator.y_pixel = tile_test_cases[test_case]["y"]
        box2d: Box2d = tile_generator.get_bbox()
        if not isinstance(box2d, Box2d):
            raise AssertionError
        if "{}".format(box2d.maxx) != tile_test_cases[test_case]["maxx"]:
            raise AssertionError
        if "{}".format(box2d.maxy) != tile_test_cases[test_case]["maxy"]:
            raise AssertionError
        if "{}".format(box2d.minx) != tile_test_cases[test_case]["minx"]:
            raise AssertionError
        if "{}".format(box2d.miny) != tile_test_cases[test_case]["miny"]:
            raise AssertionError
Esempio n. 2
0
def test_render_tile_without_data(tile_generator: TileGenerator,
                                  tile_test_cases: Dict[str, dict]):
    """
    test render tiles for tile_test_cases without using ohdm test data
    
    Arguments:
        tile_generator {TileGenerator} -- default TileGenerator
    """

    for test_case in tile_test_cases:
        print("test: {}".format(test_case))
        tile_generator.zoom = tile_test_cases[test_case]["zoom"]
        tile_generator.x_pixel = tile_test_cases[test_case]["x"]
        tile_generator.y_pixel = tile_test_cases[test_case]["y"]

        # generate new tile into a tmp file
        new_tile: SpooledTemporaryFile = SpooledTemporaryFile()
        new_tile.write(tile_generator.render_tile())
        new_tile.seek(0)

        # open new tile as image
        new_tile_image: Image = Image.open(new_tile)

        # check if the tile is a PNG file
        assert new_tile_image.format == "PNG"

        # monochrome & resize images to better compare them
        reference_tile = Image.open(
            "/app/compose/local/django/test_tile/{}".format(
                tile_test_cases[test_case]["tile_png"]))

        assert ImageChops.difference(reference_tile,
                                     new_tile_image).getbbox() is None
Esempio n. 3
0
def test_render_tile_with_data(tile_generator: TileGenerator,
                               tile_test_cases: Dict[str, dict]):
    """
    test render tiles for tile_test_cases with using ohdm test data
    
    Arguments:
        tile_generator {TileGenerator} -- default TileGenerator
    """
    # cleanup data
    clear_mapnik_tables()

    # fill database
    run_import(
        file_path="/map.osm",
        db_cache_size=10000,
        cache2file=False,
    )

    tile_generator.request_date = timezone.now()

    for test_case in tile_test_cases:
        # contine if test case has not test data
        if not tile_test_cases[test_case]["has_date_data"]:
            continue

        print("test: {}".format(test_case))
        tile_generator.zoom = tile_test_cases[test_case]["zoom"]
        tile_generator.x_pixel = tile_test_cases[test_case]["x"]
        tile_generator.y_pixel = tile_test_cases[test_case]["y"]

        # generate new tile into a tmp file
        new_tile: SpooledTemporaryFile = SpooledTemporaryFile()
        new_tile.write(tile_generator.render_tile())
        new_tile.seek(0)

        # open new tile as image
        new_tile_image: Image = Image.open(new_tile)

        new_tile_image.save("/app/bremen.png")

        # check if the tile is a PNG file
        assert new_tile_image.format == "PNG"

        # monochrome & resize images to better compare them
        reference_tile = Image.open(
            "/app/compose/local/django/test_tile/{}".format(
                tile_test_cases[test_case]["tile_png"]))

        diff: bool = ImageChops.difference(reference_tile,
                                           new_tile_image).getbbox() is None
        assert diff is False

    # cleanup data
    clear_mapnik_tables()
Esempio n. 4
0
def generate_tile_reload_style(request, year: int, month: int, day: int,
                               zoom: int, x_pixel: float,
                               y_pixel: float) -> HttpResponse:
    """
    reload style.xml & than generate a new mapnik tile
    :param request: django request
    :param year: request year as INT
    :param month: request month as INT
    :param day: request day as INT
    :param zoom: mapnik zoom level
    :param x_pixel: mapnik x coordinate
    :param y_pixel: mapnik y coordinate
    :return:
    """
    # generate time sensitive tile and reload style.xml
    tile_gen: TileGenerator = TileGenerator(
        request_date=date(year=int(year), month=int(month), day=int(day)),
        style_xml_template=get_style_xml(
            generate_style_xml=False,
            carto_sytle_path=env("CARTO_STYLE_PATH")),
        zoom=int(zoom),
        x_pixel=float(x_pixel),
        y_pixel=float(y_pixel),
        osm_cato_path=env("CARTO_STYLE_PATH"),
    )

    return HttpResponse(tile_gen.render_tile(), content_type="image/jpeg")
Esempio n. 5
0
def test_get_bbox_random_zoom_10_20(tile_generator: TileGenerator):
    """
    test get_bbox for random 1000 tiles each zoom level

    Arguments:
        tile_generator {TileGenerator} -- default TileGenerator
    """
    for zoom in range(10, 20):
        tile_generator.zoom = zoom
        coordinate_limit: int = int(pow(2, zoom))
        for _ in range(100):
            x: int = randrange(coordinate_limit)
            for _ in range(100):
                y: int = randrange(coordinate_limit)
                tile_generator.x_pixel = x
                tile_generator.y_pixel = y
                assert isinstance(tile_generator.get_bbox(), Box2d)
Esempio n. 6
0
def test_without_date():
    tile_generator: TileGenerator = TileGenerator(zoom=0,
                                                  x_pixel=0,
                                                  y_pixel=0,
                                                  use_cache=False)

    with pytest.raises(RenderErrorNoDate):
        tile_generator.render_tile()
Esempio n. 7
0
    def test_success_empty_cache(
        self, test_tile: Dict[str, dict], tile_generator: TileGenerator
    ):
        # clear cache
        cache.clear()

        request: WSGIRequest = RequestFactory().get(
            self.get_path(kwargs=test_tile["data"])
        )
        response: HttpResponse = generate_tile(
            request=request,
            year=test_tile["data"]["year"],
            month=test_tile["data"]["month"],
            day=test_tile["data"]["day"],
            zoom=test_tile["data"]["zoom"],
            x_pixel=test_tile["data"]["x_pixel"],
            y_pixel=test_tile["data"]["y_pixel"],
        )

        tile_cache: Optional[dict] = cache.get(test_tile["cache"]["cache_key"])
        if tile_cache is None:
            raise AssertionError
        tile: Optional[bytes] = cache.get(tile_cache["tile_hash"])

        tile_generator.zoom = test_tile["data"]["zoom"]
        tile_generator.x_pixel = test_tile["data"]["x_pixel"]
        tile_generator.y_pixel = test_tile["data"]["y_pixel"]

        # check if the right tile was rendert
        if response.content != tile_generator.render_tile():
            raise AssertionError

        # check if the cache was setup right
        if hashlib.md5(response.content).hexdigest() != tile_cache["tile_hash"]:
            raise AssertionError
        if response.content != tile:
            raise AssertionError

        if not isinstance(response.content, bytes):
            raise AssertionError
        if response.status_code != 200:
            raise AssertionError
        if response["content-type"] != "image/jpeg":
            raise AssertionError
Esempio n. 8
0
def async_generate_tile(
    year: int,
    month: int,
    day: int,
    style_xml_template: str,
    zoom: int,
    x_pixel: float,
    y_pixel: float,
    osm_cato_path: str,
    cache_key: str,
) -> str:
    """
    run celery background task to generate a mapnik tile & cache the tile
    :param year: request year as INT
    :param month: request month as INT
    :param day: request day as INT
    :param style_xml_template: path to style.xml
    :param zoom: mapnik zoom level
    :param x_pixel: mapnik x coordinate
    :param y_pixel: mapnik y coordinate
    :param osm_cato_path: path to osm cato
    :param cache_key: cache key for mapnik tile
    :return:
    """

    # render requested tile
    tile: bytes = TileGenerator(
        request_date=date(year=int(year), month=int(month), day=int(day)),
        style_xml_template=style_xml_template,
        zoom=int(zoom),
        x_pixel=float(x_pixel),
        y_pixel=float(y_pixel),
        osm_cato_path=osm_cato_path,
        use_cache=True,
    ).render_tile()

    # create a md5 hash of the tile
    tile_hash: str = hashlib.md5(tile).hexdigest()

    # set url-tile cache content
    tile_cache: dict = {"process_id": None, "tile_hash": tile_hash}

    # update tile cache & url-tile cache content
    if zoom <= env.int("ZOOM_LEVEL", 13):
        # cache for ever
        cache.set(tile_hash, tile, None)
        cache.set(cache_key, tile_cache, None)
    else:
        # cache for time in TILE_CACHE_TIME
        cache.set(tile_hash, tile, env.int("TILE_CACHE_TIME", 2592000) * 10)
        cache.set(cache_key, tile_cache, env.int("TILE_CACHE_TIME", 2592000))

    return tile_hash
Esempio n. 9
0
    def set_valid_date(self):
        tile_generator: TileGenerator = TileGenerator(zoom=self.zoom,
                                                      x_pixel=self.x_pixel,
                                                      y_pixel=self.y_pixel)
        geom = Polygon.from_bbox(tile_generator.get_bbox())

        valid_since: Optional[date] = self.valid_since
        valid_until: Optional[date] = self.valid_until
        self.valid_since = None
        self.valid_until = None

        planet_osm_lines: List[PlanetOsmLine] = []
        for planet_osm_line in PlanetOsmLine.objects.filter(
                way__bbcontains=geom,
                valid_since__lte=valid_since,
                valid_until__gte=valid_until,
        ):
            planet_osm_lines.append(planet_osm_line)
        self.set_valid_date_iterate_objects(planet_osm_lines)

        planet_osm_points: List[PlanetOsmPoint] = []
        for planet_osm_point in PlanetOsmPoint.objects.filter(
                way__bbcontains=geom,
                valid_since__lte=valid_since,
                valid_until__gte=valid_until,
        ):
            planet_osm_points.append(planet_osm_point)
        self.set_valid_date_iterate_objects(planet_osm_points)

        planet_osm_polygons: List[PlanetOsmPolygon] = []
        for planet_osm_polygon in PlanetOsmPolygon.objects.filter(
                way__bbcontains=geom,
                valid_since__lte=valid_since,
                valid_until__gte=valid_until,
        ):
            planet_osm_polygons.append(planet_osm_polygon)
        self.set_valid_date_iterate_objects(planet_osm_polygons)

        planet_osm_roadss: List[PlanetOsmRoads] = []
        for planet_osm_roads in PlanetOsmRoads.objects.filter(
                way__bbcontains=geom,
                valid_since__lte=valid_since,
                valid_until__gte=valid_until,
        ):
            planet_osm_roadss.append(planet_osm_roads)
        self.set_valid_date_iterate_objects(planet_osm_roadss)

        if self.valid_since is None:
            self.valid_since = valid_since
        if self.valid_until is None:
            self.valid_until = valid_until

        self.save()
Esempio n. 10
0
def test_from_py_to_lat(tile_test_cases: Dict[str, dict]):
    """
    test if method from_py_to_lat convert px & zoom to lat

    Arguments:
        tile_test_cases {Dict[str, dict]} -- tile test cases
    """
    for test_case in tile_test_cases:
        print("lat test for {}".format(test_case))
        lat: float = TileGenerator.from_py_to_lat(
            py=tile_test_cases[test_case]["y"],
            zoom=tile_test_cases[test_case]["zoom"],
        )
        assert "{:0.10f}".format(lat) == tile_test_cases[test_case]["lat"]
        assert isinstance(lat, float)
Esempio n. 11
0
def test_from_px_to_lon(tile_test_cases: Dict[str, dict]):
    """
    test if method from_px_to_lon convert px & zoom to lon

    Arguments:
        tile_test_cases {Dict[str, dict]} -- tile test cases
    """
    for test_case in tile_test_cases:
        print("lon test for {}".format(test_case))
        lon: float = TileGenerator.from_px_to_lon(
            px=tile_test_cases[test_case]["x"],
            zoom=tile_test_cases[test_case]["zoom"],
        )
        assert "{:0.10f}".format(lon) == tile_test_cases[test_case]["lon"]
        assert isinstance(lon, float)
Esempio n. 12
0
def test_tile_generator_init():
    """test TileGenerator constructor"""
    # test valid zoom level
    for zoom in range(20):
        if not isinstance(TileGenerator(zoom=zoom, x_pixel=0, y_pixel=0),
                          TileGenerator):
            raise AssertionError

    # test zoom level with invalid zoom level
    with pytest.raises(ZoomOutOfRange):
        TileGenerator(zoom=-1, x_pixel=0, y_pixel=0)
    with pytest.raises(ZoomOutOfRange):
        TileGenerator(zoom=20, x_pixel=0, y_pixel=0)

    # test x & y coordinate limit
    for zoom in range(20):
        max_coordinate: int = int(pow(2, zoom))
        # x to low
        with pytest.raises(CoordinateOutOfRange):
            TileGenerator(zoom=zoom, x_pixel=-1, y_pixel=0)
        # y to low
        with pytest.raises(CoordinateOutOfRange):
            TileGenerator(zoom=zoom, x_pixel=0, y_pixel=-1)
        # x to high
        with pytest.raises(CoordinateOutOfRange):
            TileGenerator(zoom=zoom, x_pixel=max_coordinate + 1, y_pixel=0)
        # y to high
        with pytest.raises(CoordinateOutOfRange):
            TileGenerator(zoom=zoom, x_pixel=0, y_pixel=max_coordinate + 1)

        # valid y & x
        if not isinstance(
                TileGenerator(zoom=zoom, x_pixel=max_coordinate, y_pixel=0),
                TileGenerator):
            raise AssertionError
        if not isinstance(
                TileGenerator(zoom=zoom, x_pixel=0, y_pixel=max_coordinate),
                TileGenerator):
            raise AssertionError
Esempio n. 13
0
def test_get_bbox_zoom_0_10(tile_generator: TileGenerator):
    """
    test get_bbox for all tiles between zoomlevel 0 to 10

    Arguments:
        tile_generator {TileGenerator} -- default TileGenerator
    """
    # test all tiles for zoom level 0 to 10
    tile_generator.get_bbox()
    for zoom in range(10):
        tile_generator.zoom = zoom
        for x in range(int(pow(2, zoom))):
            for y in range(int(pow(2, zoom))):
                tile_generator.x_pixel = x
                tile_generator.y_pixel = y
                assert isinstance(tile_generator.get_bbox(), Box2d)
Esempio n. 14
0
def async_generate_tile(
    year: int,
    month: int,
    day: int,
    style_xml_template: str,
    zoom: int,
    x_pixel: float,
    y_pixel: float,
    osm_cato_path: str,
    cache_key: str,
) -> str:
    """
    run celery background task to generate a mapnik tile & cache the tile
    :param year: request year as INT
    :param month: request month as INT
    :param day: request day as INT
    :param style_xml_template: path to style.xml
    :param zoom: mapnik zoom level
    :param x_pixel: mapnik x coordinate
    :param y_pixel: mapnik y coordinate
    :param osm_cato_path: path to osm cato
    :param cache_key: cache key for mapnik tile
    :return:
    """

    cache.set(
        cache_key,
        TileGenerator(
            request_date=date(year=int(year), month=int(month), day=int(day)),
            style_xml_template=style_xml_template,
            zoom=int(zoom),
            x_pixel=float(x_pixel),
            y_pixel=float(y_pixel),
            osm_cato_path=osm_cato_path,
            use_cache=True,
        ).render_tile(),
    )

    return cache_key
Esempio n. 15
0
def generate_osm_tile(request, zoom: int, x_pixel: float,
                      y_pixel: float) -> HttpResponse:
    """
    get a default mapnik tile, without check the valid date
    :param request:
    :param zoom:
    :param x_pixel:
    :param y_pixel:
    :return:
    """
    # generate normal osm tile
    tile_gen: TileGenerator = TileGenerator(
        request_date=date(year=2000, month=1, day=1),
        style_xml_template=get_style_xml(
            generate_style_xml=False,
            carto_sytle_path=env("CARTO_STYLE_PATH_DEBUG")),
        zoom=int(zoom),
        x_pixel=float(x_pixel),
        y_pixel=float(y_pixel),
        osm_cato_path=env("CARTO_STYLE_PATH_DEBUG"),
    )

    return HttpResponse(tile_gen.render_tile(), content_type="image/jpeg")
Esempio n. 16
0
def tile_generator() -> TileGenerator:
    return TileGenerator(zoom=0,
                         x_pixel=0,
                         y_pixel=0,
                         request_date=datetime(2020, 1, 1),
                         use_cache=False)