diff --git a/.gitignore b/.gitignore index 28208402..bd4b7173 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ osmconvert_tempfile.* **/__pycache__/* **/*.pyc **/*.DS_Store +**/*.py*.tmp # mac/unix diff --git a/.vscode/launch.json b/.vscode/launch.json index 7e86a94d..64f7c0ad 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,6 +8,8 @@ "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", "args": [ + "cli", + "-fi", "${workspaceRoot}/tests/json/germany-only1.json", "-md", "100", @@ -23,6 +25,8 @@ "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", "args": [ + "cli", + "-fi", "${workspaceRoot}/tests/json/germany-only1.json", "-tag", "tag-wahoo-hidrive2.xml", @@ -40,6 +44,8 @@ "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", "args": [ + "cli", + "-fi", "${workspaceRoot}/tests/json/germany-only2.json", "-md", "100", @@ -55,6 +61,8 @@ "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", "args": [ + "cli", + "-co", "germany" ] }, @@ -65,6 +73,8 @@ "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", "args": [ + "cli", + "-co", "malta", "-tag", "tag-wahoo.xml", @@ -81,6 +91,8 @@ "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", "args": [ + "cli", + "-co", "malta", "-tag", "tag-wahoo.xml", @@ -97,7 +109,9 @@ "request": "launch", "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", - "args": [] + "args": [ + "gui" + ] }, { "name": "cli help", @@ -116,6 +130,8 @@ "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", "args": [ + "cli", + "-co", "malta", "-tag", "tag-wahoo.xml", @@ -132,6 +148,8 @@ "program": "${workspaceRoot}/wahoo_map_creator.py", "console": "integratedTerminal", "args": [ + "cli", + "-co", "liechtenstein", "-tag", "tag-wahoo.xml", @@ -162,6 +180,42 @@ "C:\\VSCode\\python\\wahooMapsCreator\\output\\138\\100\\land.shp", "C:\\VSCode\\python\\wahooMapsCreator\\output\\138\\100\\land1.osm" ] + }, + { + "name": "x/y: 133/88", + "type": "python", + "request": "launch", + "program": "${workspaceRoot}/wahoo_map_creator.py", + "console": "integratedTerminal", + "args": [ + "cli", + "-xy", + "133/88" + ] + }, + { + "name": "x/y: 138/100 (malta)", + "type": "python", + "request": "launch", + "program": "${workspaceRoot}/wahoo_map_creator.py", + "console": "integratedTerminal", + "args": [ + "cli", + "-xy", + "138/100" + ] + }, + { + "name": "x/y: 138/100,133/88 (two tiles)", + "type": "python", + "request": "launch", + "program": "${workspaceRoot}/wahoo_map_creator.py", + "console": "integratedTerminal", + "args": [ + "cli", + "-xy", + "138/100,133/88" + ] } ] } \ No newline at end of file diff --git a/README.md b/README.md index a5717666..cf99fdd2 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,11 @@ Using Anaconda to setup a virtual Python environment is the fastest way to get w ## Run wahooMapsCreator via GUI ``` -python wahoo_map_creator.py +python wahoo_map_creator.py gui ``` via CLI ``` -python wahoo_map_creator.py malta +python wahoo_map_creator.py cli -co malta ``` A detailled description of the usage is documented [:computer: here](docs/USAGE.md#usage-of-wahoomapscreator) diff --git a/common_python/file_directory_functions.py b/common_python/file_directory_functions.py index 12639d6b..acda239b 100644 --- a/common_python/file_directory_functions.py +++ b/common_python/file_directory_functions.py @@ -6,6 +6,7 @@ # import official python packages import json import os +from os.path import isfile, join import subprocess import sys import zipfile @@ -83,11 +84,12 @@ def create_empty_directories(tiles_from_json): os.makedirs(outdir) -def read_json_file(json_file_path): +def read_json_file(json_file_path, logging = True): """ read the tiles from the given json file """ - print('\n# Read json file') + if logging: + print('\n# Read json file') with open(json_file_path) as json_file: tiles_from_json = json.load(json_file) @@ -96,10 +98,11 @@ def read_json_file(json_file_path): print('! Json file could not be opened.') sys.exit() - # logging - print( - f'+ Use json file {json_file.name} with {len(tiles_from_json)} tiles') - print('# Read json file: OK') + if logging: + # logging + print( + f'+ Use json file {json_file.name} with {len(tiles_from_json)} tiles') + print('# Read json file: OK') return tiles_from_json @@ -124,3 +127,42 @@ def write_to_file(file_path, request): with open(file_path, 'wb') as file_handle: for chunk in request.iter_content(chunk_size=1024*100): file_handle.write(chunk) + + +def get_folders_in_folder(folder): + """ + return foldernames of given folder without path as list + """ + onlyfolders = [f for f in os.listdir( + folder) if not isfile(join(folder, f))] + + return onlyfolders + + +def get_files_in_folder(folder): + """ + return filenames of given folder without path as list + """ + onlyfiles = [f for f in os.listdir(folder) if isfile(join(folder, f))] + + return onlyfiles + + +def get_filenames_of_jsons_in_folder(folder): + """ + return json-file filenames of given folder without path as list + """ + # log.debug('function: get_filenames_of_jsons_in_folder') + # log.debug('# Read available json files from directory: "%s"', folder) + + json_files = [] + + for file in get_files_in_folder(folder): + if file.endswith('.json'): + # filename = file.split('.')[0] + filename = os.path.splitext(file)[0] + json_files.extend([filename]) + + # log.debug('# Read available json files from directory: "%s" : OK', folder) + + return json_files diff --git a/common_python/input.py b/common_python/input.py index 011c0926..ff9a8ce9 100644 --- a/common_python/input.py +++ b/common_python/input.py @@ -16,6 +16,109 @@ from common_python import constants +def process_call_of_the_tool(): + """ + process CLI arguments + """ + # input argument creation and processing + desc = "Create up-to-date maps for your Wahoo ELEMNT and Wahoo ELEMNT BOLT" + parser_top = argparse.ArgumentParser(description=desc) + + subparsers = parser_top.add_subparsers(title='Choose mode', + description='choose the mode of using wahooMapsCreator. Either GUI or CLI.', + help='sub-command help', dest='subparser_name') + + # create the parser for the "gui" command + parser_gui = subparsers.add_parser( + 'gui', help='Start graphical user interface to select options') + + # create the parser for the "cli" command + parser_cli = subparsers.add_parser( + 'cli', help='Run the tool via command line interface') + + # group: primary input parameters to create map for. One needs to be given + primary_args = parser_cli.add_argument_group( + title='Primary input', description='Generate maps for...') + primary_args_excl = primary_args.add_mutually_exclusive_group( + required=True) + # country to create maps for + primary_args_excl.add_argument( + "-co", "--country", help="country to generate maps for") + # X/Y coordinates to create maps for + primary_args_excl.add_argument( + "-xy", "--xy_coordinates", help="x/y coordinates to generate maps for. Example: 133/88") + # file to create maps for + primary_args_excl.add_argument( + "-fi", "--tile_file", help="file with tiles to generate maps for") + + # group: options for map generation + options_args = parser_cli.add_argument_group( + title='Options', description='Options for map generation') + # Maximum age of source maps or land shape files before they are redownloaded + options_args.add_argument('-md', '--maxdays', type=int, default=InputData().max_days_old, + help="maximum age of source maps and other files") + # Calculate also border countries of input country or not + options_args.add_argument('-bc', '--bordercountries', action='store_true', + help="process whole tiles which involve border countries") + # Force download of source maps and the land shape file + # If False use Max_Days_Old to check for expired maps + # If True force redownloading of maps and landshape + options_args.add_argument('-fd', '--forcedownload', action='store_true', + help="force download of files") + # Force (re)processing of source maps and the land shape file + # If False only process files if not existing + # If True force processing of files + options_args.add_argument('-fp', '--forceprocessing', action='store_true', + help="force processing of files") + # Save uncompressed maps for Cruiser if True + options_args.add_argument('-c', '--cruiser', action='store_true', + help="save uncompressed maps for Cruiser") + # specify the file with tags to keep in the output // file needs to be in common_resources + options_args.add_argument('-tag', '--tag_wahoo_xml', default=InputData().tag_wahoo_xml, + help="file with tags to keep in the output") + # specify the file with tags to keep in the output // file needs to be in common_resources + options_args.add_argument('-om', '--only_merge', action='store_true', + help="only merge, do no other processing") + # option to keep the /output/country/ and /output/country-maps folders in the output + options_args.add_argument('-km', '--keep_map_folders', action='store_true', + help="keep the country and country-maps folders in the output") + # option to calculate tiles to process based on Geofabrik index-v1.json file + options_args.add_argument('-gt', '--geofabrik_tiles', action='store_true', + help="calculate tiles based on geofabrik index-v1.json file") + + args = parser_top.parse_args() + + # process depending on GUI or CLI processing. + # returns the input parameters in both cases + if args.subparser_name == 'gui': + # Prevents the initialisation of the graphical GUI on WSL. + if 'microsoft' in uname().release: + sys.exit("GUI can not be startet because no graphical interface is available. Start with 'wahoo_maps_creator.py cli -h' or 'wahoo_maps_creator.py -h' to see command line options.") + return + + o_input_data = GuiInput().start_gui() + + # cli processing + else: + o_input_data = InputData() + o_input_data.country = args.country + o_input_data.xy_coordinates = args.xy_coordinates + o_input_data.tile_file = args.tile_file + o_input_data.max_days_old = args.maxdays + + o_input_data.border_countries = args.bordercountries + o_input_data.force_download = args.forcedownload + o_input_data.force_processing = args.forceprocessing + o_input_data.geofabrik_tiles = args.geofabrik_tiles + + o_input_data.tag_wahoo_xml = args.tag_wahoo_xml + o_input_data.only_merge = args.only_merge + o_input_data.keep_map_folders = args.keep_map_folders + o_input_data.save_cruiser = args.cruiser + + return o_input_data + + def create_checkbox(self, default_value, description, row): """ this is a reuse function for creating checkboxes. @@ -42,6 +145,8 @@ class InputData(): def __init__(self): self.country = "" + self.xy_coordinates = "" + self.tile_file = "" self.max_days_old = 14 self.force_download = False @@ -63,10 +168,13 @@ def __init__(self): def is_required_input_given_or_exit(self, issue_message): """ - check, if the minimal required arguments (acutally country) is given. + check, if the minimal required arguments is given: + - country + - x/y coordinates + - file with tile coordinates If not, depending on the import parameter, the """ - if self.country == "none" or self.country == "": + if (self.country in ('None', '') and self.xy_coordinates in ('None', '') and self.tile_file in ('None', '')): if issue_message: sys.exit("Nothing to do. Start with -h or --help to see command line options." "Or in the GUI select a country to create maps for.") @@ -76,24 +184,15 @@ def is_required_input_given_or_exit(self, issue_message): return True -class Input(tk.Tk): +class GuiInput(tk.Tk): """ - This is the class to proces user-input via CLI and GUI + This is the class to proces user-input via GUI """ def __init__(self, *args, **kwargs): self.o_input_data = InputData() - if 'microsoft' in uname().release: - self.gui_mode = False - return - - if len(sys.argv) == 1: - self.gui_mode = True - - tk.Tk.__init__(self, *args, **kwargs) - else: - self.gui_mode = False + tk.Tk.__init__(self, *args, **kwargs) def start_gui(self): """ @@ -104,7 +203,7 @@ def start_gui(self): # start GUI self.mainloop() - if self.o_input_data.is_required_input_given_or_exit(False): + if self.o_input_data.is_required_input_given_or_exit(issue_message=False): return self.o_input_data def build_gui(self): @@ -185,70 +284,6 @@ def switch_reload(self, event): else: tab1.first.en_max_days_old.configure(state=tk.NORMAL) - def cli_arguments(self): - """ - process CLI arguments - """ - - o_input_data = InputData() - - # input argument creation and processing - desc = "Create up-to-date maps for your Wahoo ELEMNT and Wahoo ELEMNT BOLT" - parser = argparse.ArgumentParser(description=desc) - - # country or file to create maps for - parser.add_argument("country", help="country to generate maps for") - # Maximum age of source maps or land shape files before they are redownloaded - parser.add_argument('-md', '--maxdays', type=int, default=o_input_data.max_days_old, - help="maximum age of source maps and other files") - # Calculate also border countries of input country or not - parser.add_argument('-bc', '--bordercountries', action='store_true', - help="process whole tiles which involve border countries") - # Force download of source maps and the land shape file - # If False use Max_Days_Old to check for expired maps - # If True force redownloading of maps and landshape - parser.add_argument('-fd', '--forcedownload', action='store_true', - help="force download of files") - # Force (re)processing of source maps and the land shape file - # If False only process files if not existing - # If True force processing of files - parser.add_argument('-fp', '--forceprocessing', action='store_true', - help="force processing of files") - # Save uncompressed maps for Cruiser if True - parser.add_argument('-c', '--cruiser', action='store_true', - help="save uncompressed maps for Cruiser") - # specify the file with tags to keep in the output // file needs to be in common_resources - parser.add_argument('-tag', '--tag_wahoo_xml', default=self.o_input_data.tag_wahoo_xml, - help="file with tags to keep in the output") - # specify the file with tags to keep in the output // file needs to be in common_resources - parser.add_argument('-om', '--only_merge', action='store_true', - help="only merge, do no other processing") - # option to keep the /output/country/ and /output/country-maps folders in the output - parser.add_argument('-km', '--keep_map_folders', action='store_true', - help="keep the country and country-maps folders in the output") - # option to calculate tiles to process based on Geofabrik index-v1.json file - parser.add_argument('-gt', '--geofabrik_tiles', action='store_true', - help="calculate tiles based on geofabrik index-v1.json file") - - # set instance-attributes of class - args = parser.parse_args() - - o_input_data = InputData() - o_input_data.country = args.country - o_input_data.max_days_old = args.maxdays - - o_input_data.border_countries = args.bordercountries - o_input_data.force_download = args.forcedownload - o_input_data.force_processing = args.forceprocessing - o_input_data.geofabrik_tiles = args.geofabrik_tiles - - o_input_data.tag_wahoo_xml = args.tag_wahoo_xml - o_input_data.only_merge = args.only_merge - o_input_data.keep_map_folders = args.keep_map_folders - o_input_data.save_cruiser = args.cruiser - - return o_input_data - class ComboboxesEntryField(tk.Frame): """ diff --git a/common_python/osm_maps_functions.py b/common_python/osm_maps_functions.py index f751460f..af5c1853 100644 --- a/common_python/osm_maps_functions.py +++ b/common_python/osm_maps_functions.py @@ -22,6 +22,46 @@ from common_python.geofabrik import Geofabrik +def get_xy_coordinates_from_input(input_xy_coordinates): + """ + extract/split x/y combinations by given X/Y coordinates. + input should be "188/88" or for multiple values "188/88,100/10,109/99". + returns a list of x/y combinations as integers + """ + + xy_combinations = [] + + # split by "," first for multiple x/y combinations, then by "/" for x and y value + for xy_coordinate in input_xy_coordinates.split(","): + splitted = xy_coordinate.split("/") + + if len(splitted) == 2: + xy_combinations.append( + {"x": int(splitted[0]), "y": int(splitted[1])}) + + return xy_combinations + + +def get_tile_by_one_xy_combination_from_jsons(xy_combination): + """ + get tile from json files by given X/Y coordinate combination + """ + # go through all files in all folders of the "json" directory + file_path_jsons = os.path.join(fd_fct.COMMON_DIR, 'json') + + for folder in fd_fct.get_folders_in_folder(file_path_jsons): + for file in fd_fct.get_filenames_of_jsons_in_folder(os.path.join(file_path_jsons, folder)): + + # get content of json in folder + content = fd_fct.read_json_file( + os.path.join(file_path_jsons, folder, file + '.json'), logging = False) + + # check tiles values against input x/y combination + for tile in content: + if tile['x'] == xy_combination['x'] and tile['y'] == xy_combination['y']: + return tile + + class OsmMaps: """ This is a OSM data class @@ -30,7 +70,7 @@ class OsmMaps: osmosis_win_file_path = os.path.join( fd_fct.TOOLING_WIN_DIR, 'Osmosis', 'bin', 'osmosis.bat') - def __init__(self, oInputData): + def __init__(self, o_input_data): self.force_processing = '' # Number of workers for the Osmosis read binary fast function self.workers = '1' @@ -39,9 +79,9 @@ def __init__(self, oInputData): self.border_countries = {} self.country_name = '' - self.o_input_data = oInputData + self.o_input_data = o_input_data self.o_downloader = Downloader( - oInputData.max_days_old, oInputData.force_download) + o_input_data.max_days_old, o_input_data.force_download) if 8 * struct.calcsize("P") == 32: self.osmconvert_path = os.path.join( @@ -50,42 +90,83 @@ def __init__(self, oInputData): self.osmconvert_path = os.path.join( fd_fct.TOOLING_WIN_DIR, 'osmconvert64-0.8.8p') - def process_input(self, input_argument, calc_border_countries): + def process_input(self, calc_border_countries): """ - get relevant tiles for given input and calc border countries of these tiles + 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. .json file with tiles + 2. country name + 3. x/y combinations """ + # option 1: have a .json file as input parameter + if self.o_input_data.tile_file: + # logging + print(f'+ Input json file: {self.o_input_data.tile_file}.') - # logging - print(f'+ Input country or json file: {input_argument}.') + if os.path.isfile(self.o_input_data.tile_file): + self.tiles = fd_fct.read_json_file(self.o_input_data.tile_file) - # option 1: have a .json file as input parameter - if os.path.isfile(input_argument): - self.tiles = fd_fct.read_json_file(input_argument) + # country name is the last part of the input filename + self.country_name = os.path.split( + self.o_input_data.tile_file)[1][:-5] - # country name is the last part of the input filename - self.country_name = os.path.split(input_argument)[1][:-5] + # calc border country when input tiles via json file + calc_border_countries = True # option 2: input a country as parameter, e.g. germany - else: + elif self.o_input_data.country: + # logging + print(f'+ Input country : {self.o_input_data.country}.') + # option 2a: use Geofabrik-URL to calculate the relevant tiles if self.o_input_data.geofabrik_tiles: self.force_processing = self.o_downloader.check_and_download_geofabrik_if_needed() - o_geofabrik = Geofabrik(input_argument) + o_geofabrik = Geofabrik(self.o_input_data.country) self.tiles = o_geofabrik.get_tiles_of_country() # option 2b: use static json files in the repo to calculate relevant tiles else: json_file_path = os.path.join(fd_fct.COMMON_DIR, 'json', - const_fct.get_region_of_country(input_argument), input_argument + '.json') + const_fct.get_region_of_country(self.o_input_data.country), self.o_input_data.country + '.json') self.tiles = fd_fct.read_json_file(json_file_path) # country name is the input argument - self.country_name = input_argument + self.country_name = self.o_input_data.country + + # option 3: input a x/y combinations as parameter, e.g. 134/88 or 133/88,130/100 + elif self.o_input_data.xy_coordinates: + # logging + print( + f'+ Input X/Y coordinates : {self.o_input_data.xy_coordinates}.') + + # # option 3a: use Geofabrik-URL to get the relevant tiles + if self.o_input_data.geofabrik_tiles: + sys.exit("X/Y coordinated via Geofabrik not implemented now") + + # option 3b: use static json files in the repo to get relevant tiles + else: + xy_coordinates = get_xy_coordinates_from_input( + self.o_input_data.xy_coordinates) + + # loop through x/y combinations and find each tile in the json files + for xy_comb in xy_coordinates: + self.tiles.append(get_tile_by_one_xy_combination_from_jsons( + xy_comb)) + + # country name is the X/Y combinations separated by minus + # >1 x/y combinations are separated by underscore + if not self.country_name: + self.country_name = f'{xy_comb["x"]}-{xy_comb["y"]}' + else: + self.country_name = f'{self.country_name}_{xy_comb["x"]}-{xy_comb["y"]}' + + # calc border country when input X/Y coordinates + calc_border_countries = True # Build list of countries needed self.border_countries = {} - if calc_border_countries or os.path.isfile(input_argument): + if calc_border_countries: self.calc_border_countries() else: self.border_countries[self.country_name] = {} diff --git a/docs/USAGE.md b/docs/USAGE.md index b027e044..bce40e52 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -5,35 +5,50 @@ wahooMapsCreator can be used in two different ways: Both ways support the same arguments to be used for the map-creation process. You can choose the arguments via GUI or as [CLI-arguments](#advanced-cli-usage). -### GUI (Graphical User Interface) +## Run wahooMapsCreator for your country +It might be a good idea to run wahooMapsCreator first for a small country e.g. Malta to check if everything is running fine. +In a next step you can run it for your own country. + +## GUI (Graphical User Interface) From the `root` folder of wahooMapsCreator, run: - - `python wahoo_map_creator.py` + - `python wahoo_map_creator.py gui` Set your arguments as required via the window: wahooMapsCreator GUI -### CLI (Command Line Interface) +## CLI (Command Line Interface) From the `root` folder of wahooMapsCreator, run: -- `python wahoo_map_creator.py ` +- `python wahoo_map_creator.py cli -co ` Examples: -- for Malta: `python wahoo_map_creator.py malta` -- for Ireland: `python wahoo_map_creator.py ireland` - -### Run wahooMapsCreator for your country -It might be a good idea to run wahooMapsCreator first for a small country e.g. Malta to check if everything is running fine. -In a next step you can run it for your own country. +- for Malta: `python wahoo_map_creator.py cli -co malta` +- for Ireland: `python wahoo_map_creator.py cli -co ireland` -### Advanced CLI-Usage -The script supports many arguments. +## Advanced CLI-Usage +The script supports many arguments via command line. For a list of all supported arguments, run: -- `python wahoo_map_creator.py -h` +- `python wahoo_map_creator.py cli -h` -Examples: +### Main arguments +**Create maps for a country** +- `python wahoo_map_creator.py cli -co ` + +**Create maps for X/Y coordinates** + +In particular for testing adjustments in configuration-files or coding it is helpful to create maps for only one tile or a handful of tiles! + +To create maps for only one tile and not a whole country, one can use the X/Y coordinates of that tile. X/Y coordinates can be retrieved from this in zoom-level 8: [link](http://tools.geofabrik.de/map/#8/50.3079/8.8026&type=Geofabrik_Standard&grid=1). +- `python wahoo_map_creator.py cli -xy ` + +### Examples - for Malta, download new maps if existing maps are older than 100 days and process files even if files exist - - `python wahoo_map_creator.py malta -md 100 -fp` + - `python wahoo_map_creator.py cli -co malta -md 100 -fp` - for Germany, download and process whole tiles which involves other countries than the given - - `python wahoo_map_creator.py germany -bc` \ No newline at end of file + - `python wahoo_map_creator.py cli -co germany -bc` +- to create maps for only one tile + - `python wahoo_map_creator.py cli -xy 134/88` +- for multiple tiles + - `python wahoo_map_creator.py cli -xy 134/88,133/88` \ No newline at end of file diff --git a/tests/test_cli.py b/tests/test_cli.py index c83be347..913f6219 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -3,7 +3,6 @@ """ import os import unittest -import platform # import custom python packages @@ -13,15 +12,30 @@ class TestCli(unittest.TestCase): tests for the CLI of the python file """ + def test_top_parser_help(self): + """ + tests, if help of top parser can be called + """ + + result = os.system("python wahoo_map_creator.py -h") + + self.assertEqual(result, 0) + def test_cli_help(self): """ - tests, if help can be called + tests, if CLI help can be called + """ + + result = os.system("python wahoo_map_creator.py cli -h") + + self.assertEqual(result, 0) + + def test_gui_help(self): + """ + tests, if GUI help can be called """ - if platform.system() == "Windows": - result = os.system("python wahoo_map_creator.py -h") - else: - result = os.system("python3 wahoo_map_creator.py -h") + result = os.system("python wahoo_map_creator.py gui -h") self.assertEqual(result, 0) diff --git a/tests/test_osm_maps.py b/tests/test_osm_maps.py index 554a6799..c7f549ea 100644 --- a/tests/test_osm_maps.py +++ b/tests/test_osm_maps.py @@ -9,6 +9,8 @@ # sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from common_python.osm_maps_functions import OsmMaps +from common_python.osm_maps_functions import get_tile_by_one_xy_combination_from_jsons +from common_python.osm_maps_functions import get_xy_coordinates_from_input from common_python.input import InputData from common_python import file_directory_functions as fd_fct from common_python import constants_functions as const_fct @@ -32,7 +34,8 @@ def test_input_country_malta(self): check, if the given input-parameter is saved to the OsmMaps instance """ - self.o_osm_maps.process_input('malta', True) + self.o_osm_maps.o_input_data.country = 'malta' + self.o_osm_maps.process_input(True) result = self.o_osm_maps.country_name self.assertEqual(result, 'malta') @@ -42,46 +45,53 @@ def test_input_json_file(self): Test a json file as input to the wahooMapsCreator check, if the given input-parameter is saved to the OsmMaps instance """ - json_file_path = os.path.join( self.file_path_test_json, 'germany-only1.json') - self.o_osm_maps.process_input(json_file_path, True) + + self.o_osm_maps.o_input_data.tile_file = json_file_path + self.o_osm_maps.process_input(True) result = self.o_osm_maps.country_name self.assertEqual(result, 'germany-only1') - def test_calc_border_countries(self): + def test_calc_border_countries_input_country(self): """ Test initialized border countries - of malta - of germany - - of a file with 1 tile - - of a file with 2 tiles """ # malta - self.process_and_check_border_countries('malta', True, {'malta': {}}) + self.process_and_check_border_countries( + 'malta', True, {'malta': {}}, 'country') # germany expected_result = {'czech_republic': {}, 'germany': {}, 'austria': {}, 'liechtenstein': {}, 'switzerland': {}, 'italy': {}, 'netherlands': {}, 'belgium': {}, 'luxembourg': {}, 'france': {}, 'poland': {}, 'denmark': {}} self.process_and_check_border_countries( - 'germany', True, expected_result) + 'germany', True, expected_result, 'country') + + def test_calc_border_countries_input_json_file(self): + """ + Test initialized border countries + - of a file with 1 tile + - of a file with 2 tiles + """ # one tile - france and germany input_file = os.path.join( self.file_path_test_json, 'germany-france-only1.json') expected_result = {'france': {}, 'germany': {}} self.process_and_check_border_countries( - input_file, True, expected_result) + input_file, True, expected_result, 'json_file') # two tiles - germany input_file = os.path.join( self.file_path_test_json, 'germany-only2.json') expected_result = {'germany': {}} self.process_and_check_border_countries( - input_file, True, expected_result) + input_file, True, expected_result, 'json_file') def test_calc_without_border_countries(self): """ @@ -93,24 +103,25 @@ def test_calc_without_border_countries(self): # germany self.process_and_check_border_countries( - 'germany', False, {'germany': {}}) + 'germany', False, {'germany': {}}, 'country') # china - self.process_and_check_border_countries('china', False, {'china': {}}) + self.process_and_check_border_countries( + 'china', False, {'china': {}}, 'country') # one tile - france and germany input_file = os.path.join( self.file_path_test_json, 'germany-france-only1.json') expected_result = {'france': {}, 'germany': {}} self.process_and_check_border_countries( - input_file, False, expected_result) + input_file, False, expected_result, 'json_file') # two tiles - germany input_file = os.path.join( self.file_path_test_json, 'germany-only2.json') expected_result = {'germany': {}} self.process_and_check_border_countries( - input_file, False, expected_result) + input_file, False, expected_result, 'json_file') def test_tiles_via_static_json(self): """ @@ -120,15 +131,19 @@ def test_tiles_via_static_json(self): 'right': 15.46875, 'bottom': 35.46067, 'countries': ['malta']}] self.calculate_tiles_via_static_json('malta', expected_tiles) - def process_and_check_border_countries(self, country, calc_border_countries, expected_result): + def process_and_check_border_countries(self, inp_val, calc_border_c, exp_result, inp_mode): """ - helper method to check a country without border countries + helper method to process a country or json file and check the calculated border countries """ + if inp_mode == 'country': + self.o_osm_maps.o_input_data.country = inp_val + elif inp_mode == 'json_file': + self.o_osm_maps.o_input_data.tile_file = inp_val - self.o_osm_maps.process_input(country, calc_border_countries) + self.o_osm_maps.process_input(calc_border_c) result = self.o_osm_maps.border_countries - self.assertEqual(result, expected_result) + self.assertEqual(result, exp_result) def calculate_tiles_via_static_json(self, country, expected_result): """ @@ -140,6 +155,43 @@ def calculate_tiles_via_static_json(self, country, expected_result): self.assertEqual(tiles, expected_result) + def test_splitting_of_single_xy_coordinate(self): + """ + use static json files in the repo to calculate relevant tiles + """ + xy_tuple = get_xy_coordinates_from_input("133/88") + + self.assertEqual(xy_tuple, [{"x": 133, "y": 88}]) + + xy_tuple = get_xy_coordinates_from_input("11/92") + + self.assertEqual(xy_tuple, [{"x": 11, "y": 92}]) + + xy_tuple = get_xy_coordinates_from_input("138/100") + expected_result = [{"x": 138, "y": 100}] + + self.assertEqual(xy_tuple, expected_result) + + def test_splitting_of_multiple_xy_coordinate(self): + """ + use static json files in the repo to calculate relevant tiles + """ + xy_tuple = get_xy_coordinates_from_input("133/88,138/100") + expected_result = [{"x": 133, "y": 88}, {"x": 138, "y": 100}] + + self.assertEqual(xy_tuple, expected_result) + + def test_get_tile_via_xy_coordinate(self): + """ + use static json files in the repo to calculate relevant tiles + """ + tile = get_tile_by_one_xy_combination_from_jsons({"x": 133, "y": 88}) + + expected_result = fd_fct.read_json_file( + '/Users/benjamin/VSCode/wahooMapsCreator/tests/json/germany-only9.json') + + self.assertEqual(tile, expected_result[3]) + if __name__ == '__main__': unittest.main() diff --git a/wahoo_map_creator.py b/wahoo_map_creator.py index b60b3aa0..53e76022 100644 --- a/wahoo_map_creator.py +++ b/wahoo_map_creator.py @@ -6,7 +6,7 @@ # import official python packages # import custom python packages -from common_python.input import Input +from common_python.input import process_call_of_the_tool from common_python.file_directory_functions import initialize_work_directories from common_python.osm_maps_functions import OsmMaps @@ -15,15 +15,11 @@ # ! means error # + means additional comment in a working-unit -oInput = Input() - -if oInput.gui_mode: - oInputData = oInput.start_gui() -else: - oInputData = oInput.cli_arguments() +# handle GUI and CLI processing via one function and different cli-calls +oInputData = process_call_of_the_tool() # Is there something to do? -oInputData.is_required_input_given_or_exit(True) +oInputData.is_required_input_given_or_exit(issue_message=True) initialize_work_directories() @@ -32,7 +28,7 @@ # Read json file # Check for expired land polygons file and download, if too old # Check for expired .osm.pbf files and download, if too old -oOSMmaps.process_input(oInputData.country, oInputData.border_countries) +oOSMmaps.process_input(oInputData.border_countries) oOSMmaps.check_and_download_files()