예제 #1
0
def search(spatial, start_date, end_date, properties, datasource, debug,
           output):
    if debug:
        start = time.time()

    geoj = {
        "type":
        "Polygon",
        "coordinates": [[[spatial[0], spatial[3]], [spatial[2], spatial[3]],
                         [spatial[2], spatial[1]], [spatial[0], spatial[1]],
                         [spatial[0], spatial[3]]]]
    }

    temporal = (start_date, end_date) if start_date and end_date else None

    manifest = Manifest()
    for source in datasource:
        manifest[source].search(geoj,
                                temporal=temporal,
                                properties=properties,
                                limit=10)

    if debug:
        click.echo("Number of searches: {}".format(len(manifest.searches)))

    response = manifest.execute()

    if debug:
        for item in list(response):
            print("Found {} features for {}".format(
                len(response[item]['features']), item))

    if output:
        json.dump(response, output)

    if debug:
        print("Runtime: {}".format(time.time() - start))

    return 0
def __TEMPLATENAME__(event, context):
    manifest = Manifest()
    manifest['__TEMPLATENAME__'].search(**event)
    response = manifest.execute()
    return response
def NAIP(event, context):
    manifest = Manifest()
    manifest['NAIP'].search(**event)
    response = manifest.execute()
    return response
예제 #4
0
class BaseTestCases(unittest.TestCase):
    def setUp(self):
        self.spatial_mode = 'geometry'
        self._setUp()
        self.manifest = Manifest()
        self.name = self.__class__.__name__.replace('TestCases', '')
        self.manifest.update({self.name: self.datasource(self.manifest)})
        self.spatial_geom = Polygon(self.spatial['coordinates'][0])

    def check_properties(self, asset, properties):
        for item in properties:
            equality = next(iter(properties[item]))
            comparison_operator = getattr(operator, equality)
            if not comparison_operator(asset[item],
                                       properties[item][equality]):
                return False
        return True

    def _setUp(self):
        raise NotImplementedError

    def test_pattern(self):
        # Testing that datasource implements proper pattern
        for source in self.manifest.sources:
            self.assertTrue(hasattr(source, 'execute'))
            self.assertTrue(hasattr(source, 'search'))
            self.assertTrue(hasattr(source, 'tags'))
            self.assertTrue(hasattr(source, 'stac_compliant'))

    def test_spatial_search(self):
        self.manifest.flush()
        self.manifest[self.name].search(self.spatial)
        response = self.manifest.execute()

        # Buffering the input geometry to account for small discrepencies in S2 (especially with large area searches)
        # This test passes if all returned geometries are within 3% of the average length of the polygon.
        buffered_geom = self.spatial_geom.buffer(0.03 *
                                                 self.spatial_geom.length / 4)

        # Confirming that each output feature intersects input
        for feat in response[self.name]['features']:
            if self.spatial_mode == 'geometry':
                asset_geom = Polygon(feat['geometry']['coordinates'][0])
            elif self.spatial_mode == 'extent':
                asset_geom = Polygon([[feat['bbox'][0], feat['bbox'][3]],
                                      [feat['bbox'][2], feat['bbox'][3]],
                                      [feat['bbox'][2], feat['bbox'][1]],
                                      [feat['bbox'][0], feat['bbox'][1]],
                                      [feat['bbox'][0], feat['bbox'][3]]])

            self.assertTrue(asset_geom.intersects(buffered_geom))

    def test_temporal_search(self):
        self.manifest.flush()
        self.manifest[self.name].search(self.spatial, self.temporal)

        response = self.manifest.execute()
        query = STACQuery(self.spatial, self.temporal)

        # Confirming that each output feature is within temporal window
        for feat in response[self.name]['features']:
            if len(feat['properties']['datetime']) == 10:
                year, month, day = feat['properties']['datetime'].split('-')
            else:
                year, month, day = feat['properties']['datetime'].split(
                    'T')[0].split('-')

            date_time = datetime.strptime(f"{year}-{month}-{day}", "%Y-%m-%d")

            self.assertTrue(query.check_temporal(date_time))

    def test_properties_search(self):
        self.manifest.flush()
        self.manifest[self.name].search(self.spatial,
                                        properties=self.properties)
        response = self.manifest.execute()

        # Confirming that output features ars filtered properly
        for feat in response[self.name]['features']:
            self.assertTrue(
                self.check_properties(feat['properties'], self.properties))

    def test_limit(self):
        # Confirming that the limit kwarg works
        self.manifest.flush()
        self.manifest[self.name].search(self.spatial, limit=self.limit)
        response = self.manifest.execute()
        self.assertLessEqual(len(response[self.name]['features']), self.limit)

    def test_stac_compliant(self):
        self.manifest.flush()
        self.manifest[self.name].search(self.spatial)
        response = self.manifest.execute()

        # Confirming that output features are STAC-compliant
        for feat in response[self.name]['features']:

            fd, path = tempfile.mkstemp()
            try:
                with os.fdopen(fd, 'w') as tmp:
                    json.dump(feat, tmp)

                stac = stac_validator.StacValidate(path)
                stac.run()
                try:
                    self.assertEqual(stac.status['items']['valid'], 1)
                except:
                    # TODO: figure out why this error happens
                    if 'Unresolvable JSON pointer' in stac.message[0][
                            'error_message']:
                        pass
                    else:
                        raise

            finally:
                os.remove(path)
예제 #5
0
def SRTM(event, context):
    manifest = Manifest()
    manifest['SRTM'].search(**event)
    response = manifest.execute()
    return response
def ElevationTiles(event, context):
    manifest = Manifest()
    manifest['ElevationTiles'].search(**event)
    response = manifest.execute()
    return response
예제 #7
0
def PlanetData(event, context):
    manifest = Manifest()
    manifest['PlanetData'].search(**event)
    response = manifest.execute()
    return response
예제 #8
0
def USGS3DEP(event, context):
    manifest = Manifest()
    manifest['USGS3DEP'].search(**event)
    response = manifest.execute()
    return response
def Sentinel2(event, context):
    manifest = Manifest()
    manifest['Sentinel2'].search(**event)
    response = manifest.execute()
    return response
def Landsat8(event, context):
    manifest = Manifest()
    manifest['Landsat8'].search(**event)
    response = manifest.execute()
    return response
def MicrosoftBuildingFootprints(event, context):
    manifest = Manifest()
    manifest['MicrosoftBuildingFootprints'].search(**event)
    response = manifest.execute()
    return response
def CBERS(event, context):
    manifest = Manifest()
    manifest['CBERS'].search(**event)
    response = manifest.execute()
    return response