openlayersopenstreetmapangular-openlayers

OL OSM get center point of a specific Layer


I am using Open layer OSM map with Angular to browse countries then states and then cities accordingly. I am able to level up as per selction and adding new layer for each. I am not removing but Just hidding previous layer suppose if someone selected New york from United states then all countries layer will be made hidden and upper layer with NewYark Cities will be visible. Now I need to give user ability to drill back to Upper level. Like double clicking on New York will display back all counties. so to do it when I hide current Layer and show previous layer it shows correctly but I am unable to retrieve its center point. can any one help in it ?

this.map.on('singleclick', (event) => {
    // do foreach for each layer  this.MapLevel is each layer number in map
    this['vectorLayer' + this.MapLevel].getFeatures(event.pixel).then((features) => {
        if (!features.length) {
          selection = {};
          return;
        }
        const feature = features[0];
        if (!feature) {
          return;
        }
 this.MapLevel = this.MapLevel + 1;
        this['vectorLayer' + this.MapLevel] = new VectorLayer({
source: new VectorSource({
          url: this.MapSourceURl, // local json file path to retrive Data
          map: this.map,
          format: new GeoJSON(),
          wrapX: false,
          useSpatialIndex: false,
          overlaps: false 
         })}); // layer parameters not pasting here as it has long
        this.map.addLayer(this['vectorLayer' + this.MapLevel]);
        this['vectorLayer'+ this.MapLevel].setVisible(true);
        this['vectorLayer' + (this.MapLevel - 1)].setVisible(false);
      });
      });


// On double click I am trying to show previous layer to downgrade Level in map

this.map.on('dblclick', (event) => {


     this['vectorLayer' + (this.MapLevel - 1)].setVisible(true);
     this['vectorLayer' + (this.MapLevel - 1)].setOpacity(1);
     this.view.animate({center: toLonLat([this.long, this.lati]), zoom : this.view.getZoom() - 1, duration: 2000});
     this.map.removeLayer(this['vectorLayer' + this.MapLevel]);
     this['vectorLayer'+ this.MapLevel].setVisible(false);
    });

But I am not getting correct zoom level of previous layer this so this code is failing. 

Solution

  • If I understand you correctly, this may work,

    let updateViewExtent = function (pixel, level) {
      this['vectorLayer' + level].getFeatures(event.pixel).then((features) => {
        if (features.length > 0) {
          return;
        }
        const feature = features[0];
        if (!feature) {
          return;
        }
        // zoom to feature clicked (here just first feature)
        this.map.getView().fit(feature.getGeometry().getExtent(), {size: this.map.getSize()});
    }
    this.map.on('singleclick', (event) => {
      // if this is the lower level return
      if (this.MapLevel === LOWERLEVEL) {
        return;
      }
      // zoom to the clicked feature of the level
      updateViewExtent(event.pixel, this.MapLevel);
      // update map level and layers visibility
      this['vectorLayer' + this.MapLevel].setVisible(false);
      this.MapLevel += 1;
      this['vectorLayer' + this.MapLevel].setVisible(true);
    });
    this.map.on('dblclick', (event) => {
      // if this is the upper level return
      if (this.MapLevel === UPPERLEVEL) {
        return;
      }
      // zoom to the clicked feature of the upper level
      updateViewExtent(event.pixel, this.MapLevel - 1);
      // update map level and layers visibility
      this['vectorLayer' + this.MapLevel].setVisible(false);
      this.MapLevel -= 1;
      this['vectorLayer' + this.MapLevel].setVisible(true);
    });
    
    

    I use a function to zoom desire extent, in this case the clicked feature. Actually it could happen that is more than a feature, you could zoom to extended extent. If you actually want to zoom to the layer extent on double click then instead of calling the function just use this,

    // zoom upper layer extent
    this.map.getView().fit(
      this['vectorLayer' + (this.MapLevel - 1)].getSource().getExtent(),
      {size: this.map.getSize()}
    );
    

    Lastly, you may need to cancel the default behavior of the map on double click (zoom in one level).