Load an ESRI Shape File

1428
15
05-13-2011 10:48 AM
MichaelAquilina
New Contributor
Hey guys, i was wondering if the ArcGIS library for WPF contains a method or class for loading and saving Shape file information.

I am aware that the format for a shape file is documented, so i could implement it myself if needed; but if the method is readily available there would be no need for this.
0 Kudos
15 Replies
IgressT
New Contributor II
0 Kudos
MichaelAquilina
New Contributor
http://esrislcontrib.codeplex.com/


Thanks! just what i need!

....however i cant seem to find the download link :S
0 Kudos
LanceCrumbliss
Occasional Contributor II
i seem to recall being able to download the compiled assembly, but you're right, it's not there any more.  it looks like you'll need to download the source code and compile it yourself.
0 Kudos
MichaelAquilina
New Contributor
i seem to recall being able to download the compiled assembly, but you're right, it's not there any more.  it looks like you'll need to download the source code and compile it yourself.


I took too much time trying to find the assembly so i decided to implement a method for reading and writing shape files myself.....was surprisingly easy! If anyone wishes some simple code snippets for help just ask 🙂

Thanks for the help!
0 Kudos
IgressT
New Contributor II
I took too much time trying to find the assembly so i decided to implement a method for reading and writing shape files myself.....was surprisingly easy! If anyone wishes some simple code snippets for help just ask 🙂

Thanks for the help!


Can you please send me the code?
0 Kudos
MichaelAquilina
New Contributor
Can you please send me the code?


well i implemented the code for loading Polyline and Point objects only since those are the ones i need but here it is:

