Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

[android] app freeze when drawing lots of markerviews #9726

Closed

Description

@joaopedro1520

Hello, since version 5.1.0-5.12 when drawing ~100-300 markerviewoptions the app shows few icons with big icons and then freezes while trying to add all others for a good 5 seconds.
The code i use:

MarkerViewOptions options = new MarkerViewOptions().position(new LatLng(mapObject.getLatitude (), mapObject.getLongitude())).icon(UIUtils.getIcon(getAppCtx(), mapObject.getMarkerIcon(false, getAppCtx()))); mMapboxMap.addMarker(options);

Platform: Android
Mapbox SDK version: 5.1.0-5.1.2

Activity

  1. added
    AndroidMapbox Maps SDK for Android
    annotationsAnnotations on iOS and macOS or markers on Android
    on Aug 8, 2017
  2. Guardiola31337 commented on Aug 8, 2017

    @Guardiola31337
    Contributor

    @joaopedro1520 thank you for reaching out and reporting your problem.
    Similar issue was reported in #9026
    👀 #9026 (comment)

    BTW, if you move Icon creation out of the for loop it works fine.
    Actually, if you don't need to create a different Icon each time, you should implement it like this:

    public void addMarkers() {
        // Create Icon once so memory isn't waste it
        IconFactory iconFactory = IconFactory.getInstance(MainActivity.this);
        Drawable drawable = ContextCompat.getDrawable(MainActivity.this, R.drawable.poi);
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        Icon icon = iconFactory.fromBitmap(bitmap);
        //
        for (int i=0; i<MARKERS_CNT; i++) {
            Random r = new Random();
            double lat = r.nextDouble() * 50;
            double lon = r.nextDouble() * 50;
              
            Marker marker = mapBoxMap.addMarker(new MarkerOptions()
                    .position(new LatLng(lat, lon))
                    .icon(icon));
        }
    }

    ☝️ is using Markers but the same applies to MarkerViews.

    How are you creating the MarkerViews? If there is any sample or pseudo code you can provide, that would also be really helpful.

  3. joaopedro1520 commented on Aug 8, 2017

    @joaopedro1520
    Author

    The function i posted above is inside a for cycle for marker creation. I have different icons that i need to create depending on a mapObject

  4. Guardiola31337 commented on Aug 9, 2017

    @Guardiola31337
    Contributor

    @joaopedro1520 👀 #9026 (comment) that might help

    I create icon before loop and it works fine. But if you need use different icons for markers I recommended divide objects into several parts and call several loop.

    BTW, did you try using Markers and MarkerOption instead? It performs better.

    Another option would be using Symbols. It’s even more optimal than Markers. Symbols are part of the Mapbox style specification and allow to SymbolLayers to show icons/text labels on the map. 👀 the SymbolLayerActivity example for further information.

  5. joaopedro1520 commented on Aug 10, 2017

    @joaopedro1520
    Author

    Yeah I tried using them but they don't fit my needs. The thing is that on the previous versions it worked fine

  6. Guardiola31337 commented on Sep 6, 2017

    @Guardiola31337
    Contributor

    Hey @joaopedro1520

    We're moving from an Android SDK View to a core implementation. Progress on the implementation in #9782

    As a workaround, you could implement that behavior from your side 👀 the implementation details in #9782 or wait until that PR lands.

    Eventually, that will be implemented as a plugin 👉 mapbox/mapbox-plugins-android#7

  7. tobrun commented on Sep 27, 2017

    @tobrun
    Member

    MarkerView is going to be deprecated with #9782. We are no longer maintaining this API and will remove it in future versions of the SDK. As noted in the deprecation message. We are advising users to leverage SymbolLayer instead (you can use the sample code in #9782 to convert Android SDK views to an Image to be used as a Symbol). While we no longer maintain the API we are happy to accept any PRs on it.

  8. joaopedro1520 commented on Sep 27, 2017

    @joaopedro1520
    Author

    @tobrun I followed the symbol layer approach and its indeed faster drawing the markers on map. The problem is that after you add ~1000 the map becomes really slow when performing gestures. I ended up using MarkerOptions and needed to adapt few things so my app can support it. The symbol layer approach is good for some markers but for many it makes the map slow

  9. tobrun commented on Sep 27, 2017

    @tobrun
    Member

    @joaopedro1520 that shouldn't happen, can you add some code on how you are creating/adding your layer? A good reference implementation for a symbollayer with different images can be found here. Since you are talking about 1000 markers, have you tried using clustering?

  10. joaopedro1520 commented on Sep 27, 2017

    @joaopedro1520
    Author

    @tobrun this was my approach, I might be doing something wrong but i followed the implementation you posted.

    I added 1000 markers for testing performance against markerview.

    `

                    for (MapObject tmpObject : data) {
    
                        Random rand = new Random();
    
                        FeatureCollection markers = FeatureCollection.fromFeatures(new Feature[] {Feature.fromGeometry(Point.fromCoordinates(new double[]{tmpObject.getLongitude(), tmpObject.getLatitude()}))});
                        int n = rand.nextInt(5000000) + 1;
    
                        Source source = new GeoJsonSource(GENERATED_SYMBOL_SOURCE_ID + n, markers);
                        mMapboxMap.addSource(source);
    
                        ImageView imageView = new ImageView(getAppCtx());
                        imageView.setImageResource(R.drawable.mapbox_marker_icon_default);
    
    
                        // create bitmap from view
                        String iconId = GENERATED_SYMBOL_IMAGE_ID_BASE + tmpObject.getId();
                        mMapboxMap.addImage(iconId,SymbolGenerator.generate(imageView) );
    
                        // create layer for bitmap and filter source on name
                        String layerId = GENERATED_SYMBOL_LAYER_ID_BASE + tmpObject.getId();
                        layerIds.add(layerId);
                        mMapboxMap.addLayer(new SymbolLayer(layerId, GENERATED_SYMBOL_SOURCE_ID+n)
                                .withProperties(
                                        iconImage(iconId),
                                        iconAllowOverlap(false)
                                )
                        );
    
    
                    }
    

    `

  11. tobrun commented on Sep 27, 2017

    @tobrun
    Member

    in this case you have a layer for each marker, I could advice you to use a one layer approach instead. It's possible to have a symbolLayer with different images. The example here does this. With that in place you should be able to hit 1000 symbols on a map.

  12. joaopedro1520 commented on Oct 3, 2017

    @joaopedro1520
    Author

    @tobrun Hi again,
    I tried the approach above and I have around a ~1000 icons, but they only start appearing gradually when zoom its applied to their position. When zooming out it only shows 4/5 markers from all the 1000 Is this a feature of symbol layer or there might be something wrong?
    Thanks

  13. tobrun commented on Oct 3, 2017

    @tobrun
    Member

    SymbolLayer exposes allowIconOverlap as a property, setting it to true will always show all symbols.

  14. joaopedro1520 commented on Oct 4, 2017

    @joaopedro1520
    Author

    @tobrun So i managed to add different markers onto the same layer but something really strange is happening. I even tried to add just a unique marker but still didnt solve the problem.
    Here is the behaviour after i add lots of markers to the map
    screenshot_2017-10-04-14-26-56

    Here is the code

    `

             List<Feature> markerCoordinates = new ArrayList<>();
                    for (MapObject tmpObject : data) {
    
                        Feature feature = Feature.fromGeometry(
                                Point.fromCoordinates(com.mapbox.services.commons.models.Position.fromCoordinates(tmpObject.getLongitude(),tmpObject.getLatitude())));
                        feature.addStringProperty("nameProperty",tmpObject.getId());
    
                        markerCoordinates.add(feature);
    
                        markers.put(tmpObject.getId(),new LatLng(tmpObject.getLatitude(),tmpObject.getLongitude()));
    
                        ImageView imageView = new ImageView(getContext());
                        imageView.setImageResource(tmpObject.getMarkerIcon(false, getContext()));
    
                        Bitmap icon = UIUtils.getMapMarker(getContext(), mapMarkers, tmpObject.getMarkerIcon(false, getContext()));
    
    
                        // Add the marker image to map
                        mMapboxMap.addImage(tmpObject.getId(),icon );
    
                    }
    
                    FeatureCollection featureCollection = FeatureCollection.fromFeatures(markerCoordinates);
    
                    Source geoJsonSource = new GeoJsonSource("marker-source1", featureCollection);
    
                    mMapboxMap.addSource(geoJsonSource);
                    sources.add(geoJsonSource);
    
                    SymbolLayer markers = new SymbolLayer("marker-layer1", "marker-source1")
                            .withProperties(iconImage("{nameProperty}"),iconAllowOverlap(false));
    
    
                    mMapboxMap.addLayer(markers);
                    layers.add(markers);
    

    `

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    AndroidMapbox Maps SDK for AndroidannotationsAnnotations on iOS and macOS or markers on Androidbugneeds information

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions