2 Commits

Author SHA1 Message Date
  Andreas Demmelbauer b5c6cade76 fix rows 2 years ago
  Andreas Demmelbauer 07feae7eb2 update redame 2 years ago
3 changed files with 73 additions and 20 deletions
Split View
  1. +9
    -3
      README.md
  2. +63
    -16
      gis-svg-stitcher.py
  3. +1
    -1
      requirements.txt

+ 9
- 3
README.md View File

@@ -24,13 +24,14 @@ The process has three steps:
```
python3 gis-svg-stitcher.py relative_path/to/the/image_files --scale=15 --base_rotation=115 --rotation_corr_left=28
```
It produces a file called `map.svg`
It produces a file called `map.svg` next to the original tiles.

* `convert-svg-to-geotiff.py` for converting the (edited) SVG canvas
Example usage:
```
python3 convert-svg-to-geotiff.py relative_path/to/the/image_files/map.svg output.tiff
```
It produces the output file, but also some temporary files, which can be deleted manually afterwards. The (likely) hundrets of generated png tiles insnde the "thermalpng" directory may take some disk space (around 0.5 MB per tile).


### Requirements
@@ -38,10 +39,11 @@ The process has three steps:
* python3 + pip
* inkscape
* firefox
* git

### Installation

Install Python3, Inkscape and Firefox.
Install Python3, Inkscape, Firefox and git.

Then clone repo and install script dependencies:
```
@@ -50,9 +52,13 @@ cd deep-crop
pip3 install -r requirements.txt
```

It's recommended to use a virtualEnv if the host is also used for other python jobs.

### How to use

Use the scripts. Use the `--help` flag for more information:
You should be able to run commands on the command line.

Use the `--help` flag for more information about how to use the scripts:

