Passed
Pull Request — dev (#31)
by Stephan
01:10
created

openstreetmap   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 100
dl 0
loc 178
rs 10
c 0
b 0
f 0
wmc 5

3 Functions

Rating   Name   Duplication   Size   Complexity  
A download_pbf_file() 0 11 2
A to_postgres() 0 43 1
B add_metadata() 0 97 2
1
"""The central module containing all code dealing with importing OSM data.
2
3
This module either directly contains the code dealing with importing OSM
4
data, or it re-exports everything needed to handle it. Please refrain
5
from importing code from any modules below this one, because it might
6
lead to unwanted behaviour.
7
8
If you have to import code from a module below this one because the code
9
isn't exported from this module, please file a bug, so we can fix this.
10
"""
11
12
from urllib.request import urlretrieve
13
import json
14
import os
15
import subprocess
16
import time
17
18
from egon.data import db
19
import egon.data.config
20
21
22
def download_pbf_file():
23
    """Download OpenStreetMap `.pbf` file."""
24
    data_config = egon.data.config.datasets()
25
    osm_config = data_config["openstreetmap"]["original_data"]
26
27
    target_file = os.path.join(
28
        os.path.dirname(__file__), osm_config["target"]["path"]
29
    )
30
31
    if not os.path.isfile(target_file):
32
        urlretrieve(osm_config["source"]["url"], target_file)
33
34
35
def to_postgres(num_processes=4, cache_size=4096):
36
    """Import OSM data from a Geofabrik `.pbf` file into a PostgreSQL database.
37
38
    Parameters
39
    ----------
40
    num_processes : int, optional
41
        Number of parallel processes used for processing during data import
42
    cache_size: int, optional
43
        Memory used during data import
44
45
    """
46
    # Read database configuration from docker-compose.yml
47
    docker_db_config = db.credentials()
48
49
    # Get dataset config
50
    data_config = egon.data.config.datasets()
51
    osm_config = data_config["openstreetmap"]["original_data"]
52
    input_file = os.path.join(
53
        os.path.dirname(__file__), osm_config["target"]["path"]
54
    )
55
56
    # Prepare osm2pgsql command
57
    cmd = [
58
        "osm2pgsql",
59
        "--create",
60
        "--slim",
61
        "--hstore-all",
62
        f"--number-processes {num_processes}",
63
        f"--cache {cache_size}",
64
        f"-H {docker_db_config['HOST']} -P {docker_db_config['PORT']} "
65
        f"-d {docker_db_config['POSTGRES_DB']} "
66
        f"-U {docker_db_config['POSTGRES_USER']}",
67
        f"-p {osm_config['target']['table_prefix']}",
68
        f"-S {osm_config['source']['stylefile']}",
69
        f"{input_file}",
70
    ]
71
72
    # Execute osm2pgsql for import OSM data
73
    subprocess.run(
74
        " ".join(cmd),
75
        shell=True,
76
        env={"PGPASSWORD": docker_db_config["POSTGRES_PASSWORD"]},
77
        cwd=os.path.dirname(__file__),
78
    )
79
80
81
def add_metadata():
82
    """Writes metadata JSON string into table comment."""
83
    # Prepare variables
84
    osm_config = egon.data.config.datasets()["openstreetmap"]
85
    spatial_and_date = os.path.basename(
86
        osm_config["original_data"]["target"]["path"]
87
    ).split("-")
88
    spatial_extend = spatial_and_date[0]
89
    osm_data_date = (
90
        "20"
91
        + spatial_and_date[1][0:2]
92
        + "-"
93
        + spatial_and_date[1][2:4]
94
        + "-"
95
        + spatial_and_date[1][4:6]
96
    )
97
    osm_url = osm_config["original_data"]["source"]["url"]
98
99
    # Insert metadata for each table
100
    licenses = [
101
        {
102
            "name": "Open Data Commons Open Database License 1.0",
103
            "title": "",
104
            "path": "https://opendatacommons.org/licenses/odbl/1.0/",
105
            "instruction": (
106
                "You are free: To Share, To Create, To Adapt;"
107
                " As long as you: Attribute, Share-Alike, Keep open!"
108
            ),
109
            "attribution": "© Reiner Lemoine Institut",
110
        }
111
    ]
112
    for table in osm_config["processed"]["tables"]:
113
        table_suffix = table.split("_")[1]
114
        meta = {
115
            "title": f"OpenStreetMap (OSM) - Germany - {table_suffix}",
116
            "description": (
117
                "OpenStreetMap is a free, editable map of the"
118
                " whole world that is being built by volunteers"
119
                " largely from scratch and released with"
120
                " an open-content license."
121
            ),
122
            "language": ["EN", "DE"],
123
            "spatial": {
124
                "location": "",
125
                "extent": f"{spatial_extend}",
126
                "resolution": "",
127
            },
128
            "temporal": {
129
                "referenceDate": f"{osm_data_date}",
130
                "timeseries": {
131
                    "start": "",
132
                    "end": "",
133
                    "resolution": "",
134
                    "alignment": "",
135
                    "aggregationType": "",
136
                },
137
            },
138
            "sources": [
139
                {
140
                    "title": (
141
                        "Geofabrik - Download - OpenStreetMap Data Extracts"
142
                    ),
143
                    "description": (
144
                        'Data dump taken on "referenceDate",'
145
                        f" i.e. {osm_data_date}."
146
                        " A subset of this is selected using osm2pgsql"
147
                        ' using the style file "oedb.style".'
148
                    ),
149
                    "path": f"{osm_url}",
150
                    "licenses": licenses,
151
                }
152
            ],
153
            "licenses": licenses,
154
            "contributors": [
155
                {
156
                    "title": "Guido Pleßmann",
157
                    "email": "http://github.com/gplssm",
158
                    "date": time.strftime("%Y-%m-%d"),
159
                    "object": "",
160
                    "comment": "Imported data",
161
                }
162
            ],
163
            "metaMetadata": {
164
                "metadataVersion": "OEP-1.4.0",
165
                "metadataLicense": {
166
                    "name": "CC0-1.0",
167
                    "title": "Creative Commons Zero v1.0 Universal",
168
                    "path": (
169
                        "https://creativecommons.org/publicdomain/zero/1.0/"
170
                    ),
171
                },
172
            },
173
        }
174
175
        meta_json = "'" + json.dumps(meta) + "'"
176
177
        db.submit_comment(meta_json, "openstreetmap", table)
178