简体   繁体   中英

How to load data from CSV to use it in a Leaflet heatmap?

I'm trying to display a heatmap from some data in CSV format. I'm trying to get the data from the CSV file into a JavaScript variable, but I don't know how to do that.

I use the following Leaflet plugins:

<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>

<script src="heatmap.js"></script>

<script src="leaflet-heatmap.js"></script>

My code is below:

<script>

  window.onload = function() {

    var baseLayer = L.tileLayer(
      'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
        attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://cloudmade.com">CloudMade</a>',
        maxZoom: 18
      }
    );
    var testData = {
      max: 8,
      data: [
        {lat: 24.6408, lng:46.7728, count: 3},
        {lat: 50.75, lng:-1.55, count: 1},
        {lat: 52.6333, lng:1.75, count: 1}
      ]
    };
    var cfg = {
      "radius": 2,
      "maxOpacity": .8, 
      "scaleRadius": true, 
      "useLocalExtrema": true,
      latField: 'lat',
      lngField: 'lng',
      valueField: 'count'
    };
    var heatmapLayer = new HeatmapOverlay(cfg);
    var map = new L.Map('map', {
      center: new L.LatLng(25.6586, -80.3568),
      zoom: 4,
      layers: [baseLayer, heatmapLayer]
    });
    heatmapLayer.setData(testData);
    layer = heatmapLayer;
  };
</script>

The CSV file looks like this:

id;Código postal;Localidad;Valoracion;lat;lng
1;46100;Burjassot;8;39.51;-0.425055
2;18005;Granada;7;37.169266;-3.597161

Try this. In practice, you'll need an AJAX call to load your CSV file. In the success function, assign it to a variable (rather than using a textarea, as I have here, for illustration).

 mapData = []; CSV = $('#input').val(); var lines = CSV.split("\\n"); var result = []; var headers = lines[0].split(";"); for (var i = 1; i < lines.length; i++) { var obj = {}; var nextline = lines[i].split(";"); for (var j = 0; j < headers.length; j++) { obj[headers[j]] = nextline[j]; } result.push(obj); } $.each(result, function(i, el) { lat = el.lat; lng = el.lng; newData = { lat: lat, lng: lng }; mapData.push(newData); }); console.log(mapData); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <textarea id="input"> id;Código postal;Localidad;Valoracion;lat;lng 1;46100;Burjassot;8;39.51;-0.425055 2;18005;Granada;7;37.169266;-3.597161</textarea> 

There are a lot of different approaches to the problem. What I'm going to describe is just one of them .


First off, I'm gonna use the latest available version of Leaflet:

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.2/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.2/dist/leaflet.js"></script>

And just one heatmap plugin. There is no reason on earth why you should need two heatmap plugins at the same time.

<script src="https://unpkg.com/leaflet.heat@0.2.0/dist/leaflet-heat.js"></script>

Next off is reading the contents of a text file into a JS variable . There are several methods, but I'm particularly fond of the fetch API :

fetch('http://something/something/data.csv').then(function(response){
    return response.text();
}).then(function(text){
    // Handling of the text contents goes here
}).catch(function(err){
    // Error handling goes here (e.g. the network request failed, etc)
})

Split the text into lines...

var lines = text.split("\n");

...iterate through the lines, except the first one...

for (var i=1; i<lines.length; i++) {

...split the line into the comma-separated parts (in this case, semicolon-separated); I'm assuming a trivial CSV format ( things can get a bit more complicated with some CSV files )...

var parts = lines[i].split(";");

...get the data you want to show on the heatmap, in a form that the heatmap plugin will like, keeping in mind that parts is a 0-indexed array...

var heatData = []
for(...){
   ...
   // heatData.push( lat, lng, weight )
   heatData.push( [ parts[4], parts[5], parts[3] ] )

...and once the loop over the lines is over and heatData is ready, init the heatmap:

var heat = L.heatLayer(heatData, {radius: 25}).addTo(map);

And put it all together:

    var map = new L.Map('map').fitWorld();

    var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a>'
    }).addTo(map);

    // I'll just ignore the network request and fake some data.

//    fetch('http://something/something/data.csv').then(function(response){
//        return response.text();
//    }).then(function(text){

          text = "id;Código postal;Localidad;Valoracion;lat;lng\n1;46100;Burjassot;8;39.51;-0.425055\n2;18005;Granada;7;37.169266;-3.597161";

          var lines = text.split("\n");
          var heatData = [];
          for (var i=1; i<lines.length; i++) {
            var parts = lines[i].split(";");
            heatData.push( [ parts[4], parts[5], parts[3] ] );
          }

          var heat = L.heatLayer(heatData, {radius: 25}).addTo(map);

//    }).catch(function(err){
//        // Error handling for the fetch goes here (e.g. the network request failed, etc)
//    })

See a working example here .


Please do not blindly copy-paste the code. Every time you copy-paste code, the stackoverflow gods kill a kitten and somebody cooks rice with peas and fish on it and calls it paella. Think on the kittens. And the paella.

Please note that I've split the problem is several, smaller problems:

  • Choose the right tools (leaflet version, heatmap implementation)
  • Read a text file (fetch/ajax/XHR/etc)
  • Parse the CSV (split lines from the file, and fields form the lines)
  • Create a data structure for the heatmap (loop, choose fields)

Depending on your specific scenario, you might have to modify any of these smaller problems.

There are many ways to do it but I prefer to read CSV files using D3.js library. It may be useful where you can do more calculations on your data or maybe just read it!!

after installing d3:

<script src="https://d3js.org/d3.v4.js" charset="utf-8"></script>

then simply:

d3.csv(url, function(data) {
console.log(data)
})

url refer to your data source it may be something like this

url = 'http://something/something/data.csv'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM