Skip to content

Commit

Permalink
create RScript python class + create separate R packages installation…
Browse files Browse the repository at this point in the history
…s scripts called from mobility.setup + distribute a forked version of the osmdata R package as a binary to speed up OSM data parsing + switch to pyproject.toml
  • Loading branch information
FlxPo committed May 2, 2024
1 parent f2d5600 commit 05eca13
Show file tree
Hide file tree
Showing 29 changed files with 1,004 additions and 562 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include mobility/ressources/*
8 changes: 6 additions & 2 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: mobility
channels:
- conda-forge
dependencies:
- python=3.11
- r-base
- geopandas
- pip:
- mobility-tools
- osmium-tool
# - pip:
# - mobility-tools
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import os
import dotenv

from mobility.setup_mobility import setup_mobility
from mobility.transport_zones import get_transport_zones
from mobility.dodgr import compute_travel_costs
import mobility

dotenv.load_dotenv()

setup_mobility(
mobility.setup(
package_data_folder_path=os.environ["MOBILITY_PACKAGE_DATA_FOLDER"],
project_data_folder_path=os.environ["MOBILITY_PROJECT_DATA_FOLDER"],
path_to_pem_file=os.environ["MOBILITY_CERT_FILE"],
http_proxy_url=os.environ["HTTP_PROXY"],
https_proxy_url=os.environ["HTTPS_PROXY"]
)

transport_zones = get_transport_zones("42139", method="radius", radius=20)
travel_costs = compute_travel_costs(transport_zones, "car")
transport_zones = mobility.TransportZones("69123", method="radius", radius=10)

car_travel_costs = mobility.TravelCosts(transport_zones, "car")
walk_travel_costs = mobility.TravelCosts(transport_zones, "walk")
bicycle_travel_costs = mobility.TravelCosts(transport_zones, "bicycle")
3 changes: 3 additions & 0 deletions mobility/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
from .setup import setup
from .trip_sampler import TripSampler
from .transport_zones import TransportZones
from .travel_costs import TravelCosts
120 changes: 120 additions & 0 deletions mobility/asset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import json
import hashlib
import pathlib

from typing import Any
from abc import ABC, abstractmethod

class Asset(ABC):
"""
Abstract base class representing an Asset, with functionality for cache validation
based on input hash comparison.
Attributes:
inputs (Dict): A dictionary of inputs used to generate the Asset.
cache_path (pathlib.Path): The file path for storing the Asset.
hash_path (pathlib.Path): The file path for storing the hash of the inputs.
inputs_hash (str): The hash of the inputs.
Methods:
get_cached_asset: Abstract method to retrieve a cached Asset.
create_and_get_asset: Abstract method to create and retrieve an Asset.
get: Retrieves the cached Asset or creates a new one if needed.
compute_inputs_hash: Computes a hash based on the inputs.
is_update_needed: Checks if an update is needed based on the input hash.
get_cached_hash: Retrieves the cached hash from the file system.
update_hash: Updates the cached hash with a new hash value.
"""

def __init__(self, inputs: dict, cache_path: pathlib.Path):
"""
Initializes the Asset instance with given inputs and cache path.
Args:
inputs (Dict): The inputs used for creating or updating the Asset.
cache_path (pathlib.Path): The path where the Asset is cached.
"""
self.inputs = inputs
self.cache_path = cache_path
self.hash_path = cache_path.with_suffix(".inputs-hash")
self.inputs_hash = self.compute_inputs_hash()
self.get()

@abstractmethod
def get_cached_asset(self):
"""
Abstract method to get the Asset from the cache.
Returns:
The cached Asset.
"""
pass

@abstractmethod
def create_and_get_asset(self):
"""
Abstract method to create and get the Asset.
Returns:
The created Asset.
"""
pass

def get(self) -> Any:
"""
Retrieves the Asset, either from the cache or by creating a new one if the
cache is outdated or non-existent.
Returns:
The retrieved or newly created Asset.
"""
if self.is_update_needed():
asset = self.create_and_get_asset()
self.update_hash(self.inputs_hash)
return asset
return self.get_cached_asset()

def compute_inputs_hash(self) -> str:
"""
Computes a hash based on the current inputs of the Asset.
Returns:
A hash string representing the current state of the inputs.
"""
hashable_inputs = {
k: v.get_cached_hash() if isinstance(v, Asset) else v for k, v in self.inputs.items()
}
serialized_inputs = json.dumps(hashable_inputs, sort_keys=True).encode('utf-8')
return hashlib.md5(serialized_inputs).hexdigest()

def is_update_needed(self) -> bool:
"""
Checks if an update to the Asset is needed based on the current inputs hash.
Returns:
True if an update is needed, False otherwise.
"""
return self.get_cached_hash() != self.inputs_hash

def get_cached_hash(self) -> str:
"""
Retrieves the cached hash of the Asset's inputs from the file system.
Returns:
The cached hash string if it exists, otherwise None.
"""
if self.hash_path.exists():
with open(self.hash_path, "r") as f:
return f.read()
return None

def update_hash(self, new_hash: str) -> None:
"""
Updates the cached hash of the Asset's inputs with a new hash.
Args:
new_hash (str): The new hash string to be cached.
"""
self.inputs_hash = new_hash
with open(self.hash_path, "w") as f:
f.write(new_hash)
22 changes: 0 additions & 22 deletions mobility/caching.py

This file was deleted.

113 changes: 0 additions & 113 deletions mobility/dodgr.py

This file was deleted.

7 changes: 0 additions & 7 deletions mobility/dodgr_modes.py

This file was deleted.

13 changes: 3 additions & 10 deletions mobility/get_dodgr_osm_tags.R
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
source("mobility/load_packages.R")
packages <- c("dodgr", "optparse")
load_packages(packages)
library(dodgr)

option_list = list(
make_option(c("-d", "--dodgr-mode"), type = "character")
)

opt_parser = OptionParser(option_list = option_list)
opt = parse_args(opt_parser)
dodgr_mode <- commandArgs(trailingOnly = TRUE)

profiles <- dodgr::weighting_profiles$weighting_profiles
highway_tags <- profiles[profiles$name == opt[["dodgr-mode"]] & !is.na(profiles$max_speed) & profiles$value > 0.0, "way"]
highway_tags <- profiles[profiles$name == dodgr_mode & !is.na(profiles$max_speed) & profiles$value > 0.0, "way"]
highway_tags <- paste(highway_tags, collapse = ",")

cat(paste(highway_tags, collapse = ","))
Loading

0 comments on commit 05eca13

Please sign in to comment.