Tutorial

This tutorial assumes that you have snowfloat-python installed already.

If you have trouble going through this tutorial, please email us at SnowFloat Help.

Let’s learn by example.

We are tracking two seals: “Sally” (Red points) and “Tom” (Green points).

../../_images/trace.png

Each point in this example has three dimensions:

  • longitude (x).
  • latitude (y).
  • altitude (z).

Each point in this example has three fields:

  • a timestamp.
  • a heartbeat value.
  • a seal ID.

We want to store this data online and run some queries on it.

Our set of points can be seen as a layer. A layer has a spatial reference system defined by an SRID EPSG code and a number of dimensions. In this example, we will use SRID EPSG code 4326 and 3 dimensions.

We can associate features to a layer. Each feature has one geometry attached. Here, it is a point. Each feature has fields associated to it. The fields here are: “timestamp”, “heartbeat” and “seal_id”.

Note

SnowFloat can be applied to many different domains. Roads, lots, mobile application location...

Sign up

First step is to sign up and take note of your API keys.

Add the following to snowfloat.conf in your home directory:

[snowfloat]
api_key_id = your API key ID (no quotes)
api_secret_key = your API secret key (no quotes)

Make sure that your API key ID is accessible when settings is imported.

>>> import snowfloat.settings
>>> snowfloat.settings.API_KEY_ID
'your API key ID'

Note: The current setup is self-financed so you are currently limited to:

  • 10 layers.
  • 10 000 features.
  • 100 000 points. Some geometries consist of multiple points.
  • 10 tasks per hour.
  • 900 seconds per hour of task running time.
  • 1000 HTTP requests per hour.

Adding the layer

Let’s start with couple of imports.

>>> import snowfloat.layer
>>> import snowfloat.client

We define the list of fields for our layer.

>>> fields = [{'name': 'timestamp', 'type': 'datetime'},
...           {'name': 'heartbeat', 'type': 'integer'},
...           {'name': 'seal_id', 'type': 'integer'}]

See Fields for a complete list of the possible field types.

>>> layer = snowfloat.layer.Layer(name='Seals', fields=fields, srid=4326,
...                               dims=3)

We define our client to talk to the server and we add our layer.

>>> client = snowfloat.client.Client()
>>> layers = client.add_layers([layer,])

At that point, the layer is stored online. Note how the layer now has a unique ID and a unique URI.

>>> layer = layers[0]
>>> layer
Layer(name=Seals,
      uuid=11d53e204a9b45299e68d186e7405779,
      date_created='2013-01-25T06:01:23-00:00',
      date_modified='2013-01-25T06:01:23-00:00',
      uri=/geo/1/layers/11d53e204a9b45299e68d186e7405779,
      num_features=0,
      num_points=0,
      fields=[{'name': 'timestamp', 'type': 'datetime'},
              {'name': 'heartbeat', 'type': 'integer'},
              {'name': 'seal_id', 'type': integer}],
      srid=4326,
      dims=3,
      extent=None)
>>> layer.name
u'Seals'

See Layers for more on layers.

Adding our points to the layer

We create two features, one for each Seal, with a snowfloat.geometry.Point geometry attached to each of them. We also set the fields values for each feature.

>>> import snowfloat.feature
>>> import snowfloat.geometry
>>> point = snowfloat.geometry.Point([-95.363151, 29.763374, -18])
>>> fields = {'seal_id': 1, 'timestamp': '2013-02-01 06:15:11',
...           'heartbeat': 61}
>>> feature1 = snowfloat.feature.Feature(point, fields)
>>> point = snowfloat.geometry.Point([-95.429287, 29.391127, -20])
>>> fields = {'seal_id': 2, 'timestamp': '2013-02-01 06:15:11',
...           'heartbeat': 63}
>>> feature2 = snowfloat.feature.Feature(point, fields)

We pass the list of snowfloat.feature.Feature objects to the method snowfloat.layer.Layer.add_features():

>>> features = layer.add_features([feature1, feature2])

The features are now stored online.

