File size: 8,214 Bytes
d217564
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
07cb5be
 
 
 
 
 
d217564
 
 
 
 
 
 
 
 
 
07cb5be
d217564
8909510
 
07cb5be
 
 
 
 
 
 
 
 
 
 
 
 
d217564
 
 
 
 
 
 
 
 
 
 
07cb5be
 
d217564
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import ee
import geemap
import solara

def applyBurnedPopulationMask(image, burnedData):
        popMask = image.select('population').neq(0)  # masking out areas that have 0 population
        burnedMask = burnedData.select('BurnDate').neq(0)  # masking out areas that were not burned
        mask = popMask.And(burnedMask)  # only keep areas that were both burned and have a population
        return image.updateMask(mask).select("population").copyProperties(image, ['population'])



class Map(geemap.Map):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.add_ee_data()
        self.basemap_added = False
        # self.add_plot_gui()
    
         
    def add_ee_data(self):
        california_area = ee.FeatureCollection("TIGER/2018/States").filter(ee.Filter.eq('NAME', 'California'))
        # population grid
        popdataset2020 = ee.ImageCollection("WorldPop/GP/100m/pop")\
            .filterDate("2020-01-01", "2021-01-01")

        pop2020 = popdataset2020.mean().clip(california_area)

        pop_params = {
        'bands': ['population'],
        'min': 1.0,
        'max': 60.0,
        'palette' : ['bdd7e7','6baed6','2171b5']
        }

        popdataset2001 = ee.ImageCollection("WorldPop/GP/100m/pop")\
            .filterDate("2001-01-01", "2002-01-01")

        pop2001 = popdataset2001.mean().clip(california_area)

        # burned
        burnedCollection2020 = ee.ImageCollection('MODIS/006/MCD64A1').filter(ee.Filter.date('2020-01-01', '2021-01-01'))
        burned2020 = burnedCollection2020.select('BurnDate').mean().clip(california_area)
        burned_params = {
        'min': 30.0,
        'max': 341.0,
        'palette':['red']
        }

        burnedCollection2001 = ee.ImageCollection('MODIS/006/MCD64A1').filter(ee.Filter.date('2001-01-01', '2002-01-01'))
        burned2001 = burnedCollection2001.select('BurnDate').mean().clip(california_area)
        burnedpop2020 = popdataset2020.map(lambda img: applyBurnedPopulationMask(img, burned2020))
        burnedpop2001 = popdataset2001.map(lambda img: applyBurnedPopulationMask(img, burned2001))

        impacted_pop_params = {
            'bands': ['population'],
            'min': 0.0,
            'max': 60.0,
            'palette' : ['white','bdd7e7','6baed6','2171b5']
        }

        # plot graph
        roi = ee.Geometry.Point(-119.6, 37.4)
        self.add_basemap("SATELLITE")

        # num_legends = self.getLegendCount()

    
        # legend for population
        legend_dict = {
            'No population': '000000',
            'Low population':'6baed6',
            'High population': '2171b5',
            'Area with population affected by wildfires': 'ffffff',
            'Burn areas': 'ff0000'
        }
        self.centerObject(roi, 4)
        # try:
        #     self.add_legend(legend_title="Population and Burn Scars", legend_elements=legend_dict)
        # except Exception as e:
        #     print(f"Error adding legend: {e}")


        landcover2 = ee.ImageCollection("NOAA/DMSP-OLS/NIGHTTIME_LIGHTS") \
            .filter(ee.Filter.date('1992-01-01', '1992-12-31')).mean()
        curImage = landcover2.select('stable_lights')
        curImage = curImage.where(curImage.neq(1), 1)
        self.add_layer(curImage,{'palette':['white']},'Background')

        landcover = ee.ImageCollection('USGS/NLCD').select('landcover').filterDate("2016-01-01", "2017-01-01").first().clip(california_area)
        landcover3 = ee.ImageCollection("NOAA/DMSP-OLS/NIGHTTIME_LIGHTS") \
            .filter(ee.Filter.date('1992-01-01', '1992-12-31')).mean()
        curImage = landcover3.select('stable_lights').clip(california_area)
        curImage = curImage.updateMask(landcover.neq(11).And(landcover.neq(12)).And(landcover.neq(90)).And(landcover.neq(95)).And(landcover.neq(31)))
        curImage = curImage.where(curImage.neq(1), 1)
        self.add_layer(curImage,{'palette':['a4a7ab']},'California')


        # population
        worldPop2020 = ee.ImageCollection("WorldPop/GP/100m/pop")\
            .filterDate("2020-01-01", "2020-12-01").select('population').mean().clip(california_area)

        worldPop2020 = worldPop2020.updateMask(worldPop2020.gte(5))

        worldPop2001 = ee.ImageCollection("WorldPop/GP/100m/pop")\
            .filterDate("2001-01-01", "2002-12-01").select('population').mean().clip(california_area)

        worldPop2001 = worldPop2001.updateMask(worldPop2001.gte(5))

        pop_params2 = {
        'bands': ['population'],
        'min': 0.0,
        'max': 50.0,
        'palette': ['white','bdd7e7','6baed6','2171b5']
        }

       
        self.addLayer(pop2020, pop_params, "Population 2020", False)
        self.addLayer(burned2020, burned_params, 'Burned Area 2020', True, 0.6)
        self.addLayer(burnedpop2020, impacted_pop_params, "Area of Impacted Population 2020", False)
        self.addLayer(worldPop2020, pop_params2, "Impacted Population Overlay 2020", True)

        self.addLayer(pop2001, pop_params, "Population 2001", False)
        self.addLayer(burned2001, burned_params, 'Burned Area 2001', False, 0.6)
        self.addLayer(burnedpop2001, impacted_pop_params, "Area of Impacted Population 2001", False)
        self.addLayer(worldPop2001, pop_params2, "Impacted Population Overlay 2001", False)

        
        # self.centerObject(roi, 10)
        # self.addLayer(roi, {}, 'ROI')
        # try:
        #     self.add_legend(legend_title="Population and Burn Scars", legend_elements=legend_dict)
        # except Exception as e:
        #     print(f"Error adding legend: {e}")
        
        # time.sleep(20)
        # add_legend_after_overlay(self)     

