Skip to main content
GuidesAPI ReferenceExamples

Define Persistent Roadblock

|

In this guide you will learn how to render an interactively defined road block on an interactive map and fly to the road block.

Initial map

Once the map is loaded, zoom in and tap on a road to define a road block.

Roadblock example #1
Roadblock example #2
Roadblock example #3

The selected road section is indicated with red roadblock polylines which may be on one or both sides of the road, depending on the road type.
Clicking on a different road section will move the roadblock there.
The map is interactive and fully 3D, supporting pan, pinch-zoom, rotate and tilt.

The roadblock variable is defined in the class MainActivity : AppCompatActivity() class to store the current section of road set as a roadblock by the user.

private var roadblock: TrafficEvent? = null

In the class MainActivity : AppCompatActivity(), in the onCreate() function the x,y position of a user touch event is obtained using onTouch and set in cursorScreenPosition so the map can be queried about traffic events, if any, at that location.
If there are 1 or more traffic events at the touch location, if (!trafficEvents.isNullOrEmpty()) then the roadblock is set on the first traffic event in the list (at index 0).

  • val trafficEvent = trafficEvents[0]
  • if (trafficEvent.isRoadblock())
    Otherwise, if there are 1 or more road sections at the touch location, if (!streets.isNullOrEmpty()) then the roadblock is set on the first street in the list (at index 0) streets[0].coordinates?.let { addPersistentRoadblock(it) }.
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?)
{
...
gemSurfaceView.mapView?.onTouch = { xy ->
SdkCall.execute {
// tell the map view where the touch event happened
gemSurfaceView.mapView?.cursorScreenPosition = xy

val trafficEvents = gemSurfaceView.mapView?.cursorSelectionTrafficEvents
if (!trafficEvents.isNullOrEmpty())
{
val trafficEvent = trafficEvents[0]
if (trafficEvent.isRoadblock())
{
return@execute
}
}

val streets = gemSurfaceView.mapView?.cursorSelectionStreets
if (!streets.isNullOrEmpty())
{
streets[0].coordinates?.let { addPersistentRoadblock(it) }
}
}
}
...
}

The addPersistentRoadblock() function gets the current time and sets the roadblock end time 1 minute into the future.
The roadblock class member variable is initially set to null, as we have seen above. Here it is checked and if it is not null, roadblock?.let { roadblock -> that means the user already set a previous roadblock.
In that case, the previous roadblock is removed first:

  • roadblock.referencePoint?.let { coordinates ->
  • traffic.removePersistentRoadblock(coordinates) }

Then the new roadblock is added, and saved in the class member variable:

  • roadblock = traffic.addPersistentRoadblock(
  • coords = arrayListOf(coordinates),
  • startUTC = startTime,
  • expireUTC = endTime,
  • transportMode = ERouteTransportMode.Car.value)

Finally, the camera flies to the bounding box enclosing the roadblock section to center it in the viewing area such that it fills the viewport.

MainActivity.kt
private fun addPersistentRoadblock(coordinates: Coordinates)
{
val startTime = Time.getUniversalTime()
val endTime = Time.getUniversalTime().also { endTime -> endTime?.let { it.minute += 1 } }

if (startTime != null && endTime != null)
{
val traffic = Traffic()

roadblock?.let { roadblock ->
roadblock.referencePoint?.let { coordinates ->
traffic.removePersistentRoadblock(coordinates)
}
}

roadblock = traffic.addPersistentRoadblock(
coords = arrayListOf(coordinates),
startUTC = startTime,
expireUTC = endTime,
transportMode = ERouteTransportMode.Car.value
)

if (roadblock?.referencePoint?.valid() == true)
{
roadblock?.boundingBox?.let {
gemSurfaceView.mapView?.centerOnArea(
area = it,
zoomLevel = -1,
xy = null,
animation = Animation(EAnimation.Linear)
)
}

Util.postOnMain { hint.visibility = View.GONE }
}
}
}