from wand.image import Image import PIL.Image import io import exiftool import subprocess import os import lxml.etree as ET import copy import cv2 import flirimageextractor from matplotlib import cm import numpy as np import urllib.request dirname = os.path.dirname(__file__) working_dir = 'source_images_full' filename = os.path.join(dirname, 'canvas.svg') tree = ET.parse(filename) root = tree.getroot() d = root.nsmap main_layer = root.xpath('//*[@id="tiles"]', namespaces={'n': "http://www.w3.org/2000/svg"})[0] tile_rows = root.xpath('//*[@id="tile_rows"]', namespaces={'n': "http://www.w3.org/2000/svg"})[0] def deg_coordinates_to_decimal(coordStr): coordArr = value.split(', ') calculatedCoordArray = [] for calculation in coordArr: calculationArr = calculation.split('/') calculatedCoordArray.append(int(calculationArr[0]) / int(calculationArr[1])) degrees = calculatedCoordArray[0] minutes = calculatedCoordArray[1] seconds = calculatedCoordArray[2] return (degrees + (minutes * 1/60) + (seconds * 1/60 * 1/60)) # # extracting TIF Data # for root, directories, file in os.walk(os.path.join(dirname, working_dir)): # for file in file: # if(file.endswith(".jpg")): # print(os.path.join(root, file)) # full_filepath = os.path.join(root, file) # with exiftool.ExifTool() as et: # cmd = ['exiftool', full_filepath, "-b", "-RawThermalImage"] # tif_data = subprocess.check_output(cmd) # tif_image = PIL.Image.open(io.BytesIO(tif_data)) # tif_filepath = os.path.join(dirname, working_dir, file.split('.')[0] + '_thermal.tif') # tif_image.save(tif_filepath) # print(tif_filepath) # finding the boundaries of the whole canvas latsArr = [] lonsArr = [] for root_path, directories, file in os.walk(os.path.join(dirname, working_dir)): for file in file: if(file.endswith(".jpg")): print(os.path.join(root_path, file)) full_filepath = os.path.join(root_path, file) with Image(filename=full_filepath) as image: print(image.width) print(image.height) for key, value in image.metadata.items(): if key == 'exif:GPSLatitude': lat = deg_coordinates_to_decimal(value) # lat -> Y vertical latsArr.append(lat) print("{}: {}".format(key, value)) print('lat '+ str(lat)) if key == 'exif:GPSLongitude': lon = deg_coordinates_to_decimal(value) # lon -> X horizontal lonsArr.append(lon) print("{}: {}".format(key, value)) print('lon '+ str(lon)) minLat = min(latsArr) minLon = min(lonsArr) maxLat = max(latsArr) maxLon = max(lonsArr) width = maxLon - minLon height = maxLat- minLat # placing the images into the svg rotation = 125 y_scale = -1800000 #-400000 x_scale = 655000 #-950000 # y_scale = 2600000 #-400000 # x_scale = 1200000 #-950000 image_rotation_up = rotation #32 image_rotation_down = rotation + 180 #192 for root_path, directories, file in os.walk(os.path.join(dirname, working_dir)): for file in file: if(file.endswith(".jpg")): print(os.path.join(root_path, file)) full_filepath = os.path.join(root_path, file) with Image(filename=full_filepath) as image: print(image.width) print(image.height) for key, value in image.metadata.items(): # print("{}: {}".format(key, value)) if key == 'exif:GPSLatitude': lat = deg_coordinates_to_decimal(value) - minLat print('lat '+ str(lat)) if key == 'exif:GPSLongitude': lon = deg_coordinates_to_decimal(value) - minLon print('lon '+ str(lon)) if key == 'exif:GPSImgDirection': direction = value.split('/') rotation = int(direction[0])/int(direction[1])/2 g_pos_el_attributes = { # 'x': str(lat*scale), # 'y': str(lon*scale), 'transform': "translate({}, {})".format(format(lon*x_scale, '.20f'), format(lat*y_scale, '.20f')), 'data-lat': format(lat, '.20f'), 'data-lon': format(lon, '.20f'), 'class': 'tile', 'id': 'tile_{}'.format(file.split('.')[0]), # 'style': 'opacity:.6', } g_pos_el = ET.SubElement(main_layer, 'g', attrib=g_pos_el_attributes) g_offset_corr_el_attributes = { 'transform': "translate(150, 0)", 'class': 'tile-offset-corr', } g_offset_corr_el = ET.SubElement(g_pos_el, 'g', attrib=g_offset_corr_el_attributes) g_center_el_attributes = { 'class': 'tile-center', 'transform': 'translate({}, {})'.format(str(image.width/2*-1), str(image.height/2*-1)) } g_center_el = ET.SubElement(g_offset_corr_el, 'g', attrib=g_center_el_attributes) g_rot_el_attributes = { 'class': 'tile-rotate', 'data-image-rotation': str(image_rotation_up), 'data-image-dimensions': str(image.width/2) + ' ' + str(image.height/2), 'transform': 'rotate({} {} {})'.format(str(image_rotation_up), str(image.width/2), str(image.height/2)) } g_rot_el = ET.SubElement(g_center_el, 'g', attrib=g_rot_el_attributes) xlinkns ="http://www.w3.org/1999/xlink" image_el = ET.SubElement(g_rot_el, 'image', { "class": 'thermal_image', "{%s}href" % xlinkns: file, "width": str(image.width), "height": str(image.height), "mask" : "url(#tilefademask)", }) # transform_str = "translate(-{}, -{})".format(str(min(latsArr)*scale), str(min(lonsArr)*scale)) # print(transform_str) # main_layer.attrib['transform'] = transform_str # sort elements def getkey(elem): # Used for sorting elements by @LIN. # returns a tuple of ints from the exploded @LIN value # '1.0' -> (1,0) # '1.0.1' -> (1,0,1) return float(elem.get('id').split('_')[2]) main_layer[:] = sorted(main_layer, key=getkey) # rotate image if previous element is under the current one last_state = 'down' for index, el in enumerate(main_layer): if(el.getprevious() is not None): if (el.getprevious().attrib['data-lon'] > el.attrib['data-lon'] or (el.getprevious().attrib['data-lon'] == el.attrib['data-lon'] and last_state == 'up')): print('up') rot_el = el[0][0][0] # print(rot_el.attrib['data-image-rotation']) # print(rot_el.attrib['data-image-dimensions']) el.attrib['data-direction'] = 'up' # print(el.attrib['data-lat'], el.getprevious().attrib['data-lat']) else: rot_el = el[0][0][0] el.attrib['data-direction'] = 'down' # el.attrib['style'] = 'opacity:0' new_rotation = image_rotation_down #float(rot_el.attrib['data-image-rotation']) + 180 rot_el.attrib['transform'] = "rotate({} {})".format(str(new_rotation), rot_el.attrib['data-image-dimensions']) print('down') # print(rot_el.attrib['data-image-rotation']) # print(rot_el.attrib['data-image-dimensions']) # merge tiles into groups print(index) print("el.attrib['data-direction'] " + el.attrib['data-direction']) print("last_state " + last_state) if index is 1 or last_state != el.attrib['data-direction']: current_row = ET.SubElement(tile_rows, 'g', attrib={ 'class': 'tile-row' }) copyElem = copy.deepcopy(el) current_row.insert(0, copyElem) last_state = el.attrib['data-direction'] root.remove(main_layer) with open(os.path.join(working_dir,'map.svg'), 'wb') as f: tree.write(f, encoding='utf-8') # # get some base satellite map for reference # apikey = "MYaMHCLtPz1fUfe0FzZqOMI35m893jIV80oeHG19Piw" # lon_center = # lat_center = # zoom = # map_width = # request = "https://image.maps.ls.hereapi.com/mia/1.6/mapview?apiKey={}&c={},{}&sb=mk&t=1&z={}&w={}&nodot".format(apikey, lon_center, lat_center, zoom, map_width) # svg = ET.tostring(tree, encoding="unicode") # print(svg) print('Done!')