Skip to content

Instantly share code, notes, and snippets.

@juanpujol
Created September 17, 2016 23:46
Show Gist options
  • Save juanpujol/89e8a76a5467423f8bddd7e45bbd19bd to your computer and use it in GitHub Desktop.
Save juanpujol/89e8a76a5467423f8bddd7e45bbd19bd to your computer and use it in GitHub Desktop.
Building Service Docs

Beakyn Buildings Service

This services is in charge of finding buildings and keept a sync reference with POIs.

Request and response logic

Responses will be always in geoJSON format and will return as FeatureCollection with Features of type GeometryCollection, which include a polygon or multipolygon at index 0 and a point at index 1.

If a single building is requested using an ID the response will be a geoJSON of type Feature.

Also a property centroid is included on the root of the object. This is the center of mass for a polygon. It is the same value as in GeometryCollection index 1.

The centroid is used to calculate the radius included on the properties.

A centroid and a building polygon can work together with appplications to detect user pivots.

Other properties are:

  • radius - Minimum radius calculated from the centroid (used to establish a radial geofence around a building)
  • building - Building type inherited from Open Street Maps
  • countryCode - Example: "USA"
  • country - Example: "United States"
  • regionCode - Example: "NY"
  • region - Example: "New York"
  • locality - Example: "New York"
  • osmId - Open Street Maps Id

List response example:

{
  "type": "FeatureCollection",
  "total": 1,
  "features": [
    {
      "id": "57d41c2f8a5f72bd70323591",
      "properties": {
        "radius": 32,
        "building": "yes",
        "countryCode": "USA",
        "country": "United States",
        "regionCode": "NY",
        "region": "New York",
        "locality": "New York",
        "osmId": 248773769
      },
      "type": "Feature",
      "geometry": {
        "geometries": [
          {
            "coordinates": [
              [
                [-73.99225590000002,40.736458500000005],
                [-73.9920985,40.7366774],
                [-73.9920584,40.7366608],
                [-73.9919515,40.73681090000001],
                [-73.99188400000001,40.736904800000005],
                [-73.99187990000001,40.73691050000001],
                [-73.99171750000001,40.736843],
                [-73.99192270000002,40.7365574],
                [-73.99201619999998,40.736589300000006],
                [-73.9920758,40.7365075],
                [-73.9920182,40.7364972],
                [-73.9920491,40.73641580000001],
                [-73.99225590000002,40.736458500000005]
              ]
            ],
            "type": "Polygon"
          },
          {
            "coordinates": [-73.991993975,40.73665275833334],
            "type": "Point"
          }
        ],
        "type": "GeometryCollection"
      },
      "centroid": {
        "lon": -73.991993975,
        "lat": 40.73665275833334
      }
    }
  ]
}

NOTE: All list requests will include the total of results at the root of the object.

Single building response example:

{
  "id": "57d41c2f8a5f72bd70323591",
  "properties": {
    "radius": 32,
    "building": "yes",
    "countryCode": "USA",
    "country": "United States",
    "regionCode": "NY",
    "region": "New York",
    "locality": "New York",
    "osmId": 248773769
  },
  "type": "Feature",
  "geometry": {
    "geometries": [
      {
        "coordinates": [
          [
            [-73.99225590000002,40.736458500000005],
            [-73.9920985,40.7366774],
            [-73.9920584,40.7366608],
            [-73.9919515,40.73681090000001],
            [-73.99188400000001,40.736904800000005],
            [-73.99187990000001,40.73691050000001],
            [-73.99171750000001,40.736843],
            [-73.99192270000002,40.7365574],
            [-73.99201619999998,40.736589300000006],
            [-73.9920758,40.7365075],
            [-73.9920182,40.7364972],
            [-73.9920491,40.73641580000001],
            [-73.99225590000002,40.736458500000005]
          ]
        ],
        "type": "Polygon"
      },
      {
        "coordinates": [-73.991993975,40.73665275833334],
        "type": "Point"
      }
    ],
    "type": "GeometryCollection"
  },
  "centroid": {
    "lon": -73.991993975,
    "lat": 40.73665275833334
  }
}

Consumer API

In order to use the Buildings Service and its APIs an application, client or user should be registered as a consumer using the Consumer API.

A consumer has a UUID (Universally unique identifier) which will need to be passed on every request along with an access token in order to validate data owenrship.

This API will only connect existing consumers to the Buildings service. In order to create a brand new consumer you should learn more about the Consumer Service (Not implemented yet).


Registering a consumer

POST /v1/consumers/

Request body

Attributes Description
consumerId String: Consumer UUID is required a long with authentication on header.

Headers

TODO: Describe authentication headers with accessToken attributes

Response

HTTP 201 Created

Removing a consumer

DELETE /v1/consumers/{consumerId}

Attributes Description
consumerId String: Consumer UUID is required a long with authentication on header.

Headers

TODO: Describe authentication headers with accessToken attributes

Response

HTTP 204 No Content

Get Buldings using the point-in-polygon filter

This API will find buildings using the coordinates system: [lon,lat].

It is possible to find more than one building that intersects the same POI since nested polygons could exists. That's why this API will always return a FeatureCollection.

GET /v1/buildings

Query String parameters

Attributes Description
point-in-polygon An Array with the format: [longitude,latitude].The order of values is important since it follows the GeoJSON standatd.
q A MongoDB compatible query represented as JSON object.

Headers

TODO: Describe authentication headers with consumerId and accessToken attributes

Response

HTTP 200 OK

Get buildings using the near filter

This API will find buildings using the coordinates system: [lon,lat].

The near API will return buildings on a FeatureCollection sorted by distance from the point passed in the query.

