NAV
swift kotlin java

Introduction


Welcome to Mappy.

We build geospatial platforms connecting venues to their guests. Our turnkey solutions (developer tools, including the Mappy API and Mappy SDK, for mobile apps), improve the guest experience using interactive and social custom maps. Our data analytics platform and operations dashboards are designed to inform data driven decisions.

Mappy SDKs provide an elegant and composable interface for mapping, geocoding, and routing.

The Mappy SDKs leverages the power of best in class technology, including ESRI using the ArcGIS Runtime SDKs as dependencies.

This guide describes how to use the latest version of the Mappy SDK for iOS and Android for ski resorts. Terms of Service for our developer tools, data analytics platform, and mapping services portal are found here.

Get started with Mappy SDK

iOS

Install the following:

If you don't have an Xcode project and want to try out a Mappy product, you can download a quick-start sample.

Android

Install the following:

If you don't have an Android project and want to try out a Mappy product, or want to see a code example, you can download or clone this quick-start sample.

Register your App with Mappy

Your app needs to be registered with Mappy to use the Mappy SDK in your app. For a quote, please email info@beMappy.io. Mappy will provide customers a Client Id and a secret key associated with your app. Make sure you store them securely.

Add Mappy SDK to your App

iOS

  1. If you don't have Cocoapods installed on your machine, install it by following this guide.
  2. Add pod 'Mappy' to your project's podfile.
  3. Run the pod install command from the root directory of the project.
  4. When finished, open the project's workspace and find the Mappy dependency under the Pod’s project.

Android

dependencies {
    implement("io.mappy.sdk:mappy:0.3.1")
}
dependencies {
    implement("io.mappy.sdk:mappy:0.4.0")
}

Localize the module level build.gradle file where you want the SDK installed and add the dependency full qualified name, you can find an example code at the right.

maven { url = uri("https://esri.jfrog.io/artifactory/arcgis") }
maven {
    name = "GitHubPackages"
    url = uri("https://maven.pkg.github.com/beMappy/Mappy-Kotlin")
    credentials {
        username = <GITHUB_USERNAME>
        password = <GITHUB_PERSONAL_ACCESS_TOKEN>
    }
}
maven { url = uri("https://esri.jfrog.io/artifactory/arcgis") }
maven {
    name = "GitHubPackages"
    url = uri("https://maven.pkg.github.com/beMappy/Mappy-Kotlin")
    credentials {
        username = <GITHUB_USERNAME>
        password = <GITHUB_PERSONAL_ACCESS_TOKEN>
    }
}

The Mappy Android SDK, for now, is available through Github Packages. So add the following to the project/build.gradle file, you can find an example code at the right.

The SDK is dependant on a special toolkit dependency stored in Jfrog. If you are not familiar to Github Personal Access Token, generate it using this guide

Initialize Mappy in Your App

Mappy needs to be initialized in your app by adding an initialization code.

iOS

To initialize use this code

import Mappy

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

  MappyCore.initialize(clientId: <ClientId>, secret: <ClientSecret>)
    .sink(receiveCompletion: {
        if case .failure(let error) = $0 {
            print("initialize: error: \(error)")
        }
    }, receiveValue: {
        print("MappyCore Initialized")
    })
    .store(in: &cancellables)

  return true
}

Make sure to replace `ClientId` and `ClientSecret` with your credentials.

  1. Import the Mappy module in your UIApplicationDelegate.
  2. Configure a Mappy shared instance, typically in your app's initializer or app delegate's application(_:didFinishLaunchingWithOptions:) method:

This function helps to instantiate the Mappy SDK. Post initialization, SDK APIs can be used internally across the project. This is the static method and requires a Client Id and a secret.

Android

Using Kotlin Coroutines

val mappy = Mappy.createInstance(applicationContext)
CoroutineScope(Dispatchers.IO).launch {
    mappy.initialize(<ClientId>, <ClientSecret>)
}

Using Callback

