def crop(o): if o.crop or o.area.crop: if platform.system() == 'Windows' and platform.architecture( )[0] == '32bit' and os.path.getsize(o.area.mapDataName) > 2000000000: raise ValueError( _('Soubor pro orez je prilis velky') + ' (' + "{:.2f}".format( os.path.getsize(o.area.mapDataName) / 1000000000) + ' GB), ' + _('maximum jsou 2 GB. Detaily viz GitHub.')) say(_('Vytvarim vyrez oblasti'), o) osmconvert = ('' if platform.system() == 'Windows' else './' ) + 'osmconvert' + platform.architecture()[0][0:2] + ( '.exe' if platform.system() == 'Windows' else '') os.chdir('osmconvert') run( osmconvert + ' \ ../' + o.area.mapDataName + ' -B=../' + o.temp + 'polygon.poly \ --complete-ways --complete-multipolygons --complete-boundaries \ --out-pbf \ -o=../' + o.temp + o.area.id + '.osm.pbf', o) os.chdir('..') o.area.mapDataName = o.temp + o.area.id + '.osm.pbf'
def _makeAreaObject(id, obj, options, continent=None): # Doplnim id a dataId obj.id = id if hasattr(obj, 'parent') and obj.parent is not None: say('Oblast je zavisla na datech oblasti ' + obj.parent, options) state = _findState(obj.parent) if state is not None: obj.url = "http://download.geofabrik.de/%s/%s-latest.osm.pbf" % ( state[1], state[0].url) elif obj.parent in USER_AREAS: obj.url = USER_AREAS[obj.parent].url else: raise ValueError('Ivalid parent ID \'' + obj.parent + '\' in \'' + id + '\'') obj.mapDataName = options.pbf + obj.parent + '.osm.pbf' else: obj.url = "http://download.geofabrik.de/%s/%s-latest.osm.pbf" % ( continent, obj.url) obj.mapDataName = options.pbf + id + '.osm.pbf' if continent is not None: obj.continent = continent return obj
def contours(o): say(_('Generuji vrstevnice'), o) # Zjistim, zda mam hotove vrstevnice if not os.path.isfile(o.pbf + o.area.id + '-SRTM.osm.pbf'): run( 'phyghtmap \ --polygon=' + o.temp + 'polygon.poly \ -o ' + o.pbf + o.area.id + '-SRTM \ --pbf \ -j 2 \ -s 10 \ -c 200,100 \ --hgtdir=' + o.hgt + ' \ --source=view3 \ --start-node-id=20000000000 \ --start-way-id=10000000000 \ --write-timestamp \ --max-nodes-per-tile=0', o) os.rename( glob.glob(o.pbf + o.area.id + '-SRTM*.osm.pbf')[0], o.pbf + o.area.id + '-SRTM.osm.pbf') else: say(_('Pouzivam drive vytvorene vrstevcnice'), o)
def mapData(o): say('Start map data download', o) o.downloaded = False # Zjistim, zda mam stahovat data if o.area.url is None: say('I don\'t have data url - skip downloading', o) if o.area.fileHeader is None: raise ValueError('Map file does NOT exist!') return if o.downloadMap == 'skip': say('User set "--download skip" - skip downloading', o) return if o.downloadMap == 'auto': if o.area.timestamp is None: o.downloaded = True else: diff = datetime.now(timezone.utc) - o.area.timestamp if diff.total_seconds() > o.maximumDataAge: o.downloaded = True else: say('Map data is to young - skip downloading', o) if o.downloadMap == 'force' or o.downloaded is True: try: say('Downloading map data', o) download(o.area.url, o.area.mapDataName) parser.fileHeader(o) except: raise ValueError("Cann't download map data!")
def _prepareLicence(o): # Vytvorim licencni soubor say(_('Pripravuji licencni soubor'), o) with open('./template/license.txt', 'r') as license: content = license.read() with open(o.temp + 'license.txt', 'w') as license: license.write(content + "\n" + str(o.area.timestamp))
def main(): try: # TODO vytvorit TMP slozku # Objekt pro ulozeni globalnich promennych a nastaveni o = Options() # Nactu konfiguracni soubor config.load(o) # Nactu a zpracuji arumenty args.parse(o) # Zaznamenam cas spusteni o.timeStart = datetime.now() say('Start at ' + str(o.timeStart), o) # Ziskam informace o statu parser.area(o) # Nactu informace z hlavicky parser.fileHeader(o) # Stahnu mapova data download.mapData(o) # Stahnu polygon download.polygon(o) # Zpracuji polygon polygon.load(o) # Vytvorim vrstevnice generator.contours(o) # Oriznu mapovy soubor generator.crop(o) # Generuji Garmin mapu generator.garmin(o) # TODO remove temp except KeyboardInterrupt: error("\nUkonceno uzivatelem") except Exception as e: error(str(e)) exit(1) finally: # Ukoncim generovani end(o)
def _makeZip(o): say(_('Vytvarim zip soubor'), o) os.chdir(o.img) zip = zipfile.ZipFile('./' + o.area.id + o.sufix + '.zip', 'w') for dirname, subdirs, files in os.walk('./' + o.area.id + o.sufix): zip.write(dirname) for filename in files: zip.write(os.path.join(dirname, filename)) zip.close() os.chdir('..')
def _makeInfo(o): say('Make info file', o) infoData = { 'version': str(o.VERSION), 'datetime': str(o.area.timestamp), 'timestamp': str(o.area.timestamp.timestamp()), 'hashImg': _sha1(o.img + o.area.id + o.sufix + '.img'), 'hashZip': _sha1(o.img + o.area.id + o.sufix + '.zip'), 'codePage': o.code } with open(o.img + o.area.id + o.sufix + '.info', 'w') as info: info.write(json.dumps(infoData))
def area(o): if o.area is None: while True: print('\nVyberte svetadil') for continent in STATES: print(continent) continent = input('Vybrano: ') if continent not in STATES: continue else: break while True: print('\nVyberte stat') for state in STATES[continent]: print(state, ' (', STATES[continent][state].nameCs, ')', sep='') state = input('Vybrano: ') if state not in STATES[continent]: continue else: o.area = state break say('Dekoduji oblast ' + o.area, o) if o.area in USER_AREAS: say('Oblast nalezena v uzivatelskych oblastech', o) o.area = _makeAreaObject(id=o.area, obj=USER_AREAS[o.area], options=o) else: state = _findState(o.area) if state is not None: o.area = _makeAreaObject(id=o.area, obj=state[0], options=o, continent=state[1]) else: raise ValueError('Neplana oblast ' + o.area) if o.mapNumber is not None: o.area.number = o.mapNumber if o.variant is not None: o.area.number += int(o.variant) say(str(o.area), o) say('Area id: ' + o.area.id, o)
def _splitFiles(o): input_file = o.area.mapDataName input_srtm_file = o.pbf + o.area.id + '-SRTM.osm.pbf' if o.split: say(_('Spoustim rozdeleni souboru'), o) # Data neexistuji nebo jsem stahl nova if not os.path.exists(o.pbf + o.area.id + '-SPLITTED') or o.downloaded: # Smazu puvodni soubory for file in glob.glob(o.pbf + o.area.id + '-SPLITTED/*'): os.remove(file) # Spustim splitter run( 'java ' + o.JAVAMEM + ' -jar \ ./splitter-r' + str(o.splitter) + '/splitter.jar ' + input_file + ' --max-areas=4096 \ --max-nodes=1600000 \ --output-dir=' + o.pbf + o.area.id + '-SPLITTED', o) # Aktualizuji seznam vstupnich souboru input_file = o.pbf + o.area.id + '-SPLITTED/*.osm.pbf' # input_file = [] # for file in glob.glob( o.pbf + o.area.id + '-SPLITTED/*.osm.pbf' ): # input_file.append(file) # Rozdelim soubor s vrstevnicemi if not os.path.isdir(o.pbf + o.area.id + '-SPLITTED-SRTM'): run( 'java ' + o.JAVAMEM + ' -jar \ ./splitter-r' + str(o.splitter) + '/splitter.jar ' + input_srtm_file + ' --max-areas=4096 \ --max-nodes=1600000 \ --output-dir=' + o.pbf + o.area.id + '-SPLITTED-SRTM', o) say(_('Rozdeleni souboru - HOTOVO'), o) # Aktualizuji seznam vstupnich souboru input_srtm_file = o.pbf + o.area.id + '-SPLITTED-SRTM/*.osm.pbf' # input_srtm_file = [] # for file in glob.glob( o.pbf + o.area.id + '-SPLITTED-SRTM/*.osm.pbf' ): # input_srtm_file.append(file) return input_file, input_srtm_file
def fileHeader(o): say("Parsing file header", o) o.area.timestamp = None o.area.fileHeader = None if os.path.isfile(o.area.mapDataName): o.area.fileHeader = osmium.io.Reader( o.area.mapDataName, osmium.osm.osm_entity_bits.NOTHING).header() o.area.timestamp = o.area.fileHeader.get( "osmosis_replication_timestamp") try: o.area.timestamp = datetime.strptime(o.area.timestamp, "%Y-%m-%dT%H:%M:%SZ") o.area.timestamp = o.area.timestamp.replace(tzinfo=timezone.utc) except ValueError: error( "Date in OSM file header is not in ISO8601 format (e.g. 2015-12-24T08:08Z). Ignored", o) o.area.timestamp = None say("File from " + str(o.area.timestamp), o)
def fileHeader(o): say(_('Ctu hlavicku souboru'), o) o.area.timestamp = None o.area.fileHeader = None if os.path.isfile(o.area.mapDataName): o.area.fileHeader = osmium.io.Reader( o.area.mapDataName, osmium.osm.osm_entity_bits.NOTHING).header() o.area.timestamp = o.area.fileHeader.get( "osmosis_replication_timestamp") try: o.area.timestamp = datetime.strptime(o.area.timestamp, "%Y-%m-%dT%H:%M:%SZ") o.area.timestamp = o.area.timestamp.replace(tzinfo=timezone.utc) except ValueError: error( _('Datum v hlavicce OSM souboru neni ve formatu ISO8601 (napr. 2015-12-24T08:08Z). Ignoruji' ), o) o.area.timestamp = None say(_("Soubor z ") + str(o.area.timestamp), o)
def _makeBat(name, o): say('Make ' + name + '.bat file', o) if name not in ['install', 'uninstall']: raise ValueError('Invalid bat file name') # Prevedu ID do hexa tvaru numberHex = format(o.area.number, 'x') numberHex = numberHex[2:4] + numberHex[0:2] # Vytvorim instalacni bat soubor with open('./template/' + name + '.bat', 'r') as batFile: content = batFile.read() content = content.replace('%NAME%', o.area.nameCs) content = content.replace('%ID%', str(o.area.number).zfill(4)) content = content.replace('%ID_HEX%', numberHex) with open(o.img + o.area.id + o.sufix + '/' + name + '.bat', 'w') as batFile: batFile.write(content)
def run(program, o): program = ' '.join(program.split()) say(program, o, '[RUN] ') process = subprocess.Popen(program, universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) while True: output = process.stdout.readline() if output == '' and process.poll() is not None: break if output: say(output, o, '', '') log(output, o) if process.poll() != 0: error('stderr: ' + process.stderr.read(), o) raise ValueError(program + ' ' + _('vratil') + ' ' + str(process.poll()) + ' (ocekavana 0)')
def crop(o): if o.crop or o.area.crop: if platform.system() == 'Windows' and platform.architecture( )[0] == '32bit' and os.path.getsize(o.area.mapDataName) > 2000000000: raise ValueError('File for crop is too big (' + "{:.2f}".format( os.path.getsize(o.area.mapDataName) / 1000000000) + ' GB), maximum is 2 GB. See GitHub for details.') say('Vytvarim vyrez oblasti', o) osmconvert = './osmconvert' + platform.architecture()[0][0:2] + ( '.exe' if platform.system() == 'Windows' else '') os.chdir('osmconvert') run( osmconvert + ' \ ../' + o.area.mapDataName + ' -B=../' + o.temp + 'polygon.poly \ --complete-ways --complete-multipolygons --complete-boundaries \ --out-pbf \ -o=../' + o.temp + o.area.id + '.osm.pbf', o) os.chdir('..') o.area.mapDataName = o.temp + o.area.id + '.osm.pbf'
def _extend(o): say('Extending polygon', o) # [[17.25743, 49.58712], [17.24355, 49.58712], [17.24355, 49.5964], [17.25743, 49.5964], [17.25743, 49.58712]] extender = pyclipper.PyclipperOffset() MULTIPLIER = 100000 path = [] for point in o.polygon: path.append([int(point[0] * MULTIPLIER), int(point[1] * MULTIPLIER)]) # http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Methods/AddPath.htm extender.AddPath(path, pyclipper.JT_MITER, pyclipper.ET_CLOSEDPOLYGON) solution = extender.Execute(1600 * o.extend)[0] # FIXME hodnota 1600 experimentálně funguje pro CR for i in range(len(solution)): point = solution[i] solution[i] = [point[0]/MULTIPLIER, point[1]/MULTIPLIER] solution.append(solution[0]) o.polygon = solution
def mapData(o): say(_('Spoustim stahovani mapovych dat'), o) o.downloaded = False # Zjistim, zda mam stahovat data if o.area.url is None: say(_('Neznam URL adresu - preskakuji'), o) if o.area.fileHeader is None: raise ValueError(_('Mapový soubor NEEXISTUJE!')) return if o.downloadMap == 'skip': say(_('Uzivatel nastavil "--download skip" - nestahuji'), o) return if o.downloadMap == 'auto': if o.area.timestamp is None: o.downloaded = True else: diff = datetime.now(timezone.utc) - o.area.timestamp if diff.total_seconds() > o.maximumDataAge: o.downloaded = True else: say(_('Mapova data jsou prilis mlada - nestahuji'), o) if o.downloadMap == 'force' or o.downloaded is True: try: say(_('Stahuji mapova data'), o) download(o.area.url, o.area.mapDataName) parser.fileHeader(o) except: raise ValueError(_('Nelze stahnout mapova data!'))
def garmin(o): say(_('Vytvarim mapu pro Garmin...'), o) # Vytvorim cilovou podslozku if not os.path.exists(o.img + o.area.id + o.sufix): os.makedirs(o.img + o.area.id + o.sufix) input_file, input_srtm_file = _splitFiles(o) _prepareLicence(o) say(_('Generuji mapu'), o) run( 'java ' + o.JAVAMEM + ' -jar ./mkgmap-r' + str(o.mkgmap) + '/mkgmap.jar \ -c ./garmin-style/mkgmap-settings.conf \ --bounds=' + o.bounds + ' \ --precomp-sea=' + o.sea + 'sea/ \ --dem=' + o.hgt + 'VIEW3/ \ --max-jobs=' + str(o.MAX_JOBS) + ' \ --mapname="' + str(o.area.number).zfill(4) + '0001\" \ --overview-mapnumber="' + str(o.area.number).zfill(4) + '0000\" \ --family-id="' + str(o.area.number).zfill(4) + '" \ --description="' + o.area.nameCs + o.sufix + '" \ --family-name="' + o.area.nameCs + o.sufix + '" \ --series-name="' + o.area.nameCs + o.sufix + '" \ --area-name="' + o.area.nameCs + o.sufix + '" \ --country-name="' + o.area.nameCs + o.sufix + '" \ --country-abbr="' + o.area.id + '" \ --region-name="' + o.area.nameCs + o.sufix + '" \ --region-abbr="' + o.area.id + '" \ --product-version=' + str(o.VERSION) + ' \ --output-dir=' + o.img + o.area.id + o.sufix + ' \ --dem-poly=' + o.polygons + o.area.id + '.poly \ --license-file=' + o.temp + 'license.txt \ --code-page=' + o.code + ' \ ' + input_file + ' \ ' + input_srtm_file + ' \ ' + ' '.join(o.area.pois) + ' \ ./garmin-style/style.txt', o) _makeBat('install', o) _makeBat('uninstall', o) # Prejmenuji vystupni soubor say(_('Prejmenuji soubory'), o) if os.path.isfile(o.img + o.area.id + o.sufix + '.img'): os.remove(o.img + o.area.id + o.sufix + '.img') os.rename(o.img + o.area.id + o.sufix + '/gmapsupp.img', o.img + o.area.id + o.sufix + '.img') _makeZip(o) _makeInfo(o)
def polygon(o): if hasattr(o.area, 'continent') and not os.path.isfile(o.polygons + o.area.id + '.poly'): say('Downloading polygon', o) download(o.area.url[0:-15] + '.poly', o.polygons + o.area.id + '.poly')
def garmin(o): say('Making map for garmin...', o) # Vytvorim cilovou podslozku if not os.path.exists(o.img + o.area.id + o.sufix): os.makedirs(o.img + o.area.id + o.sufix) input_file, input_srtm_file = _splitFiles(o) _prepareLicence(o) say('Generating map', o) run( 'java ' + o.JAVAMEM + ' -jar ./mkgmap-r' + str(o.mkgmap) + '/mkgmap.jar \ -c ./garmin-style/mkgmap-settings.conf \ --bounds=' + o.bounds + ' \ --precomp-sea=' + o.sea + 'sea/ \ --dem=' + o.hgt + 'VIEW3/ \ --max-jobs=' + str(o.MAX_JOBS) + ' \ --mapname="' + str(o.area.number).zfill(4) + '0001\" \ --overview-mapnumber="' + str(o.area.number).zfill(4) + '0000\" \ --family-id="' + str(o.area.number).zfill(4) + '" \ --description="' + o.area.nameCs + o.sufix + '" \ --family-name="' + o.area.nameCs + o.sufix + '" \ --series-name="' + o.area.nameCs + o.sufix + '" \ --area-name="' + o.area.nameCs + o.sufix + '" \ --country-name="' + o.area.nameCs + o.sufix + '" \ --country-abbr="' + o.area.id + '" \ --region-name="' + o.area.nameCs + o.sufix + '" \ --region-abbr="' + o.area.id + '" \ --product-version=' + str(o.VERSION) + ' \ --output-dir=' + o.img + o.area.id + o.sufix + ' \ --dem-poly=' + o.polygons + o.area.id + '.poly \ --license-file=' + o.temp + 'license.txt \ --code-page=' + o.code + ' \ ' + input_file + ' \ ' + input_srtm_file + ' \ ' + ' '.join(o.area.pois) + ' \ ./garmin-style/style.txt', o) # mkgmap = 'java ' + o.JAVAMEM + ' -jar ./mkgmap-r' + str(o.mkgmap) + '/mkgmap.jar \ # -c ./garmin-style/mkgmap-settings.conf \ # --bounds=' + o.bounds + ' \ # --precomp-sea=' + o.sea + 'sea/ \ # --dem=' + o.hgt +'VIEW3/ \ # --max-jobs=' + str( o.MAX_JOBS ) + ' \ # --mapname="' + str(o.area.number).zfill(4) + '0001\" \ # --overview-mapnumber="' + str(o.area.number).zfill(4) + '0000\" \ # --family-id="' + str(o.area.number).zfill(4) + '" \ # --description="' + o.area.nameCs + o.sufix + '" \ # --family-name="' + o.area.nameCs + o.sufix + '" \ # --series-name="' + o.area.nameCs + o.sufix + '" \ # --area-name="' + o.area.nameCs + o.sufix + '" \ # --country-name="' + o.area.nameCs + o.sufix + '" \ # --country-abbr="' + o.area.id + '" \ # --region-name="' + o.area.nameCs + o.sufix + '" \ # --region-abbr="' + o.area.id + '" \ # --product-version=' + str( o.VERSION ) + ' \ # --output-dir=' + o.img + o.area.id + o.sufix + ' \ # --dem-poly=' + o.polygons + o.area.id + '.poly \ # --license-file=' + o.temp + 'license.txt \ # --code-page=' + o.code + ' \ # ' + ' '.join(input_file) + ' \ # ' + ' '.join(input_srtm_file) + ' \ # ' + ' '.join(o.area.pois) + ' \ # ./garmin-style/style.txt' # run(o, mkgmap) # FIXME # err = subprocess.run(mkgmap, shell=True, capture_output=False) # log(err.stdout.decode(), o) # if err.returncode != 0: # error(err.stderr.decode(), o) # raise ValueError(program + ' return ' + str(err.returncode) + ' (0 expected)') _makeBat('install', o) _makeBat('uninstall', o) # Prejmenuji vystupni soubor say('Rename files', o) if os.path.isfile(o.img + o.area.id + o.sufix + '.img'): os.remove(o.img + o.area.id + o.sufix + '.img') os.rename(o.img + o.area.id + o.sufix + '/gmapsupp.img', o.img + o.area.id + o.sufix + '.img') _makeZip(o) _makeInfo(o)