Skip to content

Instantly share code, notes, and snippets.

View thorwebdev's full-sized avatar
🔨
building

Thor 雷神 Schaeff thorwebdev

🔨
building
View GitHub Profile
@thorwebdev
thorwebdev / MyFence.java
Created December 7, 2014 15:59
For the sake of convenience we’re only storing the fences’ vertices and some metadata. To send and receive data through our endpoints we need an object model which we create in a little Java Bean called MyFence.java.
package com.google.appengine.geo.fencing;
/** The object model for the data we are sending through endpoints */
public class MyFence {
private long id = -1;
public String name;
public String entityGroup;
public String description;
public double[][] vertices;
@thorwebdev
thorwebdev / MyIndex_add_polys_snippet.java
Last active August 29, 2015 14:10
To speed up our geofencing queries we’re going to index our fences in an STR tree. The JTS library does most of the heavy lifting here, so we only need to fetch all our fences from Datastore, create a polygon object for each one and add the polygon’s bounding box to the index.
//Get all fences of group from DataStore.
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key fenceKey = KeyFactory.createKey("Geofence", group);
Query query = new Query("Fence", fenceKey).addSort("id", Query.SortDirection.DESCENDING);
List < Entity > fencesFromStore = datastore.prepare(query).asList(FetchOptions.Builder.withDefaults());
if (!fencesFromStore.isEmpty()) {
//Create STRTree-Index.
STRtree index = new STRtree();
@thorwebdev
thorwebdev / MyIndex_build_snippet.java
Created December 7, 2014 16:01
We then build the index and store it to Memcache for fast read access.
//Build the index.
index.build();
//Write the index to Memcache.
MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
//Last param is expiration date. Set to null to keep it in Memcache forever.
syncCache.put(group, index, null);
@thorwebdev
thorwebdev / addFence_snippet.java
Created December 7, 2014 16:02
Now we need to create an endpoint called add. This endpoint expects a string for the group name, a boolean indicating whether to rebuild our index, and a JSON object representing our fence’s object model. From this we create a new fence and write it to Cloud Datastore.
@ApiMethod(name = "add", httpMethod = "post", path = "add")
public MyFence addFence(@Named("group") String group, @Named("index") boolean buildIndex, MyFence fence) {
//Get the last fences' id.
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key fenceKey = KeyFactory.createKey("Geofence", group);
long nextId;
if (fence.getId() != -1) {
nextId = fence.getId();
} else {
@thorwebdev
thorwebdev / getFenceById_snippet.java
Created December 7, 2014 16:03
When we query our fences we only return the ids of the fences that were returned, therefore we need an endpoint to retrieve the metadata that corresponds to a fence id. This endpoint simply accepts an id, queries the Datastore and returns the metadata of the fence with the corresponding id.
@ApiMethod(name = "getById", httpMethod = "get", path = "getById")
public ArrayList < MyFence > getFenceById(@Named("group") String group, @Named("id") long id) {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key fenceKey = KeyFactory.createKey("Geofence", group);
Filter propertyFilter = new FilterPredicate("id", FilterOperator.EQUAL, id);
Query query = new Query("Fence", fenceKey).setFilter(propertyFilter);
Entity fenceFromStore = datastore.prepare(query).asSingleEntity();
ArrayList < MyFence > fences = new ArrayList < MyFence > ();
if (fenceFromStore != null) {
@thorwebdev
thorwebdev / listFences_snippet.java
Created December 7, 2014 16:04
For some use cases it makes sense to fetch all the fences at once in the beginning, so we want to have an endpoint to list all fences from a certain group.
@ApiMethod(name = "list", httpMethod = "get", path = "list")
public ArrayList < MyFence > listFences(@Named("group") String group) {
ArrayList < MyFence > fences = new ArrayList < MyFence > ();
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key fenceKey = KeyFactory.createKey("Geofence", group);
Query query = new Query("Fence", fenceKey).addSort("id", Query.SortDirection.DESCENDING);
List < Entity > fencesFromStore = datastore.prepare(query).asList(FetchOptions.Builder.withDefaults());
@thorwebdev
thorwebdev / polygon_snippet.java
Last active August 29, 2015 14:10
When testing for a polygon I want to get back all fences that are either completely or partly contained in my polygon. Therefore I test if the returned fences are within my polygon or are not disjoint.
@ApiMethod(name = "polygon", httpMethod = "post", path = "polygon")
public ArrayList < MyFence > queryPolygon(@Named("group") String group, MyPolyLine polyline) {
ArrayList < MyFence > fences = new ArrayList < MyFence > ();
//Get index from Memcache
MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
STRtree index = (STRtree) syncCache.get(group); // read from cache
if (index != null) {
//Create coordinate array.
double[][] points = polyline.getCoordinates();
@thorwebdev
thorwebdev / polyline_snippet.java
Last active August 29, 2015 14:10
The process of testing for a point can easily be adapted to test our fences against polylines and polygons. In the case of polylines we query the index with the polyline’s bounding box and then test if the polyline actually crosses the returned fences.
@ApiMethod(name = "polyline", httpMethod = "post", path = "polyline")
public ArrayList < MyFence > queryPolyLine(@Named("group") String group, MyPolyLine polyline) {
ArrayList < MyFence > fences = new ArrayList < MyFence > ();
//Get the index from Memcache.
MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
GeometryFactory gf = new GeometryFactory();
STRtree index = (STRtree) syncCache.get(group); // read from cache
if (index != null) {
//Create coordinate array.
@thorwebdev
thorwebdev / queryPoint_snippet.java
Last active August 29, 2015 14:10
We need an endpoint to test any latitude-longitude-pair against all our fences. This is the actual geofencing part. We want to be able to know, if the point falls into any of our fences and if so, we want to get back the ids of the fences the point is in. For this we first need to retrieve our index from Memcache. We then query the index with th…
@ApiMethod(name = "point", httpMethod = "get", path = "point")
public ArrayList < MyFence > queryPoint(@Named("group") String group, @Named("lng") double lng, @Named("lat") double lat) {
ArrayList < MyFence > fences = new ArrayList < MyFence > ();
//Get the Index from Memcache.
MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
GeometryFactory gf = new GeometryFactory();
STRtree index = (STRtree) syncCache.get(group); // read from cache
if (index != null) {
Coordinate coord = new Coordinate(lng, lat);
@thorwebdev
thorwebdev / avg_tip_amount.sql
Last active August 29, 2015 14:11
Calculate the average tip amount for each area with more than 50,000 trips that have a tip recorded. Exclude tips with value 0.
SELECT
pickup_polyId,
SUM(tip_amount)/COUNT(*) AS average_tip,
COUNT(*) AS no_of_trips
FROM
[nyctaximap:dataflow.nyc_output_join_fare_distinct]
WHERE
tip_amount!=0
GROUP BY
pickup_polyId