Skip to content

Commit

Permalink
Deployed 3ee7062 with MkDocs version: 1.5.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefan Kuethe committed Jan 23, 2024
1 parent 097d303 commit 2cdeb50
Show file tree
Hide file tree
Showing 5 changed files with 298 additions and 105 deletions.
167 changes: 167 additions & 0 deletions examples/earthquake_clusters/app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Pymaplibregl</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css"/>
<body>
<div id="pymaplibregl" style="height:600px;"></div>
<script>
(() => {
// srcjs/pymaplibregl.js
var PyMapLibreGL = class {
constructor(mapOptions) {
this._id = mapOptions.container;
this._map = new maplibregl.Map(mapOptions);
this._map.on("mouseover", () => {
this._map.getCanvas().style.cursor = "pointer";
});
this._map.on("mouseout", () => {
this._map.getCanvas().style.cursor = "";
});
this._map.addControl(new maplibregl.NavigationControl());
}
getMap() {
return this._map;
}
applyMapMethod(name, params) {
this._map[name](...params);
}
addControl(type, options, position) {
this._map.addControl(new maplibregl[type](options), position);
}
addMarker({ lngLat, popup, options }) {
const marker = new maplibregl.Marker(options).setLngLat(lngLat);
if (popup) {
const popup_ = new maplibregl.Popup(popup.options).setHTML(popup.text);
marker.setPopup(popup_);
}
marker.addTo(this._map);
}
addLayer(layer) {
this._map.addLayer(layer);
if (typeof Shiny !== "undefined") {
this._map.on("click", layer.id, (e) => {
console.log(e, e.features[0]);
const layerId_ = layer.id.replaceAll("-", "_");
const inputName = `${this._id}_layer_${layerId_}`;
const feature = {
props: e.features[0].properties,
layer_id: layer.id
};
console.log(inputName, feature);
Shiny.onInputChange(inputName, feature);
});
}
}
addPopup(layerId, property) {
const popupOptions = {
closeButton: false
};
const popup = new maplibregl.Popup(popupOptions);
this._map.on("click", layerId, (e) => {
const feature = e.features[0];
const text = feature.properties[property];
popup.setLngLat(e.lngLat).setHTML(text).addTo(this._map);
});
}
addTooltip(layerId, property) {
const popupOptions = {
closeButton: false,
closeOnClick: false
};
const popup = new maplibregl.Popup(popupOptions);
this._map.on("mousemove", layerId, (e) => {
const feature = e.features[0];
const text = feature.properties[property];
popup.setLngLat(e.lngLat).setHTML(text).addTo(this._map);
});
this._map.on("mouseleave", layerId, () => {
popup.remove();
});
}
setSourceData(sourceId, data) {
this._map.getSource(sourceId).setData(data);
}
render(calls) {
calls.forEach(([name, params]) => {
if ([
"addLayer",
"addPopup",
"addTooltip",
"addMarker",
"addPopup",
"addControl",
"setSourceData"
].includes(name)) {
console.log("Custom method", name, params);
this[name](...params);
return;
}
console.log("Map method", name);
this.applyMapMethod(name, params);
});
}
};

// srcjs/index.js
var version = "0.1.0";
console.log("pymaplibregl", version);
if (typeof Shiny === "undefined") {
window.pymaplibregl = function({ mapOptions, calls }) {
const id = "pymaplibregl";
const container = document.getElementById(id);
const pyMapLibreGL = new PyMapLibreGL(
Object.assign({ container: container.id }, mapOptions)
);
const map = pyMapLibreGL.getMap();
map.on("load", () => {
pyMapLibreGL.render(calls);
});
};
}
if (typeof Shiny !== "undefined") {
class MapLibreGLOutputBinding extends Shiny.OutputBinding {
find(scope) {
return scope.find(".shiny-maplibregl-output");
}
renderValue(el, payload) {
console.log("id:", el.id, "payload:", payload);
const pyMapLibreGL = new PyMapLibreGL(
Object.assign({ container: el.id }, payload.mapData.mapOptions)
);
const map = pyMapLibreGL.getMap();
map.on("load", () => {
pyMapLibreGL.render(payload.mapData.calls);
});
map.on("click", (e) => {
console.log(e);
const inputName = `${el.id}`;
const data = { coords: e.lngLat, point: e.point };
console.log(inputName, data);
Shiny.onInputChange(inputName, data);
});
const messageHandlerName = `pymaplibregl-${el.id}`;
console.log(messageHandlerName);
Shiny.addCustomMessageHandler(messageHandlerName, ({ id, calls }) => {
console.log(id, calls);
pyMapLibreGL.render(calls);
});
}
}
Shiny.outputBindings.register(
new MapLibreGLOutputBinding(),
"shiny-maplibregl-output"
);
}
})();

// ...
(() => {
var data = {"mapOptions": {"center": [-118.0931, 33.78615], "hash": true, "style": "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json", "zoom": 3}, "calls": [["addSource", ["earthquakes", {"data": "https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson", "cluster": true, "clusterMaxZoom": 14, "clusterMinPoints": 2, "clusterProperties": {"maxMag": ["max", ["get", "mag"]], "minMag": ["min", ["get", "mag"]]}, "clusterRadius": 50, "type": "geojson"}]], ["addLayer", [{"id": "earthquake-clusters", "type": "circle", "filter": ["has", "point_count"], "paint": {"circle-color": ["step", ["get", "point_count"], "#51bbd6", 100, "#f1f075", 750, "#f28cb1"], "circle-radius": ["step", ["get", "point_count"], 20, 100, 30, 750, 40]}, "source": "earthquakes"}]], ["addLayer", [{"id": "earthquake-circles", "type": "circle", "filter": ["!", ["has", "point_count"]], "paint": {"circle-color": "darkblue"}, "source": "earthquakes"}]], ["addTooltip", ["earthquake-clusters", "maxMag"]], ["addLayer", [{"id": "text", "type": "symbol", "filter": ["has", "point_count"], "layout": {"text-field": ["get", "point_count_abbreviated"], "text-size": 12}, "source": "earthquakes"}]]]};
pymaplibregl(data);
})();
</script>
</body>
</html>
28 changes: 20 additions & 8 deletions examples/earthquake_clusters/app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import sys

from maplibre import (
Layer,
LayerType,
Expand Down Expand Up @@ -69,6 +71,17 @@

map_options = MapOptions(style=Carto.POSITRON, center=CENTER, zoom=3, hash=True)


def create_map() -> Map:
m = Map(map_options)
m.add_source(EARTHQUAKE_SOURCE, earthquakes_source)
m.add_layer(earthquake_clusters)
m.add_layer(earthquake_circles)
m.add_tooltip(EARTHQUAKE_CLUSTERS, "maxMag")
m.add_layer(earthquake_labels)
return m


app_ui = ui.page_fluid(
ui.panel_title("Earthquakes Cluster"),
output_maplibregl("maplibre", height=500),
Expand All @@ -78,13 +91,7 @@
def server(input, output, session):
@render_maplibregl
def maplibre():
m = Map(map_options)
m.add_source(EARTHQUAKE_SOURCE, earthquakes_source)
m.add_layer(earthquake_clusters)
m.add_layer(earthquake_circles)
m.add_tooltip(EARTHQUAKE_CLUSTERS, "maxMag")
m.add_layer(earthquake_labels)
return m
return create_map()

@reactive.Effect
@reactive.event(input.maplibre)
Expand All @@ -95,4 +102,9 @@ async def result():
app = App(app_ui, server)

if __name__ == "__main__":
app.run()
if len(sys.argv) == 2:
file_name = sys.argv[1]
with open(file_name, "w") as f:
f.write(create_map().to_html())
else:
app.run()
Loading

0 comments on commit 2cdeb50

Please sign in to comment.