Transforming an iModel - Filtering data by a view definition

Tutorial result example

Introduction

This quick start is intended to help you create your first iModel Transformation. In this walk-through, you will configure and run a transformation, wait for it to complete and view the result.

Info

Skill level:

Intermediate

Duration:

20 minutes

Prerequisites

This tutorial assumes that you already have:

  • A tool such as Postman that can be used to execute http calls. These calls can also be made using the Try it out button in the API documentation or any other http request tool.
  • A created connected project. You can create a project by following instructions at Create a new iTwin Project.
  • A source iModel with some data for the transformation. You can create an iModel from Bentley Sample by following instructions at Create an iModel.
  • An empty target iModel for the transformation. You can create an empty iModel by following instructions at Create an iModel.

1. Register an Application

You will need to register an application to use the iTwin Platform APIs. You can use the Register button to automatically create your first single page application (SPA). This will allow you to configure Authorization Code Flow for your SPA application and get the correct access token.

Once generated, you will be shown a few lines of code under the button.

  • IMJS_AUTH_CLIENT_CLIENT_ID - this is the unique identifier for your application. Displayed on application details page as Client ID.
  • IMJS_AUTH_CLIENT_REDIRECT_URI - specifies where users are redirected after they have chosen whether or not to authenticate your app. Displayed on application details page as one of Redirect URIs.
  • IMJS_AUTH_CLIENT_LOGOUT_URI - specifies where users can be returned to after logging out. Displayed on application details page as one of Post logout redirect URIs.
  • IMJS_AUTH_CLIENT_SCOPES - list of accesses granted to the application. Displayed on application details page as Scopes.

Or optionally: Register and configure your application manually following instructions in Register and modify an Application tutorial.

Requires you to sign in. Will automatically generate a Single page application (SPA) that is required to complete this tutorial. You will be able to manage your SPA from your My apps page.

2. Get a token

To make requests to the API, a user token is needed. There are several ways to get it.

Implement Authorization Code Flow in the application

Follow this article to implement Authorization code workflow in your application.

Here you can use Client ID generated from previous registration step.

Grab a user token from Api reference "Try it out" Section

  1. Go to Create Configuration
  2. Click "Try it out" button.
  3. On Authorization section select "AuthorizationCode".
  4. After popup closes Authorization header with your user token value should be visible.
  5. Save user token value for this tutorial.

Use user token to replace JWT_TOKEN dynamic parameter in the next steps.

3. Decide on what data to keep inside an iModel.

Open iModel and take note of data that has to be kept inside an iModel.

Easiest way to query for iModel data is by using an iModel Console web application. Open your source iModel by replacing values in this link: https://imodelconsole.bentley.com/?projectid=SOURCE_PROJECT_ID&imodelid=SOURCE_IMODEL_ID

3.1 A View definition

A View renders geometry from one or more Models of an iModel in a web browser. iTwin.js applications can embed and interact with Views anywhere on a web page. A View is saved in an iModel as an element of the ViewDefinition class. ViewDefinitions hold all the information necessary to show the same content across sessions.

A view contains a model selector and a category selector which holds a list of Ids of models and categories that should be displayed in a view. Views are used to hide information in a browser, but the iModel itself holds the full data. Filter by view definition transformation relies on the data from model selector and category selector within the view and accepts arrays of Ids to filter on.

3.2 Query for Physical Models/Partitions

Run ECSQL query: SELECT ECInstanceId, CodeValue, UserLabel from bis.PhysicalPartition To learn more about ECSQL follow this link.

This ECSQL query returns a list of physical partitions inside an iModel. To learn more about iModel internals, follow this link.

Save all ECInstanceId values and remove those that you would like to filter out.

Note: If parent model element is omitted from the list, all child elements will get filtered out automatically.

3.3 Query for Spatial categories

Run ECSQL query: SELECT ECInstanceId, CodeValue, UserLabel from bis.Spatialcategory

This ECSQL query returns a list of spatial categories inside an iModel. Save all ECInstanceId values and remove those that you would like to filter out.

Note: If parent category element is omitted from the list, all child elements will get filtered out automatically.

4. Create a configuration

A transformation configuration is needed to create an association between source and target iModels with some additional metadata to successfully carry out the transformation. Creating a configuration does not start the transformation process itself.

A configuration is created by sending a request to https://api.bentley.com/transformations/configurations/filterbyviewdefinition endpoint with the payload describing the source and target iModel association.

These are the required properties for the endpoint:

transformName - free form text field so you could name your configuration
sourceProjectId - source projectId
sourceIModelId - iModelId of an iModal that is going to be used as a source of the transformation
targetProjectId - target projectId
targetIModelId - iModelId of an iModal that is going to be used as a target of the transformation. Initial transformation should always run on an empty target iModel
comment - a comment of the transformation. transformData.models - an array of ECInstanceIds that specify model elements that should be kept inside an iModel after transformation. transformData.categories - an array of ECInstanceIds that specify category elements that should be kept inside an iModel after transformation.

You can execute the request in FilterByViewDefinition page, "Try it out" section.

