Select Drawn Graphic using Touch

2945
4
04-23-2014 08:28 PM
steelissteelis
New Contributor
Hi,

After drawing a Graphic (for instance a free hand line), we were trying to implement a function to select and move the drawn graphics as available in the Sample tools. However, we come to realize that it is not as easy when using the touch to select the Graphic for moving as compare to a mouse. May I know if that is some limitation for the RunTime SDK at the moment for touch to move Graphic?

Finally is there any function in the SDK for grouping of Graphics (without using Layers)?

Thanks in advance.
0 Kudos
4 Replies
EugenReiswich
New Contributor
We've experienced a similar problem using touch to move graphics. We needed to touch precisely in the middle of the graphic in order to move it. What we've done is to expand the "hit area" around the graphic by e.g. 25px:


        internal async void OnTouchUp(MapView view, TouchEventArgs touchArgs)
        {
            Point position = touchArgs.GetTouchPoint(view).Position;
            TouchDevice device = touchArgs.TouchDevice;

           if (UpEventOnMapView(view, device))
            {
                if (_touchTapChecker.IsTapEvent(device, position))
                {
                    Graphic hitGraphic = await GetSelectedGraphic(view, position);
                    HandleGraphicTapped(hitGraphic, device);
                }
            }
        }

         private async Task<Graphic> GetSelectedGraphic(MapView sender, Point position)
        {
            Rect touchArea = GetTouchAreaFromPoint(position);
            Task<Graphic> graphicTask = graphicsLayer.HitTestAsync(sender, touchArea);
            // do parallel tasks here if needed
            return await graphicTask;
        }

        private Rect GetTouchAreaFromPoint(Point point)
        {
            Point positionLeftUp = new Point(point.X - 25, point.Y - TouchAreaSize);
            Point positionRightDown = new Point(point.X + 25, point.Y + TouchAreaSize);

            Rect touchPosition = new Rect(positionLeftUp, positionRightDown);
            return touchPosition;
        }


I hope this helps.
Eugen
0 Kudos
AnttiKajanus1
Occasional Contributor III
In Runtime for WPF, you work with .NET framework based touch-events. From SDK point of view, we don't restrict touch based interactions on anyway (thou we don't provide out-of-the-box Map events like we do in new ArcGIS Runtime for .NET) but there are many things that you should be considering when building application that uses touch as a main interaction model.

Design and UX should be based on the type of interaction and also you think what is the accuracy your users can get when working with app. This affected by type (mouse / touch), type of device (phone / laptop / tablet...), situation where users uses the app, etc... Depending on the accuracy and acceptable error factors, you should be deciding the size of the touch area, in this case we are more or less talking about the rectangle that is viewed as a area surrounding the graphic that is considered as a hit box. We don't have any magical numbers to give, what size is good or bad because all these values varies on case by case.

Here is one interesting chart : (taken from : http://msdn.microsoft.com/en-us/library/windows/apps/hh465415.aspx )

Size vs. efficiency: Target size influences error rate


Since this study is done for the normal Windows Store apps, it doesn't show truth in map apps but gives good reference. I find it interesting that ereiswichs has found 50ish pixels good value that matches well with this chart. This value is considered as a "When accuracy matters" group where it is very important that user hits that with first try.

This answer might hit the question from a bit different angle, but hope this helps to design your implementation.
0 Kudos
steelissteelis
New Contributor
Hi,

Thanks for the suggestion thus far. However, I still could not quite implement the touch selection function for the Graphics in an active layer in my Map control. The following code is created based on the sample applications from Arcgis.



        public void EnableActiveLayerGraphicSelection()
        {
            ActiveMLL.gl.MouseLeftButtonDown += GraphicsLayer_MouseLeftButtonDown;
        }

        private void GraphicsLayer_MouseLeftButtonDown(object sender, GraphicMouseButtonEventArgs e)
        {
            e.Handled = true;

            if (e.Graphic.Geometry is MapPoint)
            {
                e.Graphic.Selected = true;

                selectedPointGraphic = e.Graphic as gGraphics;
            }
            else
            {
                editGeometry.StartEdit(e.Graphic);
            }
        }


The above code is what I would use to select a Graphic object in my active layer in a map. However, I couldn't find a similar method for touch in the Layer class that will allow me to easily obtain the Graphic object nor provide me with a touch event.

As of now, I am able to listen to the touch event in my Map control then obtain the touchpoint. But after that, I have no idea on how to easily check if the point is within a Graphic object other than looping through all the layers then check with the Geometry of each graphic.
0 Kudos
EugenReiswich
New Contributor
Hmm, we've been working on this problem for days so I won't be able to post you all the source code needed to solve your problem. But here are the basic steps we've done:


  1. Listen for touch events provided by the map control

  2. create a TouchService that will delegate touch events to every part of your system where touches are needed. This is necessary because in a Map application the only UI element that is able to broadcast touch events on the map is the map, layers e.g. can't do this.

  3. in PreviewTouchDown-Event: we disable the map, so it won't be moved while a user is moving his finger

  4. in TouchDown-Event: we first do a AsyncHitTest (MapView-Method) to determine, if a user touched a graphic or wants to e.g. move the map. Than we store the finger (device) ID that has touched a graphic and the Graphic in a Dictionary (because in a multitouch application several users can move graphics simultaneously)

  5. in TouchMove-Event: we retrieve the finger (device) ID from the TouchEventArgs and retrieve our Graphic from Dictionary for the finger ID. you can get the new position for your graphic by asking the TouchEventArgs for the new TouchPosition, find an appropriate Geo-Positoin for the Touch using the ScreenToLocation-Method (MapView) and afterwards change the Geometry-Property of your graphic

  6. In Touch-Up: we enable the map, so it can be manipulated by users again

0 Kudos