keplergl / kepler.gl

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

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

Open benwah92 opened 3 years ago

benwah92 commented 3 years ago

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.

macrigiuseppe commented 3 years ago

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

benwah92 commented 3 years ago

@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.

heshan0131 commented 3 years ago

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 commented 3 years ago

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

benwah92 commented 3 years ago

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!

chrisgervang commented 3 years ago

Did this resolve your issue?

benwah92 commented 3 years ago

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.

giswqs commented 3 years ago

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.

heshan0131 commented 3 years ago

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: {
     ...
    }
  }
}
ferreteleco commented 2 years ago

Could you please provide an example on that?

osterm38 commented 2 years ago

@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!

cgpeltier commented 1 year ago

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.