Skip to content

Commit

Permalink
Merge pull request #868 from biigle/ol-v9
Browse files Browse the repository at this point in the history
Upgrade OpenLayers
  • Loading branch information
mzur authored Jul 16, 2024
2 parents ca1b525 + 5f23767 commit 2d0b462
Show file tree
Hide file tree
Showing 25 changed files with 1,194 additions and 805 deletions.
929 changes: 294 additions & 635 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
"vue-template-compiler": "^2.6.11"
},
"dependencies": {
"@biigle/ol": "^5.3.0",
"@biigle/ol": "^9.2.4",
"@fortawesome/fontawesome-free": "^5.2.0",
"@turf/boolean-contains": "^6.5.0",
"@turf/difference": "^6.5.0",
"@turf/helpers": "^6.5.0",
"@turf/union": "^6.5.0",
"bootstrap-sass": "^3.3.7",
"echarts": "^5.3.2",
"jsts": "^2.11.0",
Expand Down
5 changes: 2 additions & 3 deletions resources/assets/js/annotations/annotatorContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -501,10 +501,9 @@ export default {
}, 10000);
},
updateColorAdjustment(params) {
let canvas = this.$refs.canvas;
debounce(function () {
debounce(() => {
ImagesStore.updateColorAdjustment(params);
canvas.render();
this.$refs.canvas.fireImageSourceChanged();
}, 100, 'annotations.color-adjustment.update');
},
handleSettingsChange(key, value) {
Expand Down
49 changes: 35 additions & 14 deletions resources/assets/js/annotations/components/annotationCanvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as PolygonValidator from '../ol/PolygonValidator';
import AnnotationTooltip from './annotationCanvas/annotationTooltip';
import AttachLabelInteraction from './annotationCanvas/attachLabelInteraction';
import CanvasSource from '@biigle/ol/source/Canvas';
import CanvasSource from '../ol/source/Canvas';
import Circle from '@biigle/ol/geom/Circle';
import Collection from '@biigle/ol/Collection';
import ControlButton from './controlButton';
Expand Down Expand Up @@ -48,7 +48,6 @@ import {shiftKeyOnly as shiftKeyOnlyCondition} from '@biigle/ol/events/condition
import {singleClick as singleClickCondition} from '@biigle/ol/events/condition';
import { isInvalidShape } from '../utils';
/**
* The annotator canvas
*
Expand Down Expand Up @@ -328,8 +327,6 @@ export default {
center: view.getCenter(),
resolution: view.getResolution(),
});
},
invertPointsYAxis(points) {
// Expects a points array like [x1, y1, x2, y2]. Inverts the y axis of
Expand Down Expand Up @@ -520,7 +517,7 @@ export default {
this.annotationSource.removeFeature(e.feature);
return;
}
if (isInvalidShape(e.feature)) {
// This must be done in the change event handler.
// Not exactly sure why.
Expand Down Expand Up @@ -586,10 +583,10 @@ export default {
this.resetInteractionMode();
}
},
render() {
if (this.map) {
this.map.render();
this.$emit('render');
fireImageSourceChanged() {
const source = this.imageLayer?.getSource();
if (source) {
source.changed();
}
},
handleRegularImage(image) {
Expand Down Expand Up @@ -710,12 +707,34 @@ export default {
this.resetHoveredAnnotations();
},
selectedAnnotations(annotations) {
let source = this.annotationSource;
// This allows selection of annotations outside OpenLayers and forwards
// the state to the SelectInteraction.
let features = this.selectedFeatures;
features.clear();
annotations.forEach(function (annotation) {
features.push(source.getFeatureById(annotation.id));
let featureIdMap = {};
let annotationIdMap = {};
annotations.forEach(a => annotationIdMap[a.id] = true);
let toRemove = [];
features.forEach(f => {
const id = f.getId();
if (annotationIdMap[id]) {
featureIdMap[id] = true;
} else {
toRemove.push(f);
}
});
if (toRemove.length === features.getLength()) {
features.clear();
} else {
toRemove.forEach(f => features.remove(f));
}
annotations
.filter(a => !featureIdMap[a.id])
.forEach(
a => features.push(this.annotationSource.getFeatureById(a.id))
);
},
extent(extent, oldExtent) {
// The extent only truly changes if the width and height changed.
Expand All @@ -736,12 +755,14 @@ export default {
projection: this.projection,
center: center,
resolution: this.resolution,
zoomFactor: 2,
// Allow a maximum of 100x magnification for non-tiled images. More
// cannot be represented in the URL parameters.
minResolution: 0.01,
// Restrict movement.
extent: extent,
showFullExtent: true,
constrainOnlyCenter: true,
padding: [10, 10, 10, 10],
}));
if (this.resolution === undefined) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default {
return layer.get('name') === 'annotations';
},
updateHoveredAnnotations(e) {
let features = this.map.getFeaturesAtPixel(e.pixel, {layerFilter: this.annotationLayerFilter}) || [];
let features = this.map.getFeaturesAtPixel(e.pixel, {layerFilter: this.annotationLayerFilter});
let hash = features.map((f) => f.getId()).join('-');
if (this.hoveredFeaturesHash !== hash) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import Keyboard from '../../../core/keyboard';
import ModifyPolygonBrushInteraction from '@biigle/ol/interaction/ModifyPolygonBrush';
import PolygonBrushInteraction from '@biigle/ol/interaction/PolygonBrush';
import ModifyPolygonBrushInteraction from '../../ol/interaction/ModifyPolygonBrush';
import PolygonBrushInteraction from '../../ol/interaction/PolygonBrush';
import SelectInteraction from '@biigle/ol/interaction/Select';
import Styles from '../../stores/styles';
import { never, noModifierKeys, click, shiftKeyOnly, altKeyOnly } from '@biigle/ol/events/condition';
Expand Down
70 changes: 47 additions & 23 deletions resources/assets/js/annotations/components/minimap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

<script>
import Feature from '@biigle/ol/Feature';
import {CancelableMap as Map} from '../ol/CancelableMap';
import ImageLayer from '@biigle/ol/layer/Image';
import Map from '@biigle/ol/Map';
import Styles from '../stores/styles';
import TileLayer from '@biigle/ol/layer/Tile';
import VectorLayer from '@biigle/ol/layer/Vector';
import VectorSource from '@biigle/ol/source/Vector';
import View from '@biigle/ol/View';
import ZoomifySource from '@biigle/ol/source/Zoomify';
import {fromExtent} from '@biigle/ol/geom/Polygon';
import {getCenter} from '@biigle/ol/extent';
Expand All @@ -31,10 +34,6 @@ export default {
type: Number,
default: 200,
},
renderActive: {
type: Boolean,
default: true,
},
},
data() {
return {
Expand All @@ -48,7 +47,7 @@ export default {
updateViewport() {
// The map size and center might be undefined if the minimap is created
// initially. This function will be called again once the map is ready.
if (this.mapSize && this.mapView.getCenter()) {
if (this.mapSize && this.mapView.getCenter() && this.mapView.getResolution()) {
this.viewport.setGeometry(fromExtent(this.mapView.calculateExtent(this.mapSize)));
}
},
Expand All @@ -57,6 +56,7 @@ export default {
},
updateMapSize(e) {
this.mapSize = e.target.getSize();
this.updateViewport();
},
updateMapView(e) {
if (this.mapView) {
Expand All @@ -66,6 +66,7 @@ export default {
this.mapView = e.target.getView();
this.mapView.on('change:center', this.updateViewport);
this.mapView.on('change:resolution', this.updateViewport);
this.updateViewport();
},
updateElementSize() {
let imageWidth = this.extent[2];
Expand Down Expand Up @@ -95,37 +96,65 @@ export default {
// to update the layer here, too.
let name = e.element.get('name');
if (name && name.startsWith('image')) {
if (this.originalLayer) {
this.originalLayer.un('change:source', this.handleChangeSource);
}
this.originalLayer = e.element;
if (this.originalLayer instanceof TileLayer) {
this.currentLayer = new TileLayer({
source: this.originalLayer.getSource()
});
} else {
this.currentLayer = new ImageLayer({
source: this.originalLayer.getSource()
});
}
this.originalLayer.on('change:source', this.handleChangeSource);
let layers = this.minimap.getLayers();
if (layers.getLength() > 1) {
layers.setAt(0, e.element);
layers.setAt(0, this.currentLayer);
} else {
layers.insertAt(0, e.element);
layers.insertAt(0, this.currentLayer);
}
}
},
handleChangeSource(e) {
if (this.currentLayer) {
let source = e.target.getSource();
// Create a new tile source instead of sharing it because otherwise the
// minimap would flicker on zoom/pan sometimes.
if (this.currentLayer instanceof TileLayer) {
let image = this.$parent.image
source = new ZoomifySource({
url: image.url,
size: [image.width, image.height],
extent: [0, 0, image.width, image.height],
transition: 0,
});
}
this.currentLayer.setSource(source);
}
},
initImageLayer(layers) {
layers.getArray().forEach((layer) => {
this.refreshImageLayer({element: layer});
});
},
render() {
this.minimap.render();
},
},
watch: {
// Refresh the view if the extent (i.e. image size) changed.
extent() {
this.updateElementSize();
},
renderActive(render) {
if (render) {
this.minimap.render();
} else {
this.minimap.cancelRender();
}
},
},
created() {
// Must not be reactive.
this.originalLayer = null;
this.currentLayer = null;
this.minimap = new Map({
// remove controls
controls: [],
Expand All @@ -145,8 +174,6 @@ export default {
this.updateMapView({target: map});
map.on('change:size', this.updateMapSize);
map.on('change:view', this.updateMapView);
// Initialize the viewport once.
map.once('postcompose', this.updateViewport);
// Add the viewport layer now. Add the image layer later when it was
// added to the map.
Expand All @@ -158,8 +185,6 @@ export default {
this.minimap.on('pointerdrag', this.dragViewport);
this.minimap.on('click', this.dragViewport);
this.initImageLayer(map.getLayers());
this.$parent.$on('render', this.render);
},
mounted() {
this.updateElementSize();
Expand All @@ -175,7 +200,6 @@ export default {
map.un('change:size', this.updateMapSize);
map.un('change:view', this.updateMapView);
map.getLayers().un('add', this.refreshImageLayer);
this.$parent.$off('render', this.render);
},
};
</script>
16 changes: 11 additions & 5 deletions resources/assets/js/annotations/components/screenshotButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,20 @@ export default {
},
capture() {
if (this.map) {
this.map.once('postcompose', (e) => {
this.makeBlob(e.context.canvas)
.then(this.download)
.catch(this.handleError);
});
this.map.once('rendercomplete', this.handleRenderComplete);
this.map.renderSync();
}
},
handleRenderComplete(e) {
// See: https://openlayers.org/en/v6.15.1/examples/export-map.html
// This version is modified/simplified because we want the screenshot
// in the actual device pixel ratio and not at the original size.
const canvas = e.target
.getViewport()
.querySelector('.ol-layer canvas, canvas.ol-layer');
this.makeBlob(canvas).then(this.download).catch(this.handleError);
},
handleError(message) {
Messages.danger(message);
},
Expand Down
13 changes: 0 additions & 13 deletions resources/assets/js/annotations/ol/CancelableMap.js

This file was deleted.

Loading

0 comments on commit 2d0b462

Please sign in to comment.