Merge pull request #763 from pierotofy/cogeo

BUG: #762 memory overallocation for tiles outside zoom level
pull/778/head
Piero Toffanin 2019-12-09 10:16:05 -05:00 zatwierdzone przez GitHub
commit acb3905d87
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 45 dodań i 19 usunięć

Wyświetl plik

@ -17,6 +17,11 @@ from .tasks import TaskNestedView
from rest_framework import exceptions
from rest_framework.response import Response
def get_zoom_safe(src_dst):
minzoom, maxzoom = get_zooms(src_dst)
if maxzoom < minzoom:
maxzoom = minzoom
return minzoom, maxzoom
def get_tile_url(task, tile_type, query_params):
url = '/api/projects/{}/tasks/{}/{}/tiles/{{z}}/{{x}}/{{y}}.png'.format(task.project.id, task.id, tile_type)
@ -100,7 +105,7 @@ class TileJson(TaskNestedView):
raise exceptions.NotFound()
with rasterio.open(raster_path) as src_dst:
minzoom, maxzoom = get_zooms(src_dst)
minzoom, maxzoom = get_zoom_safe(src_dst)
return Response({
'tilejson': '2.1.0',
@ -199,6 +204,9 @@ class Metadata(TaskNestedView):
info['scheme'] = 'xyz'
info['tiles'] = [get_tile_url(task, tile_type, self.request.query_params)]
if info['maxzoom'] < info['minzoom']:
info['maxzoom'] = info['minzoom']
return Response(info)
def get_elevation_tiles(elevation, url, x, y, z, tilesize, nodata):
@ -244,9 +252,6 @@ class Tiles(TaskNestedView):
x = int(x)
y = int(y)
if x == 0 and y == 0 and z == 0:
raise exceptions.NotFound()
scale = int(scale)
ext = "png"
driver = "jpeg" if ext == "jpg" else ext
@ -288,9 +293,15 @@ class Tiles(TaskNestedView):
tilesize = scale * 256
url = get_raster_path(task, tile_type)
if not os.path.isfile(url):
raise exceptions.NotFound()
with rasterio.open(url) as src:
minzoom, maxzoom = get_zoom_safe(src)
if z < minzoom or z > maxzoom:
raise exceptions.NotFound()
try:
if expr is not None:
tile, mask = expression(
@ -320,19 +331,16 @@ class Tiles(TaskNestedView):
hillshade = float(hillshade)
if hillshade <= 0:
hillshade = 1.0
print(hillshade)
except ValueError:
raise exceptions.ValidationError("Invalid hillshade value")
if tile.shape[0] != 1:
raise exceptions.ValidationError("Cannot compute hillshade of non-elevation raster (multiple bands found)")
with rasterio.open(url) as src:
minzoom, maxzoom = get_zooms(src)
z_value = min(maxzoom, max(z, minzoom))
delta_scale = (maxzoom + 1 - z_value) * 4
dx = src.meta["transform"][0] * delta_scale
dy = -src.meta["transform"][4] * delta_scale
z_value = min(maxzoom, max(z, minzoom))
delta_scale = (maxzoom + 1 - z_value) * 4
dx = src.meta["transform"][0] * delta_scale
dy = -src.meta["transform"][4] * delta_scale
ls = LightSource(azdeg=315, altdeg=45)

Wyświetl plik

@ -7,7 +7,6 @@ import '../vendor/leaflet/L.Control.MousePosition.css';
import '../vendor/leaflet/L.Control.MousePosition';
import '../vendor/leaflet/Leaflet.Autolayers/css/leaflet.auto-layers.css';
import '../vendor/leaflet/Leaflet.Autolayers/leaflet-autolayers';
import '../vendor/leaflet/L.TileLayer.NoGap';
import Dropzone from '../vendor/dropzone';
import $ from 'jquery';
import ErrorMessage from './ErrorMessage';

Wyświetl plik

@ -220,8 +220,12 @@ L.TileLayer.include({
var offset = L.point(coords.x, coords.y)
.subtract(level.canvasRange.min)
.scaleBy(this.getTileSize());
level.ctx.drawImage(imageSource, offset.x, offset.y, tileSize.x, tileSize.y);
try{
level.ctx.drawImage(imageSource, offset.x, offset.y, tileSize.x, tileSize.y);
}catch(e){
console.error(e);
}
// TODO: Clear the pixels of other levels' canvases where they overlap
// this newly dumped tile.

Wyświetl plik

@ -388,6 +388,9 @@ class TestApiTask(BootTransactionTestCase):
for f in fields:
self.assertTrue(f in metadata)
self.assertEqual(metadata['minzoom'], 17)
self.assertEqual(metadata['maxzoom'], 17)
# Colormaps and algorithms should be empty lists
self.assertEqual(metadata['algorithms'], [])
self.assertEqual(metadata['color_maps'], [])
@ -452,6 +455,12 @@ class TestApiTask(BootTransactionTestCase):
self.assertEqual(metadata['statistics']['1']['min'], algos['VARI']['range'][0])
self.assertEqual(metadata['statistics']['1']['max'], algos['VARI']['range'][1])
tile_path = {
'orthophoto': '17/32042/46185',
'dsm': '18/64083/92370',
'dtm': '18/64083/92370'
}
# Metadata for DSM/DTM
for tile_type in ['dsm', 'dtm']:
res = client.get("/api/projects/{}/tasks/{}/{}/metadata".format(project.id, task.id, tile_type))
@ -475,7 +484,7 @@ class TestApiTask(BootTransactionTestCase):
# Can access individual tiles
for tile_type in tile_types:
res = client.get("/api/projects/{}/tasks/{}/{}/tiles/17/32042/46185.png".format(project.id, task.id, tile_type))
res = client.get("/api/projects/{}/tasks/{}/{}/tiles/{}.png".format(project.id, task.id, tile_type, tile_path[tile_type]))
self.assertEqual(res.status_code, status.HTTP_200_OK)
with Image.open(io.BytesIO(res.content)) as i:
@ -484,7 +493,7 @@ class TestApiTask(BootTransactionTestCase):
# Can access retina tiles
for tile_type in tile_types:
res = client.get("/api/projects/{}/tasks/{}/{}/tiles/17/32042/46185@2x.png".format(project.id, task.id, tile_type))
res = client.get("/api/projects/{}/tasks/{}/{}/tiles/{}@2x.png".format(project.id, task.id, tile_type, tile_path[tile_type]))
self.assertEqual(res.status_code, status.HTTP_200_OK)
with Image.open(io.BytesIO(res.content)) as i:
@ -495,6 +504,12 @@ class TestApiTask(BootTransactionTestCase):
res = client.get("/api/projects/{}/tasks/{}/orthophoto/tiles/0/0/0.png".format(project.id, task.id))
self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND)
# Cannot access zoom levels outside of the allowed zoom levels
res = client.get("/api/projects/{}/tasks/{}/orthophoto/tiles/16/32042/46185.png".format(project.id, task.id))
self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND)
res = client.get("/api/projects/{}/tasks/{}/orthophoto/tiles/18/32042/46185.png".format(project.id, task.id))
self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND)
# Can access hillshade, formulas, bands, rescale, color_map
params = [
("dsm", "color_map=jet_r&hillshade=3&rescale=150,170", status.HTTP_200_OK),
@ -531,7 +546,7 @@ class TestApiTask(BootTransactionTestCase):
params.append(("orthophoto", "formula={}&bands={}&color_map=rdylgn".format(k, f), status.HTTP_200_OK))
for tile_type, url, sc in params:
res = client.get("/api/projects/{}/tasks/{}/{}/tiles/17/32042/46185.png?{}".format(project.id, task.id, tile_type, url))
res = client.get("/api/projects/{}/tasks/{}/{}/tiles/{}.png?{}".format(project.id, task.id, tile_type, tile_path[tile_type], url))
self.assertEqual(res.status_code, sc)
# Another user does not have access to the resources
@ -543,7 +558,7 @@ class TestApiTask(BootTransactionTestCase):
res = other_client.get("/api/projects/{}/tasks/{}/{}/tiles.json".format(project.id, task.id, tile_type))
self.assertEqual(res.status_code, expectedStatus)
res = other_client.get("/api/projects/{}/tasks/{}/{}/tiles/17/32042/46185.png".format(project.id, task.id, tile_type))
res = other_client.get("/api/projects/{}/tasks/{}/{}/tiles/{}.png".format(project.id, task.id, tile_type, tile_path[tile_type]))
self.assertEqual(res.status_code, expectedStatus)
res = other_client.get("/api/projects/{}/tasks/{}/".format(project.id, task.id))

Wyświetl plik

@ -1,6 +1,6 @@
{
"name": "WebODM",
"version": "1.2.0",
"version": "1.2.1",
"description": "Open Source Drone Image Processing",
"main": "index.js",
"scripts": {