mappy.initialize(<ClientId>, <ClientSecret>, object: CompletionCallback<Void?> {
    override fun onSuccess(result: Void?) {
        //Initialization Success
    }

    override fun onError(throwable: Throwable) {
        //Initialization Error
    }
})
Mappy mappy = Mappy.createInstance(getApplicationContext());

mappy.initialize(<ClientId>, <ClientSecret>, new CompletionCallback<Void>() {
    @Override
    public void onSuccess(Void result) {
        //Initialization Success
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Initialization Error
    }
});
  1. Import the Mappy module.
  2. Create a Mappy object instance through the code instruction displayed in the example, be sure to pass a valid context to the createInstance method.
  3. Give the SDK your ClientID and ClientSecret using the initialize method. Post initialization, SDK APIs can be used internally across the project.

Venues

Get All Venues

let venuesService = VenuesService()
venuesService.getVenues()
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self] venues in
        // Received venues
  })
  .store(in: &cancellables)

Using Kotlin Coroutines

val venueService = VenueService.createInstance(applicationContext)
CoroutineScope(Dispatchers.IO).launch {      
    val venues = venueService.getVenues()
}

Using Callback

venueService.getVenues(object: CompletionCallback<List<Venue>> {
    override fun onSuccess(result: List<Venue>) {
      //Get Venues Successful
    }

    override fun onError(throwable: Throwable) {
      //Get Venues Error
    }
})
VenueService venueService = VenueService.createInstance(getApplicationContext());
venueService.getVenues(new CompletionCallback<List<Venue>>() {
    @Override
    public void onSuccess(List<Venue> result) {
        //Get Venues Successful
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Get Venues Error
    }
});

This function provides a list of venues associated with a particular Client Id. The data returned includes all details of available venues.

Get a Specific Venue

let venuesService = VenuesService()
venuesService.getVenue(venueId: <VenueId>)
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self] venue in
        // Received Venue
  })
  .store(in: &cancellables)

Using Kotlin Coroutines

val venueService = VenueService.createInstance(applicationContext);
CoroutineScope(Dispatchers.IO).launch {
    venueService.getVenue(<ID>)
}

Using Callback

venueService.getVenue(<ID>, object: CompletionCallback<Venue> {
    override fun onSuccess(result: Venue) {
        //Get Venue Successful
    }

    override fun onError(throwable: Throwable) {
        //Get Venue Error
    }
})
VenueService venueService = VenueService.createInstance(getApplicationContext());
venueService.getVenue(<ID>, new CompletionCallback<Venue>() {
    @Override
    public void onSuccess(Venue venue) {
        //Get Venue Successful
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Get Venue Error
    }
});

This function helps to get the details for a specific venue using its identifier.

Parameters

Parameter DataType Description
VenueId String The ID of the venue to retrieve

Rendering

Map

Map - Load

map = Map(mapInfo: <info>)
map.load()
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self, weak map, weak mapView] _ in
        // Map has been loaded
        if let map = map {
            self?.mapView?.map = map
        }
  })
  .store(in: &cancellables)
val map = Map(venue)
map.load(this, object : CompletionCallback<Map>() {
    fun onSuccess(map: Map) {
        binding.mapView.setMap(map)
    }

    fun onError(throwable: Throwable) {
        // Error Handling
    }
})

Map - Using Jetpack Compose

// must execute load method successfully first on the map object
MapView(
    map = map,
    modifier = Modifier,
    mapController = MapController()
)
Map map = new Map(venue);
map.load(this, new CompletionCallback<Map>() {
    @Override
    public void onSuccess(@NonNull Map map) {
        binding.mapView.setMap(map);
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        // Error Handling
    }
});

A Map is a class that represents the 2D map. You need to inject all the required data associated with a venue to instantiate and load a Map.

Get Features

Map - Get Features

map.getFeatures()
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self] featues in
        // Received featues
  })
  .store(in: &cancellables)

Get Features - Using Kotlin Coroutines

val map = Map(venue)
CoroutineScope(Dispatchers.IO).launch {     
    val loadedMap = map.load()
    loadedMap.getFeatures()
}

Get Features - Using Callback

