kopia lustrzana https://github.com/OpenDroneMap/WebODM
commit
591b8b065e
|
@ -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?
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
|
|
Ładowanie…
Reference in New Issue