Skip to content

Commit

Permalink
Merge pull request #32 from eodaGmbH/release/v0.1.3
Browse files Browse the repository at this point in the history
Release/v0.1.3
  • Loading branch information
crazycapivara authored Feb 6, 2024
2 parents bf885da + 6f09cf9 commit fd74821
Show file tree
Hide file tree
Showing 39 changed files with 776 additions and 554 deletions.
3 changes: 1 addition & 2 deletions .examples/earthquakes_cluster/app.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from shiny import App, reactive, ui

from maplibre import Layer, Map, MapOptions, output_maplibregl, render_maplibregl
from maplibre.basemaps import Carto
from maplibre.sources import GeoJSONSource
from shiny import App, reactive, ui

SOURCE_ID = "earthquakes"
LAYER_ID = "earthquakes"
Expand Down
14 changes: 4 additions & 10 deletions .examples/experimental/app2.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import requests as req
from shiny import App, reactive, render, ui

from maplibre import (
Layer,
LayerType,
Map,
MapContext,
output_maplibregl,
render_maplibregl,
)
from maplibre import (Layer, LayerType, Map, MapContext, output_maplibregl,
render_maplibregl)
from maplibre.basemaps import Carto
from maplibre.experimental import LineLayer
from shiny import App, reactive, render, ui

LAYER_ID = "counties"
LAYER_ID_LINE = "us-states-line"
Expand Down Expand Up @@ -103,3 +96,4 @@ async def color():

if __name__ == "__main__":
app.run()
un()
10 changes: 8 additions & 2 deletions .examples/experimental/flights.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

import pandas as pd
import shapely
from maplibre import (Layer, LayerType, Map, MapContext, output_maplibregl,
render_maplibregl)
from maplibre import (
Layer,
LayerType,
Map,
MapContext,
output_maplibregl,
render_maplibregl,
)
from maplibre.basemaps import Carto
from maplibre.utils import GeometryType, df_to_geojson
from shiny import App, reactive, ui
Expand Down
13 changes: 3 additions & 10 deletions .examples/h3_hexagons/app.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import h3
import pandas as pd
from shiny import App, reactive, ui

# import shapely
from maplibre import (
Layer,
LayerType,
Map,
MapContext,
output_maplibregl,
render_maplibregl,
)
from maplibre import (Layer, LayerType, Map, MapContext, output_maplibregl,
render_maplibregl)
from maplibre.basemaps import Carto
from maplibre.utils import GeometryType, df_to_geojson, get_bounds
from shiny import App, reactive, ui

LAYER_ID = "motor_vehicle_collisions"

Expand Down
2 changes: 1 addition & 1 deletion .examples/motor_vehicle_collisions/app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import h3
import pandas as pd
from shiny import App, reactive, ui

# import shapely
from maplibre import (
Expand All @@ -13,6 +12,7 @@
)
from maplibre.basemaps import Carto
from maplibre.utils import GeometryType, df_to_geojson, get_bounds
from shiny import App, reactive, ui

LAYER_ID = "motor_vehicle_collisions"

Expand Down
3 changes: 1 addition & 2 deletions .examples/text_layer/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from maplibre import (Layer, LayerType, Map, output_maplibregl,
render_maplibregl)
from maplibre import Layer, LayerType, Map, output_maplibregl, render_maplibregl
from maplibre.basemaps import Carto
from shiny import App, reactive, render, ui

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog for MapLibre for Python

## maplibre v0.1.3

* Display all properties in popup and tooltip if `prop = None` (#26)
* Support [mustache](https://github.com/janl/mustache.js) templates for popups and tooltips (#27)

## maplibre v0.1.2

* Add `Map.set_data`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ poetry install

poetry run pytest

poetry run pytest --doctest-modules maplibre
poetry run pytest --ignore=maplibre/ipywidget.py --doctest-modules maplibre
```

### JavaScript
Expand Down
6 changes: 6 additions & 0 deletions build-docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
set -e

cp CHANGELOG.md docs/changelog.md

poetry run mkdocs build
19 changes: 19 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog for MapLibre for Python

## maplibre v0.1.3

* Display all properties in popup and tooltip if `prop = None` (#26)
* Support [mustache](https://github.com/janl/mustache.js) templates for popups and tooltips (#27)

## maplibre v0.1.2

* Add `Map.set_data`
* Add `Map.set_visibility`
* Do not import `ipywidget.MapWidget` in `__init__` and skip tests for `MapWidget`, because it causes a `core dumped` error, see [anywidget issue](https://github.com/manzt/anywidget/issues/374)
* Remove `requests` dependency
* Remove dead code
* Add more examples

## maplibre v0.1.1

* Initial PyPI release
4 changes: 3 additions & 1 deletion docs/examples/3d_indoor_mapping/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<a href="app.html" target="_blank">See example in action</a>
<!-- <a href="app.html" target="_blank">See example in action</a> -->

<iframe src="app.html" height="620px", width="100%" style="border:none;"></iframe>

```python
-8<-- "3d_indoor_mapping/app.py"
Expand Down
167 changes: 167 additions & 0 deletions docs/examples/airports/app.html

Large diffs are not rendered by default.

39 changes: 25 additions & 14 deletions docs/examples/airports/app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import sys

import pandas as pd
from maplibre import (
Layer,
Expand Down Expand Up @@ -64,6 +66,23 @@ def get_color(airport_type: str) -> str:

popup_options = PopupOptions(close_button=False)


def create_map() -> Map:
m = Map(map_options)
m.add_layer(airport_circles)
for _, r in airports_data.iterrows():
marker = Marker(
lng_lat=r["coordinates"],
options=MarkerOptions(color=get_color(r["type"])),
popup=Popup(
text=r["name"],
options=popup_options,
),
)
m.add_marker(marker)
return m


app_ui = ui.page_fluid(
ui.panel_title("Airports"),
output_maplibregl("maplibre", height=600),
Expand All @@ -73,22 +92,14 @@ def get_color(airport_type: str) -> str:
def server(input, output, session):
@render_maplibregl
def maplibre():
m = Map(map_options)
for _, r in airports_data.iterrows():
marker = Marker(
lng_lat=r["coordinates"],
options=MarkerOptions(color=get_color(r["type"])),
popup=Popup(
text=r["name"],
options=popup_options,
),
)
m.add_marker(marker)
m.add_layer(airport_circles)
return m
return create_map()


app = App(app_ui, server)

if __name__ == "__main__":
app.run()
if len(sys.argv) == 2:
with open(sys.argv[1], "w") as f:
f.write(create_map().to_html())
else:
app.run()
2 changes: 2 additions & 0 deletions docs/examples/airports/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<iframe src="app.html" height="620px", width="100%" style="border:none;"></iframe>

```python
-8<-- "airports/app.py"
```
Expand Down
6 changes: 4 additions & 2 deletions docs/examples/custom_basemap/index.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<!-- <a href="app.html" target="_blank">See example in action</a> -->

<iframe src="app.html" height="620px", width="100%" style="border:none;"></iframe>

```python
-8<-- "custom_basemap/app.py"
```

<a href="app.html" target="_blank">See example in action</a>

Run example:

``` bash
Expand Down
167 changes: 167 additions & 0 deletions docs/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>
Loading

0 comments on commit fd74821

Please sign in to comment.