// must execute load method successfully first on the map object
loadedMap.getFeatures(object: CompletionCallback<List<Feature>> {
    override fun onSuccess(result: List<Feature>) {
        //Get Features Successful
    }

    override fun onError(throwable: Throwable) {
        //Get Features Error
    }
})
// must execute load method successfully first on the map object
loadedMap.getFeatures(new CompletionCallback<List<Feature>>() {
    @Override
    public void onSuccess(List<Feature> result) {
        //Get Features Successful
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Get Features Error
    }
});

Get all the available features in the map like Ski run, lift, buidling, amenity, bookmarks, etc.

Search features by keyword

Map - Search Features

map.getFeatures(text: <SearchText>)
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self] featues in
        // Received featues
  })
  .store(in: &cancellables)

Search features - Using Kotlin Coroutines

val map = Map(venue)
CoroutineScope(Dispatchers.IO).launch {     
    val loadedMap = map.load()
    loadedMap.getFeatures(<keyword>)
}

Search features - Using Callback

// must execute load method successfully first on the map object
loadedMap.getFeatures(<keyword>, object: CompletionCallback<List<Feature>> {
    override fun onSuccess(result: List<Feature>) {
        //Get Features Successful
    }

    override fun onError(throwable: Throwable) {
        //Get Features Error
    }
})
// must execute load method successfully first on the map object
loadedMap.getFeatures(<keyword>, new CompletionCallback<List<Feature>>() {
    @Override
    public void onSuccess(List<Feature> result) {
        //Get Features Successful
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Get Features Error
    }
});

Get all the available features in the map like Ski run, lift, buidling, amenity, bookmarks, etc. that contains a given keyword.

Filter features by type

Map - Filter Features

map.getFeatures(category: <FeatureCategory>)
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self] featues in
        // Received featues
  })
  .store(in: &cancellables)

Filter features - Using Kotlin Coroutines

val map = Map(venue)
CoroutineScope(Dispatchers.IO).launch {     
    val loadedMap = map.load()
    loadedMap.getFeatures(<classType>)
}

Filter features - Using Callback

// must execute load method successfully first on the map object
loadedMap.getFeatures(<classType>, object: CompletionCallback<List<Feature>> {
    override fun onSuccess(result: List<Feature>) {
        //Get Features Successful
    }

    override fun onError(throwable: Throwable) {
        //Get Features Error
    }
})

/**
* Possible classTypes:
*   - SkiLift::class.java
*   - SkiSlope::class.java
*   - Building::class.java
*   - BuildingAmenity::class.java
*/
// must execute load method successfully first on the map object
loadedMap.getFeatures(<classType>, new CompletionCallback<List<Feature>>() {
    @Override
    public void onSuccess(List<Feature> result) {
        //Get Features Successful
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Get Features Error
    }
});

/**
* Possible classTypes:
*   - SkiLift.class
*   - SkiSlope.class
*   - Building.class
*   - BuildingAmenity.class
*/

Get all the available features in the map like Ski run, lift, buidling, amenity, bookmarks, etc. that matches a given type.

MapView

MapView - Initialize

MapView()

MapView - Using XML UI

import io.bemappy.sdk.ui.MapView
MapView(context)

MapView - Using Jetpack Compose

import io.bemappy.sdk.ui.compose.MapView 
MapView(map, modifier, mapController)
import io.bemappy.sdk.ui.MapView;
new MapView(context)

MapView is an UI class that helps in rendering the 2D map. Once the map is loaded, add the map to MapView and then you can add the same to your UI hierarchy.

Rotate To North

MapView - Rotate To North

mapView.rotateToNorth()

Rotate - Using XML UI (with View Binding or Data Binding)

binding.mapView.rotateToNorth()

Rotate - Using Jetpack Compose

// must execute load method successfully first on the map object
val mapController = remember { MapController() }

MapView(
    map = loadedMap,
    modifier = Modifier,
    mapController = mapController
)

mapController.rotateToNorth()
binding.mapView.rotateToNorth();

Rotates the map to the default orientation

Set Initial ViewPoint

MapView - Set Initial ViewPoint

mapView.setInitialViewpoint()

