Search code examples
openlayersgeojsonsidebar

How to add minimap on the sidebar in OpenLayers working by click


I have a simple OpenLayers map with a GeoJSON layer (several cities as points and labels) and a working sidebar where the properties of each city selected by mouseclick are displayed. In simplified form, this part of the code in main.js looks like this:

const idElement = document.querySelector("#id");
const coordsElement = document.querySelector("#coords");

map.on('click', function (evt) {
    let hit = false;
    const coordinate = evt.coordinate;
    const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
    //Filter for clicks aside from point
        if ( layer === mygeojsonLayer) {
            hit = true;
            return feature;
        } else {}
        });
    if (hit) {
        idElement.innerHTML = feature.get('id');
        coordsElement.innerHTML = feature.get('lonlat');
    } else {
        idElement.innerHTML = ' ';
        coordsElement.innerHTML = ' ';
    }
    if (!feature) {
        return;
    }
});

//I don't know where to put this:
const minimap = new Map({
    target: 'minimap', //<div id="minimap"> in index.html
    layer: new TileLayer({
        source: new OSM(),
    }),
    view: new View({
        projection: 'EPSG:3857',
        center: //???,
        zoom: 10,
    }),
});

In index.html the sidebar is a simple table with div and span id="id" and span id="minimap" in the rows. And apart from the minimap, everything works fine for me.

So where in main.js should I insert const.minimap part so that the minimap is in the sidebar and displays the selected city with a large zoom? So that the coordinates of the city are taken not from the location of the click on the main map, but from the properties of the city in the GeoJSON file?

I tried to insert const.minimap in various places inside if and else and the main problem was that the number of my minimaps on the sidebar grew with every click. Or, in other cases, I got no minimap at all - just two zoom buttons and OSM attribute.


Solution

  • Thank you, Mike, it works! The correct code is:

    let minimap;
    
    map.on('click', function (evt) {
        let hit = false;
        const coordinate = evt.coordinate;
        const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
        //Filter for clicks aside from point
            if ( layer === mygeojsonLayer) {
                hit = true;
                return feature;
            } else {}
            });
        if (hit) {
            idElement.innerHTML = feature.get('id');
            //coordsElement.innerHTML = feature.get('lonlat');
            const view = new View({
                projection: 'EPSG:3857',
                center: getCenter(feature.getGeometry().getExtent()),
                zoom: 10,
            });
            if (!minimap) {
                minimap = new Map({
                    target: 'minimap', //<div id="minimap"> in index.html
                    layers: [
                        new TileLayer({
                            source: new OSM(),
                        }),
                    ],
                });
            }
            minimap.setView(view);
        } else {
            idElement.innerHTML = '&nbsp;';
            //coordsElement.innerHTML = '&nbsp;';
        }
        if (!feature) {
            return;
        }
    });