diff --git a/canvas.svg b/canvas.svg
index 878d9ea..6ccdab3 100644
--- a/canvas.svg
+++ b/canvas.svg
@@ -19,9 +19,6 @@
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
-
+
Y vertical
+# if key == 'exif:GPSLongitude':
+# # print('lonstr', value)
+# lon = deg_coordinates_to_decimal(value) # lon -> X horizontal
+
+# return [lat, lon]
+
+
+# def get_coordinate_boundaries():
+# image_names = get_used_tiles_relpaths()
+# coordinates = {
+# 'lat': [],
+# 'lon': []
+# }
+# for filename in image_names:
+# tile_coordinates = read_coordinates_from_tile(filename)
+# coordinates['lat'].append(tile_coordinates[0])
+# coordinates['lon'].append(tile_coordinates[1])
+
+# boundaries = {
+# 'xmin': min(coordinates['lon']),
+# 'xmax': max(coordinates['lon']),
+# 'ymin': min(coordinates['lat']),
+# 'ymax': max(coordinates['lat']),
+# }
+# return boundaries
+
+
+# def create_ungrouped_svg():
+# """
+# exports the SVG without any grouped elements
+# (the quick and dirty way)
+# """
+# print('Create an SVG without groups ...')
+# inkscape_actions = "select-all:groups; SelectionUnGroup; select-all:groups; SelectionUnGroup; select-all:groups; SelectionUnGroup; select-all:groups; SelectionUnGroup; select-all:groups; SelectionUnGroup; select-all:groups; SelectionUnGroup; select-all:groups; SelectionUnGroup; export-filename: {}; export-plain-svg; export-do;".format(TEMP_MAP_UNGROUPED_SVG_PATH)
+# command = [
+# '/snap/bin/inkscape',
+# '--pipe',
+# '--actions={}'.format(inkscape_actions),
+# ],
+# input_file = open(INPUT_PATH, "rb")
+# completed = subprocess.run(
+# *command,
+# cwd=INPUT_DIR, # needed for reative image links
+# stdin=input_file,
+# )
+# print('completed', completed)
+# return completed
+
+
+def get_ground_control_points():
+ """
+ Using selenium with firefox for rendering the SVG and
+ getting the positional matching between GPS
+ and x/y coords of SVG-image.
+ image tags need to have the gps data attached as data attributes.
+ """
+ print('Getting ground control points ...')
+ options = webdriver.firefox.options.Options()
+ options.headless = True
+ driver = webdriver.Firefox(options=options)
+ driver.get("file://{}".format(INPUT_PATH))
+ images = driver.find_elements_by_class_name("thermal_image")
+
+ gcps = []
+ for image in images:
+ location = image.location
+ size = image.size
+ raster_y = float(location['y'] + size['height']/2)
+ raster_x = float(location['x'] + size['width']/2)
+ reference_lon = float(image.get_attribute('data-lon'))
+ reference_lat = float(image.get_attribute('data-lat'))
+ imageMapping = rasterio.control.GroundControlPoint(row=raster_y, col=raster_x, x=reference_lon, y=reference_lat)
+ gcps.append(imageMapping)
+
+ driver.quit()
+ return gcps
+
+
+# def make_vector_shapefile():
+# w = shapefile.Writer(VECTOR_SHAPEFILE_PATH)
+# w.field('name', 'C')
+
+# tree = ET.parse(INPUT_PATH)
+# root = tree.getroot()
+# tiles = root.xpath('//*[@class="thermal_image"]')
+# for index, tile in enumerate(tiles):
+# w.point(float(tile.attrib['data-lon']), float(tile.attrib['data-lat']))
+# w.record('point{}'.format(index))
+# w.close()
+# return True
+
+def verify_coordinate_matching():
+ """
+ During development, i want to proof
+ that the point/coordinate matching is right.
+ Producing a png file with red dots for visual proof.
+ """
+ img = cv2.imread(TEMP_MAP_THERMALPNG_PATH, cv2.IMREAD_GRAYSCALE)
+ img = cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)
+
+ options = webdriver.firefox.options.Options()
+ # options.headless = True
+ driver = webdriver.Firefox(options=options)
+ driver.get("file://{}".format(INPUT_PATH))
+ images = driver.find_elements_by_class_name("thermal_image")
+
+ gcps = []
+ for image in images:
+ location = image.location
+ size = image.size
+ raster_y = int(location['y'] + size['height']/2)
+ raster_x = int(location['x'] + size['width']/2)
+ reference_lon = float(image.get_attribute('data-lon'))
+ reference_lat = float(image.get_attribute('data-lat'))
+ print(raster_x, raster_y)
+ img = cv2.circle(img, (raster_x, raster_y), radius=10, color=(0, 0, 255), thickness=-1)
+ driver.quit()
+ cv2.imwrite(TEMP_MAP_ALIGNMENTPROOF_PATH, img)
+
+
+
+
+def make_geotiff_image():
+
+ thermal_numpy_array = get_thermal_numpy_array()
+ thermal_numpy_array[thermal_numpy_array == 0] = np.NaN # zeros to NaN
+
+ # # coordinates of all tiles
+ # geo_bound = get_coordinate_boundaries()
+ # print('boundaries', geo_bound)
+
+ np_shape = thermal_numpy_array.shape
+ image_size = (np_shape[0], np_shape[1])
+
+ gcps = get_ground_control_points()
+ print('Applying affine transform ...')
+ gcp_transform = rasterio.transform.from_gcps(gcps)
+ print(gcp_transform)
+
+ print('Generating the GeoTiff ...')
+
+ raster_io_dataset = rasterio.open(
+ OUTPUT_PATH,
+ 'w',
+ driver='GTiff',
+ height=thermal_numpy_array.shape[0],
+ width=thermal_numpy_array.shape[1],
+ count=1,
+ dtype=thermal_numpy_array.dtype,
+ transform=gcp_transform,
+ crs='+proj=latlong',
+ )
+ raster_io_dataset.write(thermal_numpy_array, 1)
+
+ # # try to get rid of the black frame
+ # src = rasterio.open(OUTPUT_PATH)
+ # src[src == 0] = np.NaN # zeros to NaN
+ # raster_io_dataset2 = rasterio.open(
+ # OUTPUT_PATH,
+ # 'w',
+ # driver='GTiff',
+ # height=src.shape[0],
+ # width=src.shape[1],
+ # count=1,
+ # dtype=src.dtype,
+ # crs='+proj=latlong',
+ # )
+ # raster_io_dataset2.write(src, 1)
+
+ print('Saved to ', OUTPUT_PATH)
+
+
+
+# make_thermalpng_tiles()
+make_thermalpng_svg()
+make_thermalpng()
+make_geotiff_image()
+
+# # Helpers for debugging
+# verify_coordinate_matching()
+# make_vector_shapefile()
diff --git a/export-gis-jpg.py b/export-gis-jpg.py
deleted file mode 100644
index c14a5c3..0000000
--- a/export-gis-jpg.py
+++ /dev/null
@@ -1,263 +0,0 @@
-import os
-import argparse
-import lxml.etree as ET
-import subprocess
-import flirimageextractor
-import cv2
-import numpy as np
-from pathlib import Path
-from wand.image import Image
-from osgeo import gdal
-from osgeo import osr
-
-arg_parser = argparse.ArgumentParser(description='Export SVG composition of FLIR images as TIFF with thermo layer')
-
-arg_parser.add_argument('Input',
- metavar='input_svg',
- type=str,
- help='Path to the input SVG file cotaining xlinks to FLIR images')
-
-arg_parser.add_argument('Output',
- metavar='output_tiff',
- type=str,
- help='Output filename')
-
-
-args = arg_parser.parse_args()
-dirname = os.path.dirname(__file__)
-INPUT_PATH = os.path.join(dirname, args.Input)
-INPUT_DIR = os.path.split(INPUT_PATH)[0]
-
-TEMP_MAP_THERMALPNG_SVG_PATH = os.path.join(INPUT_DIR, 'map_thermalpng.svg')
-TEMP_MAP_THERMALPNG_PATH = os.path.join(INPUT_DIR, 'map_thermalpng.png')
-TEMP_MAP_PREVIEW_PATH = os.path.join(INPUT_DIR, 'map_preview.png')
-THERMALPNG_DIR = 'thermalpngs'
-
-OUTPUT_PATH = os.path.join(dirname, args.Output)
-
-
-
-def make_thermalpng_tiles():
- """
- Extract thermal infomration as greyscale PNG-16 (temp * 1000 to retain some decimals)
- and save the png tiles
- """
- Path(os.path.join(INPUT_DIR, THERMALPNG_DIR)).mkdir(parents=True, exist_ok=True)
- png_output_dir = os.path.join(INPUT_DIR, THERMALPNG_DIR)
-
- for root_path, directories, file in os.walk(os.path.join(dirname, INPUT_DIR)):
- for file in file:
- if(file.endswith(".jpg")):
- print('Extracting thermal info from ' + file)
- full_filepath = os.path.join(root_path, file)
- flir = flirimageextractor.FlirImageExtractor()
- flir.process_image(full_filepath)
- thermal_img_np = flir.thermal_image_np
- multiplied_image = cv2.multiply(thermal_img_np, 1000)
- output_file_path = os.path.join(png_output_dir, file + '.thermal.png')
- print(output_file_path)
- cv2.imwrite(output_file_path, multiplied_image.astype(np.uint16))
-
-
-
-
-def make_thermalpng_svg():
- """
- replaces the image paths with the thermal pngs
- and creates new SVG file
- """
- # print("svg_file")
- # print(dir(svg_file))
- tree = ET.parse(INPUT_PATH)
- root = tree.getroot()
- # print(ET.tostring(root))
- # tile_rows = root.xpath('//image', namespaces={'n': "http://www.w3.org/2000/svg"})
- # print(dir(root))
- tile_elements = root.xpath('//*[@class="thermal_image"]')
- linkattrib ='{http://www.w3.org/1999/xlink}href'
- for tile in tile_elements:
- tile.attrib[linkattrib] = os.path.join(THERMALPNG_DIR, tile.attrib[linkattrib] + '.thermal.png')
- # newxml = ET.tostring(tree, encoding="unicode")
- # print(newxml)
- # return newxml
-
- with open(TEMP_MAP_THERMALPNG_SVG_PATH, 'wb') as f:
- tree.write(f, encoding='utf-8')
-
- return tree
-
-
-
-def make_thermalpng():
- """
- exports the SVG canvas as Gray_16 PNG
- """
- command = [
- '/snap/bin/inkscape',
- '--pipe',
- '--export-type=png',
- '--export-png-color-mode=Gray_16'
- ],
- input_file = open(TEMP_MAP_THERMALPNG_SVG_PATH, "rb")
- output_file = open(TEMP_MAP_THERMALPNG_PATH, "wb")
- completed = subprocess.run(
- *command,
- cwd=INPUT_DIR, # needed for reative image links
- stdin=input_file,
- stdout=output_file
- )
- return completed
-
-def make_thermalpreview():
- """
- exports the preview image
- """
- command = [
- '/snap/bin/inkscape',
- '--pipe',
- '--export-type=png',
- '--export-png-color-mode=Gray_8'
- ],
- input_file = open(TEMP_MAP_THERMALPNG_SVG_PATH, "rb")
- output_file = open(TEMP_MAP_PREVIEW_PATH, "wb")
- completed = subprocess.run(
- *command,
- cwd=INPUT_DIR, # needed for reative image links
- stdin=input_file,
- stdout=output_file
- )
- return completed
-
-# def make_thermalpreview():
-# """
-# exports the preview image
-# """
-# command = [
-# '/snap/bin/inkscape',
-# '--pipe',
-# '--export-type=png',
-# '--export-png-color-mode=Gray_8'
-# ]
-# input_file = open(TEMP_MAP_THERMALPNG_SVG_PATH, "rb")
-# output_file = open(TEMP_MAP_PREVIEW_PATH, "wb")
-# completed = subprocess.run(
-# *command,
-# cwd=INPUT_DIR, # needed for reative image links
-# stdin=input_file,
-# stdout=output_file
-# )
-# return completed
-
-
-def get_thermal_numpy_array():
- # input_file = open(TEMP_MAP_THERMALPNG_PATH, "rb")
- image = cv2.imread(TEMP_MAP_THERMALPNG_PATH, cv2.IMREAD_ANYDEPTH)
- image_float = image.astype(np.float32)
- image_float_normalized = cv2.divide(image_float, 1000)
- print(image_float_normalized[1000][905])
- # cv2.imshow("OpenCV Image Reading", image)
- return image_float_normalized
-
-def get_used_tiles_relpaths():
- """
- outputs an array of all used tile filenames in the input SVG
- (relative filepaths like they appear in the svg.)
- """
- images = []
- tree = ET.parse(INPUT_PATH)
- root = tree.getroot()
- tile_elements = root.xpath('//*[@class="thermal_image"]')
- linkattrib ='{http://www.w3.org/1999/xlink}href'
- for tile in tile_elements:
- images.append(tile.attrib[linkattrib])
- return images
-
-def deg_coordinates_to_decimal(coordStr):
- coordArr = coordStr.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]
- decimal = (degrees + (minutes * 1/60) + (seconds * 1/60 * 1/60))
- # print(decimal)
- return decimal
-
-
-def read_coordinates_from_tile(filename):
- full_filepath = os.path.join(INPUT_DIR, filename)
- with Image(filename=full_filepath) as image:
- for key, value in image.metadata.items():
- if key == 'exif:GPSLatitude':
- # print('latstr', value)
- lat = deg_coordinates_to_decimal(value) # lat -> Y vertical
- if key == 'exif:GPSLongitude':
- # print('lonstr', value)
- lon = deg_coordinates_to_decimal(value) # lon -> X horizontal
- if key == 'exif:GPSImgDirection':
- direction = value.split('/')
- print(int(direction[0])/int(direction[1])/2, ' ', (value))
-
- return [lat, lon]
-
-def get_coordinate_boundaries():
- image_names = get_used_tiles_relpaths()
- coordinates = {
- 'lat': [],
- 'lon': []
- }
- for filename in image_names:
- tile_coordinates = read_coordinates_from_tile(filename)
- coordinates['lat'].append(tile_coordinates[0])
- coordinates['lon'].append(tile_coordinates[1])
-
- boundaries = {
- 'xmin': min(coordinates['lon']),
- 'xmax': max(coordinates['lon']),
- 'ymin': min(coordinates['lat']),
- 'ymax': max(coordinates['lat']),
- }
- return boundaries
-
-
-def make_geotiff_image():
- thermal_numpy_array = get_thermal_numpy_array()
-
- # coordinates of all tiles
- geo_bound = get_coordinate_boundaries()
- print('boundaries', geo_bound)
-
- np_shape = thermal_numpy_array.shape
- image_size = (np_shape[0], np_shape[1])
-
- # set geotransform
- nx = image_size[0]
- ny = image_size[1]
- xres = (geo_bound['xmax'] - geo_bound['xmin']) / float(nx)
- yres = (geo_bound['ymax'] - geo_bound['ymin']) / float(ny)
- geotransform = (geo_bound['xmin'], xres, 0, geo_bound['ymax'], 0, -yres)
-
- # create the 3-band raster file
- dst_ds = gdal.GetDriverByName('GTiff').Create(OUTPUT_PATH, ny, nx, 1, gdal.GDT_Float32)
- dst_ds.SetGeoTransform(geotransform) # specify coords
- srs = osr.SpatialReference() # establish encoding
- res = srs.SetWellKnownGeogCS( "WGS84" ) # WGS84 lat/long
- dst_ds.SetProjection(srs.ExportToWkt()) # export coords to file
- dst_ds.GetRasterBand(1).WriteArray(thermal_numpy_array) # write thermal-band to the raster
- dst_ds.FlushCache() # write to disk
-
-
-
-
-# make_thermalpng_tiles()
-# make_thermalpng_svg()
-# make_thermalpreview()
-# make_thermalpng()
-make_geotiff_image()
-
-
-# dataset = gdal.Open("working_result_example.tif", gdal.GA_ReadOnly)
-# print(dir(dataset))
-# print(dataset.GetMetadata_List())
diff --git a/gis-svg-stitcher.py b/gis-svg-stitcher.py
index 3853cc0..0544f57 100644
--- a/gis-svg-stitcher.py
+++ b/gis-svg-stitcher.py
@@ -1,23 +1,48 @@
-from wand.image import Image
-import PIL.Image
-import io
-import exiftool
-import subprocess
import os
+import argparse
+from wand.image import Image
import lxml.etree as ET
import copy
+import math
+
+
+from pyproj import CRS
+from pyproj.aoi import AreaOfInterest
+from pyproj.database import query_utm_crs_info
+from pyproj import Transformer
+
+
+
+arg_parser = argparse.ArgumentParser(description='Place drone FLIR-tiles into a SVG in order to edit them in Inkscape')
-import cv2
-import flirimageextractor
-from matplotlib import cm
-import numpy as np
-import urllib.request
+arg_parser.add_argument('Input',
+ metavar='input_directory',
+ type=str,
+ help='Path where the FLIR tiles are')
+arg_parser.add_argument(
+ '--base_rotation', action='store', default=115,
+ help="Base orientation of drone in degrees (0-360) Defaults to 115",
+ type=int, dest='base_rotation'
+)
+
+arg_parser.add_argument(
+ '--scale', action='store', default=15,
+ help="Scaling (higher number leads to bigger canvas and less dense tiles) (defaults to 15)",
+ type=int, dest='scale'
+)
+
+
+
+
+args = arg_parser.parse_args()
+
dirname = os.path.dirname(__file__)
-working_dir = 'source_images_full'
+working_dir = args.Input
+OUTPUT_PATH = os.path.join(working_dir,'map.svg')
filename = os.path.join(dirname, 'canvas.svg')
@@ -42,25 +67,10 @@ def deg_coordinates_to_decimal(coordStr):
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")):
@@ -86,24 +96,71 @@ minLat = min(latsArr)
minLon = min(lonsArr)
maxLat = max(latsArr)
maxLon = max(lonsArr)
-width = maxLon - minLon
-height = maxLat- minLat
+midLon = (minLon + maxLon) /2
+midLat = (minLat + maxLat) /2
+
+
+
+# find CRS system
+utm_crs_list = query_utm_crs_info(
+ datum_name="WGS 84",
+ area_of_interest=AreaOfInterest(
+ west_lon_degree=minLon,
+ south_lat_degree=minLat,
+ east_lon_degree=maxLon,
+ north_lat_degree=maxLat,
+ ),
+)
+utm_crs = CRS.from_epsg(utm_crs_list[0].code)
+transformer = Transformer.from_crs("EPSG:4326", utm_crs, always_xy=True)
+
+min_transformed_lon, min_transformed_lat = transformer.transform(minLon, minLat)
+max_transformed_lon, max_transformed_lat = transformer.transform(maxLon, maxLat)
+
+
+width = max_transformed_lon - min_transformed_lon
+height = max_transformed_lat - min_transformed_lat
+
+
+
+# def latlngToGlobalXY(lat, lng):
+# earth_radius = 6371
+# # Calculates x based on cos of average of the latitudes
+# x = earth_radius * lng * math.cos((minLat + maxLat)/2)
+# # Calculates y based on latitude
+# y = earth_radius * lat
+# return {x: x, y: y}
+
+# def latlngToScreenXY(lat, lng):
+# topLeft_corner = latlngToGlobalXY(minLat, minLon)
+# bottomRight_corner = latlngToGlobalXY(maxLat, maxLon)
+# # Calculate global X and Y for projection point
+# pos = latlngToGlobalXY(lat, lng)
+# # Calculate the percentage of Global X position in relation to total global width
+# pos.perX = ((pos.x - topLeft_corner.x) / (bottomRight_corner.x - topLeft_corner.x))
+# # Calculate the percentage of Global Y position in relation to total global height
+# pos.perY = ((pos.y - topLeft_corner.y) / (bottomRight_corner.y - topLeft_corner.y))
+
+# # Returns the screen position based on reference points
+# return {
+# x: p0.scrX + (p1.scrX - p0.scrX)*pos.perX,
+# y: p0.scrY + (p1.scrY - p0.scrY)*pos.perY
+# }
+
+
# 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
+
+
+# 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:
@@ -111,52 +168,48 @@ for root_path, directories, file in os.walk(os.path.join(dirname, working_dir)):
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)
+ # 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))
+ lat = deg_coordinates_to_decimal(value)
+ lat_offset = lat - minLat
if key == 'exif:GPSLongitude':
- lon = deg_coordinates_to_decimal(value) - minLon
- print('lon '+ str(lon))
+ lon = deg_coordinates_to_decimal(value)
+ lon_offset = lon - minLon
if key == 'exif:GPSImgDirection':
direction = value.split('/')
- rotation = int(direction[0])/int(direction[1])/2
-
+ rotation = ( int(direction[0]) / int(direction[1]) ) / 2 + args.base_rotation
+ print('rotation',rotation)
+ transformed_lon, transformed_lat = transformer.transform(lon, lat)
+ lon_offset = transformed_lon - min_transformed_lon
+ lat_offset = transformed_lat - min_transformed_lat
+ # print(transformed_lon, min_transformed_lon, transformed_lat, min_transformed_lat)
+ # print('lon_offset, lat_offset', lon_offset, lat_offset)
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'),
+ 'transform': "translate({}, {})".format(format(lon_offset*args.scale, '.20f'), format(lat_offset*args.scale*-1, '.20f')),
+ 'data-lat-offset': format(lat_offset, '.20f'),
+ 'data-lon-offset': format(lon_offset, '.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)",
+ 'transform': "translate({}, {})".format(-image.width/2, -image.height/2),
'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))
+ 'data-image-rotation': str(rotation),
+ 'data-image-dimensions': str(image.width) + ' ' + str(image.height),
+ 'transform': 'rotate({} {} {})'.format(str(rotation), str(image.width/2), str(image.height/2))
+ # 'transform': 'rotate({} {} {})'.format(str(rotation), 0,0)
}
- g_rot_el = ET.SubElement(g_center_el, 'g', attrib=g_rot_el_attributes)
+ g_rot_el = ET.SubElement(g_offset_corr_el, 'g', attrib=g_rot_el_attributes)
xlinkns ="http://www.w3.org/1999/xlink"
image_el = ET.SubElement(g_rot_el, 'image', {
@@ -164,14 +217,10 @@ for root_path, directories, file in os.walk(os.path.join(dirname, working_dir)):
"{%s}href" % xlinkns: file,
"width": str(image.width),
"height": str(image.height),
- "mask" : "url(#tilefademask)",
+ 'data-lat': format(lat, '.20f'),
+ 'data-lon': format(lon, '.20f'),
})
-# 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):
@@ -184,55 +233,62 @@ def getkey(elem):
main_layer[:] = sorted(main_layer, key=getkey)
-# rotate image if previous element is under the current one
+# find rows
+# up/down is actually left/right or right/left
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')):
+ if (el.getprevious().attrib['data-lon-offset'] > el.attrib['data-lon-offset'] or (el.getprevious().attrib['data-lon-offset'] == el.attrib['data-lon-offset'] 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'])
+ rot_el = el[0][0]
el.attrib['data-direction'] = 'up'
-
- # print(el.attrib['data-lat'], el.getprevious().attrib['data-lat'])
else:
- rot_el = el[0][0][0]
+ rot_el = el[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'])
+ # NOT NEEDED SINCE THERE IS A ROTATION INFORMATION
# 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']:
+ # print(index)
+ # print("el.attrib['data-direction'] " + el.attrib['data-direction'])
+ # print("last_state " + last_state)
+ if index is 1 or last_state is not 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']
+# remove temporary group
root.remove(main_layer)
+# resize canvas to tiles and add some padding
-with open(os.path.join(working_dir,'map.svg'), 'wb') as f:
- tree.write(f, encoding='utf-8')
+print(width, height, args.scale)
+scaled_width = width * args.scale
+scaled_height = height * args.scale
+
+padding = 500
+
+canvas_width = str(scaled_width + padding*2)
+canvas_height = str(scaled_height + padding*2)
+viewbox_x = str(padding * -1)
+viewbox_y = str((scaled_height + padding) * -1)
+viewbox_width = canvas_width
+viewbox_height = canvas_height
-# # 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)
+root.attrib['width'] = canvas_width
+root.attrib['height'] = canvas_height
+root.attrib['viewBox'] = "{} {} {} {}".format(viewbox_x, viewbox_y, viewbox_width, viewbox_height)
+
+
+
+# Finally save the svg
+with open(OUTPUT_PATH, 'wb') as f:
+ tree.write(f, encoding='utf-8')
-# svg = ET.tostring(tree, encoding="unicode")
-# print(svg)
print('Done!')
+
+