Merge pull request #769 from pierotofy/cogeo

Fix histogram deformations
pull/778/head
Piero Toffanin 2019-12-10 18:29:26 -05:00 zatwierdzone przez GitHub
commit 591b8b065e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 44 dodań i 27 usunięć

Wyświetl plik

@ -58,11 +58,13 @@ algos = {
},
'LAI': {
'expr': '3.618 * (2.5 * (N - R) / (N + 6*R - 7.5*B + 1)) * 0.118',
'help': 'Leaf Area Index estimates foliage areas and predicts crop yields.'
'help': 'Leaf Area Index estimates foliage areas and predicts crop yields.',
'range': (-1, 1)
},
'EVI': {
'expr': '2.5 * (N - R) / (N + 6*R - 7.5*B + 1)',
'help': 'Enhanced Vegetation Index is useful in areas where NDVI might saturate, by using blue wavelengths to correct soil signals.'
'help': 'Enhanced Vegetation Index is useful in areas where NDVI might saturate, by using blue wavelengths to correct soil signals.',
'range': (-1, 1)
},
# more?

Wyświetl plik

@ -170,7 +170,7 @@ class Metadata(TaskNestedView):
info['statistics'][b]['max'] = hrange[1]
cmap_labels = {
"jet_r": "Jet",
"jet": "Jet",
"terrain": "Terrain",
"gist_earth": "Earth",
"rdylgn": "RdYlGn",
@ -183,7 +183,7 @@ class Metadata(TaskNestedView):
colormaps = []
algorithms = []
if tile_type in ['dsm', 'dtm']:
colormaps = ['jet_r', 'terrain', 'gist_earth', 'pastel1']
colormaps = ['jet', 'terrain', 'gist_earth', 'pastel1']
elif formula and bands:
colormaps = ['rdylgn', 'spectral', 'rdylgn_r', 'spectral_r']
algorithms = *get_algorithm_list(),
@ -214,29 +214,39 @@ class Metadata(TaskNestedView):
return Response(info)
def get_elevation_tiles(elevation, url, x, y, z, tilesize, nodata, resampling_method):
def get_elevation_tiles(url, x, y, z, indexes, tilesize, nodata):
resampling = "bilinear"
padding = 16
elevation, _ = main.tile(url, x, y, z, indexes=indexes, tilesize=tilesize, nodata=nodata,
resampling_method=resampling, tile_edge_padding=padding)
tile = np.full((tilesize * 3, tilesize * 3), nodata, dtype=elevation.dtype)
try:
left, _ = main.tile(url, x - 1, y, z, indexes=1, tilesize=tilesize, nodata=nodata, resampling_method=resampling_method)
left, _ = main.tile(url, x - 1, y, z, indexes=1, tilesize=tilesize, nodata=nodata,
resampling_method=resampling, tile_edge_padding=padding)
tile[tilesize:tilesize*2,0:tilesize] = left
except TileOutsideBounds:
pass
try:
right, _ = main.tile(url, x + 1, y, z, indexes=1, tilesize=tilesize, nodata=nodata, resampling_method=resampling_method)
right, _ = main.tile(url, x + 1, y, z, indexes=1, tilesize=tilesize, nodata=nodata,
resampling_method=resampling, tile_edge_padding=padding)
tile[tilesize:tilesize*2,tilesize*2:tilesize*3] = right
except TileOutsideBounds:
pass
try:
bottom, _ = main.tile(url, x, y + 1, z, indexes=1, tilesize=tilesize, nodata=nodata, resampling_method=resampling_method)
bottom, _ = main.tile(url, x, y + 1, z, indexes=1, tilesize=tilesize, nodata=nodata,
resampling_method=resampling, tile_edge_padding=padding)
tile[tilesize*2:tilesize*3,tilesize:tilesize*2] = bottom
except TileOutsideBounds:
pass
try:
top, _ = main.tile(url, x, y - 1, z, indexes=1, tilesize=tilesize, nodata=nodata, resampling_method=resampling_method)
top, _ = main.tile(url, x, y - 1, z, indexes=1, tilesize=tilesize, nodata=nodata,
resampling_method=resampling, tile_edge_padding=padding)
tile[0:tilesize,tilesize:tilesize*2] = top
except TileOutsideBounds:
pass
@ -281,10 +291,6 @@ class Tiles(TaskNestedView):
except ValueError as e:
raise exceptions.ValidationError(str(e))
resampling = "nearest"
if tile_type in ['dsm', 'dtm']:
resampling = "bilinear"
if tile_type in ['dsm', 'dtm'] and rescale is None:
rescale = "0,1000"
@ -314,11 +320,11 @@ class Tiles(TaskNestedView):
try:
if expr is not None:
tile, mask = expression(
url, x, y, z, expr=expr, tilesize=tilesize, nodata=nodata, resampling_method=resampling
url, x, y, z, expr=expr, tilesize=tilesize, nodata=nodata, tile_edge_padding=0, resampling_method="nearest"
)
else:
tile, mask = main.tile(
url, x, y, z, indexes=indexes, tilesize=tilesize, nodata=nodata, resampling_method=resampling
url, x, y, z, indexes=indexes, tilesize=tilesize, nodata=nodata, tile_edge_padding=0, resampling_method="nearest"
)
except TileOutsideBounds:
raise exceptions.NotFound("Outside of bounds")
@ -346,8 +352,7 @@ class Tiles(TaskNestedView):
if tile.shape[0] != 1:
raise exceptions.ValidationError("Cannot compute hillshade of non-elevation raster (multiple bands found)")
z_value = min(maxzoom, max(z, minzoom))
delta_scale = (maxzoom + 1 - z_value) * 4
delta_scale = (maxzoom + ZOOM_EXTRA_LEVELS + 1 - z) * 4
dx = src.meta["transform"][0] * delta_scale
dy = -src.meta["transform"][4] * delta_scale
@ -355,7 +360,7 @@ class Tiles(TaskNestedView):
# Hillshading is not a local tile operation and
# requires neighbor tiles to be rendered seamlessly
elevation = get_elevation_tiles(tile[0], url, x, y, z, tilesize, nodata, resampling)
elevation = get_elevation_tiles(url, x, y, z, indexes, tilesize, nodata)
intensity = ls.hillshade(elevation, dx=dx, dy=dy, vert_exag=hillshade)
intensity = intensity[tilesize:tilesize*2,tilesize:tilesize*2]

Wyświetl plik

@ -115,6 +115,11 @@ export default class Histogram extends React.Component {
return [band.histogram[1][i], e];
});
// Make sure histogram starts and ends at 0
// to prevent oblique looking charts
data.unshift([data[0][0], 0]);
data.push([data[data.length - 1][0], 0]);
// Plot the area
svg.append('g')
.append("path")

