overturetoosm

overturetoosm is a Python package to convert objects tagged in the Overture schema for use in OSM. Only Overture's places, buildings, and addresses layers are currently supported.

Links:

 1"""`overturetoosm` is a Python package to convert objects tagged in the 
 2Overture schema for use in OSM. Only Overture's `places`, `buildings`, 
 3and `addresses` layers are currently supported.
 4
 5Links:
 6* [Project GitHub](https://github.com/whubsch/overturetoosm)
 7* [Documentation](https://whubsch.github.io/overturetoosm/)
 8* [PyPI](https://pypi.org/project/overturetoosm/)
 9"""
10
11from .places import process_place
12from .buildings import process_building
13from .addresses import process_address
14from .utils import process_geojson
15from . import places
16from . import buildings
17from . import addresses
18from . import objects
19from . import utils
20from . import resources
21
22__all__ = [
23    "process_place",
24    "process_building",
25    "process_address",
26    "process_geojson",
27    "places",
28    "buildings",
29    "addresses",
30    "objects",
31    "utils",
32    "resources",
33]
def process_place( props: dict, confidence: float = 0.0, region_tag: str = 'addr:state', unmatched: Literal['error', 'force', 'ignore'] = 'ignore') -> Dict[str, str]:
 10def process_place(
 11    props: dict,
 12    confidence: float = 0.0,
 13    region_tag: str = "addr:state",
 14    unmatched: Literal["error", "force", "ignore"] = "ignore",
 15) -> Dict[str, str]:
 16    """Convert Overture's places properties to OSM tags.
 17
 18    Example usage:
 19    ```python
 20    import json
 21    from overturetoosm import process_place
 22
 23    with open("overture.geojson", "r", encoding="utf-8") as f:
 24        contents: dict = json.load(f)
 25
 26        for feature in contents["features"]:
 27            feature["properties"] = process_place(feature["properties"], confidence=0.5)
 28
 29    with open("overture_out.geojson", "w+", encoding="utf-8") as x:
 30        json.dump(contents, x, indent=4)
 31    ```
 32    Args:
 33        props (dict): The feature properties from the Overture GeoJSON.
 34        region_tag (str, optional): What tag to convert Overture's `region` tag to.
 35            Defaults to `addr:state`.
 36        confidence (float, optional): The minimum confidence level. Defaults to 0.0.
 37        unmatched (Literal["error", "force", "ignore"], optional): How to handle
 38            unmatched Overture categories. The "error" option raises an UnmatchedError
 39            exception, "force" puts the category into the `type` key, and "ignore"
 40            only returns other properties. Defaults to "ignore".
 41
 42    Returns:
 43        dict[str, str]: The reshaped and converted properties in OSM's flat str:str schema.
 44
 45    Raises:
 46        `overturetoosm.objects.UnmatchedError`: Raised if `unmatched` is set to `error` and
 47            the Overture category has no OSM definition.
 48        `overturetoosm.objects.ConfidenceError`: Raised if the confidence level is set
 49            above a feature's confidence.
 50    """
 51    new_props = {}
 52    prop_obj = PlaceProps(**props)
 53    if prop_obj.confidence < confidence:
 54        raise ConfidenceError(confidence, prop_obj.confidence)
 55
 56    if prop_obj.categories:
 57        prim = places_tags.get(prop_obj.categories.main)
 58        if prim:
 59            new_props = {**new_props, **prim}
 60        elif unmatched == "force":
 61            new_props["type"] = prop_obj.categories.main
 62        elif unmatched == "error":
 63            raise UnmatchedError(prop_obj.categories.main)
 64
 65    if prop_obj.names.primary:
 66        new_props["name"] = prop_obj.names.primary
 67
 68    if prop_obj.phones is not None:
 69        new_props["phone"] = prop_obj.phones[0]
 70
 71    if prop_obj.websites is not None:
 72        new_props["website"] = str(prop_obj.websites[0])
 73
 74    if add := prop_obj.addresses[0]:
 75        if add.freeform:
 76            new_props["addr:street_address"] = add.freeform
 77        if add.country:
 78            new_props["addr:country"] = add.country
 79        if add.postcode:
 80            new_props["addr:postcode"] = add.postcode
 81        if add.locality:
 82            new_props["addr:city"] = add.locality
 83        if add.region:
 84            new_props[region_tag] = add.region
 85
 86    if prop_obj.sources:
 87        new_props["source"] = (
 88            ", ".join({i.dataset for i in prop_obj.sources}) + " via overturetoosm"
 89        )
 90
 91    if prop_obj.socials is not None:
 92        for social in prop_obj.socials:
 93            social_str = str(social)
 94            if "facebook" in social_str:
 95                new_props["contact:facebook"] = social_str
 96            elif "twitter" in str(social):
 97                new_props["contact:twitter"] = social_str
 98
 99    if prop_obj.brand:
