Was this helpful?
Using GraphQL, you can locations to your itinerary. Alpaca will organise the locations you add for itineraries into various structures, including a simple list through to something more complex (such as organised by segments etc).
You may also wish to review the following guides as starting points:
Locations added to an itinerary contain information for the audience such as the physical place they are visiting, as well as any personalised content or planning data about that location (such as stories/photos or supplying reasons to visit the place).
When we add locations to an itinerary, we will need to have the itinerary id
that we will be adding to.
When you want to add a location to your itinerary that does not have an
associated place provider, you can add the location directly to the itinerary.
In this case, you need to provide the title and longitude and latitude of the
location to the createItineraryLocation
mutation.
Here is an example of how you can add a location directly to an itinerary:
1mutation {
2 createItineraryLocation(
3 itineraryId: "itinerary/ABC123"
4 location: {
5 title: "Eiffel Tower"
6 synopsis: "An iconic place of interest"
7 place: { position: { lon: 2.2944, lat: 48.8584 } }
8 }
9 ) {
10 location {
11 id
12 }
13 }
14}
Sandbox: Configure | Try Operation
In the above example, we are adding the location "Eiffel Tower" to the itinerary
with the ID "itinerary/ABC123". The longitude and latitude of the location is
provided in the position
field of the place
object.
If the mutation is successful, the server will return the ID of the newly
created location, as seen in the location
field of the response.
1{
2 "data": {
3 "createItineraryLocation": {
4 "location": {
5 "__typename": "ItineraryLocation",
6 "id": "itinerary/ABC123/location/DEF456"
7 }
8 }
9 }
10}
Various information about the location can be stored against the location.
It is important to note that when adding a location directly, you will not have access to additional information about the location from a place provider. If you want to add a location with more information, you can use a place provider as described in the next subsection.
When adding a location to your itinerary, you have the option to associate the location with a place provider. This allows you to access additional information about the location, such as photos, ratings, contact information, addresses, website and social URL's or other information that is available from the place provider.
Alpaca supports a number of place providers, including OpenStreetMap/WikiData, GeoNames, OpenAddresses, Facebook, and Australian Tourism Data Warehouse. Each provider has their own unique identifier format for a place, so make sure to use the correct format when creating a location.
For example, to add a location to your itinerary and associate it with a place on Facebook, you can use the following mutation:
1mutation CreateItineraryLocationWithFacebookPlace {
2 createItineraryLocation(
3 itineraryId: "itinerary/ABC123"
4 location: {
5 title: "Visit Mavis The Grocer"
6 synopsis: "A great place to grab a breakfast and a coffee"
7 place: {
8 id: "place/facebook:page:mavisthegrocer"
9 position: { lon: 145.0043, lat: -37.8021 }
10 }
11 }
12 ) {
13 location {
14 __typename
15 id
16 }
17 }
18}
Sandbox: Configure | Try Operation
In this example, we are using the Facebook place ID
"place/facebook:page:mavisthegrocer" and providing a fallback position of
lon: 145.0043
, lat: -37.8021
. When querying the itinerary, the position from
the place provider will be used if available.
It's also worth noting that you can leave the place.id field empty, and instead you'll need to supply all the information about the place directly.
Using a place provider can be especially useful when you want to show additional information about the location, such as photos, ratings, or contact information, to your users. It also allows you to easily update the information about the location in case the place provider updates their data.
In addition to linking locations to places provided by external providers, you
may also want to store your own ID's against a location in your itinerary. To do
this, you can use the special custom attributes custom/external-ref
and
custom/external-source
.
The custom/external-ref
attribute accepts a string value, which should be a
unique identifier per record. The custom/external-source
attribute is used to
attribute the identifiers to a source. This attribute should be common across
all your locations and differentiate between different source locations you may
have.
Here's an example of creating an itinerary location with external references:
1mutation CreateItineraryLocationWithExternalReferences {
2 createItineraryLocation(
3 itineraryId: "itinerary/ABC123"
4 location: {
5 title: "Eiffel Tower"
6 place: { position: { lon: 2.2944, lat: 48.8584 } }
7 attrs: [
8 # Use the special custom attributes for linking to your identifiers
9 { id: "custom/external-ref", value: "12345" }
10 { id: "custom/external-source", value: "site" }
11 ]
12 # Other extended fields can be stored against a location
13 websiteUrl: "https://mywebsite.com/places/eiffel-tower"
14 }
15 ) {
16 location {
17 id
18
19 externalRef: attrValue(id: "custom/external-ref")
20 externalSource: attrValue(id: "custom/external-source")
21
22 websiteUrl
23 }
24 }
25}
Sandbox: Configure | Try Operation
With this example, the Alpaca platform will return the external reference ID's that you can then use to map your own place information outside of the Alpaca Travel GraphQL API call.
The Alpaca Data Structure enables a wide range of predefined fields for you to provide and store with your location. You can also store extended data outside of this set.
When adding an Itinerary Location to an itinerary, the createItineraryLocation
mutation supports specifying where you wish to add the location.
In order to control the position, the fields "positionAtStart", "positionAtEnd", "positionAfterSibling", "positionBeforeSibling" and "positionOnLastCollection" fields are provided for you to specify the desired position for the added location.
1mutation {
2 createItineraryLocation(
3 itineraryId: "itinerary/ABC123"
4 location: {
5 title: "Eiffel Tower"
6 place: { position: { lon: 2.2944, lat: 48.8584 } }
7 # Specify the desired position to add the location
8 positionAfterSibling: { siblingId: "itinerary/ABC123/location/DEF456" }
9 }
10 ) {
11 location {
12 id
13 }
14 }
15}
Sandbox: Configure | Try Operation
In the above query, the positionAfterSibling
property allows you to specify
the siblingId
to another existing location that you wish to insert the new
location positioned after.
Using the Alpaca GraphQL API, there are many different ways to query and
retrieve the locations of the itinerary. This is typically done using either the
node
or itinerary
query depending if you want to read back multiple
locations at once, or want to target a specific location node.
The below example shows how to use the node
query to retrieve a specific
location based on an id.
1query GetItineraryLocation {
2 # The node query can generally target any ID
3 node(id: "itinerary/ABC123/location/DEF456") {
4 id
5 __typename
6
7 ... on ItineraryLocation {
8 # We can query the itinerary location fields specifically
9 title
10 synopsis
11
12 # Access the position and any information relating to this position
13 position {
14 lon
15 lat
16 # Use position attributes to query information, available without
17 # a place provider (relies on lon/lat positions)
18 # Access the timezone at the coordinate
19 timezone: attrValue(id: "place/time-zone")
20 # Access the currency for the country
21 currency: attrValue(id: "place/country-currency")
22 # Further information, such as regions..
23 iso3166: attrValue(id: "place/iso-3166-2")
24 }
25
26 # Use any additional attributes you have stored, such as your own ID's
27 externalRef: attrValue(id: "custom/external-ref")
28
29 place {
30 # When using a place provider, information can be accessed here
31 id
32 name
33
34 address {
35 addressLineOne
36 locality
37 region
38 country
39 }
40
41 # Extended place attributes
42 phoneNumber: attrValue(id: "place/phone-number")
43 websiteUrl: attrValue(id: "place/website-url")
44 facebookUrl: attrValue(id: "place/facebook-url")
45 instagramUrl: attrValue(id: "place/instagram-url")
46 }
47 }
48 }
49}
Sandbox: Configure | Try Operation
When adding a location to an itinerary without using a place provider, you will not have access to additional information such as the place's name, address, photos, or reviews. However, you can still add additional information to the location by including position attributes, which provide additional information about the longitude/latitude pair, such as the country, timezone, region, or currency used. Additionally, when querying places within Australia, additional geographical information from ABS and Wine Australia are provided. This can be useful if you have your own place data and wish to map it to an itinerary location.
The Itinerary Location object provides predetermined fields for you to store your content and media associated with a location.
You can provide this content when you are initially creating the location using
the createItineraryLocation
mutation, or alternatively use the
updateItineraryLocation
mutation to provide or update these values later.
1mutation CreateItineraryLocationWithContent {
2 createItineraryLocation(
3 itineraryId: "itinerary/ABC123"
4 location: {
5 place: { position: { lon: 2.2944, lat: 48.8584 } }
6 # Various standard fields, see "CreateItineraryLocationInput" type
7 title: "Eiffel Tower"
8 synopsis: "A short summary for the location"
9 description: "Markdown formatted description for the location"
10 # Extended attributes
11 attrs: [
12 { id: "place/website-url", value: "https://www.toureiffel.paris/en" }
13 {
14 id: "place/facebook-url"
15 value: "https://www.facebook.com/EiffelTower.OfficialPage"
16 }
17 ]
18 }
19 ) {
20 location {
21 id
22 }
23 }
24}
Sandbox: Configure | Try Operation
You can also update values using the "updateItineraryLocation" mutation.
1mutation UpdateItineraryLocationWithContent {
2 updateItineraryLocation(
3 id: "itinerary/ABC123/location/DEF456"
4 location: {
5 # Various standard fields, see "UpdateItineraryLocationInput" type
6 title: "Eiffel Tower"
7 synopsis: "A short summary for the location"
8 description: "Markdown formatted description for the location"
9 # Extended attributes
10 upsertAttrs: [
11 { id: "place/website-url", value: "https://www.toureiffel.paris/en" }
12 {
13 id: "place/facebook-url"
14 value: "https://www.facebook.com/EiffelTower.OfficialPage"
15 }
16 ]
17 # You can remove values using the deleteAttrs
18 # example value: [{ id: "place/website-url" }]
19 deleteAttrs: []
20 }
21 ) {
22 location {
23 id
24 }
25 }
26}
Sandbox: Configure | Try Operation
The description field is formatted using basic markdown formatting.
You can also assign place attributes to the attributes within the location. You can not specifically assign the attributes to the place object, as the place object represents the dynamically references values from place providers, even if you are not using them.
Attribute | Description |
---|---|
place/address | The address object to use for the place ("addressLineOne", "locality", "region", "country", etc) |
place/phone-number | The phone number to use for the place |
place/website-url | The website URL to use for the place |
place/booking-url | The booking URL to use for the place |
place/facebook-url | The facebook URL to use for the place |
place/instagram-url | The instagram URL to use for the place |
place/opening-hours | The opening hours of the place, stored in OSM Opening Hours format (See Accessing hours) |
Once you have added locations to your list, you may want to check if a particular place is already present in the list before adding it again. This can be useful for creating a "Add to List" button with different states, such as "Added" or "Remove" depending on whether the place is already present in the list.
The following GraphQL query can be used to check if a place is present in a list:
1query CheckItineraryPlacePresent {
2 itinerary(id: "itinerary/ABC123") {
3 descendants(placeIds: ["place/123"], first: 1) {
4 nodes {
5 id
6 }
7 totalCount
8 }
9 }
10}
Sandbox: Configure | Try Operation
The itinerary
query is used, supplying the id
of the list to check. The
descendants
field is then queried, providing the placeIds
to check and the
first
parameter, which limits the number of returned results to 1.
In the response, the nodes
field will contain an array of itinerary location
objects, each representing a location in the list that matches the provided
placeIds
. The id
field of each itinerary location object can be used to
refer to the location in future operations. The totalCount
field will indicate
the total number of matching locations in the list, which can be used to check
if the place is already present in the list.
Example response:
1{
2 "data": {
3 "itinerary": {
4 "descendants": {
5 "nodes": [
6 {
7 "id": "itineraryLocation/123"
8 }
9 ],
10 "totalCount": 1
11 }
12 }
13 }
14}
If the place is already present in the list, the totalCount field will be greater than 0.
The Location can also contain other positions that can assist with presenting the location to the user.
For instance, for a place, your place provider may provide a position in order to draw a pin or draw a label. This position is not the location we wish to send the user to when actually visiting this location physically.
Further to the example, you may also wish to have the user first navigate to a position such as a car park or entry gates.
This leads to the possibility of many different positions being used to describe the location being added.
You can assign a preferred position using the location.position
or add an
attribute to the location with the ID of
itinerary/location/directions-position-preference
We also support the use custom data to contain further positions that you wish to store and leverage in you use case.
A specific topic exists to assist you with reordering locations.
1# Removes an itinerary item, such as a location
2
3mutation DeleteItineraryLocation {
4 # Use the deleteItineraryItem operation to remove an itinerary location
5 deleteItineraryItem(
6 # Supply your ID of the itinerary location to remove (no undo)
7 id: "itinerary/ABC123/item/DEF456"
8 ) {
9 # Select back the ID of the itinerary location that was removed
10 id
11 }
12}
Sandbox: Configure | Try Operation
Copyright © 2024 - Made with love ❤️ in Australia.