Example #1
0
        /// <inheritdoc />
        protected override void AppendGeometry(ShapefileHeader header, IGeometry feature, int numFeatures)
        {
            var fi     = new FileInfo(Filename);
            int offset = Convert.ToInt32(fi.Length / 2);

            var shpStream = new FileStream(Filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000);
            var shxStream = new FileStream(header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 100);

            Coordinate point         = feature.Coordinates[0];
            int        contentLength = 10;

            if (header.ShapeType == ShapeType.PointM)
            {
                contentLength += 4; // one additional value (m)
            }

            if (header.ShapeType == ShapeType.PointZ)
            {
                contentLength += 8; // 2 additional values (m, z)
            }

            ////                                            Index File
            //                                              ---------------------------------------------------------
            //                                              Position     Value               Type        Number      Byte Order
            //                                              ---------------------------------------------------------
            shxStream.WriteBe(offset);                      // Byte 0     Offset             Integer     1           Big
            shxStream.WriteBe(contentLength);               // Byte 4    Content Length      Integer     1           Big
            shxStream.Flush();
            shxStream.Close();
            ////                                            X Y Points
            //                                              ---------------------------------------------------------
            //                                              Position     Value               Type        Number      Byte Order
            //                                              ---------------------------------------------------------
            shpStream.WriteBe(numFeatures);                 // Byte 0       Record Number       Integer     1           Big
            shpStream.WriteBe(contentLength);               // Byte 4       Content Length      Integer     1           Big
            shpStream.WriteLe((int)header.ShapeType);       // Byte 8       Shape Type 3        Integer     1           Little
            if (header.ShapeType == ShapeType.NullShape)
            {
                return;
            }

            shpStream.WriteLe(point.X);                     // Byte 12      X                   Double      1           Little
            shpStream.WriteLe(point.Y);                     // Byte 20      Y                   Double      1           Little

            if (header.ShapeType == ShapeType.PointM)
            {
                shpStream.WriteLe(point.M);                 // Byte 28      M                   Double      1           Little
            }
            else if (header.ShapeType == ShapeType.PointZ)
            {
                shpStream.WriteLe(point.Z);                 // Byte 28      Z                   Double      1           Little
                shpStream.WriteLe(point.M);                 // Byte 36      M                   Double      1           Little
            }

            shpStream.Flush();
            shpStream.Close();
            offset += contentLength;
            Shapefile.WriteFileLength(Filename, offset + 4); // Add 4 for the record header
            Shapefile.WriteFileLength(header.ShxFilename, 50 + numFeatures * 4);
        }