100        new_props["brand"] = prop_obj.brand.names.primary
101        new_props["brand:wikidata"] = prop_obj.brand.wikidata
102
103    return new_props

Convert Overture's places properties to OSM tags.

Example usage:

import json
from overturetoosm import process_place

with open("overture.geojson", "r", encoding="utf-8") as f:
    contents: dict = json.load(f)

    for feature in contents["features"]:
        feature["properties"] = process_place(feature["properties"], confidence=0.5)

with open("overture_out.geojson", "w+", encoding="utf-8") as x:
    json.dump(contents, x, indent=4)
Arguments:
  • props (dict): The feature properties from the Overture GeoJSON.
  • region_tag (str, optional): What tag to convert Overture's region tag to. Defaults to addr:state.
  • confidence (float, optional): The minimum confidence level. Defaults to 0.0.
  • unmatched (Literal["error", "force", "ignore"], optional): How to handle unmatched Overture categories. The "error" option raises an UnmatchedError exception, "force" puts the category into the type key, and "ignore" only returns other properties. Defaults to "ignore".
Returns:

dict[str, str]: The reshaped and converted properties in OSM's flat str:str schema.

Raises:
def process_building(props: dict, confidence: float = 0.0) -> Dict[str, str]:
 9def process_building(
10    props: dict,
11    confidence: float = 0.0,
12) -> Dict[str, str]:
13    """Convert Overture's building properties to OSM tags.
14
15    Args:
16        props (dict): The feature properties from the Overture GeoJSON.
17        confidence (float, optional): The minimum confidence level. Defaults to 0.0.
18
19    Returns:
20        Dict[str, str]: The reshaped and converted properties in OSM's flat str:str schema.
21
22    Raises:
23        `overturetoosm.objects.ConfidenceError`: Raised if the confidence level is set
24            above a feature's confidence.
25    """
26    new_props = {}
27    prop_obj = BuildingProps(**props)
28    confidences = [source.confidence for source in prop_obj.sources]
29    if any(conf < confidence for conf in confidences):
30        raise ConfidenceError(confidence, max(confidences))
31
32    new_props["building"] = prop_obj.class_
33
34    new_props["source"] = source_statement(prop_obj.sources)
35
36    obj_dict = prop_obj.model_dump(exclude_none=True).items()
37    new_props.update(
38        {
39            k.replace("facade", "building")
40            .replace("_", ":")
41            .replace("color", "colour"): v
42            for k, v in obj_dict
43            if k.startswith(("roof", "facade"))
44        }
45    )
46    new_props.update({k: v for k, v in obj_dict if k.endswith("height")})
47
48    if prop_obj.is_underground:
49        new_props["location"] = "underground"
50    if prop_obj.num_floors:
51        new_props["building:levels"] = prop_obj.num_floors
52    if prop_obj.num_floors_underground:
53        new_props["building:levels:underground"] = prop_obj.num_floors_underground
54    if prop_obj.min_floor:
55        new_props["building:min_level"] = prop_obj.min_floor
56    return new_props

Convert Overture's building properties to OSM tags.

