calvinmetcalf / shapefile-js

Convert a Shapefile to GeoJSON. Not many caveats.
http://calvinmetcalf.github.io/shapefile-js/
715 stars 228 forks source link

Error: no layers founds #116

Closed Anexo closed 5 years ago

Anexo commented 5 years ago

Hi Calvin!

I am loading a ZIP file using JSZip. I am loading it correctly (or at least I see the content listed , when I console log).

I am using Angular and loading the content through an input.

Here is the code of the function I call, when I submit the file:

self.importShapefile = function(){
        var x = document.getElementById("shapefile-uploader");

        var zip = new JSZip();
        zip.loadAsync( x.files[0] )
            .then(function(zip) {

                shp(zip).then(function(geojson){
                  console.log('success');
                })
                .catch(function (response) {
                  console.log(response);
                })
            }, function() {
              alert("Not a valid zip file")
            });
};

The catch response is:

Error: no layers founds

When I upload the same exact ZIP to your local example, it works like a charm.

On the other hand, when I save the file in a subfolder, and load it from there:

      shp('assets/files/test.zip').then(function(geojson){
        callback(geojson);
        })
        .catch(function (response) {
        console.log(response);
      });

The response I have is:

TypeError: coordinates must be finite numbers

Any help will be really appreciated.

Thanks,

Anexo commented 5 years ago

Ok, I have been doing some tests, and I am able to load the shp, when saving it to a local folder:

     shp('assets/files/test.zip').then(function(geojson){
        leafletData.getMap().then(function(map) {
          L.geoJson(geojson, {
              style: function (feature) {
                  return {color: feature.properties.color};
              },
              onEachFeature: function (feature, layer) {
                  layer.bindPopup(feature.properties.description);
              }
            }).addTo(map);
          });
        })
        .catch(function (response) {
        console.log(response);
      });

Now, when I try to upload that exact same file, I catch the error: Error: no layers founds

    self.importShapefile = function(){
        var x = document.getElementById("shapefile-uploader");
        var zip = new JSZip();
        zip.loadAsync( x.files[0] )
            .then(function(zip) {
                shp(zip).then(function(geojson){
                    leafletData.getMap().then(function(map) {
                      L.geoJson(geojson, {
                          style: function (feature) {
                              return {color: feature.properties.color};
                          },
                          onEachFeature: function (feature, layer) {
                              layer.bindPopup(feature.properties.description);
                          }
                        }).addTo(map);
                      });
                })
                .catch(function (response) {
                  console.log(response);
                });
              }, function() {
              alert("Not a valid zip file")
        });
   };

Any ideas?

calvinmetcalf commented 5 years ago

you don't need to unzip the file, all you need to do is is grab the file as an array buffer and pass it to shp

so if you have a function

const fileToArrayBuffer = files => new Promise((resolve, reject) => {
  var reader = new FileReader();
  reader.onload = ()=>{
    resolve(reader.result);
  };
  reader.onerror = reject;
  reader.readAsArrayBuffer(files.files[0]);
});

you can do

var x = document.getElementById("shapefile-uploader");
fileToArrayBuffer(x).then(zip).then(layers => {
   // do your thing
})
Anexo commented 5 years ago

Great! Thanks, this helped a lot, now it is working!