Bokeh tile antimeridian problem

Hi and happy new bokeh year !
I am trying to display some data over European countries on a world tile map (CARTODBPOSITRON).
I am loading a GeoDataFrame() with crs=“EPSG:4326” and then project using to_crs(‘EPSG:3857’).
I have a huge problem for what concerns animeridian part of my map (when longitude > 180° or <-180°)


Do you have any idea how I can solve this ?
By advance thank you
cheers
Olivier

@odadoun this could potentially be a bug, or a usage issue. It’s impossible to say without more information. What is really necessary is a complete Minimal Reproducible Example that can be run and investigated.

@Bryan this is the minimal example to reproduce my problem (hope it will be enough).

from bokeh.plotting import figure
from bokeh.tile_providers import CARTODBPOSITRON, get_provider
from bokeh.models import GeoJSONDataSource
import geopandas as gpd
import shapely.geometry as sg
import json
from bokeh.io import show, output_notebook
import numpy as np
output_notebook(hide_banner=True)

tile_provider = get_provider(CARTODBPOSITRON)
p = figure(x_range=(0.0,22000000),y_range=(0,6500000),x_axis_type="mercator", y_axis_type="mercator")
p.add_tile(tile_provider)

#this Polygon is a very small part of Russia
p1=sg.Polygon([(180,70.832199), (178.903425 ,70.78113999),(178.7253, 71.0988),(180 ,71.515714), \
                (180.12812 ,71.55762),(180.97567 ,71.55553),(182.4255, 71.26948),(182.325 ,71.19),\
                (181.30622 ,70.893020),(180,70.832199)])

gg=gpd.GeoDataFrame({'geoid':1,'location':'PartofRussia','geometry':gpd.GeoSeries(p1)},crs="EPSG:4326")
gg2 = gg.copy()
gg = gg.set_index("geoid")

# Project using EPSG:3857 to fit with WEB mercator
gg['geometry'] = gg['geometry'].to_crs('EPSG:3857')

json_data = json.dumps(json.loads(gg.to_json()))
geosource = GeoJSONDataSource(geojson = json_data)

p.patches('xs','ys', source = geosource,fill_color = 'green',
                  line_color = 'black', line_width = 0.25, fill_alpha = 1)
# As you can see this draw a horizaontal bar from east to west (it should not)

#  This antimeridian problem seems to be a recurrent one
# see for instance https://stackoverflow.com/questions/53772047/folium-and-the-meridians-180-180
# If I use this formula (and not to_crs('EPSG:3857') method) it seems to solve it 
# ref : https://stackoverflow.com/questions/57178783/how-to-plot-latitude-and-longitude-in-bokeh
def wgs84_to_web_mercator(tuple_xy):
            """Converts decimal longitude/latitude to Web Mercator format"""
            k = 6378137
            x = tuple_xy[0] * (k * np.pi/180.0)
            y = np.log(np.tan((90 + tuple_xy[1]) * np.pi/360.0)) * k
            return x,y


new=[sg.Polygon([wgs84_to_web_mercator(t) for t in p.exterior.coords]) for p in gg2.geometry]
gg2['geometry']=gpd.GeoSeries(new)
gg2 = gg2.set_index("geoid")
json_data = json.dumps(json.loads(gg2.to_json()))
geosource = GeoJSONDataSource(geojson = json_data)

p.patches('xs','ys', source = geosource,fill_color = 'red',
                  line_color = 'black', line_width = 0.25, fill_alpha = 1)
show(p)

In green the to_crs(‘EPSG:3857’) problem and in red the solution I have implemented to solve it…

OK with the other SO link I actually understand this is the “wrap around” problem, which I did not appreciate from your initial post. I am not really surprised that Bokeh (and other tools) do not handle the wrap-around case very well. I don’t offhand have any suggestions for you, unfortunately. It would be reasonable to make a GitHub issue about this, but couldn’t begin to speculate when it might be looked at (there are no GIS experts on the Bokeh core team that I am aware of, and I am skeptical that this has a quick/easy fix).