Search code examples
csvdrag-and-dropleaflet

Drag and drop csv file into Leaflet map


Have not to find any solution for Drag and Drop CSV files into a Leaflet map. There is a plugin for GeoJSON, TopoJSON, and zipped Shapefiles Drag and Drop calvinmetcalf. For those files, you need GIS software or special tools that can convert to these file types. I want a plain CSV file that users can use without having special software.

Esri has a function similar to what I'm looking for. A simple drag and drop of CSV onto the map, the CSV of course needs to have lat/lon values to work...

I have been trying with drag and drop function and this plugin Leaflet.geoCSV using the below script. But not sure how to get the dropped file to interact with the plugin. The file gets uploaded to the browser but can't get the data to show on the map and there are no errors... I am missing something or have got everything wrong...

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

Solution

  • You need to add the file content to the L.geoCsv and not the file name: L.geoCsv(ev.dataTransfer.files[i].name, you can do this for example with FileReader like here.

    PS: This two lines are the same, so you can remove one of them:

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