Select to view content in your preferred language

Convert ISpatialReference to WKT

1649
5
Jump to solution
12-16-2021 12:11 PM
AbelPerez
Frequent Contributor

ArcMap 10.8.1 using .NET ArcObjects

I have a geometry with a spatial reference. How do I get its projection WKT? I've been looking for hours and can't seem to find a simple way to do this.

Dim pGeom As IGeometry = CreateGeometry()

Dim wkt as String = pGeom.SpatialReference.ToWKT '<=== What API do I use for this conversion?

The output should be something like:

PROJCS["World_Azimuthal_Equidistant",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Azimuthal_Equidistant"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-86.02400831252139],PARAMETER["Latitude_Of_Origin",41.70912056625856],UNIT["Meter",1.0]]

0 Kudos
1 Solution

Accepted Solutions
GKmieliauskas
Esri Regular Contributor

Hi,

You can serialize ISpatialReference object to xml ant then read wkt from it. Code for serialization:

        private static string GetSpatialReferenceAsXmlString(ISpatialReference spatialReference)
        {
            if (spatialReference == null) throw new ArgumentNullException("spatialReference");

            var xmlStream = new XMLStreamClass();
            var xmlWriter = new XMLWriterClass();
            var xmlSerializer = new XMLSerializerClass();

            xmlWriter.WriteTo(xmlStream);
            xmlSerializer.WriteObject(xmlWriter, null, null, string.Empty, string.Empty, spatialReference);

            return xmlStream.SaveToString();
        }

You will get xml like this:

<ProjectedCoordinateSystem xsi:type='typens:ProjectedCoordinateSystem' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/10.8'>
<WKT>PROJCS[&quot;LKS_1994_Transverse_Mercator&quot;,GEOGCS[&quot;GCS_LKS_1994&quot;,DATUM[&quot;D_Lithuania_1994&quot;,SPHEROID[&quot;GRS_1980&quot;,6378137.0,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0.0],UNIT[&quot;Degree&quot;,0.0174532925199433]],PROJECTION[&quot;Transverse_Mercator&quot;],PARAMETER[&quot;False_Easting&quot;,500000.0],PARAMETER[&quot;False_Northing&quot;,0.0],PARAMETER[&quot;Central_Meridian&quot;,24.0],PARAMETER[&quot;Scale_Factor&quot;,0.9998],PARAMETER[&quot;Latitude_Of_Origin&quot;,0.0],UNIT[&quot;Meter&quot;,1.0]]</WKT>
<XOrigin>-22523120044.116333</XOrigin>
<YOrigin>-22527998119.405388</YOrigin>
<XYScale>18181.818166159173</XYScale>
<ZOrigin>-100000</ZOrigin>
<ZScale>10000</ZScale>
<MOrigin>-100000</MOrigin>
<MScale>10000</MScale>
<XYTolerance>0.001</XYTolerance>
<ZTolerance>0.001</ZTolerance>
<MTolerance>0.001</MTolerance>
<HighPrecision>true</HighPrecision>
</ProjectedCoordinateSystem>

Then read WKT node from it

View solution in original post

0 Kudos
5 Replies
GKmieliauskas
Esri Regular Contributor

Hi,

You can serialize ISpatialReference object to xml ant then read wkt from it. Code for serialization:

        private static string GetSpatialReferenceAsXmlString(ISpatialReference spatialReference)
        {
            if (spatialReference == null) throw new ArgumentNullException("spatialReference");

            var xmlStream = new XMLStreamClass();
            var xmlWriter = new XMLWriterClass();
            var xmlSerializer = new XMLSerializerClass();

            xmlWriter.WriteTo(xmlStream);
            xmlSerializer.WriteObject(xmlWriter, null, null, string.Empty, string.Empty, spatialReference);

            return xmlStream.SaveToString();
        }

You will get xml like this:

<ProjectedCoordinateSystem xsi:type='typens:ProjectedCoordinateSystem' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/10.8'>
<WKT>PROJCS[&quot;LKS_1994_Transverse_Mercator&quot;,GEOGCS[&quot;GCS_LKS_1994&quot;,DATUM[&quot;D_Lithuania_1994&quot;,SPHEROID[&quot;GRS_1980&quot;,6378137.0,298.257222101]],PRIMEM[&quot;Greenwich&quot;,0.0],UNIT[&quot;Degree&quot;,0.0174532925199433]],PROJECTION[&quot;Transverse_Mercator&quot;],PARAMETER[&quot;False_Easting&quot;,500000.0],PARAMETER[&quot;False_Northing&quot;,0.0],PARAMETER[&quot;Central_Meridian&quot;,24.0],PARAMETER[&quot;Scale_Factor&quot;,0.9998],PARAMETER[&quot;Latitude_Of_Origin&quot;,0.0],UNIT[&quot;Meter&quot;,1.0]]</WKT>
<XOrigin>-22523120044.116333</XOrigin>
<YOrigin>-22527998119.405388</YOrigin>
<XYScale>18181.818166159173</XYScale>
<ZOrigin>-100000</ZOrigin>
<ZScale>10000</ZScale>
<MOrigin>-100000</MOrigin>
<MScale>10000</MScale>
<XYTolerance>0.001</XYTolerance>
<ZTolerance>0.001</ZTolerance>
<MTolerance>0.001</MTolerance>
<HighPrecision>true</HighPrecision>
</ProjectedCoordinateSystem>

Then read WKT node from it

0 Kudos
AbelPerez
Frequent Contributor

Wow, I didnt know you could do that. Thanks!

0 Kudos
KirkKuykendall1
Frequent Contributor
0 Kudos
AbelPerez
Frequent Contributor

I like that one too except you have to write it to disk first.

0 Kudos
AbelPerez
Frequent Contributor

As a final edit I took @GKmieliauskas code and made it an extension. Note I use full namespaces so as not to clash with the MS XML functions.

    <Extension()>
    Function SerializeEsri(Of T As Class)(ByVal value As T) As XDocument
        Dim sr As New ESRI.ArcGIS.esriSystem.XMLStream
        Dim ir As ESRI.ArcGIS.esriSystem.IStream = CType(sr, ESRI.ArcGIS.esriSystem.IStream)
        Dim wr As New ESRI.ArcGIS.esriSystem.XMLWriter
        Dim ser As New ESRI.ArcGIS.esriSystem.XMLSerializer

        wr.WriteTo(ir)
        ser.WriteObject(wr, Nothing, Nothing, String.Empty, String.Empty, value)

        Dim xdoc As XDocument = XDocument.Parse(sr.SaveToString)
        Return xdoc
    End Function

 

Usage:

 

    Private Function GetSpatialReferenceAsWkt(pSpatRef As ISpatialReference) As String
        If pSpatRef Is Nothing Then Return Nothing

        Dim xdoc As XDocument = pSpatRef.SerializeEsri
        Dim xelem As XElement = xdoc.Root.Element("WKT")
        Return xelem.Value
    End Function

 

0 Kudos