# Path: gbdxtools/vector_layers.py
# class VectorGeojsonLayer(VectorLayer):
#     """ Represents a vector layer created from a geojson source
# 
#         Args:
#             geojson (dict): a list of geojson features to render
#             styles (list): A list of style objects to be applied to the layer
#     """
#     def __init__(self, geojson, **kwargs):
#         super(VectorGeojsonLayer, self).__init__(**kwargs)
#         self.geojson = geojson
# 
#     def _datasource_def(self):
#         return {'type': 'geojson', 'data': self.geojson}
# 
#     def _layer_def(self, style):
#         return {
#             'id': type(style).__name__, # TODO - make this unique in the various styles
#             'type': style.type,
#             'source': self.source_id,
#             'paint': style.paint()
#         }
# 
# class VectorTileLayer(VectorLayer):
#     """ Represents a vector tile layer in a tile map
# 
#         Args:
#             url (str): a vector tile url template
#             source_name (str): the name of the source layer in the vector tiles
#             styles (list): A list of style objects to be applied to the layer
#     """
#     def __init__(self, url=None, source_layer_name='GBDX_Task_Output', **kwargs):
#         super(VectorTileLayer, self).__init__(**kwargs)
#         self.url = url
#         self.source_layer_name = source_layer_name
# 
#     def _datasource_def(self):
#         return {'type': 'vector', 'tiles': [self.url]}
# 
#     def _layer_def(self, style):
#         return {
#             'id': type(style).__name__, # TODO - make this unique in the various styles
#             'type': style.type,
#             'source': self.source_id,
#             'source-layer':  self.source_layer_name,
#             'paint': style.paint()
#         }
# 
# class ImageLayer(object):
#     """ A layer for rendering images and image arrays to slippy maps
# 
#         Args:
#             image (str): a vector tile url template
#             coordinates: the coordinate bounds (list of polygon corners) for placing the image
# 
#         Returns:
#             An string of the layer definition
#     """
#     def __new__(self, image, coordinates):
#         return json.dumps({
#             "id": uuid.uuid4().hex,
#             "type": "raster",
#             "source": {
#                 "type": "image",
#                 "url": image,
#                 "coordinates": coordinates
#             }
#         })
# 
# Path: gbdxtools/auth.py
# def Auth(**kwargs):
#     global auth
#     if auth is None or len(kwargs) > 0:
#         auth = _Auth(**kwargs)
#     return auth


from string import Template
from imageio import imsave
from io import BytesIO
from shapely.wkt import loads as load_wkt
from collections import OrderedDict
from shapely.ops import cascaded_union
from shapely.geometry import shape, box, mapping
from gbdxtools.vector_layers import VectorGeojsonLayer, VectorTileLayer, \
                                    ImageLayer
from gbdxtools.map_templates import BaseTemplate
from gbdxtools.auth import Auth
            from IPython.display import display
            from IPython.display import display
import base64
import dask.array as da
import requests
import json, time, os
        try:
        except:
            print("IPython is required to produce maps.")
            return

        assert api_key is not None, "No Mapbox API Key found. You can either pass in a key or set the MAPBOX_API_KEY environment variable. Use outside of GBDX Notebooks requires a MapBox API key, sign up for free at https://www.mapbox.com/pricing/"
        if features is None and query is not None:
            wkt = box(*bbox).wkt
            features = self.query(wkt, query, index=None)
        elif features is None and query is None and image is None:
            print('Must provide either a list of features or a query or an image')
            return

        if styles is not None and not isinstance(styles, list):
            styles = [styles]

        geojson = {"type":"FeatureCollection", "features": features}

        if center is None and features is not None:
            union = cascaded_union([shape(f['geometry']) for f in features])
            lon, lat = union.centroid.coords[0]
        elif center is None and image is not None:
            try:
                lon, lat = shape(image).centroid.coords[0]
            except:
                lon, lat = box(*image_bounds).centroid.coords[0]
        else:
            lat, lon = center

        map_id = "map_{}".format(str(int(time.time())))

