将 csv 文件拖放到 Leaflet 地图中

Drag and drop csv file into Leaflet map

没有找到将 CSV 文件拖放到 Leaflet 地图中的任何解决方案。有一个用于 GeoJSON、TopoJSON 和压缩 Shapefile Drag and Drop calvinmetcalf 的插件。 对于这些文件,您需要 GIS 软件或可以转换为这些文件类型的特殊工具。我想要一个用户无需特殊软件即可使用的普通 CSV 文件。

Esri 具有与我正在寻找的功能相似的功能。简单地将 CSV 拖放到地图上,CSV 当然需要有 lat/lon 值才能工作...

我一直在尝试使用拖放功能和此插件 Leaflet.geoCSV 使用以下脚本。但不确定如何让拖放的文件与插件交互。该文件已上传到浏览器,但无法在地图上显示数据并且没有错误...我遗漏了一些东西或一切都错了...

<div id="map" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);"></div>

<script type="text/javascript" src="../js/leaflet.geocsv.js"></script>

 function dragOverHandler(ev) {
  console.log('File(s) in drop zone');

  // Prevent default behavior (Prevent file from being opened)
  ev.preventDefault();
}

function dropHandler(ev) {
  console.log('File(s) dropped');

  // Prevent default behavior (Prevent file from being opened)
  ev.preventDefault();

  if (ev.dataTransfer.items) {
    // Use DataTransferItemList interface to access the file(s)
    for (var i = 0; i < ev.dataTransfer.items.length; i++) {
      // If dropped items aren't files, reject them
      if (ev.dataTransfer.items[i].kind === 'file') {
        var file = ev.dataTransfer.items[i].getAsFile();
        console.log('... file[' + i + '].name = ' + file.name);
      }
    }
  } else {
    // Use DataTransfer interface to access the file(s)
    for (var i = 0; i < ev.dataTransfer.files.length; i++) {
      var geoLayer = L.geoCsv(ev.dataTransfer.files[i].name, {firstLineTitles: true, fieldSeparator: ';'});
      map.addLayer(geoLayer);
      geoLayer.addTo(map);
      //console.log('... file[' + i + '].name = ' + ev.dataTransfer.files[i].name);
    }
  }

  // Pass event to removeDragData for cleanup
 // removeDragData(ev)
}

function removeDragData(ev) {
  console.log('Removing drag data')

  if (ev.dataTransfer.items) {
    // Use DataTransferItemList interface to remove the drag data
    ev.dataTransfer.items.clear();
  } else {
    // Use DataTransfer interface to remove the drag data
    ev.dataTransfer.clearData();
  }
}

/*
//Example script from Leaflet.geoCSV
(function() {
'use strict';

var map = L.map('mapContainer');

$.get('data.csv', function(csvContents) {
  var geoLayer = L.geoCsv(csvContents, {firstLineTitles: true, fieldSeparator: ','});
  map.addLayer(geoLayer);
});
}); */

您需要将文件内容添加到 L.geoCsv 而不是文件名:L.geoCsv(ev.dataTransfer.files[i].name, 您可以使用 FileReader 来执行此操作,例如 here

PS:这两行是一样的,所以你可以去掉其中一条:

      map.addLayer(geoLayer);
      geoLayer.addTo(map);

我设法使它工作,感谢您将我指向 FileReader。 我用了下面的,如果有人有类似的问题...

<div id="map" 
ondrop="dropHandler(event);" 
ondragover="dragOverHandler(event);"></div>

function dragOverHandler(ev) {
console.log('File(s) in drop zone');

// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();
}

function dropHandler(ev) {
console.log('File(s) dropped');

// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();

if (ev.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
  // If dropped items aren't files, reject them
  if (ev.dataTransfer.items[i].kind === 'file') {
    var file = ev.dataTransfer.items[i].getAsFile();
    var reader = new FileReader();
    reader.onload = function() {
        if (reader.readyState != 2 || reader.error){
            return;
      } else {
            convertToLayer(reader.result)       
        }};

reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
  const percent = (event.loaded / event.total) * 100;
  console.log(`Progress: ${Math.round(percent)}`);
}
});       
    reader.readAsText(file)
  }}
}
}

function convertToLayer(CSV) {
var geoLayer = L.geoCsv(CSV, {
    longitudeTitle: 'lng',
    latitudeTitle: 'lat',
    firstLineTitles: true,
    fieldSeparator: ';',
    pointToLayer: function (feature, latlng) {
        return L.circle(latlng, {
            radius: 5,
            fillColor: '#969696',
            fillOpacity: 0.5,
            color: '#252525',
            weight: 1,
            });
}
});
  geoLayer.addTo(map);
}