Exemple #1
0
        private static int GetShapeFileTypeNumber(ShapeFileType shapeFileType)
        {
            switch (shapeFileType)
            {
            case ShapeFileType.Null: return(0);

            case ShapeFileType.Point: return(1);

            case ShapeFileType.Polyline: return(3);

            case ShapeFileType.Polygon: return(5);

            case ShapeFileType.Multipoint: return(8);

            case ShapeFileType.PointZ: return(11);

            case ShapeFileType.PolylineZ: return(13);

            case ShapeFileType.PolygonZ: return(15);

            case ShapeFileType.MultipointZ: return(18);

            case ShapeFileType.PointM: return(21);

            case ShapeFileType.PolylineM: return(23);

            case ShapeFileType.PolygonM: return(25);

            case ShapeFileType.MultipointM: return(28);

            case ShapeFileType.Multipatch: return(31);

            default: return(0);
            }
        }
Exemple #2
0
 public ShapeFileHeader(ShapeFileType shapeFileType)
 {
     fileCode           = 9994;
     version            = fileVersionNumber;
     this.shapeFileType = shapeFileType;
     boundingBox        = new ShapeFileBoundingBox();
 }
        private static ShapeFileType GetShapeFileType(Feature feature)
        {
            ShapeFileType shapeFileType = ShapeFileType.Null;

            if (feature != null)
            {
                switch (feature.GetWellKnownType())
                {
                case WellKnownType.Point:
                    shapeFileType = ShapeFileType.Point;
                    break;

                case WellKnownType.Multipoint:
                    shapeFileType = ShapeFileType.Multipoint;
                    break;

                case WellKnownType.Line:
                case WellKnownType.Multiline:
                    shapeFileType = ShapeFileType.Polyline;
                    break;

                case WellKnownType.Polygon:
                case WellKnownType.Multipolygon:
                    shapeFileType = ShapeFileType.Polygon;
                    break;
                }
            }
            return(shapeFileType);
        }
        private void Initialize(ShapeFileType shapeFileType, string pathFileName, IEnumerable <DbfColumn> columns, string projectionWkt)
        {
            string[] suffixes = { ".shp", ".shx", ".ids", ".idx", ".dbf", ".prj" };
            foreach (var suffix in suffixes)
            {
                string fileToRemove = Path.ChangeExtension(pathFileName, suffix);
                if (File.Exists(fileToRemove))
                {
                    File.Delete(fileToRemove);
                }
            }

            if (!string.IsNullOrEmpty(projectionWkt))
            {
                File.WriteAllText(Path.ChangeExtension(pathFileName, ".prj"), projectionWkt);
            }

            ShapeFileFeatureLayer.CreateShapeFile(shapeFileType, pathFileName, columns);
            featureLayer = new ShapeFileFeatureLayer(pathFileName, GeoFileReadWriteMode.ReadWrite);
        }
        protected override SimpleShapeType GetFeatureSimpleShapeTypeCore(FeatureLayer featureLayer)
        {
            SimpleShapeType       result = SimpleShapeType.Unknown;
            ShapeFileFeatureLayer shapeFileFeatureLayer = featureLayer as ShapeFileFeatureLayer;
            bool isDataSourceAvailable = DataSourceResolveTool.IsDataSourceAvailable(featureLayer);

            if (shapeFileFeatureLayer != null && isDataSourceAvailable)
            {
                ShapeFileType shapeFileType = ShapeFileType.Null;
                shapeFileFeatureLayer.SafeProcess(()
                                                  => shapeFileType = shapeFileFeatureLayer.GetShapeFileType());

                switch (shapeFileType)
                {
                case ShapeFileType.Point:
                case ShapeFileType.PointZ:
                case ShapeFileType.Multipoint:
                case ShapeFileType.PointM:
                case ShapeFileType.MultipointM:
                    result = SimpleShapeType.Point;
                    break;

                case ShapeFileType.Polyline:
                case ShapeFileType.PolylineZ:
                case ShapeFileType.PolylineM:
                case ShapeFileType.Multipatch:
                    result = SimpleShapeType.Line;
                    break;

                case ShapeFileType.Polygon:
                case ShapeFileType.PolygonM:
                case ShapeFileType.PolygonZ:
                    result = SimpleShapeType.Area;
                    break;
                }
            }

            return(result);
        }
        private static void CreateIndexFile(string idxPathFileName, string sourceShapeFilePath)
        {
            ShapeFileFeatureLayer sourceLayer = new ShapeFileFeatureLayer(sourceShapeFilePath);

            sourceLayer.RequireIndex = false;
            ShapeFileType shapeFileType = ShapeFileType.Null;

            sourceLayer.SafeProcess(() =>
            {
                shapeFileType = sourceLayer.GetShapeFileType();
            });
            //sourceLayer.Open();
            //ShapeFileType shapeFileType = sourceLayer.GetShapeFileType();
            //sourceLayer.Close();

            if (shapeFileType == ShapeFileType.Point || shapeFileType == ShapeFileType.PointZ || shapeFileType == ShapeFileType.PointM)
            {
                RtreeSpatialIndex.CreatePointSpatialIndex(idxPathFileName, RtreeSpatialIndexPageSize.EightKilobytes, RtreeSpatialIndexDataFormat.Float);
            }
            else
            {
                RtreeSpatialIndex.CreateRectangleSpatialIndex(idxPathFileName, RtreeSpatialIndexPageSize.EightKilobytes, RtreeSpatialIndexDataFormat.Float);
            }
        }
        private void CreateShapeFile(ObservableCollection <FeatureSourceColumn> includedColumnsList
                                     , string OutputPath, Encoding ShapeFileEncoding, string csvFilePath
                                     , List <Feature> features
                                     , bool isIncludeAllFeatures
                                     , IEnumerable <MatchCondition> matchConditions
                                     , Action <UpdatingTaskProgressEventArgs> updateAction
                                     , Dictionary <string, string> invalidColumns)
        {
            Collection <DbfColumn> includeColumns = new Collection <DbfColumn>();

            RemoveUnduplicateColumn(includedColumnsList);

            foreach (var column in includedColumnsList)
            {
                DbfColumnType tmpDbfColumnType = DbfColumnType.Character;
                if (Enum.TryParse(column.TypeName, out tmpDbfColumnType))
                {
                    DbfColumn dbfColumn = new DbfColumn(column.ColumnName, tmpDbfColumnType, column.MaxLength, 0);
                    includeColumns.Add(dbfColumn);
                }
            }

            ShapeFileType shapeFileType = GetShapeFileType(features.FirstOrDefault());

            if (shapeFileType != ShapeFileType.Null)
            {
                ShapeFileFeatureLayer.CreateShapeFile(shapeFileType,
                                                      OutputPath, includeColumns, ShapeFileEncoding, OverwriteMode.Overwrite);

                var dataTable   = DataJoinAdapter.ReadDataToDataGrid(csvFilePath, Delimiter);
                var featureRows = dataTable.Rows;
                var index       = 0;
                var count       = features.Count;

                ShapeFileFeatureLayer newShapeFileFeatureLayer = new ShapeFileFeatureLayer(OutputPath, GeoFileReadWriteMode.ReadWrite);
                newShapeFileFeatureLayer.SafeProcess(() =>
                {
                    newShapeFileFeatureLayer.EditTools.BeginTransaction();

                    foreach (var feature in features)
                    {
                        index++;
                        try
                        {
                            var matchedDataRow = featureRows.Cast <DataRow>().FirstOrDefault(r => matchConditions.All(tmpCondition => feature.ColumnValues[tmpCondition.SelectedLayerColumn.ColumnName]
                                                                                                                      == r[tmpCondition.SelectedDelimitedColumn.ColumnName].ToString()));

                            if (matchedDataRow != null)
                            {
                                SetFeatureColumnValues(feature, matchedDataRow, includedColumnsList, invalidColumns);
                                newShapeFileFeatureLayer.EditTools.Add(feature);
                            }
                            else if (isIncludeAllFeatures)
                            {
                                newShapeFileFeatureLayer.EditTools.Add(feature);
                            }

                            if (UpdateProgress(updateAction, index, count))
                            {
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            var errorEventArgs   = new UpdatingTaskProgressEventArgs(TaskState.Error);
                            errorEventArgs.Error = new ExceptionInfo(string.Format(CultureInfo.InvariantCulture, "Feature id: {0}, {1}"
                                                                                   , feature.Id, ex.Message)
                                                                     , ex.StackTrace
                                                                     , ex.Source);
                            GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                            errorEventArgs.Message = feature.Id;
                            updateAction(errorEventArgs);
                        }
                    }
                    newShapeFileFeatureLayer.EditTools.CommitTransaction();
                });

                SavePrjFile(OutputPath, DisplayProjectionParameters);
            }
        }
        private void DataJoinShapeFile()
        {
            var args = new UpdatingTaskProgressEventArgs(TaskState.Updating);
            ShapeFileFeatureSource currentSource = ShapeFileFeatureSource;

            if (!currentSource.IsOpen)
            {
                currentSource.Open();
            }
            var index = 0;
            var count = currentSource.GetAllFeatures(ReturningColumnsType.AllColumns).Count;

            Collection <DbfColumn> includeColumns = new Collection <DbfColumn>();

            RemoveUnduplicateColumn(IncludedColumnsList);

            foreach (var column in IncludedColumnsList)
            {
                DbfColumnType tmpDbfColumnType = DbfColumnType.Character;
                if (Enum.TryParse(column.TypeName, out tmpDbfColumnType))
                {
                    DbfColumn dbfColumn = new DbfColumn(column.ColumnName, tmpDbfColumnType, column.MaxLength, 0);
                    includeColumns.Add(dbfColumn);
                }
            }

            ShapeFileType shapeFileType = GetShapeFileType(currentSource.GetAllFeatures(ReturningColumnsType.AllColumns).FirstOrDefault());
            var           projectionWkt = Proj4Projection.ConvertProj4ToPrj(DisplayProjectionParameters);
            var           dataTable     = DataJoinAdapter.ReadDataToDataGrid(CsvFilePath, Delimiter);
            var           featureRows   = dataTable.Rows;

            var helper = new ShapeFileHelper(shapeFileType, OutputPathFileName, includeColumns, projectionWkt);

            helper.ForEachFeatures(currentSource, (f, currentProgress, upperBound, percentage) =>
            {
                try
                {
                    bool canceled = false;
                    if (f.GetWellKnownBinary() != null)
                    {
                        index++;
                        try
                        {
                            var matchedDataRow = featureRows.Cast <DataRow>().FirstOrDefault(r => MatchConditions.All(tmpCondition => f.ColumnValues[tmpCondition.SelectedLayerColumn.ColumnName]
                                                                                                                      == r[tmpCondition.SelectedDelimitedColumn.ColumnName].ToString()));

                            if (matchedDataRow != null)
                            {
                                SetFeatureColumnValues(f, matchedDataRow, IncludedColumnsList, InvalidColumns);
                                helper.Add(f);
                            }
                            else if (IsIncludeAllFeatures)
                            {
                                helper.Add(f);
                            }

                            if (UpdateProgress(OnUpdatingProgress, index, count))
                            {
                                canceled = true;
                            }
                        }
                        catch (Exception ex)
                        {
                            var errorEventArgs   = new UpdatingTaskProgressEventArgs(TaskState.Error);
                            errorEventArgs.Error = new ExceptionInfo(string.Format(CultureInfo.InvariantCulture, "Feature id: {0}, {1}"
                                                                                   , f.Id, ex.Message)
                                                                     , ex.StackTrace
                                                                     , ex.Source);
                            GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                            errorEventArgs.Message = f.Id;
                            OnUpdatingProgress(errorEventArgs);
                        }
                    }

                    args            = new UpdatingTaskProgressEventArgs(TaskState.Updating, percentage);
                    args.Current    = currentProgress;
                    args.UpperBound = upperBound;
                    OnUpdatingProgress(args);

                    canceled = args.TaskState == TaskState.Canceled;
                    return(canceled);
                }
                catch
                {
                    return(false);
                }
            });

            helper.Commit();

            SavePrjFile(OutputPathFileName, DisplayProjectionParameters);
        }
        protected override FeatureLayer CreateFeatureLayerCore(ConfigureFeatureLayerParameters featureLayerStructureParameters)
        {
            string layerPath = LayerPluginHelper.GetLayerUriToSave(featureLayerStructureParameters.LayerUri, ExtensionFilterCore);

            if (string.IsNullOrEmpty(layerPath))
            {
                return(null);
            }
            featureLayerStructureParameters.LayerUri = new Uri(layerPath);

            ShapeFileType shapeFileType = ShapeFileType.Null;

            switch (featureLayerStructureParameters.WellKnownType)
            {
            case WellKnownType.Multipoint:
                shapeFileType = ShapeFileType.Multipoint;
                break;

            case WellKnownType.Point:
                shapeFileType = ShapeFileType.Point;
                break;

            case WellKnownType.Line:
            case WellKnownType.Multiline:
                shapeFileType = ShapeFileType.Polyline;
                break;

            case WellKnownType.Polygon:
            case WellKnownType.Multipolygon:
                shapeFileType = ShapeFileType.Polygon;
                break;
            }

            Dictionary <string, DbfColumn>   dbfColumns    = new Dictionary <string, DbfColumn>();
            Collection <FeatureSourceColumn> addedColumns  = featureLayerStructureParameters.AddedColumns;
            Dictionary <string, string>      oldNewNames   = new Dictionary <string, string>();
            Collection <Feature>             addedFeatures = featureLayerStructureParameters.AddedFeatures;

            bool truncateLongColumn = featureLayerStructureParameters.LongColumnTruncateMode == LongColumnTruncateMode.Truncate;

            if (truncateLongColumn)
            {
                Dictionary <string, string> editColumns = new Dictionary <string, string>();
                if (featureLayerStructureParameters.CustomData.ContainsKey("EditedColumns"))
                {
                    editColumns = featureLayerStructureParameters.CustomData["EditedColumns"] as Dictionary <string, string>;
                }
                addedColumns = TruncateLongColumnNames(featureLayerStructureParameters.AddedColumns, oldNewNames, editColumns);
            }

            foreach (var column in addedColumns)
            {
                if (!string.IsNullOrEmpty(column.ColumnName))
                {
                    DbfColumn dbfColumn = column as DbfColumn;
                    if (dbfColumn != null)
                    {
                        if (dbfColumn.ColumnType == DbfColumnType.DoubleInBinary || dbfColumn.ColumnType == DbfColumnType.DateTime)
                        {
                            dbfColumn.Length        = 8;
                            dbfColumn.DecimalLength = 0;
                        }
                        else if (dbfColumn.ColumnType == DbfColumnType.IntegerInBinary)
                        {
                            dbfColumn.Length        = 4;
                            dbfColumn.DecimalLength = 0;
                        }
                    }
                    else
                    {
                        int columnLenght  = column.MaxLength;
                        int decimalLength = 0;

                        switch (column.TypeName.ToUpperInvariant())
                        {
                        case "DOUBLE":
                        case "NUMERIC":
                            columnLenght = columnLenght == 0 ? 10 : columnLenght;
                            if (columnLenght < 4)
                            {
                                columnLenght = 10;
                            }
                            decimalLength = 4;
                            break;

                        case "DATE":
                        case "DATETIME":
                            columnLenght  = columnLenght == 0 ? 10 : columnLenght;
                            decimalLength = 0;
                            break;

                        case "INTEGER":
                        case "INT":
                            columnLenght  = columnLenght == 0 ? 10 : columnLenght;
                            decimalLength = 0;
                            break;

                        case "STRING":
                        case "CHARACTER":
                            columnLenght  = columnLenght == 0 ? characterTypeLength : columnLenght;
                            decimalLength = 0;
                            break;

                        case "LOGICAL":
                            columnLenght  = 5;
                            decimalLength = 0;
                            break;
                        }

                        DbfColumnType type = DbfColumnType.Character;
                        if (column.TypeName.Equals("DOUBLE", StringComparison.InvariantCultureIgnoreCase))
                        {
                            column.TypeName = DbfColumnType.Float.ToString();
                        }
                        if (column.TypeName.Equals("INT", StringComparison.InvariantCultureIgnoreCase))
                        {
                            column.TypeName = DbfColumnType.Numeric.ToString();
                        }
                        bool isSuccess = Enum.TryParse <DbfColumnType>(column.TypeName, true, out type);
                        if (!isSuccess)
                        {
                            type = DbfColumnType.Character;
                        }

                        dbfColumn           = new DbfColumn(column.ColumnName, type, columnLenght, decimalLength);
                        dbfColumn.TypeName  = column.TypeName;
                        dbfColumn.MaxLength = column.MaxLength;
                    }
                    //Feature firstFeature = featureLayerStructureParameters.AddedFeatures.FirstOrDefault();

                    ////This is to fix that fox pro columns cannot write to dbf, convert all linked columns to character column type.
                    //string tempColumnName = column.ColumnName;
                    //if (oldNewNames.ContainsValue(column.ColumnName))
                    //{
                    //    tempColumnName = oldNewNames.FirstOrDefault(f => f.Value == column.ColumnName).Key;
                    //}
                    //if (tempColumnName.Contains(".") && firstFeature != null && firstFeature.LinkColumnValues.ContainsKey(tempColumnName))
                    //{
                    //    if (dbfColumn.ColumnType != DbfColumnType.Memo)
                    //    {
                    //        dbfColumn.ColumnType = DbfColumnType.Character;
                    //        dbfColumn.Length = characterTypeLength;
                    //        dbfColumn.DecimalLength = 0;
                    //    }
                    //}

                    dbfColumns[dbfColumn.ColumnName] = dbfColumn;
                }
            }

            bool convertMemoToCharacter = featureLayerStructureParameters.MemoColumnConvertMode == MemoColumnConvertMode.ToCharacter;

            Dictionary <string, int> columnLength = new Dictionary <string, int>();

            foreach (var feature in addedFeatures)
            {
                //foreach (var linkColumnValue in feature.LinkColumnValues)
                //{
                //    if (!feature.ColumnValues.ContainsKey(linkColumnValue.Key))
                //    {
                //        string[] values = linkColumnValue.Value.Select(v =>
                //        {
                //            if (v.Value == null)
                //            {
                //                return string.Empty;
                //            }
                //            if (v.Value is DateTime)
                //            {
                //                return ((DateTime)v.Value).ToShortDateString();
                //            }
                //            return v.Value.ToString();
                //        }).ToArray();
                //        if (values.All(v => string.IsNullOrEmpty(v) || string.IsNullOrWhiteSpace(v)))
                //        {
                //            if (oldNewNames.ContainsKey(linkColumnValue.Key))
                //                feature.ColumnValues[oldNewNames[linkColumnValue.Key]] = string.Empty;
                //            else
                //                feature.ColumnValues[linkColumnValue.Key] = string.Empty;
                //        }
                //        else
                //        {
                //            string tempColumName = linkColumnValue.Key;
                //            if (oldNewNames.ContainsKey(linkColumnValue.Key))
                //            {
                //                tempColumName = oldNewNames[linkColumnValue.Key];
                //            }
                //            string linkValue = string.Join(",", values);
                //            feature.ColumnValues[tempColumName] = linkValue;

                //            //Choose the max length
                //            if (columnLength.ContainsKey(tempColumName))
                //            {
                //                if (columnLength[tempColumName] < linkValue.Length)
                //                {
                //                    columnLength[tempColumName] = linkValue.Length;
                //                }
                //            }
                //            else
                //            {
                //                columnLength[tempColumName] = linkValue.Length > 254 ? 254 : linkValue.Length;
                //            }
                //        }
                //    }
                //}
                foreach (var item in oldNewNames)
                {
                    if (feature.ColumnValues.ContainsKey(item.Key))
                    {
                        feature.ColumnValues[oldNewNames[item.Key]] = feature.ColumnValues[item.Key];
                        feature.ColumnValues.Remove(item.Key);
                    }
                }
                if (!convertMemoToCharacter)
                {
                    foreach (var item in feature.ColumnValues)
                    {
                        if (item.Value.Length > characterTypeLength && dbfColumns[item.Key].ColumnType != DbfColumnType.Memo)
                        {
                            dbfColumns[item.Key].ColumnType    = DbfColumnType.Memo;
                            dbfColumns[item.Key].Length        = 4;
                            dbfColumns[item.Key].DecimalLength = 0;
                        }
                    }
                }
            }

            foreach (var column in dbfColumns)
            {
                Feature firstFeature = featureLayerStructureParameters.AddedFeatures.FirstOrDefault();
                //This is to fix that fox pro columns cannot write to dbf, convert all linked columns to character column type.
                string tempColumnName = column.Key;
                if (oldNewNames.ContainsValue(column.Key))
                {
                    tempColumnName = oldNewNames.FirstOrDefault(f => f.Value == column.Key).Key;
                }
                //if (tempColumnName.Contains(".") && firstFeature != null && firstFeature.LinkColumnValues.ContainsKey(tempColumnName))
                //{
                //    if (column.Value.ColumnType != DbfColumnType.Memo)
                //    {
                //        column.Value.ColumnType = DbfColumnType.Character;
                //        //column.Value.Length = characterTypeLength;
                //        column.Value.DecimalLength = 0;

                //        if (columnLength.ContainsKey(tempColumnName) && column.Value.Length < columnLength[tempColumnName])
                //        {
                //            column.Value.Length = columnLength[tempColumnName];
                //        }
                //    }
                //}
            }

            ShapeFileFeatureLayer.CreateShapeFile(shapeFileType,
                                                  featureLayerStructureParameters.LayerUri.OriginalString,
                                                  dbfColumns.Values,
                                                  DefaultEncoding,
                                                  OverwriteMode.Overwrite);

            string encodingPathFileName = Path.ChangeExtension(featureLayerStructureParameters.LayerUri.OriginalString, ".cpg");

            if (File.Exists(encodingPathFileName))
            {
                File.Delete(encodingPathFileName);
            }
            File.WriteAllText(encodingPathFileName, DefaultEncoding.CodePage.ToString(CultureInfo.InvariantCulture));

            string prjPath = Path.ChangeExtension(featureLayerStructureParameters.LayerUri.OriginalString, "prj");

            File.WriteAllText(prjPath, Proj4Projection.ConvertProj4ToPrj(featureLayerStructureParameters.Proj4ProjectionParametersString));

            ShapeFileFeatureLayer resultLayer = new ShapeFileFeatureLayer(featureLayerStructureParameters.LayerUri.LocalPath, GeoFileReadWriteMode.ReadWrite);

            if (addedFeatures.Count > 0)
            {
                resultLayer.Open();
                resultLayer.EditTools.BeginTransaction();
                foreach (var feature in addedFeatures)
                {
                    if (convertMemoToCharacter)
                    {
                        foreach (var item in dbfColumns)
                        {
                            if (feature.ColumnValues.ContainsKey(item.Key) && feature.ColumnValues[item.Key].Length > 254)
                            {
                                feature.ColumnValues[item.Key] = feature.ColumnValues[item.Key].Substring(0, 254);
                            }
                            if (feature.ColumnValues.ContainsKey(item.Key) && feature.ColumnValues[item.Key].Length > item.Value.MaxLength)
                            {
                                feature.ColumnValues[item.Key] = feature.ColumnValues[item.Key].Substring(0, item.Value.MaxLength);
                            }
                        }
                    }

                    resultLayer.EditTools.Add(feature);
                }
                resultLayer.EditTools.CommitTransaction();
                resultLayer.Close();
            }

            return(resultLayer);
        }
 public ShapeFileHelper(ShapeFileType shapeFileType, string pathFileName, IEnumerable <DbfColumn> columns, string projectionWkt)
 {
     Initialize(shapeFileType, pathFileName, columns, projectionWkt);
 }
 public ShapeFileHelper(ShapeFileType shapeFileType, string pathFileName, IEnumerable <FeatureSourceColumn> columns, string projectionWkt)
 {
     Initialize(shapeFileType, pathFileName, ConvertToDbfColumns(columns), projectionWkt);
 }
Exemple #12
0
    private void readShapeFile()
    {
        FileStream fs         = new FileStream(m_sFilename, FileMode.Open);
        long       fileLength = fs.Length;

        Byte[] data = new Byte[fileLength];
        fs.Read(data, 0, (int)fileLength);
        fs.Close();
        m_iFilecode   = readIntBig(data, 0);
        m_iFileLength = readIntBig(data, 24);
        m_iVersion    = readIntLittle(data, 28);
        m_eShapeType  = (ShapeFileType)readIntLittle(data, 32);
        m_dxMin       = readDoubleLittle(data, 36);
        m_dyMin       = readDoubleLittle(data, 44);
        m_dyMin       = 0 - m_dyMin;
        m_dxMax       = readDoubleLittle(data, 52);
        m_dyMax       = readDoubleLittle(data, 60);
        m_dyMax       = 0 - m_dyMax;
        m_dzMin       = readDoubleLittle(data, 68);
        m_dzMax       = readDoubleLittle(data, 76);
        m_dmMin       = readDoubleLittle(data, 84);
        m_dmMax       = readDoubleLittle(data, 92);
        int currentPosition = 100;

        while (currentPosition < m_iFileLength)
        {
            int recordStart        = currentPosition;
            int recordNumber       = readIntBig(data, recordStart);
            int contentLength      = readIntBig(data, recordStart + 4);
            int recordContentStart = recordStart + 8;
            if (m_eShapeType == ShapeFileType.SHAPE_TYPE_POINTS)
            {
                PointF point           = new PointF();
                int    recordShapeType = readIntLittle(data, recordContentStart);
                point.X = (float)readDoubleLittle(data, recordContentStart + 4);
                point.Y = 0 - (float)readDoubleLittle(data, recordContentStart + 12);
                m_aPoints.Add(point);
            }
            if (m_eShapeType == ShapeFileType.SHAPE_TYPE_LINES)
            {
                Line line            = new Line();
                int  recordShapeType = readIntLittle(data, recordContentStart);
                line.box       = new Double[4];
                line.box[0]    = readDoubleLittle(data, recordContentStart + 4);
                line.box[1]    = readDoubleLittle(data, recordContentStart + 12);
                line.box[2]    = readDoubleLittle(data, recordContentStart + 20);
                line.box[3]    = readDoubleLittle(data, recordContentStart + 28);
                line.numParts  = readIntLittle(data, recordContentStart + 36);
                line.parts     = new int[line.numParts];
                line.numPoints = readIntLittle(data, recordContentStart + 40);
                line.points    = new PointF[line.numPoints];
                int partStart = recordContentStart + 44;
                for (int i = 0; i < line.numParts; i++)
                {
                    line.parts[i] = readIntLittle(data, partStart + i * 4);
                }
                int pointStart = recordContentStart + 44 + 4 * line.numParts;
                for (int i = 0; i < line.numPoints; i++)
                {
                    line.points[i].X = (float)readDoubleLittle(data, pointStart + (i * 16));
                    line.points[i].Y = (float)readDoubleLittle(data, pointStart + (i * 16) + 8);
                    line.points[i].Y = 0 - line.points[i].Y;
                }
                m_aLines.Add(line);
            }
            if (m_eShapeType == ShapeFileType.SHAPE_TYPE_POLYGONS)
            {
                Polygon polygon         = new Polygon();
                int     recordShapeType = readIntLittle(data, recordContentStart);
                polygon.box       = new Double[4];
                polygon.box[0]    = readDoubleLittle(data, recordContentStart + 4);
                polygon.box[1]    = readDoubleLittle(data, recordContentStart + 12);
                polygon.box[2]    = readDoubleLittle(data, recordContentStart + 20);
                polygon.box[3]    = readDoubleLittle(data, recordContentStart + 28);
                polygon.numParts  = readIntLittle(data, recordContentStart + 36);
                polygon.parts     = new int[polygon.numParts];
                polygon.numPoints = readIntLittle(data, recordContentStart + 40);
                polygon.points    = new PointF[polygon.numPoints];
                int partStart = recordContentStart + 44;
                for (int i = 0; i < polygon.numParts; i++)
                {
                    polygon.parts[i] = readIntLittle(data, partStart + i * 4);
                }
                int pointStart = recordContentStart + 44 + 4 * polygon.numParts;
                for (int i = 0; i < polygon.numPoints; i++)
                {
                    polygon.points[i].X = (float)readDoubleLittle(data, pointStart + (i * 16));
                    polygon.points[i].Y = (float)readDoubleLittle(data, pointStart + (i * 16) + 8);
                    //polygon.points[i].Y = 0 - polygon.points[i].Y;
                }
                m_aPolygons.Add(polygon);
            }
            currentPosition = recordStart + (4 + contentLength) * 2;
        }
    }
        private IEnumerable <Feature> StandardClipPoints(IEnumerable <Feature> masterFeatures, IEnumerable <Feature> clippingFeatures, ShapeFileType shpFileType)
        {
            ConcurrentQueue <Feature> results = new ConcurrentQueue <Feature>();
            int index = 1;
            int count = masterFeatures.Count();
            ConcurrentQueue <Feature> cqMasterFeatures = new ConcurrentQueue <Feature>(masterFeatures);

            if (shpFileType == ShapeFileType.Point)
            {
                Parallel.ForEach(cqMasterFeatures, feature =>
                {
                    index++;
                    ReportProgress(index * 100 / count);
                    if (clippingFeatures.Any(f =>
                    {
                        try { return(f.GetShape().Intersects(feature)); }
                        catch (Exception ex)
                        {
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                            return(false);
                        }
                    }))
                    {
                        results.Enqueue(feature);
                    }
                });
            }
            else
            {
                Parallel.ForEach(cqMasterFeatures, feature =>
                {
                    ReportProgress(index * 100 / count);
                    index++;
                    MultipointShape multiPoints = feature.GetShape() as MultipointShape;
                    if (multiPoints != null)
                    {
                        MultipointShape resultPoints = new MultipointShape();
                        Parallel.ForEach(multiPoints.Points, p =>
                        {
                            if (clippingFeatures.Any(f =>
                            {
                                try { return(f.GetShape().Intersects(p)); }
                                catch (Exception ex)
                                {
                                    HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                                    return(false);
                                }
                            }))
                            {
                                resultPoints.Points.Add(p);
                            }
                        });
                        if (resultPoints.Points.Count > 0)
                        {
                            results.Enqueue(new Feature(resultPoints.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                        }
                    }
                });
            }
            return(results);
        }
        private IEnumerable <Feature> StandardClip(FeatureSource featureSource, IEnumerable <Feature> features)
        {
            lock (featureSource)
            {
                Collection <Feature> results = new Collection <Feature>();

                //There is a bug about projection boundingbox, here is a workaround for it.
                bool       isOpen        = false;
                Projection tmpProjection = null;
                if (featureSource.Projection != null &&
                    featureSource.Projection is GISEditorManagedProj4Projection &&
                    ((GISEditorManagedProj4Projection)featureSource.Projection).IsProjectionParametersEqual)
                {
                    tmpProjection = featureSource.Projection;
                    if (featureSource.IsOpen)
                    {
                        featureSource.Close();
                        featureSource.Projection.Close();
                        isOpen = true;
                    }
                    featureSource.Projection = null;
                }

                if (!featureSource.IsOpen)
                {
                    featureSource.Open();
                }
                Collection <Feature> sourceFeatures = featureSource.GetFeaturesInsideBoundingBox(ExtentHelper.GetBoundingBoxOfItems(features), ReturningColumnsType.AllColumns);

                if (tmpProjection != null)
                {
                    featureSource.Projection = tmpProjection;
                    if (isOpen)
                    {
                        featureSource.Open();
                    }
                }

                ShapeFileType shapeFileType = ((ShapeFileFeatureSource)featureSource).GetShapeFileType();
                if (featureSource.IsOpen)
                {
                    featureSource.Close();
                }

                int index = 1;
                int count = sourceFeatures.Count;
                if (shapeFileType == ShapeFileType.Point || shapeFileType == ShapeFileType.Multipoint)
                {
                    return(StandardClipPoints(sourceFeatures, features, shapeFileType));
                }
                else if (shapeFileType == ShapeFileType.Polyline)
                {
                    MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(features));
                    foreach (var feature in sourceFeatures)
                    {
                        ReportProgress(index * 100 / count);
                        index++;
                        try
                        {
                            if (areaBaseShape.Contains(feature))
                            {
                                results.Add(feature);
                            }
                            else
                            {
                                var clippedShape = ((LineBaseShape)feature.GetShape()).GetIntersection(areaBaseShape);
                                if (clippedShape != null && clippedShape.Lines.Count > 0)
                                {
                                    results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                        }
                    }
                }
                else if (shapeFileType == ShapeFileType.Polygon)
                {
                    MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(features));
                    foreach (var feature in sourceFeatures)
                    {
                        ReportProgress(index * 100 / count);
                        try
                        {
                            index++;
                            if (areaBaseShape.Contains(feature))
                            {
                                results.Add(feature);
                            }
                            else
                            {
                                var clippedShape = areaBaseShape.GetIntersection(feature);
                                if (clippedShape != null && clippedShape.Polygons.Count > 0)
                                {
                                    results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                        }
                    }
                }
                else
                {
                    throw new NotSupportedException("The ShapeFileType is not supported.");
                }
                return(results);
            }
        }
        private IEnumerable <Feature> InverseClip(FeatureSource featureSource, IEnumerable <Feature> clippingFeatures)
        {
            lock (featureSource)
            {
                if (!featureSource.IsOpen)
                {
                    featureSource.Open();
                }
                Collection <Feature> results        = featureSource.GetFeaturesOutsideBoundingBox(ExtentHelper.GetBoundingBoxOfItems(clippingFeatures), ReturningColumnsType.AllColumns);
                Collection <Feature> sourceFeatures = new Collection <Feature>();
                ShapeFileType        shapeFileType  = ((ShapeFileFeatureSource)featureSource).GetShapeFileType();
                int index = 1;
                if (shapeFileType == ShapeFileType.Point || shapeFileType == ShapeFileType.Multipoint)
                {
                    featureSource.Open();
                    Collection <Feature> allFeatures = featureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
                    featureSource.Close();
                    foreach (Feature f in results)
                    {
                        allFeatures.Remove(f);
                    }
                    foreach (var f in InverseClipPoints(allFeatures, clippingFeatures, shapeFileType))
                    {
                        results.Add(f);
                    }
                }
                else if (shapeFileType == ShapeFileType.Polyline)
                {
                    bool              isOpen        = false;
                    Projection        tmpProjection = null;
                    MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(clippingFeatures));
                    if (featureSource.Projection != null &&
                        featureSource.Projection is GISEditorManagedProj4Projection &&
                        ((GISEditorManagedProj4Projection)featureSource.Projection).IsProjectionParametersEqual)
                    {
                        tmpProjection = featureSource.Projection;
                        if (featureSource.IsOpen)
                        {
                            featureSource.Close();
                            featureSource.Projection.Close();
                            isOpen = true;
                        }
                        featureSource.Projection = null;
                    }
                    featureSource.Open();
                    featureSource.GetFeaturesInsideBoundingBox(areaBaseShape.GetBoundingBox(), ReturningColumnsType.AllColumns).ForEach(f => { if (!areaBaseShape.Contains(f))
                                                                                                                                               {
                                                                                                                                                   sourceFeatures.Add(f);
                                                                                                                                               }
                                                                                                                                        });
                    int count = sourceFeatures.Count;
                    if (tmpProjection != null)
                    {
                        featureSource.Projection = tmpProjection;
                        if (isOpen)
                        {
                            featureSource.Open();
                        }
                    }
                    if (featureSource.IsOpen)
                    {
                        featureSource.Close();
                    }
                    foreach (var feature in sourceFeatures)
                    {
                        ReportProgress(index * 100 / count);
                        index++;
                        try
                        {
                            if (areaBaseShape.IsDisjointed(feature))
                            {
                                results.Add(feature);
                            }
                            else
                            {
                                MultilineShape multiLine   = (MultilineShape)feature.GetShape();
                                MultilineShape resultShape = new MultilineShape();
                                foreach (LineShape lineShape in multiLine.Lines)
                                {
                                    if (areaBaseShape.IsDisjointed(lineShape))
                                    {
                                        resultShape.Lines.Add(lineShape);
                                    }
                                    else
                                    {
                                        Collection <PointShape> points = new Collection <PointShape>();
                                        points.Add(new PointShape(lineShape.Vertices[0]));
                                        lineShape.GetIntersection(areaBaseShape).Lines.ForEach(l =>
                                        {
                                            PointShape p1 = new PointShape(l.Vertices[0]);
                                            if (points.Count(p => p.X == p1.X && p.Y == p1.Y && p.Z == p1.Z) <= 0)
                                            {
                                                points.Add(p1);
                                            }
                                            PointShape p2 = new PointShape(l.Vertices[l.Vertices.Count - 1]);
                                            if (points.Count(p => p.X == p2.X && p.Y == p2.Y && p.Z == p2.Z) <= 0)
                                            {
                                                points.Add(p2);
                                            }
                                        });
                                        PointShape endPoint = new PointShape(lineShape.Vertices[lineShape.Vertices.Count - 1]);
                                        if (points.Count(p => p.X == endPoint.X && p.Y == endPoint.Y && p.Z == endPoint.Z) <= 0)
                                        {
                                            points.Add(endPoint);
                                        }

                                        for (int i = 0; i < points.Count; i++)
                                        {
                                            if (i != points.Count - 1)
                                            {
                                                LineBaseShape lineBaseShape = lineShape.GetLineOnALine(points[i], points[i + 1]);

                                                if (!areaBaseShape.Intersects(lineBaseShape.GetCenterPoint()))
                                                {
                                                    resultShape.Lines.Add((LineShape)lineBaseShape);
                                                }
                                            }
                                        }
                                    }
                                }
                                if (resultShape != null && resultShape.Lines.Count > 0)
                                {
                                    results.Add(new Feature(resultShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                        }
                    }
                }
                else if (shapeFileType == ShapeFileType.Polygon)
                {
                    MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(clippingFeatures));

                    bool       isOpen        = false;
                    Projection tmpProjection = null;
                    if (featureSource.Projection != null &&
                        featureSource.Projection is GISEditorManagedProj4Projection &&
                        ((GISEditorManagedProj4Projection)featureSource.Projection).IsProjectionParametersEqual)
                    {
                        tmpProjection = featureSource.Projection;
                        if (featureSource.IsOpen)
                        {
                            featureSource.Close();
                            featureSource.Projection.Close();
                            isOpen = true;
                        }
                        featureSource.Projection = null;
                    }
                    if (!featureSource.IsOpen)
                    {
                        featureSource.Open();
                    }
                    featureSource.GetFeaturesInsideBoundingBox(areaBaseShape.GetBoundingBox(), ReturningColumnsType.AllColumns).ForEach(f => { if (!areaBaseShape.IsDisjointed(f))
                                                                                                                                               {
                                                                                                                                                   sourceFeatures.Add(f);
                                                                                                                                               }
                                                                                                                                        });
                    if (featureSource.IsOpen)
                    {
                        featureSource.Close();
                    }
                    if (tmpProjection != null)
                    {
                        featureSource.Projection = tmpProjection;
                        if (isOpen)
                        {
                            featureSource.Open();
                        }
                    }

                    int count = sourceFeatures.Count;
                    foreach (var feature in sourceFeatures)
                    {
                        ReportProgress(index * 100 / count);
                        index++;
                        try
                        {
                            if (areaBaseShape.IsDisjointed(feature))
                            {
                                results.Add(feature);
                            }
                            else
                            {
                                var clippedShape = ((AreaBaseShape)feature.GetShape()).GetDifference(areaBaseShape);
                                if (clippedShape != null && clippedShape.Polygons.Count > 0)
                                {
                                    results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                        }
                    }
                }
                else
                {
                    throw new NotSupportedException("The ShapeFileType is not supported.");
                }
                return(results);
            }
        }