calvinmetcalf / leaflet.shapefile

Shapefile in Leaflet
http://calvinmetcalf.github.io/leaflet.shapefile/
MIT License
259 stars 119 forks source link

unzip throwing exception #46

Open softsprocket opened 7 years ago

softsprocket commented 7 years ago

I'm using zipped shapefiles loaded from dronedeploy and passing an arraybuffer to leaflet.shapefile. I'm working on three projects. One succeeds but two don't I traced into shape and found this being throw by unzip: RangeError: Maximum call stack size exceeded at utf8Slice (http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:1029:30) at Uint8Array.slowToString (http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:710:16) at Uint8Array.toString (http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:739:23) at Object.utf8decode (http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:3984:53) at Object.utf8decode (http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:3590:21) at ZipObject.dataToString (http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:2788:22) at ZipObject.asText (http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:2835:29) at http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:320:20 at Array.forEach (native) at module.exports (http://localhost:1841/js/leaflet1/shp.js?_dc=1497547765872:315:8)

The line numbers won't mean much since I put some debugging in. I can download the zip file and drag it onto your test project and it works. I wondered if it's a size issue but the failed files give: ArrayBuffer returned 12228250 ArrayBuffer returned 1882584

and the successful on: ArrayBuffer returned 6531249

Only the successful one fires 'data:loaded' of course.

My code:

`var corsRequest = new Request (exp.download_path, init);

fetch (corsRequest).then (function (response) {
    return response.arrayBuffer ();
}).then (function (arrayBuffer) {
    console.log ('ArrayBuffer returned', arrayBuffer.byteLength);

    var shapeLayer = new L.Shapefile(arrayBuffer, {
        onEachFeature: function (feature, layer) {
            if (min == undefined) {
                min = feature.properties.elevation
            }

            if (max == undefined) {
                max = feature.properties.elevation
            }

            min = min < feature.properties.elevation ? min : feature.properties.elevation;
            max = max > feature.properties.elevation ? max : feature.properties.elevation;

            layer.bindPopup (Object.keys (feature.properties).map (function (k) {
                return k + ": " + feature.properties[k];
            }).join("<br/>"), {
                maxHeight: 200
            });

        },

        style: function(feature) {
            var num = Math.floor (Number (feature.properties.elevation) + 100);
            num = num / 200;
            var r = Math.floor (num * 255);
            var g = Math.floor (num * 255);
            var b = Math.floor (num * 255);
            return { color: 'rgba(' + r.toString () + ',' + g.toString () + ',' + b.toString () + ',' + 0.6 + ')' };
        },

        filter: function (feature, layer) {
            return feature.properties.ID % 4 == 0;
        }
    });

    shapeLayer.addTo (this.map);

    shapeLayer.once ('data:loaded', function () {                           
        console.log ('BOUNDS', shapeLayer.getBounds().isValid());                       
        console.log (arguments);
    });
}.bind (this));

`

softsprocket commented 7 years ago

HorshoeBa_ElevationToolbox_WedJun14163538.zip One of the zip files that fails. I can unzip it with zip.js and am trying to hack my away around jszip at the moment.

softsprocket commented 7 years ago

All that said the solution was to modify unzip thusly:

` var JSZip = require('jszip'); module.exports = function(buffer) { var zip = new JSZip(buffer); var files = zip.file(/.+/);

var out = {};
files.forEach(function(a) {
    if (a.name.slice(-3).toLowerCase() === 'shx') { return out; }
    if (a.name.slice(-3).toLowerCase() === 'shp' || a.name.slice(-3).toLowerCase() === 'dbf') {
        out[a.name] = a.asArrayBuffer();
    }
    else {
        out[a.name] = a.asText();
    }
});
return out;

};

`

calvinmetcalf commented 7 years ago

I'm not sure I understand your fix

softsprocket commented 7 years ago

On some loads the *.shx file would result in an exception. They were being processed by a.asText() (they are binary). The fix just ignores them. A better fix might be: if (a.name.slice(-3).toLowerCase() === 'shp' || a.name.slice(-3).toLowerCase() === 'dbf') { out[a.name] = a.asArrayBuffer(); } else if (a.name.slice(-3).toLowerCase() === 'prj' { out[a.name] = a.asText(); }

thereby ignoring all files not required.

calvinmetcalf commented 7 years ago

yeah it think I switched it when we started handling cpg files, I should be able to fix it monday

On Fri, Jun 16, 2017 at 12:08 PM softsprocket notifications@github.com wrote:

On some loads the *.shx file would result in an exception. They were being processed by a.asText() (they are binary). The fix just ignores them. A better fix might be: if (a.name.slice(-3).toLowerCase() === 'shp' || a.name.slice(-3).toLowerCase() === 'dbf') { out[a.name] = a.asArrayBuffer(); } else if (a.name.slice(-3).toLowerCase() === 'prj' { out[a.name] = a.asText(); }

thereby ignoring all files not required.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/calvinmetcalf/leaflet.shapefile/issues/46#issuecomment-309067234, or mute the thread https://github.com/notifications/unsubscribe-auth/ABE4n1G_qFApklp3gWbAOIXiIaEnGRF8ks5sEqiIgaJpZM4N7iJV .