Hello,
I want to know how we can load more than one mmpk file for a single screen.Right now I am using this c++ in qt Creator 5.12.0 and ARCGIS 100.4 on RHEL 7.6.Go through this code if i am doing any mistake then please correct.
path1
= "/home/Gis/ChartEngine/Arcgis/Runtime/Data/MMpk/India.mmpk";path2
= "/home/Gis/ChartEngine/Arcgis/Runtime/Data/MMpk/Pak.mmpk";MobileMapPackage *
m_mobileMapPackage1 = new MobileMapPackage(path1, this);
connect(m_mobileMapPackage1, &MobileMapPackage::doneLoading, this, [this](Error error) { m_mapView->setMap(m_mobileMapPackage1->maps().at(0)); });
MobileMapPackage *
m_mobileMapPackage2 = new MobileMapPackage(path1, this); connect(m_mobileMapPackage2, &MobileMapPackage::doneLoading, this, [this](Error error) { m_mapView->setMap(m_mobileMapPackage2->maps().at(0)); });
m_mobileMapPackage->load();
m_mobileMapPackage2->load();
So when screen is coming , whatever is getting loaded last that one is only getting shown in screen.
My project requirement :-
I have to show india and pak in a single view by using mmpk file.Aditya PeriAlexandra GajewskiAndrew RossAllen ThompsonRebecca McKinleyJon Fiskness Hilary LeavellHuailin wangArcGIS IdeasException rendering offline FeatureLayerquery on ShapefileFeatureTable
Hi anshu shrivastava,
Each MapView has only one Map. The preferable solution here would be to author the data so that all the operational layers and data are within the same Map to begin with, and then to load that Map into the MapView.
Are you able to re-author the data?
Hi ,
Thank you for reply , I am not able to re-author the data .It will be very appreciable if you can provide some example code ,for loading more than one mmpk file for single mapview.
Hi ,
Thank you for reply , I am not able to re-author the data .It will be very appreciable if you can provide some example code ,for loading more than one mmpk file for single mapview.
Ok, in that case there are a few options. I must say, this is not ideal as the Map should contain all its respective data and layers to begin with.
Option 1: unpack the mmpk to disk and create all the layers programmatically. When you unpack the mobile map package, it will (or may) contains tpk and possibly geodatabase files that can be used to load and create all the layers from those files.
MobileMapPackage Class | ArcGIS for Developers
Option 2: "take" the layers from one map and place them in the other map. This will only work if one of the maps is destroyed. In this case, you will load both mobile map packages like in your sample, but for one of the maps you will change the workflow as follows:
path1 = "/home/Gis/ChartEngine/Arcgis/Runtime/Data/MMpk/India.mmpk";
path2 = "/home/Gis/ChartEngine/Arcgis/Runtime/Data/MMpk/Pak.mmpk";
MobileMapPackage *m_mobileMapPackage1 = new MobileMapPackage(path1, this);
connect(m_mobileMapPackage1, &MobileMapPackage::doneLoading, this, [this](Error) {
m_mapView->setMap(m_mobileMapPackage1->maps().at(0));
m_mobileMapPackage2->load();
});
MobileMapPackage *m_mobileMapPackage2 = new MobileMapPackage(path1, this);
connect(m_mobileMapPackage2, &MobileMapPackage::doneLoading, this, [this](Error) {
auto* map2 = m_mobileMapPackage2->maps().at(0));
QList<Layer*> layersFromMap2;
for (auto* layerFromMap2 : *(map2->operationalLayers()))
{
layersFromMap2.append(layerFromMap2);
layerFromMap2->setParent(this); // re-parent the layers
}
// delete the map
delete map2;
// add all the layers to the mapView's map
auto* operationalLayers = m_mapView->map()->operationalLayers();
for (auto* layer : layersFromMap2)
operationalLayers->append(layer);
});
m_mobileMapPackage->load();
This is pseudo code and may have some errors, but this is the general workflow. Please let us know if this works.
In both cases, the ordering of the layers may not be preserved properly so you may need to adjust which order the layers are added in.
Hi James ,
We tried this pseudo code but still we are not able to load two mmpk data for single screen.Please go through this code if i am doing any mistak
void CTacticalViewClass::LoadingOfmmpkfile(const QUrl &file,const QUrl &file2)
{
QString dataPath = file.toString();
QString dataPath2 = file2.toString();
m_mobileMapPackage = new MobileMapPackage(dataPath, this);
m_mobileMapPackage1 = new MobileMapPackage(dataPath2, this);
connect(m_mobileMapPackage, &MobileMapPackage::doneLoading, this, [this](Error error)
{
if (error.isEmpty())
{
m_mapView->setMap(m_mobileMapPackage->maps().at(0));
qDebug()<<"m_mapView->map()->operationalLayers()"<<m_mapView->map()->operationalLayers()->size()<<m_mobileMapPackage->maps().at(0)->operationalLayers()->size();
m_mobileMapPackage1->load();
}
});
/*
* tried but not working completely
connect(m_mobileMapPackage1, &MobileMapPackage::doneLoading, this, [this](Error) {
auto* map2 = m_mobileMapPackage1->maps().at(0);
qDebug()<<"Operational layer count ------>>"<<m_mobileMapPackage1->maps().at(0)->operationalLayers()->size()<<"map2"<<map2->operationalLayers()->size();
QList<Layer*> layersFromMap2;
LayerListModel* layerFromMap2;
for (int i = 0;i<m_mobileMapPackage1->maps().at(0)->operationalLayers()->size();i++)
{
qDebug()<<"i - "<<i;
layersFromMap2.append(m_mobileMapPackage1->maps().at(0)->operationalLayers()->at(i));
layerFromMap2 = map2->operationalLayers();
layerFromMap2->setParent(this); // re-parent the layers
}
qDebug()<<"layersFromMap2"<<layersFromMap2.size()<<"layerFromMap2 "<<layerFromMap2->size();
// delete the map
delete map2;
// // add all the layers to the mapView's map
for (int i = 0;i<layersFromMap2.size();i++)
{
m_mapView->map()->operationalLayers()->append(layersFromMap2.at(i));
qDebug()<<"operationalLayers "<<m_mapView->map()->operationalLayers()->size();
}
auto* operationalLayers = m_mapView->map()->operationalLayers();
for (auto* layer : layersFromMap2)
operationalLayers->append(layer);
qDebug()<<"total layers "<<operationalLayers->size();
});
Unfortunately the team cannot help with debugging, but I can outline the workflow without code to indicate how it should be working.
1. Load both mmpk files.
2. Set the first mmpk's Map to the MapView.
3. For the second one, pull the layers out of the map and store them locally.
4. Re-parent the layers (very important) - without this step they will get deleted with the map they came from.
5. Delete the second map - this should free up the layers to be displayed in a different map. Layers cannot be part of two different maps at the same time - this is why the second map must be deleted.
6. Add the set of layers to the MapView's map (which is from the first mmpk loaded).
It does look like your code is following this pattern, but double check you've not missed something minor along the way.
Another potential solution (and I use that phrase loosely), is that the Map object is JsonSerializable. You could call map->toJson() to get the serialized text of each map. Within the text it will contain an operationalLayers tag with the serialized data for all the layers. You could use this information to build up a map from the first map's Json, but with the second map's operationalLayers text added to it. With that serialized data string, you could create a map from json, see Map::fromJson.
operationalLayers | ArcGIS for Developers
Map Class | ArcGIS for Developers
Let us know if this helps.
Hi James ,
We tried this pseudo code but still we are not able to load two mmpk data for single screen.Go through this code if i am doing any
mistak, Please inform.
path1 = "/home/Gis/ChartEngine/Arcgis/Runtime/Data/MMpk/India.mmpk";
path2 = "/home/Gis/ChartEngine/Arcgis/Runtime/Data/MMpk/Pak.mmpk";
void CTacticalViewClass::LoadingOfmmpkfile(const QUrl &file,const QUrl &file2)
{
QString dataPath = file.toString();
QString dataPath2 = file2.toString();
m_mobileMapPackage = new MobileMapPackage(dataPath, this);
m_mobileMapPackage1 = new MobileMapPackage(dataPath2, this);
connect(m_mobileMapPackage, &MobileMapPackage::doneLoading, this, [this](Error error)
{
if (error.isEmpty())
{
m_mapView->setMap(m_mobileMapPackage->maps().at(0));
m_mobileMapPackage1->load();
}
});
connect(m_mobileMapPackage1, &MobileMapPackage::doneLoading, this, [this](Error) {
auto* map2 = m_mobileMapPackage1->maps().at(0);
qDebug()<<"Operational layer count ------>>"<<m_mobileMapPackage1->maps().at(0)->operationalLayers()->size()<<"map2"<<map2->operationalLayers()->size();//here 3 operational layer is coming
QList<Layer*> layersFromMap2;
//***** We made changes in for loop because we were getting error in for loop
LayerListModel* layerFromMap2;
for (int i = 0;i<m_mobileMapPackage1->maps().at(0)->operationalLayers()->size();i++)
{
layersFromMap2.append(m_mobileMapPackage1->maps().at(0)->operationalLayers()->at(i));
layerFromMap2 = map2->operationalLayers();
layerFromMap2->setParent(this); // re-parent the layers
}
qDebug()<<"layersFromMap2"<<layersFromMap2.size()<<"layerFromMap2 "<<layerFromMap2->size();
// delete the map
delete map2;
////********************** After deletion of map2 ,we are getting operational layers as zero
// // add all the layers to the mapView's map
auto* operationalLayers = m_mapView->map()->operationalLayers();
for (auto* layer : layersFromMap2)
operationalLayers->append(layer);
qDebug()<<"total layers "<<operationalLayers->size();
});
m_mobileMapPackage->load();