How to display a huge GeoJSON file to the MapBox?
Asked Answered
W

3

6

I'm new in MapBox GL Js and I want to call a big GeoJSON file over https and display it to the map. I think that calling vector Tile is the best way to do that, I found some tutorials that show how to convert your GeoJSON data to Vector Tile but on Server Side or upload it to the MapBox Style but my GeoJSON file is frequently changing. So I found this solution is a new JavaScript library called geojson-vt, describing how to convert a huge GeoJSON files to vector tile on the fly (Client Side) with crazy fast, It's seems like what I'm looking for, BUT !!, How can I integrate it to the MapBox GL JS for calling the layer ??

Blocking on How can I add Layer using Mapbox GL JS with the following result : var tileIndex = geojsonvt(MyGeoJSON); var tile = tileIndex.getTile(z, x, y);

... Or I just didn't get it ! Please somebody helps or can propose some other solution for my problem.

Wednesday answered 21/4, 2020 at 11:13 Comment(0)
A
1

You don't need to worry about geojson-vt. Mapbox-GL-JS does that internally. So you can just follow the standard documentation for loading a GeoJSON layer.

If your GeoJSON is really huge, then probably the limiting factor will be network transfer, which means you really need to be serving server-side vector tiles.

Atomics answered 22/4, 2020 at 13:23 Comment(8)
Thank you Steve your're right geojson-vt already include in Mapbox-GL-JS. But my problem is still persis. The size of GeoJSON file is like 0.5GB loading it to the map as layer make my browser freezing. So I server it from my GeoServer like a Vector layer (WMTS) but it still so slow.Then I saw that solution converting a GeoJSON(761Mb) file to a MBTiles(4.7Mb) file then upload it BUT the problem is my Data is changing every minute. Is there any other solution or some suggestion please share it with me.Wednesday
Yep, 500MB is too big. There are obviously many possible solutions, but that's a bit too broad for a StackOverflow question. Generally they involve server-side solutions. You might be better off asking at gis.stackexchange.comAtomics
There's also commercial providers of server-side tiling like CARTO: carto.com/developers/carto-js/examples/…Mantelpiece
Or, um, Mapbox.Atomics
Hey @ElkadiriImad, i am facing the same issue. i need to render a huge geojson file in mapbox and it freezes my browser. Did you find any solution for that? Thanks, DanielaMachinegun
Don't load the geojson directly into the browser. Generate vector tiles and host them somewhere such as Mapbox, Maptiler Cloud, etc.Atomics
Hey @Machinegun sorry for the late reply... No need to load all the GeoJSON file.. For my case I transfet the file into a table in Database then I configure the wabservice (GeoServer) to read from this table finally i call the Geometry and it alphanumeric from MapBox via the webservice in a Vector Tiles Format. Hope this will help you !Wednesday
@ElkadiriImad I am wondering how fast it is when connecting it with GeoServer. On your above comment, what do you mean by alphanumeric from MapBox?Ponytail
M
1

I'd recommend using Deck.gl GeoJSON Layer. Here's an example:

<html>
  <head>
    <title>deck.gl GeoJsonLayer (Polygon) Example</title>

    <script src="https://unpkg.com/deck.gl@^8.0.0/dist.min.js"></script>
    <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.4.0/mapbox-gl.js"></script>

    <style type="text/css">
      body {
        width: 100vw;
        height: 100vh;
        margin: 0;
        overflow: hidden;
      }
      .deck-tooltip {
        font-family: Helvetica, Arial, sans-serif;
        padding: 6px !important;
        margin: 8px;
        max-width: 300px;
        font-size: 10px;
      }
    </style>
  </head>

  <body>
  </body>

  <script type="text/javascript">

    const {DeckGL, GeoJsonLayer} = deck;

    const COLOR_SCALE = [
      // negative
      [65, 182, 196],
      [127, 205, 187],
      [199, 233, 180],
      [237, 248, 177],

      // positive
      [255, 255, 204],
      [255, 237, 160],
      [254, 217, 118],
      [254, 178, 76],
      [253, 141, 60],
      [252, 78, 42],
      [227, 26, 28],
      [189, 0, 38],
      [128, 0, 38]
    ];

    const geojsonLayer = new GeoJsonLayer({
      data: 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/geojson/vancouver-blocks.json',
      opacity: 0.8,
      stroked: false,
      filled: true,
      extruded: true,
      wireframe: true,

      getElevation: f => Math.sqrt(f.properties.valuePerSqm) * 10,
      getFillColor: f => colorScale(f.properties.growth),
      getLineColor: [255, 255, 255],

      pickable: true
    });

    new DeckGL({
      mapboxApiAccessToken: '<mapbox-access-token>',
      mapStyle: 'mapbox://styles/mapbox/light-v9',
      initialViewState: {
        latitude: 49.254,
        longitude: -123.13,
        zoom: 11,
        maxZoom: 16,
        pitch: 45
      },
      controller: true,
      layers: [geojsonLayer],
      getTooltip
    });

    function colorScale(x) {
      const i = Math.round(x * 7) + 4;
      if (x < 0) {
        return COLOR_SCALE[i] || COLOR_SCALE[0];
      }
      return COLOR_SCALE[i] || COLOR_SCALE[COLOR_SCALE.length - 1];
    }

    function getTooltip({object}) {
      return object && `Average Property Value
        ${object.properties.valuePerSqm}
        Growth
        ${Math.round(object.properties.growth * 100)}`;
    }

  </script>
