1# import the batch module and dbvalue from init
2# set the global variable, batch, on init before importing this file
3import brl_init
4dbvalue = brl_init.DummyBatch()
5batch = brl_init.DummyBatch()
6
7
8def create_satellite_resouces(roi_kml, leaf_size=0.1,
9                              eliminate_same_images=False):
10    batch.init_process("volmCreateSatResourcesProcess")
11    batch.set_input_string(0, roi_kml)
12    batch.set_input_float(1, leaf_size)
13    batch.set_input_bool(2, eliminate_same_images)
14    batch.run_process()
15    (id, type) = batch.commit_output(0)
16    sat_res = dbvalue(id, type)
17    return sat_res
18
19
20def add_satellite_resources(sat_res, sat_res_folder):
21    batch.init_process("volmAddSatelliteResourcesProcess")
22    batch.set_input_from_db(0, sat_res)
23    batch.set_input_string(1, sat_res_folder)
24    batch.run_process()
25
26
27def save_satellite_resources(sat_res, out_file):
28    batch.init_process("volmSaveSatResourcesProcess")
29    batch.set_input_from_db(0, sat_res)
30    batch.set_input_string(1, out_file)
31    batch.run_process()
32
33
34def map_sdet_to_volm_ids(sdet_color_class_img):
35    batch.init_process("volmGenerateClassMapProcess")
36    batch.set_input_from_db(0, sdet_color_class_img)
37    batch.run_process()
38    (id, type) = batch.commit_output(0)
39    out_img = dbvalue(id, type)
40    return out_img
41
42
43def volm_id_color_img(id_img, id_to_color_txt=""):
44    batch.init_process("volmGenerateColorClassMapProcess")
45    batch.set_input_from_db(0, id_img)
46    batch.set_input_string(1, id_to_color_txt)
47    batch.run_process()
48    (id, type) = batch.commit_output(0)
49    out_img = dbvalue(id, type)
50    return out_img
51
52
53def update_class_map(class_img, source_img):
54    batch.init_process("volmUpdateClassMapProcess")
55    batch.set_input_from_db(0, class_img)
56    batch.set_input_from_db(1, source_img)
57    status = batch.run_process()
58    return status
59
60
61def load_sat_resources(res_file_name):
62    batch.init_process("volmLoadSatResourcesProcess")
63    batch.set_input_string(0, res_file_name)
64    batch.run_process()
65    (res2_id, res2_type) = batch.commit_output(0)
66    res2 = dbvalue(res2_id, res2_type)
67    return res2
68
69
70def find_resource_pair(res, name, tol=10.0):
71    batch.init_process("volmFindResourcePairProcess")
72    batch.set_input_from_db(0, res)
73    batch.set_input_string(1, name)
74    batch.set_input_double(2, tol)
75    statuscode = batch.run_process()
76    (f_id, f_type) = batch.commit_output(0)
77    full_path = batch.get_output_string(f_id)
78    batch.remove_data(f_id)
79    (n_id, n_type) = batch.commit_output(1)
80    pair_name = batch.get_output_string(n_id)
81    batch.remove_data(n_id)
82    (p_id, p_type) = batch.commit_output(2)
83    full_path_pair_name = batch.get_output_string(p_id)
84    batch.remove_data(p_id)
85    return statuscode, full_path, pair_name, full_path_pair_name
86
87
88def get_full_path(res, name):
89    batch.init_process("volmGetFullPathProcess")
90    batch.set_input_from_db(0, res)
91    batch.set_input_string(1, name)
92    statuscode = batch.run_process()
93    (f_id, f_type) = batch.commit_output(0)
94    full_path = batch.get_output_string(f_id)
95    batch.remove_data(f_id)
96    return full_path
97
98## band_name is PAN or MULTI
99
100
101def pick_nadir_resource(res, lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, satellite_name, band_name="PAN", non_cloud_folder=""):
102    batch.init_process("volmPickNadirResProcess")
103    batch.set_input_from_db(0, res)
104    batch.set_input_double(1, lower_left_lon)
105    batch.set_input_double(2, lower_left_lat)
106    batch.set_input_double(3, upper_right_lon)
107    batch.set_input_double(4, upper_right_lat)
108    batch.set_input_string(5, band_name)
109    batch.set_input_string(6, satellite_name)
110    batch.set_input_string(7, non_cloud_folder)
111    batch.run_process()
112    (id, type) = batch.commit_output(0)
113    sat_path = batch.get_output_string(id)
114    return sat_path
115
116# find the PAN/MULTI pair for given rectangular region, also output the
117# sorted list of such PAN/MULIT lists
118
119
120def pick_nadir_resource_pair(res, lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, satellite_name, out_folder, band_name="PAN", non_cloud_folder=""):
121    batch.init_process("volmPickNadirResPairProcess")
122    batch.set_input_from_db(0, res)
123    batch.set_input_double(1, lower_left_lon)
124    batch.set_input_double(2, lower_left_lat)
125    batch.set_input_double(3, upper_right_lon)
126    batch.set_input_double(4, upper_right_lat)
127    batch.set_input_string(5, band_name)
128    batch.set_input_string(6, satellite_name)
129    batch.set_input_string(7, non_cloud_folder)
130    batch.set_input_string(8, out_folder)
131    statuscode = batch.run_process()
132    if statuscode:
133        (p_id, p_type) = batch.commit_output(0)
134        pan_path = batch.get_output_string(p_id)
135        batch.remove_data(p_id)
136        (m_id, m_type) = batch.commit_output(1)
137        multi_path = batch.get_output_string(m_id)
138        batch.remove_data(m_id)
139    else:
140        pan_path = ""
141        multi_path = ""
142    return statuscode, pan_path, multi_path
143
144# GSD: ground sampling distance, e.g. pass 1 to eliminate all the images
145# which have pixel GSD more than 1 meter; the default is 10 meters, so
146# practically returns all the satellite images
147
148
149def scene_resources(res, lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, scene_res_file, band="PAN", GSD_threshold=10.0, pick_seeds=0, n_seeds=0):
150    batch.init_process("volmQuerySatelliteResourcesProcess")
151    batch.set_input_from_db(0, res)
152    batch.set_input_double(1, lower_left_lon)
153    batch.set_input_double(2, lower_left_lat)
154    batch.set_input_double(3, upper_right_lon)
155    batch.set_input_double(4, upper_right_lat)
156    batch.set_input_string(5, scene_res_file)
157    batch.set_input_string(6, band)
158    # of 0, it returns all resources that intersect the box, otherwise, it
159    # picks n_seeds among these resources
160    batch.set_input_bool(7, pick_seeds)
161    batch.set_input_int(8, n_seeds)
162    batch.set_input_double(9, GSD_threshold)
163    batch.run_process()
164    (id, type) = batch.commit_output(0)
165    cnt = batch.get_output_unsigned(id)
166    return cnt
167
168
169def scene_resources2(res, poly_kml, scene_res_file, band="PAN", GSD_threshold=10.0, pick_seeds=0, n_seeds=0):
170    batch.init_process("volmQuerySatelliteResourceKmlProcess")
171    batch.set_input_from_db(0, res)
172    batch.set_input_string(1, poly_kml)
173    batch.set_input_string(2, scene_res_file)
174    batch.set_input_string(3, band)
175    batch.set_input_bool(4, pick_seeds)
176    batch.set_input_int(5, n_seeds)
177    batch.set_input_double(6, GSD_threshold)
178    batch.run_process()
179    (id, type) = batch.commit_output(0)
180    cnt = batch.get_output_unsigned(id)
181    return cnt
182
183
184def find_stereo_pairs(res, lower_left_lon, lower_left_lat, upper_right_lon, upper_right_lat, GSD_threshold, scene_res_file, satellite_name):
185    batch.init_process("volmFindSatellitePairsProcess")
186    batch.set_input_from_db(0, res)
187    batch.set_input_double(1, lower_left_lon)
188    batch.set_input_double(2, lower_left_lat)
189    batch.set_input_double(3, upper_right_lon)
190    batch.set_input_double(4, upper_right_lat)
191    batch.set_input_string(5, scene_res_file)
192    batch.set_input_string(6, satellite_name)
193    batch.set_input_float(7, GSD_threshold)
194    batch.run_process()
195    (id, type) = batch.commit_output(0)
196    cnt = batch.get_output_unsigned(id)
197    return cnt
198
199
200def find_stereo_pairs2(res, poly_roi, GSD_threshold, scene_res_file, satellite_name):
201    batch.init_process("volmFindSatellitePairsPolyProcess")
202    batch.set_input_from_db(0, res)
203    batch.set_input_string(1, poly_roi)
204    batch.set_input_string(2, scene_res_file)
205    batch.set_input_string(3, satellite_name)
206    batch.set_input_float(4, GSD_threshold)
207    batch.run_process()
208    (id, type) = batch.commit_output(0)
209    cnt = batch.get_output_unsigned(id)
210    return cnt
211
212
213def find_seed_sat_resources(res, poly_kml, downsample_factor, sat_res_file):
214    batch.init_process("volmFindOverlappingSatResourcesProcess")
215    batch.set_input_from_db(0, res)             # satellite resource
216    batch.set_input_string(1, poly_kml)         # kml polygon filename
217    # factor by which to downsample resource footprints when
218    batch.set_input_float(2, downsample_factor)
219    # computing the raster (smaller factor takes more time & memory)
220    # output file to print the list (this will also save a kml version)
221    batch.set_input_string(3, sat_res_file)
222    batch.run_process()
223
224
225def find_intersecting_sat_resources(res, poly_kml, max_intersecting_resources, sat_res_file):
226    batch.init_process("volmFindIntersectingSatResourcesProcess")
227    batch.set_input_from_db(0, res)         # satellite resource
228    batch.set_input_string(1, poly_kml)     # kml polygon filename
229    # maximum number of intersecting images to consider, e.g., 5
230    batch.set_input_float(2, max_intersecting_resources)
231    # be careful with this number as this process computes
232    # a rising powerset, i.e., n choose k ... n choose l
233    # output file to print the list (this will also save a kml version)
234    batch.set_input_string(3, sat_res_file)
235    batch.run_process()
236
237
238def correct_ransac_process(cor_file, output_folder, pixel_radius):
239    batch.init_process("volmCorrectRationalCamerasRANSACProcess")
240    batch.set_input_string(0, cor_file)
241    batch.set_input_string(1, output_folder)
242    # pixel radius to count for inliers
243    batch.set_input_float(2, pixel_radius)
244    batch.run_process()
245
246# this one checks if the camera is already corrected and exists in the output folder
247# weights the cameras accordingly
248
249
250def correct_ransac_process2(res, cor_file, output_folder, pixel_radius, enforce_existing=0):
251    batch.init_process("volmCorrectRationalCamerasRANSACProcess2")
252    batch.set_input_from_db(0, res)
253    batch.set_input_string(1, cor_file)
254    batch.set_input_string(2, output_folder)
255    # pixel radius to count for inliers
256    batch.set_input_float(3, pixel_radius)
257    # if 1: enforce to have at least 2 existing images
258    batch.set_input_int(4, enforce_existing)
259    statuscode = batch.run_process()
260    return statuscode
261
262# this one perform camera correction with an 3-d initial guessing point
263# defined from the overlapped region of all cameras
264
265
266def correct_ransac_with_initial_process(res, cor_file, dem_folder, output_folder, pixel_radius, enforce_existing=False):
267    batch.init_process("volmCorrectRationalCameraRANSACwithIntialProcess")
268    batch.set_input_from_db(0, res)
269    batch.set_input_string(1, cor_file)
270    batch.set_input_string(2, dem_folder)
271    batch.set_input_string(3, output_folder)
272    batch.set_input_float(4, pixel_radius)
273    batch.set_input_bool(5, enforce_existing)
274    status = batch.run_process()
275    return status
276
277# process to transfer geo_index leaf id to leaf string
278# the geo index is loaded from tree_txt
279
280
281def obtain_leaf_string(tree_txt, out_txt):
282    batch.init_process("volmTransferGeoIndexIDToStr")
283    batch.set_input_string(0, tree_txt)
284    batch.set_input_string(1, out_txt)
285    batch.run_process()
286
287# process to transfer geo_index leaf id to leaf string
288# the geo index is created from given region and min_size
289
290
291def obtain_leaf_string2(min_size, in_poly, out_txt):
292    batch.init_process("volmTransferGeoIndexIDToStr")
293    batch.set_input_float(0, min_size)
294    batch.set_input_string(1, in_poly)
295    batch.set_input_string(2, out_txt)
296    batch.run_process()
297
298
299def generate_height_map_from_ply(ply_folder, ni, nj):
300    batch.init_process("volmGenerateHeightMapFromPlyProcess")
301    batch.set_input_string(0, ply_folder)
302    batch.set_input_unsigned(1, ni)
303    batch.set_input_unsigned(2, nj)
304    batch.run_process()
305    (id, type) = batch.commit_output(0)
306    out = dbvalue(id, type)
307    return out
308
309# process to refine the height map obtained from bvxm world
310# max_h and min_h are the predominant height for sky and ground mask
311
312
313def refine_bvxm_height_map(img, max_h, min_h):
314    batch.init_process("volmRefineBvxmHeightMapProcess")
315    batch.set_input_from_db(0, img)
316    batch.set_input_float(1, max_h)
317    batch.set_input_float(2, min_h)
318    status = batch.run_process()
319    if status:
320        (id, type) = batch.commit_output(0)
321        out_img = dbvalue(id, type)
322    else:
323        out_img = 0
324    return out_img
325
326# process to project open street map roads onto a cropped satellite images using
327# its local cropped RPC camera, an ortho height map and an ortho camera
328
329
330def project_osm_to_crop_img(crop_img, crop_cam, ortho_img, ortho_cam, osm_bin_file, band="r", is_road=True, is_region=False, vsol_bin_filename="", kml_file=""):
331    batch.init_process("volmMapOSMtoImage")
332    batch.set_input_from_db(0, crop_img)
333    batch.set_input_from_db(1, crop_cam)
334    batch.set_input_from_db(2, ortho_img)
335    batch.set_input_from_db(3, ortho_cam)
336    batch.set_input_string(4, osm_bin_file)
337    batch.set_input_string(5, band)
338    batch.set_input_bool(6, is_region)
339    batch.set_input_bool(7, is_road)
340    batch.set_input_string(8, vsol_bin_filename)
341    batch.set_input_string(9, kml_file)
342    status = batch.run_process()
343    if status:
344        (id, type) = batch.commit_output(0)
345        out_img = dbvalue(id, type)
346    else:
347        out_img = 0
348    return out_img
349
350# process to project open street map roads onto an ortho image using its
351# vpgl_geo_camera. no height map is necessary
352
353
354def project_osm_to_ortho_img(img_byte, ortho_cam, osm_file, output_vsol_binary_name=""):
355    batch.init_process("volmMapOSMProcess")
356    batch.set_input_from_db(0, img_byte)
357    batch.set_input_from_db(1, ortho_cam)
358    batch.set_input_string(2, osm_file)
359    batch.set_input_string(3, output_vsol_binary_name)
360    # process returns true if any osm objects hit the image area in this tile
361    hit = batch.run_process()
362    (id, type) = batch.commit_output(0)
363    out_img = dbvalue(id, type)
364    return hit, out_img
365
366
367def project_osm_category_to_ortho_img(img_byte, ortho_cam, osm_file, osm_category_name, output_vsol_binary_name):
368    batch.init_process("volmMapOSMontoImageProcess3")
369    batch.set_input_from_db(0, img_byte)
370    batch.set_input_from_db(1, ortho_cam)
371    batch.set_input_string(2, osm_file)
372    batch.set_input_string(3, osm_category_name)
373    batch.set_input_string(4, output_vsol_binary_name)
374    # process returns true if any osm objects hit the image area in this tile
375    hit = batch.run_process()
376    return hit
377
378# process to project open street map roads onto a cropped satellite images using
379# its local cropped RPC camera, an ortho height map and an ortho camera
380# pass osm_category_name as in the volm category names in table:
381# Dropbox\projects\FINDER\data\OSM\land_category_08_12_2014.txt
382
383
384def project_osm_to_crop_img2(crop_img, crop_cam, ortho_img, ortho_cam, osm_bin_file, osm_category_name, vsol_bin_filename):
385    batch.init_process("volmMapOSMontoImageProcess2")
386    batch.set_input_from_db(0, crop_img)
387    batch.set_input_from_db(1, crop_cam)
388    batch.set_input_from_db(2, ortho_img)
389    batch.set_input_from_db(3, ortho_cam)
390    batch.set_input_string(4, osm_bin_file)
391    batch.set_input_string(5, osm_category_name)
392    batch.set_input_string(6, vsol_bin_filename)
393    status = batch.run_process()
394    if status:
395        (id, type) = batch.commit_output(0)
396        out_img = dbvalue(id, type)
397        (id, type) = batch.commit_output(1)
398        out_mask = dbvalue(id, type)
399        return out_img, out_mask
400    else:
401        return None, None
402
403# process to project DEM images to a satellite image given the satellite viewpoint
404# modified to also input ortho camera (instead of a rational camera) so
405# that DEMs or height maps can be projected onto any ortho image - just
406# pass the ortho cam for sat_cam
407
408
409def project_dem_to_sat_img(sat_cam, sat_img, dem_file, lower_left_lon=-1.0, lower_left_lat=-1.0, upper_right_lon=-1.0, upper_right_lat=-1.0, dem_cam=0):
410    batch.init_process("volmProjectDEMtoSatImgPorcess")
411    batch.set_input_from_db(0, sat_cam)
412    batch.set_input_from_db(1, sat_img)
413    batch.set_input_string(2, dem_file)
414    batch.set_input_from_db(3, dem_cam)
415    batch.set_input_double(4, lower_left_lon)
416    batch.set_input_double(5, lower_left_lat)
417    batch.set_input_double(6, upper_right_lon)
418    batch.set_input_double(7, upper_right_lat)
419    status = batch.run_process()
420    return status
421
422# process to up-sample the projected cropped ASTER DEM image
423
424
425def upsample_projected_img(input_img, num_neighbors=4, bin_size_col=30, bin_size_row=30):
426    batch.init_process("volmUpsampleDemImgProcess")
427    batch.set_input_from_db(0,  input_img)
428    batch.set_input_unsigned(1, num_neighbors)
429    batch.set_input_unsigned(2, bin_size_col)
430    batch.set_input_unsigned(3, bin_size_row)
431    status = batch.run_process()
432    if status:
433        (id, type) = batch.commit_output(0)
434        output_img = dbvalue(id, type)
435    else:
436        output_img = 0
437    return output_img
438
439
440def generate_height_map_plot(gt_height, height, dif_init, dif_final, dif_increment, gt_fix):
441    batch.init_process("volmGenerateHeightMapPlotProcess")
442    batch.set_input_from_db(0, gt_height)
443    batch.set_input_from_db(1, height)
444    batch.set_input_float(2, dif_init)
445    batch.set_input_float(3, dif_final)
446    batch.set_input_float(4, dif_increment)
447    batch.set_input_float(5, gt_fix)
448    batch.run_process()
449    (id, type) = batch.commit_output(0)
450    correct_rate_array = batch.get_bbas_1d_array_float(id)
451    (id, type) = batch.commit_output(1)
452    height_dif_array = batch.get_bbas_1d_array_float(id)
453    (id, type) = batch.commit_output(2)
454    out_map = dbvalue(id, type)
455    (id, type) = batch.commit_output(3)
456    out_map_dif = dbvalue(id, type)
457    return correct_rate_array, height_dif_array, out_map, out_map_dif
458
459# combine height map
460
461
462def combine_height_map(height_map_folder, poly_roi, out_folder, size_in_degree=0.0625, leaf_id=-1):
463    batch.init_process("volmCombineHeightMapProcess")
464    batch.set_input_string(0, height_map_folder)
465    batch.set_input_string(1, poly_roi)
466    batch.set_input_string(2, out_folder)
467    batch.set_input_float(3, size_in_degree)
468    batch.set_input_int(4, leaf_id)
469    batch.run_process()
470
471# combine height maps by taking the median pixel values
472
473
474def combine_height_map2(height_map_folder, threshold):
475    batch.init_process("volmCombineHeightMapProcess2")
476    batch.set_input_string(0, height_map_folder)
477    batch.set_input_float(1, threshold)
478    status = batch.run_process()
479    if status:
480        (id, type) = batch.commit_output(0)
481        out_map = dbvalue(id, type)
482        return out_map
483    else:
484        return 0
485
486# combine dem generated from multiple stereo pairs
487
488def combine_dem_pairs(height_map_folder, threshold, out_dir = "", select_pair = False, is_debug = False):
489    batch.init_process("volmCombineDEMPairsProcess")
490    batch.set_input_string(0, height_map_folder)
491    batch.set_input_float(1, threshold)
492    batch.set_input_bool(2, select_pair)
493    batch.set_input_bool(3, is_debug)
494    batch.set_input_string(4, out_dir)
495    status = batch.run_process()
496    if status:
497        (id, type) = batch.commit_output(0)
498        out_map = dbvalue(id, type)
499        (id, type) = batch.commit_output(1)
500        out_conf = dbvalue(id, type)
501        return out_map, out_conf
502    else:
503        return None, None
504
505# process that takes an ortho height map, an ortho classification map (id image) and their ortho camera
506# extracts the outlines of the buildings in the classification map
507# converts them to geo positions and outputs a .csv file and a kml file
508
509
510def extract_building_outlines(height_img, class_img, geocam, csv_file_name, kml_file_name):
511    batch.init_process("volmExtractBuildinOutlinesProcess")
512    batch.set_input_from_db(0, height_img)
513    batch.set_input_from_db(1, class_img)
514    batch.set_input_from_db(2, geocam)
515    batch.set_input_string(3, csv_file_name)
516    batch.set_input_string(4, kml_file_name)
517    batch.run_process()
518    (id, type) = batch.commit_output(0)
519    binary_img = dbvalue(id, type)
520    (id, type) = batch.commit_output(1)
521    binary_img_e = dbvalue(id, type)
522    (id, type) = batch.commit_output(2)
523    binary_img_d = dbvalue(id, type)
524    return binary_img, binary_img_e, binary_img_d
525
526
527def registration_error_analysis(gt_file, cor_file, ori_file, gsd=1.0, cor_vector_file="", ori_vector_file=""):
528    batch.init_process("volmRegistrationErrorProcess")
529    batch.set_input_string(0, gt_file)
530    batch.set_input_string(1, cor_file)
531    batch.set_input_string(2, ori_file)
532    batch.set_input_double(3, gsd)
533    batch.set_input_string(4, cor_vector_file)
534    batch.set_input_string(5, ori_vector_file)
535    status = batch.run_process()
536    if status:
537        (id, type) = batch.commit_output(0)
538        cor_average = batch.get_output_double(id)
539        (id, type) = batch.commit_output(1)
540        cor_std = batch.get_output_double(id)
541        (id, type) = batch.commit_output(2)
542        ori_average = batch.get_output_double(id)
543        (id, type) = batch.commit_output(3)
544        ori_std = batch.get_output_double(id)
545        return cor_average, cor_std, ori_average, ori_std
546    else:
547        return 0.0, 0.0, 0.0, 0.0
548
549
550def stereo_h_map_fix(h_img, height_fix=0.0):
551    batch.init_process("volmStereoHeightFixProcess")
552    batch.set_input_from_db(0, h_img)
553    batch.set_input_float(1, height_fix)
554    batch.run_process()
555
556# process that find the minimum and maximum elevation from height map, for
557# a give 2-d rectangluar region
558
559
560def find_min_max_elev(ll_lon, ll_lat, ur_lon, ur_lat, dem_folder):
561    batch.init_process("volmFindMinMaxHeightPorcess")
562    batch.set_input_double(0, ll_lon)
563    batch.set_input_double(1, ll_lat)
564    batch.set_input_double(2, ur_lon)
565    batch.set_input_double(3, ur_lat)
566    batch.set_input_string(4, dem_folder)
567    status = batch.run_process()
568    if status:
569        (id, type) = batch.commit_output(0)
570        min_elev = batch.get_output_double(id)
571        (id, type) = batch.commit_output(1)
572        max_elev = batch.get_output_double(id)
573        return min_elev, max_elev
574    else:
575        return 0.0, 0.0
576
577# process that generate normalized height map from multiple height map tiles created by bvxm 3-d reconstruction
578# the land cover image is used to define the ground pixel and coverage region
579
580
581def generate_ndsm(ll_lon, ll_lat, ur_lon, ur_lat, img_size_ni, img_size_nj, geo_index_txt, h_map_folder, grd_map_folder, window_size=20, max_h_limit=254.0):
582    batch.init_process("volmNdsmGenearationProcess")
583    batch.set_input_double(0, ll_lon)
584    batch.set_input_double(1, ll_lat)
585    batch.set_input_double(2, ur_lon)
586    batch.set_input_double(3, ur_lat)
587    batch.set_input_unsigned(4, img_size_ni)
588    batch.set_input_unsigned(5, img_size_nj)
589    batch.set_input_string(6, geo_index_txt)
590    batch.set_input_string(7, h_map_folder)
591    batch.set_input_string(8, grd_map_folder)
592    batch.set_input_unsigned(9, window_size)
593    batch.set_input_float(10, max_h_limit)
594    status = batch.run_process()
595    if status:
596        (id, type) = batch.commit_output(0)
597        out_ndsm = dbvalue(id, type)
598        (id, type) = batch.commit_output(1)
599        out_dsm = dbvalue(id, type)
600        (id, type) = batch.commit_output(2)
601        grd_img = dbvalue(id, type)
602        (id, type) = batch.commit_output(3)
603        out_cam = dbvalue(id, type)
604        return out_ndsm, out_dsm, grd_img, out_cam
605    else:
606        return None, None, None, None
607
608# process to estimate ground plane from a height map
609
610
611def dsm_ground_estimation(dsm_image, invalid_pixel=-1.0, window_size=20, sample_size=10):
612    batch.init_process("volmDsmGroundEstimationProcess")
613    batch.set_input_from_db(0, dsm_image)
614    batch.set_input_int(1, sample_size)
615    batch.set_input_int(2, window_size)
616    batch.set_input_float(3, invalid_pixel)
617    status = batch.run_process()
618    if status:
619        (id, type) = batch.commit_output(0)
620        grd_img = dbvalue(id, type)
621        return grd_img
622    else:
623        return None
624
625
626def dsm_ground_estimation_edge(dsm_image, edge_img, invalid_pixel=-1.0, sample_size=10):
627    batch.init_process("volmDsmGroundEstimationEdgeProcess")
628    batch.set_input_from_db(0, dsm_image)
629    batch.set_input_from_db(1, edge_img)
630    batch.set_input_int(2, sample_size)
631    batch.set_input_float(3, invalid_pixel)
632    status = batch.run_process()
633    if status:
634        (id, type) = batch.commit_output(0)
635        grd_img = dbvalue(id, type)
636        return grd_img
637    else:
638        return None
639
640
641def dsm_mgf_ground_filtering(dsm_img, elev_thres, slope_thres, window_size=3.0, pixel_res=1.0):
642    batch.init_process("volmDsmGroundFilterMGFProcess")
643    batch.set_input_from_db(0, dsm_img)
644    batch.set_input_float(1, window_size)
645    batch.set_input_float(2, elev_thres)
646    batch.set_input_float(3, slope_thres)
647    batch.set_input_float(4, pixel_res)
648    status = batch.run_process()
649    if status:
650        (id, type) = batch.commit_output(0)
651        grd_mask = dbvalue(id, type)
652        (id, type) = batch.commit_output(1)
653        grd_img = dbvalue(id, type)
654        return grd_mask, grd_img
655    else:
656        return None, None
657
658# process to mosaics a set of images that covers the given region
659
660
661def combine_geotiff_images(ll_lon, ll_lat, ur_lon, ur_lat, in_img_folder, init_value=-1.0):
662    batch.init_process("volmCombineHeightMapProcess3")
663    batch.set_input_string(0, in_img_folder)
664    batch.set_input_double(1, ll_lon)
665    batch.set_input_double(2, ll_lat)
666    batch.set_input_double(3, ur_lon)
667    batch.set_input_double(4, ur_lat)
668    batch.set_input_float(5, init_value)
669    status = batch.run_process()
670    if status:
671        (id, type) = batch.commit_output(0)
672        out_img = dbvalue(id, type)
673        (id, type) = batch.commit_output(1)
674        out_cam = dbvalue(id, type)
675        return out_img, out_cam
676    else:
677        return None, None
678
679# process to generate building layers from land cover image and height image
680
681
682def generate_building_layers(land_img, land_cam, height_img, height_cam, land_txt, min_h, max_h):
683    batch.init_process("volmBuildingLayerExtractionProcess")
684    batch.set_input_from_db(0, land_img)
685    batch.set_input_from_db(1, land_cam)
686    batch.set_input_from_db(2, height_img)
687    batch.set_input_from_db(3, height_cam)
688    batch.set_input_string(4, land_txt)
689    batch.set_input_float(5, min_h)
690    batch.set_input_float(6, max_h)
691    status = batch.run_process()
692    if status:
693        (id, type) = batch.commit_output(0)
694        out_img = dbvalue(id, type)
695        (id, type) = batch.commit_output(1)
696        mask_img = dbvalue(id, type)
697        (id, type) = batch.commit_output(2)
698        out_cam = dbvalue(id, type)
699        return out_img, mask_img, out_cam
700    else:
701        return None, None, None
702
703
704def generate_layers(land_img, land_cam, height_img, height_cam, land_txt, min_h, max_h, beta=10.0):
705    batch.init_process("volmLayerExtractionProcess")
706    batch.set_input_from_db(0, land_img)
707    batch.set_input_from_db(1, land_cam)
708    batch.set_input_from_db(2, height_img)
709    batch.set_input_from_db(3, height_cam)
710    batch.set_input_string(4, land_txt)
711    batch.set_input_float(5, min_h)
712    batch.set_input_float(6, max_h)
713    batch.set_input_double(7, beta)
714    status = batch.run_process()
715    if status:
716        (id, type) = batch.commit_output(0)
717        out_prob_img = dbvalue(id, type)
718        (id, type) = batch.commit_output(1)
719        out_img = dbvalue(id, type)
720        (id, type) = batch.commit_output(2)
721        mask_img = dbvalue(id, type)
722        (id, type) = batch.commit_output(3)
723        out_cam = dbvalue(id, type)
724        return out_prob_img, out_img, mask_img, out_cam
725    else:
726        return None, None, None, None
727
728# process to convert a polygons in KML to geotiff byte image
729# Note that this process will update the input image according to given
730# polygon structures
731
732
733def render_kml_polygon_mask(in_kml, image, ll_lon, ll_lat, ur_lon, ur_lat, mask_value=255):
734    batch.init_process("volmRenderKmlPolygonMaskProcess")
735    batch.set_input_from_db(0, image)
736    batch.set_input_double(1, ll_lon)
737    batch.set_input_double(2, ll_lat)
738    batch.set_input_double(3, ur_lon)
739    batch.set_input_double(4, ur_lat)
740    batch.set_input_string(5, in_kml)
741    batch.set_input_unsigned(6, mask_value)
742    status = batch.run_process()
743    if status:
744        (id, type) = batch.commit_output(0)
745        out_cam = dbvalue(id, type)
746        return out_cam
747    else:
748        return None
749
750# process to generate a kml file from a binary image
751
752
753def generate_kml_from_image(in_img, in_cam, out_kml, threshold=127, r=0, g=255, b=0):
754    batch.init_process("volmGenerateKmlFromBinaryImageProcess")
755    batch.set_input_from_db(0, in_img)
756    batch.set_input_from_db(1, in_cam)
757    batch.set_input_unsigned(2, threshold)
758    batch.set_input_string(3, out_kml)
759    batch.set_input_unsigned(4, r)
760    batch.set_input_unsigned(5, g)
761    batch.set_input_unsigned(6, b)
762    status = batch.run_process()
763    if status:
764        (id, type) = batch.commit_output(0)
765        n_connected_component = batch.get_output_unsigned(id)
766        return n_connected_component
767    else:
768        return None
769
770# process to downsample a binary layer image
771
772
773def downsample_binary_layer(in_img, in_mask, in_cam, out_img, out_mask, out_cam):
774    batch.init_process("volmDownsampleLayerImageProcess")
775    batch.set_input_from_db(0, in_img)
776    batch.set_input_from_db(1, in_mask)
777    batch.set_input_from_db(2, in_cam)
778    batch.set_input_from_db(3, out_img)
779    batch.set_input_from_db(4, out_mask)
780    batch.set_input_from_db(5, out_cam)
781    status = batch.run_process()
782    return status
783
784# process to compute detection rate based ROC
785
786
787def region_wise_roc_analysis(in_img, in_cam, positive_kml, negative_kml):
788    batch.init_process("volmDetectionRateROCProcess")
789    batch.set_input_from_db(0, in_img)
790    batch.set_input_from_db(1, in_cam)
791    batch.set_input_string(2, positive_kml)
792    batch.set_input_string(3, negative_kml)
793    status = batch.run_process()
794    if status:
795        (id, type) = batch.commit_output(0)
796        thres_out = batch.get_bbas_1d_array_float(id)
797        (id, type) = batch.commit_output(1)
798        tp = batch.get_bbas_1d_array_float(id)
799        (id, type) = batch.commit_output(2)
800        tn = batch.get_bbas_1d_array_float(id)
801        (id, type) = batch.commit_output(3)
802        fp = batch.get_bbas_1d_array_float(id)
803        (id, type) = batch.commit_output(4)
804        fn = batch.get_bbas_1d_array_float(id)
805        (id, type) = batch.commit_output(5)
806        tpr = batch.get_bbas_1d_array_float(id)
807        (id, type) = batch.commit_output(6)
808        fpr = batch.get_bbas_1d_array_float(id)
809        return thres_out, tp, tn, fp, fn, tpr, fpr
810    else:
811        return None, None, None, None, None, None, None
812