2

I have a dataset on countries in sub-Saharan Africa (which is set so that anybody can use it):

var SSA = ee.FeatureCollection('users/salem043/Africa_Districts')
.select("ADM0")

I would like to produce grids that cover this entire region but are within-country. That's to say, I do not want any grids to overlap a country's border.

For country-level grids, I usually use the country boundary, create a bounding box, then split that box up into grids. Here, for example, is my code for creating 20,000 grids for Iraq:


//Bounding box over Iraq
var lat_start = 29.0990251735;
var lat_end = 37.3852635768;
var lon_start = 38.7923405291; 
var lon_end = 48.5679712258;

//Set number of grid cells
var num_cells = 20000;
var lon_edge = (lon_end-lon_start)/Math.sqrt(num_cells);
var lat_edge = (lat_end-lat_start)/Math.sqrt(num_cells);
// 3) Create the grid
var polys = [];
var polys_line = [];
var cell_id = 0;
for (var lon = lon_start; lon < lon_end; lon += lon_edge) {
  var x1 = lon;
  var x2 = lon + lon_edge;
  for (var lat = lat_start; lat < lat_end; lat += lat_edge) {
    cell_id = cell_id + 1;
    var y1 = lat;
    var y2 = lat + lat_edge;

    polys.push(ee.Feature(ee.Geometry.Rectangle(x1, y1, x2, y2), {label: cell_id}));
  }
}

I imagine there is a function that can call on each ADM0 (country boundary) in my feature collection, but I want the grids to be equal size, and it would be very tedious testing each one to figure out what to set the grid count to in order to ensure they have the same dimensions. What else can I do?

1 Answer 1

2

I'm not following completely what it is you're looking for in terms of equally sized tiles. However, this is the utility function I've written to do my tiling. If it doesn't do exactly what you need it to do, maybe it can give you some ideas:

function tile(region, size_in_degrees) {
  function tile_geometry(geometry) {
    var coords = ee.List(geometry.bounds().coordinates().get(0))
    var min_point = ee.List(coords.get(0))
    var max_point = ee.List(coords.get(2))

    function sequence(direction) {
      var start = min_point.get(direction)
      var stop = ee.Number(max_point.get(direction))
      return ee.List.sequence(start, stop, size_in_degrees)
    }

    var tiles = sequence(0).map(function (x) {
      return sequence(1).map(function (y) { 
          return ee.Feature(ee.Geometry.Rectangle([
            [ee.Number(x), ee.Number(y)],
            [
              ee.Number(x).add(size_in_degrees).min(max_point.get(0)),
              ee.Number(y).add(size_in_degrees).min(max_point.get(1))
            ]
        ]).intersection(geometry, 30))
      })
    }).flatten()
    return ee.FeatureCollection(tiles).filterBounds(geometry)
  }

  function tile_feature_collection(feature_collection) {
    return ee.FeatureCollection(
      feature_collection.iterate(
        function (feature, acc) {
          return ee.FeatureCollection(acc).merge(tile_geometry(ee.Feature(feature).geometry()))
        }, ee.FeatureCollection([]))
    )
  }

  if (region instanceof ee.FeatureCollection)
    return tile_feature_collection(region)
  else if (region instanceof ee.Feature)
    return tile_geometry(region.geometry())
  else if (region instanceof ee.Geometry)
    return tile_geometry(region)
  else
    throw Error(
      'region must be ee.FeatureCollection, ee.Feature, or ee.Geometry. Was ' + region
    )
}

Here's a script applying this to a subset of your features:

https://code.earthengine.google.com/f08e5aa713df9413a4e33dd02b613353

3
  • Very interesting algorythm. What do you usually use tiling for?
    – Basile
    Commented Feb 26, 2020 at 14:17
  • 1
    Exporting mosaics of really large areas or when exporting data used for offline time-series processing. Commented Feb 26, 2020 at 14:49
  • Hello Daniel! The example script no longer works. Throws "Layer 1: Layer error: Element.geometry, argument 'feature': Invalid type. Expected type: Element. Actual type: Float. Actual value: -6.564405398407892"
    – Basile
    Commented Sep 4, 2020 at 8:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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