【问题标题】:How to load data from CSV to use it in a Leaflet heatmap?如何从 CSV 加载数据以在 Leaflet 热图中使用它?
【发布时间】:2016-11-21 17:39:49
【问题描述】:

我正在尝试从一些 CSV 格式的数据中显示热图。我正在尝试将 CSV 文件中的数据放入 JavaScript 变量中,但我不知道该怎么做。

我使用以下 Leaflet 插件:

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

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

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

我的代码如下:

<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>

CSV 文件如下所示:

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

【问题讨论】:

  • 如果您可以从 CSV 文件中复制粘贴前几行,那将很有帮助。

标签: javascript leaflet heatmap


【解决方案1】:

有很多不同的方法来解决这个问题。我要描述的只是其中之一


首先,我将使用最新版本的 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>

而且只有一个热图插件。地球上没有理由同时需要两个热图插件。

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

接下来是reading the contents of a text file into a JS variable。有几种方法,但我特别喜欢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)
})

将文本分成几行...

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

...遍历行,除了第一个...

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

...将行拆分为逗号分隔的部分(在本例中为分号分隔);我假设一个简单的 CSV 格式 (things can get a bit more complicated with some CSV files)...

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

...以heatmap plugin 喜欢的形式获取您想要在热图上显示的数据,请记住parts 是一个0 索引数组...

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

...一旦线路上的循环结束并且heatData 准备就绪,则初始化热图:

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

把它们放在一起:

    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)
//    })

查看working example here


请不要盲目复制粘贴代码。每次您复制粘贴代码时,stackoverflow 之神都会杀死一只小猫,然后有人用豌豆和鱼在米饭上煮饭,并称之为海鲜饭。想想小猫。还有海鲜饭。

请注意,我已将问题拆分为几个较小的问题:

  • 选择合适的工具(传单版本、热图实施)
  • 读取文本文件(fetch/ajax/XHR/etc)
  • 解析 CSV(从文件中拆分行,字段组成行)
  • 为热图创建数据结构(循环,选择字段)

根据您的具体情况,您可能需要修改这些小问题中的任何一个。

【讨论】:

  • 感谢 Ivan,我知道下面的代码用于从网络传递 csv 文件: fetch('something/something/data.csv').then(function(response){ return response.text(); }).then(function(text) { 但是有必要我在文中介绍所有csv的行吗?
  • 没有。您应该只使用 fetch API,它将使用文件的内容填充 text 变量。在我的代码中复制粘贴 CSV 的内容只是一个示例。
  • 顺便说一句,fetch(...) 代码不是“通过”CSV 文件。该代码使您的浏览器获取远程资源,在本例中为 csv 文件。那里有区别。
  • 嗨,你可能想说:小猫,小猫。但我可能是错的。 :-) 顺便说一句,写得很好。太棒了!
【解决方案2】:

试试这个。实际上,您需要一个 AJAX 调用来加载您的 CSV 文件。在成功函数中,将其分配给一个变量(而不是使用文本区域,就像我在这里的说明一样)。

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>

【讨论】:

  • 感谢您向我解释这部分代码,但我的主要问题是我无法使用我之前编写的代码生成热图
  • 好的,没关系。我在你的问题中错过了这一点。另一个答案可能会有所帮助。
【解决方案3】:

有很多方法可以做到这一点,但我更喜欢使用 D3.js 库读取 CSV 文件。在您可以对数据进行更多计算或者只是阅读它的情况下,它可能很有用!

安装d3后:

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

那么简单:

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

url是指你的数据源,可能是这样的

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

【讨论】:

    猜你喜欢
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多