LoginSignup
2
4

More than 1 year has passed since last update.

Leaflet.VectorGrid で GeoJSON データの読み込み

Last updated at Posted at 2018-02-02

こんにちは。
Leaflet.VectorGrid というものを見つけたので GeoJSON データの読み込みを試してみました(us-mapscounty.geo.json (195.67 MB))1。ただし最終段階が遅いことが気になり(下記)、Many Polygons with geojson-vt on Leaflet に比べると、数倍遅い感触です。

loading county.geo.json 1325 ms
parsing 195.67 MB 9515 ms
indexing 3221 features
with 7384329 vertexes and 0 points
adding to map 17426 ms

counties.png

leaflet_vectorgrid.html
<!DOCTYPE html>
<html>
<head>
    <title>Leaflet.GridLayer.Vector.Slicer</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.0/dist/leaflet.css">
    <script src="https://unpkg.com/leaflet@1.3.0/dist/leaflet.js"></script>
    <script src="https://unpkg.com/leaflet.vectorgrid@1.3.0"></script>
    <script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js"></script>
</head>
<body style='margin:0'>
    <div id="map" style="width: 100vw; height: 100vh"></div>
    <script>
    var map = L.map('map');
    var dropArea = document.getElementById('map');

    var CD_URL = 'http://{s}.basemaps.cartocdn.com/{style}/{z}/{x}/{y}.png';
    var CD_ATTR = '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a>';

    L.tileLayer( CD_URL, {
                attribution: CD_ATTR,
                style: 'light_nolabels',
                opacity: 1
                }).addTo(map);
    L.control.scale().addTo(map);
    map.setView({lat:0, lng:0}, 2);

    dropArea.ondragover = function () {
        return false;
    };
    dropArea.ondragend = function () {
        return false;
    };
    dropArea.ondrop = function (e) {
        var reader = new FileReader();
        var file = e.dataTransfer.files[0];
        reader.readAsText(file, 'utf-8');
        var start = new Date().getTime();
        reader.onload = function (event) {
            var elapsed = new Date().setTime(new Date().getTime() - start);
            console.log(`loading ${file.name} ${elapsed} ms`);
            try {
                var result = event.target.result;
                start = new Date().getTime();
                var data = JSON.parse(result);
                elapsed = new Date().setTime(new Date().getTime() - start);
                console.log(`parsing ${humanDataSize(result.length)} ${elapsed} ms`);
                var vertCount = countVertex(data);
                start = new Date().getTime();
                console.log(`indexing ${data.features.length} features`);
                console.log(`with ${vertCount[0]} vertexes and ${vertCount[1]} points`);
                addGeojsonData(data);
                elapsed = new Date().setTime(new Date().getTime() - start);
                console.log(`adding to map ${elapsed} ms`);
            } catch (err) {
                console.log(`${err}`);
            }
        };
        e.preventDefault();
        return false;
    };


    function bboxLeaflet(geojson) {
        var bb = turf.bbox(geojson);
        return [[bb[1], bb[0]], [bb[3], bb[2]]];
    }

    function humanDataSize(size) {
        var i = Math.floor(Math.log(size) / Math.log(1024));
        var siz = [size / Math.pow(1024, i), ['B', 'kB', 'MB', 'GB', 'TB'][i]];
        siz[0] = Math.round(siz[0]*100)/100;
        return siz.join(' ');
    }

    function countVertex(data) {
        var len, coords, counter = [0,0];            
        for (var i = data.features.length - 1; i >= 0; i--) {
            coords = data.features[i].geometry.coordinates;
            len = coords[0].length;
            if (len) {
                counter[0] += len;
            } else {
                counter[1] += 1;
            }
        }
        return counter;
    }

    function addGeojsonData(data) {
        map.fitBounds(bboxLeaflet(data));
        var vectorGridLayer = L.vectorGrid.slicer( data, {
            rendererFactory: L.svg.tile,
            maxZoom: 20,
            interactive: true,
            vectorTileLayerStyles: {
                sliced: function(properties, zoom) {
                    return {
                        fillColor: "yellow",
                        fillOpacity: 0.5,
                        stroke: true,
                        fill: true,
                        color: 'blue',
                        weight: 0.7,
                    }
                }
            },
        })
        .addTo(map);
    }
    </script>
</body>
</html>
2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4