Example #2
0
        /// <inheritdoc/>
        protected override void AppendBasicGeometry(ShapefileHeader header, IBasicGeometry feature, int numFeatures)
        {
            FileInfo fi     = new FileInfo(Filename);
            int      offset = Convert.ToInt32(fi.Length / 2);

            FileStream shpStream = new FileStream(Filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000);
            FileStream shxStream = new FileStream(header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 100);

            List <int> parts = new List <int>();

            List <Coordinate> points = new List <Coordinate>();
            int contentLength        = 22;

            for (int iPart = 0; iPart < feature.NumGeometries; iPart++)
            {
                parts.Add(points.Count);
                IBasicPolygon pg = feature.GetBasicGeometryN(iPart) as IBasicPolygon;
                if (pg == null)
                {
                    continue;
                }
                var bl     = pg.Shell;
                var coords = bl.Coordinates;

                if (CgAlgorithms.IsCounterClockwise(coords))
                {
                    // Exterior rings need to be clockwise
                    coords.Reverse();
                }

                points.AddRange(coords);
                foreach (IBasicLineString hole in pg.Holes)
                {
                    parts.Add(points.Count);
                    var holeCoords = hole.Coordinates;
                    if (CgAlgorithms.IsCounterClockwise(holeCoords) == false)
                    {
                        // Interior rings need to be counter-clockwise
                        holeCoords.Reverse();
                    }
                    points.AddRange(holeCoords);
                }
            }
            contentLength += 2 * parts.Count;
            if (header.ShapeType == ShapeType.Polygon)
            {
                contentLength += points.Count * 8;
            }
            if (header.ShapeType == ShapeType.PolygonM)
            {
                contentLength += 8;                 // mmin mmax
                contentLength += points.Count * 12; // x, y, m
            }
            if (header.ShapeType == ShapeType.PolygonZ)
            {
                contentLength += 16;                // mmin, mmax, zmin, zmax
                contentLength += points.Count * 16; // x, y, m, z
            }

            //                                              Index File
            //                                              ---------------------------------------------------------
            //                                              Position     Value               Type        Number      Byte Order
            //                                              ---------------------------------------------------------
            shxStream.WriteBe(offset);                      // Byte 0     Offset             Integer     1           Big
            shxStream.WriteBe(contentLength);               // Byte 4    Content Length      Integer     1           Big
            shxStream.Flush();
            shxStream.Close();
            //                                              X Y Poly Lines
            //                                              ---------------------------------------------------------
            //                                              Position     Value               Type        Number      Byte Order
            //                                              ---------------------------------------------------------
            shpStream.WriteBe(numFeatures);                 // Byte 0       Record Number       Integer     1           Big
            shpStream.WriteBe(contentLength);               // Byte 4       Content Length      Integer     1           Big
            shpStream.WriteLe((int)header.ShapeType);       // Byte 8       Shape Type 3        Integer     1           Little
            if (header.ShapeType == ShapeType.NullShape)
            {
                return;
            }

            shpStream.WriteLe(feature.Envelope.Minimum.X);             // Byte 12      Xmin                Double      1           Little
            shpStream.WriteLe(feature.Envelope.Minimum.Y);             // Byte 20      Ymin                Double      1           Little
            shpStream.WriteLe(feature.Envelope.Maximum.X);             // Byte 28      Xmax                Double      1           Little
            shpStream.WriteLe(feature.Envelope.Maximum.Y);             // Byte 36      Ymax                Double      1           Little
            shpStream.WriteLe(parts.Count);                            // Byte 44      NumParts            Integer     1           Little
            shpStream.WriteLe(points.Count);                           // Byte 48      NumPoints           Integer     1           Little
            // Byte 52      Parts               Integer     NumParts    Little
            foreach (int iPart in parts)
            {
                shpStream.WriteLe(iPart);
            }
            double[] xyVals = new double[points.Count * 2];

            int i = 0;

            foreach (Coordinate coord in points)
            {
                xyVals[i * 2]     = coord.X;
                xyVals[i * 2 + 1] = coord.Y;
                i++;
            }
            shpStream.WriteLe(xyVals, 0, 2 * points.Count);

            if (header.ShapeType == ShapeType.PolygonZ)
            {
                shpStream.WriteLe(feature.Envelope.Minimum.Z);
                shpStream.WriteLe(feature.Envelope.Maximum.Z);
                double[] zVals = new double[points.Count];
                for (int ipoint = 0; ipoint < points.Count; ipoint++)
                {
                    zVals[ipoint] = points[ipoint].Z;
                }
                shpStream.WriteLe(zVals, 0, points.Count);
            }

            if (header.ShapeType == ShapeType.PolygonM || header.ShapeType == ShapeType.PolygonZ)
            {
                if (feature.Envelope == null)
                {
                    shpStream.WriteLe(0.0);
                    shpStream.WriteLe(0.0);
                }
                else
                {
                    shpStream.WriteLe(feature.Envelope.Minimum.M);
                    shpStream.WriteLe(feature.Envelope.Maximum.M);
                }

                double[] mVals = new double[points.Count];
                for (int ipoint = 0; ipoint < points.Count; i++)
                {
                    mVals[ipoint] = points[ipoint].M;
                    ipoint++;
                }
                shpStream.WriteLe(mVals, 0, points.Count);
            }
            shpStream.Flush();
            shpStream.Close();
            offset += contentLength;
            Shapefile.WriteFileLength(Filename, offset);
            Shapefile.WriteFileLength(header.ShxFilename, 50 + numFeatures * 4);
        }
