How to relocation Graphic in QML

947
2
Jump to solution
05-16-2021 07:22 PM
KanjaSousuke
New Contributor

I want to relocation Graphic.

What I want to do is click on an already placed graphic, rewrite the latitude and longitude, and reposition it.

To be more specific.

  1. click map and add point. (add PointA)
  2. click map and add point again. (add PointB)
  3. click near PointA to bring up the input screen.
  4. rewrite Lat/Long to update the display.

When I click near a point that I have already placed, can I read the information about that point?

0 Kudos
1 Solution

Accepted Solutions
JaredCaccamo
Esri Contributor

Hello @KanjaSousuke ,

When I click near a point that I have already placed, can I read the information about that point?

Yes.  GeoView.identifyGraphicsOverlay will identify the topmost graphic which you can then use to obtain the graphic identified which has attributes, geometry, symbol, and a few other properties which you can see here, https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-graphic.html

Below I wrote a quick little example to show the functionality you seek to implement. It looks for two clicks on the map. For the first two it creates two points from those clicks. Then on all subsequent clicks it does an identifyGraphicsOverlay operation to locate the graphic you clicked near. It creates a new point using the Long and Lat from the identified graphic and add 100000 to it just to show you can update it's location. You could also take another mouse click and update it's location that way. We have many samples that illustrate similar behavior but the one that comes to mind right now is "Edit features with feature-linked annotation", https://github.com/Esri/arcgis-runtime-samples-qt/blob/main/ArcGISRuntimeSDKQt_QMLSamples/EditData/E....


import QtQuick 2.6
import QtQuick.Controls 2.2
import Esri.ArcGISRuntime 100.11

ApplicationWindow {
    id: appWindow
    width: 800
    height: 600
    title: "RelocateGraphic"

    // add a mapView component
    MapView {
        id: mapView
        anchors.fill: parent
        // set focus to enable keyboard navigation
        focus: true

        // add a map to the mapview
        Map {
            // add the ArcGISStreets basemap to the map
            initBasemapStyle: Enums.BasemapStyleArcGISStreets
        }

        onMouseClicked: {
            let clickPoint = screenToLocation(mouse.x, mouse.y);
            if (pointA.geometry == null) {
                pointA.geometry = clickPoint;
            } else if (pointB.geometry == null) {
                pointB.geometry = clickPoint;
                setViewpointGeometryAndPadding(overlay.extent, 100 /*padding in device independent pixels (DIPS)*/);
            } else {
                identifyGraphicsOverlay(overlay, mouse.x, mouse.y, 5 /*tolerance*/, false /*returnPopupsOnly*/);
            }
        }

        onIdentifyGraphicsOverlayStatusChanged: {
            if (identifyGraphicsOverlayStatus != Enums.TaskStatusCompleted)
                return;

            const result = identifyGraphicsOverlayResult;
            print("longitude: " + result.graphics[0].geometry.x);
            print("latitude: " + result.graphics[0].geometry.y);

            print("Add 100000 to long and lat respectively and update");
            let geom = result.graphics[0].geometry;

            // Point is immutable which requires us to create a new one
            // then assign it to the graphic we want to update.
            let newPoint = ArcGISRuntimeEnvironment.createObject("Point", {
                                                                 x: geom.x + 100000,
                                                                 y: geom.y + 100000,
                                                                 spatialReference: geom.spatialReference
                                                                 });
            result.graphics[0].geometry = newPoint;
            print("new longitude: " + result.graphics[0].geometry.x);
            print("new latitude: " + result.graphics[0].geometry.y);
        }

        GraphicsOverlay {
            id: overlay

            Graphic {
                id: pointA
                SimpleMarkerSymbol {
                    color: "red"
                    size: 15
                    style: Enums.SimpleMarkerSymbolStyleCircle
                }
            }

            Graphic {
                id: pointB
                SimpleMarkerSymbol {
                    color: "blue"
                    size: 15
                    style: Enums.SimpleMarkerSymbolStyleCross
                }
            }
        }
    }
}

 

