public static Collection <Feature> GetFeaturesIntersecting(this QueryTools queryTools, BaseShape targetShape, IEnumerable <string> returningColumnNames, bool useSqlType)
        {
            Collection <Feature> returnFeatures = null;

            if (useSqlType)
            {
                returnFeatures = new Collection <Feature>();
                RectangleShape       boundingBox         = targetShape.GetBoundingBox();
                Collection <Feature> allPossibleFeatures = queryTools.GetFeaturesInsideBoundingBox(boundingBox, returningColumnNames);
                foreach (Feature feature in allPossibleFeatures)
                {
                    BaseShape sourceShape = feature.GetShape();
                    sourceShape = SqlTypesGeometryHelper.MakeValid(sourceShape);
                    targetShape = SqlTypesGeometryHelper.MakeValid(targetShape);
                    bool intersects = SqlTypesGeometryHelper.Intersects(sourceShape, targetShape);
                    if (intersects)
                    {
                        returnFeatures.Add(feature);
                    }
                }
            }
            else
            {
                returnFeatures = queryTools.GetFeaturesIntersecting(targetShape, returningColumnNames);
            }
            return(returnFeatures);
        }
Beispiel #2
0
        private IEnumerable <Feature> ShatterTwoFeatures(ref Feature feature1, Feature feature2)
        {
            Collection <Feature> resultFeatures = new Collection <Feature>();
            var columns = GetColumnValues(feature1, feature2);

            // var diff1 = feature1.GetDifference(feature2);
            feature1 = SqlTypesGeometryHelper.MakeValid(feature1);
            feature2 = SqlTypesGeometryHelper.MakeValid(feature2);
            var diff1 = SqlTypesGeometryHelper.GetDifference(feature1, feature2);
            //var diff2 = feature2.GetDifference(feature1);
            var diff2 = SqlTypesGeometryHelper.GetDifference(feature2, feature1);
            //var inter = feature1.GetIntersection(feature2);
            var inter = SqlTypesGeometryHelper.GetIntersection(feature1, feature2);

            feature1 = diff1;
            if (inter != null)
            {
                inter = new Feature(inter.GetWellKnownBinary(), inter.Id, columns);
                AddValidFeature(resultFeatures, inter);
            }

            if (diff2 != null)
            {
                AddValidFeature(resultFeatures, diff2);
            }

            return(resultFeatures);
        }
