How do I flip X/Y geometry in a feature class?

4413
12
10-17-2016 07:54 AM
EricEagle
Occasional Contributor III

I have a geoJSON service I'm querying that's being supplied by GeoServer.  I have a python script that ingests this feed routinely and uses arcpy.AsShape to render the geoJSON as various feature classes (I am extracting points, lines and polygons).

The problem is that the X/Ys in the service itself are backwards, even according to its own documentation.  So my features are falling in all kinds of impossible locations.

Is there a fast way in python to flip the X/Y geometry in feature classes, including the vertices of line and polygon types?

0 Kudos
12 Replies
DanPatterson_Retired
MVP Emeritus
np.flipud(np.fliplr(a))
array([[9, 4],
       [8, 3],
       [7, 2],
       [6, 1],
       [5, 0]])‍‍‍‍‍‍

One more for the head  .... just roll with it

>>> np.roll(a, 2, axis=0)
array([[3, 8],
       [4, 9],
       [0, 5],
       [1, 6],
       [2, 7]])
0 Kudos
DanPatterson_Retired
MVP Emeritus

for people trying to follow along

AsShape—Help | ArcGIS for Desktop 

If the Esri JSON is a feature set, AsShape will return a FeatureSet. ArcGIS REST API specification defines feature set as a collection of features with a specific geometry type, fields, and a spatial reference. The JSON to Features tool can be used to convert Esri JSON directly into a feature class.

 

which leads to here

JSON To Features—Help | ArcGIS for Desktop 

0 Kudos
TedKowal
Occasional Contributor III

I have not dealt with that specific problem, but I am working with SQL server with features converted to text strings (WKT) and mapping them over Bing Maps.  SQL server stores the X,Y coordinate opposite of the way the Bing Maps API needs them, and a few other parens  "()"  formatting issues.... so I created a class in vb.net to rewrite the WKT  stored in SQL Server flipping the XY coordinates on the fly.... Hopefully this will give you some ideas?

Imports Microsoft.VisualBasic

Namespace TSK.GML2VE
     Public Class GML2VE
          Private mGML As String = ""
          Private mFeatureType As String = ""
          Private mShapeID As String = ""
          Private mFID As Integer = 0
          Public Property ShapeID() As String
               Get
                    Return mShapeID
               End Get
               Set(ShapeID As String)
                    mShapeID = ShapeID
               End Set
          End Property

          Public Property FID() As Integer
               Get
                    Return mFID
               End Get
               Set(FID As Integer)
                    mFID = FID
               End Set
          End Property
          Public Property GML() As String
               Get
                    Return mGML
               End Get
               Set(GML As String)
                    mGML = GML
               End Set
          End Property
          Public Property FeatureType() As String 
               Get
                    Return mFeatureType
               End Get
               Set(FeatureType As String)
                    mFeatureType = FeatureType
               End Set
          End Property
          Public Function VE() As String
               If mGML = "" Or mFeatureType = "" Or mShapeID = "" Then
                    Return "Set GML, Feature Type"
               Else
                    Dim WKT As String = ""
                    Dim Output As String = ""
                    Dim VEGM As String = ""
                    Select Case mFeatureType
                         Case "Point"
                              'Get the WKT representation of the object
                              WKT = mGML
                              'Replace the double brakets that surround the coordinate pair
                              WKT = Replace(WKT, "POINT (", "")
                              ''Remove the closing double brackets 
                              WKT = Replace(WKT, ")", "")
                              'Build the Pushpin/GMarker object from the coordinates
                              VEGM = ""
                              Dim Coords() = Split(Trim(WKT), " ")
                              VEGM = VEGM + "new VELatLong(" + Coords(1) + "," + Coords(0) + ")"
                              Output += "var " + mShapeID + "=new VEShape(VEShapeType.Pushpin, " + VEGM + ");"
                         Case "LineString"
                              'Get the WKT
                              WKT = mGML
                              'Remove the Line String definition and opening bracket
                              WKT = Replace(WKT, "LINESTRING (", "")
                              'Remove the last bracket
                              WKT = Replace(WKT, ")", "")
                              'Create an Array of each point in the LineString
                              Dim PointArray() As String = Split(WKT, ",")
                              'Loop  through each point in the array
                              Dim i As Integer = 0
                              While i <= PointArray.Length - 1
                                   'Split the pint into individual coordinates
                                   Dim Coords() = Split(Trim(PointArray(i)), " ")
                                   'Build an array of the equivalent point definitions
                                   VEGM = VEGM + " new VELatLong(" + Coords(1) + "," + Coords(0) + "),"
                                   'Go on to the next point
                                   i = i + 1
                              End While
                              'Remove the trailing comma
                              VEGM = Left(VEGM, VEGM.Length - 1)
                              Output += "var " + mShapeID + "= new VEShape(VEShapeType.Polyline, [" + VEGM + "]);"
                              'Do Text and pretty stuff
                         Case "Polygon"
                              'Get the WKT representation of the object
                              WKT = mGML
                              'Replace the double brackets that surround the coordinate point pairs
                              WKT = Replace(WKT, "POLYGON ((", "")
                              'Remove the closing double brackets
                              WKT = Replace(WKT, "))", "")
                              'Create an array of each point in the Polygon 
                              Dim PointArray() As String = Split(WKT, ",")
                              'Build the appropriate VE/GMaps Polygon object from the coordinates
                              VEGM = ""
                              Dim i As Integer = 0
                              While i <= PointArray.Length - 1
                                   Dim Coords() = Split(Trim(PointArray(i)), " ")
                                   Coords(0) = Coords(0).Replace("(", "")
                                   Coords(1) = Coords(1).Replace(")", "")
                                   VEGM = VEGM + "new VELatLong(" + Coords(1) + "," + Coords(0) + "),"
                                   i = i + 1
                              End While
                              'Remove the last trailing comma
                              VEGM = Left(VEGM, VEGM.Length - 1)
                              'Add the constructor for the Polygon, and apply styling options
                              Output += "var " + mShapeID + "=new VEShape(VEShapeType.Polygon, [" + VEGM + "]);"
                    End Select
                    Return Output
               End If
          End Function
     End Class
End Namespace

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