ThinkGeo.com    |     Documentation    |     Premium Support

ContextMenu and MapShapes project

I am trying to add a context menu for my project, which is based on the MapShapes project using a MapShapesLayer. I can use the BaseShape.Contains(mouseLocation) API in order to detect if a click falls on top of a shape that uses an AreaShape. However, it doesn't work for a LineShape. What's the best way for me to tell whether a PointShape (in world coordinates) is along the path of a lineshape?



Greg,



  There is a better way to do this.  What you want to do is to take the point shape and then buffer it a little.  To buffer it you usally want to do that in pixels so you need to find out how many meters are in a pixel and then after you have the buffer call an Intersects method to see if the buffered point intersects the shape.  I have some code below but I did not test it thoroughly as we are pretty busy today.  i think you can get the idea of it though.  We have done this tons of times so I am fairly certain of the method.  I have also provided two interfaces, one for shapes and one for features.  Let me know if you have any questions.



David




        private bool IsShapeNearPoint(ScreenPointF screenSearchPoint, Feature searchFeature, int pixelTolerance, GeographyUnit mapUnit, RectangleShape currentExtent, float mapWidth, float mapHeight)
        {
            return IsShapeNearPoint(screenSearchPoint, searchFeature.GetShape(), pixelTolerance, mapUnit, currentExtent, mapWidth, mapHeight);
        }

        private bool IsShapeNearPoint(ScreenPointF screenSearchPoint, BaseShape searchShape, int pixelTolerance, GeographyUnit mapUnit, RectangleShape currentExtent, float mapWidth, float mapHeight)
        {           
            // Here we convert the screen point to a world point
            PointShape worldSearchPoint = ExtentHelper.ToWorldCoordinate(currentExtent, screenSearchPoint, mapWidth, mapHeight);
            // Here we get the world distance between two screen points.  We take the point the user clicked and we add to the X
            // and Y the distance of the search tolerance.  This gives us like 100 or 1000 meters or whatever
            double radiusInMeters = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(currentExtent, screenSearchPoint.X, screenSearchPoint.Y, screenSearchPoint.X + pixelTolerance, screenSearchPoint.Y + pixelTolerance, mapWidth, mapHeight, mapUnit, DistanceUnit.Meter);
            // We take the radius from the above line and we buffer the world point that large.  This gives us a 
            // world polygon which should be where we want to search
            MultipolygonShape searchArea = worldSearchPoint.Buffer(radiusInMeters, mapUnit, DistanceUnit.Meter);

            // You can then call the Intersects on the search shape and if the search shape shares any points
            // with the area of the polygon it will true true.
            bool intersects = searchArea.Intersects(searchShape);

            return intersects;
        }