简体   繁体   English

如何使用C#ArcObjects获取鼠标单击的地理坐标

[英]How to get Geographic Coordinates of a Mouse Click using C# ArcObjects

I've got an ArcObjects C# tool (most of this code was found here on Stack Exchange) in ArcGIS that identifies map coordinates when a user clicks on a location within a map. 我在ArcGIS中有一个ArcObjects C#工具(大部分代码在Stack Exchange上找到),当用户单击地图中的某个位置时,该工具可以识别地图坐标。 Here's the code that I have used: 这是我使用的代码:

    public override void OnMouseDown(int Button, int Shift, int X, int Y)
    {
        if (Button == 1)
        {
            ESRI.ArcGIS.Display.IScreenDisplay screenDisplay = (m_application.Document as IMxDocument).ActiveView.ScreenDisplay;
            ESRI.ArcGIS.Geometry.IPoint point = screenDisplay.DisplayTransformation.ToMapPoint(X, Y);

            MessageBox.Show("X position is " + point.X.ToString() + " Y position is " + point.Y.ToString());
        }
    }

Our map uses units of feet so the tool displays the feet coordinates. 我们的地图使用英尺单位,因此该工具会显示英尺坐标。 How can I have this tool return degrees-minutes-seconds? 我怎样才能让这个工具返回度-分钟-秒? The standard Identify tool from ESRI does this and is what I'm looking to get similar results to. ESRI的标准“识别”工具可以做到这一点,而我正在寻求类似的结果。

You can easily change the maps units of your IDisplayTransformation object, before getting the coordinates: 在获取坐标之前,您可以轻松更改IDisplayTransformation对象的地图单位:

        ESRI.ArcGIS.Display.IDisplayTransformation displayTransformation = screenDisplay.DisplayTransformation;
        displayTransformation.Units = ESRI.ArcGIS.esriSystem.esriUnits.esriMeters; // or another unit
        ESRI.ArcGIS.Geometry.IPoint point = displayTransformation.ToMapPoint(X, Y);

You can get information about the different ESRI Units here 您可以在此处获取有关不同ESRI单位的信息

You have to first transform the screenpoints into the maps current coordinate system, then you need to project the point into WGS84, then just convert to Degrees Minutes Seconds. 您必须先将屏幕点转换为地图的当前坐标系,然后将其投影到WGS84,然后才转换为度分秒。 I've created a Class below. 我在下面创建了一个类。 You're welcome dude. 不客气,老兄。

Implementation 履行

Public Overrides Sub OnMouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer)
    Dim getMethod As New DecimalDegreesToDegreesMinutesSeconds
    getMethod.PointFromScreenPoint(X, Y)
End Sub

    Public Class DecimalDegreesToDegreesMinutesSeconds
' Used by both
Private pSpRFc As ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment

' WGS1984
Private pSpRef1 As ESRI.ArcGIS.Geometry.ISpatialReference
Private pGCS As ESRI.ArcGIS.Geometry.IGeographicCoordinateSystem

'' NAD83 FEET STATEPLANES NC 
'Private pSpRef2 As ESRI.ArcGIS.Geometry.ISpatialReference
'Private pPCS As ESRI.ArcGIS.Geometry.IProjectedCoordinateSystem

Private ReadOnly Property WGS84() As ESRI.ArcGIS.Geometry.ISpatialReference
    Get
        ' WGS1984
        pSpRFc = New ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment
        pGCS = pSpRFc.CreateGeographicCoordinateSystem(4326)
        pSpRef1 = pGCS
        pSpRef1.SetFalseOriginAndUnits(-180, -90, 1000000)
        Return pSpRef1
    End Get
End Property

' pass the original screen point into this function
Public Sub PointFromScreenPoint(pX As Double, pY As Double)
    Dim scrDisp As ESRI.ArcGIS.Display.IScreenDisplay = Nothing
    Dim pnt As ESRI.ArcGIS.Geometry.IPoint = Nothing
    Dim pGeoSpRef As ESRI.ArcGIS.Geometry.IGeometry = Nothing

    Try
        '
        scrDisp = New ESRI.ArcGIS.Display.ScreenDisplay
        scrDisp = SGProperties.pActiveView.ScreenDisplay ' the activeview
        scrDisp.StartDrawing(scrDisp.hDC, CShort(ESRI.ArcGIS.Display.esriScreenCache.esriNoScreenCache))
        '
        pnt = scrDisp.DisplayTransformation.ToMapPoint(pX, pY)
        '
        pGeoSpRef = pnt
        pGeoSpRef.SpatialReference = SGProperties.pMap.SpatialReference ' the current maps
        pGeoSpRef.Project(WGS84())

        Windows.Forms.MessageBox.Show("X position is " + ConvertDegrees(pnt.X, DegreesType.Longitude).ToString() + " Y position is " + ConvertDegrees(pnt.Y, DegreesType.Latitude).ToString())
    Catch ex As Exception

    Finally
        If scrDisp IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(scrDisp)
        scrDisp = Nothing
        If pnt IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(pnt)
        pnt = Nothing
        If pGeoSpRef IsNot Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(pGeoSpRef)
        pGeoSpRef = Nothing
    End Try
End Sub

Enum DegreesType
    Latitude
    Longitude
End Enum

Private Function ConvertDegrees(pInDegrees As Double, pInType As DegreesType)
    Dim degrees As Integer
    Dim submin As Double
    Dim minutes As Double
    Dim subsecsonds As Double
    Dim direction As String
    Dim output As String

    Try

        degrees = Math.Truncate(pInDegrees)
        submin = Math.Abs((pInDegrees - Math.Truncate(pInDegrees)) * 60)
        minutes = Math.Truncate(submin)
        subsecsonds = Math.Abs((submin - Math.Truncate(submin)) * 60)
        direction = ""

        If pInType.ToString().Trim().ToUpper() = "Latitude".ToUpper() Then
            If degrees < 0 Then
                direction = "S"
            ElseIf (degrees > 0) Then
                direction = "N"
            Else
                direction = ""
            End If
        ElseIf pInType.ToString().Trim().ToUpper() = "Longitude".ToUpper() Then
            If degrees < 0 Then
                direction = "W"
            ElseIf (degrees > 0) Then
                direction = "E"
            Else
                direction = ""
            End If
        End If

        output = degrees.ToString() + ":" + minutes.ToString() + ":" + subsecsonds.ToString().Substring(0, 5) + direction

        Return output
    Catch ex As Exception
        Return Nothing
    End Try
End Function

End Class 末级

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM