Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programmatically-added LineLayer disappears at some zoom levels #3075

Closed
Riningan opened this issue Dec 10, 2024 · 8 comments
Closed

Programmatically-added LineLayer disappears at some zoom levels #3075

Riningan opened this issue Dec 10, 2024 · 8 comments
Labels

Comments

@Riningan
Copy link

Riningan commented Dec 10, 2024

MapLibre Android Version

11.6.1

Android SDK Version

Android 14

Device

Google Pixel 6a

What happened?

I catch bug when trying generate snapshot with line. The line cutting at specific zoom level. In screenshot, line starts and ends on Android icons.
On zoom 12.9 or lower bug is not repeated.
Image

Bug is repeated on zoom 13.0 or higher.
Image

On zoom 15.0 or higher the line disappears completely.
Image

Also bug repeated only for specific points. For example:

  LatLng(58.005540000000000, 56.298040000000000),
  LatLng(58.015180000000000, 56.286520000000000)

I think the problem repeating only at specific line angles.

Also bug repeated on vulkan version.

Steps to reproduce

Activity code

class MapSnapshotterActivity : AppCompatActivity() {
    lateinit var imageView: ImageView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_map_snapshotter)

        imageView = findViewById(R.id.snapshot)
        imageView.getViewTreeObserver()
            .addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this)
                    addSnapshot()
                }
            })
    }

    private fun addSnapshot() {
        val latlngs = listOf(
            LatLng(58.005540000000000, 56.298040000000000),
            LatLng(58.015180000000000, 56.286520000000000)
        )

        val builder = Style.Builder()
            .fromUri("https://tiles.versatiles.org/assets/styles/colorful.json")
            .withSources(
                GeoJsonSource(LINE_SOURCE, FeatureCollection.fromFeatures(
                    arrayOf(
                        Feature.fromGeometry(
                            MultiPoint.fromLngLats(
                                latlngs.map { Point.fromLngLat(it.longitude, it.latitude) }
                            ),
                            JsonObject()
                        )
                    )
                ))
            )
            .withSources(
                GeoJsonSource(MARKER_SOURCE, FeatureCollection.fromFeatures(
                    latlngs.map {
                        Feature.fromGeometry(
                            Point.fromLngLat(it.longitude, it.latitude),
                            JsonObject()
                        )
                    }
                ))
            )
            .withLayers(
                LineLayer(LINE_LAYER, LINE_SOURCE).withProperties(
                    PropertyFactory.lineColor(Color.RED),
                    PropertyFactory.lineWidth(5f)
                )
            )
            .withLayers(
                SymbolLayer(MARKER_LAYER, MARKER_SOURCE).withProperties(
                    PropertyFactory.iconImage("icon")
                )
            )
            .withImage("icon", ResourcesCompat.getDrawable(resources, R.drawable.ic_android_2, theme)!!.toBitmap())

        val options = MapSnapshotter
            .Options(imageView.measuredWidth, imageView.measuredHeight)
            .withPixelRatio(1f)
            .withCameraPosition(
                CameraPosition.Builder()
                    .target(
                        LatLng(
                            latlngs.sumOf { it.latitude } / latlngs.size,
                            latlngs.sumOf { it.longitude } / latlngs.size
                        )
                    )
                    .zoom(15.0)
                    .build()
            )
            .withStyleBuilder(builder)

        val snapshotter = MapSnapshotter(this@MapSnapshotterActivity, options)
        snapshotter.start({ snapshot ->
            imageView.setImageBitmap(snapshot.bitmap)
        })
    }

    companion object {
        private const val LINE_SOURCE = "line-source"
        private const val MARKER_SOURCE = "marker-source"
        private const val LINE_LAYER = "line-layer"
        private const val MARKER_LAYER = "marker-layer"
    }
}

layout

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/snapshot"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@null" />

</FrameLayout>

Renderer

OpenGL (choose this if you are unsure), Vulkan

@louwers louwers added OpenGL Issues related to the OpenGL renderer backend Vulkan labels Dec 10, 2024
@louwers
Copy link
Collaborator

louwers commented Dec 10, 2024

Confirmed. Thank you for the detailed report.

I have pushed a reproduction to repro-3075 (use the Map Snapshotter Acitivty in MapLibreAndroidTestApp) if someone can have a look at this.

This bug also happens for legacy.

@louwers
Copy link
Collaborator

louwers commented Dec 10, 2024

Looks like the snapshot is a red herring. Also happens for a normal map.

screen-20241210-142312.mp4

I have updated 'Snapshot Activity' with the repro as well.

@louwers
Copy link
Collaborator

louwers commented Dec 10, 2024

I tried 10.2.0 and it's the same behavior there. So this is a very old bug.

@louwers louwers changed the title Snapshot incorrect line drawing Pragmatically added LineLayer disappears at some zoom levels Dec 10, 2024
@louwers louwers removed OpenGL Issues related to the OpenGL renderer backend Vulkan labels Dec 10, 2024
@TimSylvester TimSylvester changed the title Pragmatically added LineLayer disappears at some zoom levels Programmatically-added LineLayer disappears at some zoom levels Dec 10, 2024
@TimSylvester
Copy link
Collaborator

I'm not sure if this is a real bug or just a lack of support for what seems like an obvious use-case of using a geoJSON MultiPoint to specify a line feature.

The core problem is that when the MultiPoint feature is split up, it ends up generating a tile with just one point in some cases. The line generation code of course rejects this as invalid geometry and produces nothing.

The geoJSON splitting code (geojsonvt.hpp) is external and doesn't pay attention to the feature types. So I think that by the time we know we're using the result for lines (LineBucket::addFeature), it's already too late to do anything. So there's no simple fix.

The good news, though, is that there's a simple way you can avoid it: using line features instead of points.

Instead of:

                            MultiPoint.fromLngLats(
                                latlngs.map { Point.fromLngLat(it.longitude, it.latitude) }
                            ),

use:

                        LineString.fromLngLats(
                            MultiPoint.fromLngLats(
                                latlngs.map { Point.fromLngLat(it.longitude, it.latitude) }
                            )),

or, of course, construct the LineString directly, but it didn't like taking latlngs as a parameter but does accept a MultiPoint.

@Riningan
Copy link
Author

Thanks. Wrapping with LineString works fine. What about issue. Need close or not?

@TimSylvester
Copy link
Collaborator

Since this is the same in 10.x, and not a simple change, I expect we'll consider it "as designed" and not something we will try to fix. Bart, Steve, re-open otherwise.

@TimSylvester TimSylvester reopened this Dec 12, 2024
@TimSylvester TimSylvester closed this as not planned Won't fix, can't repro, duplicate, stale Dec 12, 2024
@louwers
Copy link
Collaborator

louwers commented Dec 12, 2024

@TimSylvester Thanks for looking into it. It is definitely a gotcha, but probably not worth fixing since there is a good workaround.

@TimSylvester
Copy link
Collaborator

How about a one-time log warning?

line_bucket.cpp:88-91

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants