1

I have a Feature Collection of badly drawn polygons. I have managed to identify the ones that are overlapping. I need to eliminate the ones that are overlapping more than 80%, however keeping the feature that is newer if the crop is the same. (this is identified by the contract number, higher number means newer contract; in my example collection all the crops are "Soya")

I have made some advance but seem to be stuck with the variable types when trying to make comparisons. The full code is attached, but the area with problems is the function selectedDouble()

var fields2 = ee.FeatureCollection("users/JASPR/Results/fields2");

Map.centerObject(fields2);

// find features that intersect. add properties to the feature.
// intersects: how many features it intersects with
// interRatio: percentage of intersection. Always the larger of the 2
var intersect = function(feature){
          // immediately fiter to the (f)eatures withing bounds of our feature
  var fc = fields2.filterBounds(feature.geometry()).map(function(f){
    // get the area of the intersection
    var intersectionArea = feature.geometry().intersection(f.geometry()).area();
    // get the minimum area of the 2 features
    var smallerArea = feature.geometry().area().min(f.geometry().area());
    // get the ratio by dividing the intersection by the smaller area
    var interRatio = intersectionArea.divide(smallerArea);
    // create a boolean to assign as an intersection
    var intersects = feature.geometry().intersects(f.geometry());
    // return (f)eature with new properties.  Intersect T/F and intersectRatio
    return(f.set({intersects: intersects, interRatio: interRatio}));
  });
  // count how many of the fc has intersects and subract 1 (itself)
  var status = ee.Number(ee.List(fc.aggregate_array("intersects")).frequency(true)).subtract(1);
  // calculate the mean overlap (sum of ratios minus 1(itself)) divide by count minus 1(itself)
  var interRatio = ee.Number(fc.aggregate_sum("interRatio")).subtract(1).divide(ee.Number(fc.aggregate_count("contract")).subtract(1));
  //return feature with new properties how many intersects, and the intersect ratio mean
  return(feature.set({intersects: status, interRatio: interRatio}));

};


var newFields = fields2.map(intersect);


// filter to only the fields that overlap
var overlappingFields = newFields.filterMetadata("intersects","greater_than",0)

// filter non-overlapping fields
var singleFields = newFields.filterMetadata("intersects","equals", 0)

// add the single Fields to the Map
Map.addLayer(singleFields,{color:"green"},"singleFields")


// Get the fields that are more than 80% overlapping
var doubleFields = overlappingFields.filterMetadata("intersects","greater_than",0)
                                    .filterMetadata("interRatio","greater_than",0.8)

//Get the fields that are less than 80% overlapping
var justOverlapEdge = overlappingFields.filterMetadata("intersects","equals",1)
                                      .filterMetadata("interRatio","less_than",0.8)

//Get the fields that are touching more than 1 field.
var multiOverlap = overlappingFields.filterMetadata("intersects","greater_than",1)

// identify the fields that should be kept
var selectedDouble = function(feature){

    var fc2 = doubleFields.filterBounds(feature.geometry()).map(function(f){
      var featureCrop = feature.get("crop");
      var fCrop = f.get("crop");
      var featureProp = feature.get("contract");
      var fProp = f.get("contract");
      var keep = false;
      if((featureCrop==fCrop) && (featureProp>fProp)) {
        keep = true;
      } 
      return(f.set({higherProp: fProp, keep: keep}));
    });
    var higherProp = ee.List(fc2.aggregate_array("higherProp"));
    var keep = ee.List(fc2.aggregate_array("keep")).frequency(true).gte(1);
    return(feature.set({higherProp: higherProp, keep: keep}));
};

var myKeepers = doubleFields.map(selectedDouble).filterMetadata("keep","equals",1);



Map.addLayer(myKeepers,{color: "yellow"},"myKeepers");

Map.addLayer(doubleFields,{color: "red"},"Double Fields");
Map.addLayer(justOverlapEdge,{color: "blue"},"overlap Edge");
Map.addLayer(multiOverlap, {color: "brown"},"multiOverlap");
#

EDIT doubleFields filter changed to 'intersects','greater_than',1

2

I think the problem arises when you use client-side functions (if and &&) inside the mapped function. Instead, double use ee.Algorithm.If() to accomplish what you want with the If and && statements:

// identify the fields that should be kept
var selectedDouble = function(feature){

    var fc2 = doubleFields.filterBounds(feature.geometry()).map(function(f){
      var featureCrop = ee.String(feature.get("crop"));
      var fCrop = ee.String(f.get("crop"));
      var featureProp = ee.Number(feature.get("contract")).toInt();
      var fProp = ee.Number(f.get("contract")).toInt();
      var keep = false;
      var keep = ee.Algorithms.If({condition: featureCrop.compareTo(fCrop),
                                    falseCase: ee.Algorithms.If({condition: featureProp.gt(fProp),
                                                                  trueCase: true})
                                    });
      return(f.set({higherProp: fProp, keep: keep}));
    });
    var higherProp = ee.List(fc2.aggregate_array("higherProp"));
    var keep = ee.List(fc2.aggregate_array("keep")).frequency(true).gte(1);
    return(feature.set({higherProp: higherProp, keep: keep}));
};

var myKeepers = doubleFields.map(selectedDouble).filterMetadata("keep","equals",1);
print(myKeepers)
Map.addLayer(myKeepers,{color: "yellow"},"myKeepers");

Let me know if this does what you had in mind, and if not, please show the erroneous features arising in a link to your script.

link

  • This is exactly what was wrong. With the ee.Algorithms.If() it works how it should. Though it's not giving me the answer I want, at least I can see my problem with the logic now. – Sean Roulet Feb 25 at 18:14
  • I think you'll need to set 'falseCase' instead of 'trueCase' with the string operator compareTo, as that gives 0 when the strings are equal. I updated the answer. – Kuik Feb 26 at 9:01
  • And that is why it wasn't giving me the answer I wanted! Confusing that the true is 0 in compareTo(). But that is what the docs are for, to clarify the details. – Sean Roulet Feb 27 at 1:42

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.