Beispiel #3
0
        public IEnumerable <Feature> IntersectFeatures(IEnumerable <Feature> features)
        {
            List <Feature> featuresList = features.ToList();

            var results       = new ConcurrentStack <Feature>();
            var featureGroups = featuresList.GroupBy(feature => feature.Tag).ToList();
            int index         = 1;

            for (int i = 0; i < featureGroups.Count; i++)
            {
                var group = featureGroups[i];
                foreach (var feature in group)
                {
                    int progress = index * 100 / featuresList.Count;
                    isCanceled = ReportProgress(progress, index, featuresList.Count);
                    if (isCanceled)
                    {
                        break;
                    }

                    var otherFeatures = featureGroups.Where(g => featureGroups.IndexOf(g) > i).SelectMany(f => f);
                    Parallel.ForEach(otherFeatures, otherFeature =>
                    {
                        try
                        {
                            AreaBaseShape originalShape = (AreaBaseShape)feature.GetShape();
                            AreaBaseShape matchShape    = (AreaBaseShape)otherFeature.GetShape();

                            //if (originalShape.Intersects(matchShape))
                            if (SqlTypesGeometryHelper.Intersects(originalShape, matchShape))
                            {
                                //AreaBaseShape resultShape = originalShape.GetIntersection(matchShape);
                                AreaBaseShape resultShape = (AreaBaseShape)SqlTypesGeometryHelper.GetIntersection(originalShape, matchShape);
                                if (resultShape != null)
                                {
                                    var columnValues      = GetColumnValues(feature, otherFeature);
                                    Feature resultFeature = new Feature(resultShape, columnValues);
                                    results.Push(resultFeature);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                        }
                    });

                    index++;
                }
            }

            return(results);
        }
 private Feature UnionTrackedShapes()
 {
     try
     {
         Feature[] allPolygonFeatures = map.TrackOverlay.TrackShapeLayer.InternalFeatures.Where(f => f.GetShape() is PolygonShape).ToArray();
         return(SqlTypesGeometryHelper.Union(allPolygonFeatures));
     }
     catch
     {
         return(null);
     }
 }
        private MultipolygonShape BufferShape(BaseShape shape)
        {
            MultipolygonShape bufferedShape = null;

            if (capstyle == BufferCapType.Round)
            {
                bufferedShape = SqlTypesGeometryHelper.Buffer(shape, Distance, Smoothness, Capstyle, MapUnit, DistanceUnit);
            }
            else
            {
                bufferedShape = shape.Buffer(distance, smoothness, capstyle, mapUnit, distanceUnit);
            }
            return(bufferedShape);
        }
Beispiel #6
0
        private List <Feature> ShatterFeatures(List <Feature> features, Feature featureToBeShattered)
        {
            List <Feature> resultFeatures = new List <Feature>();

            if (featureToBeShattered != null && featureToBeShattered.CanMakeValid)
            {
                featureToBeShattered = featureToBeShattered.MakeValid();
            }

            for (int i = 0; i < features.Count; i++)
            {
                Feature tmpFeature = features[i];
                tmpFeature = GetValidPolygonFeature(tmpFeature);
                if (tmpFeature == null)
                {
                    continue;
                }

                if (tmpFeature.CanMakeValid)
                {
                    tmpFeature = tmpFeature.MakeValid();
                }
                if (featureToBeShattered != null)
                {
                    //if (featureToBeShattered.IsDisjointed(tmpFeature))
                    if (SqlTypesGeometryHelper.IsDisjointed(featureToBeShattered, tmpFeature))
                    {
                        resultFeatures.Add(tmpFeature);
                    }
                    else
                    {
                        foreach (var shatteredFeature in ShatterTwoFeatures(ref featureToBeShattered, tmpFeature).ToArray())
                        {
                            resultFeatures.Add(shatteredFeature);
                        }
                    }
                }
                else
                {
                    resultFeatures.Add(tmpFeature);
                }
            }

            if (featureToBeShattered != null)
            {
                AddValidFeature(resultFeatures, featureToBeShattered);
            }

            return(resultFeatures);
        }
 private void TrackOverlay_TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e)
 {
     try
     {
         PolygonShape[] allPolygonFeatures = mapControl.TrackOverlay.TrackShapeLayer.InternalFeatures.Select(f => f.GetShape()).OfType <PolygonShape>().ToArray();
         BaseShape      trackedShape       = SqlTypesGeometryHelper.Union(allPolygonFeatures);
         if (trackedShape != null)
         {
             OnQueryAreaChanged(trackedShape);
         }
     }
     catch (Exception ex)
     {
         Debug.WriteLine(ex.Message);
     }
 }
        public static Collection <AreaBaseShape> GetSplitResult(this AreaBaseShape polygon, Collection <LineShape> lines)
        {
            SqlGeometry polygonGeom = SqlGeometry.STGeomFromWKB(new SqlBytes(polygon.GetWellKnownBinary()), 0);

            if (!polygonGeom.STIsValid())
            {
                polygonGeom = polygonGeom.MakeValid();
            }
            //GeometryLibrary library = BaseShape.GeometryLibrary;
            //BaseShape.GeometryLibrary = GeometryLibrary.Unmanaged;
            foreach (var item in lines)
            {
                //MultipolygonShape multipolygon = item.Buffer(0.2, 8, BufferCapType.Square, GeographyUnit.DecimalDegree, DistanceUnit.Meter);
                MultipolygonShape multipolygon     = SqlTypesGeometryHelper.Buffer(item, 0.2, 8, BufferCapType.Square, GeographyUnit.DecimalDegree, DistanceUnit.Meter);
                SqlGeometry       multipolygonGeom = SqlGeometry.STGeomFromWKB(new SqlBytes(multipolygon.GetWellKnownBinary()), 0);
                if (!multipolygonGeom.STIsValid())
                {
                    multipolygonGeom = multipolygonGeom.MakeValid();
                }

                polygonGeom = polygonGeom.STDifference(multipolygonGeom);
            }

            //BaseShape.GeometryLibrary = library;

            byte[]    bytes = polygonGeom.STAsBinary().Value;
            BaseShape shape = BaseShape.CreateShapeFromWellKnownData(bytes) as AreaBaseShape;

            MultipolygonShape splittedMultipolygonShape = shape as MultipolygonShape;
            PolygonShape      splittedPolygonShape      = shape as PolygonShape;

            if (splittedMultipolygonShape == null && splittedPolygonShape != null)
            {
                splittedMultipolygonShape = new MultipolygonShape();
                splittedMultipolygonShape.Polygons.Add(splittedPolygonShape);
                shape = splittedMultipolygonShape;
            }

            Collection <AreaBaseShape> shapes = new Collection <AreaBaseShape>();

            if (splittedMultipolygonShape != null)
            {
                CloseSplittedPolygons(polygon, splittedMultipolygonShape, lines[0], GeographyUnit.DecimalDegree, DistanceUnit.Meter, .3);
                FillShapes(shapes, shape);
            }
            return(shapes);
        }
Beispiel #9
0
        private int StandardClipLines(IEnumerable <Feature> features, Collection <Feature> results, Collection <Feature> sourceFeatures, int index, int count)
        {
            //MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(features));
            List <AreaBaseShape> clippingAreaShapes = GetValidFeatures(features).Select(f => f.GetShape()).OfType <AreaBaseShape>().ToList();
            MultipolygonShape    areaBaseShape      = (MultipolygonShape)SqlTypesGeometryHelper.Union(clippingAreaShapes);

            ConcurrentQueue <Feature> concurrentResult = new ConcurrentQueue <Feature>();

            Parallel.ForEach(sourceFeatures, feature =>
            {
                try
                {
                    //if (areaBaseShape.Contains(feature))
                    if (SqlTypesGeometryHelper.Contains(areaBaseShape, feature))
                    {
                        concurrentResult.Enqueue(feature);
                    }
                    else
                    {
                        //var clippedShape = ((LineBaseShape)feature.GetShape()).GetIntersection(areaBaseShape);
                        var clippedShape = SqlTypesGeometryHelper.GetIntersection(feature.GetShape(), areaBaseShape) as MultilineShape;
                        if (clippedShape != null && clippedShape.Lines.Count > 0)
                        {
                            concurrentResult.Enqueue(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                        }
                    }
                }
                catch (Exception ex)
                {
                    GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                    HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                }
                finally
                {
                    isCanceled = ReportProgress(index++, count);
                }
            });

            foreach (var feature in concurrentResult)
            {
                results.Add(feature);
            }
            return(index);
        }
Beispiel #10
0
        public static Feature UnionAreaFeatures(IEnumerable <Feature> features)
        {
            Collection <Feature> tempFeatuers = new Collection <Feature>();

            foreach (var item in features)
            {
                if (!SqlTypesGeometryHelper.IsValid(item))
                {
                    tempFeatuers.Add(SqlTypesGeometryHelper.MakeValid(item));
                }
                else
                {
                    tempFeatuers.Add(item);
                }
            }

            var unionresult = AreaBaseShape.Union(tempFeatuers);

            return(new Feature(unionresult));
        }
        protected virtual Feature CreateHighlightFeatureCore(Feature sourceFeature, FeatureLayer sourceFeatureLayer)
        {
            string newFeatureId = CreateHighlightFeatureId(sourceFeature, sourceFeatureLayer);

            try
            {
                sourceFeature = SqlTypesGeometryHelper.MakeValid(sourceFeature);
            }
            catch { }

            Feature newFeature = new Feature(sourceFeature.GetWellKnownBinary(), newFeatureId, sourceFeature.ColumnValues);

            //LINK:
            //foreach (var item in sourceFeature.LinkColumnValues)
            //{
            //    newFeature.LinkColumnValues.Add(item.Key, item.Value);
            //}
            newFeature.Tag = sourceFeature.Tag;
            return(newFeature);
        }
Beispiel #12
0
        private IEnumerable <Feature> StandardClipPoints(IEnumerable <Feature> masterFeatures, IEnumerable <Feature> clippingFeatures)
        {
            ConcurrentQueue <Feature> results = new ConcurrentQueue <Feature>();
            int index = 1;
            int count = masterFeatures.Count();
            ConcurrentQueue <Feature> cqMasterFeatures = new ConcurrentQueue <Feature>(masterFeatures);

            if (count > 0)
            {
                var firstFeature = masterFeatures.FirstOrDefault();
                var firstWktType = firstFeature.GetWellKnownType();
                if (firstWktType == WellKnownType.Point)
                {
                    Parallel.ForEach(cqMasterFeatures, feature =>
                    {
                        index++;
                        isCanceled = ReportProgress(index, count);
                        if (isCanceled)
                        {
                            return;
                        }

                        if (clippingFeatures.Any(f =>
                        {
                            try //{ return f.GetShape().Intersects(feature); }
                            {
                                return(SqlTypesGeometryHelper.Intersects(f.GetShape(), feature));
                            }
                            catch (Exception ex)
                            {
                                GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                                HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                                return(false);
                            }
                        }))
                        {
                            results.Enqueue(feature);
                        }
                    });
                }
                else
                {
                    Parallel.ForEach(cqMasterFeatures, feature =>
                    {
                        isCanceled = ReportProgress(index, count);
                        if (isCanceled)
                        {
                            return;
                        }

                        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); }
                                    {
                                        return(SqlTypesGeometryHelper.Intersects(f.GetShape(), p));
                                    }
                                    catch (Exception ex)
                                    {
                                        GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(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);
        }
Beispiel #13
0
        private IEnumerable <Feature> StandardClip(FeatureLayer featureLayer, IEnumerable <Feature> features)
        {
            lock (featureLayer)
            {
                Collection <Feature> results = new Collection <Feature>();

                #region replace project to null

                bool isOpen = false;
                Proj4ProjectionInfo projectionInfo = featureLayer.GetProj4ProjectionInfo();
                if (projectionInfo != null && projectionInfo.CanProject)
                {
                    if (featureLayer.IsOpen)
                    {
                        featureLayer.Close();
                        projectionInfo.Close();
                        isOpen = true;
                    }
                    featureLayer.FeatureSource.Projection = null;
                }

                #endregion replace project to null

                Collection <Feature> tmpFeatures = new Collection <Feature>();
                if (projectionInfo != null && projectionInfo.CanProject)
                {
                    projectionInfo.Open();
                    foreach (var item in features)
                    {
                        tmpFeatures.Add(projectionInfo.ConvertToInternalProjection(item));
                    }
                    projectionInfo.Close();
                }
                else
                {
                    tmpFeatures = new Collection <Feature>(features.ToList());
                }

                if (!featureLayer.IsOpen)
                {
                    featureLayer.Open();
                }
                List <Feature> tmpSourceFeatures = featureLayer.FeatureSource.GetFeaturesInsideBoundingBox(ExtentHelper.GetBoundingBoxOfItems(tmpFeatures), featureLayer.GetDistinctColumnNames()).Select(f => f.MakeValidIfCan()).ToList();

                Collection <Feature> sourceFeatures = new Collection <Feature>(tmpSourceFeatures);
                if (projectionInfo != null)
                {
                    featureLayer.FeatureSource.Projection = projectionInfo.Projection;
                    if (isOpen)
                    {
                        featureLayer.Open();
                    }
                }

                SimpleShapeType simpleShapeType = SimpleShapeType.Unknown;
                var             shapeAdapter    = GisEditor.LayerManager.GetLayerPlugins(featureLayer.GetType()).FirstOrDefault() as FeatureLayerPlugin;
                if (shapeAdapter != null)
                {
                    simpleShapeType = shapeAdapter.GetFeatureSimpleShapeType(featureLayer);
                }
                if (featureLayer.IsOpen)
                {
                    featureLayer.Close();
                }

                int index = 1;
                int count = sourceFeatures.Count;
                if (simpleShapeType == SimpleShapeType.Point)
                {
                    return(StandardClipPoints(sourceFeatures, tmpFeatures));
                }
                else if (simpleShapeType == SimpleShapeType.Line)
                {
                    StandardClipLines(tmpFeatures, results, sourceFeatures, index, count);
                }
                else if (simpleShapeType == SimpleShapeType.Area)
                {
                    //MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(tmpFeatures));
                    List <AreaBaseShape> clippingAreaShapes = GetValidFeatures(tmpFeatures)
                                                              .Select(f => f.GetShape())
                                                              .OfType <AreaBaseShape>()
                                                              .ToList();

                    BaseShape         unionResultShape = SqlTypesGeometryHelper.Union(clippingAreaShapes);
                    MultipolygonShape areaBaseShape    = ConvertSqlQueryResultToMultiPolygonShape(unionResultShape);

                    foreach (var feature in sourceFeatures)
                    {
                        isCanceled = ReportProgress(index, count);
                        if (isCanceled)
                        {
                            break;
                        }

                        try
                        {
                            index++;
                            //if (areaBaseShape.Contains(feature))
                            if (SqlTypesGeometryHelper.Contains(areaBaseShape, feature))
                            {
                                results.Add(feature);
                            }
                            else
                            {
                                //var clippedShape = areaBaseShape.GetIntersection(feature);
                                AreaBaseShape targetAreaShape = feature.GetShape() as AreaBaseShape;
                                if (targetAreaShape != null)
                                {
                                    var clippedShape = SqlTypesGeometryHelper.GetIntersection(areaBaseShape, targetAreaShape) as MultipolygonShape;
                                    if (clippedShape != null && clippedShape.Polygons.Count > 0)
                                    {
                                        results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                        }
                    }
                }
                else
                {
                    throw new NotSupportedException("The ShapeFileType is not supported.");
                }

                Collection <Feature> convertedFeatures = new Collection <Feature>();
                if (projectionInfo != null && projectionInfo.CanProject)
                {
                    projectionInfo.Open();
                    foreach (var item in results)
                    {
                        convertedFeatures.Add(projectionInfo.ConvertToExternalProjection(item));
                    }
                    projectionInfo.Close();
                }
                else
                {
                    convertedFeatures = new Collection <Feature>(results.ToList());
                }

                return(convertedFeatures);
            }
        }
Beispiel #14
0
        private IEnumerable <Feature> InverseClip(FeatureLayer featureLayer, IEnumerable <Feature> clippingFeatures)
        {
            lock (featureLayer)
            {
                if (!featureLayer.IsOpen)
                {
                    featureLayer.Open();
                }
                Collection <Feature> results         = featureLayer.FeatureSource.GetFeaturesOutsideBoundingBox(ExtentHelper.GetBoundingBoxOfItems(clippingFeatures), featureLayer.GetDistinctColumnNames());
                Collection <Feature> sourceFeatures  = new Collection <Feature>();
                SimpleShapeType      simpleShapeType = GisEditor.LayerManager.GetFeatureSimpleShapeType(featureLayer);
                int index = 1;
                if (simpleShapeType == SimpleShapeType.Point)
                {
                    featureLayer.Open();
                    Collection <Feature> allFeatures = featureLayer.FeatureSource.GetAllFeatures(featureLayer.GetDistinctColumnNames());
                    featureLayer.Close();
                    foreach (Feature f in results)
                    {
                        allFeatures.Remove(f);
                    }
                    foreach (var f in InverseClipPoints(allFeatures, clippingFeatures, simpleShapeType))
                    {
                        results.Add(f);
                    }
                }
                else if (simpleShapeType == SimpleShapeType.Line)
                {
                    bool isOpen = false;
                    Proj4ProjectionInfo projectionInfo = featureLayer.GetProj4ProjectionInfo();
                    //MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(clippingFeatures));
                    List <AreaBaseShape> clippingAreaShapes = GetValidFeatures(clippingFeatures)
                                                              .Select(f => f.GetShape())
                                                              .OfType <AreaBaseShape>()
                                                              .ToList();
                    MultipolygonShape areaBaseShape = AreaBaseShape.Union(clippingAreaShapes);

                    if (projectionInfo != null && projectionInfo.CanProject)
                    {
                        if (featureLayer.IsOpen)
                        {
                            featureLayer.Close();
                            projectionInfo.Close();
                            isOpen = true;
                        }
                        featureLayer.FeatureSource.Projection = null;
                    }
                    featureLayer.Open();
                    featureLayer.FeatureSource.GetFeaturesInsideBoundingBox(areaBaseShape.GetBoundingBox(), featureLayer.GetDistinctColumnNames()).ForEach(f => { if (!areaBaseShape.Contains(f))
                                                                                                                                                                  {
                                                                                                                                                                      sourceFeatures.Add(f);
                                                                                                                                                                  }
                                                                                                                                                           });
                    int count = sourceFeatures.Count;
                    if (projectionInfo != null)
                    {
                        featureLayer.FeatureSource.Projection = projectionInfo.Projection;
                        if (isOpen)
                        {
                            featureLayer.Open();
                        }
                    }
                    if (featureLayer.IsOpen)
                    {
                        featureLayer.Close();
                    }
                    foreach (var feature in sourceFeatures)
                    {
                        isCanceled = ReportProgress(index, count);
                        if (isCanceled)
                        {
                            break;
                        }

                        index++;
                        try
                        {
                            //if (areaBaseShape.IsDisjointed(feature))
                            if (SqlTypesGeometryHelper.IsDisjointed(areaBaseShape, feature))
                            {
                                results.Add(feature);
                            }
                            else
                            {
                                MultilineShape multiLine   = (MultilineShape)feature.GetShape();
                                MultilineShape resultShape = new MultilineShape();
                                foreach (LineShape lineShape in multiLine.Lines)
                                {
                                    //if (areaBaseShape.IsDisjointed(lineShape))
                                    if (SqlTypesGeometryHelper.IsDisjointed(areaBaseShape, lineShape))
                                    {
                                        resultShape.Lines.Add(lineShape);
                                    }
                                    else
                                    {
                                        var resultLine = lineShape.GetDifference(areaBaseShape);
                                        foreach (var line in resultLine.Lines)
                                        {
                                            resultShape.Lines.Add(line);
                                        }
                                    }
                                }
                                if (resultShape != null && resultShape.Lines.Count > 0)
                                {
                                    results.Add(new Feature(resultShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                        }
                    }
                }
                else if (simpleShapeType == SimpleShapeType.Area)
                {
                    //MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(clippingFeatures));
                    List <AreaBaseShape> clippingAreaShapes = GetValidFeatures(clippingFeatures)
                                                              .Select(f => f.GetShape())
                                                              .OfType <AreaBaseShape>()
                                                              .ToList();

                    BaseShape         unionResultShape = SqlTypesGeometryHelper.Union(clippingAreaShapes);
                    MultipolygonShape areaBaseShape    = ConvertSqlQueryResultToMultiPolygonShape(unionResultShape);

                    bool isOpen = false;
                    Proj4ProjectionInfo projectionInfo = featureLayer.GetProj4ProjectionInfo();
                    if (projectionInfo != null && projectionInfo.CanProject)
                    {
                        if (featureLayer.IsOpen)
                        {
                            featureLayer.Close();
                            if (projectionInfo != null)
                            {
                                projectionInfo.Close();
                            }
                            isOpen = true;
                        }
                        featureLayer.FeatureSource.Projection = null;
                    }
                    if (!featureLayer.IsOpen)
                    {
                        featureLayer.Open();
                    }
                    featureLayer.FeatureSource.GetFeaturesInsideBoundingBox(areaBaseShape.GetBoundingBox(), featureLayer.GetDistinctColumnNames()).ForEach(f => sourceFeatures.Add(f));
                    if (featureLayer.IsOpen)
                    {
                        featureLayer.Close();
                    }
                    if (projectionInfo != null)
                    {
                        featureLayer.FeatureSource.Projection = projectionInfo.Projection;
                        if (isOpen)
                        {
                            featureLayer.Open();
                        }
                    }

                    int count = sourceFeatures.Count;
                    foreach (var feature in sourceFeatures)
                    {
                        isCanceled = ReportProgress(index, count);
                        if (isCanceled)
                        {
                            break;
                        }

                        index++;
                        try
                        {
                            //if (areaBaseShape.IsDisjointed(feature))
                            if (SqlTypesGeometryHelper.IsDisjointed(areaBaseShape, feature))
                            {
                                results.Add(feature);
                            }
                            else
                            {
                                //var clippedShape = ((AreaBaseShape)feature.GetShape()).GetDifference(areaBaseShape);
                                BaseShape         differenceResultShape = SqlTypesGeometryHelper.GetDifference((AreaBaseShape)feature.GetShape(), areaBaseShape);
                                MultipolygonShape clippedShape          = ConvertSqlQueryResultToMultiPolygonShape(differenceResultShape);
                                if (clippedShape != null && clippedShape.Polygons.Count > 0)
                                {
                                    results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                            HandleExceptionFromInvalidFeature(feature.Id, ex.Message);
                        }
                    }
                }
                else
                {
                    throw new NotSupportedException("The ShapeFileType is not supported.");
                }
                return(results);
            }
        }
        //private IEnumerable<string> GetMatchColumnsFromString(string matchColumnsInString)
        //{
        //    string[] columns = matchColumnsInString.Split(',');
        //    return columns;
        //}

        private void Dissolve()
        {
            Collection <Feature> dissolvedFeatures = new Collection <Feature>();

            // get features to dissolve.
            Collection <Feature> featuresToDissolve = GetFeaturesToDissolve();

            // group features.
            var featureGroupByShapeType = featuresToDissolve.GroupBy(f =>
            {
                return(f.GetShape().GetType());
            });

            // collect export columns.
            var filteredFeatureColumns = new Collection <FeatureSourceColumn>();

            foreach (var matchColumn in this.matchColumns)
            {
                var tmpColumn = featureColumns.FirstOrDefault(f => f.ColumnName.Equals(matchColumn, StringComparison.Ordinal));
                if (tmpColumn != null)
                {
                    filteredFeatureColumns.Add(tmpColumn);
                }
            }

            foreach (var extraColumn in this.operatorPairs)
            {
                var tmpColumn = featureColumns.FirstOrDefault(f => f.ColumnName.Equals(extraColumn.ColumnName, StringComparison.Ordinal));
                if (tmpColumn != null)
                {
                    filteredFeatureColumns.Add(tmpColumn);
                }
            }

            filteredFeatureColumns.Add(new FeatureSourceColumn("Count", "Integer", 8));

            Action <IGrouping <Type, Feature>, Action <IEnumerable <Feature>, Dictionary <string, string> > > dissolveAction
                = new Action <IGrouping <Type, Feature>, Action <IEnumerable <Feature>, Dictionary <string, string> > >
                      ((groupByType, finalProcessAction) =>
            {
                //CancelTask(this.CancellationSource.Token, content, parameter);
                var groupByColumns = GroupByColumns(groupByType, this.matchColumns);
                groupByColumns.ForEach(groupFeature =>
                {
                    //CancelTask(this.CancellationSource.Token, content, parameter);
                    Dictionary <string, string> newColumnValues = new Dictionary <string, string>();
                    foreach (var tmpMatchColumn in this.matchColumns)
                    {
                        newColumnValues.Add(tmpMatchColumn, groupFeature.First().ColumnValues[tmpMatchColumn]);
                    }

                    foreach (var operatorPair in this.operatorPairs)
                    {
                        //CancelTask(this.CancellationSource.Token, content, parameter);
                        CollectNewColumnValues(groupFeature, newColumnValues, operatorPair);
                        var value        = newColumnValues[operatorPair.ColumnName];
                        var resultColumn = filteredFeatureColumns.FirstOrDefault(c => c.ColumnName.Equals(operatorPair.ColumnName));
                        if (resultColumn != null)
                        {
                            if (resultColumn.MaxLength < value.Length)
                            {
                                var indexOf = filteredFeatureColumns.IndexOf(resultColumn);
                                filteredFeatureColumns.RemoveAt(indexOf);
                                var newColumn = new FeatureSourceColumn(resultColumn.ColumnName, resultColumn.TypeName, value.Length);
                                filteredFeatureColumns.Insert(indexOf, newColumn);
                            }
                        }
                    }

                    newColumnValues.Add("Count", groupFeature.Count().ToString());

                    try
                    {
                        if (finalProcessAction != null)
                        {
                            finalProcessAction(groupFeature, newColumnValues);
                        }
                    }
                    catch (Exception e)
                    {
                        GisEditor.LoggerManager.Log(LoggerLevel.Debug, e.Message, new ExceptionInfo(e));
                        throw e;
                    }
                });
            });

            foreach (var groupByType in featureGroupByShapeType)
            {
                try
                {
                    //CancelTask(this.CancellationSource.Token, content, parameter);
                    if (groupByType.Key.IsSubclassOf(typeof(AreaBaseShape)))
                    {
                        dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) =>
                        {
                            //MultipolygonShape dissolveShape = AreaBaseShape.Union(GetValidFeatures(tmpFeatures));
                            List <AreaBaseShape> areaShapes = GetValidFeatures(tmpFeatures)
                                                              .Select(f => f.GetShape())
                                                              .OfType <AreaBaseShape>()
                                                              .ToList();

                            MultipolygonShape dissolveShape = (MultipolygonShape)SqlTypesGeometryHelper.Union(areaShapes);

                            if (dissolveShape != null)
                            {
                                Feature dissolveFeature = new Feature(dissolveShape, tmpColumnValues);
                                dissolvedFeatures.Add(dissolveFeature);
                            }
                        });
                    }
                    else if (groupByType.Key.IsSubclassOf(typeof(LineBaseShape)))
                    {
                        dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) =>
                        {
                            MultilineShape dissolveShape = new MultilineShape();
                            tmpFeatures.ForEach(tmpFeature =>
                            {
                                BaseShape tmpShape      = tmpFeature.GetShape();
                                LineShape tmpLine       = tmpShape as LineShape;
                                MultilineShape tmpMLine = tmpShape as MultilineShape;
                                if (tmpLine != null)
                                {
                                    dissolveShape.Lines.Add(tmpLine);
                                }
                                else if (tmpMLine != null)
                                {
                                    tmpMLine.Lines.ForEach(tmpLineInMLine => dissolveShape.Lines.Add(tmpLineInMLine));
                                }
                            });

                            if (dissolveShape.Lines.Count > 0)
                            {
                                dissolvedFeatures.Add(new Feature(dissolveShape, tmpColumnValues));
                            }
                        });
                    }
                    else if (groupByType.Key.IsSubclassOf(typeof(PointBaseShape)))
                    {
                        dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) =>
                        {
                            MultipointShape multipointShape = new MultipointShape();
                            tmpFeatures.ForEach(tmpFeature =>
                            {
                                BaseShape tmpShape        = tmpFeature.GetShape();
                                PointShape tmpPoint       = tmpShape as PointShape;
                                MultipointShape tmpMPoint = tmpShape as MultipointShape;
                                if (tmpPoint != null)
                                {
                                    multipointShape.Points.Add(tmpPoint);
                                }
                                else if (tmpMPoint != null)
                                {
                                    tmpMPoint.Points.ForEach(tmpPointInMPointShape => multipointShape.Points.Add(tmpPointInMPointShape));
                                }
                            });
                            dissolvedFeatures.Add(new Feature(multipointShape, tmpColumnValues));
                        });
                    }
                    if (isCanceled)
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    var errorEventArgs = new UpdatingTaskProgressEventArgs(TaskState.Error);
                    errorEventArgs.Error = new ExceptionInfo(string.Format(CultureInfo.InvariantCulture, "Feature id: {0}, {1}"
                                                                           , groupByType.FirstOrDefault().Id, ex.Message)
                                                             , ex.StackTrace
                                                             , ex.Source);
                    GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex));
                    errorEventArgs.Message = groupByType.FirstOrDefault().Id;
                    OnUpdatingProgress(errorEventArgs);
                    continue;
                }
            }
            if (!isCanceled)
            {
                string saveFolder = Path.GetDirectoryName(outputPathFileName);
                if (!Directory.Exists(saveFolder))
                {
                    Directory.CreateDirectory(saveFolder);
                }

                var info = new FileExportInfo(dissolvedFeatures, filteredFeatureColumns, outputPathFileName, Wkt);
                Export(info);
            }
        }
        private Collection <Feature> GetTargetFeaturesInterseting(BaseShape baseShape)
        {
            BaseShape searchArea = baseShape;

            if (baseShape.GetWellKnownType() == WellKnownType.Point)
            {
                PointShape worldCoordinate  = (PointShape)baseShape;
                double     searchTorlerence = 15 * MapArguments.CurrentResolution;
                searchArea = new RectangleShape(worldCoordinate.X - searchTorlerence,
                                                worldCoordinate.Y + searchTorlerence, worldCoordinate.X + searchTorlerence,
                                                worldCoordinate.Y - searchTorlerence);
            }

            Collection <Feature> features = new Collection <Feature>();

            lock (EditTargetLayer)
            {
                if (!EditTargetLayer.IsOpen)
                {
                    EditTargetLayer.Open();
                }

                //var excludeFeatures = new Collection<string>();
                //foreach (var item in editTargetLayer.FeatureIdsToExclude)
                //{
                //    excludeFeatures.Add(item);
                //}

                editTargetLayer.FeatureIdsToExclude.Clear();
                foreach (var item in newFeatureIds)
                {
                    editTargetLayer.FeatureIdsToExclude.Add(item);
                }

                EditTargetLayer.SafeProcess(() =>
                {
                    var intersectingFeatures = EditTargetLayer.QueryTools.GetFeaturesIntersecting(searchArea, EditTargetLayer.GetDistinctColumnNames());
                    foreach (var feature in intersectingFeatures)
                    {
                        try
                        {
                            features.Add(feature);
                        }
                        catch
                        {
                            features.Add(SqlTypesGeometryHelper.MakeValid(feature));
                        }
                    }
                });
            }

            foreach (var item in editShapesLayer.InternalFeatures)
            {
                if (item.GetShape().Intersects(searchArea) && !features.Any(f => f.GetWellKnownText() == item.GetWellKnownText()))
                {
                    features.Add(item);
                }
            }

            foreach (var item in editCandidatesLayer.InternalFeatures)
            {
                if (item.GetShape().Intersects(searchArea) && !features.Any(f => f.GetWellKnownText() == item.GetWellKnownText()))
                {
                    features.Add(item);
                }
            }

            return(features);
        }
        private void BufferAllFeatures()
        {
            FeaturesToBuffer = GetFeaturesToBuffer(FeatureSource);

            int bufferdFeaturesCount = 0;
            Collection <Feature> bufferedFeatures = new Collection <Feature>();
            MultipolygonShape    dissolvedShape   = null;

            bool isCanceled = false;

            foreach (Feature feature in featuresToBuffer)
            {
                try
                {
                    BaseShape         shape           = feature.GetShape();
                    MultipolygonShape bufferedShape   = BufferShape(shape);
                    Feature           bufferedFeature = new Feature(bufferedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues);

                    bufferedFeature.Tag = feature.Tag;
                    bufferedFeatures.Add(bufferedFeature);

                    if (dissolve)
                    {
                        if (dissolvedShape == null)
                        {
                            dissolvedShape     = bufferedShape;
                            dissolvedShape.Tag = feature.Tag;
                        }
                        else
                        {
                            //dissolvedShape = dissolvedShape.Union(bufferedShape);
                            dissolvedShape = (MultipolygonShape)SqlTypesGeometryHelper.Union(dissolvedShape, bufferedShape);
                        }
                    }
                }
                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;
                    OnUpdatingProgress(errorEventArgs);
                    continue;
                }

                Interlocked.Increment(ref bufferdFeaturesCount);
                int progressPercentage = bufferdFeaturesCount * 100 / featuresToBuffer.Count;
                var updatingArgs       = new UpdatingTaskProgressEventArgs(TaskState.Updating, progressPercentage);
                updatingArgs.Current    = bufferdFeaturesCount;
                updatingArgs.UpperBound = featuresToBuffer.Count;
                OnUpdatingProgress(updatingArgs);

                if (updatingArgs.TaskState == TaskState.Canceled)
                {
                    isCanceled = true;
                    break;
                }
            }

            if (!isCanceled)
            {
                if (dissolve && dissolvedShape != null)
                {
                    bufferedFeatures.Clear();
                    bufferedFeatures.Add(new Feature(dissolvedShape.GetWellKnownBinary(), "1", new Dictionary <string, string> {
                        { "OBJECTID", "1" }, { "SHAPE", "MULTIPOLYGON" }
                    })
                    {
                        Tag = dissolvedShape.Tag
                    });
                }
                OnUpdatingProgress(new UpdatingTaskProgressEventArgs(TaskState.Updating)
                {
                    Message = "Creating File"
                });
                Output(bufferedFeatures, OutputPathFileName, DisplayProjectionParameters, Dissolve);
            }
        }