Crop fade animation, layers reload working

pull/1636/head
Piero Toffanin 2025-03-26 15:34:37 -04:00
rodzic 69499dd26b
commit 4e035c3ba9
5 zmienionych plików z 56 dodań i 15 usunięć

Wyświetl plik

@ -358,10 +358,12 @@ class Task(models.Model):
# must be enclosed within all raster extents
# and have a positive area
if self.crop is not None:
has_extents = False
for extent in [self.orthophoto_extent, self.dsm_extent, self.dtm_extent]:
if extent is not None:
has_extents = True
self.crop = extent.intersection(self.crop)
if self.crop.area <= 0:
if not has_extents or self.crop.area <= 0:
self.crop = None
self.clean()
@ -1007,6 +1009,7 @@ class Task(models.Model):
self.update_size()
self.potree_scene = {}
self.running_progress = 1.0
self.crop = None
self.status = status_codes.COMPLETED
if is_backup:

Wyświetl plik

@ -59,6 +59,14 @@ export default {
return (url.indexOf("?") !== -1 ? url.slice(0, url.indexOf("?")) : url) + this.toSearchQuery(params);
},
buildUrlReplaceParams: function(url, params){
let q = this.queryParams({search: url});
for (let k in params){
q[k] = params[k];
}
return this.buildUrlWithQuery(url, q);
},
clone: function(obj){
return JSON.parse(JSON.stringify(obj));
},

Wyświetl plik

@ -167,11 +167,20 @@ class CropButton extends React.Component {
}
}
deletePolygon = () => {
deletePolygon = (opts = {}) => {
if (this.polygon){
this.group.removeLayer(this.polygon);
this.polygon = null;
this.props.onPolygonChange(null);
const remove = () => {
this.group.removeLayer(this.polygon);
this.polygon = null;
if (opts.triggerEvents) this.props.onPolygonChange(null);
};
if (opts.fade){
this.polygon._path.classList.add("fade");
setTimeout(remove, 1500);
}else{
remove();
}
}
}
@ -280,8 +289,8 @@ export default L.Control.extend({
return container;
},
deletePolygon: function(){
return this._btn.deletePolygon();
deletePolygon: function(opts = {}){
return this._btn.deletePolygon(opts);
},
getCropPolygon: function(){

Wyświetl plik

@ -276,7 +276,7 @@ class Map extends React.Component {
if (meta.task.crop) params.crop = 1;
tileUrl = Utils.buildUrlWithQuery(tileUrl, params);
}
const layer = Leaflet.tileLayer(tileUrl, {
bounds,
minZoom: 0,
@ -665,16 +665,16 @@ _('Example:'),
if (this.props.permissions.indexOf("change") !== -1){
const updateCropArea = geojson => {
// Find tasks IDs
const taskMetas = {};
const taskMap = {};
const requests = [];
if (!geojson) geojson = '';
// Crop affects all tasks in the map
for (let layer of this.state.imageryLayers){
if (layer._map && !layer.isHidden()){
if (layer._map){
const meta = layer[Symbol.for("meta")];
const task = meta.task;
if (!taskMetas[task.id]){
if (!taskMap[task.id]){
requests.push($.ajax({
url: `/api/projects/${task.project}/tasks/${task.id}/`,
contentType: 'application/json',
@ -684,7 +684,7 @@ _('Example:'),
dataType: 'json',
type: 'PATCH'
}));
taskMetas[task.id] = meta;
taskMap[task.id] = meta;
}
}
}
@ -697,14 +697,30 @@ _('Example:'),
responses = [responses];
}
// Update task info
// Update task in meta and tiles objects
responses.forEach(task => {
taskMetas[task.id].task = task;
if (!task) return;
const meta = taskMap[task.id];
meta.task = task;
for (let i = 0; i < this.props.tiles.length; i++){
const tile = this.props.tiles[i];
if (tile.meta && tile.meta.task.id === task.id){
tile.meta.task = task;
}
}
});
this.loadImageryLayers();
})
.fail(e => {
this.setState({error: _("Cannot set cropping area. Check your internet connection.")});
console.error(e);
}).always(() => {
setTimeout(() => {
this.cropButton.deletePolygon({triggerEvents: false, fade: true});
}, 1000);
});
};
@ -719,7 +735,8 @@ _('Example:'),
if (window.confirm(_('Are you sure you want to set a new crop area?'))){
updateCropArea(null);
}else{
return true; // Stop crop button from toggling
// Stop crop button from toggling
return true;
}
}

Wyświetl plik

@ -22,6 +22,10 @@
.leaflet-interactive.crop.pulse {
animation: cropPulseFill 1s infinite ease-in-out;
}
.leaflet-interactive.crop.fade{
-webkit-transition-duration: 1s;
transition-duration: 1s;
}
@keyframes cropPulseFill {
0% {