Arguments:
  • props (dict): The feature properties from the Overture GeoJSON.
  • confidence (float, optional): The minimum confidence level. Defaults to 0.0.
Returns:

Dict[str, str]: The reshaped and converted properties in OSM's flat str:str schema.

Raises:
def process_address(props: dict, style: str = 'US') -> Dict[str, str]:
 8def process_address(
 9    props: dict,
10    style: str = "US",
11) -> Dict[str, str]:
12    """Convert Overture's address properties to OSM tags.
13
14    Args:
15        props (dict): The feature properties from the Overture GeoJSON.
16        style (str, optional): How to handle the `address_levels` field. Open
17            a pull request or issue to add support for other regions. Defaults to "US".
18
19    Returns:
20        Dict[str, str]: The reshaped and converted properties in OSM's flat str:str schema.
21    """
22    bad_tags = ["version", "theme", "type", "address_levels"]
23    prop = AddressProps(**props)
24
25    obj_dict = prop.model_dump(exclude_none=True, by_alias=True)
26
27    if obj_dict["address_levels"] and len(obj_dict["address_levels"]) > 0:
28        if style == "US":
29            obj_dict["addr:state"] = str(obj_dict["address_levels"][0]["value"])
30
31    for tag in bad_tags:
32        obj_dict.pop(tag, None)
33
34    return obj_dict

Convert Overture's address properties to OSM tags.

Arguments:
  • props (dict): The feature properties from the Overture GeoJSON.
  • style (str, optional): How to handle the address_levels field. Open a pull request or issue to add support for other regions. Defaults to "US".
Returns:

Dict[str, str]: The reshaped and converted properties in OSM's flat str:str schema.

def process_geojson( geojson: dict, fx: Callable, confidence: float = 0.0, options: Optional[dict] = None) -> dict:
13def process_geojson(
14    geojson: dict,
15    fx: Callable,
16    confidence: float = 0.0,
17    options: Optional[dict] = None,
18) -> dict:
19    """Convert an Overture `place` GeoJSON to one that follows OSM's schema.
20
21    Example usage:
22    ```python
23    import json
24    from overturetoosm import process_geojson
25
26    with open("overture.geojson", "r", encoding="utf-8") as f:
27        contents: dict = json.load(f)
28        geojson = process_geojson(contents, fx=process_building)
29
30    with open("overture_out.geojson", "w+", encoding="utf-8") as x:
31        json.dump(geojson, x, indent=4)
32    ```
33    Args:
34        geojson (dict): The dictionary representation of the Overture GeoJSON.
35        fx (Callable): The function to apply to each feature.
36        confidence (float, optional): The minimum confidence level. Defaults to 0.0.
37        options (dict, optional): Function-specific options to pass as arguments to
38            the `fx` function.
39
40    Returns:
41        dict: The dictionary representation of the GeoJSON that follows OSM's schema.
42    """
43    options = options or {}
44    new_features = []
45    for feature in geojson["features"]:
46        try:
47            feature["properties"] = fx(feature["properties"], confidence, **options)
48            new_features.append(feature)
49        except (ConfidenceError, UnmatchedError):
50            pass
51
52    geojson["features"] = new_features
53    return geojson

Convert an Overture place GeoJSON to one that follows OSM's schema.

Example usage:

import json
from overturetoosm import process_geojson

with open("overture.geojson", "r", encoding="utf-8") as f:
    contents: dict = json.load(f)
    geojson = process_geojson(contents, fx=process_building)

with open("overture_out.geojson", "w+", encoding="utf-8") as x:
    json.dump(geojson, x, indent=4)
Arguments:
  • geojson (dict): The dictionary representation of the Overture GeoJSON.
  • fx (Callable): The function to apply to each feature.
  • confidence (float, optional): The minimum confidence level. Defaults to 0.0.
  • options (dict, optional): Function-specific options to pass as arguments to the fx function.
Returns:

dict: The dictionary representation of the GeoJSON that follows OSM's schema.