Initial ViewPoint - Using XML UI (with View Binding or Data Binding)

binding.mapView.setInitialViewpoint()

Initial ViewPoint - Using Jetpack Compose

mapController.setInitialViewpoint()
binding.mapView.setInitialViewpoint();

Restores the map to its initial state where the venue is entirely visible

Tap on a Feature

Tap on a Feature

mapView.event
    .receive(on: DispatchQueue.main)
    .sink(receiveValue: {
        switch $0 {
        case .onTap(let feature):
            // Handle the tap event
        default:
            break
        }
    })
    .store(in: &cancellables)

Tap Listener - Using XML UI (with View Binding or Data Binding)

binding.mapView.setTapListener(object: TapListener {
        override fun onTouch(feature: Feature?) {
             // handle tap
        }
    }
)

Tap Listener - Using Jetpack Compose

MapView(
    map = loadedMap,
    modifier = Modifier.fillMaxSize(),
    mapController = mapController,
    onTap = { feature -> // handle tap }
)
binding.mapView.setTapListener((feature) -> {
    //handle tap
});

A callback that will be invoked with the feature the user taps on.

View Point Change

MapView - View Point Change

mapView.event
    .receive(on: DispatchQueue.main)
    .sink(receiveValue: {
        switch $0 {
        case .onViewpointChange:
            // Handle the event
        default:
            break
        }
    })
    .store(in: &cancellables)

View Point Change Listener - Using XML UI (with View Binding or Data Binding)

binding.mapView.setViewPointChangeListener(object: ViewpointChangeListener {
    override fun onChanged() {
        //handle viewpoint change
    }
})

View Point Change Listener - Using Jetpack Compose

MapView(
    map = loadedMap,
    modifier = Modifier.fillMaxSize(),
    mapController = mapController,
    onViewPointChanged = { 
        //handle viewpoint change
    }
)
// lambda example
binding.mapView.setViewPointChangeListener(() -> {
    //handle viewpoint change
});

A callback that will be invoked every time when the user interacts with the Map except in the case of a tap.

Select a Feature

Select a Feature

mapView.select(feature: <Feature>)

Select a Feature - Using XML UI (with View Binding or Data Binding)

binding.mapView.selectFeature(<Feature>)

Select a Feature - Using Jetpack Compose

MapView(
    map = loadedMap,
    modifier = Modifier.fillMaxSize(),
    mapController = mapController
)

mapController.selectFeature(<Feature>)

Select a Feature

binding.mapView.selectFeature(<Feature>)

A function that highlights and zooms to the feature provided

Unselect a Feature

Unselect a Feature

mapView.select(feature: nil)

Unselect a Feature - Using XML UI (with View Binding or Data Binding)

binding.mapView.unselectFeature()

Unselect a Feature - Using Jetpack Compose

MapView(
    map = loadedMap,
    modifier = Modifier.fillMaxSize(),
    mapController = mapController
)

mapController.unselectFeature()

Unselect a Feature

binding.mapView.unselectFeature()

A function that removes the highlight from the selected feature

Scene

Scene - Load

scene = Scene(sceneInfo: <info>)
scene.load()
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self, weak scene, weak sceneView] _ in
        // Scene has been loaded
        if let scene = scene {
            self?.sceneView?.scene = scene
        }
  })
  .store(in: &cancellables)

Scene - Using XML UI (with View Binding or Data Binding)

val scene = Scene(venue)
scene.load(this, object : CompletionCallback<Scene>() {
    fun onSuccess(scene: Scene) {
        binding.sceneView.setScene(scene)
    }

    fun onError(throwable: Throwable) {
        // Error Handling
    }
})

Scene - Using Jetpack Compose

// must execute load method successfully first on the scene object
SceneView(
    scene = scene,
    modifier = Modifier,
    sceneController = SceneController()
)
Scene scene = new Scene(venue);
scene.load(this, new CompletionCallback<Scene>() {
    @Override
    public void onSuccess(@NonNull Scene scene) {
        binding.sceneView.setScene(scene);
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        // Error Handling
    }
});

