0

I'm fairly new to GIS programming but I've managed to do the following in Leaflet along with OSM:

  1. Display the map (very simple indeed)
  2. Get coordinates from user input (onClick on map, gives me lat/lng)
  3. Given coordinates, I can retrieve geocoding address information from nominatim (OSM)
  4. Given the geocoding data, I can see if it's a city, town, village, hamlet, or neither.

I was wondering if it is possible to generate and display this text when a user hovers over a city, town, village or hamlet, or highlight it when they press on it. Or is my only option to put a pin on the text?

2
  • I am not familiar with Leaflet, but I think what you are trying to display are labels. This might help you.
    – ChloeG
    Sep 9 at 5:47
  • Coding question on GIS SE site should include relevant existing code, otherwise it's most likely to be closed as not compliant with the site policy. Please edit your question and add relevant existing code.
    – TomazicM
    Sep 9 at 7:10

1 Answer 1

1

What you can do is query nominatim when the mouse hasn't moved after x seconds. For displaying it without out a pin / marker you can use a plain popup. In the example I am making the query if the mouse hasn't moved for one second. Additionally a queryState is set to true, so that if the user moves the mouse during a running query another query to the endpoint is prevented:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>Query Nominatem</title>
    
    <link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>

    <style>
   html, body, #map {
      height:100%;
      width:100%;
      padding:0px;
      margin:0px;
   } 
    </style>

    
</head>
<body>

<div id="map"></div>
<script>

    const map = L.map('map').setView([48.210033, 16.363449], 10);

    const tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
    }).addTo(map);


  let timeOut;
  let popUp;
  let queryState = false;

  function mousemove(e) {
    clearTimeout(timeOut)
    if (!queryState) {
      timeOut = setTimeout(() => {
        queryState = true;
        if (popUp) {
          popUp.remove()
        }
        popPup = L.popup()
          .setLatLng(e.latlng)
          .setContent("Loading data....")
          .openOn(map);
        queryNominatem(e)
      }, 1000);
    }
  }

  function queryNominatem(e) {
    fetch(`https://nominatim.openstreetmap.org/reverse.php?lat=${e.latlng.lat}&lon=${e.latlng.lng}&zoom=${map.getZoom()}&format=json`).then(
      (x) => {
        return x.json()
      }
    ).then(
      (data) => {
        popUp = L.popup()
          .setLatLng(e.latlng)
          .setContent(data.display_name)
          .openOn(map);
        queryState = false;
      }
    ).catch(
      (err) => {
        console.log(err);       
        popUp = L.popup()
          .setLatLng(e.latlng)
          .setContent("Error Loading data ... ")
          .openOn(map);

        setTimeout(() => {
          popUp.remove();
          queryState = false;
        }, 1000);
      }
    );    
  }

  map.on("mousemove", mousemove);
</script>
</body>
</html>


Not the answer you're looking for? Browse other questions tagged or ask your own question.