Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
208 views
in Technique[技术] by (71.8m points)

javascript - Loading CSV with FileReader to make JS Objects for Map Markers (Maps API)

Basically I'm trying to load a csv file, parse it to an array of js objects and use those objects to make map markers with the Google Maps API.

The loading works, the parsing works, all the values are correct (to my knowledge), I've been console logging to death and I get the values that I want but... my map isn't loading.

I think it may be because of timing? Like the map isn't initializing or being loaded correctly.

I occasionally get errors about connections timing out and security errors from the Maps API but refreshing the page and reloading the csv seems to clear that up. The errors come and go.

Here's the JS:

window.onload = function() {
  var fileInput = document.getElementById('fileInput');
  var fileDisplayArea = document.getElementById('fileDisplayArea');

  fileInput.addEventListener('change', function(e) {
    var file = fileInput.files[0];
    var textType = /csv.*/;
    var companies;

    // Check if csv file. If so, then run program. If not, show error.
    if (file.type.match(textType)) {
      var reader = new FileReader();

      reader.onload = function(e) {
        var text = reader.result;

        // Log for debug. Success.
        // console.log(text);

        // Parse csv file and make objects to store in companies array.
        function csvParse(csv) {
          var lines = csv.split("
");

          // Log for debug. Success.
          // console.log(lines);

          var result = [];
          var headers = lines[0].split(",");

          for (var i = 1; i < lines.length; i++) {
            var obj = {};
            var currentline = lines[i].split(",");

            for (var j = 0; j < headers.length; j++) {
              obj[headers[j]] = currentline[j];
            }

            result.push(obj);
          }

          return result;
        }

        // Store objects in companies.
        companies = csvParse(text);

        // Log for debug. Success.
        // console.log(companies);

        var siteCircle;
        var companyMarker;

        // Log for debug. Success.
        // console.log(companies[1].sites);

        function initialize() {
          // Create the map of north america.
          var mapOptions = {
            zoom: 5,
            center: new google.maps.LatLng(37.09024, -95.712891),
            mapTypeId: google.maps.MapTypeId.TERRAIN
          }

          var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

          // Construct a circle and marker for each value in companies.
          for (var company in companies) {
            var latitude = (parseFloat(companies[company].lat)).toFixed(6);
            var longitude = (parseFloat(companies[company].long)).toFixed(6);

            // Log for debug. Success.
            // console.log(latitude);
            // console.log(longitude);
            // console.log(parseInt(companies[company].sites));

            var circleStyle = {
              // Set constant options.
              strokeColor: '#000000',
              fillColor: '#000000',
              strokeOpacity: 0.8,
              strokeWeight: 2,
              fillOpacity: 0.35,
              map: map,
              center: new google.maps.LatLng(latitude, longitude),
              radius: parseInt(companies[company].sites) * 100
            };

            // Not yet. circles first.
            /*
            var markerOptions = {
              // Place marker at same loacation and with a label.
              position: new google.maps.LatLng(parseFloat(companies[company].lat), parseFloat(companies[company].long)),
              map: map,
              title: companies[company].name,
            };
            */

            // Log for debug. Success.
            // console.log(circleStyle)

            // Add circle and marker to map. Repeat.
            siteCircle = new google.maps.Circle(circleStyle);

            // Circles need to populate first.
            // companyMarker = new google.maps.Marker(markerOptions);
          }
        }

        // Run mapping.
        initialize();
      }

      reader.readAsText(file);
    } else {
      fileDisplayArea.innerText = "File not supported!";
    }
  });
}

Also here is a gist with all the files : https://gist.github.com/mhelmetag/20eeae8cd4c901fb1094

Thanks so much in advance!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your posted code does not contain all the issues.

  1. I commented out the if (file.type.match(textType)) { test, that was giving me an error: "File not supported!" fiddle

  2. the csvParse function doesn't correctly parse the last entry of the file, you are getting NaN for the longitude (so the google.maps.LatLngs are not valid)

  3. removed the .toFixed(6) after the parseFloat call, changed:

var latitude = (parseFloat(companies[company].lat)).toFixed(6); 
var longitude = (parseFloat(companies[company].long)).toFixed(6);

To:

var latitude = parseFloat(companies[company].lat);
var longitude = parseFloat(companies[company].long);
  1. your map doesn't have a size, so once the issue with "longitude" is fixed, you can't see it.

  2. as an aside you have an issue with your css, the line below causes artifacts with the map controls, I removed it:

    img { max-width: 100%; }

working jsfiddle

Data file used:

name,type,sites,lat,long,dummy
Yum Brands,QSR,36000,38.198117,-85.695723,nothing
McDonalds,QSR,11772,41.848117,-87.944818,nothing
Dollar General,Discount,8414,36.309512,-86.699107,nothing
WalMart,Big Box,7873,36.365399,-94.217752,nothing
Walgreens,Drug Store,7500,42.156776,-87.871079,nothing
Starbucks,QSR,6793,47.581000,-122.335855,nothing
Dunkin Brands,QSR,6500,42.207285,-71.129786,nothing
CVS,Drug Store,6301,41.990542,-71.477562,nothing
Gamestop,Specialty,6207,32.902302,-97.087347,nothing
7-Eleven,C-Store,6100,32.791810,-96.795768,nothing
Family Dollar,Discount,6000,35.131827,-80.731703,nothing
Couche Tarde,C-Store,5600,33.335586,-111.955955,nothing

working code snippet:

window.onload = function() {
  var fileInput = document.getElementById('fileInput');
  var fileDisplayArea = document.getElementById('fileDisplayArea');

  fileInput.addEventListener('change', function(e) {
    var file = fileInput.files[0];
    var textType = /csv.*/;
    var companies;

    // Check if csv file. If so, then run program. If not, show error.
    //     if (file.type.match(textType)) {
    var reader = new FileReader();

    reader.onload = function(e) {
      var text = reader.result;

      // Log for debug. Success.
      // console.log(text);

      // Parse csv file and make objects to store in companies array.
      function csvParse(csv) {
        var lines = csv.split("
");

        // Log for debug. Success.
        // console.log(lines);

        var result = [];
        var headers = lines[0].split(",");

        for (var i = 1; i < lines.length; i++) {
          var obj = {};
          var currentline = lines[i].split(",");

          for (var j = 0; j < headers.length; j++) {
            obj[headers[j]] = currentline[j];
          }

          result.push(obj);
        }

        return result;
      }

      // Store objects in companies.
      companies = csvParse(text);

      // Log for debug. Success.
      // console.log(companies);

      var siteCircle;
      var companyMarker;

      // Log for debug. Success.
      // console.log(companies[1].sites);

      function initialize() {
        // Create the map of north america.
        var mapOptions = {
          zoom: 5,
          center: new google.maps.LatLng(37.09024, -95.712891),
          mapTypeId: google.maps.MapTypeId.TERRAIN
        }

        var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

        // Construct a circle and marker for each value in companies.
        for (var company in companies) {
          var latitude = parseFloat(companies[company].lat);
          var longitude = parseFloat(companies[company].long);

          // Log for debug. Success.
          // console.log(latitude);
          // console.log(longitude);
          // console.log(parseInt(companies[company].sites));

          var circleStyle = {
            // Set constant options.
            strokeColor: '#000000',
            fillColor: '#000000',
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillOpacity: 0.35,
            map: map,
            center: new google.maps.LatLng(latitude, longitude),
            radius: parseInt(companies[company].sites) * 100
          };

          // Not yet. circles first.
          /*
          var markerOptions = {
            // Place marker at same loacation and with a label.
            position: new google.maps.LatLng(parseFloat(companies[company].lat), parseFloat(companies[company].long)),
            map: map,
            title: companies[company].name,
          };
          */

          // Log for debug. Success.
          // console.log(circleStyle)

          // Add circle and marker to map. Repeat.
          siteCircle = new google.maps.Circle(circleStyle);

          // Circles need to populate first.
          // companyMarker = new google.maps.Marker(markerOptions);
        }
      }

      // Run mapping.
      initialize();
    }

    reader.readAsText(file);
    /*    } else {
          fileDisplayArea.innerText = "File not supported!";
        }
    */
  });
}

/* test.csv
name,type,sites,lat,long
Yum Brands,QSR,36000,38.198117,-85.695723
McDonalds,QSR,11772,41.848117,-87.944818
Dollar General,Discount,8414,36.309512,-86.699107
WalMart,Big Box,7873,36.365399,-94.217752
Walgreens,Drug Store,7500,42.156776,-87.871079
Starbucks,QSR,6793,47.581000,-122.335855
Dunkin Brands,QSR,6500,42.207285,-71.129786
CVS,Drug Store,6301,41.990542,-71.477562
Gamestop,Specialty,6207,32.902302,-97.087347
7-Eleven,C-Store,6100,32.791810,-96.795768
Family Dollar,Discount,6000,35.131827,-80.731703
Couche Tarde,C-Store,5600,33.335586,-111.955955
*/
html {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 100%;
  background: #333;
}
html,
bofy {
  height: 100%;
  width: 100%;
}
#page-wrapper {
  width: 600px;
  background: #FFF;
  padding: 1em;
  margin: 1em auto;
  min-height: 300px;
  border-top: 5px solid #69c773;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.8);
}
h1 {
  margin-top: 0;
}
#fileDisplayArea {
  margin-top: 2em;
  width: 100%;
  overflow-x: auto;
}
#map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="page-wrapper">

  <h1>CSV File to JS Object Test</h1>
  <div>
    Select a CSV file:
    <input type="file" id="fileInput" />
  </div>
  <pre id="fileDisplayArea"><pre>
 
  </div>
  <div id="map-canvas" style="height: 500px; width: 500px;"></div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...