예제 #1
0
    def from_file(cls, href):
        """Reads a STACObject implementation from a file.

        Args:
            href (str): The HREF to read the object from.

        Returns:
            The specific STACObject implementation class that is represented
            by the JSON read from the file located at HREF.
        """
        if not is_absolute_href(href):
            href = make_absolute_href(href)
        d = STAC_IO.read_json(href)

        if cls == STACObject:
            o = STAC_IO.stac_object_from_dict(d, href=href)
        else:
            o = cls.from_dict(d, href=href)

        # Set the self HREF, if it's not already set to something else.
        if o.get_self_href() is None:
            o.set_self_href(href)

        # If this is a root catalog, set the root to the catalog instance.
        root_link = o.get_root_link()
        if root_link is not None:
            if not root_link.is_resolved():
                if root_link.get_absolute_href() == href:
                    o.set_root(o, link_type=root_link.link_type)
        return o
예제 #2
0
    def save_object(self, include_self_link=True, dest_href=None):
        """Saves this STAC Object to it's 'self' HREF.

        Args:
          include_self_link (bool): If this is true, include the 'self' link with this object.
              Otherwise, leave out the self link.
          dest_href (str): Optional HREF to save the file to. If None, the object will be saved
              to the object's self href.

        Raises:
            :class:`~pystac.STACError`: If no self href is set, this error will be raised.

        Note:
            When to include a self link is described in the `Use of Links section of the
            STAC best practices document
            <https://github.com/radiantearth/stac-spec/blob/v0.8.1/best-practices.md#use-of-links>`_
        """
        if dest_href is None:
            self_href = self.get_self_href()
            if self_href is None:
                raise STACError(
                    'Self HREF must be set before saving without an explicit dest_href.')
            dest_href = self_href

        STAC_IO.save_json(dest_href, self.to_dict(include_self_link=include_self_link))
예제 #3
0
    def save(self, href=None, include_self_link=True):
        """Saves this ItemCollection.

        Args:
            href (str): The HREF to save the ItemCollection to. If None,
                will save to the currently set ``self`` link.
                If supplied, will set this href to the ItemCollection's self link.
            include_self_link (bool): If True, will include the self link
                in the set of links of the saved JSON.
        """
        if href is None:
            href = self.get_self_href()
            if href is None:
                raise STACError('Must either supply an href or set a self href on '
                                'this ItemCollection.')
        else:
            self.set_self_href(href)

        STAC_IO.save_json(href, self.to_dict(include_self_link=include_self_link))
예제 #4
0
def merge_common_properties(item_dict, collection_cache=None, json_href=None):
    """Merges Collection properties into an Item.

    Args:
        item_dict: JSON dict of the Item which properties should be merged
            into.
        collection_cache: Optional cache of Collection JSON that has previously
            read. Keyed to either the Collection ID or an HREF.
        json_href: The HREF of the file that this JSON comes from. Used
            to resolve relative paths.

    Returns:
        bool: True if Collection properties have been merged, otherwise False.
    """
    properties_merged = False
    collection = None
    collection_href = None

    # Try the cache if we have a collection ID.
    if 'collection' in item_dict:
        collection_id = item_dict['collection']
        if collection_cache is not None:
            collection = collection_cache.get(collection_id)

    # Next, try the collection link.
    if collection is None:
        links = item_dict['links']
        collection_link = next((l for l in links if l['rel'] == 'collection'),
                               None)
        if collection_link is not None:
            collection_href = collection_link['href']
            if json_href is not None:
                collection_href = make_absolute_href(collection_href,
                                                     json_href)
            if collection_cache is not None:
                collection = collection_cache.get(collection_href)

            if collection is None:
                collection = STAC_IO.read_json(collection_href)

    if collection is not None:
        if 'properties' in collection:
            for k in collection['properties']:
                if k not in item_dict['properties']:
                    properties_merged = True
                    item_dict['properties'][k] = collection['properties'][k]

        if collection_cache is not None and collection[
                'id'] not in collection_cache:
            collection_id = collection['id']
            collection_cache[collection_id] = collection
            if collection_href is not None:
                collection_cache[collection_href] = collection

    return properties_merged