GET /v1/buildings

Query String parameters

Attributes Description
near An Array with the format: [longitude,latitude].The order of values is important since it follows the GeoJSON standatd.
max-distance Number : Max radius distance in meters
min-distance Number : Min radius distance in meters
unit String : mi, miles, km, kilometers, m, meters
q Object : JSON MongoDB compatible query

Headers

TODO: Describe authentication headers with consumerId and accessToken attributes

Response

HTTP 200 OK

Note implemented yet.

Create a POI/Building relationship

The Consumer is responsible to create, update and delete relationships with buildings. It should execute the right requests at the right moment.

For example, to create a relationship a consumer could execute the following request to an async worker after saving a POI:

POST /v1/pois/

Request body

Attributes Description
poiId The entity id to be associated with a building.
buildingId Can be used instead of location and it's faster. The id for the building to associate with the poidId.
location Can be used instead of buildingId. An Array with the format: [longitude,latitude]. The order of values is important since it follows the GeoJSON standatd. The API will find a buildingId using the point-in-polygon filter.

Headers

TODO: Describe authentication headers with consumerId and accessToken attributes

Response

HTTP 200 OK
{
  "updatedAt": "2016-09-14T23:56:58.526Z",
  "createdAt": "2016-09-14T23:56:58.526Z",
  "poiId": "5399a06c6d240bda68309cad",
  "buildingId": "57d41cb58a5f72bd70329b43",
  "consumerId": "500bed5c-95ba-424c-b646-d58d3d276780",
  "id": "57d9e3cab213a89587d1cd05"
}

If no building is found the request will return a 404 error.

HTTP 404 Not Found

Note implemented yet.

Updating a POI/Building relationship

If for some reason the location of the POI changes with new coordinates, then a PUT request can be made to find and update the Building ID.

PUT /v1/pois/{poiId}

Attributes Description
poiId The entity id associated with a building. Note that the PUT command will use the poiId in combination with the consumerId to find the right document. Do not use the id attribute.

Headers

TODO: Describe authentication headers with consumerId and accessToken attributes

Request body

Attributes Description
buildingId Can be used instead of location and it's faster. The id for the building to associate with the poidId.
location Can be passed instead of buildingId. An Array with the format: [longitude,latitude]. The order of values is important since it follows the GeoJSON standatd. The API will find a buildingId using the point-in-polygon filter.

Response

HTTP 200 OK
{
  "updatedAt": "2016-09-14T23:56:58.526Z",
  "createdAt": "2016-09-14T23:56:58.526Z",
  "poiId": "5399a06c6d240bda68309cad",
  "buildingId": "57d41cb58a5f72bd70329b43",
  "consumerId": "500bed5c-95ba-424c-b646-d58d3d276780",
  "id": "57d9e3cab213a89587d1cd05"
}

If no building is found the request will return a 404 error.

HTTP 404 Not Found

Note implemented yet.

Delete a POI/Building relationship

The Consumer is responsible for mantaining the relationships between POI and Building. If a POI is destrooyed a worker could execute the following request to clean the relationship on the buildings service.

DELETE /v1/pois/{poiId}

Attributes Description
poiId The entity id associated with a building. Note that the DELETE command will use the poiId in combination with the consumerId to find the right document. Do not use the id attribute.

Headers

TODO: Describe authentication headers with consumerId and accessToken attributes

Response

204 No Content

Note implemented yet.

Get Buldings from multiple POIs using the poi-ids filter

The Buildings API supports a scenario where we have a collection of POIs IDs and we want to retrieve the buildings for each one.

GET /v1/buildings

Query String parameters

Attributes Description
poi-ids list of Strings representing POI ids

Headers

TODO: Describe authentication headers with consumerId and accessToken attributes

How does this works on the backend?

The buildings service has a POI model that stores relationships between POIs and Buildings.

First, we query the POI collection to get all of the relevant building IDs:

const poiIds = JSON.parse(query.pois);
const consumerId = headers.consumerId;

Poi.find({
  poiId: { $in: poiIds.map((o) => mongoose.Types.ObjectId(o)) }
})
  .then((response) => {
    const buildingIds = response.map((o) => o.buildingId);
    return Building.find({ _id: { $in: buildingIds } });
  });

This will return an array with POI IDs and Building IDs:

This requires two queries to MongoDB making the request more complex and slower. But now the relationship is completly decoupled from the remote POI service.


Note implemented yet.

Get Building from a single POI id

We can always use the point-in-polygon parameter to find a Building from a [lon,lat] coordinate array. But what if we want to find the building of a POI already registerd with a relationship?

In that case we could use the endpoint above just passing one POI ID, or we could request direclty to the POIs endpoint.

This should make it a little faster since we're looking for a specific ID instead of a collection.

GET /v1/pois/{poiId}/buildings

Headers

TODO: Describe authentication headers with consumerId and accessToken attributes

How does this works on the backend?
const poiId = param.poiId;
const consumerId = headers.consumerId;

Poi.find({ poiId, consumerId })
  .then((response) => Building.find({ _id: response.buildingId }))

Note implemented yet.

Get all POI ids inside a Building

If we want to return all the POI IDs that exist inside of a Building, then we could pass the following request to the Building/POI endpoint.

NOTE: This will only return POI IDs frome the relationships previously created. Later, these IDs can be used by the consumer to query the right database.

GET /v1/buildings/{buildingId}/pois

Attributes Description
buildingId The id for the building to query the POIs

Headers

TODO: Describe authentication headers with consumerId and accessToken attributes

How it works on the backend

const buildingId = param.buildingId;
const consumerId = headers.consumerId;

Poi.find({ buildingId, consumerId });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment