Run RF propagation
Supply transmitter locations and RF values directly, wait for the job, and read the generated map tiles. Entities are optional.
/api/terrain-analysis/rf-propagationProvide the transmitter values directly.
This workflow does not require an entity. Supply between one and 32 transmitter locations with their antenna height, frequency, and effective radiated power. This example uses the boundary and center point from Getting Started, so boundary_shape defines the area that will be analyzed.
Instead of a boundary, you can define a circular analysis area with analysis_radius_m on each transmitter or max_radius_m for the request.
curl --request POST "$BLUE_API_URL/api/terrain-analysis/rf-propagation" \
--header "Authorization: Bearer $BLUE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"map_id": "'"$BLUE_MAP_ID"'",
"boundary_shape": {
"type": "Polygon",
"coordinates": [[
[-93.1213, 31.1275],
[-93.1207, 31.0890],
[-93.0442, 31.0880],
[-93.0439, 31.1283],
[-93.1213, 31.1275]
]]
},
"quality_preset": "balanced",
"transmitters": [
{
"id": "hilltop-relay",
"name": "Hilltop Relay",
"latitude": 31.10815,
"longitude": -93.0826,
"antenna_height_m": 2.44,
"frequency_mhz": 51.5,
"erp_watts": 5
}
]
}'Copy the returned job_id.
export BLUE_RF_JOB_ID="YOUR_JOB_ID"Poll until the job succeeds.
Run the curl again until status is success. Stop if it returns failed orcancelled. The Python example performs the polling loop for you.
curl --silent --show-error --fail-with-body \
--header "Authorization: Bearer $BLUE_API_KEY" \
"$BLUE_API_URL/api/terrain-analysis/rf-propagation/jobs/$BLUE_RF_JOB_ID"Treat the RF collection as a tiled coverage.
List the map-owned tile collections after the RF job succeeds.
curl --silent --show-error --fail-with-body \
--header "Authorization: Bearer $BLUE_API_KEY" \
"$BLUE_API_URL/api/maps/$BLUE_MAP_ID/ogc/tiles/collections"Copy the returned collection id. RF collection IDs use the formlayer--{map_layer_id}.
export BLUE_RF_COLLECTION_ID="layer--YOUR_LAYER_ID"The collection is the complete RF result. It is divided into square 256 × 256 WebMercatorQuad tiles at each zoom level. A map client requests every tile that intersects its current view and positions those tiles next to one another. Tile URLs use {zoom}/{row}/{column}.png order.
The example below downloads one tile containing the radio location. It is only one piece of the coverage at zoom 12, so opening this file alone will not show the complete RF footprint. Request the neighboring row and column addresses to assemble the rest of the coverage at that zoom.
curl --silent --show-error --fail-with-body \
--header "Authorization: Bearer $BLUE_API_KEY" \
--output rf-tile-z12-r1675-c988.png \
"$BLUE_API_URL/api/maps/$BLUE_MAP_ID/ogc/tiles/collections/$BLUE_RF_COLLECTION_ID/tiles/WebMercatorQuad/12/1675/988.png"Convert each pixel into received power.
These PNGs are lossless data containers, not finished colored map images. Each valid pixel stores the predicted received power at that location in dBm. Image viewers treat the encoded bytes as ordinary colors, so a tile may look strange when opened directly.
alpha = 0means the pixel has no RF data;alpha = 255means it is valid.encoded = red × 65536 + green × 256 + blue.dBm = -200 + encoded ÷ 100.- Choose a useful dBm threshold and color ramp, then apply them to the decoded values.
- Place every requested tile at its WebMercatorQuad address to render the coverage over a map.
Blue uses this same process: it downloads the visible tiles, decodes their dBm values, hides readings below the selected threshold, applies its signal-strength color ramp and opacity, and joins the tiles on the map.
Resolve the transmitter from a radio entity.
If your operation already stores entities in Blue, RF can read the location and completed radio configuration from an entity's communications.radio capability. The operation and map must refer to the same operation, and API keys need the ENTITIES scope.
The example location is the center of the Getting Started boundary. Blue fills in the remaining radio and antenna defaults for these known models.
curl --request POST "$BLUE_API_URL/api/operations/$BLUE_OPERATION_ID/entities/" \
--header "Authorization: Bearer $BLUE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"profile": {
"unit_name": "Hilltop Relay",
"sidc": "10031000001211000000",
"affiliation": "friendly",
"capabilities": [
{
"id": "primary-radio",
"type": "communications.radio",
"schema_version": 1,
"model": "RT1523_ASIP",
"config": {
"network_name": "command",
"selected_power_level_id": "HI",
"operating_frequency_mhz": 51.5,
"antenna": {"model": "AS3900A"}
}
}
]
},
"current_state": {
"location": {"type": "Point", "coordinates": [-93.0826, 31.10815]}
}
}'Copy the returned entity id.
export BLUE_ENTITY_ID="YOUR_ENTITY_ID"curl --request POST "$BLUE_API_URL/api/terrain-analysis/rf-propagation/entities" \
--header "Authorization: Bearer $BLUE_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"map_id": "'"$BLUE_MAP_ID"'",
"quality_preset": "balanced",
"entities": [
{
"entity_id": "'"$BLUE_ENTITY_ID"'",
"radio_capability_ids": ["primary-radio"]
}
]
}'Copy the returned job_id, then use the same polling, collection discovery, and tile-decoding steps above.
export BLUE_RF_JOB_ID="YOUR_JOB_ID"