A scene is a class that represents the 3D map. You need to inject in all the required data associated with a venue to instantiate and load a Scene.

Get Features

Scene - Get Features

scene.getFeatures()
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self] featues in
        // Received featues
  })
  .store(in: &cancellables)

Get Features - Using Kotlin Coroutines

val scene = Scene(venue)
CoroutineScope(Dispatchers.IO).launch {     
    val loadedScene = scene.load()
    loadedScene.getFeatures()
}

Get Features - Using Callback

// must execute load method successfully first on the scene object
loadedScene.getFeatures(object: CompletionCallback<List<Feature>> {
    override fun onSuccess(result: List<Feature>) {
        //Get Features Successful
    }

    override fun onError(throwable: Throwable) {
        //Get Features Error
    }
})
// must execute load method successfully first on the map object
loadedScene.getFeatures(new CompletionCallback<List<Feature>>() {
    @Override
    public void onSuccess(List<Feature> result) {
        //Get Features Successful
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Get Features Error
    }
});

Get all the available features in the scene like Ski run, lift, buidling, amenity, bookmarks, etc.

Search features by keyword

Scene - Search Features

scene.getFeatures(text: <SearchText>)
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self] featues in
        // Received featues
  })
  .store(in: &cancellables)

Search features - Using Kotlin Coroutines

val scene = Scene(venue)
CoroutineScope(Dispatchers.IO).launch {     
    val loadedScene = scene.load()
    loadedScene.getFeatures(<keyword>)
}

Search features - Using Callback

// must execute load method successfully first on the scene object
loadedScene.getFeatures(<keyword>, object: CompletionCallback<List<Feature>> {
    override fun onSuccess(result: List<Feature>) {
        //Get Features Successful
    }

    override fun onError(throwable: Throwable) {
        //Get Features Error
    }
})
// must execute load method successfully first on the map object
loadedScene.getFeatures(<keyword>, new CompletionCallback<List<Feature>>() {
    @Override
    public void onSuccess(List<Feature> result) {
        //Get Features Successful
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Get Features Error
    }
});

Get all the available features in the scene like Ski run, lift, buidling, amenity, bookmarks, etc. that contains a given keyword.

Filter features by type

Scene - Filter Features

scene.getFeatures(category: <FeatureCategory>)
  .receive(on: DispatchQueue.main)
  .sink(receiveCompletion: { completion in
      switch completion {
      case .finished: break
      case .failure(let error):
          print("error: \(error)")
      }
  }, receiveValue: { [weak self] featues in
        // Received featues
  })
  .store(in: &cancellables)

Filter features - Using Kotlin Coroutines

val scene = Scene(venue)
CoroutineScope(Dispatchers.IO).launch {     
    val loadedScene = scene.load()
    loadedScene.getFeatures(<classType>)
}

Filter features - Using Callback

// must execute load method successfully first on the map object
loadedScene.getFeatures(<classType>, object: CompletionCallback<List<Feature>> {
    override fun onSuccess(result: List<Feature>) {
        //Get Features Successful
    }

    override fun onError(throwable: Throwable) {
        //Get Features Error
    }
})

/**
* Possible classTypes:
*   - SkiLift::class.java
*   - SkiSlope::class.java
*   - Building::class.java
*   - BuildingAmenity::class.java
*/
// must execute load method successfully first on the map object
loadedScene.getFeatures(<classType>, new CompletionCallback<List<Feature>>() {
    @Override
    public void onSuccess(List<Feature> result) {
        //Get Features Successful
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
        //Get Features Error
    }
});

/**
* Possible classTypes:
*   - SkiLift.class
*   - SkiSlope.class
*   - Building.class
*   - BuildingAmenity.class
*/

Get all the available features in the scene like Ski run, lift, buidling, amenity, bookmarks, etc. that matches a given type.

SceneView

SceneView - Initialize

SceneView()

SceneView - Using XML UI

import io.bemappy.sdk.ui.SceneView
SceneView(context)

SceneView - Using Jetpack Compose

