{"id":18,"date":"2012-12-05T16:31:43","date_gmt":"2012-12-06T00:31:43","guid":{"rendered":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/?page_id=18"},"modified":"2012-12-07T08:45:57","modified_gmt":"2012-12-07T16:45:57","slug":"code","status":"publish","type":"page","link":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/code\/","title":{"rendered":"Code"},"content":{"rendered":"<p>Included here is the code for the python script used in ArcGIS. As previously mentioned this is a site specific code and requires the presense of certain GIS grid files to be present within the working geodatabase to execute properly. But in the spirit of open source, here it is anyway. The author of the code in no way suggests that this is an accurate representation of the true avalanche hazard, it is simply a tool that can be used in helping to assess the current conditions.<\/p>\n<p>&#8221;&#8217;<br \/>\nCreated on Nov 16, 2012<br \/>\n@author: wesleyashwood<br \/>\n&#8221;&#8217;<\/p>\n<p>import urllib2<br \/>\nimport arcpy<br \/>\nfrom arcpy.sa import *<\/p>\n<p>#function to extract string from a given line of text<br \/>\ndef extract(raw_string, start_marker, end_marker):<br \/>\nstart = raw_string.index(start_marker) + len(start_marker)<br \/>\nend = raw_string.index(end_marker, start)<br \/>\nreturn raw_string[start:end]<\/p>\n<p>#get text from url<br \/>\nurl = urllib2.urlopen(&#8220;http:\/\/images.drivebc.ca\/bchighwaycam\/pub\/weather\/26224.html#&#8221;)<br \/>\ntext = url.readlines()<br \/>\nurl.close()<\/p>\n<p>#specific lines to search<br \/>\nlines = [3,9,11,13,15,17,19]<\/p>\n<p>#what to extract from each line<br \/>\nfor i in lines:<br \/>\nif i == 3:<br \/>\nline = text[i]<br \/>\nstart_marker = &#8216;right;background-color:#B9E5FB;padding:2px;&#8221;&gt;&#8217;<br \/>\nend_marker = &#8216;&lt;\/td&gt;&lt;\/tr&gt;&#8217;<br \/>\ntime = extract(line,start_marker,end_marker)<br \/>\nif i == 9:<br \/>\nline = text[i]<br \/>\nstart_marker = &#8216;0px;&#8221;&gt;&#8217;<br \/>\nend_marker = &#8216;&lt;sup&gt;o&lt;\/sup&gt;&#8217;<br \/>\ntemp = float(extract(line,start_marker,end_marker))<br \/>\nif i == 11:<br \/>\nline = text[i]<br \/>\nstart_marker = &#8216;0px;&#8221;&gt;&#8217;<br \/>\nend_marker = &#8216;mm (&lt;a href=&#8221;#&#8221;&#8216;<br \/>\nprecip = int(extract(line,start_marker,end_marker))<br \/>\nif i == 13:<br \/>\nline = text[i]<br \/>\nstart_marker = &#8216;0px;&#8221;&gt;&#8217;<br \/>\nend_marker = &#8216;&lt;\/td&gt;&lt;\/tr&gt;&#8217;<br \/>\nloading = extract(line,start_marker,end_marker)<br \/>\nif i == 15:<br \/>\nline = text[i]<br \/>\nstart_marker = &#8216;0px;&#8221;&gt;&#8217;<br \/>\nend_marker = &#8216; km\/h&lt;\/td&gt;&lt;\/tr&gt;&#8217;<br \/>\nwind = float(extract(line,start_marker,end_marker))<br \/>\nif i == 17:<br \/>\nline = text[i]<br \/>\nstart_marker = &#8216;0px;&#8221;&gt;&#8217;<br \/>\nend_marker = &#8216; km\/h&lt;\/td&gt;&lt;\/tr&gt;&#8217;<br \/>\nwind_max = float(extract(line,start_marker,end_marker))<br \/>\nif i == 19:<br \/>\nline = text[i]<br \/>\nstart_marker = &#8216;0px;&#8221;&gt;&#8217;<br \/>\nend_marker = &#8216;&lt;\/td&gt;&lt;\/tr&gt;&#8217;<br \/>\nwind_dir = extract(line,start_marker,end_marker)<\/p>\n<p>print time<br \/>\nprint &#8220;Temperature: &#8221; + str(temp) + &#8221; C&#8221;<br \/>\nprint &#8220;Precipitation since 0600 or 1800: &#8221; + str(precip) + &#8221; mm&#8221;<br \/>\nprint &#8220;Precipitation in last hour: &#8221; + loading<br \/>\nprint &#8220;Wind speed: &#8221; + str(wind) + &#8221; km\/h&#8221;<br \/>\nprint &#8220;Max. wind: &#8221; + str(wind_max) + &#8221; km\/h&#8221;<br \/>\nprint &#8220;Wind direction: &#8221; + wind_dir + &#8220;\\n&#8221;<\/p>\n<p>#Get average precipitation<br \/>\nstart_marker = &#8216; &#8216;<br \/>\nend_marker = &#8216;:00:00&#8217;<br \/>\nT = extract(time,start_marker,end_marker)<br \/>\nT = int(T)<br \/>\nif T &gt; 6:<br \/>\nT = T &#8211; 6<br \/>\nelse:<br \/>\nT = T + 6<br \/>\nP = 100*float(precip\/T) #mm\/hr water equivalent<\/p>\n<p>#Precipitation weight value<br \/>\nif P == 0:<br \/>\nwt_precip = 0<br \/>\nelif 0 &lt; P &lt;= 20:<br \/>\nwt_precip = 6<br \/>\nelif 20 &lt; P &lt;= 40:<br \/>\nwt_precip = 12<br \/>\nelif 40 &lt; P &lt;= 60:<br \/>\nwt_precip = 16<br \/>\nelif 60 &lt; P &lt;= 80:<br \/>\nwt_precip = 24<br \/>\nelif P &gt; 80:<br \/>\nwt_precip = 30<\/p>\n<p>#Assign aspect values to wind direction<br \/>\nif wind_dir == &#8220;N&#8221;:<br \/>\naspect = 180<br \/>\nelif wind_dir == &#8220;NE&#8221;:<br \/>\naspect = 225<br \/>\nelif wind_dir == &#8220;E&#8221;:<br \/>\naspect = 270<br \/>\nelif wind_dir == &#8220;SE&#8221;:<br \/>\naspect = 315<br \/>\nelif wind_dir == &#8220;S&#8221;:<br \/>\naspect = 0<br \/>\nelif wind_dir == &#8220;SW&#8221;:<br \/>\naspect = 45<br \/>\nelif wind_dir == &#8220;W&#8221;:<br \/>\naspect = 90<br \/>\nelif wind_dir == &#8220;NW&#8221;:<br \/>\naspect = 135<\/p>\n<p>#Aspect weight value<br \/>\nif wind_max == 0:<br \/>\nwt_wind = 2<br \/>\nelif 0 &lt; wind_max &lt;= 5:<br \/>\nwt_wind = 6<br \/>\nelif 5 &lt; wind_max &lt;= 10:<br \/>\nwt_wind = 12<br \/>\nelif 10 &lt; wind_max &lt;= 15:<br \/>\nwt_wind = 16<br \/>\nelif 15 &lt; wind_max &lt;= 20:<br \/>\nwt_wind = 24<br \/>\nelif wind_max &gt; 20:<br \/>\nwt_wind = 30<\/p>\n<p>#Weight for slope<br \/>\nwt_slope = 30<\/p>\n<p>#Elevation bonus<br \/>\nwt_elev = 5<\/p>\n<p>#Immediate loading bonus<br \/>\nif loading == &#8220;Yes&#8221;:<br \/>\nwt_loading = 5<br \/>\nelse:<br \/>\nwt_loading = 0<\/p>\n<p>#ArcGIS processing<\/p>\n<p>#Set environment<br \/>\narcpy.env.workspace = &#8220;C:\\data\\project\\Duffy_backcountry.gdb&#8221;<br \/>\narcpy.env.overwriteOutput = True<br \/>\narcpy.env.addOutputsToMap = False<br \/>\n#Check out extension<br \/>\narcpy.CheckOutExtension(&#8220;Spatial&#8221;)<\/p>\n<p>#Set clipping mask<br \/>\nmask = &#8220;bndy_mask&#8221;<\/p>\n<p>#Fuzzy Membership for slope, Gaussian Distribution centered at 38 degrees with spread of 0.01<br \/>\ntemp_FM_Slope = FuzzyMembership(&#8220;Slope_30m&#8221;, FuzzyGaussian(38, 0.01))<br \/>\n#Extract by Mask for slope<br \/>\nFM_bndy_Slope = ExtractByMask(temp_FM_Slope, mask)<\/p>\n<p>#Fuzzy Membership for aspect, Gaussian Distribution based on wind direction<br \/>\nif aspect == 0:<br \/>\n#Rotate values 180 degrees and perform FM<br \/>\ntemp_Aspect1 = Raster(&#8220;Aspect_30m&#8221;) + 180<br \/>\ntemp_Aspect2 = Con(temp_Aspect1 &gt; 360, temp_Aspect1 &#8211; 360, temp_Aspect1)<br \/>\ntemp_FM_Aspect = FuzzyMembership(temp_Aspect2, FuzzyGaussian(180, 0.001))<br \/>\n#Extract by Mask for Aspect<br \/>\nFM_bndy_Aspect = ExtractByMask(temp_FM_Aspect, mask)<br \/>\narcpy.Delete_management(temp_Aspect1)<br \/>\narcpy.Delete_management(temp_Aspect2)<br \/>\nelse:<br \/>\ntemp_FM_Aspect = FuzzyMembership(&#8220;Aspect_30m&#8221;, FuzzyGaussian(aspect, 0.001))<br \/>\nFM_bndy_Aspect = ExtractByMask(temp_FM_Aspect, mask)<\/p>\n<p>#Fuzzy Membership for elevation, need to get local max and min<br \/>\nradius = 100<br \/>\ntemp_stat_min = FocalStatistics(&#8220;DEM_30m&#8221;, NbrCircle(radius, &#8220;MAP&#8221;), &#8220;MINIMUM&#8221;, &#8220;&#8221;)<br \/>\ntemp_stat_max = FocalStatistics(&#8220;DEM_30m&#8221;, NbrCircle(radius, &#8220;MAP&#8221;), &#8220;MAXIMUM&#8221;, &#8220;&#8221;)<br \/>\ntemp_FM_Elev = 1.0 * (Raster(&#8220;DEM_30m&#8221;) &#8211; temp_stat_min) \/ (temp_stat_max &#8211; temp_stat_min)<br \/>\nFM_bndy_Elev = ExtractByMask(temp_FM_Elev, mask)<\/p>\n<p>print &#8220;Precipitation weight = &#8221; + str(wt_precip) + &#8220;%&#8221;<br \/>\nprint &#8220;Slope weight = &#8221; + str(wt_slope) + &#8220;%&#8221;<br \/>\nprint &#8220;Aspect weight based on max. wind speed = &#8221; + str(wt_wind) + &#8220;%&#8221;<br \/>\nprint &#8220;Elevation bonus = 5%&#8221;<br \/>\nprint &#8220;Immediate loading bonus = &#8221; + str(wt_loading)<\/p>\n<p>#Weighted Sum<br \/>\nWSumTableObj = WSTable([[FM_bndy_Slope, &#8220;VALUE&#8221;, wt_slope], [FM_bndy_Aspect, &#8220;VALUE&#8221;, wt_wind],<br \/>\n[FM_bndy_Elev, &#8220;VALUE&#8221;, wt_elev]])<br \/>\ntemp_WSum = WeightedSum(WSumTableObj)<br \/>\nAvalanche_Hazard = temp_WSum + wt_precip + wt_loading<br \/>\narcpy.env.addOutputsToMap = True<br \/>\nAvalanche_Hazard.save(&#8220;Avalanche_Hazard&#8221;)<\/p>\n<p>#Delete temp layers<br \/>\narcpy.Delete_management(temp_FM_Slope)<br \/>\narcpy.Delete_management(FM_bndy_Slope)<br \/>\narcpy.Delete_management(temp_FM_Aspect)<br \/>\narcpy.Delete_management(FM_bndy_Aspect)<br \/>\narcpy.Delete_management(temp_stat_min)<br \/>\narcpy.Delete_management(temp_stat_max)<br \/>\narcpy.Delete_management(temp_FM_Elev)<br \/>\narcpy.Delete_management(FM_bndy_Elev)<br \/>\narcpy.Delete_management(temp_WSum)<\/p>\n<p>arcpy.RefreshTOC()<br \/>\narcpy.RefreshActiveView()<\/p>\n<p>print &#8220;Avalanche hazard updated&#8221;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Included here is the code for the python script used in ArcGIS. As previously mentioned this is a site specific code and requires the presense of certain GIS grid files to be present within the working geodatabase to execute properly. But in the spirit of open source, here it is anyway. The author of the [&hellip;]<\/p>\n","protected":false},"author":15189,"featured_media":0,"parent":0,"menu_order":6,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-18","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/wp-json\/wp\/v2\/pages\/18","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/wp-json\/wp\/v2\/users\/15189"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":6,"href":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/wp-json\/wp\/v2\/pages\/18\/revisions"}],"predecessor-version":[{"id":90,"href":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/wp-json\/wp\/v2\/pages\/18\/revisions\/90"}],"wp:attachment":[{"href":"https:\/\/blogs.ubc.ca\/dynamicavalanche\/wp-json\/wp\/v2\/media?parent=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}