>>> feature = features[0]
>>> feature
Feature(
      uuid=6bf3f0bc551f41a6b6d435d51793c850,
      uri=/geo/1/layers/11d53e204a9b45299e68d186e7405779/features/6bf3f0bc551f41a6b6d435d51793c850,
      date_created='2013-01-25T06:01:23-00:00',
      date_modified='2013-01-25T06:01:23-00:00',
      geometry=Point(coordinates=[-95.363151, 29.763374, -18]),
      fields={'seal_id': 1, 'timestamp': '2013-02-01 06:15:11',
              'heartbeat': 61},
      layer_uuid='11d53e204a9b45299e68d186e7405779',
      spatial=None)

We could also have used the method snowfloat.client.Client.add_features() and specified the layer ID.

If you have Shapely installed, the Geometry objects will also be shapely.geometry objects:

>>> feature.geometry.x
-95.363151

Likely, we can add polygons, linestrings, multipoints, multipolygons, multilinestrings and geometry collections to our layer. See Geometries for more on geometries.

See Import geospatial data to learn how to import data using an OGR data source.

See Features for more on features.

Retrieving features

We want to retrieve the list of points for our first seal.

>>> features = layer.get_features(field_seal_id_exact=1)

See Lookups for a complete list of the attributes and field lookups you can perform.

We also could have used the method snowfloat.client.Client.get_features() and specified the layer ID.

Distance queries

We can run some distance queries on our data online. For example, we want to get the list of features less than 10kms from a given point.

../../_images/distance.png

This will tell us how much time was spent by our two seals in this circular area:

>>> point = snowfloat.geometry.Point([-95.3, 29.7])

# Let's run our query on our dataset.
>>> features = layer.get_features(query='distance_lt',
...                               geometry=point,
...                               distance=10000)
# The distance needs to be in meters.

See Fields and attributes queries for a complete list of distance queries you can perform.

Spatial queries

We can run some spatial queries on our data online. For example, we want to get the list of features contained by a polygon.

../../_images/polygon.png
>>> polygon = snowfloat.geometry.Polygon([[[-96.5, 30.5],
...                                        [-95.1, 30.5],
...                                        [-95.1, 29.1],
...                                        [-96.5, 29.1],
...                                        [-96.5, 30.5]]])

# Let's run our query on our dataset.
>>> features = layer.get_features(query='contained', geometry=polygon)

See Spatial queries for a complete list of spatial queries you can perform.

Spatial operations

In addition, we can perform a spatial operation on each geometry that was returned by the query. The output of this operation is stored in the attribute “spatial” of each Feature object returned.

We want to compute the distance from each feature point in our query to a given geometry. Here, the lookup geometry is a point:

>>> point = snowfloat.geometry.Point([-95, 29])

# Let's run our query on our dataset.
>>> features = layer.get_features(spatial_operation='distance',
...                               spatial_geometry=point)
# The operation output is stored in the attribute "spatial".
# Distance is in the spatial refence system units.
>>> for f in features: print f.spatial
91887.1503937
60232.1193816

You can mix distance/spatial queries and spatial operations in the same query.

See Spatial operations for a complete list of spatial operations you can perform.

Tasks

We can also execute some tasks to perform time consuming computations. The method snowfloat.client.Client.execute_tasks() will send the tasks to the server, wait for them to complete and return the results.

A task is specified using an operation and some parameters specific to the operation chosen. We can execute multiple tasks at the same time.

One example is to execute a task generating a map with the points from our layer. The result is a URL you can use in a GET request to retrieve the map (png format):

>>> task = snowfloat.task.Task(
...            operation='map',
...            task_filter={'layer_uuid_exact': layer.uuid},
...            extras={'bbox': [-96, 29, -95, 30]})
>>> r = client.execute_tasks([task,])
>>> r
[[{"url": "http://snowfloat.results.s3.amazonaws.com/ac7a4cf7b5cb4ace9cc33710883d68d7?Signature=PuVycdfhYyUmK4tMZ0YXaCYWG2Y%3D&Expires=1360635770&AWSAccessKeyId=AKIAJW5GLVYHVBDEHB7Q"}]]

Note

The URLs are only valid for 10 minutes for security reasons.

Note

If a task fails, the dictionary contains a key ‘error’ with a value set to the failure’s reason.

See Tasks for a complete list of the tasks you can execute.

See Performance for a report on the performance for common operations.

Table Of Contents

This Page