kopia lustrzana https://github.com/OpenDroneMap/WebODM
Rescale update working
rodzic
4d529715ed
commit
8f16c17e34
|
@ -59,13 +59,18 @@ def rescale_tile(tile, mask, rescale = None):
|
|||
if len(rescale_arr) != tile.shape[0]:
|
||||
rescale_arr = ((rescale_arr[0]),) * tile.shape[0]
|
||||
for bdx in range(tile.shape[0]):
|
||||
tile[bdx] = np.where(
|
||||
mask,
|
||||
linear_rescale(
|
||||
if mask is not None:
|
||||
tile[bdx] = np.where(
|
||||
mask,
|
||||
linear_rescale(
|
||||
tile[bdx], in_range=rescale_arr[bdx], out_range=[0, 255]
|
||||
),
|
||||
0,
|
||||
)
|
||||
else:
|
||||
tile[bdx] = linear_rescale(
|
||||
tile[bdx], in_range=rescale_arr[bdx], out_range=[0, 255]
|
||||
),
|
||||
0,
|
||||
)
|
||||
)
|
||||
tile = tile.astype(np.uint8)
|
||||
|
||||
return tile, mask
|
||||
|
@ -120,14 +125,20 @@ class Metadata(TaskNestedView):
|
|||
"""
|
||||
task = self.get_and_check_task(request, pk)
|
||||
|
||||
expr = lookup_formula(self.request.query_params.get('formula'), self.request.query_params.get('bands'))
|
||||
formula = self.request.query_params.get('formula')
|
||||
bands = self.request.query_params.get('bands')
|
||||
color_map = self.request.query_params.get('color_map')
|
||||
|
||||
if formula == '': formula = None
|
||||
if bands == '': bands = None
|
||||
if color_map == '': color_map = None
|
||||
|
||||
expr = lookup_formula(formula, bands)
|
||||
|
||||
pmin, pmax = 2.0, 98.0
|
||||
raster_path = get_raster_path(task, tile_type)
|
||||
info = main.metadata(raster_path, pmin=pmin, pmax=pmax, histogram_bins=255, expr=expr)
|
||||
|
||||
|
||||
if tile_type == 'plant':
|
||||
info['algorithms'] = get_algorithm_list(),
|
||||
info['filters'] = get_camera_filters_list()
|
||||
|
@ -195,12 +206,19 @@ class Tiles(TaskNestedView):
|
|||
indexes = None
|
||||
nodata = None
|
||||
|
||||
expr = lookup_formula(self.request.query_params.get('formula'), self.request.query_params.get('bands'))
|
||||
formula = self.request.query_params.get('formula')
|
||||
bands = self.request.query_params.get('bands')
|
||||
rescale = self.request.query_params.get('rescale')
|
||||
color_map = self.request.query_params.get('color_map')
|
||||
hillshade = self.request.query_params.get('hillshade')
|
||||
|
||||
# TODO: server-side expressions
|
||||
if formula == '': formula = None
|
||||
if bands == '': bands = None
|
||||
if rescale == '': rescale = None
|
||||
if color_map == '': color_map = None
|
||||
if hillshade == '': hillshade = None
|
||||
|
||||
expr = lookup_formula(formula, bands)
|
||||
|
||||
if tile_type in ['dsm', 'dtm'] and rescale is None:
|
||||
raise exceptions.ValidationError("Cannot get tiles without rescale parameter. Add ?rescale=min,max to the URL.")
|
||||
|
|
|
@ -6,12 +6,14 @@ import d3 from 'd3';
|
|||
export default class Histogram extends React.Component {
|
||||
static defaultProps = {
|
||||
width: 280,
|
||||
colorMap: null
|
||||
colorMap: null,
|
||||
onUpdate: null
|
||||
};
|
||||
static propTypes = {
|
||||
statistics: PropTypes.object.isRequired,
|
||||
colorMap: PropTypes.array,
|
||||
width: PropTypes.number
|
||||
width: PropTypes.number,
|
||||
onUpdate: PropTypes.func
|
||||
}
|
||||
|
||||
constructor(props){
|
||||
|
@ -132,7 +134,7 @@ export default class Histogram extends React.Component {
|
|||
.attr('x2', minXStart)
|
||||
.attr('y2', height)
|
||||
.attr('class', 'theme-stroke-primary slider-line min')
|
||||
.on("mousedown", function(){ self.minDown = true; })[0][0];
|
||||
.on("mousedown", function(){ self.maxDown = false; self.minDown = true; })[0][0];
|
||||
|
||||
|
||||
const maxXStart = ((this.state.max - this.rangeX[0]) / (this.rangeX[1] - this.rangeX[0])) * width;
|
||||
|
@ -143,7 +145,7 @@ export default class Histogram extends React.Component {
|
|||
.attr('x2', maxXStart)
|
||||
.attr('y2', height)
|
||||
.attr('class', 'theme-stroke-primary slider-line max')
|
||||
.on("mousedown", function(){ self.maxDown = true; })[0][0];
|
||||
.on("mousedown", function(){ self.minDown = false; self.maxDown = true; })[0][0];
|
||||
|
||||
const handleLeave = () => {
|
||||
this.maxDown = this.minDown = false;
|
||||
|
@ -224,10 +226,14 @@ export default class Histogram extends React.Component {
|
|||
prevState.max !== this.state.max){
|
||||
if (!this.maxDown && !this.minDown) this.redraw();
|
||||
this.updateColorMap();
|
||||
|
||||
if (this.props.onUpdate !== undefined) this.props.onUpdate({min: this.state.min, max: this.state.max});
|
||||
}
|
||||
}
|
||||
|
||||
updateColorMap = () => {
|
||||
if (!this.colorMapElem) return;
|
||||
|
||||
const { min, max } = this.state;
|
||||
|
||||
const minPerc = Math.abs(min - this.rangeX[0]) / (this.rangeX[1] - this.rangeX[0]) * 100.0;
|
||||
|
|
|
@ -20,7 +20,7 @@ export default class LayersControlLayer extends React.Component {
|
|||
|
||||
this.map = props.layer._map;
|
||||
|
||||
const url = this.props.layer._url;
|
||||
const url = this.getLayerUrl();
|
||||
const params = Utils.queryParams({search: url.slice(url.indexOf("?"))});
|
||||
|
||||
this.colorMaps = [
|
||||
|
@ -37,8 +37,17 @@ export default class LayersControlLayer extends React.Component {
|
|||
this.state = {
|
||||
visible: true,
|
||||
expanded: props.expanded,
|
||||
color: params.color_map
|
||||
color_map: params.color_map || "",
|
||||
formula: params.formula || "",
|
||||
bands: params.bands || "",
|
||||
hillshade: params.hillshade || ""
|
||||
};
|
||||
|
||||
this.rescale = "";
|
||||
}
|
||||
|
||||
getLayerUrl = () => {
|
||||
return this.props.layer._url;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState){
|
||||
|
@ -59,12 +68,50 @@ export default class LayersControlLayer extends React.Component {
|
|||
}
|
||||
|
||||
handleSelectColor = e => {
|
||||
this.setState({color: e.target.value});
|
||||
this.setState({color_map: e.target.value});
|
||||
}
|
||||
|
||||
updateLayer = () => {
|
||||
if (this.updateTimer){
|
||||
clearTimeout(this.updateTimer);
|
||||
this.updateTimer = null;
|
||||
}
|
||||
|
||||
this.updateTimer = setTimeout(() => {
|
||||
const url = this.getLayerUrl();
|
||||
const { color_map,
|
||||
formula,
|
||||
bands,
|
||||
hillshade } = this.state;
|
||||
|
||||
const newUrl = (url.indexOf("?") !== -1 ? url.slice(0, url.indexOf("?")) : url) + Utils.toSearchQuery({
|
||||
color_map,
|
||||
formula,
|
||||
bands,
|
||||
hillshade,
|
||||
rescale: encodeURIComponent(this.rescale)
|
||||
});
|
||||
|
||||
const { layer } = this.props;
|
||||
|
||||
layer.setUrl(newUrl, true);
|
||||
|
||||
// Hack to get leaflet to actually redraw tiles :/
|
||||
layer._removeAllTiles();
|
||||
setTimeout(() => {
|
||||
layer.redraw();
|
||||
}, 1);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
handleHistogramUpdate = e => {
|
||||
this.rescale = `${e.min},${e.max}`;
|
||||
this.updateLayer();
|
||||
}
|
||||
|
||||
render(){
|
||||
const { layer } = this.props;
|
||||
const { color } = this.state;
|
||||
const { color_map } = this.state;
|
||||
|
||||
const tmeta = layer[Symbol.for("tile-meta")];
|
||||
const meta = layer[Symbol.for("meta")];
|
||||
|
@ -77,13 +124,14 @@ export default class LayersControlLayer extends React.Component {
|
|||
<div className="layer-expanded">
|
||||
<Histogram width={280}
|
||||
statistics={tmeta.statistics}
|
||||
colorMap={tmeta.color_map}/>
|
||||
colorMap={tmeta.color_map}
|
||||
onUpdate={this.handleHistogramUpdate} />
|
||||
|
||||
{this.state.color ?
|
||||
{this.state.color_map ?
|
||||
<div className="row form-group form-inline">
|
||||
<label className="col-sm-3 control-label">Color:</label>
|
||||
<div className="col-sm-9 ">
|
||||
<select className="form-control" value={color} onChange={this.handleSelectColor}>
|
||||
<select className="form-control" value={color_map} onChange={this.handleSelectColor}>
|
||||
{this.colorMaps.map(c => <option key={c.key} value={c.key}>{c.label}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
|
|
Ładowanie…
Reference in New Issue