You can use the default LuciadRIA create and edit controllers, but you can also create custom controllers, by implementing
                           Controller.
                           You need custom controllers to add custom user interaction to your application.
                        
Handling user gestures and key strokes
Extensions of Controller can respond to input events by overriding the Controller.onGestureEvent(GestureEvent) and Controller.onKeyEvent(KeyEvent) methods.
                        
luciad.view.input.GestureEvent describes incoming gesture events.
                           The GestureEvent class serves as a wrapper for the raw events generated by the browser.
                           You can obtain the raw DOM event with the domEvent property.
                        
Similarly, luciad.view.input.KeyEvent provides a wrapper for browser key events.
                           You can obtain the raw DOM event with the domEvent property.
                        
Controller implementations can also use the MapNavigator class to move around and zoom on the map.
                           You can get a MapNavigator instance from the Map.
                        
GestureEvent to handle incoming motion events. (from toolbox/ria/ruler3d/Ruler3DController.ts)
                        /**
 * Handle the user input gestures. The event-object contains information about the type of user-interaction
 */
onGestureEvent(gestureEvent: GestureEvent): HandleEventResult {
  if (!this._enabled) {
    return EVENT_IGNORED;
  }
  if (this._projector && !this._projector?.ready) {
    const result = this._projector.handleEventForInitialization(gestureEvent);
    if (result === HandleEventResult.EVENT_HANDLED) {
      this.invalidate();
    }
    return result;
  } else if (gestureEvent.type === GestureEventType.SINGLE_CLICK_UP) {
    return this.handleClick(gestureEvent);
  } else if (gestureEvent.type === GestureEventType.MOVE) {
    return this.handleMove(gestureEvent);
  } else if (gestureEvent.type === GestureEventType.DOUBLE_CLICK) {
    return this.handleDoubleClick();
  } else {
    return HandleEventResult.EVENT_IGNORED;
  }
}Painting shapes in a Controller
You can use GeoCanvas to paint shapes in your controller.
                           You use it in a similar way as in FeaturePainter.
                        
The following snippet shows an example of painting shapes using a GeoCanvas from within the controller’s onDraw method.
                        
Controller implementation that illustrates the usage of GeoCanvas (from toolbox/ria/controller/GetFeatureInfoController.ts)
                        onDraw(geoCanvas: GeoCanvas): void {
  if (this._feature && this._feature.shape) {
    geoCanvas.drawShape(this._feature.shape, {
      stroke: {
        color: "rgb(255,0,0)",
        width: 2
      }
    });
  }
}Painting labels in a Controller
You can use LabelCanvas to paint labels in your controller.
                           You use it in a similar way as in FeaturePainter.
                        
Controller implementation that illustrates the usage of LabelCanvas (from samples/ria/createedit/themes/custom/ArrowEditor.ts)
                        onDrawLabel(labelCanvas: LabelCanvas) {
  if (this.active) {
    const arrow = this._arrowFeature;
    const css = `
      font-family: monospace;
      font-size: large;
      color: white;
      text-shadow: -1px -1px 0 black,
         1px -1px 0 black,
         -1px 1px 0 black,
         1px 1px 0 black;
    `;
    const html = `<div style="${css}">Width: ${arrow.width.toFixed(0)}m</div>`;
    const [helperLine1, helperLine2] = this.getHelperLines();
    labelCanvas.drawLabelOnPath(html, helperLine1, {positions: PathLabelPosition.ABOVE});
    labelCanvas.drawLabelOnPath(html, helperLine2, {positions: PathLabelPosition.ABOVE});
  }
}| Controller implementations must call  | 
Changing the mouse cursor
In a Controller
To change the mouse cursor in a Controller, you can use Controller.cursor.
                           
For example, if you want to show a 'grabbing' cursor while panning, you can do that as follows:
PanController implementation that illustrates how you can change the map’s cursor. While panning, it shows a 'grabbing' cursor.
                           class GrabPanController extends PanController {
  onGestureEvent(gestureEvent: GestureEvent): HandleEventResult {
    const result = super.onGestureEvent(gestureEvent);
    this.cursor = isHandled(result) ? "grabbing" : null;
    return result;
  }
}
const navigateController = new NavigateController({
  panController: new GrabPanController()
});
map.defaultController = new DefaultController({
  navigateController
});Outside a Controller
To change the map’s mouse cursor outside a Controller, you can use Map.cursorManager.
                              You add a cursor to the manager by calling CursorManager.addCursor.
                              This activates the passed cursor and returns a Handle. When the cursor should be removed from the Map, you call Handle.remove.