Open heshan0131 opened 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?
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
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).
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.
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}
/>
}
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
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.
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.
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.
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
.
@heshan0131 @macrigiuseppe I will start work on this Monday to meet an internal deadline. Would like to hear your feedback.
Hi everyone, What's the current status of this?
Thanks.
@ricardoekm priorities changed for my team. I will probably not finish this one.
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 toKeplerGl
.layerGroups
properties are used to toggle layer visibilities in the map layers panel. A working examples atopen-map-tiles
branchconst 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
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.
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
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
Allow a user to upload a Mapbox style J (with links to custom tile server)
Dynamically request tile-based data