- Messages
- 286
- Country
Hi,
Here is a tutorial on querying for raster data in the simulator using the SimIn API. Raster data includes Elevation, LandClass, PopulationDensity, Region, Season, and WaterClass data that forms the base layers for the simulator terrain generation algorithms. Aerial imagery is not yet supported by SimIn. The raw data returned from SimIn could be used for many purposes, such as a moving map display, GPWS, or additional terrain rendering code. This is a continuation of the SimIn tutorial started here: https://www.fsdeveloper.com/forum/threads/use-simin-sdk-to-query-facilities.444018/
Step 1.
Setup your project according to the steps in the above facilities tutorial, up to Step 4. Once you have your .cpp file setup with headers the module initialization, you are ready to add the code to query for raster data.
In addition, you will want to setup a variable for the terrain service like the facilities:
Step 2.
You will add code to the DebugCallback (called every frame) to query for raster data using the terrain service. Note that this is an asynchronous service, so although you will request data every frame, you will only receive data in the callbacks once the sim has loaded everything.
First you will create a RasterRequest struct. Note that as per the SimIn documentation, this struct is shared across several different requests types, each having unique parameter requirements. Here we will use a Radius request type, which in this case will query a grid of QMID7 cells centered around a specific Lat point (at 43.0N, 123.0W) within a 10.0km radius.
Note that certain layers, such as terrain, can be clipped to any QMID Zoom Level. Certain features, like landclass and waterclass are present only at QMID level 7. For more information, see the Prepar3d SDK.
Next, you will issue a terrain service request with a pointer to your RasterRequest struct and a callback function that will asynchronously receive the results when the query is complete:
Step 3.
Define a callback function called landclassLoadedCallback, which has the following prototype:
This function will be called asynchronously when the data is loaded, dataraw->Data will be NULL if failed, else it will contain the data to be read.
The results of the request, stored in dataraw->Data, are a 2D grid of cells, one per QMID in the request. QMIDs increase linearly from top to bottom and left to right. The Data for each QMID contains a pointer to a 1D array of raw data, representing the "pixels" for the raster image. Therefore, to iterate over all of the results returned, you will need a nested for loop, iterating over each datapointer inside each cell in the 2D grid. Note that in QMIDs, the Y dimension refers to the rows, while the X dimension refers to the columns.
Step 4.
Inside the landclassLoadedCallback callback, you can iterate to process the data. Iterate over each QMID block, from top to bottom, left to right increasing. It is important that you copy the raw data from each QMID cell if you need access to it outside of the scope of your callback, for example, for rendering.
Note that depending upon the raster request type, the size of each image pointer pixel array will vary. For example, elevation values use grids of 257 x 257 floats. Landclass uses bytes, and terrain indexes use 32X32 bytes. For more information, please see the P3D SDK.
Once you have copied the data, you can access an individual "pixel"'s data from the linear array by taking:
For more information on everything related to raster data in the simulator, including all of the fields that SimIn has access to read, see the documentation in the P3D SDK on resample here: http://www.prepar3d.com/SDKv4/sdk/world/terrain/terrain_overview.html#The Resample Tool
If you need commercial support for reading / processing / or rendering based on rater data, feel free to contact us.
Happy developing!
Here is a tutorial on querying for raster data in the simulator using the SimIn API. Raster data includes Elevation, LandClass, PopulationDensity, Region, Season, and WaterClass data that forms the base layers for the simulator terrain generation algorithms. Aerial imagery is not yet supported by SimIn. The raw data returned from SimIn could be used for many purposes, such as a moving map display, GPWS, or additional terrain rendering code. This is a continuation of the SimIn tutorial started here: https://www.fsdeveloper.com/forum/threads/use-simin-sdk-to-query-facilities.444018/
Step 1.
Setup your project according to the steps in the above facilities tutorial, up to Step 4. Once you have your .cpp file setup with headers the module initialization, you are ready to add the code to query for raster data.
In addition, you will want to setup a variable for the terrain service like the facilities:
C++:
ITerrainServiceV1 *terrain;
// and in module_init
sdk->GetService(SERVICE_ITerrainServiceV1, reinterpret_cast<void**>(&terrain));
Step 2.
You will add code to the DebugCallback (called every frame) to query for raster data using the terrain service. Note that this is an asynchronous service, so although you will request data every frame, you will only receive data in the callbacks once the sim has loaded everything.
First you will create a RasterRequest struct. Note that as per the SimIn documentation, this struct is shared across several different requests types, each having unique parameter requirements. Here we will use a Radius request type, which in this case will query a grid of QMID7 cells centered around a specific Lat point (at 43.0N, 123.0W) within a 10.0km radius.
C++:
auto request = RasterRequest
{
RASTERTYPE_USERLOCATION,
REQUESTTYPE_RADIUS,
ZOOMLEVEL7,
10.0,
0.0,
-123.0,
43.0
}
Note that certain layers, such as terrain, can be clipped to any QMID Zoom Level. Certain features, like landclass and waterclass are present only at QMID level 7. For more information, see the Prepar3d SDK.
Next, you will issue a terrain service request with a pointer to your RasterRequest struct and a callback function that will asynchronously receive the results when the query is complete:
C++:
terrain ->QueryRasterAsync(&request, &landclassLoadedCallback);
Step 3.
Define a callback function called landclassLoadedCallback, which has the following prototype:
C++:
HRESULT SIMINAPI landclassLoadedCallback (RasterData* dataraw)
This function will be called asynchronously when the data is loaded, dataraw->Data will be NULL if failed, else it will contain the data to be read.
The results of the request, stored in dataraw->Data, are a 2D grid of cells, one per QMID in the request. QMIDs increase linearly from top to bottom and left to right. The Data for each QMID contains a pointer to a 1D array of raw data, representing the "pixels" for the raster image. Therefore, to iterate over all of the results returned, you will need a nested for loop, iterating over each datapointer inside each cell in the 2D grid. Note that in QMIDs, the Y dimension refers to the rows, while the X dimension refers to the columns.
Step 4.
Inside the landclassLoadedCallback callback, you can iterate to process the data. Iterate over each QMID block, from top to bottom, left to right increasing. It is important that you copy the raw data from each QMID cell if you need access to it outside of the scope of your callback, for example, for rendering.
Note that depending upon the raster request type, the size of each image pointer pixel array will vary. For example, elevation values use grids of 257 x 257 floats. Landclass uses bytes, and terrain indexes use 32X32 bytes. For more information, please see the P3D SDK.
Once you have copied the data, you can access an individual "pixel"'s data from the linear array by taking:
C++:
BYTE value = grid[row * NUMPIXELS + col];
For more information on everything related to raster data in the simulator, including all of the fields that SimIn has access to read, see the documentation in the P3D SDK on resample here: http://www.prepar3d.com/SDKv4/sdk/world/terrain/terrain_overview.html#The Resample Tool
If you need commercial support for reading / processing / or rendering based on rater data, feel free to contact us.
Happy developing!