1
+ import rasterio
2
+ import geopandas as gpd
3
+ import numpy
4
+ import os
5
+ import sys
6
+ from osgeo import ogr
7
+ from osgeo import gdal
8
+ from osgeo import osr
9
+ import pandas as pd
10
+ from rasterio .windows import Window
11
+ from rasterio .windows import from_bounds
12
+ from rasterio .mask import mask
13
+ import tqdm .notebook as tqdm
14
+ import numpy .ma as ma
15
+ import numpy as np
16
+ def Exposure (input_zone , input_value_raster ,Ear_Table_PK ):
17
+ vector = ogr .Open (input_zone )
18
+ lyr = vector .GetLayer ()
19
+ feat = lyr .GetNextFeature ()
20
+ geom = feat .GetGeometryRef ()
21
+ geometrytype = geom .GetGeometryName ()
22
+ if (geometrytype == 'POLYGON' or geometrytype == 'MULTIPOLYGON' ):
23
+ return zonalPoly (input_zone ,input_value_raster ,Ear_Table_PK ,agg_col = None )
24
+
25
+ elif (geometrytype == 'POINT' or geometrytype == 'MULTIPOINT' ):
26
+ return zonalLine (input_zone ,input_value_raster ,Ear_Table_PK ,agg_col = None )
27
+
28
+ elif (geometrytype == 'LINESTRING' or geometrytype == 'MULTILINESTRING' ):
29
+ return zonalPoint (lyr ,input_value_raster ,Ear_Table_PK ,agg_col = None )
30
+ def zonalPoly (input_zone_data ,input_value_raster ,Ear_Table_PK ,agg_col = None ):
31
+ raster = rasterio .open (input_value_raster )
32
+ data = gpd .read_file (input_zone_data )
33
+ df = pd .DataFrame ()
34
+ for ind ,row in tqdm .tqdm (data .iterrows (),total = data .shape [0 ]):
35
+ maska ,transform = rasterio .mask .mask (raster , [row .geometry ], crop = True ,nodata = 0 )
36
+ zoneraster = ma .masked_array (maska , mask = maska == 0 )
37
+ len_ras = zoneraster .count ()
38
+ #print(len_ras)
39
+ if len_ras == 0 :
40
+ continue
41
+
42
+ unique , counts = np .unique (zoneraster , return_counts = True )
43
+ if ma .is_masked (unique ):
44
+ unique = unique .filled (0 )
45
+ idx = np .where (unique == 0 )[0 ][0 ]
46
+ #print(idx)
47
+ ids = np .delete (unique , idx )
48
+ cus = np .delete (counts , idx )
49
+ else :
50
+ ids = unique
51
+ cus = counts
52
+ frequencies = np .asarray ((ids , cus )).T
53
+ for i in range (len (frequencies )):
54
+ frequencies [i ][1 ]= (frequencies [i ][1 ]/ len_ras )* 100
55
+ #print(frequencies)
56
+ df_temp = pd .DataFrame (frequencies , columns = ['class' ,'exposed' ])
57
+ df_temp ['geom_id' ]= row [Ear_Table_PK ]
58
+ df = df .append (df_temp ,ignore_index = True )
59
+
60
+ raster = None
61
+ return df
62
+ def zonalLine (lyr ,input_value_raster ,Ear_Table_PK ,agg_col = None ):
63
+ tempDict = {}
64
+ featlist = range (lyr .GetFeatureCount ())
65
+ raster = gdal .Open (input_value_raster )
66
+
67
+ projras = osr .SpatialReference (wkt = raster .GetProjection ())
68
+ epsgras = projras .GetAttrValue ('AUTHORITY' ,1 )
69
+
70
+ projear = lyr .GetSpatialRef ()
71
+ epsgear = projear .GetAttrValue ('AUTHORITY' ,1 )
72
+ #print(epsgear,epsgras)
73
+ if not epsgras == epsgear :
74
+ toEPSG = "EPSG:" + str (epsgear )
75
+ output_raster = input_value_raster .replace (".tif" ,"_projected.tif" )
76
+ gdal .Warp (output_raster ,input_value_raster ,dstSRS = toEPSG )
77
+ raster = None
78
+ raster = gdal .Open (output_raster )
79
+ else :
80
+ pass
81
+ # Get raster georeference info
82
+ raster_srs = osr .SpatialReference ()
83
+ raster_srs .ImportFromWkt (raster .GetProjectionRef ())
84
+ gt = raster .GetGeoTransform ()
85
+ xOrigin = gt [0 ]
86
+ yOrigin = gt [3 ]
87
+ pixelWidth = gt [1 ]
88
+ pixelHeight = gt [5 ]
89
+ rb = raster .GetRasterBand (1 )
90
+
91
+
92
+ df = pd .DataFrame ()
93
+ for FID in featlist :
94
+ feat = lyr .GetFeature (FID )
95
+ geom = feat .GetGeometryRef ()
96
+ extent = geom .GetEnvelope ()
97
+ xmin = extent [0 ]
98
+ xmax = extent [1 ]
99
+ ymin = extent [2 ]
100
+ ymax = extent [3 ]
101
+
102
+ xoff = int ((xmin - xOrigin )/ pixelWidth )
103
+ yoff = int ((yOrigin - ymax )/ pixelWidth )
104
+ xcount = int ((xmax - xmin )/ pixelWidth )+ 1
105
+ ycount = int ((ymax - ymin )/ pixelWidth )+ 1
106
+
107
+ target_ds = gdal .GetDriverByName ('MEM' ).Create ('' , xcount , ycount , 1 , gdal .GDT_Byte )
108
+ target_ds .SetGeoTransform ((
109
+ xmin , pixelWidth , 0 ,
110
+ ymax , 0 , pixelHeight ,
111
+ ))
112
+ # Create for target raster the same projection as for the value raster
113
+ target_ds .SetProjection (raster_srs .ExportToWkt ())
114
+
115
+ gdal .RasterizeLayer (target_ds , [1 ], lyr , burn_values = [1 ])
116
+
117
+ # Read raster as arrays
118
+ banddataraster = raster .GetRasterBand (1 )
119
+ dataraster = banddataraster .ReadAsArray (xoff , yoff , xcount , ycount ).astype (numpy .float )
120
+
121
+ bandmask = target_ds .GetRasterBand (1 )
122
+ datamask = bandmask .ReadAsArray (0 , 0 , xcount , ycount ).astype (numpy .float )
123
+ # Mask zone of raster
124
+ zoneraster = numpy .ma .masked_array (dataraster , numpy .logical_not (datamask ))
125
+ #print(zoneraster)
126
+ (unique , counts ) = numpy .unique (zoneraster , return_counts = True )
127
+ unique [unique .mask ] = 9999
128
+ if 9999 in unique :
129
+ falsedata = numpy .where (unique == 9999 )[0 ][0 ]
130
+ ids = numpy .delete (unique , falsedata )
131
+ cus = numpy .delete (counts , falsedata )
132
+ else :
133
+ ids = unique
134
+ cus = counts
135
+ #print(ids)
136
+ frequencies = numpy .asarray ((ids , cus )).T
137
+ len_ras = zoneraster .count ()
138
+ for i in range (len (frequencies )):
139
+ frequencies [i ][1 ]= (frequencies [i ][1 ]/ len_ras )* 100
140
+
141
+ df_temp = pd .DataFrame (frequencies , columns = ['class' ,'exposed' ])
142
+ df_temp ['geom_id' ] = feat [Ear_Table_PK ]
143
+ #df_temp['exposure_id'] = exposure_id
144
+ #df_temp['admin_unit'] =feat[agg_col]
145
+ df = df .append (df_temp ,ignore_index = True )
146
+ raster = None
147
+ return df
148
+ def zonalPoint (lyr ,input_value_raster ,Ear_Table_PK ,agg_col ):
149
+ df = gpd .read_file (lyr )
150
+ src = rasterio .open (input_value_raster )
151
+ print ("Calculating via centroid" )
152
+ coords = [(x ,y ) for x , y in tqdm .tqdm (zip (df .geometry .x , df .geometry .y ))]
153
+ a = src .sample (coords )
154
+ exposure = []
155
+ for value in a :
156
+ exposure .append (value [0 ])
157
+ df ['class' ]= exposure
158
+ df ['exposed' ]= 100
159
+ df .loc [(df ['class' ]< 0 )| (df ['class' ]> 1000 ), 'class' ] = 0
160
+ df .loc [df ['class' ]== 0 , 'exposed' ] = 0
161
+ df = df .rename (columns = {Ear_Table_PK :'geom_id' })
162
+ if agg_col != None :
163
+ df_sel = df [['class' ,'exposed' ,'geom_id' ,'admin_unit' ]]
164
+ else :
165
+ df_sel = df [['class' ,'exposed' ,'geom_id' ]]
166
+
167
+ src = None
168
+ return df_sel
169
+ def saveshp (df ,outputname ):
170
+ df .to_file (outputname + ".shp" )
171
+ def savecsv (df ,outputname ):
172
+ df .drop ('geometry' ,axis = 1 ).to_csv (outputname + ".csv" )
173
+ def ComputeExposure (ear ,hazard ,ear_key ,outputdir ,outputformat = "csv" ):
174
+ exposure = Exposure (ear , hazard ,ear_key )
175
+ #import geopandas as gpd
176
+ ear = gpd .read_file (ear )
177
+ exposure_merged = ear .merge (exposure , how = 'right' , left_on = [ear_key ], right_on = ['geom_id' ])
178
+ if outputformat == "shp" :
179
+ saveshp (exposure_merged ,outputdir )
180
+ if outputformat == "csv" :
181
+ savecsv (exposure_merged ,outputdir )
182
+ def aggregate (df ,agg_col ):
183
+ try :
184
+ df ['exposed_areaOrLen' ]= df ['exposed' ]* df ['areaOrLen' ]/ 100
185
+ df_aggregated = df .groupby (['admin_unit' ,'class' ],as_index = False ).agg ({'exposed_areaOrLen' :'sum' ,'exposed' :'count' })
186
+ except :
187
+ df_aggregated = df .groupby (['admin_unit' ,'class' ],as_index = False ).agg ({'exposed' :'count' })
188
+ return df_aggregated
189
+ def ComputeExposureAgg (ear ,hazard ,ear_key ,admin_unit ,agg_col ,outputname ,outputformat = "csv" ):
190
+ ear_data = gpd .read_file (ear )
191
+ admin_data = gpd .read_file (admin_unit )
192
+ ear_temp = gpd .overlay (ear_data , admin_data , how = 'intersection' , make_valid = True , keep_geom_type = True )
193
+
194
+ tempfile = ear .replace (".shp" ,"_tempadmin.shp" )
195
+ ear_temp .to_file (tempfile )
196
+ ear = tempfile
197
+
198
+ exposure = Exposure (ear , hazard ,ear_key ,agg_col )
199
+ agg_exposure = aggregate (exposure ,agg_col )
200
+ #import geopandas as gpd
201
+ #admin=gpd.read_file(ear)
202
+ exposure_merged = admin_data .merge (agg_exposure , how = 'right' , left_on = [agg_col ], right_on = ['admin_unit' ])
203
+ #return exposure_merged
204
+ if outputformat == "shp" :
205
+ saveshp (exposure_merged ,outputdir )
206
+ if outputformat == "csv" :
207
+ savecsv (exposure_merged ,outputdir )
0 commit comments