import io.bemappy.sdk.ui.compose.SceneView 
SceneView(scene, modifier, sceneController)
import io.bemappy.sdk.ui.SceneView;
new SceneView(context)

SceneView is an UI class that helps in rendering the 3D map. Once the scene is loaded, add the scene to SceneView and then you can add the same to your UI hierarchy.

Rotate To North

SceneView - Rotate To North

sceneView.rotateToNorth()

Rotate To North - Using XML UI (with View Binding or Data Binding)

binding.sceneView.rotateToNorth()

Rotate To North - Using Jetpack Compose

// must execute load method successfully first on the map object
val sceneController = remember { SceneController() }

SceneView(
    scene = loadedScene,
    modifier = Modifier,
    sceneController = sceneController
)

sceneController.rotateToNorth()
binding.sceneView.rotateToNorth();

Rotates the scene to the default orientation

Set Initial ViewPoint

SceneView - Set Initial ViewPoint

sceneView.setInitialViewpoint()

Set Initial ViewPoint - Using XML UI (with View Binding or Data Binding)

binding.sceneView.setInitialViewpoint()

Set Initial ViewPoint - Using Jetpack Compose

sceneController.setInitialViewpoint()
binding.sceneView.setInitialViewpoint();

Restores the scene to its initial state where the venue is entirely visible.

Tap on a Feature

Tap on a Feature

sceneView.event
    .receive(on: DispatchQueue.main)
    .sink(receiveValue: {
        switch $0 {
        case .onTap(let feature):
            // Handle the tap event
        default:
            break
        }
    })
    .store(in: &cancellables)

Tap Listener - Using XML UI (with View Binding or Data Binding)

binding.sceneView.setTapListener(object: TapListener {
        override fun onTouch(feature: Feature?) {
             // handle tap
        }
    }
)

Tap Listener - Using Jetpack Compose

SceneView(
    scene = loadedScene,
    modifier = Modifier.fillMaxSize(),
    sceneController = sceneController,
    onTap = { feature -> // handle tap }
)
binding.sceneView.setTapListener((feature) -> {
    //handle tap
});

A callback that will be invoked with the feature the user taps on.

View Point Change

SceneView - View Point Change

sceneView.event
    .receive(on: DispatchQueue.main)
    .sink(receiveValue: {
        switch $0 {
        case .onViewpointChange:
            // Handle the event
        default:
            break
        }
    })
    .store(in: &cancellables)

View Point Change Listener - Using XML UI (with View Binding or Data Binding)

binding.sceneView.setViewPointChangeListener(object: ViewpointChangeListener {
    override fun onChanged() {
        //handle viewpoint change
    }
})

View Point Change Listener - Using Jetpack Compose

SceneView(
    scene = loadedScene,
    modifier = Modifier.fillMaxSize(),
    sceneController = sceneController,
    onViewPointChanged = { 
        //handle viewpoint change
    }
)
// lambda example
binding.sceneView.setViewPointChangeListener(() -> {
    // handle viewpoint change
});

A callback that will be invoked every time when the user interacts with the Scene except in the case of a tap.

Select a Feature

Select a Feature

sceneView.select(feature: <Feature>)

Select a Feature - Using XML UI (with View Binding or Data Binding)

binding.sceneView.selectFeature(<Feature>)

Select a Feature - Using Jetpack Compose

SceneView(
    scene = loadedScene,
    modifier = Modifier.fillMaxSize(),
    sceneController = sceneController
)

sceneController.selectFeature(<Feature>)

Select a Feature - Using Jetpack Compose

binding.sceneView.selectFeature(<Feature>)

A function that highlights and zooms to the feature provided

Unselect a Feature

Unselect a Feature

sceneView.select(feature: nil)

Unselect a Feature - Using XML UI (with View Binding or Data Binding)

binding.sceneView.unselectFeature()

Unselect a Feature - Using Jetpack Compose

SceneView(
    scene = loadedScene,
    modifier = Modifier.fillMaxSize(),
    sceneController = sceneController
)

sceneController.unselectFeature()

Unselect a Feature

binding.sceneView.unselectFeature()

A function that removes the highlight from the selected feature