Example #3
0
        /// <inheritdoc/>
        protected override void AppendGeometry(ShapefileHeader header, Geometry feature, int numFeatures)
        {
            FileInfo fi     = new FileInfo(Filename);
            int      offset = Convert.ToInt32(fi.Length / 2);

            FileStream shpStream = new FileStream(Filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000);
            FileStream shxStream = new FileStream(header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 100);

            List <int> parts = new List <int>();

            List <Coordinate> points = new List <Coordinate>();
            int contentLength        = 22;

            for (int iPart = 0; iPart < feature.NumGeometries; iPart++)
            {
                parts.Add(points.Count);
                Polygon pg = feature.GetGeometryN(iPart) as Polygon;
                if (pg == null)
                {
                    continue;
                }
                var bl = pg.Shell;
                IEnumerable <Coordinate> coords = bl.Coordinates;

                if (Orientation.IsCCW(bl.Coordinates))
                {
                    // Exterior rings need to be clockwise
                    coords = coords.Reverse();
                }

                points.AddRange(coords);
                foreach (LineString hole in pg.Holes)
                {
                    parts.Add(points.Count);
                    IEnumerable <Coordinate> holeCoords = hole.Coordinates;
                    if (!Orientation.IsCCW(hole.Coordinates))
                    {
                        // Interior rings need to be counter-clockwise
                        holeCoords = holeCoords.Reverse();
                    }

                    points.AddRange(holeCoords);
                }
            }

            contentLength += 2 * parts.Count;
            if (header.ShapeType == ShapeType.Polygon)
            {
                contentLength += points.Count * 8;
            }
            else if (header.ShapeType == ShapeType.PolygonM)
            {
                contentLength += 8;                 // mmin mmax
                contentLength += points.Count * 12; // x, y, m
            }
            else if (header.ShapeType == ShapeType.PolygonZ)
            {
                contentLength += 16;                // mmin, mmax, zmin, zmax
                contentLength += points.Count * 16; // x, y, m, z
            }

            ////                                              Index File
            //                                                 ---------------------------------------------------------
            //                                                 Position     Value               Type        Number      Byte Order
            //                                                 ---------------------------------------------------------
            shxStream.WriteBe(offset);                         // Byte 0     Offset             Integer     1           Big
            shxStream.WriteBe(contentLength);                  // Byte 4    Content Length      Integer     1           Big
            shxStream.Flush();
            shxStream.Close();
            ////                                                 X Y Poly Lines
            //                                                 ---------------------------------------------------------
            //                                                 Position     Value               Type        Number      Byte Order
            //                                                 ---------------------------------------------------------
            shpStream.WriteBe(numFeatures);                    // Byte 0       Record Number       Integer     1           Big
            shpStream.WriteBe(contentLength);                  // Byte 4       Content Length      Integer     1           Big
            shpStream.WriteLe((int)header.ShapeType);          // Byte 8       Shape Type 3        Integer     1           Little
            if (header.ShapeType == ShapeType.NullShape)
            {
                return;
            }

            shpStream.WriteLe(feature.EnvelopeInternal.MinX);  // Byte 12      Xmin                Double      1           Little
            shpStream.WriteLe(feature.EnvelopeInternal.MinY);  // Byte 20      Ymin                Double      1           Little
            shpStream.WriteLe(feature.EnvelopeInternal.MaxX);  // Byte 28      Xmax                Double      1           Little
            shpStream.WriteLe(feature.EnvelopeInternal.MaxY);  // Byte 36      Ymax                Double      1           Little
            shpStream.WriteLe(parts.Count);                    // Byte 44      NumParts            Integer     1           Little
            shpStream.WriteLe(points.Count);                   // Byte 48      NumPoints           Integer     1           Little

            foreach (int iPart in parts)
            {
                shpStream.WriteLe(iPart);                      // Byte 52      Parts               Integer     NumParts    Little
            }

            double[] xyVals = new double[points.Count * 2];
            for (var i = 0; i < points.Count; i++)
            {
                xyVals[i * 2]     = points[i].X;
                xyVals[i * 2 + 1] = points[i].Y;
            }

            shpStream.WriteLe(xyVals, 0, 2 * points.Count);

            if (header.ShapeType == ShapeType.PolygonZ)
            {
                // Pandell, 2020-06-23: "NetTopologySuite" version 1.7.5 doesn't have "NetTopologySuite.Geometries.Envelope.Minimum" property
                // shpStream.WriteLe(feature.EnvelopeInternal.Minimum.Z);
                // shpStream.WriteLe(feature.EnvelopeInternal.Maximum.Z);
                shpStream.WriteLe(double.NaN);
                shpStream.WriteLe(double.NaN);
                double[] zVals = new double[points.Count];
                for (int ipoint = 0; ipoint < points.Count; ipoint++)
                {
                    zVals[ipoint] = points[ipoint].Z;
                }

                shpStream.WriteLe(zVals, 0, points.Count);
            }

            if (header.ShapeType == ShapeType.PolygonM || header.ShapeType == ShapeType.PolygonZ)
            {
                if (feature.EnvelopeInternal == null)
                {
                    shpStream.WriteLe(0.0);
                    shpStream.WriteLe(0.0);
                }
                else
                {
                    // Pandell, 2020-06-23: "NetTopologySuite" version 1.7.5 doesn't have "NetTopologySuite.Geometries.Envelope.Minimum" property
                    // shpStream.WriteLe(feature.EnvelopeInternal.Minimum.M);
                    // shpStream.WriteLe(feature.EnvelopeInternal.Maximum.M);
                    shpStream.WriteLe(double.NaN);
                    shpStream.WriteLe(double.NaN);
                }

                double[] mVals = new double[points.Count];
                for (int ipoint = 0; ipoint < points.Count; ipoint++)
                {
                    mVals[ipoint] = points[ipoint].M;
                }

                shpStream.WriteLe(mVals, 0, points.Count);
            }

            shpStream.Flush();
            shpStream.Close();
            offset += contentLength;
            Shapefile.WriteFileLength(Filename, offset + 4); // Add 4 for the record header
            Shapefile.WriteFileLength(header.ShxFilename, 50 + numFeatures * 4);
        }
