JavaScript – Resolving New Map Creation on Every Country Search in OpenLayers

javascriptopenlayers

As a beginner I am trying to create a map with JavaScript using OpenLayers
for coordinates I am using REST countries API.
When I search for a country it creates a new map every time. If I search 5 countries there are five maps in a row. but it should only be changing marker on the map according to coordinates.

Code is somthing like this:

     const input = document.getElementById("search");
  function openMap(longitude, latitude,) {
  
    var attribution = new ol.control.Attribution({
      collapsible: false,
    });
  
    map = new ol.Map({
      controls: ol.control.defaults({ attribution: false }).extend([attribution]),
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM({
            attributions: [
              ol.source.OSM.ATTRIBUTION,
            ],
            maxZoom: 10,
          }),
        }),
      ],
      target: "map",
      view: new ol.View({
        center: ol.proj.fromLonLat([latitude, longitude]),
        maxZoom: 4,
        zoom: 3,
      }),
    });
   
    var layer = new ol.layer.Vector({
      source: new ol.source.Vector({
        features: [
          new ol.Feature({
            geometry: new ol.geom.Point(
              ol.proj.fromLonLat([latitude, longitude])
            ),
          }),
        ],
      }),
    });
  
    map.addLayer(layer);
    layer.removeAll;
  
    var overlay = new ol.Overlay({
      autoPan: true,
      autoPanAnimation: {
        duration: 250,
      },
    });
    map.addOverlay(overlay)
}

 input.addEventListener("input", (e) => {
      fetch("https://restcountries.eu/rest/v2/all").then((response) => {
        response.json().then((json) => {
          json.forEach((country) => {
            // console.log(country);
            if(e.target.value === country.name){
              console.log(country.latlng[0],country.latlng[1]);
              openMap(country.latlng[0],country.latlng[1]) // here i am calling openLayer's function  
                
              
            }
          });
        });
      });
    });
    

Best Answer

With each search you are creating a new map with the call to the openMap function. You have to create map only once at the first search. On subsequent searches just clear old country center point feature, add new center point and center map to that point.

Code could then look something like this:

const input = document.getElementById("search");

var map;
var layer;

function addCountryCenterPoint(lonLat) {
  var pointFeature = new ol.Feature({
    geometry: new ol.geom.Point(lonLat)
  });
  var source = layer.getSource();
  source.clear();
  source.addFeature(pointFeature);
}

function openMap(lonLat) {
  var attribution = new ol.control.Attribution({
    collapsible: false,
  });
  map = new ol.Map({
    controls: ol.control.defaults({ attribution: false }).extend([attribution]),
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM({
          attributions: [
            ol.source.OSM.ATTRIBUTION,
          ],
          maxZoom: 10,
        }),
      }),
    ],
    target: "map",
    view: new ol.View({
      center: lonLat,
      maxZoom: 4,
      zoom: 3,
    }),
  });
  layer = new ol.layer.Vector({
    source: new ol.source.Vector()
  });
  addCountryCenterPoint(lonLat);
  map.addLayer(layer);
}

input.addEventListener("input", (e) => {
  fetch("https://restcountries.eu/rest/v2/all").then((response) => {
    response.json().then((json) => {
      json.forEach((country) => {
        if(e.target.value === country.name){
          var lonLat = ol.proj.fromLonLat([country.latlng[1], country.latlng[0]]);
          if (!map)
            openMap(lonLat);
          else {
            addCountryCenterPoint(lonLat);
            map.getView().setCenter(lonLat);
          }
        }
      });
    });
  });
});