How identify a Graphic item in a GraphicsOverlay (UID) ?

728
2
01-21-2020 06:37 AM
thierrylechevallier
New Contributor II

Using C++ SDK, I'm trying to make a polygon on a map, then move its vertices.
I can't find any example on this topic. I found only example that show how select a Graphic identified thanks to MapGraphicsView::identifyGraphicsOverlaysCompleted.
A strange behaviour with identifyGraphicsOverlaysCompleted is that the returned Graphics are not those I've created...

An other point : how can I move a Graphic item and not navigate on the map ?

I think I need reiplement my custom MapGraphicsView class, but no example on this topic...

Any help appreciated !

0 Kudos
2 Replies
thierrylechevallier
New Contributor II

A simplest example :

- Add a graphic on the overlay :

    m_ptBuilderTest = new PointBuilder(SpatialReference::wgs84()); //m_map->spatialReference());
    m_ptBuilderTest->setXY(-1.524836, 47.210722);
    m_gPtTest = new Graphic(m_ptBuilderTest->toGeometry());
    m_gPtTest->attributes()->insertAttribute("UID", QVariant(1234));

    m_symTest = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Circle, QColor("red"), 10, this);
    m_gPtTest->setSymbol(m_symTest);
    m_graphicsOverlay->graphics()->append(m_gPtTest);

- In the slot of identifyGraphicsOverlaysCompleted :

void DisplayMap::onIdentifyGraphicsOverlaysCompleted(QUuid taskId, QList<Esri::ArcGISRuntime::IdentifyGraphicsOverlayResult *> identifyResults)
{
    bool bFound = false;

    // Make a list with all Graphic items under the mouse
    QList<Graphic *> lg;
    for(auto i : identifyResults ) {
        for(auto g : i->graphics()) {
            lg.append(g);
            bFound = true; 

            AttributeListModel *alm = g->attributes();
            int sUID = alm->attributeValue("UID").toInt(); // <=============  Break point here

....

With only one item on the map, when I click on this item, I expect found my object m_gPtTest, but no, the pointers are differents (g != m_gPtTest)
One way I found, is to add a Unique ID on each Graphic item thanks to the attibutes of the GeoElement. It works well, I get back the good UID.

Is there an other way to identify an item of a map ?

0 Kudos
thierrylechevallier
New Contributor II

I finally solved all my initial problem thanks to the attributs.

I also solved a memory leak made by the signal : identifyGraphicsOverlaysCompleted(QUuid taskId, QList<Esri::ArcGISRuntime::IdentifyGraphicsOverlayResult *> identifyResults).
=>In your slot, you have to delete items of the list identifyResults.
It's a strange use of Qt connections because if you have several slots listenning the same signal, only the last slot should delete the objects passed as argument. Very hard to manage...

An other recommendation : if you call identifyGraphicsOverlaysCompleted after a MouseMove signal, use a flag to not call identifyGraphicsOverlaysCompleted if the previous call is not terminated. You will free your CPU with this tip 😉

Finally :

void DisplayMap::onMouseMoved(QMouseEvent &mouseEvent)
{
    ...
    if( ! m_identifyBusy ) {
        // prevent too much call of identify
        m_identifyBusy = true;
        m_mapView->identifyGraphicsOverlays(mouseEvent.x(), mouseEvent.y(), 10, false, 100);
    }
}


void DisplayMap::onIdentifyGraphicsOverlaysCompleted(QUuid taskId, QList<Esri::ArcGISRuntime::IdentifyGraphicsOverlayResult *> identifyResults)
{
  ...
    // delete results (memory leak else)
    for(auto i : identifyResults ) {
        delete i;
    }
    identifyResults.clear();

    // update flag
    m_identifyBusy = false;
}