```
python3 gis-svg-stitcher.py --help


+ 63
- 16
gis-svg-stitcher.py View File

@@ -22,6 +22,18 @@ arg_parser.add_argument('Input',
help='Path where the FLIR tiles are')


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'
)

arg_parser.add_argument(
'--direction', action='store', default='both',
help="left, right, both (both is default)",
type=str, dest='direction'
)

arg_parser.add_argument(
'--base_rotation', action='store', default=115,
help="Base orientation of drone in degrees (0-360) Defaults to 115",
@@ -30,29 +42,30 @@ arg_parser.add_argument(

arg_parser.add_argument(
'--rotation_corr_right', action='store', default=0,
help="correction for tiles where drone flies into right direction",
help="rotation correction for tiles where drone flies into right direction",
type=int, dest='rotation_corr_right'
)
arg_parser.add_argument(
'--rotation_corr_left', action='store', default=0,
help="correction for tiles where drone flies into left direction",
help="rotation correction for tiles where drone flies into left direction",
type=int, dest='rotation_corr_left'
)

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'
'--pos_corr_right', action='store', default="0x0",
help="position correction for tiles where drone flies into right direction in pixels. eg. 10x80",
type=str, dest='pos_corr_right'
)

arg_parser.add_argument(
'--direction', action='store', default='both',
help="left, right, both (both is default)",
type=str, dest='direction'
'--pos_corr_left', action='store', default="0x0",
help="position correction for tiles where drone flies into left direction in pixels. eg. 10x80",
type=str, dest='pos_corr_left'
)





args = arg_parser.parse_args()

dirname = os.path.dirname(__file__)
@@ -213,6 +226,8 @@ for root_path, directories, file in os.walk(os.path.join(dirname, working_dir)):
g_pos_el = ET.SubElement(main_layer, 'g', attrib=g_pos_el_attributes)

g_offset_corr_el_attributes = {
'data-offset-corr-x': "{}".format(-image.width/2),
'data-offset-corr-y': "{}".format(-image.height/2),
'transform': "translate({}, {})".format(-image.width/2, -image.height/2),
'class': 'tile-offset-corr',
}
@@ -256,18 +271,47 @@ for index, el in enumerate(main_layer):
if(el.getprevious() is not None):
prev_lon_offset = el.getprevious().attrib['data-lon-offset']
lon_offset = el.attrib['data-lon-offset']
if (prev_lon_offset > lon_offset or (prev_lon_offset == lon_offset and last_direction == 'left')):
# print('left {} -> {}'.format(prev_lon_offset, lon_offset))

# determine direction
direction = None
# print(prev_lon_offset - lon_offset)
if (prev_lon_offset == lon_offset):
direction = last_direction
# print('same lon!')
elif (float(prev_lon_offset) > float(lon_offset)):
direction = 'left'
elif (float(prev_lon_offset) < float(lon_offset)):
direction = 'right'

if (direction == 'left'):
# print('left {} | {} -> {}'.format(el.attrib['id'], prev_lon_offset, lon_offset))
el.attrib['data-direction'] = 'left'
if (args.pos_corr_left):
offset_corr_x, offset_corr_y = args.pos_corr_left.split('x')
# print(offset_corr_x, offset_corr_y)
pos_corr_el = el[0]
corrected_pos_x = float(pos_corr_el.attrib['data-offset-corr-x']) + float(offset_corr_x)
corrected_pos_y = float(pos_corr_el.attrib['data-offset-corr-y']) + float(offset_corr_y)
pos_corr_el.attrib['transform'] = "translate({}px, {}px)".format(corrected_pos_x, corrected_pos_y)

if (args.rotation_corr_left):
rot_el = el[0][0]
corrected_rotation = float(rot_el.attrib['data-image-rotation']) + args.rotation_corr_left
rot_el.attrib['data-image-rotation'] = str(corrected_rotation)
image = rot_el[0]
rot_el.attrib['transform'] = 'rotate({} {} {})'.format(str(corrected_rotation), str(int(image.attrib['width'])/2), str(int(image.attrib['height'])/2))
else:
# print('right {} -> {}'.format(prev_lon_offset, lon_offset))

if (direction == 'right'):
# print('right {} | {} -> {}'.format(el.attrib['id'], prev_lon_offset, lon_offset))
el.attrib['data-direction'] = 'right'
if (args.pos_corr_right):
offset_corr_x, offset_corr_y = args.pos_corr_right.split('x')
# print(offset_corr_x, offset_corr_y)
pos_corr_el = el[0]
corrected_pos_x = float(pos_corr_el.attrib['data-offset-corr-x']) + float(offset_corr_x)
corrected_pos_y = float(pos_corr_el.attrib['data-offset-corr-y']) + float(offset_corr_y)
pos_corr_el.attrib['transform'] = "translate({}px, {}px)".format(corrected_pos_x, corrected_pos_y)

if (args.rotation_corr_right):
rot_el = el[0][0]
corrected_rotation = float(rot_el.attrib['data-image-rotation']) + args.rotation_corr_right
@@ -278,13 +322,16 @@ for index, el in enumerate(main_layer):
# merge tiles into groups
# Start new line
if (args.direction == 'both' or args.direction == el.attrib['data-direction']):
if (index == 1 or last_direction is not el.attrib['data-direction']):
current_row = ET.SubElement(tile_rows, 'g', attrib={ 'class': 'tile-row' })
copyElem = copy.deepcopy(el)
# if direction changes
if (index == 1 or last_direction != el.attrib['data-direction']):
# print('new row!')
current_row = ET.SubElement(tile_rows, 'g', attrib={ 'class': 'tile-row' })
# print (el.attrib['id'], el.attrib['data-direction'])
current_row.insert(0, copyElem)

last_direction = el.attrib['data-direction']

# remove temporary group
root.remove(main_layer)



+ 1
- 1
requirements.txt View File

@@ -5,7 +5,7 @@ argparse==1.4.0
pyproj==3.2.1
flirimageextractor==1.4.0
opencv-contrib-python==4.5.3.56
numpy==1.19.5
numpy==1.21.2
pathlib==1.0.1
selenium==3.141.0
rasterio==1.2.8

Loading…
Cancel
Save