Google Earth Engine (GEE) als öffentlicher Supercomputer

Google Earth Engine- Dienstbietet die Möglichkeit, kostenlos mit riesigen Mengen an räumlichen Informationen zu arbeiten. Zum Beispiel können Sie in wenigen Minuten ein zusammengesetztes Mosaik (zusammengesetztes Bild) aus einer Million Weltraumbildern erhalten. Unter der Annahme, dass jede Szene (Satz von Spektralkanälen) von Landsat 8 1 GB in komprimierter Form belegt, verarbeitet diese Anforderung ein Informationsvolumen von etwa 1 PB. All dies ist kostenlos, schnell und jederzeit verfügbar. Es gibt jedoch eine solche Meinung (falsch), dass GEE auf kostenlosen Konten es Ihnen ermöglicht, nur kleine Datensätze zu verarbeiten und zu exportieren. Tatsächlich wird dieser Eindruck nur dadurch verursacht, dass Sie mit der Programmierung in GEE beginnen können, ohne die Servicedokumentation zu lesen. Sie können jedoch nicht viele Daten extrahieren, ohne die Dokumentation zu lesen.Als nächstes werden wir drei verschiedene Lösungen für das Problem der Vektorisierung von Rastern betrachten und auf zwei verschiedene Arten eine serverseitige GEE-Funktion schreiben, um den Geohash zu berechnen.















( , )? — ! , . ( — , , , - ), ( - , ). , . , , ( , , , - ). , . , — , , 128 , , , - . , ( , ), (, - Amazon AWS). . , , , . , , … , — , - , , ( ) , , ( - — , ). , , .







Google Earth Engine. , — javascript (, , API ). . , , - . , , , , Google Drive ( ) (, GeoTIFF) Export.image.toDrive. , , , . — 21 10 Google Drive GeoJSON, 2. ( , ).









:







  1. , , :


var points_with_attributes = Image.reduceRegion({
  reducer: ee.Reducer.toList(Image.bandNames().size()),
  geometry: points
})
      
      





, , , . .







  1. , . :


var attributes = Image.reduceRegion({
  reducer: ee.Reducer.toList(Image.bandNames().size()),
  geometry: some_area
})
      
      





, . ? , . , . , ( , ). :







var latlon = ee.Image.pixelLonLat()
var points_with_attributes = image
  .addBands(latlon)
  .reduceRegion({
    reducer: ee.Reducer.toList(),
    geometry: some_area
  });
      
      





ee.Image.pixelLonLat() , . , ( , GEE , , ). , , :







var latlon = ee.Image.pixelLonLat().reproject(image.projection())
var points_with_attributes = image
  .addBands(latlon)
  .reduceRegion({
    reducer: ee.Reducer.toList(),
    geometry: some_area
  });
      
      





, :







var latlon = ee.Image.pixelLonLat()
var points_with_attributes = image
  .addBands(latlon)
  .add(image.select(0).add(0))
  .reduceRegion({
    reducer: ee.Reducer.toList(),
    geometry: some_area
  });
      
      





(, ), , . , , , ( ), . , () .







  1. , , , :


var latlon = ee.Image.pixelLonLat()
var points_with_attributes = image
  .sample({
    region: some_area,
    geometries: true
  });
      
      





"geometries" , .









, " ", - . , , GEE. , , . , ( ). GEE, , . , (z-curve). , , , GEE. ? , — . PostgreSQL/PostGIS, Google BigQuery . , -:







var geohash_accumulate = function(obj, list) {
  // define common variables
  var base32 = ee.String('0123456789bcdefghjkmnpqrstuvwxyz'); // (geohash-specific) Base32 map
  // get previous state variables
  var prev = ee.Dictionary(ee.List(list).get(-1));
  var lat = ee.Number(prev.get('lat',0));
  var lon = ee.Number(prev.get('lon',0));
  var idx = ee.Number(prev.get('idx',0));
  var bit = ee.Number(prev.get('bit',0));
  var evenBit = ee.Number(prev.get('evenBit',1));
  var geohash = ee.String(prev.get('geohash',''));
  var latMin = ee.Number(prev.get('latMin',-90));
  var latMax = ee.Number(prev.get('latMax',90));
  var lonMin = ee.Number(prev.get('lonMin',-180));
  var lonMax = ee.Number(prev.get('lonMax',180));

  // calculate substep bit step idx
  // bisect E-W longitude
  var lonMid = ee.Number(ee.Algorithms.If(evenBit.gt(0),                      lonMin.add(lonMax).divide(2), 0)      );
  idx =        ee.Number(ee.Algorithms.If(evenBit.gt(0).and(lon.gte(lonMid)), idx.multiply(2).add(1),       idx)    );
  lonMin =     ee.Number(ee.Algorithms.If(evenBit.gt(0).and(lon.gte(lonMid)), lonMid,                       lonMin) );
  idx =        ee.Number(ee.Algorithms.If(evenBit.gt(0).and(lon.lt(lonMid)),  idx.multiply(2),              idx)    );
  lonMax =     ee.Number(ee.Algorithms.If(evenBit.gt(0).and(lon.lt(lonMid)),  lonMid,                       lonMax) );
  // bisect N-S latitude
  var latMid=  ee.Number(ee.Algorithms.If(evenBit.eq(0),                      latMin.add(latMax).divide(2), 0)      );
  idx =        ee.Number(ee.Algorithms.If(evenBit.eq(0).and(lat.gte(latMid)), idx.multiply(2).add(1),       idx)    );
  latMin =     ee.Number(ee.Algorithms.If(evenBit.eq(0).and(lat.gte(latMid)), latMid,                       latMin) );
  idx =        ee.Number(ee.Algorithms.If(evenBit.eq(0).and(lat.lt(latMid)),  idx.multiply(2),              idx)    );
  latMax =     ee.Number(ee.Algorithms.If(evenBit.eq(0).and(lat.lt(latMid)),  latMid,                       latMax) );
  // check position
  evenBit = evenBit.not();
  bit =     bit.add(1);
  geohash = ee.String(ee.Algorithms.If(bit.eq(5), geohash.cat(base32.slice(idx,ee.Number(idx).add(1))), geohash));
  idx =     ee.Number(ee.Algorithms.If(bit.eq(5), ee.Number(0), idx));
  bit =     ee.Number(ee.Algorithms.If(bit.eq(5), ee.Number(0), bit));

  // return state
  var curr = prev
    .set('idx',     idx     )
    .set('bit',     bit    )
    .set('evenBit', evenBit)
    .set('geohash', geohash)
    .set('latMin',  latMin )
    .set('latMax',  latMax )
    .set('lonMin',  lonMin )
    .set('lonMax',  lonMax );
  return ee.List([curr]);
};
function geohash_encode(lat, lon, precision) {
  var init = ee.Dictionary({lat: lat, lon: lon})
  var state = ee.List.sequence(1,precision*5).iterate(geohash_accumulate, ee.List([init]))
  return ee.String(ee.Dictionary(ee.List(state).get(-1)).get('geohash'))
}
      
      











