Skip to content

Commit

Permalink
Create package (#1)
Browse files Browse the repository at this point in the history
* Create package

* Update GitHub Pages
  • Loading branch information
g4brielvs committed Jul 8, 2024
1 parent 75aa4c4 commit 5f39a1c
Show file tree
Hide file tree
Showing 7 changed files with 747 additions and 17 deletions.
33 changes: 22 additions & 11 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
name: Publish to GitHub Pages

on:
push:
branches:
- main

jobs:
build:
build-book:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: 3.11
cache: "pip"
- name: Dependencies
- name: Install Dependencies
run: |
if [ -f docs/requirements.txt ]; then pip install -r docs/requirements.txt; fi
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f pyproject.toml ]; then pip install ".[docs]"; fi
- name: Build Jupyter Book
- name: Build Juputer Book Documentation
run: |
jupyter-book build . --config docs/_config.yml --toc docs/_toc.yml
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
if: github.ref == 'refs/heads/main' && job.status == 'success'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./_build/html
enable_jekyll: false
path: "_build/html"

deploy-book:
needs: build-book
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
101 changes: 101 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Pyenv
.python-version

# DotEnv configuration
.env

# Database
*.db
*.rdb

# Pycharm
.idea

# VS Code
.vscode/

# Spyder
.spyproject/

# Jupyter NB
.jupyter/
.ipynb_checkpoints/

# Mac OS-specific storage files
.DS_Store

# vim
*.swp
*.swo

# Mypy cache
.mypy_cache/

# Jupyter Book
_build/

# python-dotenv
.env

# Project-specific

.jupyter/
.ruff_cache/
5 changes: 5 additions & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ parts:
- caption: Literature Review & Methodology
chapters:
- file: docs/methodology
- caption: Tutorials
chapters:
- file: notebooks/tessellate.ipynb


528 changes: 528 additions & 0 deletions notebooks/tessellate.ipynb

Large diffs are not rendered by default.

16 changes: 11 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ authors = [{ name = "Development Data Group", email = "[email protected]" }]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3 :: Only",
"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
"Operating System :: OS Independent",
Expand All @@ -23,7 +21,15 @@ classifiers = [
dynamic = ["version"]

requires-python = ">=3.10"
dependencies = ["pandas>=2", "dask>=2024.1.0"]
dependencies = [
"bokeh",
"datashader",
"h3>=3,<4",
"holoviews",
"mobilkit>=0.2.8",
"scikit-mobility>=1.3.1",
"numpy<2",
]
[project.optional-dependencies]
docs = [
"docutils==0.17.1", # https://jupyterbook.org/en/stable/content/citations.html?highlight=docutils#citations-and-bibliographies
Expand All @@ -38,10 +44,10 @@ docs = [
[tool.codespell]
skip = 'docs/_build,docs/bibliography.bib,*.png,*.gz,*.whl'
ignore-regex = '^\s*"image\/png":\s.*'
ignore-words-list = ","
ignore-words-list = "dec,"

[tool.hatch.build.targets.wheel]
packages = ["src/*"]
packages = ["src/mobilyze"]

[tool.hatch.version]
source = "vcs"
Expand Down
2 changes: 1 addition & 1 deletion src/mobilyze/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from importlib.metadata import version, PackageNotFoundError
from importlib.metadata import PackageNotFoundError, version

try:
__version__ = version("mobilyze")
Expand Down
79 changes: 79 additions & 0 deletions src/mobilyze/tessellation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import geopandas
import h3
import pandas as pd
from shapely.geometry import Polygon, mapping


def tessellate(gdf: geopandas.GeoDataFrame, columns=["shapeName"], resolution=7):
"""
Tessellates the geometries in a GeoDataFrame into hexagonal cells using H3.
Parameters
----------
gdf : geopandas.GeoDataFrame
The GeoDataFrame ()containing the geometries to tessellate.
column : str, optional
The column name in `gdf` to use in the resulting GeoDataFrame.
Default is "shapeName".
resolution : int, optional
The H3 resolution level for tessellation. Higher resolution results in smaller hexagons.
Default is 7.
Returns
-------
geopandas.GeoDataFrame
A GeoDataFrame containing the tessellated hexagons with the specified `index` and geometry.
Raises
------
Exception
If a geometry type other than "Polygon" or "MultiPolygon" is encountered.
Examples
--------
>>> import geopandas as gpd
>>> from shapely.geometry import Polygon
>>> gdf = gpd.GeoDataFrame({
... 'geometry': [Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])],
... 'shapeName': ['A']
... })
>>> tessellate(gdf)
shapeName geometry
8a69a0f7fffffff POLYGON ((0 0, 0.5 0, 1 0.5, 1 1, 0.5 1, 0 1, 0 0))
"""

gdf = gdf.to_crs("EPSG:4326")
mapper = dict()

for idx, row in gdf.iterrows():
geometry = row["geometry"]

match geometry.geom_type:
case "Polygon":
hex_ids = h3.polyfill(
mapping(geometry),
resolution,
geo_json_conformant=True,
)
mapper.update([(hex_id, row[columns]) for hex_id in hex_ids])

case "MultiPolygon":
for x in geometry.geoms:
hex_ids = h3.polyfill(
mapping(x),
resolution,
geo_json_conformant=True,
)

mapper.update([(hex_id, row[columns]) for hex_id in hex_ids])
case _:
raise (Exception)

# Create dataframe containing `hex_id`
df = pd.DataFrame.from_dict(mapper, orient="index", columns=columns)

return geopandas.GeoDataFrame(
df,
geometry=[Polygon(h3.h3_to_geo_boundary(idx, True)) for idx in df.index],
crs="EPSG:4326",
)

0 comments on commit 5f39a1c

Please sign in to comment.