OL3: Zoom to vector layer on map
Asked Answered
M

4

5

I have a map with openlayers 3 and a vector layer. I want to map to be resized to this vector layer, but so far all I was able to get was to center the map on the last point of this vector, since the points of the vector layer are not accessible while creating the map:

if (trackMap != null) {
  for (var i = 0; i < trackMap.length; i++) {
    var trackInfo = trackMap[i];
    lat = parseFloat(trackInfo.lat);
    lon = parseFloat(trackInfo.lon);

    var layergpx = new ol.layer.Vector({
      source: new ol.source.Vector({
        parser: new ol.parser.GPX(),
        url: '${contextRoot}/gps/gpx2' + trackInfo.url
      })
    });
    layers.push(layergpx);
    vectorLayers.push(layergpx);
  }
}

map = new ol.Map({
  controls: ol.control.defaults().extend([
    new ol.control.FullScreen()
  ]),
  layers: layers,
  renderer: ol.RendererHint.CANVAS,
  target: 'map',
  view: new ol.View2D({
    center: ol.proj.transform([lon, lat], 'EPSG:4326', 'EPSG:3857'),
    zoom: 13
  })
});
Mim answered 6/1, 2014 at 9:48 Comment(7)
You want the map to be resized or to be zoomed into? Try the FitExtent in the View2DRabb
Zoomed into. I tried FitToExtend, but the problem is, that the track is not loaded, when calling FitToExtendMim
the extend has to be in the same coordinate system as the map. which is the coordinate system of the map, of the layer and of the extend?Rabb
Yes. I tried something, posted by somebody else, where he had a counter, which waited until all layers had been loaded and then zoomed to the extent, but that was quiet unstable. gis.stackexchange.com/questions/31323/…Mim
Can't you get the extend from server-side and start the map with that extend?Rabb
Not by default. I would have to calculate the extent, since I only have a set of coordinates (up to 10.000). And since OL calculates a layer from this, they know the extent and I had to calculate it. That would be my backup plan!Mim
Having Javascript calculating a extent for 10K point don't seems to be a good idea unless you can control the environment where the application will be run. Doing it server-side and caching it's my advice.Rabb
M
1

So... after a few days of testing and thinking I solved the problem. Not without further problems, but calculating the borders serverside and transmitting them to the script made it a bit easier.

The Javascript is fairly short for solving the problem:

if (minLon != null && minLat != null && maxLon != null && maxLat != null){
 var bottomLeft = ol.proj.transform([minLon, minLat], 'EPSG:4326', 'EPSG:3857');
 var topRight = ol.proj.transform([maxLon, maxLat], 'EPSG:4326', 'EPSG:3857');
 extent = new ol.extent.boundingExtent([bottomLeft,topRight]);
 map.getView().fitExtent(extent, map.getSize());
}
Mim answered 13/1, 2014 at 17:32 Comment(1)
fitExtent will not not longer supported (github.com/openlayers/ol3/releases/tag/v3.7.0) so you have simply to use the function fit instead.Dismay
R
6

Why not just fit to the extent of the ol.source.Vector?

var source = new ol.source.Vector();

...

map.getView().fitExtent(source.getExtent(), map.getSize());
Raouf answered 1/5, 2014 at 2:38 Comment(0)
H
6

From version 3.7.0 ol.View.fitExtent() was replaced by ol.View.fit()

var source = new ol.source.Vector();
map.getView().fit(source.getExtent(), map.getSize());
Highmuckamuck answered 9/10, 2015 at 8:13 Comment(0)
M
1

So... after a few days of testing and thinking I solved the problem. Not without further problems, but calculating the borders serverside and transmitting them to the script made it a bit easier.

The Javascript is fairly short for solving the problem:

if (minLon != null && minLat != null && maxLon != null && maxLat != null){
 var bottomLeft = ol.proj.transform([minLon, minLat], 'EPSG:4326', 'EPSG:3857');
 var topRight = ol.proj.transform([maxLon, maxLat], 'EPSG:4326', 'EPSG:3857');
 extent = new ol.extent.boundingExtent([bottomLeft,topRight]);
 map.getView().fitExtent(extent, map.getSize());
}
Mim answered 13/1, 2014 at 17:32 Comment(1)
fitExtent will not not longer supported (github.com/openlayers/ol3/releases/tag/v3.7.0) so you have simply to use the function fit instead.Dismay
N
0

I have a way of doing the view centering without worrying about transforming the degrees from one standard to another. Wondering this trick would apply to you. You first get the extents from all your sources. Factorizing their center and input that center to your viewport:

try {
    extentEMRG = geoSrcEMRG.getExtent();
    extentWARN = geoSrcWARN.getExtent();
    ext2Layers = ol.extent.getIntersection(extentEMRG, extentWARN);
    center2Layers = ol.extent.getCenter(ext2Layers);
    //alert(center2Layers);
} catch (e) {
    alert(e.message);
}
 var map = new ol.Map({
    view: new ol.View({
        center: center2Layers
        , zoom: 8
    })
    , layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        })
        , vLayerWARN 
        , vLayerEMRG 
    ] ....
Novice answered 12/11, 2014 at 17:27 Comment(2)
Clever. But what if your extents don't intersect. I'd think you want the union, not the intersection.Douzepers
Thankyou for your question, need to look at it once I got time. Haven't looked at that project for a while!Novice

© 2022 - 2024 — McMap. All rights reserved.