keplergl / kepler.gl

Kepler.gl is a powerful open source geospatial analysis tool for large-scale data sets.
http://kepler.gl
MIT License
10.4k stars 1.74k forks source link

Allow loading base map tiles from a custom tile server #406

Open heshan0131 opened 5 years ago

heshan0131 commented 5 years ago
robert-claypool commented 5 years ago

I could probably implement this, however I need Kepler to show custom tiles in addition to the standard base map.

My use case is to show (1) an already available base map such as Mapbox Muted Night and (2) map tiles from a custom tile server layered on top. The custom tiles aren't really a "base map". They are reference layers such as electric power lines, transformers, and poles.

If I issue a PR for this feature, I would like to include custom tile server support plus whatever UI is needed to toggle visibility of the custom tiles independent of the base map. Thoughts?

heshan0131 commented 5 years ago

Sounds good. Before implementation, we usually write an RFC (Request For Comment), stating implementation details so that people have an idea of the related engineering details. You can append the RFC by replying in this thread

homme commented 5 years ago

Could this be generalised further so that the UI can be used to swap out the base map completely? I.e Mapbox Muted Night is the default but you can add other basemaps (from custom tile servers) with the option of toggling visibility on any of those basemap layers (including the default).

cekali commented 5 years ago

My use case is nearly identical to @robert-claypool's. I would need the ability to add several tile layers on top of the base layer. I am currently using TileServer GL, incase that information helps.

heshan0131 commented 5 years ago

if you are using kepler.gl in your own app, kepler.gl actually supports custom vector map tiles under-the-hood. As long as your map styles is using Mapbox GL Style Specification

To do that, pass in mapStyles as an array to KeplerGl. layerGroups properties are used to toggle layer visibilities in the map layers panel. A working examples at open-map-tiles branch

const OpenMapTilesStyles = [
  {
    id: 'open_map_tile_styles',
    label: 'Positron',
    type: 'vector',
    url: 'https://api.maptiler.com/maps/positron/style.json?key=your
_key',
    icon: 'https://cloud.maptiler.com/static/img/maps/positron.png?t=1555336586',
    layerGroups: [
      {
        slug: 'label',
        filter: ({id}) => id.match(/(?=(label|place_))/),
        defaultVisibility: true
      },
      {
        slug: 'road',
        filter: ({id}) =>
          id.match(/(?=(road|railway|tunnel|street|bridge|highway))(?!.*label)/),
        defaultVisibility: true
      },
      {
        slug: 'border',
        filter: ({id}) => id.match(/border|boundaries/),
        defaultVisibility: false
      },
      {
        slug: 'building',
        filter: ({id}) => id.match(/building/),
        defaultVisibility: true
      },
      {
        slug: 'water',
        filter: ({id}) => id.match(/(?=(water|stream|ferry))/),
        defaultVisibility: true
      },
      {
        slug: 'land',
        filter: ({id}) =>
          id.match(/(?=(parks|park|landcover|industrial|sand|hillshade))/),
        defaultVisibility: true
      }
    ]
  }
];

\\ App.js
   render() {
        <KeplerGl
          mapboxApiAccessToken={MAPBOX_TOKEN}
          id="map"
          mapStyles={OpenMapTilesStyles}
          width={width}
          height={height}
        />
   }
heshan0131 commented 5 years ago

However, if you want to add custom map tiles through an UI in the kepler.gl app, you are right, we need to modify the currently add custom map popup ui a little bit to allow adding custom vector tiles

robert-claypool commented 5 years ago

Finally, I think I have bandwidth to tackle this. @heshan0131, my main goal is to see multiple Mapbox Styles and control the order they are rendered -- e.g. 'Water Utility Assets' need to show on top of 'Muted Night'.

Here's a mockup.

keplergl-basemaps-mockup-2

  1. User can reorder the map styles in a drag-and-drop action, see https://github.com/atlassian/react-beautiful-dnd -- or even easier, we show ▲ and ▼ clickable arrows to reorder styles; that would need fewer dependencies.

  2. User can click a Mapbox Style (like 'Water Utility Assets') to make it active. When this happens, the Layers list will show layer groups for that selected style. Note that 'Muted Night' is the selected style in my mockup above.

  3. Eventually I want to add a "Selectable" icon to layer groups that would support it. Making a layer selectable would allow an attributes popup to open on click (ArcGIS calls this "Identify"). I think that would solve #623, but we would probably need some way to customize the resulting popup too.


