openactive-archive / opportunity-api

Repository for the Opportunity API specification
0 stars 0 forks source link

Locations Endpoint #6

Open lukehesluke opened 6 years ago

lukehesluke commented 6 years ago

Proposer

IMIN LTD

Use Case

As a consumer of an Opportunity API, I would like to show users a map of location pins for where opportunities are happening

Ideally, I would need to have returned a list of distinct latitude/longitudes of opportunities as well as a count of opportunities in each of those locations

This information could then fill a collection of pins on a map

Why is this not covered by existing properties?

With just a sessions endpoint, a consumer would have to download all pages of data and do in-process grouping to get all the distinct locations

Please provide a link to example data

Proposal

An endpoint e.g. /locations with response like:

{
  "@context": [
    "https://www.openactive.io/ns/oa.jsonld",
  ],
  "id": "https://exampleapi.com/locations?location.geo[radial]=50.8,-1.6,30",
  "type": "Collection",
  "totalItems": 22,
  "item": [
    {
      type: "Place",
      "totalEvents": 8, /* i.e. how many events are at this location */
      name: null,
      address: {
        type: 'PostalAddress',
        streetAddress: 'Quayside Leisure Centre, TQ7 1HH',
        postalCode: 'TQ7 1HH',
        addressCountry: 'GB',
      },
      geo: {
        type: 'GeoCoordinates',
        latitude: 50.280404,
        longitude: -3.777604,
      },
      identifier: null,
      amenityFeature: [],
      potentialAction: [
        {
          type: 'SearchAction',
          target: 'https://exampleapi.com/sessions?location.geo[radial]=50.280404,-3.777604,0',
        },
        {
          type: 'TravelAction',
          distance: 164827,
          fromLocation: {
            type: 'Place',
            geo: {
              type: 'GeoCoordinates',
              latitude: 50.8,
              longitude: -1.6,
            },
          },
          toLocation: {
            type: 'Place',
            name: null,
            address: {
              type: 'PostalAddress',
              streetAddress: 'Quayside Leisure Centre, TQ7 1HH',
              postalCode: 'TQ7 1HH',
              addressCountry: 'GB',
            },
            geo: {
              type: 'GeoCoordinates',
              latitude: 50.280404,
              longitude: -3.777604,
            },
            identifier: null,
            amenityFeature: [],
          },
        },
      ],
    }
  ]
}

Notes on above data:

Example

lukehesluke commented 6 years ago

Simplification of first proposal:

{
  "@context": [
    "https://www.openactive.io/ns/oa.jsonld",
  ],
  "id": "https://exampleapi.com/locations?location.geo[radial]=50.8,-1.6,30",
  "type": "Collection",
  "totalItems": 22,
  "item": [
    {
      type: "Place",
      "id": "https://exampleapi.com/locations#!/50.280404/-3.777604",
      "ext:totalEvents": 8, /* i.e. how many events are at this location */
      name: null,
      address: {
        type: 'PostalAddress',
        streetAddress: 'Quayside Leisure Centre, TQ7 1HH',
        postalCode: 'TQ7 1HH',
        addressCountry: 'GB',
      },
      geo: {
        type: 'GeoCoordinates',
        latitude: 50.280404,
        longitude: -3.777604,
      },
      identifier: null,
      amenityFeature: [],
      potentialAction: [
        {
          type: 'SearchAction',
          target: 'https://exampleapi.com/sessions?location.geo[radial]=50.280404,-3.777604,0',
        },
        {
          type: 'TravelAction',
          distance: {
            "type": "QuantitativeValue",
            "value": 8,
            "unitCode": "KMT"
          },
          toLocation: "https://exampleapi.com/locations#!/50.280404/-3.777604",
        },
      ],
    }
  ]
}

Changes:

nickevansuk commented 6 years ago

Another option:

{
  "@context": [
    "https://www.openactive.io/ns/oa.jsonld",
  ],
  "id": "https://exampleapi.com/locations?location.geo[radial]=50.8,-1.6,30",
  "type": "Collection",
  "totalItems": 22,
  "item": [
    {
      "type": "CollectionAggregate",
      "totalItems": 8,
      "collection": "https://exampleapi.com/sessions?location.geo[radial]=50.280404,-3.777604,0",
      "aggregateItem": {
        "type": "Event",
        "location": {
          "type": "Place",
          "geo": {
            "type": "GeoCoordinates",
            "latitude": 50.8,
            "longitude": -1.6
          }
        }
      }
    }
  ]
}

Or..

{
  "@context": [
    "https://www.openactive.io/ns/oa.jsonld",
  ],
  "id": "https://exampleapi.com/locations?location.geo[radial]=50.8,-1.6,30",
  "type": "Collection",
  "totalItems": 22,
  "item": [
    {
      "type": "AggregateEvent",
      "event": {
        "type": "Collection",
        "id": "https://exampleapi.com/sessions?location.geo[radial]=50.280404,-3.777604,0",
        "totalItems": 8,
      },
      "location": {
        "type": "Place",
        "geo": {
          "type": "GeoCoordinates",
          "latitude": 50.8,
          "longitude": -1.6
        }
      }
    }
  ]
}
nickevansuk commented 6 years ago

Finally the following could work:

{
  "@context": [
    "https://www.openactive.io/ns/oa.jsonld",
  ],
  "id": "https://exampleapi.com/locations?location.geo[radial]=50.8,-1.6,30",
  "type": "Collection",
  "totalItems": 22,
  "item": [
    {
      type: "Place",
      "ext:event": {
        "type": "Collection",
        "id": "https://exampleapi.com/sessions?location.geo[radial]=50.280404,-3.777604,0",
        "totalItems": 8 /* i.e. how many events are at this location */
      },
      name: "Quayside Leisure Centre",
      address: {
        type: 'PostalAddress',
        streetAddress: '123 Walking Street',
        postalCode: 'TQ7 1HH',
        addressCountry: 'GB'
      },
      geo: {
        type: 'GeoCoordinates',
        latitude: 50.280404,
        longitude: -3.777604
      },
      potentialAction: [
        {
          "type": 'TravelAction',
          "distance": {
            "type": "QuantitativeValue",
            "value": 2.1,
            "unitCode": "KMT"
          }
        }
      ]
    }
  ]
}
lukehesluke commented 6 years ago

@nickevansuk this looks good to me

Particularly the substitution of event for a Collection of events is interesting