From 89839b7e516aa536f77e40c030b3906d2ebaf112 Mon Sep 17 00:00:00 2001 From: bacetiner Date: Wed, 7 Feb 2024 14:50:13 -0800 Subject: [PATCH 1/2] Updated street-level imagery extraction to mark unattainable images as None --- brails/workflow/ImHandler.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/brails/workflow/ImHandler.py b/brails/workflow/ImHandler.py index c26c03d..3fd68b0 100644 --- a/brails/workflow/ImHandler.py +++ b/brails/workflow/ImHandler.py @@ -37,7 +37,7 @@ # Barbaros Cetiner # # Last updated: -# 01-09-2024 +# 02-07-2024 import os @@ -707,7 +707,7 @@ def download_streetlev_image(fp, fpcent, im_name, depthmap_name, apikey, try: pano['id'] = get_pano_id(pano['queryLatLon'],apikey) except: - return + return None # Get the metdata for the pano: pano = get_pano_meta(pano, savedmap = True, dmapoutname = depthmap_name) @@ -740,7 +740,7 @@ def download_streetlev_image(fp, fpcent, im_name, depthmap_name, apikey, # street-level imagery: self.footprints = footprints self.centroids = [] - self.street_images = [] + street_images = [] inps = [] for footprint in footprints: fp = np.fliplr(np.squeeze(np.array(footprint))).tolist() @@ -750,7 +750,7 @@ def download_streetlev_image(fp, fpcent, im_name, depthmap_name, apikey, imName.replace(".","") im_name = f"tmp/images/street/imstreet_{imName}.jpg" depthmap_name = f"tmp/images/depthmap/dmstreet_{imName}.txt" - self.street_images.append(im_name) + street_images.append(im_name) inps.append((fp,(fp_cent.y,fp_cent.x),im_name,depthmap_name)) # Download building-wise street-level imagery and depthmap strings: @@ -778,11 +778,12 @@ def download_streetlev_image(fp, fpcent, im_name, depthmap_name, apikey, if save_all_cam_metadata==False: self.cam_elevs = [] self.depthmaps = [] - for im in self.street_images: + for (ind,im) in enumerate(street_images): if results[im] is not None: self.cam_elevs.append(results[im][0]) self.depthmaps.append(results[im][1]) else: + street_images[ind] = None self.cam_elevs.append(None) self.depthmaps.append(None) else: @@ -793,7 +794,7 @@ def download_streetlev_image(fp, fpcent, im_name, depthmap_name, apikey, self.headings = [] self.pitch = [] self.zoom_levels = [] - for im in self.street_images: + for (ind,im) in enumerate(street_images): if results[im] is not None: self.cam_elevs.append(results[im][0]) self.cam_latlons.append(results[im][1]) @@ -810,7 +811,9 @@ def download_streetlev_image(fp, fpcent, im_name, depthmap_name, apikey, self.headings.append(None) self.pitch.append(None) self.zoom_levels.append(None) - + street_images[ind] = None + self.street_images = street_images.copy() + def GetGoogleStreetImageAPI(self,footprints): self.footprints = footprints[:] # Function that downloads a file given its URL and the desired path to save it: From 34488949c9487a4744caec9c04c663c23d06a77e Mon Sep 17 00:00:00 2001 From: bacetiner Date: Wed, 7 Feb 2024 14:51:31 -0800 Subject: [PATCH 2/2] Updated InventoryGenerator for more robust street-level image handling --- brails/InventoryGenerator.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/brails/InventoryGenerator.py b/brails/InventoryGenerator.py index fc2e337..6b94f2f 100644 --- a/brails/InventoryGenerator.py +++ b/brails/InventoryGenerator.py @@ -40,7 +40,7 @@ # Satish Rao # # Last updated: -# 02-01-2024 +# 02-07-2024 import random import sys @@ -229,7 +229,7 @@ def parse_attribute_input(attrIn,attrEnabled): return attrOut - def write_inventory_output(inventorydf,outFile): + def write_inventory_output(inventorydf,outFile,lengthUnit): """ Function that writes the data in inventorydf DataFrame into a CSV or GeoJSON file based on the file name defined in the outFile. @@ -254,7 +254,7 @@ def write_inventory_output(inventorydf,outFile): dfout = inventorydf.copy(deep=True) dfout = dfout.drop(columns=['satellite_images', 'street_images'], errors='ignore') - + for index, row in inventorydf.iterrows(): dfout.loc[index, 'Footprint'] = ('{"type":"Feature","geometry":' + @@ -267,14 +267,14 @@ def write_inventory_output(inventorydf,outFile): # Rearrange the column order of dfout such that the Footprint field is # the last: - cols = [col for col in dfout.columns if col!='Footprint'] + cols = [col for col in dfout.columns if col not in ['Footprint','Latitude','Longitude']] new_cols = ['Latitude','Longitude'] + cols + ['Footprint'] dfout = dfout[new_cols] # If the inventory is desired in CSV format, write dfout to a CSV: if '.csv' in outFile.lower(): dfout.to_csv(outFile, index=True, index_label='id') - + # Else write the inventory into a GeoJSON file: else: if '.geojson' not in outFile.lower(): @@ -287,7 +287,7 @@ def write_inventory_output(inventorydf,outFile): "properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84" }}, 'units': {"length": lengthUnit}, 'features':[]} - + attrs = dfout.columns.values.tolist() attrs.remove('Footprint') for index, row in dfout.iterrows(): @@ -300,13 +300,18 @@ def write_inventory_output(inventorydf,outFile): feature['geometry']['coordinates'] = json.loads(fp) feature['properties']['id'] = index for attr in attrs: - feature['properties'][attr] = row[attr] + res = row[attr] + if pd.isnull(res): + feature['properties'][attr] = 'NA' + else: + feature['properties'][attr] = res geojson['features'].append(feature) - + with open(outFile, 'w') as output_file: json.dump(geojson, output_file, indent=2) print(f'\nFinal inventory data available in {outFile} in {os.getcwd()}') + # Parse/correct the list of user requested building attributes: self.attributes = parse_attribute_input(attributes, self.enabledAttributes) @@ -465,7 +470,7 @@ def write_inventory_output(inventorydf,outFile): self.inventory['roofeaveheight'] = self.inventory['roofeaveheight'].apply(lambda x: x*0.3048) # Write the genereated inventory in outFile: - write_inventory_output(self.inventory,outFile) + write_inventory_output(self.inventory,outFile,lengthUnit) # Merge the DataFrame of predicted attributes with the DataFrame of # incomplete inventory and print the resulting table to the output file