API tutorial: Difference between revisions
(16 intermediate revisions by 3 users not shown) | |||
Line 8: | Line 8: | ||
==Introduction to the API== | ==Introduction to the API== | ||
The {{software}} offers access via an API, allowing for external applications to interact with and use the {{software}}. The API is an integral part of the functioning of the {{software}}, in that the default client | The {{software|server}} offers access via an API, allowing for external applications to interact with and use the {{software|server}}. The API is an integral part of the functioning of the {{software}}, in that the default {{software|client}} app uses it as well. This means the API can allow you to do anything that the {{software|client}} app allows you to do as well. | ||
The API can be used to: | The API can be used to: | ||
Line 14: | Line 14: | ||
* Automate menial and complex tasks | * Automate menial and complex tasks | ||
* Integrate the output of external applications in projects and sessions automatically | * Integrate the output of external applications in projects and sessions automatically | ||
* Integrate the {{software}} with an existing process chain | * Integrate the {{software|server}} with an existing process chain | ||
Overall, the API is split into two separate sections, a root API and a session API. The root API is for access to the {{software}} in general, and can be used to access user information or domain information, start and save projects, and manage access rights. The session API is for interactions with a specific session, modifying the data in it, or | Overall, the API is split into two separate sections, a root API and a session API. The root API is for access to the {{software|server}} in general, and can be used to access user information or domain information, start and save projects, and manage access rights. The session API is for interactions with a specific session, modifying the data in it, or obtaining results as calculated in the Session. | ||
The API can be accessed via a web browser, allowing for easy inspection of the data and options. | The API can be accessed via a web browser, allowing for easy inspection of the data and options. | ||
{{page_break}} | {{page_break}} | ||
==Session API== | ==Session API== | ||
Start a project in the editor. In the | Start a project in the editor. In the [[Tools]] ribbon tab, click on the [[API Overview]]. | ||
Notice in the address bar the generic end-point ("/api/"), and the end-point indicating to connect to a specific session ("/session/"). Also notice the "token" parameter, which is an alphanumerical string which serves as authentication to the API options of this specific session. Specifically, this is called an API token. | Notice in the address bar the generic end-point ("/api/"), and the end-point indicating to connect to a specific session ("/session/"). Also notice the "token" parameter, which is an alphanumerical string which serves as authentication to the API options of this specific session. Specifically, this is called an API token. | ||
Line 37: | Line 38: | ||
The session API allows for the inspection of data in a project. This data can be found in the "Content items" listing. | The session API allows for the inspection of data in a project. This data can be found in the "Content items" listing. | ||
* In the editor, select a neighborhood | * In the editor, select a neighborhood | ||
* In the web browser with the API opened, go to the "Content items" listing. Find the "Neighborhoods", and then the neighborhood selected in the editor. | * In the web browser with the API opened, go to the "Content items" listing. Find the "Neighborhoods", and then the [[neighborhood]] selected in the editor. | ||
* Take note of the data in the neighborhood item matching the data displayed in the editor. | * Take note of the data in the neighborhood item matching the data displayed in the editor. | ||
* In the editor, change the name of the neighborhood | * In the editor, change the name of the neighborhood | ||
Line 73: | Line 74: | ||
Go to the list of neighborhoods, and select the JSON format. | Go to the list of neighborhoods, and select the JSON format. | ||
Notice the list of all neighborhoods is now in | Notice the list of all neighborhoods is now in [[GeoJSON]] format, without any HTML layout or styling. This is the format which can most easily be processed by your own code. | ||
{{page_break}} | {{page_break}} | ||
Line 214: | Line 215: | ||
{{page_break}} | {{page_break}} | ||
===Requesting updated data=== | ===Requesting updated data=== | ||
Besides actively requesting information, and interacting with a project yourself, it can also be important to be able to recognize when the session is affected by others. This can include: | Besides actively requesting information, and interacting with a project [[session]] yourself, it can also be important to be able to recognize when the session is affected by others. This can include: | ||
* The completion of a calculation running on the server | * The completion of a calculation running on the server | ||
* Another user modifying data in a session, either by editing or as an in-session action. | * Another user modifying data in a session, either by editing or as an in-session action. | ||
Line 329: | Line 330: | ||
{{page_break}} | {{page_break}} | ||
==Root API== | ==Root API== | ||
Some basic facts to remember concerning the root API: | Some basic facts to remember concerning the root API: | ||
Line 345: | Line 347: | ||
Switch to the JSON format. Note that more information is available. | Switch to the JSON format. Note that more information is available. | ||
Just like with the session API, the root API allows you to fire events as instruction to the {{software}}. Go back to the "/api/", and go to "Fire Service Event". Next, select "IO" (which stands for "IO Service Events"). | Just like with the session API, the root API allows you to fire events as instruction to the {{software|server}}. Go back to the "/api/", and go to "Fire Service Event". Next, select "IO" (which stands for "IO Service Events"). | ||
Select the event "GET_DOMAIN_STARTABLE_PROJECTS". Enter the name of your domain, and fire the event. The response will be a list of all projects which can be started by your user in your domain. | Select the event "GET_DOMAIN_STARTABLE_PROJECTS". Enter the name of your domain, and fire the event. The response will be a list of all projects which can be started by your user in your domain. | ||
Line 377: | Line 379: | ||
* $USERNAME: your username | * $USERNAME: your username | ||
* $KEY: the login key retrieved earlier | * $KEY: the login key retrieved earlier | ||
* $PROJECT: the filename of the project you wish to start | * $PROJECT: the filename of the project you wish to start. | ||
{{code|1=var USERNAME = $USERNAME; | {{code|1=var USERNAME = $USERNAME; | ||
var PASSWORD = $KEY; | var PASSWORD = $KEY; | ||
Line 485: | Line 487: | ||
First, the project must be created. | First, the project must be created. | ||
{{code|1=var USERNAME = $USERNAME; | {{code|1=var USERNAME = $USERNAME; | ||
var PASSWORD = $ | var PASSWORD = $KEY; | ||
var PROJECT_NAME = $PROJECT_NAME; | var PROJECT_NAME = $PROJECT_NAME; | ||
var PROJECT_LANGUAGE = $PROJECT_LANGUAGE; | var PROJECT_LANGUAGE = $PROJECT_LANGUAGE; | ||
Line 527: | Line 529: | ||
{{page_break}} | {{page_break}} | ||
====Setting location==== | ====Setting location==== | ||
Next, a location can be set for the project. | Next, a location can be set for the project. | ||
Line 638: | Line 641: | ||
To save your project, run the following code: | To save your project, run the following code: | ||
{{code|1=var USERNAME = $USERNAME; | {{code|1=var USERNAME = $USERNAME; | ||
var PASSWORD = $ | var PASSWORD = $KEY; | ||
var SESSION_ID = $SESSION_ID; | var SESSION_ID = $SESSION_ID; | ||
$.ajax({ | $.ajax({ | ||
Line 655: | Line 658: | ||
It is also possible to "save as" the project. This will create a copy of the project based on the current state of the session. To do so, run the following code: | It is also possible to "save as" the project. This will create a copy of the project based on the current state of the session. To do so, run the following code: | ||
{{code|1=var USERNAME = $USERNAME; | {{code|1=var USERNAME = $USERNAME; | ||
var PASSWORD = $ | var PASSWORD = $KEY; | ||
var DOMAIN = $DOMAIN; | var DOMAIN = $DOMAIN; | ||
var SESSION_ID = $SESSION_ID; | var SESSION_ID = $SESSION_ID; | ||
Line 683: | Line 686: | ||
To do so, start the project which you want to use as a template. After the project has started, "save as" it, but with the final parameter set to "false". To do so, run the following code: | To do so, start the project which you want to use as a template. After the project has started, "save as" it, but with the final parameter set to "false". To do so, run the following code: | ||
{{code|1=var USERNAME = $USERNAME; | {{code|1=var USERNAME = $USERNAME; | ||
var PASSWORD = $ | var PASSWORD = $KEY; | ||
var DOMAIN = $DOMAIN; | var DOMAIN = $DOMAIN; | ||
var SESSION_ID = $SESSION_ID; | var SESSION_ID = $SESSION_ID; | ||
Line 884: | Line 887: | ||
All tasks can be performed via the API. However, for some tasks the appropriate events and their parameters may not be directly apparent. | All tasks can be performed via the API. However, for some tasks the appropriate events and their parameters may not be directly apparent. | ||
As a general rule of thumb, to perform any task via the API, it can be beneficial to perform the task in the client of the {{software}} first, and take note of the kind of steps taken to complete the full task. | As a general rule of thumb, to perform any task via the API, it can be beneficial to perform the task in the {{software|client}} of the {{software}} first, and take note of the kind of steps taken to complete the full task. | ||
===Use GeoTIFF as heightmap=== | ===Use GeoTIFF as heightmap=== | ||
To base the heightmap on a GeoTIFF, first a GeoTIFF must be uploaded. | To base the heightmap on a [[GeoTIFF]], first a GeoTIFF must be uploaded. | ||
After uploading the GeoTIFF, the map must be modified based on the GeoTIFF. | After uploading the GeoTIFF, the map must be modified based on the GeoTIFF. | ||
Line 901: | Line 904: | ||
}} | }} | ||
Applying the GeoTIFF to the heightmap is a singular action. When doing so, the GeoTIFF as it is in that moment is used to redraw the heightmap. After this action is completed, there is no explicit link between the height map and the GeoTIFF. This means that if or when the GeoTIFF is updated afterwards, the heightmap does not "follow" that same modification automatically. The event should be used again to update the heightmap to the new state of the GeoTIFF, if it is so desired. | Applying the [[GeoTIFF]] to the heightmap is a singular action. When doing so, the GeoTIFF as it is in that moment is used to redraw the heightmap. After this action is completed, there is no explicit link between the height map and the GeoTIFF. This means that if or when the GeoTIFF is updated afterwards, the heightmap does not "follow" that same modification automatically. The event should be used again to update the heightmap to the new state of the GeoTIFF, if it is so desired. | ||
{{page break}} | {{page break}} | ||
Latest revision as of 15:55, 2 March 2023
Prerequisites
The following prerequisites should be met before starting this tutorial:
- This tutorial can be followed with any project of any arbitrary location. Note that minor changes will be made to the project during this tutorial. Also note that during this tutorial an additional project will be created.
- You will need an IDE or environment in which to edit simple web-calls and inspect the results. For example: Firefox's or Chrome's developer tools (used in this tutorial).
Preparations
Take the following steps as preparation for following this tutorial:
- Start your project. This can be a pre-existing project, or a newly created project.
- Start your preferred internet browser.
Introduction to the API
The Tygron Engine offers access via an API, allowing for external applications to interact with and use the Tygron Engine. The API is an integral part of the functioning of the Tygron Platform, in that the default Tygron Client app uses it as well. This means the API can allow you to do anything that the Tygron Client app allows you to do as well.
The API can be used to:
- Inspect data in a session in greater detail
- Automate menial and complex tasks
- Integrate the output of external applications in projects and sessions automatically
- Integrate the Tygron Engine with an existing process chain
Overall, the API is split into two separate sections, a root API and a session API. The root API is for access to the Tygron Engine in general, and can be used to access user information or domain information, start and save projects, and manage access rights. The session API is for interactions with a specific session, modifying the data in it, or obtaining results as calculated in the Session.
The API can be accessed via a web browser, allowing for easy inspection of the data and options.
Session API
Start a project in the editor. In the Tools ribbon tab, click on the API Overview.
Notice in the address bar the generic end-point ("/api/"), and the end-point indicating to connect to a specific session ("/session/"). Also notice the "token" parameter, which is an alphanumerical string which serves as authentication to the API options of this specific session. Specifically, this is called an API token.
Some basic facts to remember concerning the session API:
- Accessible from the editor.
- Opens in (and is accessible via) the browser.
- No log-in credentials required.
- Authentication token required instead, specifically an API token.
- Different session of the same project have different API tokens.
Inspecting data
The session API allows for the inspection of data in a project. This data can be found in the "Content items" listing.
- In the editor, select a neighborhood
- In the web browser with the API opened, go to the "Content items" listing. Find the "Neighborhoods", and then the neighborhood selected in the editor.
- Take note of the data in the neighborhood item matching the data displayed in the editor.
- In the editor, change the name of the neighborhood
- In the web browser with the API opened, refresh the page and notice the name has changed
Try the same thing by adding an attribute to the neighborhood and editing it.
Affecting data
The session API allows for interaction with the session as well. This can be done via "Events".
Events are divided between session events and editor events. This mirrors the division between the modifications you can make in the editor, and which actions you can take as a participant.
- In the web browser with the API opened, go to EditorArea events
- Go to "ADD"
- Fire event
- Notice the response. The response is the newly created area's ID.
- Go to EditorArea events again
- Go to "SET_ATTRIBUTE"
- This event requires parameters.
- Enter as parameters:
- The ID returned by the ADD event, to indicate the area you wish to modify
- The name of the attribute you wish to add. For example: "FOO"
- The value the attribute should have. For example: "3"
- Fire event
- Notice the response is an http status code (204). The call has been received successfully, but the event does not return any data.
- In the editor, notice that the area has been given an attribute, with the name and the value you've provided.
Try performing similar actions with panels by creating a text panel and modifying its content.
HTML and JSON
By default, the web browser offers an HTML representation of the data and of the responses given by requests. However, on most pages you will also find a block offering multiple format types.
Go to the list of neighborhoods, and select the JSON format.
Notice the list of all neighborhoods is now in GeoJSON format, without any HTML layout or styling. This is the format which can most easily be processed by your own code.
Calls and responses
From the browser view of the API, copy the API token (the "token" parameter in the address bar). In all code examples, use that token in place of "$TOKEN".
In the editor, go to any panel (adding one, if none exist yet). Open the panel in the web browser by selecting "Open in Web Browser".
(The web browser view of the panel has a built-in JQuery library, which makes defining http calls easy. This makes it a good environment for some basic experimentation.)
Note that the token used to display the panel in the web browser is different from the API token. This is because access to the API allows a user to perform many actions which a potential end-user of a session should not be allowed to do. For all code examples here, we use the API token.
Open the browser's developer tools. This should include both a javascript console, and a network communication overview. The console will allow you to run code on-the-fly, and the network communication overview will allow you to inspect the exact structure of the calls sent and the replies received.
In the developer tools console, run the following code.
var token='$TOKEN'; $.ajax({ url:'/api/session/items/areas/?f=JSON&token='+token, method: "GET" });
(Note that the url stated is relative. The full url would be to the effect of "https://engine.tygron.com/api/session/items/areas/?f=JSON&token=$TOKEN".)
The following is important to note about this call:
- To request information, the used method is "GET".
- The token is sent as part of the url query parameters ("token=..."). It is also possible to send the token as a header ("token").
- The format requested ("f=...") is "JSON". This means the response of the call will be in JSON format.
Inspect the returned data: a JSON structure of all the areas in the project.
[ { "array" : null, "attributes" : { "ACTIVE" : [ 1.0 ], "COLOR" : [ -5517969.0 ], "FOO" : [ 3.0 ] }, "center" : null, "id" : 0, "maquetteOverride" : null, "name" : "Area", "polygons" : { "type" : "MultiPolygon", "coordinates" : [ ] }, "relations" : { }, "sourceIDs" : [ 1000000 ], "version" : 10 } ]
Run the following code:
var token='$TOKEN'; $.ajax({ url:'/api/session/event/editorarea/add/?token='+token, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([]) });
(Note again that the url stated is relative. The full url would be to the effect of "https://engine.tygron.com/api/session/event/editorarea/add/?token=$TOKEN".)
The following is important to note about this call:
- To fire an event (i.e. giving an instruction), the used method is "POST".
- The token is sent as part of the url query parameters ("token=..."). It is also possible to send the token as a header ("ServerToken").
Make note of the response of the call, the ID of the added area.
Notice in the editor a new area is added.
Run the following code, with "$ID" replaced by the response of the previous call.
var token='$TOKEN'; $.ajax({ url:'/api/session/event/editorarea/set_attribute/?token='+token, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([$ID, "FOO", 12345]) });
The following is important to note about this call:
- To fire an event (i.e. giving an instruction), the used method is "POST".
- The token is sent as part of the url query parameters ("token=..."). It is also possible to send the token as a header ("ServerToken").
- The "Content-Type" header (specified by the "contentType" parameter) and the data sent to the API must be (and specify) a JSON format.
Finally, run the following code:
var token='$TOKEN'; $.ajax({ url:'/api/session/items/areas/?f=JSON', headers: { 'token':token, }, method: "GET" });
(Note that this is the same call as the first GET call in this section, but that the token is sent as a header, rather than as a query parameters. This is purely for illustration purposes and is functionally identical.)
Notice a new area is added to the data structure, with the attribute specified in the set_attribute event.
[ { "array" : null, "attributes" : { "ACTIVE" : [ 1.0 ], "COLOR" : [ -5517969.0 ], "FOO" : [ 3.0 ] }, "center" : null, "id" : 0, "maquetteOverride" : null, "name" : "Area", "polygons" : { "type" : "MultiPolygon", "coordinates" : [ ] }, "relations" : { }, "sourceIDs" : [ 1000000 ], "version" : 10 }, { "array" : null, "attributes" : { "ACTIVE" : [ 1.0 ], "COLOR" : [ -1484304.0 ], "FOO" : [ 12345.0 ] }, "center" : null, "id" : 3, "maquetteOverride" : null, "name" : "Area (2)", "polygons" : { "type" : "MultiPolygon", "coordinates" : [ ] }, "relations" : { }, "sourceIDs" : [ ], "version" : 23 } ]
Requesting updated data
Besides actively requesting information, and interacting with a project session yourself, it can also be important to be able to recognize when the session is affected by others. This can include:
- The completion of a calculation running on the server
- Another user modifying data in a session, either by editing or as an in-session action.
Requesting updates manually
For any given call, it is possible to add a "version=..." query parameter to the request. This parameter is used to indicate what the most recent data is which your application currently has. All data requested from a session is accompanied by a "version" property, which indicates in which iteration of the data that particular item was last modified. If the server is aware of an item which has a higher version number (i.e. data which is more reason than what is indicated in the request) only the newer data which has changed since the provided version will be sent. If the version parameter is omitted from the request, all data is sent.
Run the following code:
var token='$TOKEN'; $.ajax({ url:'/api/session/items/areas/version?f=JSON&token='+token, method: "GET" });
The returned value is the current version of the "areas" data. Take note of the current version number.
Run the following code:
var token='$TOKEN'; $.ajax({ url:'/api/session/event/editorarea/add/?token='+token, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([]) });
Now, a new area is added to the project.
Run the following code:
var token='$TOKEN'; $.ajax({ url:'/api/session/items/areas/?f=JSON&token='+token, method: "GET" });
The returned data structure will feature all areas present in the project.
Run the following code, with "$VERSION" replaced by the response of the call in which the version number was requested.
var token='$TOKEN'; var version='$VERSION'; $.ajax({ url:'/api/session/items/areas/?f=JSON&version='+version+'&token='+token, method: "GET" });
The returned data structure now only features the area added since the version indicated.
Note that this syntax only allows new and updated items to be sent. Items which have been removed from the project since the provided version are not included in the response.
Requesting updates automatically
Besides manually requesting specific data, the server also offers the ability to request an update of data in a single request, via the "/update/" endpoint.
Run the following code, with "$VERSION" replaced by the response of the call in which the version number was requested.
var token='$TOKEN'; var version='$VERSION'; $.ajax({ url:'/api/session/update/?token='+token, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify({ "AREAS" : version }) });
The response will be a data structure similar to the following:
{ "deletes" : { "AREAS" : [ { "id" : 8, "version" : 30 } ] }, "items" : { "AREAS" : [ { "array" : null, "attributes" : { "ACTIVE" : [ 1.0 ], "COLOR" : [ -1.5765646E7 ] }, "center" : null, "id" : 9, "maquetteOverride" : null, "name" : "Area (4)", "polygons" : { "type" : "MultiPolygon", "coordinates" : [ ] }, "relations" : { }, "sourceIDs" : [ 1000000 ], "version" : 29 } ] }, "timeStamp" : 1557319226438 }
The datastructure features a property "items" in which per item type all new and updated data is returned. There is also a "deleted" property, which is an explicit listing of all the items which have been removed (and in which version). Finally, the "timeStamp" allows for synchronizing with the server.
Try for yourself to add, edit, and delete a number of areas. You can do this in the editor, via the API overview in the web browser, or by running code. Somewhere along the way be sure to request a version number again. Then make a request to the "/update/" endpoint, and inspect the results.
Miscellaneous session options
Additional options can accessed and explored in a similar fashion.
- Session info
- The session API offers some general information about the currently running session. This allows an arbitrary user or application with access to the API to determine the kind of session it in.
- World map location
- The session API also provides general information about the location where the project is located. This includes information on the extend of the map.
- TQL Query
- The session API allows for the execution of TQL queries. TQL queries can be sent as a single parameter, which will result in a simple text response. TQL update statements can also be accompanied by a value, allowing for updates as well.
- Overlay Web Services
- The session API also advertised direct access to the Overlay Web Services endpoint. This endpoint offers access to images generated by overlays part of the project. For each request, any number of parameters can be added to the requested image to determine sizes, bounds, and other configurations.
Root API
Some basic facts to remember concerning the root API:
- Is accessible via the browser.
- Log-in credentials required
- Authentication occurs via HTTP Basic Access Authentication.
Accessing the root API can be done in your web browser by navigating to https://engine.tygron.com/api/.
You will be prompted to log in using your Tygron Platform account.
The root API provides access to a number of data structures regarding your user and your domain.
Select "My user", and see that some basic information about your account is displayed.
Switch to the JSON format. Note that more information is available.
Just like with the session API, the root API allows you to fire events as instruction to the Tygron Engine. Go back to the "/api/", and go to "Fire Service Event". Next, select "IO" (which stands for "IO Service Events").
Select the event "GET_DOMAIN_STARTABLE_PROJECTS". Enter the name of your domain, and fire the event. The response will be a list of all projects which can be started by your user in your domain.
Go back to the event "GET_DOMAIN_STARTABLE_PROJECTS". Enter the name of your domain, and select the "JSON" format. Now fire the event. The response will be a list of all projects which can be started by your user in your domain, in JSON format.
Authenticating via login key
Just like with the session API, it is possible to fire the event programmatically as well. However, because login credentials are required while interacting with the root API, this would mean both a username and password must be part the code written here. Instead, it is possible to request a login key for your user, an alphanumeric string which can be used in place of your actual password.
Go to https://engine.tygron.com/api/event/user/get_my_login_key/, and fire the event. Take note of the result.
Now, run the following code, with "$USERNAME" replaced by your username, and "$KEY" replaced by the login key from the last event's result:
var USERNAME = $USERNAME; var PASSWORD = $KEY; $.ajax({ url:'/api/event/user/get_my_user/?f=JSON', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST" });
Note the space after the term "Basic". Omitting it will cause authentication to fail.
The returned data is information on your own user, in JSON format.
Sessions
To start a new session based on an existing project, run the following code with the following replacements:
- $USERNAME: your username
- $KEY: the login key retrieved earlier
- $PROJECT: the filename of the project you wish to start.
var USERNAME = $USERNAME; var PASSWORD = $KEY; var PROJECT_TO_START = $PROJECT; $.ajax({ url:'/api/event/io/start/', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify(['EDITOR', PROJECT_TO_START]) });
Notice that the server takes a few seconds to respond, and then responds with a session ID. This means a new session has started on the server. Specifically, the project has started as a session in the editor.
Take note of the session ID.
To formally join a session (which is also required if you or your code have originally started the session), run the following code with the following replacements:
- $USERNAME: your username
- $KEY: the login key retrieved earlier
- $SESSION_ID: the session ID retrieved earlier
var USERNAME = $USERNAME; var PASSWORD = $KEY; var SESSION_ID = $SESSION_ID; $.ajax({ url:'/api/event/io/join/', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([SESSION_ID, 'EDITOR', 'Tutorial-Code']) });
The response is a data structure which includes the following:
- The API token with which to authenticate against the session.
- A clientToken which can be sent in a "clientToken" header along with POST requests, to keep the session alive.
- A list of all data which exists in the session
Take note of the client token.
With this response, it is possible to construct the API url to access the session itself.
When interaction with a session has concluded, it is recommended to properly remove yourself from the session. Run the following code with the following replacements:
- $USERNAME: your username
- $KEY: the login key retrieved earlier
- $SESSION_ID: the session ID retrieved earlier
- $CLIENT_TOKEN: the client token retrieved earlier
var USERNAME = $USERNAME; var PASSWORD = $KEY; var SESSION_ID = $SESSION_ID; var CLIENT_TOKEN = $CLIENT_TOKEN; $.ajax({ url:'/api/event/io/close/', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([SESSION_ID, CLIENT_TOKEN, false]) });
Now, your client is no longer connected to the session.
The last parameter provided in the "close" event indicates whether the session should keep running (if your application was the last connected client. If there are other clients still connected to the session, the session is not closed by your application leaving.)
Depending on the access rights of the account used to fire these events, it is also possible to explicitly "kill" a session. This would attempt to stop the session immediately, and forcefully remove all connected clients. If you start a new session, you can try it yourself by running the following code:
- $USERNAME: your username
- $KEY: the login key retrieved earlier
- $SESSION_ID: the session ID of the session
var USERNAME = $USERNAME; var PASSWORD = $KEY; var SESSION_ID = $SESSION_ID; $.ajax({ url:'/api/event/io/kill/', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([SESSION_ID]) });
Note that if you use an account that does not have DOMAIN_ADMIN rights to fire this event, you will get an authorization error. This is to be expected, as only DOMAIN_ADMIN users can kill sessions.
Common API tasks
There are a few basic procedures which can commonly occur in automated processes, but which require some additional attention.
Project creation
Project creation is relatively straightforward, but takes a number of steps.
Note: The steps in this chapter will trigger the creation of a new project. This will be counted in your license's allowance for the creation of new projects. If this is undesirable, you can skip the code-running steps in this chapter.
Creating a new project
First, the project must be created.
var USERNAME = $USERNAME; var PASSWORD = $KEY; var PROJECT_NAME = $PROJECT_NAME; var PROJECT_LANGUAGE = $PROJECT_LANGUAGE; $.ajax({ url:'/api/event/io/add_project/', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([PROJECT_NAME, PROJECT_LANGUAGE]) });
Data is returned on the created project. Of special note is the filename, which is required to start the project.
{ "activeVersion" : 0, "deleteDate" : null, "description" : "", "domain" : $DOMAIN, "fileName" : $FILENAME, "languages" : [ "EN" ], "lastActivity" : null, "lastUser" : null, "owner" : $USERNAME, "permissions" : [ "WRITE", "NONE", "NONE" ], "restoreDate" : null, "sizeM" : [ 0, 0 ], "subDomain" : "All Sub Domains", "template" : false, "universal" : false, "versionMap" : { "0" : "Base Version" }, "versions" : [ "Base Version" ] }
When the project is created, the project can be started and joined as demonstrated before.
Setting location
Next, a location can be set for the project.
var token='$TOKEN'; var WIDTH = $WIDTH; var HEIGHT = $HEIGHT; $.ajax({ url:'/api/session/event/editor/set_initial_map_size/?token='+token, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([WIDTH, HEIGHT]) });
This will set the size of the project area to the specified width and height. This can only be done once. When the map size has already been set it cannot be changed.
Starting project generation
The actual process of project generation can be started with the following event, which must be provided with the coordinates of the project area. The coordinates must be in EPSG:3857 Pseudo-Mercator. For example, the longitude 480133.86118372413 and latitude 6815187.212438513 specify a location in The Hague in the Netherlands.
var token='$TOKEN'; var LONGITUDE = $LONGITUDE; var LATITUDE = $LATITUDE; $.ajax({ url:'/api/session/event/editor/start_map_creation/?token='+token, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([LONGITUDE, LATITUDE]) });
The response will not contain any content, but the project creation process will have been set in motion.
The server will now be busy for a while generating the project area based on the data sources applicable for the selected area. While the project is generating, its progress can be followed via the Progress data items.
Run the following code while the project generation process is running:
var token='$TOKEN'; $.ajax({ url:'/api/session/items/progress/?f=JSON&token='+token, method: "GET" });
The response will be a JSON structure, in which each element represents the progress made with downloading the data of a specific source. Depending on the location and the settings of the project, the amount of items can vary, but in general it will be structured as follows:
[ { "failText" : "", "featureCount" : 12, "iconName" : "satellite.gif", "id" : 0, "name" : "Satellite Background", "progress" : 0.6923076923076923, "source" : "Esri", "version" : 75 }, { "failText" : "", "featureCount" : 12, "iconName" : "terrain.gif", "id" : 1, "name" : "Terrain Elevation", "progress" : 1.0, "source" : "Esri", "version" : 60 }, { "failText" : "", "featureCount" : 0, "iconName" : null, "id" : 15, "name" : "Finalizing (validating data integrity)", "progress" : 1.0, "source" : null, "version" : 324 } ]
The "progress" property of each item indicates how far along the download of data from that particular source is. When the progress for all data sources is "1.0", all data has been downloaded and the project is ready for use.
Note the "failText" property. If an error occurs with the download from any data source, this property will contain (as human-readable text) information on the error that has occurred.
Also note that the Progress is transient, meaning this data is not stored along with the project. It only exists in a session after the map generation proces has run, and will be deleted once the session is closed, regardless of whether the resulting project is saved or not.
You can also check the current state of the session, via the Settings data items. Run the following code to see the session's current state:
var token='$TOKEN'; $.ajax({ url:'/api/session/items/settings/STATE/value/?f=JSON&token='+token, method: "GET" });
When the response is "GEO_WIZARD", the session is in the process of generating the map. When the response is "NORMAL", the session is ready for editing.
Project with empty map
It is also possible to create a project, which is not based on a real-life location. In these cases, you still need to set the map size. Next, instead of setting coordinates and starting the generation proces, the following event can be used to allow editing of the project:
var token='$TOKEN'; $.ajax({ url:'/api/session/event/editorsetting/wizard_finished/?token='+token, method: "POST", contentType: "application/json" });
This event will simply end the setup phase of the project, allowing regular access to the session.
Saving
When a project has been created, and should be kept available for future use, it is possible to save it via the API.
Note: The steps in this chapter will trigger the saving of multiple projects. This will be counted in your license's allowance for simultaneously permitted projects. (It is possible to delete the projects afterwards.) If this is undesirable, you can skip the code-running steps in this chapter.
To save your project, run the following code:
var USERNAME = $USERNAME; var PASSWORD = $KEY; var SESSION_ID = $SESSION_ID; $.ajax({ url:'/api/event/io/save_project/', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([SESSION_ID]) });
This will save the current state of the project. If the session is closed, and the project is then opened anew, all changes made to the project before saving will still be present in the project.
It is also possible to "save as" the project. This will create a copy of the project based on the current state of the session. To do so, run the following code:
var USERNAME = $USERNAME; var PASSWORD = $KEY; var DOMAIN = $DOMAIN; var SESSION_ID = $SESSION_ID; var NEW_PROJECT_NAME = $NEW_PROJECT_NAME; $.ajax({ url:'/api/event/io/save_project_as/', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([SESSION_ID, DOMAIN, NEW_PROJECT_NAME, true]) });
Now, the running session is unchanged, but will be a running session of the newly created (saved) project, going by the new name. All subsequent saves will refer to the new project rather than the old project. The old project still exists (if it was saved at any point), and can be opened as a separate session.
Creating a project based on a template
It's possible to create a project based on an already existing project. In the software itself, this is known as using a template. When doing so, the new project will have all non-geographic data of the old project, and allow a new location to be selected for the new project.
Note: The steps in this chapter will trigger the creation of a new project. This will be counted in your license's allowance for the creation of new projects. If this is undesirable, you can skip the code-running steps in this chapter.
Creating project based on existing project
To do so, start the project which you want to use as a template. After the project has started, "save as" it, but with the final parameter set to "false". To do so, run the following code:
var USERNAME = $USERNAME; var PASSWORD = $KEY; var DOMAIN = $DOMAIN; var SESSION_ID = $SESSION_ID; var NEW_PROJECT_NAME = $NEW_PROJECT_NAME; $.ajax({ url:'/api/event/io/save_project_as/', headers: { "Authorization": "Basic " + btoa(USERNAME + ":" + PASSWORD) }, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([SESSION_ID, DOMAIN, NEW_PROJECT_NAME, false]) });
This will create a new project, and make the currently running session a session of that new project. The session still contains geographical data, but the saved project does not.
Note that if you close the project now, it will be automatically deleted as it is considered to be in an incomplete state.
Clearing geographical data from project
Next, the session should be cleared of geographical data, and its stored geographical reference point should be cleared. To do so: run the following code:
var token='$TOKEN'; $.ajax({ url:'/api/session/event/editor/clear_map/?token='+token, method: "POST", contentType: "application/json", datatype: "json", data: JSON.stringify([true]) });
The parameter indicates that, in addition to the geographical data, the map size and geographical reference must be cleared as well.
Now the session is in a state where a new location can be configured, and map generation can be started, as if creating a new project. For more information, see the project creation instructions described earlier, starting with setting a location. However, now in addition to the resulting geographical data loaded in by the map creation process, the project will also have all the stakeholders, indicators, overlays, and other non-geographical elements of the original project.
After generating the project, save it, and the process of creating a new project based on an existing one is completed.
Keeping a session alive
By default, if a session is not interacted with for 15 minutes, the session is closed automatically. In this context, it can mean any of the following:
- Firing an event, using a POST request.
- Polling the "/update/" endpoint, using a POST request.
- Accessing the web interface, or any part of it.
- Executing a query.
Conventionally, an application should periodically poll the "/update/" endpoint, to be made aware of changes in data in a session. This polling is sufficient to keep the session active, if it's done with an interval of less than the timeout period.
Up- and downloading
Some information, such as images, GeoTIFFs, and excel files, can be up- and downloaded. Because files are binary information, they must be encoded before they can be transmitted, and decoded when the data is received.
Downloading an excel
While GeoTIFF files can be downloaded directly from an overlay, some assets stand partially or distinctly separate from the data type they are commonly assocciated with. Indicators and their excels are an important example of this. Excel files can used as the calculation model for indicators, but also for panels or zoning plots. Additionally, an excel can be used for multiple indicator, panels, zoning plots, or combinations thereof. In addition, there is a difference between base excel files, and the excels as part of (and filled by) specific data items.
To try this out, first add a default indicator to the project by running the following code:
var token=$TOKEN; $.ajax({ url:'/api/session/event/editorindicator/add/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify(['EXCEL', 0]) });
The response is the newly added indicator's ID.
Now, it's immediately possible to download the indicator's excel, as interpreted, filled, and calculated by the indicator. Run the following code:
var token=$TOKEN; var INDICATOR_ID=$INDICATOR_ID; $.ajax({ url:'/api/session/event/editorindicator/export_debug_excel/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify([INDICATOR_ID]) });
The result will be base64-encoded binary information, decoding which will yield an excel file. This excel file will be a filled version of the excel file.
However, this excel is based on an original excel file, which is separate from the indicator. (Base) excels exist as a separate type of data. Run the following code:
var token='$TOKEN'; $.ajax({ url:'/api/session/items/excelsheets/?f=JSON&token='+token, method: "GET" });
The response is a list of all (base) excels present and available in the project, as they are uploaded. These versions are the "originals", as uploaded, and are not (yet) filled with any project-specific information. They can be downloaded in a similar fashion as the excel file was exported.
Run the following code:
var token=$TOKEN; $.ajax({ url:'/api/session/event/editorexcelsheet/export/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify([12]) });
Note: "12" is the ID of a default excel sheet meant for indicators as an initial placeholder.
The result will be base64-encoded binary information, decoding which will yield an excel file. This excel file will be a version of the excel file which has not been filled with data from the project yet. In other words, as it was uploaded.
Uploading assets
Now, it's also possible to upload assets to the project. To do so, they must be uploaded as the relevant asset data type. Then, they can be connected to whichever data type the asset is to be used by.
Run the following code, which will download an excel fie and then directly upload it back to the project as a separate excel file:
var token=$TOKEN; $.ajax({ url:'/api/session/event/editorexcelsheet/export/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify([12]) }).then(function(base64data){ $.ajax({ url:'/api/session/event/editorexcelsheet/add/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify(['new_uploaded_indicator', base64data, 'Tutorial script']) }); });
The result of this call will be the ID of the newly uploaded excel file.
Now, running the following code will make the desired indicator use the newly added excel file as its calculation model:
var token=$TOKEN; var INDICATOR_ID=$INDICATOR_ID; var EXCEL_ID=$EXCEL_ID; $.ajax({ url:'/api/session/event/editorindicator/set_excel/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify([INDICATOR_ID, EXCEL_ID]) });
Downloading a GeoTIFF
If an overlay is added to your project, for example an Average Overlay, the results can be downloaded as a GeoTIFF. Run the following code to add the overlay:
var token=$TOKEN; $.ajax({ url:'/api/session/event/editoroverlay/add/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify(['AVG']) });
The response to this event will be the ID of the added overlay.
Now, it's possible to download the results of the overlay as a GeoTIFF. This is possible via the Overlay services endpoint. Specifically, browsing to the following URL (with OVERLAY_ID replaced with the ID as returned by the previous request, and TOKEN replaced by the api token) will start the download of the GeoTIFF of the overlay:
/api/session/overlay.geotiff?id=OVERLAY_ID&token=TOKEN
Because this is a file, the data is not JSON encoded as with previous responses. Instead, any code will need to be able to handle binary data. For completeness sake of the Javascript examples, the following code will start the download of the same GeoTIFF file:
Run the following code:
var token=$TOKEN; var OVERLAY_ID=$OVERLAY_ID; var xhr = new XMLHttpRequest(); xhr.open('GET', '/api/session/overlay.geotiff?id='+OVERLAY_ID+'&token='+token); xhr.onreadystatechange = function() { if (xhr.readyState == 2) { if (xhr.status == 200) { xhr.responseType = "blob"; } else { xhr.responseType = "text"; } } }; xhr.onload = function() { if(xhr.status>=200 && xhr.status<300) { var blob = new Blob([xhr.response]); var objectURL = window.URL.createObjectURL(blob); var anchor = document.createElement('a'); anchor.href = objectURL; anchor.download = 'example-geotiff.tiff'; anchor.click(); } else { console.log('Something went wrong'); } } xhr.send();
Miscellaneous tasks via the API
All tasks can be performed via the API. However, for some tasks the appropriate events and their parameters may not be directly apparent.
As a general rule of thumb, to perform any task via the API, it can be beneficial to perform the task in the Tygron Client of the Tygron Platform first, and take note of the kind of steps taken to complete the full task.
Use GeoTIFF as heightmap
To base the heightmap on a GeoTIFF, first a GeoTIFF must be uploaded.
After uploading the GeoTIFF, the map must be modified based on the GeoTIFF.
var token=$TOKEN; var GEOTIFF_ID=$GEOTIFF_ID; $.ajax({ url:'/api/session/event/editormap/set_height_geotiff/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify([GEOTIFF_ID]) });
Applying the GeoTIFF to the heightmap is a singular action. When doing so, the GeoTIFF as it is in that moment is used to redraw the heightmap. After this action is completed, there is no explicit link between the height map and the GeoTIFF. This means that if or when the GeoTIFF is updated afterwards, the heightmap does not "follow" that same modification automatically. The event should be used again to update the heightmap to the new state of the GeoTIFF, if it is so desired.
Modify a function's function values
To change a function's function values, a function override must be created. This is also the case for function which already exist in in the Tygron Platform by default. The function override is a separate type of data from a function which can contain modifications to the values of the original. The function override can then have its values set (or unset to undo any changes).
First create a function override.
var token=$TOKEN; var FUNCTION_ID=$FUNCTION_ID; $.ajax({ url:'/api/session/event/editorfunctionoverride/add/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify([FUNCTION_ID]) });
This will create a new function override, with the same ID as the function for which an override was created. Next, the values of that function override can be modified.
To change a function value:
var token=$TOKEN; var FUNCTION_OVERRIDE_ID=$FUNCTION_ID; var FUNCTION_VALUE=$FUNCTION_VALUE; var newValue = $newValue; $.ajax({ url:'/api/session/event/editorfunctionoverride/set_function_value/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify([FUNCTION_OVERRIDE_ID, FUNCTION_VALUE, newValue]) });
To add or change an attribute:
var token=$TOKEN; var FUNCTION_OVERRIDE_ID=$FUNCTION_ID; var ATTRIBUTE_NAME=$ATTRIBUTE_NAME; var newValue = $newValue; $.ajax({ url:'/api/session/event/editorfunctionoverride/set_attribute/?token='+token, method: 'POST', contentType: 'application/json', datatype: 'json', data: JSON.stringify([FUNCTION_OVERRIDE_ID, ATTRIBUTE_NAME, newValue, null]) });
If a function value or attribute is sought for a specific building, the Tygron Platform will first look at the building itself. If that building does not have that value, a function override is consulted (if it exists). If that one too does not have the appropriate value, the function it is based on is consulted. If at any point the function was duplicated from another function, that original function may be consulted as well, if the duplicated function's override does not have its own value set.
Tutorial completed
Congratulations. You have now completed this tutorial. In it, you have learned how to find, read, and interact with the API.