예제 #5
0
    def from_file(href):
        """Reads an ItemCollection from a file.

        Args:
            href (str): The HREF to read the item from.

        Returns:
            ItemCollection: ItemCollection that was read from the given file.
        """
        d = json.loads(STAC_IO.read_text(href))
        c = ItemCollection.from_dict(d)
        return c
예제 #6
0
    def from_file(uri):
        """Reads an SingleFileSTAC from a file.

        Args:
            href (str): The HREF to read the item from.

        Returns:
            SingleFileSTAC: SingleFileSTAC that was read from the given file.
        """

        d = json.loads(STAC_IO.read_text(uri))
        c = SingleFileSTAC.from_dict(d)
        return c
예제 #7
0
    def resolve_stac_object(self, root=None):
        """Resolves a STAC object from the HREF of this link, if the link is not
        already resolved.

        Args:
            root (Catalog or Collection): Optional root of the catalog for this link.
                If provided, the root's resolved object cache is used to search for
                previously resolved instances of the STAC object.
        """
        if isinstance(self.target, str):
            target_href = self.target

            # If it's a relative link, base it off the parent.
            if not is_absolute_href(target_href):
                if self.owner is None:
                    raise STACError('Relative path {} encountered '
                                    'without owner or start_href.'.format(target_href))
                start_href = self.owner.get_self_href()

                if start_href is None:
                    raise STACError('Relative path {} encountered '
                                    'without owner "self" link set.'.format(target_href))

                target_href = make_absolute_href(target_href, start_href)
            obj = None

            if root is not None:
                obj = root._resolved_objects.get_by_href(target_href)

            if obj is None:
                obj = STAC_IO.read_stac_object(target_href, root=root)
                obj.set_self_href(target_href)
                if root is not None:
                    obj = root._resolved_objects.get_or_cache(obj)
                    obj.set_root(root, link_type=self.link_type)
        else:
            obj = self.target

        self.target = obj

        if self.owner and self.rel in ['child', 'item']:
            self.target.set_parent(self.owner, link_type=self.link_type)

        return self
예제 #8
0
def merge_common_properties(item_dict, collection_cache=None, json_href=None):
    """Merges Collection properties into an Item.

    Args:
        item_dict (dict): JSON dict of the Item which properties should be merged
            into.
        collection_cache (CollectionCache): Optional CollectionCache
            that will be used to read and write cached collections.
        json_href: The HREF of the file that this JSON comes from. Used
            to resolve relative paths.

    Returns:
        bool: True if Collection properties have been merged, otherwise False.
    """
    properties_merged = False

    collection = None
    collection_id = None
    collection_href = None

    # Check to see if this is an item 0.9 or later that
    # doesn't extend the commons extension, in which case
    # we don't have to merge.
    stac_version = item_dict.get('stac_version')
    if stac_version is not None and stac_version >= '0.9.0':
        stac_extensions = item_dict.get('stac_extensions')
        if type(stac_extensions) is list:
            if 'commons' not in stac_extensions:
                return False

    # Try the cache if we have a collection ID.
    if 'collection' in item_dict:
        collection_id = item_dict['collection']
        if collection_cache is not None:
            collection = collection_cache.get_by_id(collection_id)

    # Next, try the collection link.
    if collection is None:
        links = item_dict['links']

        # Account for 0.5 links, which were dicts
        if isinstance(links, dict):
            links = list(links.values())

        collection_link = next(
            (link for link in links if link['rel'] == 'collection'), None)
        if collection_link is not None:
            collection_href = collection_link['href']
            if json_href is not None:
                collection_href = make_absolute_href(collection_href,
                                                     json_href)
            if collection_cache is not None:
                collection = collection_cache.get_by_href(collection_href)

            if collection is None:
                collection = STAC_IO.read_json(collection_href)

    if collection is not None:
        collection_id = None
        collection_props = None
        if isinstance(collection, Collection):
            collection_id = collection.id
            collection_props = collection.properties
        else:
            collection_id = collection['id']
            if 'properties' in collection:
                collection_props = collection['properties']

        if collection_props is not None:
            for k in collection_props:
                if k not in item_dict['properties']:
                    properties_merged = True
                    item_dict['properties'][k] = collection_props[k]

        if collection_cache is not None and not collection_cache.contains_id(
                collection_id):
            collection_cache.cache(collection, href=collection_href)

    return properties_merged