Wyświetl plik

@ -7,6 +7,7 @@ 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';
@ -96,7 +97,7 @@ class Map extends React.Component {
let metaUrl = url + "metadata";
if (type == "plant") metaUrl += "?formula=NDVI&bands=RGN&color_map=rdylgn";
if (type == "dsm" || type == "dtm") metaUrl += "?hillshade=3&color_map=jet_r";
if (type == "dsm" || type == "dtm") metaUrl += "?hillshade=3&color_map=jet";
this.tileJsonRequests.push($.getJSON(metaUrl)
.done(mres => {
@ -233,7 +234,10 @@ class Map extends React.Component {
Basemaps.forEach((src, idx) => {
const { url, ...props } = src;
const layer = L.tileLayer(url, props);
const tileProps = Utils.clone(props);
tileProps.maxNativeZoom = tileProps.maxZoom;
tileProps.maxZoom = tileProps.maxZoom + 99;
const layer = L.tileLayer(url, tileProps);
if (idx === 0) {
layer.addTo(this.map);
@ -255,7 +259,8 @@ https://a.tile.openstreetmap.org/{z}/{x}/{y}.png
if (url){
customLayer.clearLayers();
const l = L.tileLayer(url, {
maxZoom: 24,
maxNativeZoom: 24,
maxZoom: 99,
minZoom: 0
});
customLayer.addLayer(l);

Wyświetl plik

@ -438,7 +438,7 @@ class TestApiTask(BootTransactionTestCase):
# Colormap is for algorithms
self.assertEqual(len([x for x in metadata['color_maps'] if x['key'] == 'rdylgn']), 1)
self.assertEqual(len([x for x in metadata['color_maps'] if x['key'] == 'jet_r']), 0)
self.assertEqual(len([x for x in metadata['color_maps'] if x['key'] == 'jet']), 0)
# Formula parameters are copied to tile URL
self.assertTrue(metadata['tiles'][0].endswith('?formula=NDVI&bands=RGN'))
@ -473,7 +473,7 @@ class TestApiTask(BootTransactionTestCase):
# Colormaps are for elevation
self.assertEqual(len([x for x in metadata['color_maps'] if x['key'] == 'rdylgn']), 0)
self.assertEqual(len([x for x in metadata['color_maps'] if x['key'] == 'jet_r']), 1)
self.assertEqual(len([x for x in metadata['color_maps'] if x['key'] == 'jet']), 1)
# Algorithms are empty
self.assertEqual(len(metadata['algorithms']), 0)
@ -513,11 +513,11 @@ class TestApiTask(BootTransactionTestCase):
# Can access hillshade, formulas, bands, rescale, color_map
params = [
("dsm", "color_map=jet_r&hillshade=3&rescale=150,170", status.HTTP_200_OK),
("dsm", "color_map=jet_r&hillshade=0&rescale=150,170", status.HTTP_200_OK),
("dsm", "color_map=jet&hillshade=3&rescale=150,170", status.HTTP_200_OK),
("dsm", "color_map=jet&hillshade=0&rescale=150,170", status.HTTP_200_OK),
("dsm", "color_map=invalid&rescale=150,170", status.HTTP_400_BAD_REQUEST),
("dsm", "color_map=jet_r&rescale=invalid", status.HTTP_400_BAD_REQUEST),
("dsm", "color_map=jet_r&rescale=150,170&hillshade=invalid", status.HTTP_400_BAD_REQUEST),
("dsm", "color_map=jet&rescale=invalid", status.HTTP_400_BAD_REQUEST),
("dsm", "color_map=jet&rescale=150,170&hillshade=invalid", status.HTTP_400_BAD_REQUEST),
("dtm", "hillshade=3", status.HTTP_200_OK),
("dtm", "hillshade=99999999999999999999999999999999999", status.HTTP_200_OK),