tileManagerDemo2.py
Author
lwiniwar

Created: 22.03.2016 Copyright: (c) lwiniwar 2016 Licence: opals license

1 ## @package python.demo.tileManagerDemo2
2 #
3 # @brief Demo script for a complex tiling with tileManager
4 #
5 # Takes a set of pointclouds and a set of rasters, creates buffered tiles, smoothes the raster,
6 # calculated normalized height in the point clouds, cuts the point clouds to net size, merges them.
7 #
8 #
9 
10 import sys, os
11 import glob
12 
13 import pprint
14 
15 import opals
16 from opals import StatFilter, AddInfo, Import
17 
18 from opals.tools import tileManager
19 from opals.tools.doxygen import brief
20 from opals.tools.opalsargparse import PkgArgumentParser, Boolean, PathArgument
21 
22 def run_tile(tile, searchRad, tempdir):
23  smoothfile = os.path.join(tempdir, tile['tile_name'], 'dtm_smooth.tif')
24  # create smoothed file
25  sf = StatFilter.StatFilter(inFile=tile['dtm'],
26  outFile=smoothfile,
27  feature="mean",
28  kernelShape=opals.Types.KernelShape.circle,
29  kernelSize=int(searchRad / 1.0)) # pixel size is 1
30  sf.run(reset=True)
31  # calculate normalized Z based on smoothed file
32  add = AddInfo.AddInfo(inFile=tile['pointcloud'],
33  gridFile=smoothfile,
34  attribute='NormalizedZ = Z - r[0]',
35  resampling=opals.Types.ResamplingMethod.bilinear)
36  add.run(reset=True)
37 
38 
39 @opals.main
40 def main(options, logger):
41  inp = [] #build list of input files (supporting wildcards)
42  for i in options.i:
43  inp.extend(glob.glob(str(i)))
44  if len(inp) == 0:
45  raise Exception("No input files found")
46  rasters = [] #build list of raster files (supporting wildcards)
47  for r in options.r:
48  rasters.extend(glob.glob(str(r)))
49  if len(rasters) == 0:
50  raise Exception("No raster files found")
51 
52  inp_files = [{'files': inp, # List of Files (relative or full path, no */?)
53  'type': 'odm', # either odm or raster
54  'name': 'pointcloud', # any name that can be used as a dict key and a (windows) filename
55  'required': True},
56  {'files': rasters,
57  'type': 'raster',
58  'name': 'dtm',
59  'required': True}
60  ]
61  tiling_concept = 'stripsPolygons.shp' # use existing shapefile
62  naming_concept = 'shp.id' # follow naming of the shapefile
63  tempdir = 'temp'
64 
65  searchRad = options.d
66 
67 
68  # prepare tileManager
69  tm = tileManager.tileManager(logger, inp_files, tiling_concept, naming_concept, tempdir, buffer=searchRad)
70  # get number of elements - this already cuts the files!
71  lix = len(tm)
72 
73  outfiles = []
74  # iterate over the tiles (no more cutting needed here)
75  for idx, tile in enumerate(tm):
76  print("Now processing tile %s/%s:" % (idx, lix))
77  pprint.pprint(tile)
78  run_tile(tile, searchRad=searchRad, tempdir=tempdir)
79  _, vectorfiles = tm.cutToNetSize(tile, vectorfiles=tile['pointcloud'], overwrite=False)
80  outfiles.append(vectorfiles[0])
81  # merge the output files into one mosaic
82  imp = Import.Import(inFile=outfiles,
83  outFile='mosaic.odm')
84  imp.run()
85 
86 if __name__ == '__main__':
87  parser = PkgArgumentParser(usage="%(prog)s [options]\n" + brief(__doc__))
88  parser.add_argument("-i", type=PathArgument, remarks='mandatory', nargs='*', help="input point cloud files")
89  parser.add_argument("-r", type=PathArgument, remarks='mandatory', nargs='*', help="input raster files")
90  parser.add_argument("-d", type=float, default=5.0, help="smoothing radius")
91  options = parser.parse_args(sys.argv[1:])
92  main(options)