Popup markers in MapBox SDK 10.10.1 for Android

76 Views Asked by At

I'm trying to implement a mechanism where a set of peaks described in a geojson file are marked on a Mapbox map. These markers should show additional information once a user clicks on them, showing the name of the peak, elevation, lat and long.

I'm having a hard time implementing this mechanism as pretty much all of the examples available online were made in Mapbox SDK v9, whereas I'm using SDK v10 - and the changes between these two were major. The fact that SDK v10 has only documentation in Kotlin and I'm writing in Java doesn't help either.

I coupled together some examples of such implementation I found online, but I'm unable to get the app running. The problem that I have is that I'm unable to read the geojson file, and I'm unable to add a layer with the geojson data to the map. For the methods below, I'm getting the "cannot resolve method "..." in 'Style'

style.addSource(geoJsonSource); style.addLayer(symbolLayer);

I'd appreciate if someone could point me in the right direction. The Mapbox documentation is not clear on this topic for me.

Here's my attempt below:

public class MapyActivity extends AppCompatActivity {

private MapView mapView;
FloatingActionButton floatingActionButton;

private MapboxMap mapboxMap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_mapy);

    mapView = findViewById(R.id.mapView);
    floatingActionButton = findViewById(R.id.focusLocation);
    floatingActionButton.hide();

    //adding map annotations

    if (ActivityCompat.checkSelfPermission(MapyActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        activityResultLauncher.launch((Manifest.permission.ACCESS_FINE_LOCATION));
    }

    mapView.getMapboxMap().loadStyleUri("mapbox://styles/hikegreg/clormq18j00q201qm3jbaewmr", new Style.OnStyleLoaded() {
        
        @Override
        public void onStyleLoaded(@NonNull Style style) {

            addMarkersFromGeoJson(style);

            mapView.getMapboxMap().setCamera(new CameraOptions.Builder().zoom(5.0).build());
            LocationComponentPlugin locationComponentPlugin = getLocationComponent(mapView);
            locationComponentPlugin.setEnabled(true);
            LocationPuck2D locationPuck2D = new LocationPuck2D();
            locationPuck2D.setBearingImage(AppCompatResources.getDrawable(MapyActivity.this, R.drawable.baseline_location_on_24));
            locationComponentPlugin.setLocationPuck(locationPuck2D);
            locationComponentPlugin.addOnIndicatorPositionChangedListener(onIndicatorPositionChangedListener);
            locationComponentPlugin.addOnIndicatorBearingChangedListener(onIndicatorBearingChangedListener);
            getGestures(mapView).addOnMoveListener(onMoveListener);

            floatingActionButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    locationComponentPlugin.addOnIndicatorBearingChangedListener(onIndicatorBearingChangedListener);
                    locationComponentPlugin.addOnIndicatorPositionChangedListener(onIndicatorPositionChangedListener);
                    getGestures(mapView).addOnMoveListener(onMoveListener);
                    floatingActionButton.hide();
                }
            });
        }
        });
}

private void addMarkersFromGeoJson(Style style) {
    try {
        //load geojson first
        InputStream inputStream = getAssets().open("tatry_wierzcholki.geojson");
        byte[] buffer = new byte[inputStream.available()];
        inputStream.read(buffer);
        inputStream.close();
        String geoJson = new String(buffer, "UTF-8");
        GeoJsonSource source = null;

        //make geojson source with geojson data
        GeoJsonSource geoJsonSource = new GeoJsonSource.Builder("geojson-source")
                .data(geoJson)
                .build();

        style.addSource(geoJsonSource);

        //symbol layer creation
        SymbolLayer symbolLayer = new SymbolLayer("symbol-layer", "geojson-source")
                .iconImage("marker-icon")
                .iconAllowOverlap(true);

        style.addLayer(symbolLayer);

        //add marker click listener
        GesturesPlugin gesturesPlugin = getGestures(mapView);
        gesturesPlugin.addOnMapClickListener(new OnMapClickListener() {
            @Override
            public boolean onMapClick(@NonNull Point point) {
                ScreenCoordinate screenCoordinate = mapView.getMapboxMap().pixelForCoordinate(point);
                List<QueriedFeature> features = mapView.getMapboxMap().queryRenderedFeatures(screenCoordinate, "symbol-layer");

                if(!features.isEmpty()){
                    QueriedFeature feature = features.get(0);
                    Feature geoJsonFeature = feature.getFeature();
                    String name = geoJsonFeature.getStringProperty("name");
                    Double elevation = (Double) geoJsonFeature.getNumberProperty("elevation");
                    Point featurePoint = (Point) geoJsonFeature.geometry();
                    double latitude = featurePoint.latitude();
                    double longitude = featurePoint.longitude();

                    showMarkerDetails(name, elevation, latitude, longitude);
                }
                return true;
            }

            private void showMarkerDetails(String name, Double elevation, double latitude, double longitude){
                String message = "Name: " + name + "\n" +
                        "Elevation: " + elevation + "m\n" +
                        "Latitude: " + latitude + "\n" +
                        "Longitude: " + longitude;

                new AlertDialog.Builder(this)
                        .setTitle("Marker Details")
                        .setMessage(message)
                        .setPositiveButton("Close",null)
                        .show();
            }
        });
        //handle IOExceptions
    } catch (IOException e) {
        e.printStackTrace();
        //handle potential json parsing errros
    } catch (JSONException e){
        e.printStackTrace();
        //handle any other unexpected errors
    } catch (Exception e) {
        e.printStackTrace();
    }
}
1

There are 1 best solutions below

0
Chathura Abeywickrama On

Replace:

style.addSource(geoJsonSource);
style.addLayer(symbolLayer);

with:

style.addSource(geoJsonSource);
style.addLayerAbove(symbolLayer, "com.mapbox.mapboxsdk.annotations.points");