Search code examples
javascriptgoogle-maps-api-3geojson

Create elevation profile from GeoJson feature


I have a map which contains a GeoJson file with lines, displaying some trails. Is it possible to use Google Maps API Elevation Service to create elevation profiles for every feature line of the GeoJson file? I want the elevation profile to be displayed when I click one of the lines.

Something like this example: http://www.trailforks.com/region/la-bouilladisse/

My code, until now, looks like this:

google.load("visualization", "1", {packages: ["columnchart"]});

function initialize() {
var options = {
    center: new google.maps.LatLng(44.701991, 22.624884),
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.TERRAIN
};

map = new google.maps.Map(document.getElementById("map"), options);

trasee = new google.maps.Data()
trasee.loadGeoJson('http://googledrive.com/host/0B55_4P6vMjhITEU4Ym9iVG8yZUU/trasee.geojson')
trasee.setMap(map)

styling = (function(feature) {
    var clasificare = feature.getProperty('Tip_drum');
    var culoare;
    if (clasificare == ('Poteca'))
        (culoare = 'brown')
    else if (clasificare == ('Drum forestier'))
        (culoare = 'green')
    else if (clasificare == ('Drum comunal (neasfaltat)'))
        (culoare = 'brown')
    else if (clasificare == ('Drum judetean (neasfaltat)'))
        (culoare = 'brown')
    else if (clasificare == ('Drum comunal (asfaltat)'))
        (culoare = 'gray')
    else if (clasificare == ('Drum judetean (asfaltat)'))
        (culoare = 'gray')
    else
        (culoare = 'black')
    return ({
        strokeColor: culoare,
        strokeWeight: 3
    })
})

trasee.setStyle(styling)

elevator = new google.maps.ElevationService();
}

I know that I have to make a request like this: var pathRequest = { 'path': source of latlng for creating the path 'samples': 256 }

So basically, I think that the GeoJson must be added somewhere in the pathRequest, but I don't know how, and how to create a different elevation plot for every feature in my GeoJson file.

fiddle of existing code

OK, so now I try to display the elevation charts along with the Tip_drum attribute in infowindows, when I click the data. I added this code:

  map.data.addListener('click', function (event) {
    document.getElementById('info').innerHTML = event.feature.getProperty('Tip_drum')
    var content = document.createElement('div')
    var elevations = document.getElementById('elevation_chart')
    var types = document.getElementById('info')
    content.appendChild(elevations)
    content.appendChild(types)
    infowindow.setContent(content)
    infowindow.setPosition(event.latLng)
    infowindow.setMap(map)
    if (event.feature.getGeometry().getType() === 'LineString') {
        drawPath(event.feature.getGeometry().getArray());

Everything works fine, until I manually close one of the infowindows. After that, the infowindows won't appear anymore.


Solution

    1. get the path from the clicked feature (event.feature.getGeometry().getArray())
    2. pass it to the elevation service (like the example in the elevations service documentation)
    3. plot the returned data on a chart (like the example in the elevations service documentation)
    4. remove the code from the Google elevation service example that creates a blue polyline over the polylines from the data layer.

    (note that some of the above didn't work with your existing code, I modified it slightly to match the working examples in the documentation)

    working fiddle

    var elevator;
    var map;
    var chart;
    var polyline;
    
    // Load the Visualization API and the columnchart package.
    google.load('visualization', '1', {
        packages: ['columnchart']
    });
    
    function initialize() {
        var options = {
            center: new google.maps.LatLng(44.701991, 22.624884),
            zoom: 12,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        };
    
        map = new google.maps.Map(document.getElementById("map"), options);
    
        trasee = new google.maps.Data();
        map.data.loadGeoJson('http://googledrive.com/host/0B55_4P6vMjhITEU4Ym9iVG8yZUU/trasee.geojson');
    
        // trasee.setMap(map);
    
        styling = (function (feature) {
            var clasificare = feature.getProperty('Tip_drum');
            var culoare;
            if (clasificare == ('Poteca'))
            (culoare = 'brown');
            else if (clasificare == ('Drum forestier'))
            (culoare = 'green');
            else if (clasificare == ('Drum comunal (neasfaltat)'))
            (culoare = 'brown');
            else if (clasificare == ('Drum judetean (neasfaltat)'))
            (culoare = 'brown');
            else if (clasificare == ('Drum comunal (asfaltat)'))
            (culoare = 'gray');
            else if (clasificare == ('Drum judetean (asfaltat)'))
            (culoare = 'gray');
            else(culoare = 'black');
            return ({
                strokeColor: culoare,
                strokeWeight: 3
            });
        });
    
        map.data.setStyle(styling);
    
        // Set mouseover event for each feature.
        map.data.addListener('click', function (event) {
            document.getElementById('info').innerHTML = event.feature.getProperty('Tip_drum');
            if (event.feature.getGeometry().getType() === 'LineString') {
                drawPath(event.feature.getGeometry().getArray());
    
                // calculate the directions once both origin and destination are set 
                // calculate();
            }
        });
    
      // When the user hovers, tempt them to click by outlining the letters.
      // Call revertStyle() to remove all overrides. This will use the style rules
      // defined in the function passed to setStyle()
      map.data.addListener('mouseover', function(event) {
        map.data.revertStyle();
          map.data.overrideStyle(event.feature, {strokeWeight: 8, strokeColor: 'blue'});
      });
    
      map.data.addListener('mouseout', function(event) {
        map.data.revertStyle();
      });
        elevator = new google.maps.ElevationService();
        // Draw the path, using the Visualization API and the Elevation service.
        // drawPath();
    }
    
    function drawPath(path) {
    
        // Create a new chart in the elevation_chart DIV.
        chart = new google.visualization.ColumnChart(document.getElementById('elevation_chart'));
    
        // Create a PathElevationRequest object using this array.
        // Ask for 256 samples along that path.
        var pathRequest = {
            'path': path,
                'samples': 256
        };
    
        // Initiate the path request.
        elevator.getElevationAlongPath(pathRequest, plotElevation);
    }
    
    // Takes an array of ElevationResult objects, draws the path on the map
    // and plots the elevation profile on a Visualization API ColumnChart.
    function plotElevation(results, status) {
        if (status != google.maps.ElevationStatus.OK) {
            return;
        }
        var elevations = results;
    
        // Extract the elevation samples from the returned results
        // and store them in an array of LatLngs.
        var elevationPath = [];
        for (var i = 0; i < results.length; i++) {
            elevationPath.push(elevations[i].location);
        }
    
        // Extract the data from which to populate the chart.
        // Because the samples are equidistant, the 'Sample'
        // column here does double duty as distance along the
        // X axis.
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Sample');
        data.addColumn('number', 'Elevation');
        for (var i = 0; i < results.length; i++) {
            data.addRow(['', elevations[i].elevation]);
        }
    
        // Draw the chart using the data within its DIV.
        document.getElementById('elevation_chart').style.display = 'block';
        chart.draw(data, {
            height: 150,
            legend: 'none',
            titleY: 'Elevation (m)'
        });
    }
    
    google.maps.event.addDomListener(window, 'load', initialize);