Platform

Configuration

You can configure the endpoint directly or utilize env variables.

export PSW_PLATFORM_SITE="http://base.platform.url"
export PSW_PLATFORM_USER="3ScaleUsername"
export PSW_PLATFORM_PASSWORD="3ScalePassword"

Products

The Product class allows you to query platform products and provides convenience methods for accessing a products other resources.

Requesting Products

from skywise.platform import Product

# Find all Products
products = Product.find()

# Find a single product
precip_product = Product.find('skywise-1hr-precipitation-analysis')

# Find all products with a particular content type
precip_products = Product.find(contentType='precipitation')

# Find all products from a particular source
wdssii_products = Product.find(source='wdssii')

# Find products for both source/content.
wdssii_precip_products = Product.find(contentType='precipitation', source='wdssii')

# Find products by aggregation period.
# Can pass 'day', 'hour', 'minute', or an int value representing the period in minutes.
hourly_precip_products = Product.find(aggregation='hour', contentType='precipitation')

# Find products that support a given date range at a particular location (Points, Polygons, and MultiPolygons accepted).
from geojson import Point
okc = Point((35.482309, -97.534994))
start = arrow.get('2015-01-01').datetime
end = arrow.get().replace(days=-1).datetime
analysis_products = Product.find(start=start, end=end, coverage=okc)

Forecasts

Forecasts are requested using the Forecast class or through a forecast product.

from skywise.platform import Forecast

# Retrieve a particular forecast
forecast = Forecast.find('my-forecast-id')

# Retrieve all forecasts for a product
forecasts = Forecast.find(product_id=product.id)

# Or calling on a product directly
forecasts = product.get_forecasts(start=start, end=end)

# Get the most recent forecast
current_forecast = Forecast.current(product.id)
current_forecast = forecast_product.current_forecast()

Frames

Frames can be requested a few ways. The easiest is using a product.

import arrow
from skywise.platform import Product

hourly_precip = Product.find('skywise-1hr-precipitation-analysis')
latest_frames = hourly_precip.get_frames()

start = arrow.get().replace(days=-1).datetime
end = arrow.get().datetime
past_24_hour_frames = hourly_precip.get_frames(start=start, end=end)

You can also access frames directly using either the ProductFrame or ForecastFrame resource, depending on the type of product you are requesting. (Using the get_frames() method of a product takes care of this distinction for you.)

from skywise.platform import ProductFrame

latest_frames = ProductFrame.find(precip_product.id)
past_24_hour_frames = ProductFrame.find(precip_product.id, start=start, end=end)

Map Tiles

There are two types of tiles in the platform module: GoogleMapsTile and BingMapsTile. First, let’s call these endpoints directly.

from skywise.platform import Product, BingMapsTile, GoogleMapsTile

product = Product.find('skywise-1hr-precipitation-analysis')
frame = product.get_frames()[0]

bing_tile = BingMapsTile.find(frame.id, '0', media_type='image/png')
google_tile = GoogleMapsTile.find(frame.id, 0, 0, 1, media_type='image/jpeg')

Here, we are specifying a BingMaps tile at quadkey ‘0’ and a GoogleMaps tile at 0, 1 with a zoom of 1. You can also retrieve tiles directly from a product.

# Get tiles for the latest frames
google_tiles = product.google_maps_tiles(0, 0, 1)
bing_tiles = product.bing_maps_tiles('0')

# Get tiles over a particular date range
last_weeks_precip_tiles = product.google_maps_tiles(0, 0, 0, start=start, end=end)

A product google_maps_tiles() call as shown above will make your tile requests asynchronously and then map them for you, effectively blocking your application until all requests are resolved.

Asynchronous

Sometimes, however, we may want to create tile requests on multiple products asynchronously and then map them together all at once rather than in two separate calls to increase performance. Let’s look at an example of how we might request tiles for precipitation on both historical and forecast products. This can be useful if you are trying to accumulate tile values over a span of time that extends over multiple products:

from skywise import Product, map_requests

precip_analysis = Product.find('skywise-24hr-precipitation-analysis')
precip_forecast = Product.find('weatherops-24hr-precipitation-forecast')

analysis_start = arrow.get().floor('day').replace(days=-7).datetime # A Week Ago
analysis_end = analysis_start.replace(days=-1).datetime # Yesterday
forecast_start = arrow.get().floor('day').datetime # Today
forecast_end = forecast_start.replace(days=+7).datetime # A Week From Now

analysis_tiles = precip_analysis.google_maps_tiles_async(0, 0, 1, start=analysis_start, end=analysis_end)
forecast_tiles = precip_forecast.google_maps_tiles_async(0, 0, 1, start=forecast_start, end=forecast_end)

tile_requests = []
tile_requests.extend(analysis_tiles)
tile_reqeusts.extend(forecast_tiles)

tiles = map_requests(tiles)

This approach can be used to arbitrarily make asynchronous calls on a number of different tiles, regardless of their originating product.

Map Tile Sets

We’re not always going to know or care about the exact map coordinates or zoom level that we want for our tile requests. Often times, we just want to grab all tiles for a region on a map. Let’s try using tileset functions to grab all precip tiles for a rainy day in Oklahoma:

precip_analysis = Product.find('skywise-24hr-precipitation-analysis')

okc_bounding_box = ((37.26, -94.17), (33.37, -103.49))

start = end = arrow.get('2015-06-13').floor('day').datetime
tiles = precip_analysis.google_maps_tileset(okc_bounding_box, start=start, end=end)

We now have all tiles for our bounding box on that particular day. Note that we did not specify a zoom level for our tiles. By default, this call will use the native resolution of our product frames. If you do want a specific zoom level, you may pass the ‘zoom’ parameter into the function.

Taking this example a bit further, let’s use our group() function to organize our tiles by their frame attribute’s validTime:

start = arrow.get('2015-06-13').floor('day').datetime
end = start.replace(days=+7).datetime
tiles = precip_analysis.google_maps_tileset(okc_bounding_box, start=start, end=end)
organized_tiles = tiles.group(['frame.validTime'])
"""
{ datetime(2015, 06, 13, ...): [<Tile 0>, <Tile 1>, ... <Tile N>],
  datetime(2015, 06, 14, ...): [<Tile 0>, <Tile 1>, ... <Tile N>],
  ...
  datetime(2015, 06, 20, ...): [<Tile 0>, <Tile 1>, ... <Tile N>]
}
"""

From here, we can easily use other tools to stitch together the tiles and create useful geospatial weather images.


Datapoints

Datapoints represent a unit value at a particular lat/lon. You can retrieve them using Datapoint or through a product.

from skywise.platform import Datapoint

# Find precip at a location over the last week
start = arrow.get().replace(days=-7).datetime
end = arrow.get().datetime
frames = precip_product.get_frames(start, end)
datapoints = [Datapoint.find(frame, 35.0, -97) for frame in frames]

# Asynchronously
requests = [Datapoint.find_async(frame, 35.0, -97) for frame in frames]
datapoints = Datapoint.map(requests)

# Find your points (asynchronous Datapoint calls) using the product convenience method
datapoints = precip_product.get_datapoints(35.0, -97, start=start, end=end)

Styles

Nothing fancy here. Just call styles using the product or the Style resource.

from skywise.platform import Style

styles = Style.find(product.id)
styles = product.find_styles()