Search code examples
openstreetmapreact-leafletoverpass-api

How to show nodes and ways on OpenStreetMap using Leaflet?


I was able to correctly query data from the OSM API.

Then, I've been able to show nodes on the map with the following codes:

for (let i = 0; i < data.elements.length; i++) {
   let pos;
   let marker;
   const e = data.elements[i];
   if (e.id in this._ids) {
       continue;
   }
                  
   this._ids[e.id] = true;
                  
   if (e.type === 'node') {
       pos = L.latLng(e.lat, e.lon);
   } 
   else{
       pos = L.latLng(e.center.lat, e.center.lon);
   }
   if (this.options.markerIcon) {
       marker = L.marker(pos, { icon: this.options.markerIcon });
   } 
   else {
       marker = L.circle(pos, 80, {
       stroke: false,
       fillColor: '#0000ff',
       fillOpacity: 0.9
       });
   } 
}

which gives me the following visual output: MyOutput-Image

How can I also show lines how it is done on OverpassTurbo: OverpassTurbo-Image


Solution

  • What does your OSM API query looks like? I assume it's an overpass query, in which case, you might have put an out center at the end, which returns the center of each way.

    Over pass out statement :

    center: This adds only the centre of the above mentioned bounding box to ways and relations. Note: The center point is not guaranteed to lie inside the polygon (example).

    Therefore, each way has a long/lat which is in the middle, which is what you plot as a marker using the e.center.lat

    example of a way with out center :

    {
      "type": "way",
      "id": 2263973,
      "center": {
        "lat": 51.5070645,
        "lon": -0.1359499
      },
      "nodes": [
        9789823,
        9789817,
        3933850766,
        ...
      ],
      "tags": {...}
    }
    

    You could either go through each associated node, and look them up and get the lat and lon. Or use the out geom option which returns the coordinates or the nodes directly:

    {
      "type": "way",
      "id": 2263973,
      "bounds": {
        "minlat": 51.5064574,
        "minlon": -0.1363268,
        "maxlat": 51.5076716,
        "maxlon": -0.1355731
      },
      "nodes": [
        9789823,
        9789817,
        ...
      ],
      "geometry": [
        { "lat": 51.5064574, "lon": -0.1355731 },
        { "lat": 51.5069432, "lon": -0.1360143 },
        { "lat": 51.5072896, "lon": -0.1363027 },
        { "lat": 51.5073314, "lon": -0.1363255 },
        { "lat": 51.5073531, "lon": -0.1363268 },
        { "lat": 51.5073965, "lon": -0.1363228 },
        { "lat": 51.5074324, "lon": -0.1363027 },
        { "lat": 51.5074691, "lon": -0.1362638 },
        { "lat": 51.5076716, "lon": -0.1356893 }
      ],
      "tags": {...}
    }
    

    Notice how you also get the min and max values for latitude and in longitude in a bounds attribute. You can then go through the geometry array, extract all the lat and lon in a latlngs array, and use:

    var polyline = L.polyline(latlngs, {color: 'blue'}).addTo(map); to draw a line. See Leaflet doc on polyline

    And you can get this, for [highway~motorway]

    enter image description here