@solara.component
def Page():
    with solara.Column(align="center"):
        markdown = """
            ## California Wildfire Analysis
            
            ### Estimated California Population Directly Affected by wildfire (2000 to 2020)

            **For this analysis we will be using [WorldPop Global Project Population Data: Estimated Residential Population per 100x100m Grid Square dataset](https://developers.google.com/earth-engine/datasets/catalog/WorldPop_GP_100m_pop#bands) for population, [MCD64A1.061 MODIS Burned Area Monthly Global 500m](https://developers.google.com/earth-engine/datasets/catalog/MODIS_061_MCD64A1) dataset for burn scars, 
            [TIGER: US Census States 2018](https://developers.google.com/earth-engine/datasets/catalog/TIGER_2018_States) for state geometry, [DMSP OLS: Nighttime Lights Time Series Version 4](https://developers.google.com/earth-engine/datasets/catalog/NOAA_DMSP-OLS_NIGHTTIME_LIGHTS) and [USGS/NLCD](https://www.usgs.gov/centers/eros/science/national-land-cover-database) for land cover with geemap. First, we will compute the zonal statistics to identify the countries with the largest forest area, and then plot them. Here the base tree cover imagery is taken from 2000**
            """
        solara.Markdown(markdown)
    
    with solara.Column(align="center",style={"min-width": "500px"}):
            forest_barchart_image_url = "/static/public/wildfire_population.png"
            solara.Image(forest_barchart_image_url)
    
    with solara.Column(align="center"):
        markdown = """

            ### Population Density and wildfire burn area

            **Let's visualize the popluation with wildfire burn area**
            #### Population and Wildfire Color Coding
            - **No population**: `#000000` ![#000000](https://via.placeholder.com/15/000000/000000?text=+)
            - **Low population**: `#6baed6` ![#6baed6](https://via.placeholder.com/15/6baed6/000000?text=+)
            - **High population**: `#2171b5` ![#2171b5](https://via.placeholder.com/15/2171b5/000000?text=+)
            - **Area with population affected by wildfires**: `#ffffff` ![#ffffff](https://via.placeholder.com/15/ffffff/000000?text=+)
            - **Burn areas**: `#ff0000` ![#ff0000](https://via.placeholder.com/15/ff0000/000000?text=+)
            """
        solara.Markdown(markdown)
    
    with solara.Column(style={"min-width": "500px"}):
        Map.element(
            center=[35, -120],
            zoom=4.5,
            height="600px",
        )