# Path: gbdxtools/vector_layers.py
# class VectorGeojsonLayer(VectorLayer):
#     """ Represents a vector layer created from a geojson source
# 
#         Args:
#             geojson (dict): a list of geojson features to render
#             styles (list): A list of style objects to be applied to the layer
#     """
#     def __init__(self, geojson, **kwargs):
#         super(VectorGeojsonLayer, self).__init__(**kwargs)
#         self.geojson = geojson
# 
#     def _datasource_def(self):
#         return {'type': 'geojson', 'data': self.geojson}
# 
#     def _layer_def(self, style):
#         return {
#             'id': type(style).__name__, # TODO - make this unique in the various styles
#             'type': style.type,
#             'source': self.source_id,
#             'paint': style.paint()
#         }
# 
# class VectorTileLayer(VectorLayer):
#     """ Represents a vector tile layer in a tile map
# 
#         Args:
#             url (str): a vector tile url template
#             source_name (str): the name of the source layer in the vector tiles
#             styles (list): A list of style objects to be applied to the layer
#     """
#     def __init__(self, url=None, source_layer_name='GBDX_Task_Output', **kwargs):
#         super(VectorTileLayer, self).__init__(**kwargs)
#         self.url = url
#         self.source_layer_name = source_layer_name
# 
#     def _datasource_def(self):
#         return {'type': 'vector', 'tiles': [self.url]}
# 
#     def _layer_def(self, style):
#         return {
#             'id': type(style).__name__, # TODO - make this unique in the various styles
#             'type': style.type,
#             'source': self.source_id,
#             'source-layer':  self.source_layer_name,
#             'paint': style.paint()
#         }
# 
# class ImageLayer(object):
#     """ A layer for rendering images and image arrays to slippy maps
# 
#         Args:
#             image (str): a vector tile url template
#             coordinates: the coordinate bounds (list of polygon corners) for placing the image
# 
#         Returns:
#             An string of the layer definition
#     """
#     def __new__(self, image, coordinates):
#         return json.dumps({
#             "id": uuid.uuid4().hex,
#             "type": "raster",
#             "source": {
#                 "type": "image",
#                 "url": image,
#                 "coordinates": coordinates
#             }
#         })
# 
# Path: gbdxtools/auth.py
# def Auth(**kwargs):
#     global auth
#     if auth is None or len(kwargs) > 0:
#         auth = _Auth(**kwargs)
#     return auth


# Path: gbdxtools/vectors.py
from string import Template
from imageio import imsave
from io import BytesIO
from shapely.wkt import loads as load_wkt
from collections import OrderedDict
from shapely.ops import cascaded_union
from shapely.geometry import shape, box, mapping
from gbdxtools.vector_layers import VectorGeojsonLayer, VectorTileLayer, \
                                    ImageLayer
from gbdxtools.map_templates import BaseTemplate
from gbdxtools.auth import Auth
            from IPython.display import display
            from IPython.display import display
import base64
import dask.array as da
import requests
import json, time, os

        try:
        except:
            print("IPython is required to produce maps.")
            return

        assert api_key is not None, "No Mapbox API Key found. You can either pass in a key or set the MAPBOX_API_KEY environment variable. Use outside of GBDX Notebooks requires a MapBox API key, sign up for free at https://www.mapbox.com/pricing/"
        if features is None and query is not None:
            wkt = box(*bbox).wkt
            features = self.query(wkt, query, index=None)
        elif features is None and query is None and image is None:
            print('Must provide either a list of features or a query or an image')
            return

        if styles is not None and not isinstance(styles, list):
            styles = [styles]

        geojson = {"type":"FeatureCollection", "features": features}

        if center is None and features is not None:
            union = cascaded_union([shape(f['geometry']) for f in features])
            lon, lat = union.centroid.coords[0]
        elif center is None and image is not None:
            try:
                lon, lat = shape(image).centroid.coords[0]
            except:
                lon, lat = box(*image_bounds).centroid.coords[0]
        else:
            lat, lon = center

        map_id = "map_{}".format(str(int(time.time())))

        map_data = VectorGeojsonLayer(geojson, styles=styles, **kwargs)