kepler.gl icon indicating copy to clipboard operation
kepler.gl copied to clipboard

Adding OGC Base Maps from other endpoints (ArcGIS, & Open Standard)

Open benwah92 opened this issue 3 years ago • 12 comments

Problem Statement Currently kepler.gl is a powerful and light geospatial application, however cannot be utilised without a MapBox service. This means that the application is only usable in situation where an internet connection can be established. Not being able to access base maps from other service endpoints limits potential use cases where a user might want customised base mapping sourced from a variety of locations (locally from the machine or potentially from a different cloud-based server or instance).

Proposed Solution The functionality to set base mapping layers from different endpoints (not just MapBox) and also through the python module for kepler.gl would extend kepler.gl functionality to operate across disconnected or isolated network instances and also allow for different user experiences with custom foundation layers.

Current Alternatives Currently I use folium/leaflet which lacks the geo analytics and user experience of kepler.gl but can support OGC and ArcGIS web mapping layer inputs. I work for a company that hosts custom isolated layer services due to being regularly disconnected. Currently our only other option is to use expensive enterprise GIS solutions which are overkill but can consume the services that are currently hosted.

benwah92 avatar Mar 09 '21 04:03 benwah92

Hello @yobimania, you can have custom mapstyle that can be located on your machine or cloud-service. You can find the doc here: https://docs.kepler.gl/docs/user-guides/f-map-styles

macrigiuseppe avatar Mar 19 '21 20:03 macrigiuseppe

@macrigiuseppe map styles are not what I am after here. This module does not work independently from MapBox. That link to the description above will only work with MapBox services. Having the ability to add services from "Anything other than MapBox" is what I am looking for.

benwah92 avatar Mar 21 '21 01:03 benwah92

kepler.gl uses mapbox-gl.js to render base map, it is not a Mapbox service. The default base maps are mapbox base maps. if you don't need mapbox hosted base maps, you can pass in custom map STYLES that are written in a JSON format called the Mapbox GL Style Spec.

Your Style Spec can points to your own vector tile server described in the sources field.

For example. when I paste the URL to my own style.json: https://raw.githubusercontent.com/heshan0131/kepler.gl-data/master/style/basic.json into the custom map style field, kepler.gl can render the map independent of mapbox vector tile service. it loads tiles from https://api.maptiler.com instead.

Screen Shot 2021-03-20 at 6 34 36 PM Screen Shot 2021-03-20 at 6 37 17 PM

And you can see in the style.json, the source is

  "sources": {
    "openmaptiles": {
      "url": "https://api.maptiler.com/tiles/v3/tiles.json?key=kznYvrAC6DrOZXPCW05C",
      "type": "vector"
    },
    "maptiler_attribution": {
      "type": "vector",
      "attribution": "<a href=\"https://www.maptiler.com/copyright/\" target=\"_blank\">&copy; MapTiler</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">&copy; OpenStreetMap contributors</a>"
    }
  },

If you are using the kepler.gl library, you pass style to mapStyles

heshan0131 avatar Mar 21 '21 01:03 heshan0131

https://github.com/keplergl/kepler.gl/pull/1440

heshan0131 avatar Mar 22 '21 04:03 heshan0131

https://github.com/keplergl/kepler.gl/pull/1440

Thank you for the demo and comments above - this is very useful and clears up confusion on my end!

benwah92 avatar Mar 22 '21 05:03 benwah92

Did this resolve your issue?

chrisgervang avatar Apr 25 '21 20:04 chrisgervang

Did this resolve your issue?

@chrisgervang, I have not been able to get it to work. For example, here is a WMTS service (https://services.ga.gov.au/gis/rest/services/NationalBaseMap/MapServer/WMTS/1.0.0/WMTSCapabilities.xml) that I would theoretically like to use as a base map. I cannot get the configuration correct to display the base map.

benwah92 avatar Apr 26 '21 10:04 benwah92

Is there a way to add custom maps styles programmatically for the kepler.gl jupyter widget? The Kepler.gl for Jupyte User Guide does not mention how to add custom map styles. I am looking for a way to add some XYZ/WMS tile services to the map using Python.

giswqs avatar Aug 03 '21 19:08 giswqs

Is there a way to add custom maps styles programmatically for the kepler.gl jupyter widget? The Kepler.gl for Jupyte User Guide does not mention how to add custom map styles. I am looking for a way to add some XYZ/WMS tile services to the map using Python.

You can add custom map style using the config object. The best way to do this is to first adding a custom map style json using the add map style UI, once added, copy the config as dict object, then save the config.mapStyle object, and use it in

config = {

  version: 'v1',
  config: {
    mapStyle: {
     ...
    }
  }
}

heshan0131 avatar Sep 13 '21 08:09 heshan0131

Could you please provide an example on that?

ferreteleco avatar Feb 20 '22 19:02 ferreteleco

@ferreteleco I can attest that @heshan0131 's above solution seems to display custom tiles within my python 3.9 jupyterlab notebook.

(Sorry for clunky code pasting; first time in a looong time contributing.) `

This displays the default carto dark map in the next cell of the notebook

import keplergl m = keplergl.KeplerGl(height=750) m `

`

after instantiating m, before adding heshan's custom style url

m.config['config']['mapStyle']

returns:

{'styleType': 'dark', 'topLayerGroups': {}, 'visibleLayerGroups': {'label': True, 'road': True, 'border': False, 'building': True, 'water': True, 'land': True, '3d building': False}, 'threeDBuildingColor': [9.665468314072013, 17.18305478057247, 31.1442867897876], 'mapStyles': {}} `

`

after adding heshan's custom style url

m.config['config']['mapStyle']

returns:

{'styleType': '23mu7n', 'topLayerGroups': {}, 'visibleLayerGroups': {'label': True, 'road': True, 'building': True, 'water': True, 'land': True}, 'threeDBuildingColor': [208.57758098124364, 208.57758098124364, 193.67918233972625], 'mapStyles': {'23mu7n': {'accessToken': None, 'custom': True, 'icon': 'https://api.mapbox.com/styles/v1/https://raw.githubusercontent.com/heshan0131/kepler.gl-data/master/style/basic.json/static/-122.3391,37.7922,9,0,0/400x300?access_token=pk.eyJ1IjoidWNmLW1hcGJveCIsImEiOiJja3RpeXhkaXcxNzJtMnZxbmtkcnJuM3BkIn0.kGmGlkbuWaCBf7_RrZXULg&logo=false&attribution=false', 'id': '23mu7n', 'label': 'Basic', 'url': 'https://raw.githubusercontent.com/heshan0131/kepler.gl-data/master/style/basic.json'}}} `

Then following the guide's instructions, you can instantiate your basic map with `

option 1; of course you could dump m.config to a json file, then load back in

n = kepler.KeplerGl(config=m.config)

option 2

n = kepler.KeplerGl() n.config = m.config

then n.add_data, etc...

`

Hope this helps!

osterm38 avatar Mar 17 '22 07:03 osterm38

Seconded, thanks @heshan0131! I used the ArcGIS basemap layer services and grabbed the JSON for the basemap I wanted, added it to my map using the UI, then saved the config as a JSON.

cgpeltier avatar Jul 25 '23 16:07 cgpeltier