Highlight Features
Contents
The Mobile Maps SDK examples require that you first complete the initial project set-up.
Highlight places on the map. The highlights are updated each time the map is panned.
activity_sample_highlight_features.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent">
<com.trimblemaps.mapsdk.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent"/>
</FrameLayout>
Sample Code
Before running the Java or Kotlin code, the theme needs to be set in the Theme.xml
file as shown below.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.AsyncAcctInit" parent="Theme.AppCompat" />
</resources>
package com.trimblemaps.navigationexamples;
import android.content.Context;
import android.graphics.RectF;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.trimblemaps.account.LicensedFeature;
import com.trimblemaps.account.TrimbleMapsAccountManager;
import com.trimblemaps.account.models.TrimbleMapsAccount;
import com.trimblemaps.android.gestures.MoveGestureDetector;
import com.trimblemaps.geojson.FeatureCollection;
import com.trimblemaps.mapsdk.TrimbleMaps;
import com.trimblemaps.mapsdk.camera.CameraPosition;
import com.trimblemaps.mapsdk.geometry.LatLng;
import com.trimblemaps.mapsdk.maps.MapView;
import com.trimblemaps.mapsdk.maps.OnMapReadyCallback;
import com.trimblemaps.mapsdk.maps.Style;
import com.trimblemaps.mapsdk.maps.TrimbleMapsMap;
import com.trimblemaps.mapsdk.style.layers.Layer;
import com.trimblemaps.mapsdk.style.layers.LineLayer;
import com.trimblemaps.mapsdk.style.layers.PropertyFactory;
import com.trimblemaps.mapsdk.style.layers.PropertyValue;
import com.trimblemaps.mapsdk.style.sources.GeoJsonSource;
import com.trimblemaps.mapsdk.style.sources.Source;
import java.util.Collections;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class SampleHighlightFeaturesAfterPanningActivity extends AppCompatActivity {
private MapView mapView;
private TrimbleMapsMap map;
private final List<com.trimblemaps.geojson.Feature> highlights = Collections.emptyList();
private final String highlightsSrcLayer = "highlighted_places";
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TrimbleMapsAccount trimbleMapsAccount = TrimbleMapsAccount.builder()
.apiKey("Your-API-key-here")
.addLicensedFeature(LicensedFeature.MAPS_SDK).build();
TrimbleMapsAccountManager.initialize(trimbleMapsAccount);
TrimbleMapsAccountManager.awaitInitialization();
TrimbleMaps.getInstance((Context) this);
this.setContentView(R.layout.activity_sample_highlight_features);
this.mapView = (MapView) this.findViewById(R.id.mapView);
if (this.mapView != null) {
this.mapView.getMapAsync((OnMapReadyCallback) (new OnMapReadyCallback() {
public final void onMapReady(@NotNull TrimbleMapsMap trimbleMapsMap) {
map = trimbleMapsMap;
map.setStyle((new Style.Builder())
.fromUri(Style.MOBILE_NIGHT)
.withSource((Source) (new GeoJsonSource(highlightsSrcLayer, FeatureCollection.fromFeatures(highlights))))
.withLayer((Layer) (new LineLayer(highlightsSrcLayer, highlightsSrcLayer))
.withProperties(new PropertyValue[]{PropertyFactory.lineWidth(4.0F), PropertyFactory.lineColor(-256), PropertyFactory.lineOpacity(0.8F)})));
if (map != null) {
map.setCameraPosition((new CameraPosition.Builder()).target(new LatLng(40.570247273677154, -74.2586578116128)).zoom(15.0).build());
}
if (map != null) {
map.addOnMoveListener((TrimbleMapsMap.OnMoveListener) (new TrimbleMapsMap.OnMoveListener() {
public void onMoveBegin(@NotNull MoveGestureDetector moveGestureDetector) {
}
public void onMove(@NotNull MoveGestureDetector moveGestureDetector) {
}
public void onMoveEnd(@NotNull MoveGestureDetector moveGestureDetector) {
RectF view = getRectF();
List<com.trimblemaps.geojson.Feature> features = map != null ? map.queryRenderedFeatures(view, new String[]{"places_sites"}) : null;
if (map != null) {
if (map.getStyle() != null) {
GeoJsonSource geoJsonSource = (GeoJsonSource) map.getStyle().getSourceAs(highlightsSrcLayer);
if (geoJsonSource != null) {
geoJsonSource.setGeoJson(FeatureCollection.fromFeatures(features));
}
}
}
}
}));
}
}
}));
}
}
@NonNull
private RectF getRectF() {
float mapViewLeft = (float) (mapView != null ? mapView.getLeft() : 0);
float mapViewTop = (float) (mapView != null ? mapView.getTop() : 0);
float mapViewRight = (float) (mapView != null ? mapView.getRight() : 0);
float mapViewBottom = (float) (mapView != null ? mapView.getBottom() : 0);
return new RectF(mapViewLeft, mapViewTop, mapViewRight, mapViewBottom);
}
protected void onStart() {
super.onStart();
if (this.mapView != null) {
this.mapView.onStart();
}
}
protected void onResume() {
super.onResume();
if (this.mapView != null) {
this.mapView.onResume();
}
}
protected void onPause() {
super.onPause();
if (this.mapView != null) {
this.mapView.onPause();
}
}
protected void onStop() {
super.onStop();
if (this.mapView != null) {
this.mapView.onStop();
}
}
public void onLowMemory() {
super.onLowMemory();
if (this.mapView != null) {
this.mapView.onLowMemory();
}
}
protected void onDestroy() {
super.onDestroy();
if (this.mapView != null) {
this.mapView.onDestroy();
}
}
}
package com.trimblemaps.kotlinsamples.samples
import android.graphics.Color
import android.graphics.RectF
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.trimblemaps.account.LicensedFeature
import com.trimblemaps.account.TrimbleMapsAccountManager
import com.trimblemaps.account.models.TrimbleMapsAccount
import com.trimblemaps.android.gestures.MoveGestureDetector
import com.trimblemaps.geojson.Feature
import com.trimblemaps.geojson.FeatureCollection
import com.trimblemaps.mapsdk.TrimbleMaps
import com.trimblemaps.mapsdk.camera.CameraPosition
import com.trimblemaps.mapsdk.geometry.LatLng
import com.trimblemaps.mapsdk.maps.MapView
import com.trimblemaps.mapsdk.maps.Style
import com.trimblemaps.mapsdk.maps.TrimbleMapsMap
import com.trimblemaps.mapsdk.maps.TrimbleMapsMap.OnMoveListener
import com.trimblemaps.mapsdk.style.layers.LineLayer
import com.trimblemaps.mapsdk.style.layers.PropertyFactory
import com.trimblemaps.mapsdk.style.sources.GeoJsonSource
class SampleHighlightFeaturesAfterPanningActivity : AppCompatActivity() {
private var mapView: MapView? = null
private var map: TrimbleMapsMap? = null
private var highlights : List<Feature> = listOf()
private var highlightsSrcLayer = "highlighted_places"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Authorize the api key for the session.
// .apiKey() requires your Trimble Maps API key
val trimbleMapsAccount = TrimbleMapsAccount.builder()
.apiKey("Your-API-key-here")
.addLicensedFeature(LicensedFeature.MAPS_SDK)
.build()
// Initialize the session
TrimbleMapsAccountManager.initialize(trimbleMapsAccount)
TrimbleMapsAccountManager.awaitInitialization()
// Get an instance of the map, done before the layout is set.
TrimbleMaps.getInstance(this)
setContentView(R.layout.activity_sample_highlight_features)
// Set up the MapView from the layout
mapView = findViewById(R.id.mapView)
// the onMapReadyCallback is fired when the map is ready to be worked with
mapView?.getMapAsync { trimbleMapsMap ->
map = trimbleMapsMap
// The TrimbleMapsMap object is created, now a style can be applied to render a map.
// Adding the source and layer for the Places highlighted. Site outlines will be
// displayed in yellow
trimbleMapsMap.setStyle(
Style
.Builder()
.fromUri(Style.MOBILE_NIGHT)
.withSource(GeoJsonSource(highlightsSrcLayer, FeatureCollection.fromFeatures(highlights)))
.withLayer(
LineLayer(highlightsSrcLayer, highlightsSrcLayer).withProperties(
PropertyFactory.lineWidth(4f),
PropertyFactory.lineColor(Color.YELLOW),
PropertyFactory.lineOpacity(.8f)
))
)
map?.cameraPosition = CameraPosition.Builder()
.target(LatLng( 40.570247273677154, -74.2586578116128))
.zoom(15.0)
.build()
map?.addOnMoveListener(object : OnMoveListener {
override fun onMoveBegin(moveGestureDetector: MoveGestureDetector) {
}
override fun onMove(moveGestureDetector: MoveGestureDetector) {
}
override fun onMoveEnd(moveGestureDetector: MoveGestureDetector) {
// We only care about when movement stops
// get all features in the user's current view
val view = RectF(mapView?.left!!.toFloat(), mapView?.top!!.toFloat(), mapView?.right!!.toFloat(), mapView?.bottom!!.toFloat())
// Find any features from the "places_sites" layer that our point intersects
val features = map?.queryRenderedFeatures(view, "places_sites")
// Update/Replace the source of data with these new found features
map?.style?.getSourceAs<GeoJsonSource>(highlightsSrcLayer)?.setGeoJson(
FeatureCollection.fromFeatures(features!!))
}
})
}
}
/**
* Activity Overrides
*/
override fun onStart() {
super.onStart()
mapView?.onStart()
}
override fun onResume() {
super.onResume()
mapView?.onResume()
}
override fun onPause() {
super.onPause()
mapView?.onPause()
}
override fun onStop() {
super.onStop()
mapView?.onStop()
}
override fun onLowMemory() {
super.onLowMemory()
mapView?.onLowMemory()
}
override fun onDestroy() {
super.onDestroy()
mapView?.onDestroy()
}
}