Using the latest ArcGIS Android API, what's the best way to create an inset map (i.e., MapView) at fixed zoom level (say 50,000).
Hello!
The Animate 3D Graphic sample has an inset map. Sync map and scene viewpoints might also help.
Let me know how it goes!
Cheers,
Trevor
Looked at the examples. I'm not famaliar with sceneView - so I tried with two MapViews. Was hoping that I could add the same map (i.e., ArcGISMap) to each mapView, then set the scale on my inset to a higher level. Unfortunately I keep getting the "Object already owned" exception. BTW, my map is coming from a mobile map package. Is this possible with a mmpk? Also, my mmpks are moderately heavy - so loading them multiple times was something I was looking to avoid.
I have not tried with a scene view because it does not appear to have options to easily change the scale (of course that could just be my lack of experince with SceneView).
Sample code below:
private MapView mMapView, mMapView_inset; private ArcGISMap arcGISMap, arcGISMap_inset; private MobileMapPackage mapPackage;
// snipmapPackage = new MobileMapPackage(pathToMmpkFile);
mapPackage.loadAsync(); // load the mobile map package asynchronously
mapPackage.addDoneLoadingListener(new Runnable() {
@Override
public void run() { // check load status and that the mobile map package has maps
switch (mapPackage.getLoadStatus()) {
// snip
case LOADED:
if (mapPackage.getMaps().size() > 0) {
arcGISMap = mapPackage.getMaps().get(0); // only load the 1st map
arcGISMap_inset = mapPackage.getMaps().get(0);
// add the map from the mobile map package to the MapView
mMapView.setMap(arcGISMap);
mMapView_inset.setMap(arcGISMap_inset); // <<<<<<<<<<<< ERROR HERE >>>>>>>>>>>>>>
Error message:
com.esri.arcgisruntime.ArcGISRuntimeException: Object already owned.: Already owned.
at com.esri.arcgisruntime.internal.jni.CoreMapView.nativeSetMap(Native Method)
at com.esri.arcgisruntime.internal.jni.CoreMapView.a(SourceFile:215)
at com.esri.arcgisruntime.internal.h.b.o.a(SourceFile:448)
at com.esri.arcgisruntime.mapping.view.MapView.setMap(SourceFile:580)
at mypackage.Map$30.run(Map.java:2935)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:7000)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
Hi!
The object already owned error refers to the same ArcGISMap being used by two different MapViews. Your code references the same map twice (thus the error).
The easiest way would be to open two mappackages from the same path, load them and set them to separate map views. Let me know if that helps.
Kind regards,
Trevor
Yes, I did learn this along the way. I ended up loading my mobile map package twice into distinct MobileMapPackage
objects. I essentially duplicated the code noted above, with seperate objects for the inset map:
mapPackage_inset = new MobileMapPackage(mmpkFile);private MapView mMapView, mMapView_inset; private ArcGISMap arcGISMap, arcGISMap_inset; private MobileMapPackage mapPackage, mapPackage_inset;// snip
mapPackage_inset.loadAsync(); // load the mobile map package asynchronously
mapPackage_inset.addDoneLoadingListener(new Runnable() {
@Override
public void run() { // check load status and that the mobile map package has maps
switch (mapPackage_inset.getLoadStatus()) {// snip
case LOADED:
Log.d(TAG, "loadMobileMapPackage_inset: MobileMapPackage: inset: " + getString(R.string.loaded));
if (mapPackage_inset.getMaps().size() > 0) {
arcGISMap_inset = mapPackage_inset.getMaps().get(0);
mMapView_inset.setMap(arcGISMap_inset);
That got me further down the road. I was then able to load two MapView objects! I was able to get the main MapView's viewpoint changes to ripple down to the inset MapView (using the method from the examples you suggested above) at a higher, desired, scale (i.e., zoomed out).
Unfortunately, that's where my progess ended. I ran into a bit of a show stopper: If I (1) open another activity (without "finish()ing" the map activity) then return to the map activty or (2) drop (hardware back button) the app then re-open it, the inset MapView does not appear to resume and disappears from the screen alltogether with out throwing any errors. Note that the main MapView, mMapView, resumes w/o issue. Further the inset MapView does perform pause/destroy/resume operations (code below).
Is there is a bug the prevents multiple MapViews from being resumed?
@Override protected void onPause() { if (mMapView != null) { mMapView.pause(); } if (mMapView_inset != null) { mMapView_inset.pause(); } super.onPause(); } @Override protected void onDestroy() { Log.d(TAG, "onDestroy: mMapView: " + mMapView); if (mMapView != null) { mMapView.dispose(); } Log.d(TAG, "onDestroy: mMapView_inset: " + mMapView_inset); if (mMapView_inset != null) { mMapView_inset.dispose(); } super.onDestroy(); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume: mMapView: " + mMapView); if (mMapView != null) { mMapView.resume(); Log.d(TAG, "onResume: mMapView: resumed: " + mMapView); } Log.d(TAG, "onResume: mMapView_inset: " + mMapView_inset); if (mMapView_inset != null) { mMapView_inset.resume(); Log.d(TAG, "onResume: mMapView_inset: resumed: " + mMapView_inset); }
Great, I'll check those out - thanks