// PostGIS check from https://postgis.net/docs/ST_GeoHash.html
print (ee.Algorithms.If(geohash_encode(48, -126, 20).compareTo('c0w3hf1s70w3hf1s70w3'),'Error','OK'));
// Google BigQuery check from https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_geohash
print (ee.Algorithms.If(geohash_encode(47.62, -122.35, 10).compareTo('c22yzugqw7'),'Error','OK'));
      
      





geohash_encode() geohash_accumulate() 5 . , GEE , . ? "calculate substep bit step idx" geohash_accumulate() ( , ). . , -, , , :







var geohash_accumulate = function(obj, list) {
  // define common variables
  var range4 = ee.List.sequence(0,4).map(function(val){return ee.Number(val).multiply(1/4)});
  var range8 = ee.List.sequence(0,8).map(function(val){return ee.Number(val).multiply(1/8)});

  // get previous state
  var prev = ee.Dictionary(ee.List(list).get(-1))
  var lat = ee.Number(prev.get('lat',0))
  var lon = ee.Number(prev.get('lon',0))
  var n = ee.Number(prev.get('n',0)).add(1)
  var geohash = ee.String(prev.get('geohash',''))
  var latMin = ee.Number(prev.get('latMin',-90))
  var latMax = ee.Number(prev.get('latMax',90))
  var lonMin = ee.Number(prev.get('lonMin',-180))
  var lonMax = ee.Number(prev.get('lonMax',180))

  // calculate step n
  var base32 = ee.String(ee.Algorithms.If(n.mod(2).eq(1), '028b139c46df57eghksujmtvnqwyprxz', '0145hjnp2367kmqr89destwxbcfguvyz'));
  var latRange = ee.List(ee.Number(ee.Algorithms.If(n.mod(2).eq(1), range4, range8)));
  latRange = latRange.map(function(item){return ee.Number(item).multiply(latMax.subtract(latMin)).add(latMin)});
  var lonRange = ee.List(ee.Number(ee.Algorithms.If(n.mod(2).eq(1), range8, range4)));
  lonRange = lonRange.map(function(item){return ee.Number(item).multiply(lonMax.subtract(lonMin)).add(lonMin)});
  var latIdx = latRange.indexOf(latRange.filter(ee.Filter.lte('item', lat)).get(-1));
  latIdx = ee.Number(ee.Algorithms.If(latIdx.gte(latRange.size().add(-1)), latIdx.add(-1), latIdx));
  var lonIdx = lonRange.indexOf(lonRange.filter(ee.Filter.lte('item', lon)).get(-1));
  lonIdx = ee.Number(ee.Algorithms.If(lonIdx.gte(lonRange.size().add(-1)), lonIdx.add(-1), lonIdx));
  var idx = lonIdx.multiply(latRange.size().add(-1)).add(latIdx);
  // reset bounds
  latMin = latRange.get(latIdx)
  latMax = latRange.get(latIdx.add(1))
  lonMin = lonRange.get(lonIdx)
  lonMax= lonRange.get(lonIdx.add(1))
  // define geohash symbol
  var geohash = geohash.cat(base32.slice(idx,ee.Number(idx).add(1)));

  // return state
  var curr = prev
    .set('n',       n       )
    .set('geohash', geohash )
    .set('latMin',  latMin  )
    .set('latMax',  latMax  )
    .set('lonMin',  lonMin  )
    .set('lonMax',  lonMax  );
  return ee.List([curr]);
};
function geohash_encode(lat, lon, precision) {
  var init = ee.Dictionary({lat: lat, lon: lon})
  var state = ee.List.sequence(1,precision).iterate(geohash_accumulate, ee.List([init]))
  return ee.String(ee.Dictionary(ee.List(state).get(-1)).get('geohash'))
}
      
      





, , Javascript-, , .









. , , , . , GitHub ( GIS Snippets GEE). , — , .








All Articles