ThinkGeo.com    |     Documentation    |     Premium Support

Creating shapefiles with objects of type polyline from SQL data

Scenario: I've got a layer called secserv of type ESRI(03) polyline. Behind this layer I have sql SDE data that is storing a binary field (Shape) along with xmin,ymin,xmax,ymax (bounding box) for each record. Because my polyline features don't have vertices for each contiguous part, I'd like to be able to extract the necessary information from the SHAPE field in order to rebuild the secserv layer when necessary. I don't even know if this is possible but I figured you guys would. What I have done is read the data from the shape field into a byte array and by that I've been able to follow the ESRI layout. I just don't know what to do with the data.


SQL example of data in SHAPE field:


0x03000000C46ECD652304244162EECB0213951A41C32F07CCB5042441C8A089952E971A41010000000200000000000000C46ECD652304244162EECB0213951A41C32F07CCB5042441C8A089952E971A4100


This is basically what you guys are writing for each record in a polyline shapefile, right?


If there is another way to generate shapefiles from Data without vertices, please let me know.






 


Steve,


Besides vertices, you can also get a shape from WKT or WKB. Here is some codes where you can find how to use WKT/WKB in Map Suite 3.0.


I tried the Hex String you provided and seems that's not a standard WKB, instead it's following the Record format of a Shape File. We don't support this format but with the specification here (esri.com/library/whitepapers/pdfs/shapefile.pdf page 7), you can easily support it by yourself.



  private void Form1_Load(object sender, EventArgs e)
        {
           // Get WKB
            LineShape lineShape = new LineShape("LINESTRING(0 0,1 1,1 2)");
            byte[] lineShapeWKB = lineShape.GetWellKnownBinary();

            // Get the hex string of the lineShape's WKB
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < lineShapeWKB.Length; i++)
            {
                sb.Append(lineShapeWKB[i].ToString("X2"));
            }
            string lineShapeWKBHexString = sb.ToString();

            // Just a test, you can see the return value lineShape2 is identical to lineShape
            byte[] lineShapeWKB2 = GetBytesFromHexString(lineShapeWKBHexString);
            BaseShape lineShape2 = BaseShape.CreateShapeFromWellKnownData(lineShapeWKB2);

            // Try to get the shape from the WKB you provide
            string userWKBHexString = "03000000C46ECD652304244162EECB0213951A41C32F07CCB5042441C8A089952E971A41010000000200000000000000C46ECD652304244162EECB0213951A41C32F07CCB5042441C8A089952E971A4100";
            byte[] userWKB = GetBytesFromHexString(userWKBHexString);
            // throws an exception here that the input WKB is not valid
            BaseShape shape = BaseShape.CreateShapeFromWellKnownData(userWKB);

  }

   private byte[] GetBytesFromHexString(string hexString)
        {
            int length = hexString.Length;
            if (length % 2 != 0)
            {
                throw new ArgumentException("The input hexString is not correct");
            }

            byte[] results = new byte[length / 2];
            for (int i = 0; i < hexString.Length; )
            {
                string subString = hexString.Substring(i, 2);
                results[i / 2] = byte.Parse(subString, System.Globalization.NumberStyles.HexNumber);
                i += 2;
            }
            return results;
        }

Let me know if you have any issues.


Thanks,


Ben