I'm trying to implement algorithm on Earth Engine Code to predict cultivated area.
This is my code:
var landsatCollection = ee.ImageCollection('LANDSAT/LC08/C01/T1')
.filterDate('2017-01-01', '2017-12-31');
// Make a cloud-free composite.
var composite = ee.Algorithms.Landsat.simpleComposite({
collection: landsatCollection,
asFloat: true
});
// Merge the three geometry layers into a single FeatureCollection.
var newfc = urban.merge(vegetation).merge(water).merge(urban).merge(fields);
// Use these bands for classification.
var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7'];
// The name of the property on the points storing the class label.
var classProperty = 'landcover';
// Sample the composite to generate training data. Note that the
// class label is stored in the 'landcover' property.
var training = composite.select(bands).sampleRegions({
collection: newfc,
properties: [classProperty],
scale: 30
});
// Train a CART classifier.
var classifier = ee.Classifier.smileCart().train({
features: training,
classProperty: [classProperty],
});
// Print some info about the classifier (specific to CART).
print('CART, explained', classifier.explain());
// Classify the composite.
var classified = composite.classify(classifier);
Map.centerObject(newfc);
Map.addLayer(classified, {min: 0, max: 3, palette: ['red', 'blue', 'green','yellow']});
// Optionally, do some accuracy assessment. Fist, add a column of
// random uniforms to the training dataset.
var withRandom = training.randomColumn('random');
// We want to reserve some of the data for testing, to avoid overfitting the model.
var split = 0.7; // Roughly 70% training, 30% testing.
var trainingPartition = withRandom.filter(ee.Filter.lt('random', split));
var testingPartition = withRandom.filter(ee.Filter.gte('random', split));
// Trained with 70% of our data.
var trainedClassifier = ee.Classifier.smileCart().train({
features: trainingPartition,
classProperty: classProperty,
inputProperties: bands
});
// Classify the test FeatureCollection.
var test = testingPartition.classify(trainedClassifier);
// Print the confusion matrix.
var confusionMatrix = test.errorMatrix(classProperty, 'classification');
print('Confusion Matrix', confusionMatrix);
I am getting these errors:
CART, explained
Dictionary (Error)
Property 'landcover' of feature '1_1_1_1_0_0' is missing.
Confusion Matrix
ConfusionMatrix (Error)
Property 'landcover' of feature '1_1_1_1_1_0' is missing.
Layer 1: Layer error: Property 'landcover' of feature '1_1_1_1_0_0' is missing.
Give me some suggestions to resolve these errors.
The error seems like in line 11,
var newfc = urban.merge(vegetation).merge(water).merge(urban).merge(fields);
Make sure urban and others are a FeatureCollection from Configure geometry import tool.
Add Property 'landcover' and value 1 for urban, 2 for water and so on.
you can check print(newfc) and look at the properties and check for feature '1_1_1_1_0_0'
I have attached the image.configure geometry point
Related
Please I need help here. I am trying to generate a time-series NDVI chart using the code below, but I keep getting an error that reads "image.normalizedDifference is not a function"
I need help with this please. I am new to the GEE platform.
var finni = ee.FeatureCollection("users/Time-series-NDVI/Finney_shapefile"),
landsat7 = ee.ImageCollection("LANDSAT/LE07/C02/T1_RT");
//define start and end dates
var startDate = '2001-01-01'
var endDate = '2020-12-31'
// filter images to cover only the dates required
var images = landsat7.filter(ee.Filter.date(startDate, endDate));
//print(images);
//crop images to my study area
var imgextent = images.filter(ee.Filter.bounds(finni));
print(imgextent);
// remove cloud cover
var image = imgextent.filter(ee.Filter.eq('CLOUD_COVER', 0));
print(image);
// Select on Red and NIR bands from the collection
var image = image.select(['B4', 'B3'])
print(image)
// Compute the Normalized Difference Vegetation Index (NDVI).
var addNDVI = function(image){
var ndvi = image.normalizedDifference(['B4', 'B3']).rename('NDVI');
return image.addBands(ndvi);
};
//Add the calculated NDVI band to my "image" already containing Red and NIR band
var withNDVI = image.map(addNDVI);
//Export a chart of only NDVI layer
var chart = ui.Chart.image.series({
imageCollection: withNDVI.select('NDVI'),
region: finni,
reducer: ee.Reducer.mean(),
scale: 30
}).setOptions({title: 'NDVI over time'});
// Display the chart in the console.
print(chart);
Use the addBands function with .clip() instead of the select function.
Use this line return image.addBands(ndvi).clip(finni); instead of this "withNDVI.select('NDVI').clip(finni);"
That should work.
Hello I dont know anything to this but I just have one mistake in my code I dont know why
// Load country features from Large Scale International Boundary (LSIB) dataset.
var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');
var roi = countries.filter(ee.Filter.eq('country_co', 'CB'));
Map.addLayer(roi,{},'Cambodia')
//Let's centre the map view over our ROI
Map.centerObject(roi, 6);
// Filter the collection for the VV product from the descending track
var collectionVV = ee.ImageCollection('COPERNICUS/S1_GRD')
.filter(ee.Filter.eq('instrumentMode', 'IW'))
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
.filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))
.filterBounds(roi)
.select(['VV'])
.median();
// Filter the collection for the VH product from the descending track
var collectionVH = ee.ImageCollection('COPERNICUS/S1_GRD')
.filter(ee.Filter.eq('instrumentMode', 'IW'))
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
.filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))
.filterBounds(roi)
.select(['VH'])
.median();
// Adding the VV layer to the map at a specific date
var image = ee.Image(collectionVV.filterDate('2020-10-14', '2020-10-20').median());
Map.addLayer(image.clip(roi), {min: -25, max: 5}, 'Image_VV');
it is for the last line I get :
Line 29: collectionVV.filterDate is not a function
Thanks
Since you end your two expressions for collectionVV and collectionVH with the .median() operation, you already reduce both ImageCollections to an image (by taking the median of that collection). Simply removing the .median() statements will fix your error. Thus:
// Filter the collection for the VH product from the descending track
var collectionVH = ee.ImageCollection('COPERNICUS/S1_GRD')
.filter(ee.Filter.eq('instrumentMode', 'IW'))
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
.filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))
.filterBounds(roi)
.select(['VH'])
//.median();
// Adding the VV layer to the map at a specific date
var image = ee.Image(collectionVH.filterDate('2020-10-14', '2020-10-20').median());
Map.addLayer(image.clip(roi), {min: -25, max: 5}, 'Image_VV');
Okay so I've been trying to map some heatmaps to a Revit room using the DataViz api. I was able to get X Y Z from Revit for the sensor inside the rooms, i've substracted the viewer.model.getGlobalOffset() and managed to show some sprites on these points. I know for a fact that those sprites / points are inside Rooms, but whenever I try to use the same points to load a heatmap I get the Some devices did not map to a room: warning and no heatmap is displayed.
Following the API documentation this warning appears when there is no room information in the point. Did I miss anything? This is "my" code:
async function loadHeatmaps(model){
const dataVizExtn = await viewer.loadExtension("Autodesk.DataVisualization");
// Given a model loaded from Forge
const structureInfo = new Autodesk.DataVisualization.Core.ModelStructureInfo(model);
const devices = [
{
id: "Oficina 6", // An ID to identify this device
name:"Oficina-",
position: { x: 22.475382737884104, y: 7.4884431474006163, z: 3.0 }, // World coordinates of this device
sensorTypes: ["temperature", "humidity"], // The types/properties this device exposes
}
];
var offset = viewer.model.getGlobalOffset();
removeOffset(devices[0],offset)
// Generates `SurfaceShadingData` after assigning each device to a room.
const shadingData = await structureInfo.generateSurfaceShadingData(devices);
console.log(shadingData)
// Use the resulting shading data to generate heatmap from.
await dataVizExtn.setupSurfaceShading(model, shadingData);
// Register color stops for the heatmap. Along with the normalized sensor value
// in the range of [0.0, 1.0], `renderSurfaceShading` will interpolate the final
// heatmap color based on these specified colors.
const sensorColors = [0x0000ff, 0x00ff00, 0xffff00, 0xff0000];
// Set heatmap colors for temperature
const sensorType = "temperature";
dataVizExtn.registerSurfaceShadingColors(sensorType, sensorColors);
// Function that provides sensor value in the range of [0.0, 1.0]
function getSensorValue(surfaceShadingPoint, sensorType) {
// The `SurfaceShadingPoint.id` property matches one of the identifiers passed
// to `generateSurfaceShadingData` function. In our case above, this will either
// be "cafeteria-entrace-01" or "cafeteria-exit-01".
const deviceId = surfaceShadingPoint.id;
// Read the sensor data, along with its possible value range
let sensorValue = readSensorValue(deviceId, sensorType);
const maxSensorValue = getMaxSensorValue(sensorType);
const minSensorValue = getMinSensorValue(sensorType);
// Normalize sensor value to [0, 1.0]
sensorValue = (sensorValue - minSensorValue) / (maxSensorValue - minSensorValue);
return clamp(sensorValue, 0.0, 1.0);
}
// This value can also be a room instead of a floor
const floorName = "01 - Entry Level";
dataVizExtn.renderSurfaceShading(floorName, sensorType, getSensorValue);
}
function removeOffset(pos, offset) {
pos.position.x = pos.position.x - offset.x;
pos.position.y = pos.position.y - offset.y;
pos.position.z = pos.position.z - offset.z;
}
And I'm calling the loadHeatmaps() function inside onDocumentLoadSuccess callback.
EDIT: It looks like in this particular case it was a problem with floorName not being set to the right value. Note that this value (first parameter to dataVizExtn.renderSurfaceShading) should be set either to the name of the room, or to the name of the floor you want to update.
The offsets are a bit tricky so I'd suggest debugging that area, for example:
What coordinate system are the sensors defined in? If they are in the same coordinate system as the building model itself, you shouldn't subtract or add any offset to them. Whenever there's a model with a "global offset" in its metadata, it basically means that the Model Derivative service moved the model to origin to avoid floating point precision issues, and the viewer will then add the global offset back to each geometry when its loaded.
Try using the viewer APIs to get the bounding box of one of the rooms that the devices should map to, and see if the bounding box actually contains the XYZ point of the device you're trying to pass into the DataViz extension. The bounds of any object can be found like so:
function getObjectBounds(model, dbid) {
const tree = model.getInstanceTree();
const frags = model.getFragmentList();
let bounds = new THREE.Box3();
tree.enumNodeFragments(dbid, function (fragid) {
let _bounds = new THREE.Box3();
frags.getWorldBounds(fragid, _bounds);
bounds.union(_bounds);
}, true);
return bounds;
}
I have the same issue and my revit model was built by revit 2020. When I update model to 2022, heatmap can show on the room correctly.
Given a point, say [-75.343, 39.984], how do I go about finding all features/markers within a 5km radius of it? I'm utilizing turf.js so I'll be using their circle() function to generate the circle about the point.
Would this work?
const center = [-75.343, 39.984];
const radius = 5;
const options = {steps: 10, units: 'kilometers', properties: {foo: 'bar'}};
const circle = turf.circle(center, radius, options);
}
const features = map.queryRenderedFeatures(
circle,
{ filter: {["within", circle] : true} }
);
I'm hoping to find all features within the circle and be able to store them in an array or in a database for further processing like accessing the feature's lat/lng, etc.
Thank you for the help!
Using queryRenderedFeatures you will be able to get the features that are actually in the viewport (visible). In case your source data is GeoJSON, you can use querySourceFeatures, so it will look to all your source features:
const filteredFeatures = map.querySourceFeatures('routes', {
filter: ['within', circle]
});
I am very new to Earth Engine and Javascript so I wouldn't be surprised if the solution to my problem is extremely simple. Anyways, I've been trying to fix this in days and I'm not doing anyhow better.
I'm trying to get the cumulative cost distance between some areas of interest and some tide gauges in the coastal U.S. To do this, I first calculated the pixel cost based on a national elevation map. Then, I calculated the cumulative cost thanks to the built-in function cumulativeCost. That went all pretty well. Now I'm trying to extract the cumulative cost values at the position of the tide gauges. To do this, someone suggested me to use the reduceRegions method. I've tried the following code but unsuccessfully.
I'm going to post my whole code so that is replicable. Please note that the part with which I have a problem is the second one.
Thanks so much in advance.
// IMPORTS
var imageCollection =
ee.ImageCollection("users/brazzolanicoletta/sourceRasters"),
sourceVis = {"opacity":1,"bands":["b1"],"min":1,"max":1,"gamma":1},
DEMVis = {"opacity":1,"bands":
["elevation"],"min":-73.50744474674659,"max":374.555654458347,"gamma":1},
imageVisParam = {"opacity":1,"bands":
["elevation"],"min":-0.02534169006347656,"max":3.6601884765625,"palette":
["0345ff","000000"]},
imageVisParam2 = {"opacity":1,"bands":
["elevation"],"min":-0.02534169006347656,"max":3.6601884765625,"palette":
["0345ff","000000"]},
cosVisParam = {"opacity":1,"bands":
["cumulative_cost"],"max":4170.014060708561,"palette":
["ff0303","efff05","4eff05","002bff","ff01f7","000000"]},
imageVisParam3 = {"opacity":1,"bands":
["cumulative_cost"],"max":4028.1446098656247,"gamma":1};
//get IDs for images in image collection
var getID = function(image){ return image.set('ID', image.id());};
var okID = imageCollection.map(function(image) { return image.set('ID',
image.id());});
// Set general estethic parameters
var dem_vis = {bands:"elevation", min:0, max:0.05,
palette:"#0345ff,#000000"};
var cost_vis = {bands:"cumulative_cost", min:0, max:10000,
palette:"ff0303,efff05,4eff05,002bff,ff01f7,000000"}
// PART 1: Cumulative Cost based on source rasters
//import elevation map
var dem = ee.Image('USGS/NED');
// pixel cost calculation
var elThreshold = ee.Number(5); //set elevation threshold
var subDEM = dem.updateMask(dem.lt(elThreshold)); //mask pixel above
elevation threshold
var costDEM = (subDEM.add(30)).divide(1000); //calculate the cost of each
pixel (height + width pixel (30m)) in km
// Add DEM to the map
Map.addLayer(costDEM, dem_vis, "SRTM");
// Cumulative cost
var calcCumCost = function(img) {
return costDEM.cumulativeCost({
source:img,
maxDistance:1E5});
}; //write a function that perform the cumulative cost calculation for each
image given the cost of the pixel
var demCost = ee.ImageCollection(okID.map(calcCumCost)); // caulcuate
cumulative cost for each source raster in the image collection
// PART 2 - Reduce Region: extract cumulative cost for tide gauges
var tideGauges =
ee.FeatureCollection('ft:1e1ik7ZklKbRSRVS50Ml_prHBTZ0WbNgW73fw7Ald');
//import fusion table of tide gauges
// WORK IN PROGRESS
// Empty Collection to fill
var ft = ee.FeatureCollection(ee.List([]));
// function that extract values from cumulative cost rasters and reduce it
for points region
var fill = function(img) {
// gets the values for the points in the current img
var ft2 = img.reduceRegions(tideGauges, ee.Reducer.first(),30);
// set ID
var ID = ee.Feature(null, {'id':img.id()});
// writes the ID in each feature
var ft3 = ft2.map(function(f){return f.set("id", ID)});
// merges the FeatureCollections
return ft.merge(ft3);
};
// Apply the function to each image in the ImageCollection
var newft = ee.FeatureCollection(demCost.map(fill));
print(newft, 'Potentially: region-reduced cost');
The maxDistance on your cumulativeCost function translates into a neighborhood of 3000 pixels (at 30m), which means each tile needs to bring in a 44 million neighbor pixels, which is just too much memory. You're going to have to lower the maxDistance or increase the scale of the reduceRegion.