kopia lustrzana https://github.com/OpenDroneMap/WebODM
Add crop parameter
rodzic
521fd8ae53
commit
8a65a97973
|
@ -141,6 +141,7 @@ class Metadata(TaskNestedView):
|
|||
formula = self.request.query_params.get('formula')
|
||||
bands = self.request.query_params.get('bands')
|
||||
defined_range = self.request.query_params.get('range')
|
||||
crop = self.request.query_params.get('crop') == '1'
|
||||
boundaries_feature = self.request.query_params.get('boundaries')
|
||||
if formula == '': formula = None
|
||||
if bands == '': bands = None
|
||||
|
@ -173,14 +174,20 @@ class Metadata(TaskNestedView):
|
|||
try:
|
||||
with COGReader(raster_path) as src:
|
||||
band_count = src.dataset.meta['count']
|
||||
if task.crop is not None:
|
||||
boundaries_cutline, boundaries_bbox = geom_transform_wkt_bbox(task.crop, src.dataset)
|
||||
if crop and task.crop is not None:
|
||||
cutline, bounds = geom_transform_wkt_bbox(task.crop, src.dataset)
|
||||
elif boundaries_feature is not None:
|
||||
boundaries_cutline = create_cutline(src.dataset, boundaries_feature, CRS.from_string('EPSG:4326'))
|
||||
boundaries_bbox = featureBounds(boundaries_feature)
|
||||
cutline = create_cutline(src.dataset, boundaries_feature, CRS.from_string('EPSG:4326'))
|
||||
bounds = featureBounds(boundaries_feature)
|
||||
else:
|
||||
boundaries_cutline = None
|
||||
boundaries_bbox = None
|
||||
cutline = None
|
||||
bounds = None
|
||||
|
||||
if cutline is not None:
|
||||
vrt_options = {'cutline': cutline}
|
||||
else:
|
||||
vrt_options = None
|
||||
|
||||
if has_alpha_band(src.dataset):
|
||||
band_count -= 1
|
||||
nodata = None
|
||||
|
@ -189,10 +196,7 @@ class Metadata(TaskNestedView):
|
|||
nodata = 0
|
||||
histogram_options = {"bins": 255, "range": hrange}
|
||||
if expr is not None:
|
||||
if boundaries_cutline is not None:
|
||||
data, mask = src.preview(expression=expr, vrt_options={'cutline': boundaries_cutline})
|
||||
else:
|
||||
data, mask = src.preview(expression=expr)
|
||||
data, mask = src.preview(expression=expr, vrt_options=vrt_options)
|
||||
data = np.ma.array(data)
|
||||
data.mask = mask == 0
|
||||
stats = {
|
||||
|
@ -202,11 +206,8 @@ class Metadata(TaskNestedView):
|
|||
stats = {b: ImageStatistics(**s) for b, s in stats.items()}
|
||||
metadata = RioMetadata(statistics=stats, **src.info().dict())
|
||||
else:
|
||||
if (boundaries_cutline is not None) and (boundaries_bbox is not None):
|
||||
metadata = src.metadata(pmin=pmin, pmax=pmax, hist_options=histogram_options, nodata=nodata
|
||||
, bounds=boundaries_bbox, vrt_options={'cutline': boundaries_cutline})
|
||||
else:
|
||||
metadata = src.metadata(pmin=pmin, pmax=pmax, hist_options=histogram_options, nodata=nodata)
|
||||
metadata = src.metadata(pmin=pmin, pmax=pmax, hist_options=histogram_options, nodata=nodata,
|
||||
bounds=bounds, vrt_options=vrt_options)
|
||||
info = json.loads(metadata.json())
|
||||
except IndexError as e:
|
||||
# Caught when trying to get an invalid raster metadata
|
||||
|
@ -277,7 +278,7 @@ class Metadata(TaskNestedView):
|
|||
info['maxzoom'] = info['minzoom']
|
||||
info['maxzoom'] += ZOOM_EXTRA_LEVELS
|
||||
info['minzoom'] -= ZOOM_EXTRA_LEVELS
|
||||
info['bounds'] = {'value': src.bounds, 'crs': src.dataset.crs}
|
||||
info['bounds'] = {'value': bounds if bounds is not None else src.bounds, 'crs': src.dataset.crs}
|
||||
|
||||
return Response(info)
|
||||
|
||||
|
@ -305,6 +306,7 @@ class Tiles(TaskNestedView):
|
|||
color_map = self.request.query_params.get('color_map')
|
||||
hillshade = self.request.query_params.get('hillshade')
|
||||
tilesize = self.request.query_params.get('size')
|
||||
crop = self.request.query_params.get('crop') == '1'
|
||||
|
||||
boundaries_feature = self.request.query_params.get('boundaries')
|
||||
if boundaries_feature == '':
|
||||
|
@ -369,15 +371,21 @@ class Tiles(TaskNestedView):
|
|||
if z < minzoom - ZOOM_EXTRA_LEVELS or z > maxzoom + ZOOM_EXTRA_LEVELS:
|
||||
raise exceptions.NotFound()
|
||||
|
||||
if task.crop is not None:
|
||||
boundaries_cutline, boundaries_bbox = geom_transform_wkt_bbox(task.crop, src.dataset)
|
||||
if crop and task.crop is not None:
|
||||
cutline, bounds = geom_transform_wkt_bbox(task.crop, src.dataset)
|
||||
elif boundaries_feature is not None:
|
||||
try:
|
||||
boundaries_cutline = create_cutline(src.dataset, boundaries_feature, CRS.from_string('EPSG:4326'))
|
||||
cutline = create_cutline(src.dataset, boundaries_feature, CRS.from_string('EPSG:4326'))
|
||||
except:
|
||||
raise exceptions.ValidationError(_("Invalid boundaries"))
|
||||
else:
|
||||
boundaries_cutline = None
|
||||
cutline = None
|
||||
|
||||
if cutline is not None:
|
||||
vrt_options = {'cutline': cutline}
|
||||
else:
|
||||
vrt_options = None
|
||||
|
||||
# Handle N-bands datasets for orthophotos (not plant health)
|
||||
if tile_type == 'orthophoto' and expr is None:
|
||||
ci = src.dataset.colorinterp
|
||||
|
@ -415,27 +423,15 @@ class Tiles(TaskNestedView):
|
|||
|
||||
try:
|
||||
if expr is not None:
|
||||
if boundaries_cutline is not None:
|
||||
tile = src.tile(x, y, z, expression=expr, tilesize=tilesize, nodata=nodata,
|
||||
padding=padding,
|
||||
tile_buffer=tile_buffer,
|
||||
resampling_method=resampling, vrt_options={'cutline': boundaries_cutline})
|
||||
else:
|
||||
tile = src.tile(x, y, z, expression=expr, tilesize=tilesize, nodata=nodata,
|
||||
padding=padding,
|
||||
tile_buffer=tile_buffer,
|
||||
resampling_method=resampling)
|
||||
tile = src.tile(x, y, z, expression=expr, tilesize=tilesize, nodata=nodata,
|
||||
padding=padding,
|
||||
tile_buffer=tile_buffer,
|
||||
resampling_method=resampling, vrt_options=vrt_options)
|
||||
else:
|
||||
if boundaries_cutline is not None:
|
||||
tile = src.tile(x, y, z, tilesize=tilesize, nodata=nodata,
|
||||
padding=padding,
|
||||
tile_buffer=tile_buffer,
|
||||
resampling_method=resampling, vrt_options={'cutline': boundaries_cutline})
|
||||
else:
|
||||
tile = src.tile(x, y, z, indexes=indexes, tilesize=tilesize, nodata=nodata,
|
||||
padding=padding,
|
||||
tile_buffer=tile_buffer,
|
||||
resampling_method=resampling)
|
||||
tile = src.tile(x, y, z, tilesize=tilesize, nodata=nodata,
|
||||
padding=padding,
|
||||
tile_buffer=tile_buffer,
|
||||
resampling_method=resampling, vrt_options=vrt_options)
|
||||
except TileOutsideBounds:
|
||||
raise exceptions.NotFound(_("Outside of bounds"))
|
||||
|
||||
|
|
|
@ -1047,6 +1047,7 @@ class Task(models.Model):
|
|||
'ground_control_points': ground_control_points,
|
||||
'epsg': self.epsg,
|
||||
'orthophoto_bands': self.orthophoto_bands,
|
||||
'crop': self.crop is not None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class CropButton extends React.Component {
|
|||
group: PropTypes.object,
|
||||
title: PropTypes.string,
|
||||
color: PropTypes.string,
|
||||
pulse: PropTypes.boolean,
|
||||
pulse: PropTypes.bool,
|
||||
onPolygonCreated: PropTypes.func,
|
||||
onPolygonChange: PropTypes.func
|
||||
};
|
||||
|
|
|
@ -185,21 +185,37 @@ class Map extends React.Component {
|
|||
let metaUrl = url + "metadata";
|
||||
let unitForward = value => value;
|
||||
let unitBackward = value => value;
|
||||
let queryParams = {};
|
||||
|
||||
if (type == "plant"){
|
||||
if (meta.task && meta.task.orthophoto_bands && meta.task.orthophoto_bands.length === 2){
|
||||
// Single band, probably thermal dataset, in any case we can't render NDVI
|
||||
// because it requires 3 bands
|
||||
metaUrl += "?formula=Celsius&bands=L&color_map=magma";
|
||||
queryParams = {
|
||||
formula: 'Celsius',
|
||||
bands: 'L',
|
||||
color_map: 'magma'
|
||||
};
|
||||
}else if (meta.task && meta.task.orthophoto_bands){
|
||||
let formula = this.hasBands(["red", "green", "nir"], meta.task.orthophoto_bands) ? "NDVI" : "VARI";
|
||||
metaUrl += `?formula=${formula}&bands=auto&color_map=rdylgn`;
|
||||
queryParams = {
|
||||
formula,
|
||||
bands: 'auto',
|
||||
color_map: 'rdylgn'
|
||||
};
|
||||
}else{
|
||||
// This should never happen?
|
||||
metaUrl += "?formula=NDVI&bands=RGN&color_map=rdylgn";
|
||||
queryParams = {
|
||||
formula: 'NDVI',
|
||||
bands: 'RGN',
|
||||
color_map: 'rdylgn'
|
||||
};
|
||||
}
|
||||
}else if (type == "dsm" || type == "dtm"){
|
||||
metaUrl += "?hillshade=6&color_map=viridis";
|
||||
queryParams = {
|
||||
hillshade: 6,
|
||||
color_map: 'viridis'
|
||||
};
|
||||
unitForward = value => {
|
||||
return unitSystem().elevation(value).value;
|
||||
};
|
||||
|
@ -210,6 +226,10 @@ class Map extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
if (meta.task.crop) queryParams.crop = 1;
|
||||
|
||||
metaUrl += Utils.toSearchQuery(queryParams);
|
||||
|
||||
this.tileJsonRequests.push($.getJSON(metaUrl)
|
||||
.done(mres => {
|
||||
const { scheme, name, maxzoom, statistics } = mres;
|
||||
|
@ -242,18 +262,23 @@ class Map extends React.Component {
|
|||
max = Math.max(statistics[b]["max"]);
|
||||
}
|
||||
}
|
||||
params["rescale"] = encodeURIComponent(`${min},${max}`);
|
||||
params.rescale = encodeURIComponent(`${min},${max}`);
|
||||
}else{
|
||||
console.warn("Cannot find min/max statistics for dataset, setting to -1,1");
|
||||
params["rescale"] = encodeURIComponent("-1,1");
|
||||
params.rescale = encodeURIComponent("-1,1");
|
||||
}
|
||||
|
||||
params["size"] = TILESIZE;
|
||||
params.size = TILESIZE;
|
||||
if (meta.task.crop) params.crop = 1;
|
||||
tileUrl = Utils.buildUrlWithQuery(tileUrl, params);
|
||||
}else{
|
||||
tileUrl = Utils.buildUrlWithQuery(tileUrl, { size: TILESIZE });
|
||||
let params = { size: TILESIZE };
|
||||
if (meta.task.crop) params.crop = 1;
|
||||
tileUrl = Utils.buildUrlWithQuery(tileUrl, params);
|
||||
}
|
||||
|
||||
console.log(tileUrl, meta.task);
|
||||
|
||||
const layer = Leaflet.tileLayer(tileUrl, {
|
||||
bounds,
|
||||
minZoom: 0,
|
||||
|
@ -838,10 +863,14 @@ _('Example:'),
|
|||
if (this.layersControl && (prevState.imageryLayers !== this.state.imageryLayers ||
|
||||
prevState.overlays !== this.state.overlays ||
|
||||
prevState.annotations !== this.state.annotations)){
|
||||
this.layersControl.update(this.state.imageryLayers, this.state.overlays, this.state.annotations);
|
||||
this.updateLayersControl();
|
||||
}
|
||||
}
|
||||
|
||||
updateLayersControl = () => {
|
||||
this.layersControl.update(this.state.imageryLayers, this.state.overlays, this.state.annotations);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.map.remove();
|
||||
this.map.off('viewreset', this.layerVisibilityCheck);
|
||||
|
|
Ładowanie…
Reference in New Issue