gdal/autotest/ogr/ogr_eeda.py

479 строки
18 KiB
Python
Исполняемый файл

#!/usr/bin/env pytest
# -*- coding: utf-8 -*-
###############################################################################
# $Id$
#
# Project: GDAL/OGR Test Suite
# Purpose: Earth Engine Data API driver test suite.
# Author: Even Rouault, even dot rouault at spatialys.com
#
###############################################################################
# Copyright (c) 2017, Planet Labs
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
###############################################################################
import json
import gdaltest
import pytest
from osgeo import gdal, ogr
pytestmark = pytest.mark.require_driver("EEDA")
###############################################################################
@pytest.fixture(autouse=True, scope="module")
def startup_and_cleanup():
with gdal.config_option("CPL_CURL_ENABLE_VSIMEM", "YES"):
yield
gdal.Unlink("/vsimem/ee/")
gdal.Unlink(
"/vsimem/ee/projects/earthengine-public/assets/collection:listImages?pageSize=1"
)
gdal.Unlink(
"/vsimem/ee/projects/earthengine-public/assets/collection:listImages?pageToken=myToken"
)
gdal.Unlink(
"/vsimem/ee/projects/earthengine-public/assets/collection:listImages?filter=raw%5Ffilter"
)
###############################################################################
# Nominal case
def test_eeda_2():
gdal.FileFromMemBuffer(
"/vsimem/ee/projects/earthengine-public/assets/collection:listImages?pageSize=1",
json.dumps(
{
"images": [
{
"properties": {
"string_field": "bar",
"int_field": 1,
"int64_field": 123456789012,
"double_field": 1.23,
}
}
]
}
),
)
# To please the unregistering of the persistent connection
gdal.FileFromMemBuffer("/vsimem/ee/", "")
with gdal.config_option("EEDA_BEARER", "mybearer"):
with gdal.config_option("EEDA_URL", "/vsimem/ee/"):
ds = ogr.Open("EEDA:collection")
lyr = ds.GetLayer(0)
assert lyr.TestCapability(ogr.OLCStringsAsUTF8) == 1
assert lyr.TestCapability("foo") == 0
assert lyr.GetLayerDefn().GetFieldCount() == 8 + 7 + 4
assert lyr.GetExtent() == (-180.0, 180.0, -90.0, 90.0)
assert lyr.GetFeatureCount() == -1
gdal.FileFromMemBuffer(
"/vsimem/ee/projects/earthengine-public/assets/collection:listImages",
json.dumps(
{
"images": [
{
"name": "projects/earthengine-public/assets/collection/first_feature",
"id": "collection/first_feature",
"updateTime": "2017-01-04T12:34:56.789Z",
"startTime": "2017-01-02T12:34:56.789Z",
"endTime": "2017-01-03T12:34:56.789Z",
"sizeBytes": 1,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[2, 49],
[2.1, 49],
[2.1, 49.1],
[2, 49.1],
[2, 49],
]
],
},
"properties": {
"string_field": "bar",
"int_field": 1,
"int64_field": 123456789012,
"double_field": 1.23,
"another_prop": 3,
},
"bands": [
{
"id": "B1",
"dataType": {
"precision": "INT",
"range": {"max": 255},
},
"grid": {
"crsCode": "EPSG:32610",
"affineTransform": {
"translateX": 499980,
"translateY": 4200000,
"scaleX": 60,
"scaleY": -60,
},
"dimensions": {"width": 1830, "height": 1831},
},
}
],
},
{
"name": "projects/earthengine-public/assets/collection/second_feature"
},
],
"nextPageToken": "myToken",
}
),
)
f = lyr.GetNextFeature()
if (
f.GetField("name")
!= "projects/earthengine-public/assets/collection/first_feature"
or f.GetField("id") != "collection/first_feature"
or f.GetField("gdal_dataset")
!= "EEDAI:projects/earthengine-public/assets/collection/first_feature"
or f.GetField("updateTime") != "2017/01/04 12:34:56.789+00"
or f.GetField("startTime") != "2017/01/02 12:34:56.789+00"
or f.GetField("endTime") != "2017/01/03 12:34:56.789+00"
or f.GetField("sizeBytes") != 1
or f.GetField("band_count") != 1
or f.GetField("band_max_width") != 1830
or f.GetField("band_max_height") != 1831
or f.GetField("band_min_pixel_size") != 60
or f.GetField("band_upper_left_x") != 499980
or f.GetField("band_upper_left_y") != 4200000
or f.GetField("band_crs") != "EPSG:32610"
or f.GetField("string_field") != "bar"
or f.GetField("int_field") != 1
or f.GetField("int64_field") != 123456789012
or f.GetField("double_field") != 1.23
or f.GetField("other_properties") != '{ "another_prop": 3 }'
or f.GetGeometryRef().ExportToWkt()
!= "MULTIPOLYGON (((2 49,2.1 49.0,2.1 49.1,2.0 49.1,2 49)))"
):
f.DumpReadable()
pytest.fail()
f = lyr.GetNextFeature()
if (
f.GetField("name")
!= "projects/earthengine-public/assets/collection/second_feature"
):
f.DumpReadable()
pytest.fail()
gdal.FileFromMemBuffer(
"/vsimem/ee/projects/earthengine-public/assets/collection:listImages?pageToken=myToken",
json.dumps(
{
"images": [
{
"name": "projects/earthengine-public/assets/collection/third_feature"
}
]
}
),
)
f = lyr.GetNextFeature()
if (
f.GetField("name")
!= "projects/earthengine-public/assets/collection/third_feature"
):
f.DumpReadable()
pytest.fail()
f = lyr.GetNextFeature()
assert f is None
lyr.ResetReading()
f = lyr.GetNextFeature()
if (
f.GetField("name")
!= "projects/earthengine-public/assets/collection/first_feature"
):
f.DumpReadable()
pytest.fail()
lyr.SetAttributeFilter("EEDA:raw_filter")
gdal.FileFromMemBuffer(
"/vsimem/ee/projects/earthengine-public/assets/collection:listImages?filter=raw%5Ffilter",
json.dumps(
{
"images": [
{
"name": "projects/earthengine-public/assets/collection/raw_filter"
}
]
}
),
)
f = lyr.GetNextFeature()
assert (
f.GetField("name")
== "projects/earthengine-public/assets/collection/raw_filter"
)
lyr.SetAttributeFilter(None)
lyr.SetAttributeFilter(
"startTime >= '1980-01-01T00:00:00Z' AND "
+ "string_field = 'bar' AND "
+ "int_field > 0 AND "
+ "int_field < 2 AND "
+ "int64_field >= 0 AND "
+ "int64_field <= 9999999999999 AND "
+ "double_field != 3.5 AND "
+ "string_field IN ('bar', 'baz') AND "
+ "NOT( int_field IN (0) OR double_field IN (3.5) )"
)
tmpfile = "/vsimem/ee/projects/earthengine-public/assets/collection:listImages?region=%7B%20%22type%22%3A%20%22Polygon%22%2C%20%22coordinates%22%3A%20%5B%20%5B%20%5B%20%2D180%2E0%2C%20%2D90%2E0%20%5D%2C%20%5B%20%2D180%2E0%2C%2090%2E0%20%5D%2C%20%5B%20180%2E0%2C%2090%2E0%20%5D%2C%20%5B%20180%2E0%2C%20%2D90%2E0%20%5D%2C%20%5B%20%2D180%2E0%2C%20%2D90%2E0%20%5D%20%5D%20%5D%20%7D&filter=%28%28%28string%5Ffield%20%3D%20%22bar%22%20AND%20%28int%5Ffield%20%3E%200%20AND%20int%5Ffield%20%3C%202%29%29%20AND%20%28%28int64%5Ffield%20%3E%3D%200%20AND%20int64%5Ffield%20%3C%3D%209999999999999%29%20AND%20%28double%5Ffield%20%21%3D%203%2E5%20AND%20string%5Ffield%20%3D%20%22bar%22%20OR%20string%5Ffield%20%3D%20%22baz%22%29%29%29%20AND%20%28NOT%20%28int%5Ffield%20%3D%200%20OR%20double%5Ffield%20%3D%203%2E5%29%29%29&startTime=1980%2D01%2D01T00%3A00%3A00Z"
with gdaltest.tempfile(
tmpfile,
json.dumps(
{
"images": [
{
"name": "projects/earthengine-public/assets/collection/filtered_feature",
"updateTime": "2017-01-03T12:34:56.789Z",
"startTime": "2017-01-02T12:34:56.789Z",
"sizeBytes": 1,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[2, 49],
[2.1, 49],
[2.1, 49.1],
[2, 49.1],
[2, 49],
]
],
},
"properties": {
"string_field": "bar",
"int_field": 1,
"int64_field": 123456789012,
"double_field": 1.23,
"another_prop": 3,
},
},
{
"name": "projects/earthengine-public/assets/collection/second_feature"
},
]
}
),
):
lyr.SetSpatialFilterRect(-180, -90, 180, 90)
f = lyr.GetNextFeature()
assert (
f.GetField("name")
== "projects/earthengine-public/assets/collection/filtered_feature"
)
lyr.SetSpatialFilter(None)
# Test time equality with second granularity
lyr.SetAttributeFilter(
"startTime >= '1980-01-01T00:00:00Z' AND endTime <= '1980-01-02T23:59:59Z'"
)
tmpfile = "/vsimem/ee/projects/earthengine-public/assets/collection:listImages?startTime=1980%2D01%2D01T00%3A00%3A00Z&endTime=1980%2D01%2D02T23%3A59%3A59Z"
with gdaltest.tempfile(
tmpfile,
json.dumps(
{
"images": [
{
"name": "projects/earthengine-public/assets/collection/filtered_feature",
"startTime": "1980-01-01T00:00:00Z",
"endTime": "1980-01-02T23:59:59Z",
},
{
"name": "projects/earthengine-public/assets/collection/second_feature"
},
]
}
),
):
f = lyr.GetNextFeature()
assert (
f.GetField("name")
== "projects/earthengine-public/assets/collection/filtered_feature"
)
# Test time equality with day granularity
lyr.SetAttributeFilter("startTime = '1980-01-01' AND endTime = '1980-01-02'")
tmpfile = "/vsimem/ee/projects/earthengine-public/assets/collection:listImages?startTime=1980%2D01%2D01T00%3A00%3A00Z&endTime=1980%2D01%2D02T23%3A59%3A59Z"
with gdaltest.tempfile(
tmpfile,
json.dumps(
{
"images": [
{
"name": "projects/earthengine-public/assets/collection/filtered_feature",
"startTime": "1980-01-01T12:00:00Z",
"endTime": "1980-01-02T23:59:59Z",
},
{
"name": "projects/earthengine-public/assets/collection/second_feature"
},
]
}
),
):
f = lyr.GetNextFeature()
assert (
f.GetField("name")
== "projects/earthengine-public/assets/collection/filtered_feature"
)
ds = None
###############################################################################
# Nominal case where collection is in eedaconf.json
def test_eeda_3():
with gdal.config_options({"EEDA_BEARER": "mybearer", "EEDA_URL": "/vsimem/ee/"}):
ds = ogr.Open("EEDA:##example_collection/example_subcollection")
lyr = ds.GetLayer(0)
assert lyr.GetLayerDefn().GetFieldCount() == 8 + 7 + 4
ds = None
###############################################################################
# Test that name and id variants are handled correctly.
def test_eeda_4():
with gdaltest.config_options(
{"EEDA_BEARER": "mybearer", "EEDA_URL": "/vsimem/ee/"}
):
# User asset ID ("users/**").
tmpfile = "/vsimem/ee/projects/earthengine-legacy/assets/users/foo:listImages?pageSize=1"
with gdaltest.tempfile(
tmpfile,
json.dumps(
{
"images": [
{"name": "projects/earthengine-legacy/assets/users/foo/bar"}
]
}
),
):
assert ogr.Open("EEDA:users/foo").GetLayer(0)
# Project asset ID ("projects/**").
tmpfile = "/vsimem/ee/projects/earthengine-legacy/assets/projects/foo:listImages?pageSize=1"
with gdaltest.tempfile(
tmpfile,
json.dumps(
{
"images": [
{"name": "projects/earthengine-legacy/assets/projects/foo/bar"}
]
}
),
):
ds = ogr.Open("EEDA:projects/foo")
assert ds.GetLayer(0)
ds = None
# Multi-folder project asset ID ("projects/foo/bar/baz").
tmpfile = "/vsimem/ee/projects/earthengine-legacy/assets/projects/foo/bar/baz:listImages?pageSize=1"
with gdaltest.tempfile(
tmpfile,
json.dumps(
{
"images": [
{
"name": "projects/earthengine-legacy/assets/projects/foo/bar/baz/qux"
}
]
}
),
):
ds = ogr.Open("EEDA:projects/foo/bar/baz")
assert ds.GetLayer(0)
ds = None
# Public-catalog asset ID (e.g. "LANDSAT").
tmpfile = (
"/vsimem/ee/projects/earthengine-public/assets/foo:listImages?pageSize=1"
)
with gdaltest.tempfile(
tmpfile,
json.dumps(
{"images": [{"name": "projects/earthengine-public/assets/foo/bar"}]}
),
):
ds = ogr.Open("EEDA:foo")
assert ds.GetLayer(0)
ds = None
# Asset name ("projects/*/assets/**").
tmpfile = "/vsimem/ee/projects/foo/assets/bar:listImages?pageSize=1"
with gdaltest.tempfile(
tmpfile, json.dumps({"images": [{"name": "projects/foo/assets/bar/baz"}]})
):
ds = ogr.Open("EEDA:projects/foo/assets/bar")
assert ds.GetLayer(0)
ds = None