0

Trying to combine coordinates (geometries) with their respective slope (numbers) in Earth Engine. I am quite lost as to how to go about doing this. I've tried using ee.Algoritm.Feature to add metadata (slope) to geometry (coordinates). How would I go about doing this in a feature collection? The problem seems to be converting geometry to GeoJSON. I am using a variation of D8 algorithm to assign coordinate direction and slope. See the attached picture for a graphic representation explain my P1,P2,P4, etc variablesenter image description here

//convert individual latitude and longitude coordinates into one coordinate
var P1 = ee.Geometry.MultiPoint(lon2[0],lat2[0]);
var P4 = ee.Geometry.MultiPoint(lon2[1],lat2[1]);
var P16 = ee.Geometry.MultiPoint(lon2[2],lat2[2]);
var P64 = ee.Geometry.MultiPoint(lon2[3],lat2[3]);
//do the same but for diagonal ones
var P2 = ee.Geometry.MultiPoint(lon2Diag[0],lat2Diag[0]);
var P8 = ee.Geometry.MultiPoint(lon2Diag[1],lat2Diag[1]);
var P32 = ee.Geometry.MultiPoint(lon2Diag[2],lat2Diag[2]);
var P128 = ee.Geometry.MultiPoint(lon2Diag[3],lat2Diag[3]);



//Put coordinates into a list
var cellList = [P1,P4,P16,P64];
var cellListDiag = [P2,P8,P32,P128];
var cellListComplete = [P1,P2,P4,P8,P16,P32,P64,P128]
print(cellListComplete);


//create a function with the the parameter of changing geometery (coordinates) that computes elevation for each coordinate
var elevationFunction = function(DifCell){
  var CellElevation  = NED.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: DifCell,
    scale: res_scale
  }); 
return(CellElevation.get('elevation'));
};

//create a function with the the parameter of changing geometery (coordinates) that computes elevation for each diagonal coordinate
var elevationFunctionDiag = function(DifCell){
  var res_scaleDiag = ee.Number(res_scale).multiply(1.41421356237)
  var CellElevation  = NED.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: DifCell,
    scale: res_scaleDiag
  }); 
return(CellElevation.get('elevation'));
};
//call all of the coordinates via list through the elvationFunction
var ElevationOfCells = cellList.map(elevationFunction);
var ElevationOfCellsDiag = cellListDiag.map(elevationFunction);
print(ElevationOfCells);
print(ElevationOfCellsDiag);




//create two lists of elevation one for diagonal cells and the rest - because rescale will be multiplied by sqrt2 for diagonal due to pathagorean theorem
//var ElevationOfCellsList = [ElevationOfCells[0], ElevationOfCells[2], ElevationOfCells[4], ElevationOfCells[6]];
//var ElevationOfCellsDiagList = [ElevationOfCells[1], ElevationOfCells[3], ElevationOfCells[5], ElevationOfCells[7]];

//function to calculate percent slope, rise (replaced with difference in elevation between original pollution location and cell elevations) over run times 100
var calcSlope = function(DifElevation){
  var slope = ee.Number(ee.Number(ee.Number(DifElevation).subtract(PFelev)).divide(res_scale)).multiply(100.0);
  return(slope);
};

//function to calculate percent slope of diagonal cells
var calcSlopeDiag = function(DifElevation){
  var slope = ee.Number(ee.Number(ee.Number(DifElevation).subtract(PFelev)).divide(ee.Number(res_scale).multiply(1.41421356237))).multiply(100.0);
  return(slope);
};

//pass the list of cell elevations through the function
var Slope = ElevationOfCells.map(calcSlope);
////pass the list of diagonal cell elevations through the function
var SlopeDiag = ElevationOfCellsDiag.map(calcSlopeDiag);


//negative values indicate downward slope from reference point of original pollution location
print(Slope);
print(SlopeDiag);


//combine regular slopes and diagonal slopes into one list
var CompleteSlopes = [Slope[0], SlopeDiag[0], Slope[1], SlopeDiag[1], Slope[2], SlopeDiag[2], Slope[3], SlopeDiag[3]];
print(CompleteSlopes);

My ultimate goal is to assign each coordinate with their respective slope and find some code to pick the steepest descent (most negative slope, calculated by the difference in elevation over res_scale). Then loop that so I have a collection of points (both elevation and coordinate location) to find where water would travel based on the original reference point (arbitrary for now, but will be the location of liquid pollution).

1

You don't get to work with individual pixels this way in Earth Engine and you generally don't get to loop at all, so I think you're headed down a dead end

Instead, you need to keep everything in raster space and used the vectrorized functions. In this case, you can get the slope of the neighbours using neighborhoodToBands. Convert that to an array and assign a "direction" to the second column of each array. Then you can find the max() of those at each location using arrayReduce and cut off the slope value to get the max slope direction.

But even with the D8 directions, you're going to have a hard time iterating to find flow. That kind of finite element analysis is explicitly one of the things Earth Engine doesn't do well.

// Get the slope of every pixels' neighbors as bands.
var ned = ee.Image("USGS/NED")
var slope = ee.Terrain.slope(ned)
var neighbors = slope.neighborhoodToBands(ee.Kernel.square(1))

// Remove the band containing the value of the center pixel
var bands = neighbors.bandNames().remove("slope_0_0")
var array = neighbors.select(bands).toArray()

// Combine with an array of indexes
var index = ee.Image.constant(ee.Array([128, 1, 2, 4, 8, 16, 32, 64]))
var arrayWithIndex = array.arrayCat(index, 1)

// Find the direction of the max slope.
var direction = arrayWithIndex.arrayReduce(ee.Reducer.max(2), [0], 1).arrayGet([0, 1])
Map.addLayer(direction)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.