After executing the request, save returned Id from the response.

Request Syntax


http
POST https://api.bentley.com/transformations/configurations/filterbyviewdefinition HTTP/1.1

Request Headers


http
Accept: application/json
Authorization: Bearer JWT_TOKEN
Content-Type: application/json

Request Body


json
{
"transformName":"Filter stadium by a view definition",
"sourceProjectId":"SourceProjectId",
"sourceIModelId":"SourceIModelId",
"targetProjectId":"TargetProjectId",
"targetIModelId":"TargetIModelId",
"comment":"Example comment",
"transformParameters":{
  "models":[
    "specify",
    "all ECInstanceIds",
    "of PhysicalPartitions",
    "that you want to keep"
  ],
  "categories":[
    "specify",
    "all spatial categories",
    "that you want to keep"
  ]
}
}

Response Headers


http
Content-Type: application/json

Response Body


json
{
"configuration":{
  "id":"5e19bee0-3aea-4355-a9f0-c6df9989ee7d",
  "transformName":"Filter stadium by a view definition",
  "comment":"Example comment",
  "createdDateTime":"2021-08-02T14:51:33.6133333Z",
  "createdBy":"00000000-0000-0000-0000-000000000000",
  "modifiedDateTime":"2021-08-02T14:52:33.6133333Z",
  "lastModifiedBy":"00000000-0000-0000-0000-000000000000",
  "transformParameters":{
    "models":[
      "specify",
      "all ECInstanceIds",
      "of PhysicalPartitions",
      "that you want to keep"
    ],
    "categories":[
      "specify",
      "all spatial categories",
      "that you want to keep"
    ]
  },
  "_links":{
    "sourceIModel":{
      "href":"https://api.bentley.com/imodels/00000000-0000-0000-0000-000000000000"
    },
    "targetIModel":{
      "href":"https://api.bentley.com/imodels/00000000-0000-0000-0000-000000000000"
    },
    "sourceProject":{
      "href":"https://api.bentley.com/projects/00000000-0000-0000-0000-000000000000"
    },
    "targetProject":{
      "href":"https://api.bentley.com/projects/00000000-0000-0000-0000-000000000000"
    }
  }
}
}

5. Create a transformation

A transformation is created by sending a request to https://api.bentley.com/transformations endpoint with the payload indicating which configuration should be used. The request is submitting a transformation job based on the configuration Id value that was provided.

You can execute the request in Create transformation page, "Try it out" section.

Response indicates the current status of the transformation. After submitting a transformation the status is "Created" which means that the transformation is enqueued and waiting to start. Possible status messages:

Created - transformation is created and waiting to be started. The transformation should start automatically, no additional actions are needed. Started - transformation is started and waiting to finish. Succeeded - transformation succeeded. You can open target iModel and inspect the results. Failed - transformation failed. Check the errorMessage node for more information on what happened.

Transformation response objects additionally stores processedElementCount and totalElementCount to allow rendering progress bars and indicate progress to the end users.

After executing the request, save returned transformation Id from the response.

Request Syntax


http
POST https://api.bentley.com/transformations HTTP/1.1

Request Headers


http
Accept: application/json
Authorization: Bearer JWT_TOKEN
Content-Type: application/json

Request Body


json
{
"configurationId":"your saved configurationId from step number 3."
}

Response Headers


http
Content-Type: application/json

Response Body


json
{
"transformation": {
  "id":"5e19bee0-3aea-4355-a9f0-c6df9989ee7d",
  "status":"Created",
  "errorMessage":"",
  "processedElementCount":0,
  "totalElementCount":0,
  "_links":{
    "configuration":{
      "href":"https://api.bentley.com/transformations/configurations/00000000-0000-0000-0000-000000000000"
    }
  }
}
}

6. Waiting for transformation to finish

Send a GET request to https://api.bentley.com/transformations/TRANSFORMATION_ID endpoint to get an updated transformation status. You can execute the request in Get transformation page, "Try it out" section.

Query for the transformation multiple times until the status changes from Created to Started and eventually to Succeeded.

Go to My iTwins section and view the target iModel.

7. Conclusion

We've successfully created a configuration, ran a transformation that filtered iModel data, waited for the transformation to completed and inspected the results.

Request Syntax


http
GET https://api.bentley.com/transformations/TRANSFORMATION_ID HTTP/1.1

Request Headers


http
Accept: application/json
Authorization: Bearer JWT_TOKEN
Content-Type: application/json

Response Headers


http
Content-Type: application/json

Response Body


json
{
"transformation": {
  "id":"5e19bee0-3aea-4355-a9f0-c6df9989ee7d",
  "status":"Started",
  "errorMessage":"",
  "processedElementCount":0,
  "totalElementCount":120000,
  "startedDateTime":"0000-00-00T00:00:00.0000000Z",
  "finishedDateTime":"0000-00-00T00:00:00.0000000Z",
  "sourceChangeSetId":"0",
  "_links":{
    "configuration":{
      "href":"https://api.bentley.com/transformations/configurations/00000000-0000-0000-0000-000000000000"
    }
  }
}
}