How to convert screen pixels to map units

1229
5
Jump to solution
02-24-2022 10:57 AM
DaveLewis73
Occasional Contributor

I am looking to create polygons (halos/rings) around the mouse cursor.  I have figured out how to create the halos by using System.Windows.Forms.Control.MousePosition and then converting into lat/long by using MapView.Active.ScreenToMap.  I have also used a MouseHook from the Win32Api to give me a MouseMove event.  This allows me to associate the polygon to the mouse cursor and move it around the map as an overlay. 

The problem that I am having now is that I can only create a polygon (halo/ring) with a radius in pixels.  I need to be able to use map units, like feet, meters, miles, kilometers, etc.  For example, I want to create a polygon (halo/ring) that has a radius of 100 feet. 

Is there some way to accomplish this?

The following is a method that I am using that takes pixels to create the halo, just in case it would be of help to someone:

private ArcGIS.Core.Geometry.Polygon CreateHaloPolygon(MapPoint mapPoint, int pixels, out double radius)
{
    // Get the halo radius
    Point screenPoint = MapView.Active.MapToScreen(mapPoint);
    Point radiusScreenPoint = new Point((screenPoint.X + pixels), screenPoint.Y);
    MapPoint radiusMapPoint = MapView.Active.ScreenToMap(radiusScreenPoint);
    radius = GeometryEngine.Instance.Distance(mapPoint, radiusMapPoint);

    // Build a circle geometry
    Coordinate2D coord2D = new Coordinate2D(mapPoint);
    EllipticArcSegment arcSegment = EllipticArcBuilder.CreateEllipticArcSegment(coord2D, radius,        esriArcOrientation.esriArcClockwise, SpatialReferences.WGS84); //MapView.Active.Map.SpatialReference);
    PolygonBuilder polyBuilder = new PolygonBuilder(new[] { arcSegment });

    return polyBuilder.ToGeometry();
}

0 Kudos
1 Solution

Accepted Solutions
DaveLewis73
Occasional Contributor

I have solved this issue by using the GeometryEngine.Instance.GeodesicEllipse method.  It takes in a GeodesicEllipseParamter containing all of the necessary parameters to create the ellipse and a spatial reference.  Included in the parameters is the radius and the linear units to use.  The following is a code snippet of creating the geodesic ellipse:

private ArcGIS.Core.Geometry.Geometry BuildBufferEllipse(MapPoint mapPt, double radius, string linearUnits)
{
    var ellipseParams = new GeodesicEllipseParameter
    {
        Center = new Coordinate2D(mapPt),
        AxisDirection = 0.0,
        LinearUnit = GetLinearUnits(linearUnits),
        OutGeometryType = GeometryType.Polygon,
        SemiAxis1Length = radius,
        SemiAxis2Length = radius,
        VertexCount = 99
    };

    return GeometryEngine.Instance.GeodesicEllipse(ellipseParams, MapView.Active.Map.SpatialReference);
}

View solution in original post

0 Kudos
5 Replies
KenBuja
MVP Esteemed Contributor

Does the snippet Calculate Selection tolerance in map units help at all in converting from screen pixel to map units?

0 Kudos
DaveLewis73
Occasional Contributor

Ken,

Thank you for your reply.  Unfortunately, I have already come across that sample and it doesn't work for me.

0 Kudos
GKmieliauskas
Esri Regular Contributor
0 Kudos
DaveLewis73
Occasional Contributor

Gintautas,

Thanks for the link.  I looked it over and I did find some interesting information concerning LinearUnits, but I didn't find an answer to my question regarding the conversion of screen coordinates in pixels to map units.

0 Kudos
DaveLewis73
Occasional Contributor

I have solved this issue by using the GeometryEngine.Instance.GeodesicEllipse method.  It takes in a GeodesicEllipseParamter containing all of the necessary parameters to create the ellipse and a spatial reference.  Included in the parameters is the radius and the linear units to use.  The following is a code snippet of creating the geodesic ellipse:

private ArcGIS.Core.Geometry.Geometry BuildBufferEllipse(MapPoint mapPt, double radius, string linearUnits)
{
    var ellipseParams = new GeodesicEllipseParameter
    {
        Center = new Coordinate2D(mapPt),
        AxisDirection = 0.0,
        LinearUnit = GetLinearUnits(linearUnits),
        OutGeometryType = GeometryType.Polygon,
        SemiAxis1Length = radius,
        SemiAxis2Length = radius,
        VertexCount = 99
    };

    return GeometryEngine.Instance.GeodesicEllipse(ellipseParams, MapView.Active.Map.SpatialReference);
}

0 Kudos