public enum ShapeType
    {
        NullShape,
        Point, PolyLine, Polygon, MultiPoint,
        PointZ, PolyLineZ, PolygonZ, MultiPointZ,
        PointM, PolyLineM, PolygonM, MultiPointM,
        MultiPatch,
        Unknown
    };

    public class ShapeFile
    {
        public static ShapeType[] SupportedShapes = new ShapeType[] { ShapeType.PolyLine, ShapeType.Point };

        public ShapeType ShapeType;
        public int FileLength;
        public int Version;
        public int FileCode;

        public BoundingBox Boundary;

        public List<VectorShape> Data = new List<VectorShape>();

        public void Read(String ShapeFile )
        {
            FileStream Stream = new FileStream(ShapeFile, FileMode.Open);
            BinaryReader Reader = new BinaryReader(Stream);

            FileCode = (int) ReverseBytes((UInt32)Reader.ReadInt32());

            if (FileCode != 9994)
                throw new IOException("The Input file specified is not a valid Shape File (Invalid FileCode)");

            //read empty bytes found in the file
            Reader.ReadBytes(20);

            FileLength = (int) ReverseBytes((UInt32)Reader.ReadInt32());
            Version = Reader.ReadInt32();
            ShapeType =  GetShapeType(Reader.ReadInt32());

            if (ShapeType == ShapeType.Unknown)
                throw new IOException("The Input file has an unknown Shape Type Specified");

            if (!SupportedShapes.Contains(ShapeType))
                throw new IOException("The Input file has a shape type that is not suppored (" + ShapeType + ")\n" +
                                      "The Following types are supported:\n" +
                                      SupportedShapes);

            Boundary = new BoundingBox();
            Boundary.XMin = Reader.ReadDouble();
            Boundary.YMin = Reader.ReadDouble();
            Boundary.XMax = Reader.ReadDouble();
            Boundary.YMax = Reader.ReadDouble();
            Boundary.ZMin = Reader.ReadDouble();
            Boundary.ZMax = Reader.ReadDouble();
            Boundary.MMin = Reader.ReadDouble();
            Boundary.MMax = Reader.ReadDouble();

            while (Stream.Position < FileLength)
            {
                int RecordNumber = (int)ReverseBytes((UInt32)Reader.ReadInt32());
                int ContentLength = (int)ReverseBytes((UInt32)Reader.ReadInt32());
                ShapeType RecordShapeType = GetShapeType( Reader.ReadInt32() );

                switch( RecordShapeType )
                {
                    case ShapeType.Point: Data.Add(ReadPoint(Reader)); break;
                    case ShapeType.PolyLine: Data.Add(ReadPolyLine(Reader)); break;
                }
            }

            Stream.Close();
        }

        public void Write(String ShapeFile)
        {
            FileStream Stream = new FileStream(ShapeFile, FileMode.Create);
            BinaryWriter Writer = new BinaryWriter(Stream);

            Writer.Write( ReverseBytes(9994) );     //filecode
            Writer.Seek(28, 0);                     //file length
            Writer.Write( (int) 1000);              //Version
            Writer.Write(GetShapeCode(ShapeType));
            Writer.Write(Boundary.XMin);
            Writer.Write(Boundary.YMin);
            Writer.Write(Boundary.XMax);
            Writer.Write(Boundary.YMax);
            Writer.Write(Boundary.ZMin);
            Writer.Write(Boundary.ZMax);
            Writer.Write(Boundary.MMin);
            Writer.Write(Boundary.MMax);

            for (int i = 0; i < Data.Count; i++)
            {
                Writer.Write((int)ReverseBytes((UInt32)i));
                Writer.Write((int)ReverseBytes((UInt32)Data.SizeOf()));       //content length

                if (Data is PolyLine)
                {
                    Writer.Write(GetShapeCode(ShapeType.PolyLine));
                    WritePolyline(Writer, (PolyLine) Data );
                }

                if (Data is Point )
                {
                    Writer.Write(GetShapeCode(ShapeType.Point));
                    WritePoint(Writer, (Point) Data );
                }
            }

            int FileLength = (int) Stream.Position;
            Writer.Seek(24,0);
            Writer.Write((int)ReverseBytes((UInt32)FileLength));

            Stream.Close();
        }

        private void WritePoint(BinaryWriter Writer, Point Point)
        {
            Writer.Write(Point.X);
            Writer.Write(Point.Y);
        }

        private Point ReadPoint(BinaryReader Reader)
        {
            Point Point = new Point();
            Point.X = Reader.ReadDouble();
            Point.Y = Reader.ReadDouble();

            return Point;
        }

        private void WritePolyline(BinaryWriter Writer, PolyLine PolyLine)
        {
            Writer.Write(PolyLine.XMin);
            Writer.Write(PolyLine.YMin);
            Writer.Write(PolyLine.XMax);
            Writer.Write(PolyLine.YMax);

            Writer.Write(PolyLine.NumParts);
            Writer.Write(PolyLine.NumPoints);
            for (int i = 0; i < PolyLine.NumParts; i++ )
                Writer.Write( PolyLine.Parts );

            for (int i = 0; i < PolyLine.NumPoints; i++)
                WritePoint(Writer, PolyLine.Points);
        }

        private PolyLine ReadPolyLine(BinaryReader Reader)
        {
            PolyLine Output = new PolyLine();
            Output.XMin = Reader.ReadDouble();
            Output.YMin = Reader.ReadDouble();
            Output.XMax = Reader.ReadDouble();
            Output.YMax = Reader.ReadDouble();

            Output.NumParts = Reader.ReadInt32();
            Output.NumPoints = Reader.ReadInt32();
            Output.Parts = new int[Output.NumParts];
            Output.Points = new Point[Output.NumPoints];

            for (int i = 0; i < Output.Parts.Length; i++)
                Output.Parts = Reader.ReadInt32();

            for (int i = 0; i < Output.Points.Length; i++)
                Output.Points = ReadPoint(Reader);

            return Output;
        }

        public static UInt32 ReverseBytes(UInt32 value)
        {
            return (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 |
                   (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24;
        }

        public static int GetShapeCode(ShapeType Type)
        {
            switch (Type)
            {
                case ShapeType.NullShape : return 0;
                case ShapeType.Point: return 1;
                case ShapeType.PolyLine : return 3;
                case ShapeType.Polygon: return 5;
                case ShapeType.MultiPoint: return 8;
                case ShapeType.PointZ: return 11;
                case ShapeType.PolyLineZ: return 13;
                case ShapeType.PolygonZ: return 15;
                case ShapeType.MultiPointZ: return 18;
                case ShapeType.PointM: return 21;
                case ShapeType.PolyLineM : return 23;
                case ShapeType.PolygonM : return 25;
                case ShapeType.MultiPointM: return 28;
                case ShapeType.MultiPatch: return 31;
                default :return -1;
            }
        }

        public static ShapeType GetShapeType(int Code)
        {
            switch (Code)
            {
                case 0: return ShapeType.NullShape;
                case 1: return ShapeType.Point;
                case 3: return ShapeType.PolyLine;
                case 5: return ShapeType.Polygon;
                case 8: return ShapeType.MultiPoint;
                case 11: return ShapeType.PointZ;
                case 13: return ShapeType.PolyLineZ;
                case 15: return ShapeType.PolygonZ;
                case 18: return ShapeType.MultiPointZ;
                case 21: return ShapeType.PointM;
                case 23: return ShapeType.PolyLineM;
                case 25: return ShapeType.PolygonM;
                case 28: return ShapeType.MultiPointM;
                case 31: return ShapeType.MultiPatch;
                default: return ShapeType.Unknown;
            }
        }

        public override string ToString()
        {
            return "Version = " + Version + ", FileLength = " + FileLength + ", FileCode = " + FileCode + ", ShapeType = " + ShapeType + ", Boundary = " + Boundary;
        }
    }
0 Kudos
DominiqueBroux
Esri Frequent Contributor
0 Kudos
ErikEngstrom
Occasional Contributor II
Yeah, I too found that rectifying the Observable assemblies taking too much time.
If you have some code to share, I'd love to see how you're uploading/writing shapefiles.

My E-mail is:
Erik.Engstrom@state.vt.us

THANKS!
0 Kudos
AngelGonzalez
Occasional Contributor II
I also would like to look at your code if you don't mind.

My email is
agonzale@fontana.org

Thanks
0 Kudos