• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

Tutorial: Use SimIn SDK to Query Raster Data


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:

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.

auto request =  RasterRequest
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:

terrain ->QueryRasterAsync(&request, &landclassLoadedCallback);
Step 3.

Define a callback function called landclassLoadedCallback, which has the following prototype:

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:

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!