Example #4
0
        protected override void InsertGeometry(ShapefileHeader header, int fid, IGeometry geometry)
        {
            var shapeHeaders = ReadIndexFile(header.ShxFilename);

            if (fid < shapeHeaders.Count)
            {
                var        tmpShpPath   = Path.GetTempFileName();
                var        tmpShxPath   = Path.GetTempFileName();
                FileStream tmpShpStream = new FileStream(tmpShpPath, FileMode.Create, FileAccess.ReadWrite);
                FileStream shpStream    = new FileStream(Filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 10000);
                FileStream tmpShxStream = new FileStream(tmpShxPath, FileMode.Create, FileAccess.ReadWrite);
                FileStream shxStream    = new FileStream(header.ShxFilename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 100);

                long shpOffset          = shapeHeaders[fid].ByteOffset;
                long shpRemainderOffset = shpOffset;
                long shpRemainderCount  = shpStream.Length - shpRemainderOffset;
                if (shpRemainderCount > 0)
                {
                    CopyTo(shpStream, tmpShpStream, shpRemainderOffset, shpRemainderCount);
                }

                long shxOffset          = 100 + fid * 8;
                long shxRemainderOffset = shxOffset;
                long shxRemainderCount  = shxStream.Length - shxRemainderOffset;
                if (shxRemainderCount > 0)
                {
                    CopyTo(shxStream, tmpShxStream, shxRemainderOffset, shxRemainderCount);
                }

                shpStream.Seek(shpOffset, SeekOrigin.Begin);
                shxStream.Seek(shxOffset, SeekOrigin.Begin);
                int recordNumber = fid + 1;

                int contentLength = GetContentLength(header.ShapeType);

                ////                                            Index File
                //                                              ---------------------------------------------------------
                //                                              Position     Value               Type        Number      Byte Order
                //                                              ---------------------------------------------------------
                shxStream.WriteBe(shapeHeaders[fid].Offset);    // Byte 0     Offset             Integer     1           Big
                shxStream.WriteBe(contentLength);               // Byte 4    Content Length      Integer     1           Big

                ////                                            X Y Points
                //                                              ---------------------------------------------------------
                //                                              Position     Value               Type        Number      Byte Order
                //                                              ---------------------------------------------------------
                shpStream.WriteBe(recordNumber);             // Byte 0       Record Number       Integer     1           Big
                shpStream.WriteBe(contentLength);            // Byte 4       Content Length      Integer     1           Big
                shpStream.WriteLe((int)header.ShapeType);    // Byte 8       Shape Type 3        Integer     1           Little
                if (header.ShapeType != ShapeType.NullShape)
                {
                    WriteGeometryContent(shpStream, header.ShapeType, geometry);
                }

                if (shxRemainderCount > 0)
                {
                    CopyTo(tmpShxStream, shxStream, 0, shxRemainderCount);
                }
                int dOffset = (int)((shpStream.Position - shpOffset) / 2);
                if (dOffset != 0)
                {
                    long shpPosition = shpStream.Position;
                    for (int i = fid; i < shapeHeaders.Count; i++)
                    {
                        shxStream.Seek(100 + (i + 1) * 8, SeekOrigin.Begin);
                        shxStream.WriteBe(shapeHeaders[i].Offset + dOffset);

                        shpStream.Seek((shapeHeaders[i].Offset + dOffset) * 2, SeekOrigin.Begin);
                        shpStream.WriteBe(i + 2);
                    }
                    shpStream.Seek(shpPosition, SeekOrigin.Begin);
                }

                int shxLength = Convert.ToInt32(shxStream.Length / 2);
                shxStream.Flush();
                tmpShxStream.Dispose();
                shxStream.Dispose();
                File.Delete(tmpShxPath);

                if (shpRemainderCount > 0)
                {
                    CopyTo(tmpShpStream, shpStream, 0, shpRemainderCount);
                }
                if (shpStream.Length != shpStream.Position + shpRemainderCount)
                {
                    shpStream.SetLength(shpStream.Position + shpRemainderCount);
                }
                ;
                int shpLength = Convert.ToInt32(shpStream.Length / 2);
                shpStream.Flush();
                shpStream.Dispose();
                Shapefile.WriteFileLength(Filename, shpLength);
                Shapefile.WriteFileLength(header.ShxFilename, shxLength);
                tmpShpStream.Dispose();
                File.Delete(tmpShpPath);
            }
        }
Example #5
0
        /// <inheritdoc/>
        protected override void AppendGeometry(ShapefileHeader header, Geometry feature, int numFeatures)
        {
            FileInfo fi     = new FileInfo(Filename);
            int      offset = Convert.ToInt32(fi.Length / 2);

            FileStream shpStream = new FileStream(Filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000);
            FileStream shxStream = new FileStream(header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 100);

            List <int> parts = new List <int>();

            List <Coordinate> points = new List <Coordinate>();
            int contentLength        = 22;

            for (int iPart = 0; iPart < feature.NumGeometries; iPart++)
            {
                parts.Add(points.Count);
                LineString pg = feature.GetGeometryN(iPart) as LineString;
                if (pg == null)
                {
                    continue;
                }
                points.AddRange(pg.Coordinates);
            }

            contentLength += 2 * parts.Count;
            if (header.ShapeType == ShapeType.PolyLine)
            {
                contentLength += points.Count * 8;
            }

            if (header.ShapeType == ShapeType.PolyLineM)
            {
                contentLength += 8;                 // mmin mmax
                contentLength += points.Count * 12; // x, y, m
            }

            if (header.ShapeType == ShapeType.PolyLineZ)
            {
                contentLength += 16;                // mmin, mmax, zmin, zmax
                contentLength += points.Count * 16; // x, y, m, z
            }

            ////                                              Index File
            //                                                -------------------------------------------------------------------
            //                                                Position     Value               Type        Number      Byte Order
            //                                                -------------------------------------------------------------------
            shxStream.WriteBe(offset);                        // Byte 0    Offset              Integer     1           Big
            shxStream.WriteBe(contentLength);                 // Byte 4    Content Length      Integer     1           Big
            shxStream.Flush();
            shxStream.Close();
            ////                                              X Y Poly Lines
            //                                                -------------------------------------------------------------------
            //                                                Position     Value               Type        Number      Byte Order
            //                                                -------------------------------------------------------------------
            shpStream.WriteBe(numFeatures);                   // Byte 0    Record Number       Integer     1           Big
            shpStream.WriteBe(contentLength);                 // Byte 4    Content Length      Integer     1           Big
            shpStream.WriteLe((int)header.ShapeType);         // Byte 8    Shape Type 3        Integer     1           Little
            if (header.ShapeType == ShapeType.NullShape)
            {
                return;
            }

            shpStream.WriteLe(feature.EnvelopeInternal.MinX); // Byte 12   Xmin                Double      1           Little
            shpStream.WriteLe(feature.EnvelopeInternal.MinY); // Byte 20   Ymin                Double      1           Little
            shpStream.WriteLe(feature.EnvelopeInternal.MaxX); // Byte 28   Xmax                Double      1           Little
            shpStream.WriteLe(feature.EnvelopeInternal.MaxY); // Byte 36   Ymax                Double      1           Little
            shpStream.WriteLe(parts.Count);                   // Byte 44   NumParts            Integer     1           Little
            shpStream.WriteLe(points.Count);                  // Byte 48   NumPoints           Integer     1           Little

            foreach (int iPart in parts)
            {
                shpStream.WriteLe(iPart);                     // Byte 52   Parts               Integer     NumParts    Little
            }

            double[] xyVals = new double[points.Count * 2];

            for (var i = 0; i < points.Count; i++)
            {
                xyVals[i * 2]       = points[i].X;
                xyVals[(i * 2) + 1] = points[i].Y;
            }

            shpStream.WriteLe(xyVals, 0, 2 * points.Count);

            if (header.ShapeType == ShapeType.PolyLineZ)
            {
                shpStream.WriteLe(feature.MinZ());
                shpStream.WriteLe(feature.MaxZ());
                double[] zVals = new double[points.Count];
                for (int ipoint = 0; ipoint < points.Count; ipoint++)
                {
                    zVals[ipoint] = points[ipoint].Z;
                }

                shpStream.WriteLe(zVals, 0, points.Count);
            }

            if (header.ShapeType == ShapeType.PolyLineM || header.ShapeType == ShapeType.PolyLineZ)
            {
                if (feature.Envelope == null)
                {
                    shpStream.WriteLe(0.0);
                    shpStream.WriteLe(0.0);
                }
                else
                {
                    shpStream.WriteLe(feature.MinM());
                    shpStream.WriteLe(feature.MaxM());
                }

                double[] mVals = new double[points.Count];
                for (int ipoint = 0; ipoint < points.Count; ipoint++)
                {
                    mVals[ipoint] = points[ipoint].M;
                }

                shpStream.WriteLe(mVals, 0, points.Count);
            }

            shpStream.Flush();
            shpStream.Close();
            offset += contentLength;
            Shapefile.WriteFileLength(Filename, offset + 4); // Add 4 for the record header
            Shapefile.WriteFileLength(header.ShxFilename, 50 + (numFeatures * 4));
        }
Example #6
0
        protected override void InsertGeometry(ShapefileHeader header, int fid, IGeometry geometry)
        {
            var shapeHeaders = ReadIndexFile(header.ShxFilename);

            if (fid < shapeHeaders.Count)
            {
                var        tmpShpPath   = Path.GetTempFileName();
                var        tmpShxPath   = Path.GetTempFileName();
                FileStream tmpShpStream = new FileStream(tmpShpPath, FileMode.Create, FileAccess.ReadWrite);
                FileStream shpStream    = new FileStream(Filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 10000);
                FileStream tmpShxStream = new FileStream(tmpShxPath, FileMode.Create, FileAccess.ReadWrite);
                FileStream shxStream    = new FileStream(header.ShxFilename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 100);

                long shpOffset          = shapeHeaders[fid].ByteOffset;
                long shpRemainderOffset = shpOffset;
                long shpRemainderCount  = shpStream.Length - shpRemainderOffset;
                if (shpRemainderCount > 0)
                {
                    CopyTo(shpStream, tmpShpStream, shpRemainderOffset, shpRemainderCount);
                }

                long shxOffset          = 100 + fid * 8;
                long shxRemainderOffset = shxOffset;
                long shxRemainderCount  = shxStream.Length - shxRemainderOffset;
                if (shxRemainderCount > 0)
                {
                    CopyTo(shxStream, tmpShxStream, shxRemainderOffset, shxRemainderCount);
                }

                shpStream.Seek(shpOffset, SeekOrigin.Begin);
                shxStream.Seek(shxOffset, SeekOrigin.Begin);
                int recordNumber = fid + 1;

                List <int>        parts  = new List <int>();
                List <Coordinate> points = new List <Coordinate>();
                int contentLength        = 22;
                for (int iPart = 0; iPart < geometry.NumGeometries; iPart++)
                {
                    parts.Add(points.Count);
                    ILineString pg = geometry.GetGeometryN(iPart) as ILineString;
                    if (pg == null)
                    {
                        continue;
                    }
                    points.AddRange(pg.Coordinates);
                }

                contentLength += 2 * parts.Count;
                switch (header.ShapeType)
                {
                case ShapeType.PolyLine:
                    contentLength += points.Count * 8;
                    break;

                case ShapeType.PolyLineM:
                    contentLength += 8;                 // mmin mmax
                    contentLength += points.Count * 12; // x, y, m
                    break;

                case ShapeType.PolyLineZ:
                    contentLength += 16;                // mmin, mmax, zmin, zmax
                    contentLength += points.Count * 16; // x, y, m, z
                    break;
                }

                ////                                            Index File
                //                                              ---------------------------------------------------------
                //                                              Position     Value               Type        Number      Byte Order
                //                                              ---------------------------------------------------------
                shxStream.WriteBe(shapeHeaders[fid].Offset);    // Byte 0     Offset             Integer     1           Big
                shxStream.WriteBe(contentLength);               // Byte 4    Content Length      Integer     1           Big

                ////                                            X Y Points
                //                                              ---------------------------------------------------------
                //                                              Position     Value               Type        Number      Byte Order
                //                                              ---------------------------------------------------------
                shpStream.WriteBe(recordNumber);             // Byte 0       Record Number       Integer     1           Big
                shpStream.WriteBe(contentLength);            // Byte 4       Content Length      Integer     1           Big
                shpStream.WriteLe((int)header.ShapeType);    // Byte 8       Shape Type 3        Integer     1           Little
                if (header.ShapeType != ShapeType.NullShape)
                {
                    shpStream.WriteLe(geometry.EnvelopeInternal.MinX); // Byte 12   Xmin                Double      1           Little
                    shpStream.WriteLe(geometry.EnvelopeInternal.MinY); // Byte 20   Ymin                Double      1           Little
                    shpStream.WriteLe(geometry.EnvelopeInternal.MaxX); // Byte 28   Xmax                Double      1           Little
                    shpStream.WriteLe(geometry.EnvelopeInternal.MaxY); // Byte 36   Ymax                Double      1           Little
                    shpStream.WriteLe(parts.Count);                    // Byte 44   NumParts            Integer     1           Little
                    shpStream.WriteLe(points.Count);                   // Byte 48   NumPoints           Integer     1           Little

                    foreach (int iPart in parts)
                    {
                        shpStream.WriteLe(iPart);                     // Byte 52   Parts               Integer     NumParts    Little
                    }

                    double[] xyVals = new double[points.Count * 2];

                    for (var i = 0; i < points.Count; i++)
                    {
                        xyVals[i * 2]     = points[i].X;
                        xyVals[i * 2 + 1] = points[i].Y;
                    }

                    shpStream.WriteLe(xyVals, 0, 2 * points.Count);

                    if (header.ShapeType == ShapeType.PolyLineZ)
                    {
                        shpStream.WriteLe(geometry.EnvelopeInternal.Minimum.Z);
                        shpStream.WriteLe(geometry.EnvelopeInternal.Maximum.Z);
                        double[] zVals = new double[points.Count];
                        for (int ipoint = 0; ipoint < points.Count; ipoint++)
                        {
                            zVals[ipoint] = points[ipoint].Z;
                        }

                        shpStream.WriteLe(zVals, 0, points.Count);
                    }

                    if (header.ShapeType == ShapeType.PolyLineM || header.ShapeType == ShapeType.PolyLineZ)
                    {
                        if (geometry.Envelope == null)
                        {
                            shpStream.WriteLe(0.0);
                            shpStream.WriteLe(0.0);
                        }
                        else
                        {
                            shpStream.WriteLe(geometry.EnvelopeInternal.Minimum.M);
                            shpStream.WriteLe(geometry.EnvelopeInternal.Maximum.M);
                        }

                        double[] mVals = new double[points.Count];
                        for (int ipoint = 0; ipoint < points.Count; ipoint++)
                        {
                            mVals[ipoint] = points[ipoint].M;
                        }

                        shpStream.WriteLe(mVals, 0, points.Count);
                    }
                }

                if (shxRemainderCount > 0)
                {
                    CopyTo(tmpShxStream, shxStream, 0, shxRemainderCount);
                }
                int dOffset = (int)((shpStream.Position - shpOffset) / 2);
                if (dOffset != 0)
                {
                    long shpPosition = shpStream.Position;
                    for (int i = fid; i < shapeHeaders.Count; i++)
                    {
                        shxStream.Seek(100 + (i + 1) * 8, SeekOrigin.Begin);
                        shxStream.WriteBe(shapeHeaders[i].Offset + dOffset);

                        shpStream.Seek((shapeHeaders[i].Offset + dOffset) * 2, SeekOrigin.Begin);
                        shpStream.WriteBe(i + 2);
                    }
                    shpStream.Seek(shpPosition, SeekOrigin.Begin);
                }

                int shxLength = Convert.ToInt32(shxStream.Length / 2);
                shxStream.Flush();
                tmpShxStream.Dispose();
                shxStream.Dispose();
                File.Delete(tmpShxPath);

                if (shpRemainderCount > 0)
                {
                    CopyTo(tmpShpStream, shpStream, 0, shpRemainderCount);
                }
                if (shpStream.Length != shpStream.Position + shpRemainderCount)
                {
                    shpStream.SetLength(shpStream.Position + shpRemainderCount);
                }
                ;
                int shpLength = Convert.ToInt32(shpStream.Length / 2);
                shpStream.Flush();
                shpStream.Dispose();
                Shapefile.WriteFileLength(Filename, shpLength);
                Shapefile.WriteFileLength(header.ShxFilename, shxLength);
                tmpShpStream.Dispose();
                File.Delete(tmpShpPath);
            }
        }