Skip to content

Instantly share code, notes, and snippets.

@eyllanesc
Last active September 13, 2022 16:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eyllanesc/7f8b58471aef0489194b613dd51b7370 to your computer and use it in GitHub Desktop.
Save eyllanesc/7f8b58471aef0489194b613dd51b7370 to your computer and use it in GitHub Desktop.
Load geojson that weigh more than 2MB in QtWebEngine
import os.path
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
import folium
from qfolium import FoliumApplication
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
folium_app = FoliumApplication()
@folium_app.register("load_geojson")
def load_geojson(latitude, longitude, zoom_start, filename):
m = folium.Map(location=[latitude, longitude], zoom_start=zoom_start)
folium.GeoJson(filename).add_to(m)
print(m)
return m
class Interceptor(QWebEngineUrlRequestInterceptor):
def interceptRequest(self, info):
info.setHttpHeader(b"Accept-Language", b"en-US,en;q=0.9,es;q=0.8,de;q=0.7")
class FoliumWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
layout = QVBoxLayout(self)
webView = QWebEngineView()
layout.addWidget(webView)
self.interceptor = Interceptor()
webView.page().profile().setUrlRequestInterceptor(self.interceptor)
# https://eric.clst.org/assets/wiki/uploads/Stuff/gz_2010_us_050_00_500k.json
county_map = "cb_2018_us_county_20m.geojson"
# 45.5236, -122.6750
params = dict(
latitude=45.5236,
longitude=-122.6750,
zoom_start=2,
filename=os.path.join(CURRENT_DIR, county_map),
)
url = folium_app.create_url("load_geojson", params=params)
webView.load(url)
app = QApplication([])
folium_app.init_handler()
widget = FoliumWidget()
widget.show()
app.exec_()
# https://stackoverflow.com/a/64493467/6622587
import json
import io
from PyQt5 import QtCore, QtWebEngineCore, QtWebEngineWidgets
class FoliumSchemeHandler(QtWebEngineCore.QWebEngineUrlSchemeHandler):
def __init__(self, app):
super().__init__(app)
self.m_app = app
def requestStarted(self, request):
url = request.requestUrl()
name = url.host()
m = self.m_app.process(name, url.query())
if m is None:
request.fail(QtWebEngineCore.QWebEngineUrlRequestJob.UrlNotFound)
return
data = io.BytesIO()
m.save(data, close_file=False)
raw_html = data.getvalue()
buf = QtCore.QBuffer(parent=self)
request.destroyed.connect(buf.deleteLater)
buf.open(QtCore.QIODevice.WriteOnly)
buf.write(raw_html)
buf.seek(0)
buf.close()
request.reply(b"text/html", buf)
class FoliumApplication(QtCore.QObject):
scheme = b"folium"
def __init__(self, parent=None):
super().__init__(parent)
scheme = QtWebEngineCore.QWebEngineUrlScheme(self.scheme)
QtWebEngineCore.QWebEngineUrlScheme.registerScheme(scheme)
self.m_functions = dict()
def init_handler(self, profile=None):
if profile is None:
profile = QtWebEngineWidgets.QWebEngineProfile.defaultProfile()
handler = profile.urlSchemeHandler(self.scheme)
if handler is not None:
profile.removeUrlSchemeHandler(handler)
self.m_handler = FoliumSchemeHandler(self)
profile.installUrlSchemeHandler(self.scheme, self.m_handler)
def register(self, name):
def decorator(f):
self.m_functions[name] = f
return f
return decorator
def process(self, name, query):
f = self.m_functions.get(name)
if f is None:
print("not found")
return
items = QtCore.QUrlQuery(query).queryItems()
params_json = dict(items).get("json", None)
if params_json is not None:
return f(**json.loads(params_json))
return f()
def create_url(self, name, params=None):
url = QtCore.QUrl()
url.setScheme(self.scheme.decode())
url.setHost(name)
if params is not None:
params_json = json.dumps(params)
query = QtCore.QUrlQuery()
query.addQueryItem("json", params_json)
url.setQuery(query)
return url
@eyllanesc
Copy link
Author

Output:

Output

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment