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

Android: Multiple MapView's apparently not supported? #194

Closed
mar-v-in opened this issue Oct 2, 2016 · 22 comments
Closed

Android: Multiple MapView's apparently not supported? #194

mar-v-in opened this issue Oct 2, 2016 · 22 comments
Labels

Comments

@mar-v-in
Copy link

mar-v-in commented Oct 2, 2016

I see various issues when having multiple MapView's on Android at the same time:

  1. Sometimes, the text is not rendered correctly, there is only a black box where text is supposed to be
  2. Sometimes, parts of the map are not rendered (lines and/or areas).
  3. Sometimes, wrong symbols are put in place
  4. Sometimes, it just crashes.

Is it intended to support multiple map views at the same time?

@devemux86
Copy link
Collaborator

Could be due to shared static data among the map views.

If you want to provide a pull request example for Samples, in order to have it live and check it.

mar-v-in added a commit to mar-v-in/vtm that referenced this issue Oct 2, 2016
@mar-v-in
Copy link
Author

mar-v-in commented Oct 2, 2016

Set of screenshots done using the new sample just provided via PR: http://imgur.com/a/2b4TW

@devemux86
Copy link
Collaborator

devemux86 commented Oct 2, 2016

I improved slightly the multi map example with separate preferences.
Note: it keeps crashing on emulator, working with artifacts on device.

@andreynovikov
Copy link

MapView on Android uses GLSurfaceView. GLSurfaceViews can not overlap:
https://groups.google.com/forum/#!topic/android-developers/COffLpanlz0

@mathieudebrito
Copy link

mathieudebrito commented Nov 14, 2016

Hi Andrey, you can use mapview.setZOrderOnTop(true) on the map on the top
to make it work. You can also use mapview.setZOrderMediaOverlay(true);.
I have a working sample.

@devemux86
Copy link
Collaborator

@andreynovikov thanks for the info.
So they mention not overlapping, what about having them side by side?

@mathieudebrito
Copy link

mathieudebrito commented Jan 26, 2017

Hi guys,

I made a working sample of fragments stack showing different mapviews (as previously said, using mapview.setZOrderMediaOverlay(true);).
It works perfectly until you pop a fragment: coming back to the mapview of the previous fragment, it all works fine except labels.

Any ideas ? Where can I find the possible shared data in order to debug ?

device-2017-01-26-150944

@ocsike
Copy link

ocsike commented Apr 17, 2017

Hi,
Possible solution for black label. It's work for me
onResume event add: mLabelLayer.update();
and onPause event add mLabelLayer.clearLabels(); mMap.render();

Where mLabelLayer is a LabelLayer instance and mMap is a Map

@devemux86
Copy link
Collaborator

@ocsike where do you use those statements, have you managed to work with MultiMapActivity example?

@ocsike
Copy link

ocsike commented Apr 19, 2017

Yes, but is not perfect solution. Black labels are show when move or zoom the map, but not continuous and not all situation.
Here is a code:

public class MultiMapActivity extends Activity {
    private MapView mMapView1, mMapView2;
    private MapPreferences mPrefs1, mPrefs2;
	
	private LabelLayer map1LabelLayer;
	private LabelLayer map2LabelLayer;
	private Map map1; 
	private Map map2;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Tile.SIZE = Tile.calculateTileSize(getResources().getDisplayMetrics().scaledDensity);
        setContentView(R.layout.activity_map_multi);

        setTitle(getClass().getSimpleName());

        // 1st map view
        mMapView1 = (MapView) findViewById(R.id.mapView1);
        map1 = mMapView1.map();
        mPrefs1 = new MapPreferences(MultiMapActivity.class.getName() + "1", this);
        VectorTileLayer baseLayer1 = map1.setBaseMap(new OSciMap4TileSource());
		map1LabelLayer = new LabelLayer(map1, baseLayer1);
        map1.layers().add(new BuildingLayer(map1, baseLayer1));
        map1.layers().add(map1LabelLayer);
        map1.setTheme(VtmThemes.DEFAULT);

        // 2nd map view
        mMapView2 = (MapView) findViewById(R.id.mapView2);
        map2 = mMapView2.map();
        mPrefs2 = new MapPreferences(MultiMapActivity.class.getName() + "2", this);
        VectorTileLayer baseLayer2 = map2.setBaseMap(new OSciMap4TileSource());
		map2LabelLayer = new LabelLayer(map2, baseLayer2);
		
        map2.layers().add(new BuildingLayer(map2, baseLayer2));
        map2.layers().add(map2LabelLayer);
        map2.setTheme(VtmThemes.DEFAULT);
    }

    @Override
    protected void onResume() {
        super.onResume();

        mPrefs1.load(mMapView1.map());
        mMapView1.onResume();

        mPrefs2.load(mMapView2.map());
        mMapView2.onResume();
		
		
		map2LabelLayer.update();
		map1LabelLayer.update();
    }

    @Override
    protected void onPause() {
        super.onPause();

        mMapView1.onPause();
        mPrefs1.save(mMapView1.map());

        mMapView2.onPause();
        mPrefs2.save(mMapView2.map());
		
		map2LabelLayer.clearLabels(); 
		map2.render();
		
		map1LabelLayer.clearLabels(); 
		map1.render();
		
    }
}

2017_04_19_08 55 29

@mathieudebrito
Copy link

I tried your solution @ocsike but for me it's same with or without update()/clear()

Do anyone have any idea of when this issue will be addressed ?
This is really annoying when using the Android Backstack. because even if you have only one mapview, it gets messed up when just resuming the fragment. And when using multiple mapviews, it's just not usable anymore :p

@devemux86
Copy link
Collaborator

@mathieudebrito doesn't the fragment example in samples work?

@mathieudebrito
Copy link

mathieudebrito commented Apr 28, 2017

@devemux86 Indeed, it works with a single fragment.
But when we pause and resume multiple times using the fragment backstack, the map gets messed up :p

But it's also very annoying when using a main map as first fragment, and use secondary maps in others fragments. At this time, the map is always messed up.

NOTE: Because the map breaks out using fragment backstack, I'm forced to use another map libraries (osmdroid) for secondary maps

@Gustl22
Copy link

Gustl22 commented Feb 20, 2019

I'll try to solve. But cannot give any promises.

@devemux86
Copy link
Collaborator

There is MultiMapViewActivity sample to play.

It never got any traction due to small interest and as any solution must not affect rest library functionality.

@Gustl22
Copy link

Gustl22 commented Feb 20, 2019

As Note: I noticed that make GLState as object is a huge intervention in whole library which could have unexpected results. Even though current approach not correspond the design patterns I propose to let all be synchronized via current GLState and find a solution to for multiple MapViews with static context.

@devemux86
Copy link
Collaborator

devemux86 commented Feb 20, 2019

I noticed that make GLState as object is a huge intervention in whole library which could have unexpected results.

Indeed, one feature can never justify such huge intervention and the possible negative outcome.

@devemux86
Copy link
Collaborator

Not supported by library.

@mathieudebrito
Copy link

mathieudebrito commented Apr 2, 2020

Hi @devemux86 ! Sorry for the question, but I just want to clarify : Is this a "Not supported by library for now" or a "will Not be supported by library" ? thank you !

@devemux86
Copy link
Collaborator

"Not supported by library", the future is unknown... 🙂

It remains open source, but if changes are so huge, then like mentioned above:

"one feature can never justify such huge intervention and the possible negative outcome"

@vvavepacket
Copy link

vvavepacket commented Sep 29, 2020

As Note: I noticed that make GLState as object is a huge intervention in whole library which could have unexpected results. Even though current approach not correspond the design patterns I propose to let all be synchronized via current GLState and find a solution to for multiple MapViews with static context.

Hello @Gustl22, could you provide some context or background regarding what variables need to be synchronized, and whats the root cause in laymen's term? Would like to spend some personal time here to help solve this issue

@Gustl22
Copy link

Gustl22 commented Sep 30, 2020

Hi @vvavepacket, like @devemux86 mentioned the main reason is that library uses static variables (especially the GLState and some Pools, and may TileData) which is shared between multiple map instances but accessing the same indices.

I came to the conclusion, that it's very hard to find all shared (static) resources and properly separate them for each map view (uploaded my attempt here, which I wouldn't recommend). You may have luck if you synchronize the GLState calls for each draw (but doesn't solve the issue with shared pools e.g on TextBuckets).

Sorry haven't worked on VTM for a while to give you more insight. Unfortunately I'm busy with other projects, so can't afford much time for this issue. Maybe there's an easier proper solution, too, which I overlooked. Hope you can continue with these infos.

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

7 participants