I hope you find this helpful. Let me know if you have any other questions.

 

Sincerely,

Jared

View solution in original post

0 Kudos
2 Replies
JaredCaccamo
Esri Contributor

Hello @KanjaSousuke ,

When I click near a point that I have already placed, can I read the information about that point?

Yes.  GeoView.identifyGraphicsOverlay will identify the topmost graphic which you can then use to obtain the graphic identified which has attributes, geometry, symbol, and a few other properties which you can see here, https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-graphic.html

Below I wrote a quick little example to show the functionality you seek to implement. It looks for two clicks on the map. For the first two it creates two points from those clicks. Then on all subsequent clicks it does an identifyGraphicsOverlay operation to locate the graphic you clicked near. It creates a new point using the Long and Lat from the identified graphic and add 100000 to it just to show you can update it's location. You could also take another mouse click and update it's location that way. We have many samples that illustrate similar behavior but the one that comes to mind right now is "Edit features with feature-linked annotation", https://github.com/Esri/arcgis-runtime-samples-qt/blob/main/ArcGISRuntimeSDKQt_QMLSamples/EditData/E....


import QtQuick 2.6
import QtQuick.Controls 2.2
import Esri.ArcGISRuntime 100.11

ApplicationWindow {
    id: appWindow
    width: 800
    height: 600
    title: "RelocateGraphic"

    // add a mapView component
    MapView {
        id: mapView
        anchors.fill: parent
        // set focus to enable keyboard navigation
        focus: true

        // add a map to the mapview
        Map {
            // add the ArcGISStreets basemap to the map
            initBasemapStyle: Enums.BasemapStyleArcGISStreets
        }

        onMouseClicked: {
            let clickPoint = screenToLocation(mouse.x, mouse.y);
            if (pointA.geometry == null) {
                pointA.geometry = clickPoint;
            } else if (pointB.geometry == null) {
                pointB.geometry = clickPoint;
                setViewpointGeometryAndPadding(overlay.extent, 100 /*padding in device independent pixels (DIPS)*/);
            } else {
                identifyGraphicsOverlay(overlay, mouse.x, mouse.y, 5 /*tolerance*/, false /*returnPopupsOnly*/);
            }
        }

        onIdentifyGraphicsOverlayStatusChanged: {
            if (identifyGraphicsOverlayStatus != Enums.TaskStatusCompleted)
                return;

            const result = identifyGraphicsOverlayResult;
            print("longitude: " + result.graphics[0].geometry.x);
            print("latitude: " + result.graphics[0].geometry.y);

            print("Add 100000 to long and lat respectively and update");
            let geom = result.graphics[0].geometry;

            // Point is immutable which requires us to create a new one
            // then assign it to the graphic we want to update.
            let newPoint = ArcGISRuntimeEnvironment.createObject("Point", {
                                                                 x: geom.x + 100000,
                                                                 y: geom.y + 100000,
                                                                 spatialReference: geom.spatialReference
                                                                 });
            result.graphics[0].geometry = newPoint;
            print("new longitude: " + result.graphics[0].geometry.x);
            print("new latitude: " + result.graphics[0].geometry.y);
        }

        GraphicsOverlay {
            id: overlay

            Graphic {
                id: pointA
                SimpleMarkerSymbol {
                    color: "red"
                    size: 15
                    style: Enums.SimpleMarkerSymbolStyleCircle
                }
            }

            Graphic {
                id: pointB
                SimpleMarkerSymbol {
                    color: "blue"
                    size: 15
                    style: Enums.SimpleMarkerSymbolStyleCross
                }
            }
        }
    }
}

 

I hope you find this helpful. Let me know if you have any other questions.

 

Sincerely,

Jared

0 Kudos
KanjaSousuke
New Contributor

Thanks, I think I can manage that.

0 Kudos