0

I want to highlight a road segment on a Leaflet Map. I have the coordinates of the end point of the road segment, so could plot it as a linestring. But the problem is how can I get the width of the road segment, so as to highlight it completely?

Is there some Leaflet function / library which can make this kind of queries?

One way could be to use this approximate method from Obtaining shape or width of road in GeoJSON format?, but is there a better method? Also this method won't work with zoom-in / zoom-out, since the width should change with zoom-in / zoom-out, but hard-coding width of different types of road will not give this effect.

1
  • "hard-coding width of different types of road will not give this effect". Actually, I think it will, if you hardcode the width as an addition to the linestring coordinates themselves.
    – user1462
    Commented Jul 11, 2018 at 14:52

1 Answer 1

0

Instead of creating a new line to show the selected feature, you can create a highlight style to use when you click on the line (Select it), the style controls the width of the original line and the highlight width.

Here is some working code, I also have a link to a GeoJSON line file, save it as text and place in the same folder as your html file, it should run. (http://www.gistechsolutions.com/leaflet/DEMO/Buffer/istate.json) or rename the var url to your GeoJSON file. Note my on.click sets the roads back to the original style before it draws the highlight style, if you don't do this it will keep the old one selected.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>

    <style>
        #map {
            width: 800px;
            height: 600px;
        }
    </style>

</head>
<body>
<div id="map"></div>
<script>
var url = "istate.json";  // http://www.gistechsolutions.com/leaflet/DEMO/Buffer/istate.json

    var map = L.map('map').setView([43, -75], 7);

    var osm=new L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png',{ 
                attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);

// Used to show each road               
var myStyle = {
    "color": "black",
    "weight": 5,  //symbol width of line
    "opacity": 0.65
};

var highlight = {
    "color": "yellow",
    "weight": 5,
    "opacity": 1
};

    function forEachFeature(feature, layer) {

            layer.on('click', function (e) {
                road.setStyle(myStyle);
                layer.setStyle(highlight); 
            })          
    }

//////////////////////////
//Define Road Layer
var road = L.geoJson(null, {
        onEachFeature: forEachFeature,   
        style: myStyle
    });

    // Add GeoJSON to road layer
    $.getJSON(url, function(data) {
       road.addData(data);
    });

    //Add road layer to map
    road.addTo(map);

 </script>
 </body>
 </html>
2
  • I think you didn't got my question. I don't want to ask how to highlight or draw a line. In your code, you have hard-coded highlight.weight, which I am also doing right now. But what I want to ask is that, is there any way in which that value could be queried from Mapbox, Leaflet or OSM data, so that it exactly overlaps the width of the underlying road on the map layer. Commented Jul 22, 2018 at 4:32
  • With Vector tiles you might have a chance, image tiles like aerials no so much. Knowing it changes with the tilelayer, the scale, and road class, you might be better picking one basemap, and test the width for each road class at each zoom level, then write a function to get the scale on map change and restyle the layer. Commented Jul 22, 2018 at 13:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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