I've started digging into code to see what I'm up against. It doesn't look easy! The structure of mapStyle would need to change, and I don't yet understand the purpose of properties like bottomMapStyle and topMapStyle.

robert-claypool commented 5 years ago

@heshan0131 @macrigiuseppe I will start work on this Monday to meet an internal deadline. Would like to hear your feedback.

ricardoekm commented 4 years ago

Hi everyone, What's the current status of this?

Thanks.

robert-claypool commented 4 years ago

@ricardoekm priorities changed for my team. I will probably not finish this one.

ALIRAZA705 commented 4 years ago

if you are using kepler.gl in your own app, kepler.gl actually supports custom vector map tiles under-the-hood. As long as your map styles is using Mapbox GL Style Specification

To do that, pass in mapStyles as an array to KeplerGl. layerGroups properties are used to toggle layer visibilities in the map layers panel. A working examples at open-map-tiles branch

const OpenMapTilesStyles = [
  {
    id: 'open_map_tile_styles',
    label: 'Positron',
    type: 'vector',
    url: 'https://api.maptiler.com/maps/positron/style.json?key=your
_key',
    icon: 'https://cloud.maptiler.com/static/img/maps/positron.png?t=1555336586',
    layerGroups: [
      {
        slug: 'label',
        filter: ({id}) => id.match(/(?=(label|place_))/),
        defaultVisibility: true
      },
      {
        slug: 'road',
        filter: ({id}) =>
          id.match(/(?=(road|railway|tunnel|street|bridge|highway))(?!.*label)/),
        defaultVisibility: true
      },
      {
        slug: 'border',
        filter: ({id}) => id.match(/border|boundaries/),
        defaultVisibility: false
      },
      {
        slug: 'building',
        filter: ({id}) => id.match(/building/),
        defaultVisibility: true
      },
      {
        slug: 'water',
        filter: ({id}) => id.match(/(?=(water|stream|ferry))/),
        defaultVisibility: true
      },
      {
        slug: 'land',
        filter: ({id}) =>
          id.match(/(?=(parks|park|landcover|industrial|sand|hillshade))/),
        defaultVisibility: true
      }
    ]
  }
];

\\ App.js
   render() {
        <KeplerGl
          mapboxApiAccessToken={MAPBOX_TOKEN}
          id="map"
          mapStyles={OpenMapTilesStyles}
          width={width}
          height={height}
        />
   }

map i have a question from this one ? i am looking fro this from 2 days thanks alot for this one ... .. map my question is i want to use my own map layer in kepler . its working fine when i do this with keppler pannel but i don't want to show keppler pannel so i want to use map styles through code how can i do that

kylebarron commented 4 years ago

This is already possible. I tried it out on the public kepler.gl demo instance; at Base Map > Add Map Style > Paste Style Url, you can just paste a URL to a style.json file describing your basemap.

I pasted a URL to a custom OpenMapTiles-derived base map of mine, and it switched to it as the basemap. image

That said, it looks like for some reason kepler.gl doesn't support the entire Mapbox GL style spec? When trying to load

https://raw.githubusercontent.com/nst-guide/osm-liberty-topo/gh-pages/style.json

as the basemap, I get console errors like

sources.terrarium.tiles: array expected, undefined found

However the source style.json is a valid Mapbox style, and this same style renders fine elsewhere using react map gl.

> gl-style-validate style.json
# No errors
kziovas commented 3 years ago

Hello any news on this. as @kylebarron said it might be possible to pass style.json files directly to kepler ui app BUT it doesn't support of mapbox gl specs! If you try to use a custom tiles server whcih dynamically serves tiles it does nto work. I want to use OpenSeaMap nautical maps in kepler but currently there is no way to doit. I can get the tile server from OpenSeaMap and it work with MapBox GL JS but it does not work with custom style.json in kepler. This is my style.json : https://raw.githubusercontent.com/kziovas/open-sea-map-basemap-mapbox-files/main/style.json