I'm trying to merge two functions that are displayed as OL's samples, the Advanced View Positioning and the View Animation. I can successfully change the view with the animation method, but I can't fix the zoom as in the Advanced View Postitioning method. I'm using these methods to change the view of some rasters loaded in OL. My problem is related only with the zoom level, how can I make it fit to the raster that I'm using? I believe that I need to get the raster extent (already did it) and somehow calculate and link to the zoom section in the flyTo()
function.
OL version: 5.3
Function I'm using for the animation:
//This is one of the locations I using with the View Animation method
var randomLocation = transform(getCenter([565280.904542, 6924581.621580, 565319.267400, 6924554.342636]), 'EPSG:31982', 'EPSG:3857');
function flyTo(location, done) {
var duration = 3000;
var zoom = view.getZoom();
var parts = 2;
var called = false;
function callback(complete) {
--parts;
if (called) {
return;
}
if (parts === 0 || !complete) {
called = true;
done(complete);
}
}
view.animate({
center: location,
duration: duration
}, callback);
view.animate({
zoom: zoom - 2,
duration: duration / 2
}, {
zoom: zoom,
duration: duration / 2
}, callback);
}
Some links that are related but did not help me (most of them use the fit(extent)
function. I tried to use it but it cancels the animate()
function):
- Open Layers 4 fit to extent zoom too much out
- https://stackoverflow.com/questions/49746970/openlayers-4-fit-to-extent-of-selected-features
- OpenLayers-3 setting zoom so layers fit in map window
- https://stackoverflow.com/questions/42369647/openlayers-animate-getview-fit
- https://stackoverflow.com/questions/49361669/openlayers-map-jitters-on-dynamic-centering-of-feature-movement-animation
- OpenLayers - Setting View Correctly Extent GEOJSon
- https://stackoverflow.com/questions/44763661/openlayers-fit-extent-with-bounce
- https://stackoverflow.com/questions/41190146/view-fit-using-view-animate-in-openlayers-3-20
- https://stackoverflow.com/questions/38291471/openlayers-3-zoom-map-to-coordinates-in-array
- View Animation of OpenLayers
1 Answer 1
I've experimented with the example and found an easy way to do it. Use .fit
to get the desired final outcome, save the resulting center and zoom, then immediately go back to the starting point. You can then flight animate the same movement. Any of the other animation examples should also work.
var flytolausanne = document.getElementById('flytolausanne');
flytolausanne.addEventListener('click', function() {
var feature = source.getFeatures()[1];
var point = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
var oldCenter = view.getCenter();
var oldZoom = view.getZoom();
view.fit(point, {padding: [170, 50, 30, 150], minResolution: 50});
var newCenter = view.getCenter();
var newZoom = view.getZoom();
view.setCenter(oldCenter);
view.setZoom(oldZoom);
flightZoom = Math.min(oldZoom, newZoom) - 2;
zoomUp = oldZoom - flightZoom;
zoomDown = newZoom - flightZoom;
var duration = 2000;
var parts = 2;
var called = false;
function callback(complete) {
--parts;
if (called) {
return;
}
if (parts === 0 || !complete) {
called = true;
//done(complete);
}
}
view.animate({
center: newCenter,
duration: duration
}, callback);
view.animate({
zoom: flightZoom,
duration: duration * zoomUp / (zoomUp + zoomDown)
}, {
zoom: newZoom,
duration: duration * zoomDown / (zoomUp + zoomDown)
}, callback);
}, false);
Just as someone has entered the coordinates for the outline of Switzerland in switzerland.geojson
in the example you will need to define your own extent. It you want to use same the extent as above you would simply replace the minimum resolution fit
with constrain resolution for a best fit:
var extent = ol.proj.transformExtent([565280.904542, 6924581.621580, 565319.267400, 6924554.342636], 'EPSG:31982', 'EPSG:3857');
view.fit(extent, {padding: [170, 50, 30, 150], constrainResolution: false});
-
Thanks Mike, I already tried something like this. The problem is that I can't get the features with the
source.getFeatures()[1];
or the geometry from the raster. This is my only problem with theview.fit()
function, since I can't use with the raster extention or other raster related object. I tried several ways to accomplish this, but all unsuccessful. Thats why I passed the raster extent in top of the code, being that I can get the extent from the ImageLayer without problems. This works nice if I have only vectors though.leonardofmed– leonardofmed2019年02月13日 10:30:32 +00:00Commented Feb 13, 2019 at 10:30 -
To convert coordinates to a geometry
point = new.ol.geom.Point(randomLocation);
The extent of a single coordinate israndomLocation.concat(randomLocation);
Mike– Mike2019年02月13日 11:34:37 +00:00Commented Feb 13, 2019 at 11:34 -
Okay, so using the
point = new Point({randomLocation});
gave me a blank screen with no erros. Passing the var point to console shows that the extension as:extent_: (4) [Infinity, Infinity, -Infinity, -Infinity]
, I guess that is the problem. Using therandomLocation.concat(randomLocation);
as a point works in your function, but the zoom is still wrong related to the raster, being now too far away and positioned northwest.leonardofmed– leonardofmed2019年02月14日 12:03:10 +00:00Commented Feb 14, 2019 at 12:03 -
Point syntax should be
new Point(randomLocation)
without the{ }
Mike– Mike2019年02月15日 10:00:29 +00:00Commented Feb 15, 2019 at 10:00 -
Thank you for the correction. This fixed the blank screen problem, but the zoom keeps with the same situation, too far and northwest related to the location.leonardofmed– leonardofmed2019年02月15日 11:19:34 +00:00Commented Feb 15, 2019 at 11:19
location
you should fly to where the full map will be centered if location is centered in the padded area. An offset ofn
pixels on the screen isn * view.getResolution()
in map coordinates. You will needmap.getSize()
and the padding array to calculate the horizontal and vertical values for n.view.fit()
function. I wonder if it is not possible to do the same with a raster and apply in thisflyTo()
function.