I use a couple of layers (for example in a basemap)
I can retrieve data like
But how can get a thumbnail?
(I provide one during creation and publishing the map...)
Thx
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
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:
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
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
Also, that bug is not related. That is for Image Services, which are a bit different
Key concepts for image services—Documentation | ArcGIS Enterprise
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() << " xyz Esri::ArcGISRuntime::PortalItem::doneLoading"; }); portalItem->load(); qCritical() << " xyz Esri::ArcGISRuntime::PortalItem::doneLoading, status = " << (int)portalItem->loadStatus(); QObject::connect(portalItem, &Esri::ArcGISRuntime::PortalItem::fetchThumbnailCompleted, this, [this](bool success) { qCritical() << " xyz fetchCommentsCompleted, success = " << success; QImage img = portalItem->thumbnail(); qCritical() << " xyz fetchCommentsCompleted, img = " << img.size(); }); portalItem->fetchThumbnail();
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() << " xyz Esri::ArcGISRuntime::PortalItem::doneLoading"; }); portalItem->load(); qCritical() << " xyz Esri::ArcGISRuntime::PortalItem::doneLoading, status = " << (int)portalItem->loadStatus();
QObject::connect(portalItem, &Esri::ArcGISRuntime::PortalItem::fetchThumbnailCompleted, this, [this](bool success) { qCritical() << " xyz fetchCommentsCompleted, success = " << success;
QImage img = portalItem->thumbnail(); qCritical() << " xyz 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.
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.
<SPAN class="keyword token">void</SPAN> Thumbnail_test<SPAN class="operator token">::</SPAN><SPAN class="token function">createPortalItem</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="comment token">// Create the Portal Item</SPAN> PortalItem<SPAN class="operator token">*</SPAN> item <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token function">PortalItem</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="token function">QUrl</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token"><SPAN>"</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fwww.arcgis.com%2Fhome%2Fitem.html%3Fid%3D10df2279f9684e4a9f6a7f08febac2a9" target="_blank">https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9</A><SPAN>"</SPAN></SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">this</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="comment token">// Connect to Portal Item signals</SPAN> <SPAN class="token function">connect</SPAN><SPAN class="punctuation token">(</SPAN>item<SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">&</SPAN>PortalItem<SPAN class="operator token">::</SPAN>doneLoading<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="operator token">=</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">(</SPAN>Error e<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>e<SPAN class="punctuation token">.</SPAN><SPAN class="token function">isEmpty</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="token function">qDebug</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token"><<</SPAN> <SPAN class="string token">"loaded portal item. fetching thumbnail..."</SPAN><SPAN class="punctuation token">;</SPAN> item<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">fetchThumbnail</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="token function">qDebug</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token"><<</SPAN> <SPAN class="string token">"failed to load"</SPAN> <SPAN class="operator token"><<</SPAN> e<SPAN class="punctuation token">.</SPAN><SPAN class="token function">message</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token"><<</SPAN> e<SPAN class="punctuation token">.</SPAN><SPAN class="token function">additionalMessage</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="token function">connect</SPAN><SPAN class="punctuation token">(</SPAN>item<SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">&</SPAN>PortalItem<SPAN class="operator token">::</SPAN>fetchThumbnailCompleted<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="operator token">=</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">bool</SPAN> success<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="token function">qDebug</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token"><<</SPAN> <SPAN class="string token">"fetch thumbnail completed successfully? -"</SPAN> <SPAN class="operator token"><<</SPAN> success<SPAN class="punctuation token">;</SPAN> QPixmap pixmap<SPAN class="punctuation token">;</SPAN> pixmap<SPAN class="punctuation token">.</SPAN><SPAN class="token function">convertFromImage</SPAN><SPAN class="punctuation token">(</SPAN>item<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">thumbnail</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> QLabel<SPAN class="operator token">*</SPAN> label <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token function">QLabel</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">this</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> label<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">setPixmap</SPAN><SPAN class="punctuation token">(</SPAN>pixmap<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> QWidget<SPAN class="operator token">*</SPAN> widget <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token function">QWidget</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> QVBoxLayout<SPAN class="operator token">*</SPAN> layout <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token function">QVBoxLayout</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> layout<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">setMargin</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> layout<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">addWidget</SPAN><SPAN class="punctuation token">(</SPAN>label<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> widget<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">setLayout</SPAN><SPAN class="punctuation token">(</SPAN>layout<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> QGraphicsProxyWidget<SPAN class="operator token">*</SPAN> proxy <SPAN class="operator token">=</SPAN> m_mapView<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">scene</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">addWidget</SPAN><SPAN class="punctuation token">(</SPAN>widget<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> proxy<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">setPos</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="number token">10</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">10</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> proxy<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">setOpacity</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="number token">0.95</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> QVBoxLayout<SPAN class="operator token">*</SPAN> vBoxLayout <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token function">QVBoxLayout</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> vBoxLayout<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">addWidget</SPAN><SPAN class="punctuation token">(</SPAN>m_mapView<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="token function">setLayout</SPAN><SPAN class="punctuation token">(</SPAN>vBoxLayout<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="comment token">// Create a Layer from the Portal Item and add to Map</SPAN> ArcGISTiledLayer<SPAN class="operator token">*</SPAN> tiledLayer <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token function">ArcGISTiledLayer</SPAN><SPAN class="punctuation token">(</SPAN>item<SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">this</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> Basemap<SPAN class="operator token">*</SPAN> basemap <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token function">Basemap</SPAN><SPAN class="punctuation token">(</SPAN>tiledLayer<SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">this</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> m_map <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token function">Map</SPAN><SPAN class="punctuation token">(</SPAN>basemap<SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">this</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> m_mapView<SPAN class="operator token">-</SPAN><SPAN class="operator token">></SPAN><SPAN class="token function">setMap</SPAN><SPAN class="punctuation token">(</SPAN>m_map<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="comment token">// this will start the load cycle</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
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 << "'";
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?
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?
Přihlášení členové mohou přispívat, sledovat aktualizace a další. Jste tu noví? Zaregistrujte si bezplatný účet.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.