How can I use map tiles while hosting an app publicly?

Problem

I have a Jupyter notebook with geo data that I serve as a Panel app. It works well when approaching the localhost address, but when I use the --allow-websocket-origin HOST[:PORT] option the map tiles don’t load.

Code

I’ve put together some example code demonstrating the issue:

import pandas as pd
import geopandas as gpd
import hvplot.pandas
import holoviews as hv
import panel as pn
from panel.interact import interact
pn.extension()

# Load some data
df = pd.read_csv('https://raw.githubusercontent.com/datasets/airport-codes/master/data/airport-codes.csv')

# Convert to GeodfFrame
df['x'] = df.coordinates.apply(lambda x: x.split(',')[0])
df['y'] = df.coordinates.apply(lambda x: x.split(',')[1])
gdf = gpd.GeoDataFrame(df[['name', 'iso_country']], geometry=gpd.points_from_xy(df['y'], df['x'], crs='epsg:4326'))

# Define a plotting function and a filter function
def hvplotter(selected_data):
    return selected_data.hvplot(geo=True, tiles=True, hover_cols=['name'], frame_width=500, frame_height=400)

def country_airports(country='BE'):
    selected_data = gdf.loc[gdf.iso_country == country]
    return hvplotter(selected_data)

# Create the interactive part
hvp = interact(country_airports, country=['ZW', 'BE', 'FR', 'NL', 'JP'])
app = pn.Column('## Select a country code to view its airports', hvp[0], hvp[1])
app.servable()

When I run

panel serve --show .\code.ipynb

I get to see the correct output:

However, I want to make this graph available to others (in the company network). I’ve opened up the firewall for port 5006 and I run:

panel serve --allow-websocket-origin full.host.name:5006 .\code.ipynb

Now I can access the Panel at full.host.name:5006/code, but the map tiles do not load:

The browser console fills with errors about the CORS policy:

Access to image at 'https://maps.wikimedia.org/osm-intl/6/32/20@2x.png' from origin 'http://full.host.name:5006' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

I am not too familiar with web development, so I’m unsure on what headers I need to include/exclude to make this work.

Could anyone perhaps give me some suggestions?

Well, as it goes with these issues, the moment you post them you find a solution…

Apparantly the Wikimedia maps don’t like cross origin requests, I found a similar issue here. Luckily hvplot allows you to chose a different tileserver. So by changing the tiles option in the hvplot line from:

return selected_data.hvplot(geo=True, tiles=True, hover_cols=['name'], frame_width=500, frame_height=400)

to:

return selected_data.hvplot(geo=True, tiles='OSM', hover_cols=['name'], frame_width=500, frame_height=400)

it now works:

1 Like

Hi @ba-tno

Welcome to the community.

Thanks for posting the solution. It helps build the knowledge base of our community. :+1: