Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
90d1b09
Refactor tooltip in pd extension
stfnkth May 3, 2025
6ecef46
Add random calor cats
stfnkth May 3, 2025
71ece91
Add to_layer and to_source to geopandas
stfnkth May 4, 2025
b77ba98
Add more import to main
stfnkth May 4, 2025
cdc850a
More examples
stfnkth May 4, 2025
bf6e5a4
Add express.IconLayer
stfnkth May 4, 2025
9e20919
Add LayerLike for express layers
stfnkth May 4, 2025
3d2c12e
Refactor LayerLike
stfnkth May 4, 2025
e9492f0
bum version to 0.1.0-rc.2
stfnkth May 4, 2025
ccdbbb8
Add olx.PolygonLayer
stfnkth May 4, 2025
d842b5b
Refactor express
stfnkth May 4, 2025
02db5f0
Add IconStyle
stfnkth May 5, 2025
eef0cfd
Refactor
stfnkth May 5, 2025
3729cb4
Add fitBounds method
stfnkth May 5, 2025
e323569
Add more map parameters
stfnkth May 5, 2025
ead9e18
Refactor
stfnkth May 5, 2025
1b2ed10
Update example
stfnkth May 5, 2025
7b55129
Add skeleton workflow
stfnkth May 5, 2025
017f707
Test package
stfnkth May 5, 2025
0911a3f
Add annotations import
stfnkth May 5, 2025
369b6cb
Add missing requirement
stfnkth May 5, 2025
551dee9
Add type backport
stfnkth May 5, 2025
cb2c6d6
Add mor annotation imports
stfnkth May 5, 2025
bb82b9f
Add missing imports
stfnkth May 5, 2025
0608764
Py 3.9 does not support types 'xyz | None'
stfnkth May 5, 2025
ff76337
Add workflow to deploy mkdocs
stfnkth May 5, 2025
463b282
Style
stfnkth May 5, 2025
ab78cb9
Add docs
stfnkth May 5, 2025
b562e11
Add docstrings
stfnkth May 5, 2025
a3a878c
Update docs
stfnkth May 5, 2025
6128156
Install pkg to build docs
stfnkth May 6, 2025
44610a5
Add method to set zoom level
stfnkth May 6, 2025
c137061
Add pyproj and methods to set center and zoom
stfnkth May 6, 2025
be48348
Add docstrings
stfnkth May 6, 2025
4c5bfc2
Add useGeographic() so that we can pass lon lat coordinates
stfnkth May 6, 2025
9372403
Fix projections
stfnkth May 6, 2025
169f395
Add extent to view object
stfnkth May 6, 2025
4af79bb
Remove dead tooltip code
stfnkth May 6, 2025
35af55e
Rename MapWidget attributes
stfnkth May 6, 2025
467b2b8
Style
stfnkth May 6, 2025
9dfa34f
Rename map_options to options
stfnkth May 6, 2025
fff3c62
Rename initial_view to initial_view_state
stfnkth May 6, 2025
c16afdd
Add geotiff express layer
stfnkth May 6, 2025
a3ed380
Add set_view_from_source method
stfnkth May 6, 2025
74afbd6
Refactor
stfnkth May 6, 2025
330e1e5
Test other cogs
stfnkth May 6, 2025
dcf5cd4
Add kml example
stfnkth May 7, 2025
b8adae6
Add attribute to KML style
stfnkth May 7, 2025
9a522e5
Add method to select features
stfnkth May 7, 2025
3bb58b2
Push selected features to anywidget
stfnkth May 7, 2025
57937df
Refactor BasemapLayer
stfnkth May 7, 2025
6bf0c6b
Style
stfnkth May 7, 2025
d2d656b
Add skeleton functions
stfnkth May 7, 2025
66115e1
Add icon style to geopandas
stfnkth May 7, 2025
4e5ec95
Add method to set source
stfnkth May 7, 2025
8a6931c
Fix import of Self in py3.10
stfnkth May 8, 2025
2726367
Add vector layer examples
stfnkth May 8, 2025
f4edc00
Add drag and drop interaction
stfnkth May 8, 2025
42ecb48
Refactor drag and drop interaction
stfnkth May 8, 2025
df2d19b
Add draw interaction
stfnkth May 8, 2025
c3f45b2
listen to layers and controls change events
stfnkth May 9, 2025
ef46168
Add zoom and rotate controls with id and type
stfnkth May 10, 2025
74ff69a
Add fit bounds attr to Vector Layer
stfnkth May 10, 2025
cb8f3c5
Refactor add and remove events
stfnkth May 10, 2025
e755647
Refactor
stfnkth May 10, 2025
2d144ca
Remove dead code
stfnkth May 10, 2025
1078725
Refactor
stfnkth May 10, 2025
9c55679
v0.1.0-rc.4
stfnkth May 10, 2025
7bf4f88
Add ol-pmtiles
stfnkth May 10, 2025
34e79cb
Add WebGLVectorTileLayer
stfnkth May 10, 2025
ca10d71
Add PMTiles Raster Layer
stfnkth May 10, 2025
16a13e3
Set fix ol-js version
stfnkth May 10, 2025
1a1e4d0
Refactor view
stfnkth May 10, 2025
8fdf9e2
Build anywidget-js
stfnkth May 10, 2025
19ebbf3
v0.1.0-rc.5
stfnkth May 11, 2025
376bed2
Add draw select box
stfnkth May 11, 2025
be6b0c5
Fix zIndex of layer
stfnkth May 11, 2025
86ad172
Add draw control
stfnkth May 11, 2025
a2cb24b
Add modify to draw features
stfnkth May 11, 2025
483a887
Refactor
stfnkth May 12, 2025
b3f0dcf
Parse draw features
stfnkth May 12, 2025
656f740
Move custom controls
stfnkth May 12, 2025
67dd7ed
Remove dead code
stfnkth May 12, 2025
f23b270
Add event listener to draw control
stfnkth May 12, 2025
828630d
Add modify interaction
stfnkth May 12, 2025
db12ea7
Refactor
stfnkth May 12, 2025
7d5172c
Build anywidget
stfnkth May 12, 2025
3174b0d
Send draw features to model
stfnkth May 13, 2025
912ce87
Convert icon to base64 automatically
stfnkth May 13, 2025
e5efcf1
Remove icon style
stfnkth May 13, 2025
6095d91
Add MVT layer
stfnkth May 13, 2025
03bbc42
Add geotiff example
stfnkth May 14, 2025
499b029
Save changed feature
stfnkth May 14, 2025
5263755
Return feature objects
stfnkth May 14, 2025
1cf600b
Add zindex
stfnkth May 14, 2025
6179f33
Update docstrings
stfnkth May 14, 2025
c579168
Add ZoomToExtentControl
stfnkth May 15, 2025
3681242
Refactor
stfnkth May 15, 2025
9e5c16a
Refactor inheritance
stfnkth May 16, 2025
5cbdaaa
Add vector image layer
stfnkth May 16, 2025
403f725
Update docs
stfnkth May 16, 2025
fbe0378
Add TileJSON source
stfnkth May 21, 2025
4e16c52
0.1.0-rc.6
stfnkth May 21, 2025
1148922
Update docs
stfnkth May 21, 2025
bb0207b
Update docs
stfnkth May 21, 2025
66587e5
Update docs
stfnkth May 21, 2025
3b3f932
Add MapTiler Geocoding control
stfnkth May 21, 2025
15a0173
Styles
stfnkth May 21, 2025
dc13f49
Update docs
stfnkth May 21, 2025
a534df7
Update README
stfnkth May 21, 2025
91d71c6
Add carto basemap layer
stfnkth May 22, 2025
40e08da
Update docstrings
stfnkth May 22, 2025
fbb4731
Refactor method names
stfnkth May 22, 2025
511f633
Refactor basemap layers
stfnkth May 22, 2025
e5c2004
Refactor
stfnkth May 22, 2025
1d6eae3
Fix all
stfnkth May 22, 2025
017ecdb
v0.1.0-rc.7
stfnkth May 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Build and deploy docs

on:
push:
branches:
- main
- dev
pull_request:
branches:
- "*"

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install package
run: pip install -e .

- name: Install dependencies
run: pip install -r requirements.docs.txt

- name: Build docs
run: mkdocs build -d dist

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./dist

deploy:
needs: build
if: github.ref == 'refs/heads/main'
permissions:
pages: write
id-token: write

environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
31 changes: 31 additions & 0 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Test package

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

# You can test your matrix by printing the current Python version
- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Install package
run: pip install -e .

- name: Install dev dependencies
run: pip install -r requirements.dev.txt

- name: Test package
run: pytest
54 changes: 53 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,38 @@
# OpenLayers for Python
# py-openlayers: OpenLayers for Python

[![Release](https://img.shields.io/github/v/release/eoda-dev/py-openlayers)](https://img.shields.io/github/v/release/eoda-dev/py-openlayers)
[![pypi](https://img.shields.io/pypi/v/openlayers.svg)](https://pypi.python.org/pypi/openlayers)
[![License](https://img.shields.io/github/license/eoda-dev/py-openlayers)](https://img.shields.io/github/license/eoda-dev/py-openlayers)
[![OpenLayers JS](https://img.shields.io/badge/OpenLayers-v10.5.0-blue.svg)](https://github.com/openlayers/openlayers/releases//tag/v10.5.0)

Provides Python bindings for [Openlayers](https://openlayers.org/), a high-performance, full-featured web mapping library that displays maps from various sources and formats. It makes it a easy to create interactive maps in [Marimo](https://marimo.io/) and [Jupyter](https://jupyter.org/) notebbooks with a few lines of code in a pydantic way.

## Features

### Tiled Layers

Pull tiles from OSM, CartoDB, MapTiler and any other XYZ source.


### Vector Layers

Render vector data from GeoJSON, TopoJSON, KML, GML and other formats.

### Controls

Add geocoding, draw, full screen and other controls to your map.

### WebGL

Render large data sets using WebGL.

### PMTiles

Render PMTiles from vector and raster sources.

### Interactions

Drag and drop GPX, GeoJSON, KML or TopoJSON files on to the map. Modify, draw and select features.

## Installation

Expand All @@ -7,3 +41,21 @@ uv init

uv add "git+https://github.com/eoda-dev/py-openlayers@main"
```

## Quickstart

```python
import openlayers as ol

# Jupyter or Marimo
m = ol.MapWidget()
m # Display map

# Standalone
m = ol.Map()
m.save()
```

## Note

The documentation is still in an early stage, more examples will be added as soon as possible.
5 changes: 5 additions & 0 deletions TODOS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# TODOS

## STAC layers

https://openlayers.org/en/latest/examples/stac-item.html
7 changes: 7 additions & 0 deletions docs/api/basemaps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Basemaps

::: openlayers.basemaps.BasemapLayer

::: openlayers.basemaps.CartoBasemapLayer

::: openlayers.basemaps.MapTilerBasemapLayer
3 changes: 3 additions & 0 deletions docs/api/controls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Controls

::: openlayers.controls
3 changes: 3 additions & 0 deletions docs/api/express.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# OpenLayersExpress

::: openlayers.express.GeoJSONLayer
5 changes: 5 additions & 0 deletions docs/api/geopandas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# GeoPandas

::: openlayers.geopandas.OLAccessor

::: openlayers.geopandas.GeoDataFrame
15 changes: 15 additions & 0 deletions docs/api/layers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Layers

::: openlayers.layers.Layer

::: openlayers.layers.VectorLayer

::: openlayers.layers.VectorTileLayer

::: openlayers.layers.TileLayer

::: openlayers.layers.WebGLVectorLayer

::: openlayers.layers.WebGLVectorTileLayer

::: openlayers.layers.WebGLTileLayer
8 changes: 8 additions & 0 deletions docs/api/map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Map

::: openlayers.Map

::: openlayers.view.View

::: openlayers.MapWidget

3 changes: 3 additions & 0 deletions docs/api/sources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Sources

::: openlayers.sources
5 changes: 5 additions & 0 deletions docs/api/styles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Styles

::: openlayers.styles.FlatStyle

::: openlayers.styles.default_style
9 changes: 9 additions & 0 deletions docs/concepts/controls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Controls

Controls are user interface elements that you can add to your map:

```python
-8<-- "concepts/controls.py"
```

> See [Controls API](../../api/controls/)
7 changes: 7 additions & 0 deletions docs/concepts/geopandas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# GeoPandas

Python-OpenLayers shipes with a [GeoPandas](https://geopandas.org/) extension:

```python
-8<-- "concepts/geopandas.py"
```
File renamed without changes.
48 changes: 48 additions & 0 deletions docs/concepts/layers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Layers and sources

Sources and layers are used to display _raster_ or _vector_ data on your map.

## Sources

Sources state which data the map should display.

```python
-8<-- "concepts/sources.py"
```

> See [Sources API](../../api/sources/)

## Layers

A layer defines how a source is displayed on the map:

```python
-8<-- "concepts/layers.py"
```

> See [Layers API](../../api/layers/)

## Styles

Vector layers are styled with an object containing properties for the different styles, such as _stroke_, _fill_, _circle_ or _icon_:

```python
style = ol.FlatStyle(
stroke_color = "yellow",
stroke_width = 1.5,
fill_color = "orange"
)
```

It is also possible to use a simple dictonary instead. In this case property names must use hyphens instead
of underscores:

```python
const style = {
"stroke-color": "yellow",
"stroke-width": 1.5,
"fill-color": "orange",
}
```

> See [Styles API](../../api/styles/) and [ol/style/flat](https://openlayers.org/en/latest/apidoc/module-ol_style_flat.html) for details.
31 changes: 31 additions & 0 deletions docs/concepts/map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Map

The [Map](../../api/map/#openlayers.Map) is the core component of your visualization, to which other components such as [controls](../controls), [layers](../layers) or overlays are added. Components can be added either during initialization or afterwards:

```python
-8<-- "concepts/basic_map.py"
```

## View state

Properties such as _center_, _zoom level_ and _projection_ are managed by the [View](../../api/map/#openlayers.view.View) instance:

```python
-8<-- "concepts/view.py"
```

## Basemaps

A basemap in openlayers consists of one or more layers from your layer stack:

```python
-8<-- "concepts/basemaps.py"
```

> See [BasemapLayer API](../../api/basemaps/#openlayers.Basemaps.BasemapLayer)

If you hand over an empty layer stack to your map, a blank background is displayed:

```python
m = ol.Map(layers=[])
```
8 changes: 8 additions & 0 deletions docs/examples/concepts/basemaps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import openlayers as ol
from openlayers.basemaps import CartoBasemapLayer, Carto

# Use default OSM basemap
m = ol.Map(layers=[ol.BasemapLayer()])

# Use a CartoDB basemap
m = ol.Map(layers=[CartoBasemapLayer(Carto.DARK_NO_LABELS)])
7 changes: 7 additions & 0 deletions docs/examples/concepts/basic_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import openlayers as ol

# Add components during initialization
m = ol.Map(controls=[ol.ZoomSliderControl()])

# Add components after initialization
m.add_control(ol.FullScreenControl())
7 changes: 7 additions & 0 deletions docs/examples/concepts/controls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import openlayers as ol

# Add controls during initialization
m = ol.Map(controls=[ol.ZoomSliderControl(), ol.OverviewMapControl()])

# Add components after initialization
m.add_control(ol.ScaleLineControl(units="degrees"))
7 changes: 7 additions & 0 deletions docs/examples/concepts/geopandas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import openlayers as ol
from openlayers.geopandas import GeoDataFrame

data = "https://openlayers.org/en/latest/examples/data/geojson/roads-seoul.geojson"

m = GeoDataFrame.from_file(data).ol.explore(tooltip=True)
m.add_control(ol.ScaleLineControl())
16 changes: 16 additions & 0 deletions docs/examples/concepts/layers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import openlayers as ol

data = "https://openlayers.org/en/latest/examples/data/geojson/roads-seoul.geojson"

vector = ol.VectorLayer(
id="roads",
source=ol.VectorSource(url=data),
fit_bounds=True,
)


m = ol.Map(
ol.View(rotation=3.14 / 8),
layers=[ol.BasemapLayer(), vector]
)
m.add_default_tooltip()
14 changes: 14 additions & 0 deletions docs/examples/concepts/sources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import openlayers as ol

geojson = ol.VectorSource(
url="https://openlayers.org/en/latest/examples/data/geojson/roads-seoul.geojson"
)

geotiff = ol.GeoTIFFSource(
sources=[{"url": "https://s2downloads.eox.at/demo/EOxCloudless/2020/rgbnir/s2cloudless2020-16bits_sinlge-file_z0-4.tif"}]
)

pmtiles = ol.PMTilesVectorSource(
url="https://r2-public.protomaps.com/protomaps-sample-datasets/nz-buildings-v3.pmtiles",
attributions=["© Land Information New Zealand"]
)
11 changes: 11 additions & 0 deletions docs/examples/concepts/view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import openlayers as ol

initial_view = ol.View(center=(9.5, 51.31667), zoom=14)

m = ol.Map(initial_view)

# Change view settings afterwards
m.set_center(lon=172.606201, lat=-43.556510)
m.set_zoom(14)

m.set_view(ol.View(center=(172.606201, -43.556510), zoom=12))
Loading