Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEV] refactor osm_maps_functions.py like geofabrik.py - using a interface and two implementing classes #194

Merged
merged 1 commit into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 12 additions & 8 deletions tests/test_osm_maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import unittest

# import custom python packages
from wahoomc.osm_maps_functions import OsmData
from wahoomc.osm_maps_functions import CountryOsmData, XYOsmData
from wahoomc.osm_maps_functions import OsmMaps
from wahoomc.osm_maps_functions import get_xy_coordinates_from_input
# from wahoomc.osm_maps_functions import TileNotFoundError
Expand Down Expand Up @@ -106,14 +106,16 @@ def process_and_check_border_countries(self, inp_val, calc_border_c, exp_result,
"""

o_input_data = InputData()
o_input_data.process_border_countries = calc_border_c

if inp_mode == 'country':
o_input_data.country = inp_val
o_osm_data = CountryOsmData(o_input_data)
elif inp_mode == 'xy_coordinate':
o_input_data.xy_coordinates = inp_val
o_input_data.process_border_countries = calc_border_c
o_osm_data = XYOsmData(o_input_data)

o_osm_data = OsmData()
o_osm_data.process_input_of_the_tool(o_input_data)
o_osm_data.process_input_of_the_tool()

result = o_osm_data.border_countries

Expand All @@ -138,8 +140,8 @@ def test_input_country_malta(self):
o_input_data = InputData()
o_input_data.country = 'malta'

o_osm_data = OsmData()
o_osm_data.process_input_of_the_tool(o_input_data)
o_osm_data = CountryOsmData(o_input_data)
o_osm_data.process_input_of_the_tool()

result = o_osm_data.country_name
self.assertEqual(result, 'malta')
Expand Down Expand Up @@ -211,8 +213,10 @@ def test_version_and_tags_of_country_config_file(self):
# prevent from downloading land_polygons each time
o_input_data.max_days_old = 1000

o_osm_data = OsmData()
o_downloader = o_osm_data.process_input_of_the_tool(o_input_data)
o_osm_data = CountryOsmData(o_input_data)
o_osm_data.process_input_of_the_tool()

o_downloader = o_osm_data.get_downloader()

# download files marked for download to fill up map_file per country to write to config
o_downloader.download_files_if_needed()
Expand Down
11 changes: 8 additions & 3 deletions wahoomc/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from wahoomc.downloader import download_tooling

from wahoomc.osm_maps_functions import OsmMaps
from wahoomc.osm_maps_functions import OsmData
from wahoomc.osm_maps_functions import CountryOsmData, XYOsmData

# logging used in the terminal output:
# # means top-level command
Expand Down Expand Up @@ -55,9 +55,14 @@ def run(run_level):
# Is there something to do?
o_input_data.is_required_input_given_or_exit(issue_message=True)

o_osm_data = OsmData()
if o_input_data.country:
o_osm_data = CountryOsmData(o_input_data)
elif o_input_data.xy_coordinates:
o_osm_data = XYOsmData(o_input_data)

# Check for not existing or expired files. Mark for download, if dl is needed
o_downloader = o_osm_data.process_input_of_the_tool(o_input_data)
o_osm_data.process_input_of_the_tool()
o_downloader = o_osm_data.get_downloader()

# Download files marked for download
o_downloader.download_files_if_needed()
Expand Down
234 changes: 146 additions & 88 deletions wahoomc/osm_maps_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,148 +89,206 @@ def get_timestamp_last_changed(file_path):
return datetime.fromtimestamp(chg_time).isoformat()


class OsmData(): # pylint: disable=too-few-public-methods
class InformalOsmDataInterface:
"""
object with all internal parameters to process maps
"""

def __init__(self):
def __init__(self, o_input_data):
"""
xxx
steps in constructor:
1. take over input paramters (force_processing is changed in the function further down)
2. check + download geofabrik file (always)
"""
self.force_processing = False
self.tiles = []
self.border_countries = {}
self.country_name = ''

def process_input_of_the_tool(self, o_input_data):
self.o_downloader = Downloader(
o_input_data.max_days_old, o_input_data.force_download, self.border_countries)
# takeover what is given by user first for force_processing
self.force_processing = o_input_data.force_processing
self.process_border_countries = o_input_data.process_border_countries

log.info('-' * 80)

# geofabrik file
if self.o_downloader.should_geofabrik_file_be_downloaded():
self.force_processing = True
self.o_downloader.download_geofabrik_file()

def process_input_of_the_tool(self):
"""
Process input: get relevant tiles and if border countries should be calculated
The three primary inputs are giving by a separate value each and have separate processing:
1. country name
2. x/y combinations
"""

# Check for not existing or expired files. Mark for download, if dl is needed
# - land polygons file
# - .osm.pbf files
def calc_tiles(self):
"""
calculate relevant tiles for input country or xy coordinate
"""

steps in this function:
1. take over input paramters (force_processing is changed in the function further down)
2. check + download geofabrik file if geofabrik-processing
3. calculate relevant tiles for map creation
4. calculate border countries for map creation
5. evaluate the country-name for folder cration during processing
6. calculate if force_processing should be set to true
def calc_border_countries(self):
"""
calculate the border countries for the given tiles. i.e.
- if CLI/GUI input by user
- if processing x/y coordinates
"""
log.info('# Determine involved/border countries')

o_downloader = Downloader(
o_input_data.max_days_old, o_input_data.force_download, self.border_countries)
# takeover what is given by user first for force_processing
self.force_processing = o_input_data.force_processing
# Build list of countries needed
for tile in self.tiles:
for country in tile['countries']:
if country not in self.border_countries:
self.border_countries[country] = {}

log.info('-' * 80)
def log_border_countries(self):
"""
write calculated border countries/involved countries to log
"""
for country in self.border_countries:
log.info('+ Involved country: %s', country)

# geofabrik file
if o_downloader.should_geofabrik_file_be_downloaded():
# input can be only one country, if there are more than one,
# border countries must be selected
if len(self.border_countries) > 1:
log.info('+ Border countries will be processed')

def get_downloader(self):
"""
steps in this function:
1. Check for not existing or expired files. Mark for download, if dl is needed
- land polygons file
- .osm.pbf files
2. Calculate if force_processing should be set to true
"""
# calc force processing
# Check for not existing or expired files. Mark for download, if dl is needed
self.o_downloader.check_land_polygons_file()
self.o_downloader.check_osm_pbf_file()

# If one of the files needs to be downloaded, reprocess all files
if self.o_downloader.need_to_dl:
self.force_processing = True
o_downloader.download_geofabrik_file()

return self.o_downloader


class CountryOsmData(InformalOsmDataInterface):
"""
object with all internal parameters to process maps for countries
"""

def __init__(self, o_input_data):
super().__init__(o_input_data)
self.input_country = o_input_data.country

self.o_geofabrik = CountryGeofabrik(self.input_country)

def process_input_of_the_tool(self):
"""
steps in this function:
1. calculate relevant tiles for map creation
2. calculate border countries for map creation
3. evaluate the country-name for folder cration during processing
"""

# calc tiles
if o_input_data.country:
self.calc_tiles_country(o_input_data)
elif o_input_data.xy_coordinates:
self.calc_tiles_xy(o_input_data)
self.calc_tiles()

# calc border countries
log.info('-' * 80)
if o_input_data.country:
self.calc_border_countries_country(o_input_data)
elif o_input_data.xy_coordinates:
self.calc_border_countries()
self.calc_border_countries()
# log border countries when and when not calculated to output the processed country(s)
self.log_border_countries()

# calc country name
if o_input_data.country:
# country name is the input argument
self.country_name = o_input_data.country
elif o_input_data.xy_coordinates:
self.calc_country_name_xy()

# calc force processing
# Check for not existing or expired files. Mark for download, if dl is needed
o_downloader.check_land_polygons_file()
o_downloader.check_osm_pbf_file()

# If one of the files needs to be downloaded, reprocess all files
if o_downloader.need_to_dl:
self.force_processing = True

return o_downloader
self.calc_country_name()

def calc_tiles_country(self, o_input_data):
def calc_tiles(self):
"""
option 1: input a country as parameter, e.g. germany
"""
log.info('# Input country: %s.', o_input_data.country)
log.info('# Input country: %s.', self.input_country)

# use Geofabrik-URL to calculate the relevant tiles
o_geofabrik = CountryGeofabrik(o_input_data.country)
self.tiles = o_geofabrik.get_tiles_of_wanted_map()
self.tiles = self.o_geofabrik.get_tiles_of_wanted_map()

def calc_tiles_xy(self, o_input_data):
"""
option 2: input a x/y combinations as parameter, e.g. 134/88 or 133/88,130/100
"""
log.info(
'# Input X/Y coordinates: %s.', o_input_data.xy_coordinates)

# use Geofabrik-URL to get the relevant tiles
xy_coordinates = get_xy_coordinates_from_input(
o_input_data.xy_coordinates)

o_geofabrik = XYGeofabrik(xy_coordinates)
# find the tiles for x/y combinations in the geofabrik json files
self.tiles = o_geofabrik.get_tiles_of_wanted_map()

def calc_border_countries_country(self, o_input_data):
def calc_border_countries(self):
"""
calculate the border countries for the given tiles when input is a country
- if CLI/GUI input by user
"""
if o_input_data.process_border_countries:
self.calc_border_countries()
if self.process_border_countries:
super().calc_border_countries()
# set the to-be-processed country as border country
else:
self.border_countries[o_input_data.country] = {}
self.border_countries[self.input_country] = {}

def calc_border_countries(self):
def calc_country_name(self):
"""
calculate the border countries for the given tiles. i.e.
- if CLI/GUI input by user
- if processing x/y coordinates
country name is the country
>1 countries are separated by underscore
"""
log.info('# Determine involved/border countries')
self.country_name = self.input_country

# Build list of countries needed
for tile in self.tiles:
for country in tile['countries']:
if country not in self.border_countries:
self.border_countries[country] = {}

def log_border_countries(self):
class XYOsmData(InformalOsmDataInterface):
"""
object with all internal parameters to process maps for XY coordinates
"""

def __init__(self, o_input_data):
super().__init__(o_input_data)
self.input_xy_coordinates = o_input_data.xy_coordinates

def process_input_of_the_tool(self):
"""
write calculated border countries/involved countries to log
Process input: get relevant tiles and if border countries should be calculated
The three primary inputs are giving by a separate value each and have separate processing:
1. country name
2. x/y combinations

# Check for not existing or expired files. Mark for download, if dl is needed
# - land polygons file
# - .osm.pbf files

steps in this function:
1. calculate relevant tiles for map creation
2. calculate border countries for map creation
3. evaluate the country-name for folder cration during processing
"""
for country in self.border_countries:
log.info('+ Involved country: %s', country)

# input can be only one country, if there are more than one,
# border countries must be selected
if len(self.border_countries) > 1:
log.info('+ Border countries will be processed')
# calc tiles
self.calc_tiles()

# calc border countries
log.info('-' * 80)
self.calc_border_countries()
# log border countries when and when not calculated to output the processed country(s)
self.log_border_countries()

# calc country name
self.calc_country_name()

def calc_tiles(self):
"""
option 2: input a x/y combinations as parameter, e.g. 134/88 or 133/88,130/100
"""
log.info('# Input X/Y coordinates: %s.', self.input_xy_coordinates)

# use Geofabrik-URL to get the relevant tiles
xy_coordinates = get_xy_coordinates_from_input(
self.input_xy_coordinates)

o_geofabrik = XYGeofabrik(xy_coordinates)
# find the tiles for x/y combinations in the geofabrik json files
self.tiles = o_geofabrik.get_tiles_of_wanted_map()

def calc_country_name_xy(self):
def calc_country_name(self):
"""
country name is the X/Y combinations separated by minus
>1 x/y combinations are separated by underscore
Expand Down