Supervised Classification with the Google Earth Engine - google-earth-engine
For a classification of the Cerrado (a region in Brazil) I have chosen to do a supervised classification using the Google Earth Engine. When running the script an error message pop's up in the console stating: "classified: Layer error: Property 'agriculture' of feature '0_0' is missing." This doesn't seems to be the problem for my other classes (city and forest) while I do exactly the same.
city, agriculture and forest are polygons drawn with the polygon tool. landsat is the image I want to classify. Goias is the region I'm focussing on.
What is the meaning of this feature '0_0'?
var forest = /* color: #0b4a8b */ee.Geometry.MultiPolygon(
[[[[-49.95376110076904, -15.710967112810327],
[-49.95560646057129, -15.714189425198422],
[-49.952216148376465, -15.71480909481255],
[-49.950928688049316, -15.709603811453348],
[-49.955735206604004, -15.70952118683543]]],
[[[-50.87038993835449, -14.062653514869359],
[-50.854811668395996, -14.071645244690382],
[-50.84751605987549, -14.064984738032894],
[-50.8626651763916, -14.058906856438178]]],
[[[-50.811166763305664, -14.182430235294726],
[-50.838375091552734, -14.184677018750275],
[-50.833847522735596, -14.201195329073467],
[-50.80580234527588, -14.200300844289204]]],
[[[-50.632081031799316, -14.484754464079412],
[-50.6339693069458, -14.49414484704292],
[-50.60023784637451, -14.4989645351375]]],
[[[-50.56989669799805, -14.577186033177513],
[-50.56955337524414, -14.552928914937938],
[-50.57933807373047, -14.566220817061826]]],
[[[-50.89845657348633, -18.015384864469013],
[-50.89292049407959, -18.01269129442521],
[-50.898070335388184, -18.01093637057725]]],
[[[-50.92931270599365, -18.013793214420286],
[-50.925493240356445, -18.018690553238297],
[-50.92193126678467, -18.013017789956983],
[-50.92467784881592, -18.011058807691924]]],
[[[-50.90643882751465, -18.011058807691924],
[-50.90373516082764, -18.01036499625073],
[-50.90437889099121, -18.006283697189883],
[-50.90643882751465, -18.006283697189883]]],
[[[-50.87399482727051, -17.982896032077118],
[-50.878329277038574, -17.97950803295561],
[-50.88137626647949, -17.985794148396778],
[-50.884766578674316, -17.984651234967618],
[-50.8857536315918, -17.985794148396778],
[-50.882019996643066, -17.990651447894532]]],
[[[-50.917725563049316, -17.979059016144365],
[-50.914249420166016, -17.981671461584988],
[-50.90897083282471, -17.97697719600834],
[-50.90939998626709, -17.974936172047833],
[-50.91085910797119, -17.976650633759945]]],
[[[-50.90394973754883, -17.97358908331176],
[-50.899529457092285, -17.97501781345918],
[-50.89794158935547, -17.971466377179688],
[-50.902276039123535, -17.96795569182738],
[-50.90682506561279, -17.96909871332269]]]]),
goias = /* color: #ffc82d */ee.Geometry.Polygon(
[[[-53.89773987402128, -17.737335150077946],
[-53.21656208374657, -18.780701454086767],
[-50.93127514381945, -19.71426205863078],
[-46.953989190809466, -18.46836077330379],
[-45.76744438500839, -14.848185932899527],
[-45.899312773543386, -12.69278776942265],
[-48.86573729240354, -12.585603620983632],
[-50.2225991477078, -12.338855625969925],
[-51.73879790880113, -15.224867030408598],
[-52.07001767927636, -15.322314089978098],
[-52.44591109792566, -15.65224412638864]]]),
city = /* color: #00ffff */ee.Geometry.MultiPolygon(
[[[[-47.92356491088867, -15.824128602644778],
[-47.92081832885742, -15.837010357573558],
[-47.90245056152344, -15.826275618823361],
[-47.8809928894043, -15.80563028827748],
[-47.89266586303711, -15.798692984390442]]],
[[[-48.13058853149414, -15.823798290439452],
[-48.11857223510742, -15.823302821119514],
[-48.108787536621094, -15.831725634384997],
[-48.12681198120117, -15.841799518532302],
[-48.11634063720703, -15.851047232007138],
[-48.100032806396484, -15.836349774735691],
[-48.07668685913086, -15.830899883899415],
[-48.09385299682617, -15.800840270519277],
[-48.11634063720703, -15.799188513979754],
[-48.12440872192383, -15.786469537412923],
[-48.140201568603516, -15.790103612200987]]],
[[[-48.07342529296875, -15.804474087471961],
[-48.05419921875, -15.826771080856748],
[-48.060035705566406, -15.798032276385078],
[-48.073768615722656, -15.803317880062274]]],
[[[-48.1230354309082, -15.884896851962742],
[-48.119773864746094, -15.898930392135671],
[-48.06364059448242, -15.87944827271288],
[-48.07394027709961, -15.855505799598921]]],
[[[-48.06621551513672, -15.912632786660408],
[-48.04939270019531, -15.922702625654379],
[-48.05574417114258, -15.908340570752602],
[-48.04269790649414, -15.902892626277593],
[-48.04664611816406, -15.899425675672019],
[-48.07119369506836, -15.902232259341346]]],
[[[-47.78572082519531, -15.89992095798885],
[-47.77627944946289, -15.907515134108964],
[-47.769412994384766, -15.903718081898417],
[-47.77799606323242, -15.891666093512773]]],
[[[-47.88991928100586, -15.846423428228759],
[-47.87395477294922, -15.85055182952652],
[-47.867088317871094, -15.841634376941688],
[-47.8754997253418, -15.831065034266503]]],
[[[-48.035831451416016, -15.806786482478387],
[-48.015403747558594, -15.814714493330174],
[-48.00870895385742, -15.790433979404416],
[-48.04664611816406, -15.793902802515186]]],
[[[-47.849063873291016, -15.745168658461244],
[-47.837562561035156, -15.758881482187945],
[-47.8318977355957, -15.768298186245215],
[-47.83498764038086, -15.749629558126074],
[-47.87137985229492, -15.724184595030325]]],
[[[-49.28895950317383, -16.659872383959307],
[-49.29119110107422, -16.668259437653628],
[-49.280033111572266, -16.683552530348035],
[-49.27196502685547, -16.66020129494842],
[-49.28861618041992, -16.658721191047853]]],
[[[-49.28947448730469, -16.722519717319],
[-49.279518127441406, -16.71840962984931],
[-49.26338195800781, -16.727451705356305],
[-49.2597770690918, -16.715121496109433],
[-49.27042007446289, -16.713970635912027],
[-49.289817810058594, -16.693911672384527]]],
[[[-49.34560775756836, -16.770847694791637],
[-49.33479309082031, -16.77528536317065],
[-49.3260383605957, -16.770354614132874],
[-49.34080123901367, -16.763944449213486]]],
[[[-49.33582305908203, -16.655596489686744],
[-49.33067321777344, -16.666450496373013],
[-49.321231842041016, -16.6666149462869],
[-49.32294845581055, -16.65115603689586],
[-49.3121337890625, -16.641123523891356],
[-49.323463439941406, -16.64013669096455],
[-49.34440612792969, -16.652307275281608]]]]),
image = ee.ImageCollection("LANDSAT/LC8_SR"),
agriculture = /* color: #d63000 */ee.Geometry.MultiPolygon(
[[[[-45.955810546875, -14.076641147746095],
[-45.924224853515625, -14.061988097202269],
[-45.797882080078125, -13.963388675891327],
[-45.8734130859375, -13.928069145372694],
[-45.99220275878906, -13.998036539606128]]],
[[[-45.874786376953125, -14.12325823495085],
[-45.874786376953125, -14.152555522222587],
[-45.87409973144531, -14.18917181904185],
[-45.8349609375, -14.19383165093469],
[-45.78620910644531, -14.148560659841655],
[-45.847320556640625, -14.06065595513735],
[-45.913238525390625, -14.099284922844143]]],
[[[-46.13433837890625, -14.138573196735809],
[-46.13433837890625, -14.09662106589108],
[-46.175537109375, -14.05266293986954],
[-46.198883056640625, -14.056659482401876],
[-46.21124267578125, -14.1325805083437]]],
[[[-46.201629638671875, -13.81274334991904],
[-46.193389892578125, -13.91607260401736],
[-46.12335205078125, -13.872079964542497],
[-45.962677001953125, -13.82941246714161],
[-45.935211181640625, -13.749389841111972],
[-46.1810302734375, -13.736050073136349]]],
[[[-46.21467590332031, -13.558559225740643],
[-46.14738464355469, -13.571241563074146],
[-46.138458251953125, -13.559226734063092],
[-46.19407653808594, -13.532524939185093]]],
[[[-45.578155517578125, -14.576938127714245],
[-45.46073913574219, -14.455293324015502],
[-45.49919128417969, -14.449973994986367],
[-45.65574645996094, -14.572286279238748],
[-45.69419860839844, -14.629430744817604],
[-45.61180114746094, -14.584912496585007]]],
[[[-45.59497833251953, -15.266631865983076],
[-45.533180236816406, -15.270275113711289],
[-45.51807403564453, -15.289152747755958],
[-45.518760681152344, -15.275905463068401],
[-45.517730712890625, -15.23085844143626],
[-45.487518310546875, -15.227877047992555],
[-45.52082061767578, -15.197729476629094],
[-45.56304931640625, -15.205018295784908],
[-45.552406311035156, -15.252720702239158]]],
[[[-45.591888427734375, -15.199386048559994],
[-45.560646057128906, -15.198060792056202],
[-45.554466247558594, -15.175530157957471],
[-45.607337951660156, -15.167577595475684]]],
[[[-45.751190185546875, -15.428529514464561],
[-45.748443603515625, -15.405361690934004],
[-45.718231201171875, -15.400065825806683],
[-45.753936767578125, -15.366301517721318],
[-45.775909423828125, -15.413305235719099]]],
[[[-48.28216552734375, -16.494855107721587],
[-48.25864791870117, -16.497324042366905],
[-48.26774597167969, -16.520695062112992],
[-48.23530197143555, -16.51460570242487],
[-48.23616027832031, -16.485143659165615],
[-48.278045654296875, -16.479217790217742]]]]);
var bands = ['B2','B3','B4','B5','B6','B7'];
var cloudy_water_landsat = ee.ImageCollection('LANDSAT/LC8_SR')
.filterBounds(goias)
.filterDate('2016-06-01', '2016-07-10')
.median()
.set('SENSOR_ID', 'OLI_TIRS');
var datamask = cloudy_water_landsat.select('cfmask_conf');
var mask = datamask.eq(1);
var water_landsat = cloudy_water_landsat.updateMask(mask);
var datawater = water_landsat.select('cfmask');
var not_water = datawater.eq(1);
var water = not_water.not();
var landsat = water_landsat.updateMask(water);
var RGB = {
bands: ['B4', 'B3', 'B2'],
min: -2000,
max: 2000,
gamma: [1,1,1],
};
Map.addLayer(landsat, RGB, 'RGB');
var agriculture = ee.Feature (landsat.clip(agriculture));
var city = ee.Feature (landsat.clip(city));
var forest = ee.Feature (landsat.clip(forest));
var polygons = ee.FeatureCollection([agriculture,city,forest]);
var training = landsat.sampleRegions(
{
collection: polygons,
properties: ['agriculture','city', 'forest'],
scale: 500
});
var classifier = ee.Classifier.svm(
{
kernelType: 'RBF',
gamma: 0.1,
cost: 10
});
var trained = classifier.train(training, ('agriculture','city', 'forest'), bands);
var classified = landsat.classify(trained);
Map.addLayer(classified,{},'classified');
Map.setCenter(-49.515, -15.824);
The second argument that you pass to classifier.train() is the name of the band with class property. This should be an integer. You're never adding a class band to the landsat pixels, so it fails on the first feature of the feature collection (the feature with the id 0_0). JavaScript doesn't have tuples like Python (or whichever language you're more used to), so the code ('agriculture','city', 'forest') resolves to the last element in the parens (in this case, forest). So you're telling GEE that your class band is forest, and when it doesn't find a forest band it throws an error. It will be clear that you're not adding a class band if you print the first element of the feature collection using print(training.first());
What you should be doing instead is adding a band to the pixels under your different polygons, something like landType, which will have a value of 0, 1 or 2 depending on whether it is agriculture, city or forest.
Related
Extract one band data from Geotiff file and plot colored image based on one band values on folium map
I am new to extracting data from Geotiff files.So this question will sound obvious.I have tiff file which I have got from api.It has 12 bands.This shows definition of what each band contains What I want After extenisve searching for days i am only able to do this. enter image description here Code which i have tried driver=gdal.GetDriverByName('GTiFF') driver.Register() ds = gdal.Open('...../286d7a11-4abd-449e-856b-79959dfd1396.tif') if ds is None: print('Could not open') geotransform = ds.GetGeoTransform() proj = ds.GetProjection() cols = ds.RasterXSize rows = ds.RasterYSize xmin=geotransform[0] ymax=geotransform[3] xmax=xmin+cols*geotransform[1] ymin=ymax+rows*geotransform[5] centerx=(xmin+xmax)/2 centery=(ymin+ymax)/2 bands = ds.RasterCount band10 = ds.GetRasterBand(10) array = band10.ReadAsArray() map= folium.Map(location=[centery, centerx], zoom_start=7,tiles='openstreetmap') image = folium.raster_layers.ImageOverlay( dataimage,opacity=0.8, bounds=[[ymin,xmin],[ymax,xmax]] ) image.add_to(map) map.fit_bounds(map.get_bounds(), padding=(10, 10)) return map
How to SUM the value of a field and add in map values when I need to group by two fields/keys in map of map
I need to show different table in VF as per Product_Category__c and sum of Volume__c for each Brand_Name__c Below was my controller code please suggest how to populate sum of Volume__c in below map: list<Rebate_Goal_Brand__c> rebBrand = new list<Rebate_Goal_Brand__c>([SELECT Brand_Name__c,Product_Category__c ,Name,Volume__c FROM Rebate_Goal_Brand__c where Contract__r.name =:contractId and Contract__r.Sales_Org__r.Sales_Org_Code__c='5191' and Product_Category__c != 'Outros']); for(Rebate_Goal_Brand__c rB: rebBrand) { if(!MapGoals.containsKey(rb.Product_Category__c) ){ MapGoals.put(rb.Product_Category__c, new map<string,string>()); } MapGoals.get(rb.Product_Category__c).put(rb.Brand_Name__c,string.valueOf(rb.Volume__c));
Kivy regarding binding multiple buttons to each individual function
Hi I am new to Kivy and just started programming. I have problem, I want to bind all the buttons i created in the for loops to the on_release for every single buttons. So that to make all buttons once click is able to go different screens. Below is my a small part of my code( I EDITED with more information) #this are the pictures of the buttons a = '_icons_/mcdonald2.png' b = '_icons_/boostjuice.png' c = '_icons_/duckrice.png' d = '_icons_/subway_logo.png' e = '_icons_/bakery.png' f = '_icons_/mrbean.png' #these are the names of the different screen n1 = 'mcdonald_screen' n2 = 'boost_screen' n3 = 'duck_screen' n4 = 'subway_screen' n5 = 'bakery_screen' n6 = 'mrbean_screen' arraylist = [[a,n1],[b,n2],[c,n3],[d,n4],[e,n5],[f,n6]] self.layout2 = GridLayout(rows=2, spacing = 50,size_hint = (0.95,0.5), pos_hint = {"top":.65,"x":0},padding=(90,0,50,0)) for image in arraylist: self.image_outlet = ImageButton( size_hint=(1, 0.1), source= image[0]) self.screen_name = image[1] self.image_outlet[0].bind(on_release= ??) ## This part is the one i want to change according to the different screen self.layout2.add_widget(self.image_outlet) self.add_widget(self.layout2) GUI = Builder.load("_kivy_/trying.kv") class TRYINGApp(App): def build(self): return GUI def change_screen(self,screen_name): screen_manager = self.root.ids['screen_manager'] screen_manager.current = screen_name #kv file# # all the varies kv file screen #: include _kivy_/variestime_screen.kv #: include _kivy_/homescreen.kv #: include _kivy_/mcdonaldscreen.kv #: include _kivy_/firstpage.kv #: include _kivy_/mrbeanscreen.kv #: include _kivy_/boostscreen.kv #: include _kivy_/duckscreen.kv #: include _kivy_/subwayscreen.kv #: include _kivy_/bakeryscreen.kv GridLayout: cols:1 ScreenManager: id : screen_manager FirstPage: name :"first_page" id : first_page VariesTimeScreen: name: "variestime_screen" id: variestime_screen HomeScreen: name : "home_screen" id : home_screen McDonaldScreen: name : "mcdonald_screen" id : mcdonald_screen BoostScreen: name : "boost_screen" id : boost_screen DuckScreen: name: "duck_screen" id: duck_screen SubwayScreen: name:"subway_screen" id: subway_screen BakeryScreen: name: "bakery_screen" id: bakery_screen MrBeanScreen: name: "mrbean_screen" id : mrbean_screen
Your on_release can be something like: self.image_outlet.bind(on_release=partial(self.change_screen, image[1])) where change_screen is a method that you must define: def change_screen(self, new_screen_name, button_instance): # some code to change to the screen with name new_screen_name Note that I have removed the [0] from self.image_outlet (I suspect that was a typo). I can't determine what code should go in the new method, because you haven't provided enough information. If you have a change_screen method in your App class, you can use that directly by referencing it in your on_release as: self.image_outlet.bind(on_release=partial(App.get_running_app().change_screen, image[1])) You will need to make a minor change to your change_screen method to handle additional args: def change_screen(self, screen_name, *args): screen_manager = self.root.ids['screen_manager'] screen_manager.current = screen_name
Python ArcPy - Print Layer with highest field value
I have some python code that goes through layers in my ArcGIS project and prints out the layer names and their corresponding highest value within the field "SUM_USER_VisitCount". Output Picture What I want the code to do is only print out the layer name and SUM_USER_VisitCount field value for the one layer with the absolute highest value. Desired Output I have been unable to figure out how to achieve this and can't find anything online either. Can someone help me achieve my desired output? Sorry if the code layout is a little weird. It got messed up when I pasted it into the "code sample" Here is my code: import arcpy import datetime from datetime import timedelta import time #Document Start Time in-order to calculate Run Time time1 = time.clock() #assign project and map frame p = arcpy.mp.ArcGISProject(r'E:\arcGIS_Shared\Python\CumulativeHeatMaps.aprx') m = p.listMaps('Map')[0] Markets = [3000] ### Centers to loop through CA_Centers = ['Castro', 'ColeValley', 'Excelsior', 'GlenPark', 'LowerPacificHeights', 'Marina', 'NorthBeach', 'RedwoodCity', 'SanBruno', 'DalyCity'] for Market in Markets: print(Market) for CA_Center in CA_Centers: Layers = m.listLayers("CumulativeSumWithin{0}_{1}_Jun2018".format(Market,CA_Center)) fields = ['SUM_USER_VisitCount'] for Layer in Layers: print(Layer) sqlClause = (None, 'ORDER BY ' + 'SUM_USER_VisitCount') # + 'DESC' with arcpy.da.SearchCursor(in_table = Layer, field_names = fields, sql_clause = sqlClause) as searchCursor: print (max(searchCursor))
You can create a dictonary that stores the results from each query and then print out the highest one at the end. results_dict = {} for Market in Markets: print(Market) for CA_Center in CA_Centers: Layers = m.listLayers("CumulativeSumWithin{0}_{1}_Jun2018".format(Market,CA_Center)) fields = ['SUM_USER_VisitCount'] for Layer in Layers: print(Layer) sqlClause = (None, 'ORDER BY ' + 'SUM_USER_VisitCount') # + 'DESC' with arcpy.da.SearchCursor(in_table = Layer, field_names = fields, sql_clause = sqlClause) as searchCursor: print (max(searchCursor)) results_dict[Layer] = max(searchCursor) # get key for dictionary item with the highest value highest_count_layer = max(results_dict, key=results_dict.get) print(highest_count_layer) print(results_dict[highest_count_layer])
Plotting multiple states bokeh
I'm trying to plot two things: Counties for MD, VA, and DC Lats/Longs for housing listings in that area (most expensive in a certain color and least expensive in another color) However, I'm having trouble with part 1, and cannot seem to plot the counties without getting the error message: "Javascript error adding output! Error: Error rendering Bokeh model: could not find tag with id: xxxxxxxxxxx See your browser Javascript console for more details." where xxxxx are numbers from bokeh.io import show from bokeh.models import ( ColumnDataSource, HoverTool, LogColorMapper) from bokeh.palettes import Viridis6 as palette from bokeh.plotting import figure from bokeh.sampledata.us_counties import data as counties from bokeh.sampledata.unemployment import data as unemployment palette.reverse() va_counties = { code: county for code, county in counties.items() if county["state"] == "va" } md_counties = { code: county for code, county in counties.items() if county["state"] == "md" } dc_counties = { code: county for code, county in counties.items() if county["state"] == "dc" } va_county_xs = [county["lons"] for county in va_counties.values()] va_county_ys = [county["lats"] for county in va_counties.values()] md_county_xs = [county["lons"] for county in md_counties.values()] md_county_ys = [county["lats"] for county in md_counties.values()] dc_county_xs = [county["lons"] for county in dc_counties.values()] dc_county_ys = [county["lats"] for county in dc_counties.values()] va_county_names = [county['name'] for county in va_counties.values()] md_county_names = [county['name'] for county in md_counties.values()] dc_county_names = [county['name'] for county in dc_counties.values()] #county_rates = [unemployment[county_id] for county_id in counties] color_mapper = LogColorMapper(palette=palette) va_source = ColumnDataSource(data=dict( x=va_county_xs, y=va_county_ys, name=va_county_names, )) md_source = ColumnDataSource(data=dict( x=md_county_xs, y=md_county_ys, name=md_county_names, )) dc_source = ColumnDataSource(data=dict( x=dc_county_xs, y=dc_county_ys, name=dc_county_names, )) TOOLS = "pan,wheel_zoom,reset,hover,save" va = figure( title="Texas Unemployment, 2009", tools=TOOLS, x_axis_location=None, y_axis_location=None ) va.grid.grid_line_color = None md = figure( title="Texas Unemployment, 2009", tools=TOOLS, x_axis_location=None, y_axis_location=None ) md.grid.grid_line_color = None dc = figure( title="Texas Unemployment, 2009", tools=TOOLS, x_axis_location=None, y_axis_location=None ) dc.grid.grid_line_color = None va.patches('x', 'y', source=va_source, fill_color={'field': 'rate', 'transform': color_mapper}, fill_alpha=0.7, line_color="white", line_width=0.5) md.patches('x', 'y', source=md_source, fill_color={'field': 'rate', 'transform': color_mapper}, fill_alpha=0.7, line_color="white", line_width=0.5) dc.patches('x', 'y', source=dc_source, fill_color={'field': 'rate', 'transform': color_mapper}, fill_alpha=0.7, line_color="white", line_width=0.5) hover = p.select_one(HoverTool) hover.point_policy = "follow_mouse" hover.tooltips = [ ("Name", "#name"), ("(Long, Lat)", "($x, $y)"), ] show(va) show(md) show(dc)
Bokeh maintains an implicit "current document" and by default everything you make gets added to that. This makes it very simple to have a script that generates one HTML file, and especially makes usage in the Jupyter notebook much more simple and transparent. In general this is a net positive, but it does make certain other usage patterns need to be slightly more verbose. In particular in your case with multiple show calls, each call to show gets the same document which is probably not what you intend. The solution is to create and show each plot in order, and call reset_output in between. Additionally, you would really need to specify unique filenames for each separate output, by using output_file. Here is a small complete example: from bokeh.io import output_file, reset_output, show from bokeh.plotting import figure # create and show one figure p1 = figure(title="plot 1") p1.circle([1,2,3], [4,6,5]) output_file("p1.html") show(p1) # clear out the "current document" reset_output() # create and show another figure p2 = figure(title="plot 2") p2.circle([1,2,3], [8,6,7]) output_file("p2.html") show(p2) There are other ways to do this by managing Bokeh Document objects explicitly yourself, but I would probably say this is the simplest to get started.