3

I'm drawing a route on a map with leaflet. I'd like to click on any point in the line and display the speed and time at that point in a popup ($speed[$i]).

latlngs = [<?php for ($i=0;$i<count($latts);$i++){echo '['. $latts[$i] .', '. $longs[$i]     .']';if($i!=count($latts)-1){echo ',';}} ?>],
itinerary = L.polyline(latlngs, {color: 'red'});
itinerary.addEventListener('click dblclick', function(e) {
    console.log(e);
    var res = e.latlng; // that's nice but I'd like to be able to get e.speed, etc...
});
map.addLayer(itinerary);

EDIT: I'm building the polyline with an array of Latitudes and Longitudes. I've got a Speed array of the same length. When the user clicks on a point on the line, I'd like to get the closest recorded Latitude and Longitude, and display the corresponding speed for that point (in a popup or in an other div). Eventually the user can slide his mouse along the line and see the speed .

2 Answers 2

4

building from this answer, you can extend L.Polyline to include any number of variables as options

customPolyline = L.Polyline.extend({
    options: {
        // default values, you can override these when constructing a new customPolyline
        speed: '25',
        bearing: '140'
    }
});

now create your polylines, and add to the map:

latlngs = [<?php for ($i=0;$i<count($latts);$i++){echo '['. $latts[$i] .', '. $longs[$i];  
var polyline = new customPolyline(latlngs,{
    color: 'red',  
    speed: '143',
    bearing: '38'
});

polyline.on('click', function() { 
    alert(this.options.speed) 
});

polyline.addTo(map);

See this fiddle for a complete example with polyline

UPDATE

Following up on your comment, you can also attach custom data to L.markers, as shown below and in this fiddle:

customMarker = L.Marker.extend({
   options: { 
      speed: '111',
      bearing: '111'
   }
});

for (var i = 0, len = latlngs.length; i < len; i++) {
    var m = new customMarker(latlngs[i], {
        // get the actual speed for this lat-long
        // if speeds are in an array in the same exact order as the lat-longs
        // it could be as easy as speed: speed[i]
        speed: '123'
    });
    m.on('click', function() {
        alert(this.options.speed)
    })
    m.addTo(map);
}

var polyline = L.polyline(latlngs,{});
polyline.addTo(map);

I don't know how your speed data are associated with each point. But assuming you can get a javascript array or object of lat-longs and speeds, you just need to edit the marker loop, above, to add the speed to each marker when it is constructed.

5
  • Thanks toms, however my speed with differ at every latlng point. For example 'var polyline = new customPolyline([[51.49,-0.11],[51.51,-0.13],[51.505,-0.09],[51.507,-0.08],[51.509,-0.07]],{ speed: [100,110,120,130,140], bearing: [1,2,3,4,5] });' Is there a way to access the key of the latitude and longitudes?? so I can go alert(this.options.speed[k]);
    – Underfrog
    Commented Nov 23, 2014 at 11:04
  • I've updated my answer, above. Hope it helps
    – toms
    Commented Nov 24, 2014 at 3:20
  • Thanks toms! Unfortunately I do not want any markers on the line, it's got to be a click at any point to get the speed corresponding to that precise location.
    – Underfrog
    Commented Nov 24, 2014 at 9:28
  • maybe you can edit your question to explain what that means exactly? Do you want the line to carry the average speed of the two points that make up the line? Or something more complex? e.g. interpolation of speed based on the distance from the click on the line to the two points, etc.
    – toms
    Commented Nov 24, 2014 at 20:05
  • Have edited my question. Just the recorded speed at the closest latLong point.
    – Underfrog
    Commented Nov 25, 2014 at 1:32
0

You should use GEOJSON instead, this will allow you to store as much data as you want

Here is the data :

var path = {
            "type": "between2captures",
            "features": [
                {
                    "type": "Feature",
                    "geometry": {
                        "type": "LineString",
                        "coordinates": [[-105.015, 39.753], [-105.012, 39.751] ]
                    },
                    "properties": {"speed": 80, }
                },
                {
                    "type": "Feature",
                    "geometry": {
                        "type": "LineString",
                        "coordinates": [[-105.012, 39.751], [-105.005, 39.758] ]
                    },
                    "properties": {"speed": 112, }
                },
                {
                    "type": "Feature",
                    "geometry": {
                        "type": "LineString",
                        "coordinates": [[-105.005, 39.758], [-105.003, 39.745] ]
                    },
                    "properties": {"speed": 160, }
                },

            ]
        };

next, you simple add this data to your map, listen to the click event and extract the data you need:

var road = L.geoJson(path, {style: style}).addTo(map);

        road.addEventListener('click dblclick', function(e) {
            alert(e.layer.feature.properties.speed)
        });

Adding color (extra)

Using this technique, you can render your line based on your data, this can help the viewer determine the speed without clicking on it :

adding a little color function :

function getColor(speed) {
            return speed > 150 ? '#d94b38' :
                   speed > 100  ? '#d9a238' :
                   speed > 50  ? '#c8d938' :
                              '#309d27';
            }

The style function used in our geoJson constructor :

function style(feature) {
            return {
                weight: 5,
                opacity: 1,
                color: getColor(feature.properties.speed),
            };
        }

and now the geoJson constructor (replacing the original one above):

var road = L.geoJson(path, {style: style}).addTo(map);

This is how it should look like :

json road

0

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.