#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2018 Mike "KemoNine" Crosson # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import subprocess, os, zipfile, shutil, fileinput, glob from . import poly FNULL = open(os.devnull, 'w') SOURCE_MAP_POSTFIX = '-latest.osm.pbf' def setup_working_dirs(base_path, current_timestamp, output_map_name): print('Creating working directories as needed') if not os.path.exists(os.path.join(base_path, 'tmp')): os.makedirs(os.path.join(base_path, 'tmp')) if not os.path.exists(os.path.join(base_path, 'out')): os.makedirs(os.path.join(base_path, 'out')) output_dir = current_timestamp + '-' + output_map_name if not os.path.exists(os.path.join(base_path, 'out', output_dir)): os.makedirs(os.path.join(base_path, 'out', output_dir)) def prep_land_sea_polys(base_path, current_timestamp, maps_dir, map_lists, output_map_name): print('Prepping land/sea polygons (one prep per map in list(s))') output_dir = current_timestamp + '-' + output_map_name polys_output_dir = os.path.join(base_path, 'out', output_dir, 'polys') polys_zip = zipfile.ZipFile(os.path.join(maps_dir, 'land-polygons-split-4326.zip')) for alist in map_lists: with open(alist, 'r') as maps: for line in maps: map_polys_dir = os.path.join(polys_output_dir, line.strip().split('/')[-1]) print(' Extracting to: ' + map_polys_dir) os.makedirs(map_polys_dir) polys_zip.extractall(map_polys_dir) polys_zip.close() def process_land_sea_polys(base_path, current_timestamp, maps_dir, map_lists, output_map_name, max_heap_space, use_ram): print('Processing land/sea polygons (one process per map in list(s))') output_dir = current_timestamp + '-' + output_map_name polys_output_dir = os.path.join(base_path, 'out', output_dir, 'polys') cached_maps_dir = os.path.abspath(maps_dir) for alist in map_lists: with open(alist, 'r') as maps: for line in maps: current_map = line.strip().split('/')[-1] print(' Processing: ' + current_map) bounds = poly.calculate_bounds(os.path.join(cached_maps_dir, current_map + '.poly')) subprocess.run(['ogr2ogr', '-overwrite', '-progress', '-skipfailures', '-clipsrc', str(bounds['left']), str(bounds['bottom']), str(bounds['right']), str(bounds['top']), os.path.join(polys_output_dir, current_map + '.shp'), os.path.join(polys_output_dir, current_map, 'land-polygons-split-4326', 'land_polygons.shp')], stdout=FNULL, stderr=subprocess.STDOUT) subprocess.run(['python2', os.path.join(base_path, 'shape2osm.py'), '-l', os.path.join(polys_output_dir, current_map), os.path.join(polys_output_dir, current_map + '.shp')], stdout=FNULL, stderr=subprocess.STDOUT) shutil.copyfile(os.path.join(base_path, 'sea.osm'), os.path.join(polys_output_dir, current_map + '_sea.osm')) with fileinput.FileInput(os.path.join(polys_output_dir, current_map + '_sea.osm'), inplace=True, backup='.bak') as sea: for line in sea: updated_line = line.replace('$BOTTOM', str(bounds['bottom'])) updated_line = updated_line.replace('$LEFT', str(bounds['left'])) updated_line = updated_line.replace('$TOP', str(bounds['top'])) updated_line = updated_line.replace('$RIGHT', str(bounds['right'])) print(updated_line, end='') map_list = [] for alist in map_lists: with open(alist, 'r') as maps: for line in maps: map_list.append(line.strip().split('/')[-1]) # Setup various runtime aspects (going to do multiple osmosis runs (maps AND POIs) env = os.environ.copy() env['JAVACMD_OPTIONS'] = '-Xmx' + max_heap_space + ' -server -Djava.io.tmpdir=' + os.path.join(base_path, 'tmp') # Setup java temp dir to something a bit more sane (tmpfs /tmp for the loss) print('Processing land/sea polys using osmosis') osmosis_cmd = [os.path.join(base_path, 'bin', 'osmosis', 'bin', 'osmosis')] for amap in map_list: osmosis_cmd.extend(['--rb', 'file=' + os.path.join(maps_dir, amap + SOURCE_MAP_POSTFIX)]) for apolymap in glob.glob(os.path.join(polys_output_dir, amap + '*.osm')): print(' Found poly map : ' + apolymap) osmosis_cmd.extend(['--rx', 'file=' + apolymap, '--s', '--m']) osmosis_cmd.extend(['--log-progress']) for x in range(0, len(map_list) - 1): osmosis_cmd.append('--merge') osmosis_cmd.extend(['--log-progress']) osmosis_cmd.extend(['--wb', 'file=' + os.path.join(base_path, 'out', output_dir, output_map_name) + '_merged_polys.pbf']) osmosis_cmd.extend(['omitmetadata=true']) cmd = subprocess.Popen(osmosis_cmd, env=env) cmd.wait() def osmosis_main(base_path, current_timestamp, maps_dir, map_lists, output_map_name, max_heap_space, use_ram): output_dir = current_timestamp + '-' + output_map_name bounds = poly.calculate_total_bounds(maps_dir, map_lists) # Setup various runtime aspects (going to do multiple osmosis runs (maps AND POIs) env = os.environ.copy() env['JAVACMD_OPTIONS'] = '-XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:ConcGCThreads=4 -Xmx' + max_heap_space + ' -server -Djava.io.tmpdir=' + os.path.join(base_path, 'tmp') # Setup java temp dir to something a bit more sane (tmpfs /tmp for the loss) print('-----------------------------') print('Processing maps using osmosis') print('-----------------------------') osmosis_cmd = [os.path.join(base_path, 'bin', 'osmosis', 'bin', 'osmosis')] osmosis_cmd.extend(['--rb', 'file=' + os.path.join(base_path, 'out', output_dir, output_map_name) + '_merged_polys.pbf']) osmosis_cmd.extend(['--log-progress']) osmosis_cmd.extend(['--mapfile-writer', 'file=' + os.path.join(base_path, 'out', output_dir, output_map_name) + '.map']) if use_ram: osmosis_cmd.extend(['type=ram']) else: osmosis_cmd.extend(['type=hd']) osmosis_cmd.extend(['bbox=' + str(bounds['bottom']) + ',' + str(bounds['left']) + ',' + str(bounds['top']) + ',' + str(bounds['right'])]) osmosis_cmd.extend(['threads=1', 'map-start-zoom=8']) cmd = subprocess.Popen(osmosis_cmd, env=env) cmd.wait() def osmosis_pois(base_path, current_timestamp, maps_dir, map_lists, output_map_name, max_heap_space): output_dir = current_timestamp + '-' + output_map_name map_list = [] for alist in map_lists: with open(alist, 'r') as maps: for line in maps: map_list.append(os.path.join(maps_dir, line.strip().split('/')[-1]+SOURCE_MAP_POSTFIX)) # Setup various runtime aspects (going to do multiple osmosis runs (maps AND POIs) env = os.environ.copy() env['JAVACMD_OPTIONS'] = '-Xmx' + max_heap_space + ' -server -Djava.io.tmpdir=' + os.path.join(base_path, 'tmp') # Setup java temp dir to something a bit more sane (tmpfs /tmp for the loss) print('Processing POIs using osmosis') osmosis_cmd = [os.path.join(base_path, 'bin', 'osmosis', 'bin', 'osmosis')] for amap in map_list: osmosis_cmd.extend(['--rb', 'file=' + amap]) for x in range(0, len(map_list) - 1): osmosis_cmd.append('--merge') osmosis_cmd.extend(['--poi-writer', 'file=' + os.path.join(base_path, 'out', output_dir, output_map_name) + '.poi', 'tag-conf-file=' + os.path.join(base_path, 'poi-mapping.xml')]) cmd = subprocess.Popen(osmosis_cmd, env=env) cmd.wait()