Loading geo assets offline [Solved]

I know this is marked as solved, but since I had a similar issue with trying to do this with Dash, and this is the first link that shows up, I thought I’d share my solution

after trying to figure out how to host the files locally, having some iptables or /etc/hosts
change that forwarded to my local machine, I eventually tried the “hack” of modifiying the topojsonURL config in my local plotly.min.js file suggest here. However that still didn’t work. I kept getting the same error about not being able to load the file from https://cdn.plot.ly/ even though I overwrote topojsonURL in plotly.min.js, and debugging the minified file was crashing my Chrome instance.

My hunch was that it was being set by something else, and sure enough, after searching a bit in
the dash files there was another reference to topojsonURL in dcc.Graph

I checked the documentation, and there was a mention of:
- topojsonURL (string; optional): URL to topojson files used in geo charts
So I passed that to the config of dcc.Graph and it worked well!

The following is a simple working example for anyone who is trying to get the ‘native’ maps to work offline (mapbox of course requires an online connection or a local instance, but since a lot of the features that make it powerful in my opinion - layers with heatmaps for example- are not yet supported, it’s not clear if it’s worth using mapbox vs. the native maps for my application.)

import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash(meta_tags = 
                [{'name':"viewport", 'content':"width=device-width, initial-scale=1"}])

portnumber=5500

# Can be passed as argument to application, automatically determined, etc.
offline = True

app.css.config.serve_locally = offline
app.scripts.config.serve_locally = offline

#Here we assume that the appropriate topoJson files (world_110m.json, world_50m.json, etc.)
#normally hosted on https://cdn.plot.ly/ are available under ./assets
plotlyConfig = {'topojsonURL':'http://127.0.0.1:%i/assets/'%portnumber} if offline else {}


data  = [ dict(
        type = 'scattergeo',
        text=['A', 'B', 'C'],
        lon=['-122', '35', '170'],
        lat=['37', '-24', '-37'], 
        mode='markers+text+lines',
        marker=dict(size=5),
        textfont=dict(size=12),
        hoverinfo='none',
) ]

layout = dict(
            width=800, height=400,
            geo = dict(
                projection=dict( type='natural earth' , scale=1),
                framewidth = 1,
                showland = True, showlakes = True, showocean=True, showcountries=True,
                landcolor = 'rgb(204, 204, 204)',
                oceancolor= 'rgb(145, 191, 219)',
                countrycolor = 'rgb(128, 128, 128)',
                lakecolor = 'rgb(145, 191, 219)',
                countrywidth = 0.5,
                subunitwidth = 0.5,
                coastlinewidth = 1,
                resolution = 75,
                center = dict(lat=0,lon=0)
            ),
            showlegend=False,
            margin = dict(l = 0, r = 0, t = 0, b = 0),
        )

fig = dict(data=data, layout=layout)

gr = dcc.Graph(id='inputMap', config=plotlyConfig, figure = fig)

app.layout = html.Div(gr)

if __name__ == '__main__':
    app.run_server(debug=True, port=portnumber) 

3 Likes