Select to view content in your preferred language

retrieve thumbnail of layer

2176
8
06-08-2017 07:16 AM
NorbertThoden
Occasional Contributor III

I use a couple of layers (for example in a basemap)

I can retrieve data like

  • mapName
  • description
  • serviceDescription

But how can get a thumbnail?

(I provide one during creation and publishing the map...)

Thx

Tags (1)
0 Kudos
8 Replies
LucasDanzinger
Esri Frequent Contributor

Norbert-

The thumbnail is stored as part of the PortalItem. I suggest you construct a PortalItem from the item id, then call fetchThumbnail and access the thumbnail from the getter - Item Class | ArcGIS for Developers 

You can then use that PortalItem instance in the constructor of your layer.

Thanks,

Luke

NorbertThoden
Occasional Contributor III

Hi Luke!

Thanks for this hint.

But where can i get the id from?

I set up the maps in the portal using AcrMap. I already looked for that id, but without success.

I tried the ctor using the url, but what is the next step?
Maybe this:

  • setup PortalItem using the url (like http:IP.FQDN/rest.....
  • load the PortalItem and wait for doneLoading
  • fetchThumbnail and wait for ...completed signal

There is a known issue related: "ArcGISTiledLayer fails to load with cached image service as portal item".

Hopefully that is not relvant to me!?

Thx,

Norbert

0 Kudos
LucasDanzinger
Esri Frequent Contributor

Norbert,

If you log in to your Portal organization and go to My Content, you should see your service in that section. You can then obtain the Portal Item ID from the URL. For example, here is an Item ID - 

92ad152b9da94dee89b9e387dfe21acd

- Luke

LucasDanzinger
Esri Frequent Contributor

Also, that bug is not related. That is for Image Services, which are a bit different

Key concepts for image services—Documentation | ArcGIS Enterprise 

0 Kudos
NorbertThoden
Occasional Contributor III

Hi Luke!

I found the id, it´s within the url, not the web page itself...

I tried this approach using the id:

The PortalItem is loaded and i call fetchThumbnail (which exists)

The result: success = false Is it a bug?
(Even in that case portalItem->thumbnail(); returns an empty image.)

My code looks like this:

    Esri::ArcGISRuntime::PortalItem *portalItem
        = new Esri::ArcGISRuntime::PortalItem(QLatin1Literal("e693970a7b834fba953ebf8217ed478c"), this);
//    = new Esri::ArcGISRuntime::PortalItem(url);

    connect(portalItem, &Esri::ArcGISRuntime::PortalItem::errorOccurred, this, [this](Esri::ArcGISRuntime::Error error)
    {
      FATAL_LOG(m_logger) << LOGFUNCTION << " PortalItem -> EsriError occured: "
                          << " code="              << error.code()
                          << " domain="            << (int)error.domain()
                          << " extendedErrorType=" << (int)error.extendedErrorType()
                          << ", message='"         << error.message() << "'";
    });
    connect(portalItem, &Esri::ArcGISRuntime::PortalItem::doneLoading, this, [this](Esri::ArcGISRuntime::Error error)
    {
      qCritical() << " XXX Esri::ArcGISRuntime::PortalItem::doneLoading";
    });
    portalItem->load();
    qCritical() << " XXX Esri::ArcGISRuntime::PortalItem::doneLoading, status = " << (int)portalItem->loadStatus();

    QObject::connect(portalItem, &Esri::ArcGISRuntime::PortalItem::fetchThumbnailCompleted, this, [this](bool success)
    {
      qCritical() << " XXX fetchCommentsCompleted, success = " << success;

      QImage img = portalItem->thumbnail();
      qCritical() << " XXX fetchCommentsCompleted, img = " << img.size();
    });
    portalItem->fetchThumbnail();

But:

I apply a couple of URLs (as String) to be used as baselayers.

They are listed in the application to let the user modifiy the visibility, brightness etc.

I just want to add the thumbnail.

Therefore it generates error-prone  extra cost to add the portalIds also...

Is there a possibilty to do retrieve the thumbnail from the layer and not from the portal?

Maybe

Does that make sense?

But that would be fine if it would be directly available in the class layer...Just an idea.

Thx

Norbert

0 Kudos
LucasDanzinger
Esri Frequent Contributor

Norbert,

Here is some example code. If your layer is secured, you may need to create a Credential object and give that to the PortalItem constructor.

void Thumbnail_test::createPortalItem()
{
  // Create the Portal Item
  PortalItem* item = new PortalItem(QUrl("https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9"), this);

  // Connect to Portal Item signals
  connect(item, &PortalItem::doneLoading, [=](Error e)
  {
    if (e.isEmpty())
    {
      qDebug() << "loaded portal item. fetching thumbnail...";
      item->fetchThumbnail();
    }
    else
    {
      qDebug() << "failed to load" << e.message() << e.additionalMessage();
    }
  });

  connect(item, &PortalItem::fetchThumbnailCompleted, [=](bool success)
  {
    qDebug() << "fetch thumbnail completed successfully? -" << success;

    QPixmap pixmap;
    pixmap.convertFromImage(item->thumbnail());
    QLabel* label = new QLabel(this);
    label->setPixmap(pixmap);
    QWidget* widget = new QWidget();
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setMargin(0);
    layout->addWidget(label);
    widget->setLayout(layout);

    QGraphicsProxyWidget* proxy = m_mapView->scene()->addWidget(widget);
    proxy->setPos(10, 10);
    proxy->setOpacity(0.95);

    QVBoxLayout* vBoxLayout = new QVBoxLayout();
    vBoxLayout->addWidget(m_mapView);
    setLayout(vBoxLayout);
  });

  // Create a Layer from the Portal Item and add to Map
  ArcGISTiledLayer* tiledLayer = new ArcGISTiledLayer(item, this);
  Basemap* basemap = new Basemap(tiledLayer, this);
  m_map = new Map(basemap, this);
  m_mapView->setMap(m_map); // this will start the load cycle
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
NorbertThoden
Occasional Contributor III

Luke, thanks for the code!

(Again, using and configuring the PortalId and so on toe the client application is error-prone due to the configuration/update process of the system..)

I assume, that i can retrieve the item, check the item type and fetch the thumbnail form that object (without the indirection Portal/PortalItemId and so on).

Should`t this work?

void LogicalLayer::onLayerDoneLoading(const Esri::ArcGISRuntime::Error &loadError)
{
if (! loadError.isEmpty())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " m_logicalName='" << m_logicalName << "'"
<< " loadError: " << " code=" << loadError.code() << " domain=" << (int)loadError.domain() << "  extendedErrorType=" << (int)loadError.extendedErrorType() << ", message='" << loadError.message() << "'";
}


Esri::ArcGISRuntime::Layer *layer = qobject_cast<Esri::ArcGISRuntime::Layer *>(sender());
if (! layer)
{
WARNING_LOG(m_logger) << LOGFUNCTION
<< " qobject_cast failed m_logicalName='" << m_logicalName << "'";
return;
}

Esri::ArcGISRuntime::Item *item = layer->item();
if (!item)
FATAL_LOG(m_logger) << LOGFUNCTION << " no item!!!! " << m_logicalName << "'";

Unfortunately, item is always null.

Maybe that´s a bug?

Or what is the sense of that item?

Thx

0 Kudos
LucasDanzinger
Esri Frequent Contributor

Hey Norbert,

I believe the item getter is only going to be populated if you construct the layer with the item. Otherwise, it will just be null. 

Are you saying you can't hardcode the item ID, and therefore can't create the layer via a PortalItem? If so, maybe you can search the portal for the proper item by searching for a tag, or something like that?

Thanks,

Luke

0 Kudos