</html>

Atrribution here.

Mantelpiece answered 21/4, 2020 at 19:55 Comment(6)
I haven't used Deck GL with Mapbox before. What are the benefits of using a DeckGL GeoJSON layer as opposed to the native Mapbox-GL-JS GeoJSON source and fill layer?Atomics
One of the reasons would be: For example, a deck.gl GeoJSON layer can be inserted in between Mapbox’s base geography and label layers, so that filled polygons no longer hamper readability of the map. More at eng.uber.com/uber-visualization-mapboxMantelpiece
You can do that with native Mapbox-GL-JS layers too?Atomics
Not sure. AFAIK the GL-JS layers are essentially a subset of what deck is capable of. I use deck mostly w/ gmaps, not mapbox, and there's no "native" option there.Mantelpiece
So Deck GL can display a 500MB as asked by OP ?Montevideo
That's an open-ended question that depends mostly on the browser: deck.gl/docs/developer-guide/performanceMantelpiece
A
1

You don't need to worry about geojson-vt. Mapbox-GL-JS does that internally. So you can just follow the standard documentation for loading a GeoJSON layer.

If your GeoJSON is really huge, then probably the limiting factor will be network transfer, which means you really need to be serving server-side vector tiles.

Atomics answered 22/4, 2020 at 13:23 Comment(8)
Thank you Steve your're right geojson-vt already include in Mapbox-GL-JS. But my problem is still persis. The size of GeoJSON file is like 0.5GB loading it to the map as layer make my browser freezing. So I server it from my GeoServer like a Vector layer (WMTS) but it still so slow.Then I saw that solution converting a GeoJSON(761Mb) file to a MBTiles(4.7Mb) file then upload it BUT the problem is my Data is changing every minute. Is there any other solution or some suggestion please share it with me.Wednesday
Yep, 500MB is too big. There are obviously many possible solutions, but that's a bit too broad for a StackOverflow question. Generally they involve server-side solutions. You might be better off asking at gis.stackexchange.comAtomics
There's also commercial providers of server-side tiling like CARTO: carto.com/developers/carto-js/examples/…Mantelpiece
Or, um, Mapbox.Atomics
Hey @ElkadiriImad, i am facing the same issue. i need to render a huge geojson file in mapbox and it freezes my browser. Did you find any solution for that? Thanks, DanielaMachinegun
Don't load the geojson directly into the browser. Generate vector tiles and host them somewhere such as Mapbox, Maptiler Cloud, etc.Atomics
Hey @Machinegun sorry for the late reply... No need to load all the GeoJSON file.. For my case I transfet the file into a table in Database then I configure the wabservice (GeoServer) to read from this table finally i call the Geometry and it alphanumeric from MapBox via the webservice in a Vector Tiles Format. Hope this will help you !Wednesday
@ElkadiriImad I am wondering how fast it is when connecting it with GeoServer. On your above comment, what do you mean by alphanumeric from MapBox?Ponytail
E
0

Oh, man, I've spent 8 days, researching that. The solution is:

var vtpbf = require('vt-pbf');
var geojsonVt = require('geojson-vt');

var orig = JSON.parse(fs.readFileSync(__dirname + 'myjson.json'))
var tileindex = geojsonVt(orig)
var tile = tileindex.getTile(x, y, z); // mapbox sends automatic request to the server, and give x, y , z

// pass in an object mapping layername -> tile object
var buff = vtpbf.fromGeojsonVt({ 'geojsonLayer': tile });

I've sent the result to the frontend, it works like Mapbox API. For the details check: https://github.com/mapbox/vt-pbf

And from the Mapbox side:

            const  source = {
                type    : 'vector',
                'tiles' : [ 'http://localhost:1234/county?z={z}&x={x}&y={y}' ],
                minzoom : 0,
                maxzoom : 14
            };

            map.addSource('source', source );
            map.addLayer({
                'id'           : 'source',
                'type'         : 'fill',
                'source'       : 'source',
                'source-layer' : 'tiles-sequences',
                'fill-color'   : '#00ffff'
            });
Einsteinium answered 22/1, 2021 at 16:12 Comment(1)
Please, could you send a bit longer example of the server side part?Willingham

© 2022 - 2024 — McMap. All rights reserved.