Esempio n. 1
0
        /// <summary>
        /// Collect edges from area inputs which should be in the result but
        /// which have not been included in a result area.
        /// </summary>
        /// <remarks>
        /// This happens ONLY:
        /// <list type="bullet">
        /// <item>
        /// <description>
        /// During an intersection when the boundaries of two areas touch
        /// in a line segment.
        /// </description>
        /// </item>
        /// <item>
        /// <description>OR as a result of a dimensional collapse.</description>
        /// </item>
        /// </list>
        /// </remarks>
        private void CollectBoundaryTouchEdge(DirectedEdge de,
                                              OverlayType opCode, ArrayList edges)
        {
            Label label = de.Label;

            if (de.LineEdge)
            {
                return;  // only interested in area edges
            }
            if (de.Visited)
            {
                return;  // already processed
            }
            if (de.InteriorAreaEdge)
            {
                return;  // added to handle dimensional collapses
            }
            if (de.Edge.InResult)
            {
                return;  // if the edge linework is already included, don't include it again
            }
            // sanity check for labelling of result edgerings
            Debug.Assert(!(de.InResult || de.Sym.InResult) || !de.Edge.InResult);

            // include the linework if it's in the result of the operation
            if (OverlayOp.IsResultOfOp(label, opCode) &&
                opCode == OverlayType.Intersection)
            {
                edges.Add(de.Edge);
                de.VisitedEdge = true;
            }
        }
Esempio n. 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="opCode"></param>
        /// <returns></returns>
        public IGeometry GetResultGeometry(SpatialFunction opCode)
        {
            IGeometry[] prepGeom = Snap();
            IGeometry   result   = OverlayOp.Overlay(prepGeom[0], prepGeom[1], opCode);

            return(PrepareResult(result));
        }
Esempio n. 3
0
        /// <summary>
        /// Determines nodes which are in the result, and creates
        /// {@link Point}s for them.
        ///
        /// This method determines nodes which are candidates for the result via their
        /// labelling and their graph topology.
        ///
        /// </summary>
        /// <param name="opCode">the overlay operation
        /// </param>
        private void ExtractNonCoveredResultNodes(OverlayType opCode)
        {
            // Add nodes from edge intersections which have not already been included in the result
            for (IEnumerator nodeit = op.Graph.Nodes.GetEnumerator(); nodeit.MoveNext();)
            {
                Node n = (Node)nodeit.Current;

                // filter out nodes which are known to be in the result
                if (n.InResult)
                {
                    continue;
                }
                // if an incident edge is in the result, then the node coordinate is included already
                if (n.IsIncidentEdgeInResult)
                {
                    continue;
                }

                if (n.Edges.Degree == 0 ||
                    opCode == OverlayType.Intersection)
                {
                    // For nodes on edges, only INTERSECTION can result in
                    // edge nodes being included even
                    // if none of their incident edges are included
                    Label label = n.Label;
                    if (OverlayOp.IsResultOfOp(label, opCode))
                    {
                        FilterCoveredNodeToPoint(n);
                    }
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Computes a <c>Geometry</c> representing the point-set which is
        /// common to both <c>a</c> and <c>b</c> Geometry.
        /// </summary>
        /// <param name="a">The 1st <c>Geometry</c></param>
        /// <param name="b">The 2nd <c>Geometry</c></param>
        /// <returns>A geometry representing the point-set common to the two <c>Geometry</c>s.</returns>
        /// <seealso cref="Geometry.Intersection"/>
        public virtual Geometry Intersection(Geometry a, Geometry b)
        {
            /**
             * TODO: MD - add optimization for P-A case using Point-In-Polygon
             */
            // special case: if one input is empty ==> empty
            if (a.IsEmpty || b.IsEmpty)
            {
                return(OverlayOp.CreateEmptyResult(SpatialFunction.Intersection, a, b, a.Factory));
            }

            // compute for GCs
            // (An inefficient algorithm, but will work)
            // TODO: improve efficiency of computation for GCs
            if (a.OgcGeometryType == OgcGeometryType.GeometryCollection)
            {
                var g2 = b;
                return(GeometryCollectionMapper.Map(
                           (GeometryCollection)a, g => g.Intersection(g2)));
            }

            // No longer needed since GCs are handled by previous code
            //CheckNotGeometryCollection(a, b);

            return(Overlay(a, b, SpatialFunction.Intersection));
        }
Esempio n. 5
0
        /// <summary>
        /// Computes a <c>Geometry</c> representing the point-set
        /// which is contained in both input <c>Geometry</c>s .
        /// </summary>
        /// <param name="a">The 1st <c>Geometry</c></param>
        /// <param name="b">The 2nd <c>Geometry</c></param>
        /// <returns>A point-set combining the points of
        /// <c>Geometry</c>'s <c>a</c> and <c>b</c>.
        /// </returns>
        /// <seealso cref="Geometry.Union(Geometry)"/>
        public virtual Geometry Union(Geometry a, Geometry b)
        {
            // handle empty geometry cases
            if (a.IsEmpty || (b == null || b.IsEmpty))
            {
                // both empty - check dimensions
                if (a.IsEmpty && (b == null || b.IsEmpty))
                {
                    return(OverlayOp.CreateEmptyResult(SpatialFunction.Union, a, b, a.Factory));
                }

                // special case: if either input is empty ==> result = other arg
                if (a.IsEmpty)
                {
                    return(b.Copy());
                }
                if (b == null || b.IsEmpty)
                {
                    return(a.Copy());
                }
            }

            // TODO: optimize if envelopes of geometries do not intersect

            CheckNotGeometryCollection(a, b);

            return(Overlay(a, b, SpatialFunction.Union));
        }
Esempio n. 6
0
        /// <summary>
        /// Computes a <c>Geometry</c> representing the closure of the point-set
        /// which is the union of the points in <c>Geometry</c> <c>a</c> which are not
        /// contained in the Geometry  <c>b</c>,
        /// with the points in the <c>b</c> Geometry not contained in the <c>Geometry</c> <c>a</c>.
        /// </summary>
        /// <param name="a">The 1st <c>Geometry</c></param>
        /// <param name="b">The 2nd <c>Geometry</c></param>
        /// <returns>
        /// A Geometry representing the point-set symmetric difference
        /// of <c>Geometry</c>'s <c>a</c> and <c>b</c>.
        /// </returns>
        /// <seealso cref="Geometry.SymmetricDifference(Geometry)"/>
        public virtual Geometry SymmetricDifference(Geometry a, Geometry b)
        {
            // handle empty geometry cases
            if (a.IsEmpty || (b == null || b.IsEmpty))
            {
                // both empty - check dimensions
                if (a.IsEmpty && (b == null || b.IsEmpty))
                {
                    return(OverlayOp.CreateEmptyResult(SpatialFunction.SymDifference, a, b, a.Factory));
                }

                // special case: if either input is empty ==> result = other arg
                if (a.IsEmpty)
                {
                    return(b.Copy());
                }
                if (b == null || b.IsEmpty)
                {
                    return(a.Copy());
                }
            }

            CheckNotGeometryCollection(a, b);

            return(Overlay(a, b, SpatialFunction.SymDifference));
        }
Esempio n. 7
0
        public IGeometry GetResultGeometry(SpatialFunction opCode)
        {
            IGeometry result    = null;
            var       isSuccess = false;

            try
            {
                result = OverlayOp.Overlay(geom[0], geom[1], opCode);
                var isValid = true;
                // not needed if noding validation is used
                //      boolean isValid = OverlayResultValidator.isValid(geom[0], geom[1], OverlayOp.INTERSECTION, result);
                // if (isValid)
                isSuccess = true;
            }
            catch (Exception ex)
            {
                // Ignore this exception, since the operation will be rerun
                Debug.WriteLine(ex);
            }
            if (!isSuccess)
            {
                // This may still throw an exception - just let it go if it does
                result = SnapOverlayOp.Overlay(geom[0], geom[1], opCode);
            }
            return(result);
        }
Esempio n. 8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="opCode"></param>
        /// <returns></returns>
        public Geometry GetResultGeometry(SpatialFunction opCode)
        {
            var prepGeom = Snap(_geom);
            var result   = OverlayOp.Overlay(prepGeom[0], prepGeom[1], opCode);

            return(PrepareResult(result));
        }
Esempio n. 9
0
		///<summary>
		/// Returns a set combining the points in this Geometry not in other, and the points in other not
		/// in this Geometry.
		///</summary>
		///<remarks>This method returns the closure of the resultant Geometry.</remarks>
		///<param name="geometry"> the Geometry with which to compute the symmetric difference.</param>
		///<returns>Returns the point set symmetric difference of this Geometry with other geometry.</returns>
		public virtual Geometry SymDifference(Geometry geometry) 
		{
			CheckNotGeometryCollection(this);
			CheckNotGeometryCollection(geometry);
			CheckEqualSRID(geometry);
			CheckEqualPrecisionModel(geometry);
			return OverlayOp.Overlay(this, geometry, OverlayOp.SymDifference);
		}
Esempio n. 10
0
		///<summary>
		/// Returns a Geometry representing all the points in this Geometry and other.  
		///</summary>
		///<param name="geometry"> the Geometry with which to compute the union </param>
		///<returns>Returns a set combining the points of this Geometry and the points of other geometry.</returns>
		public virtual Geometry Union(Geometry geometry) 
		{
			CheckNotGeometryCollection(this);
			CheckNotGeometryCollection(geometry);
			CheckEqualSRID(geometry);
			CheckEqualPrecisionModel(geometry);
			return OverlayOp.Overlay(this, geometry, OverlayOp.Union);
		}
Esempio n. 11
0
        public LineBuilder(OverlayOp op, GeometryFactory geometryFactory,
                           PointLocator ptLocator)
        {
            lineEdgesList  = new ArrayList();
            resultLineList = new GeometryList();

            this.op = op;
            this.geometryFactory = geometryFactory;
            this.ptLocator       = ptLocator;
        }
Esempio n. 12
0
        private Exception TryOverlay(Geometry g1, Geometry g2)
        {
            Exception ex = null;

            try
            {
                OverlayOp.Overlay(g1, g2, SpatialFunction.Intersection);
            }
            catch (Exception e)
            {
                ex = e;
            }
            return(ex);
        }
        private static bool IsValidResult(SpatialFunction overlayOp, Location[] location)
        {
            bool expectedInterior = OverlayOp.IsResultOfOp(location[0], location[1], overlayOp);

            bool resultInInterior = (location[2] == Location.Interior);
            // MD use simpler: boolean isValid = (expectedInterior == resultInInterior);
            bool isValid = !(expectedInterior ^ resultInInterior);

            if (!isValid)
            {
                ReportResult(overlayOp, location, expectedInterior);
            }

            return(isValid);
        }
Esempio n. 14
0
        /// <summary>
        /// Collect line edges which are in the result.
        /// Line edges are in the result if they are not part of
        /// an area boundary, if they are in the result of the overlay operation,
        /// and if they are not covered by a result area.
        /// </summary>
        /// <param name="de">the directed edge to test</param>
        /// <param name="opCode">the overlap operation</param>
        /// <param name="edges">the list of included line edges</param>
        private void CollectLineEdge(DirectedEdge de, OverlayType opCode, ArrayList edges)
        {
            Label label = de.Label;
            Edge  e     = de.Edge;

            // include L edges which are in the result
            if (de.LineEdge)
            {
                if (!de.Visited && OverlayOp.IsResultOfOp(label, opCode) && !e.Covered)
                {
                    edges.Add(e);
                    de.VisitedEdge = true;
                }
            }
        }
        /// <summary>
        /// Cuts the given linestring in one of more segments.
        /// </summary>
        /// <param name="tilePolygon">The tile polygon.</param>
        /// <param name="lineString">The linestring.</param>
        /// <returns>One or more segments.</returns>
        public static IEnumerable <LineString> Cut(this Polygon tilePolygon, LineString lineString)
        {
            var op           = new OverlayOp(lineString, tilePolygon);
            var intersection = op.GetResultGeometry(SpatialFunction.Intersection);

            if (intersection.IsEmpty)
            {
                yield break;
            }

            switch (intersection)
            {
            case LineString ls:
                // intersection is a linestring.
                yield return(ls);

                yield break;

            case GeometryCollection gc:
            {
                foreach (var geometry in gc.Geometries)
                {
                    switch (geometry)
                    {
                    case LineString ls0:
                        yield return(ls0);

                        break;

                    case Point _:
                        // The linestring only has a single point in this tile
                        // We skip it
                        // TODO check if this is correct
                        continue;

                    default:
                        throw new Exception(
                                  $"{nameof(LineStringTiler)}.{nameof(Cut)} failed: A geometry was found in the intersection that wasn't a {nameof(LineString)}.");
                    }
                }

                yield break;
            }

            default:
                throw new Exception($"{nameof(LineStringTiler)}.{nameof(Cut)} failed: Unknown result.");
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Computes a <c>Geometry</c> representing the closure of the point-set
        /// of the points contained in this <c>Geometry</c> that are not contained in
        /// the <c>other</c> Geometry.
        /// </summary>
        /// <param name="a">The 1st <c>Geometry</c></param>
        /// <param name="b">The 2nd <c>Geometry</c></param>
        /// <returns>
        /// A Geometry representing the point-set difference
        /// of <c>Geometry</c>'s <c>a</c> and <c>b</c>.
        /// </returns>
        /// <seealso cref="Geometry.Difference(Geometry)"/>
        public virtual Geometry Difference(Geometry a, Geometry b)
        {
            // special case: if A.isEmpty ==> empty; if B.isEmpty ==> A
            if (a.IsEmpty)
            {
                return(OverlayOp.CreateEmptyResult(SpatialFunction.Difference, a, b, a.Factory));
            }
            if (b == null || b.IsEmpty)
            {
                return(a.Copy());
            }

            CheckNotGeometryCollection(a, b);

            return(Overlay(a, b, SpatialFunction.Difference));
        }
        public IGeometry GetResultGeometry(SpatialFunction opCode)
        {
            IGeometry result         = null;
            var       isSuccess      = false;
            Exception savedException = null;

            try
            {
                // try basic operation with input geometries
                result = OverlayOp.Overlay(_geom[0], _geom[1], opCode);
                var isValid = true;
                // not needed if noding validation is used
                //      boolean isValid = OverlayResultValidator.isValid(geom[0], geom[1], OverlayOp.INTERSECTION, result);
                // if (isValid)
                isSuccess = true;
            }
            catch (Exception ex)
            {
                savedException = ex;
                //// Ignore this exception, since the operation will be rerun
                //Debug.WriteLine(ex);
                //Console.WriteLine(ex.Message));
                //Console.WriteLine("Geom 0: " + geom[0]);
                //Console.WriteLine("Geom 1: " + geom[1]);
            }
            if (!isSuccess)
            {
                // this may still throw an exception
                // if so, throw the original exception since it has the input coordinates
                try
                {
                    result = SnapOverlayOp.Overlay(_geom[0], _geom[1], opCode);
                }
                catch (Exception)
                {
                    throw savedException;
                }
            }
            return(result);
        }
        public Geometry GetResultGeometry(SpatialFunction opCode)
        {
            Geometry result    = null;
            bool     isSuccess = false;
            ExceptionDispatchInfo savedException = null;

            try
            {
                // try basic operation with input geometries
                result = OverlayOp.Overlay(_geom[0], _geom[1], opCode);
                bool isValid = true;
                // not needed if noding validation is used
                //      boolean isValid = OverlayResultValidator.isValid(geom[0], geom[1], OverlayOp.INTERSECTION, result);
                // if (isValid)
                isSuccess = true;
            }
            catch (Exception ex)
            {
                savedException = ExceptionDispatchInfo.Capture(ex);
                // Ignore this exception, since the operation will be rerun
            }
            if (!isSuccess)
            {
                // this may still throw an exception
                // if so, throw the original exception since it has the input coordinates
                try
                {
                    result = SnapOverlayOp.Overlay(_geom[0], _geom[1], opCode);
                }
                catch (Exception)
                {
                    savedException.Throw();
                }
            }
            return(result);
        }
Esempio n. 19
0
 public PointBuilder(OverlayOp op, GeometryFactory geometryFactory)
 {
     this.op = op;
     this.geometryFactory = geometryFactory;
     this.resultPointList = new GeometryList();
 }
Esempio n. 20
0
        /// <summary>
        /// Computes a unary union with no extra optimization, and no short-circuiting.
        /// </summary>
        /// <remarks>
        /// Due to the way the overlay operations are implemented, this is still efficient in the case of linear and puntal geometries.
        /// </remarks>
        /// <param name="g0">A geometry</param>
        /// <returns>The union of the input geometry</returns>
        private IGeometry UnionNoOpt(IGeometry g0)
        {
            var empty = _geomFact.CreatePoint();

            return(OverlayOp.Overlay(g0, empty, SpatialFunction.Union));
        }
Esempio n. 21
0
        static void Main(string[] args)
        {
            BasicConfigurator.Configure();


            string geoJSONdatafile = @"D:\research\wifidata\network_minspan_001.geojson";

            var networksInRange = new HashSet <string>(new string[] {
                "bc:ae:c5:c3:71:66",
                "00:20:a6:5d:5f:7c",
                "00:22:3f:7a:76:39"
            });


            var            json     = File.ReadAllText(geoJSONdatafile);
            var            coll     = (JObject)JsonConvert.DeserializeObject(json);
            List <JObject> found    = new List <JObject>();
            List <Polygon> polygons = new List <Polygon>();

            foreach (JObject feature in coll["features"])
            {
                JObject atts  = (JObject)feature["properties"];
                var     bssid = (string)atts["bssid"];

                if (networksInRange.Contains(bssid))
                {
                    found.Add(feature);
                    //polygons.Add(ReadPolygon((JObject)feature["geometry"]));
                }
            }

            //argh.
            GeoJsonReader reader = new GeoJsonReader();

            //var result = reader.Read<Polygon>(json);
            for (int i = 0; i < found.Count; i++)
            {
                var     feat = found[i];
                JObject geom = (JObject)feat["geometry"];
                Polygon p    = ReadPolygon(geom);
                polygons.Add(p);



                if (p != null)
                {
                    _log.InfoFormat("found {0} : {1} ", feat["bssid"], p.ToText());
                }
            }


            IGeometry result = null;

            if (polygons.Count > 1)
            {
                for (int i = 0; i < polygons.Count - 1; i++)
                {
                    if ((result == null) || (result.IsEmpty))
                    {
                        result = polygons[i];
                    }
                    result = OverlayOp.Overlay(result, polygons[i + 1], SpatialFunction.Intersection);
                }
            }
            _log.InfoFormat("YOU ARE HERE {0} ", result);
            Clipboard.SetText(result.ToString());



            _log.Info("Done -- Copied to clipboard");
        }
Esempio n. 22
0
        ///<summary>
        /// Computes a unary union with no extra optimization, and no short-circuiting.
        ///</summary>
        /// <remarks>
        /// Due to the way the overlay operations are implemented, this is still efficient in the case of linear and puntal geometries.
        /// </remarks>
        /// <param name="g0">A geometry</param>
        /// <returns>The union of the input geometry</returns>
        private IGeometry UnionNoOpt(IGeometry g0)
        {
            IGeometry empty = _geomFact.CreatePoint((Coordinate)null);

            return(OverlayOp.Overlay(g0, empty, SpatialFunction.Union));
        }
Esempio n. 23
0
        public static FeatureClassSDO Intersect(this FeatureClassSDO featureClassSelf, FeatureClassSDO featureClassOther)
        {
            FeatureClassSDO newFeatureClass = null;

            try
            {
                if (featureClassSelf == null || featureClassOther == null)
                {
                    throw new ArgumentException("对象未实例化");
                }
                if (featureClassSelf.GeometryTypeNet != featureClassOther.GeometryTypeNet)
                {
                    throw new ArgumentException("空间对象类型错误");
                }
                if (CompareProperties(featureClassSelf.spatialReference, featureClassOther.spatialReference, typeof(object)))
                {
                    throw new ArgumentException("空间坐标系不一致");
                }
                newFeatureClass = new FeatureClassSDO()
                {
                    Name             = $"{featureClassSelf.Name}_{featureClassOther.Name}",
                    DisplayFieldName = $"{featureClassSelf.DisplayFieldName}_{featureClassOther.DisplayFieldName}",
                    Fields           = featureClassSelf.Fields,
                    GeometryType     = featureClassSelf.GeometryType,
                    GeometryTypeNet  = featureClassSelf.GeometryTypeNet,
                    spatialReference = featureClassSelf.spatialReference
                };
                foreach (var item in featureClassOther.Fields)
                {
                    if (item.Type == enumFieldType.esriFieldTypeGeometry || item.Name.ToLower() == "shape_area")
                    {
                        continue;
                    }
                    newFeatureClass.Fields.Add(new Field()
                    {
                        Alias = $"{featureClassOther.Name}_{item.Alias}",
                        Type  = item.Type,
                        Name  = $"{featureClassOther.Name}_{item.Name}"
                    });
                }
                int groupCount = featureClassOther.Features.Count / SpatialDataObtain.MinWorkThreadCount;
                Parallel.ForEach(featureClassOther.Features, (otherItem) =>
                {
                    foreach (var selfItem in featureClassSelf.Features)
                    {
                        if (otherItem.Geometry.Intersects(selfItem.Geometry))
                        {
                            OverlayOp overlayOp  = new OverlayOp(otherItem.Geometry, selfItem.Geometry);
                            Geometry newGeometry = overlayOp.GetResultGeometry(SpatialFunction.Intersection);

                            Feature newFeature    = new Feature();
                            newFeature.Attributes = new Dictionary <string, object>(selfItem.Attributes);
                            foreach (var oterAttribute in otherItem.Attributes)
                            {
                                Field field = featureClassOther.Fields.Single(item => item.Name == oterAttribute.Key);
                                if (field.Type == enumFieldType.esriFieldTypeGeometry || field.Name.ToLower() == "shape_area")
                                {
                                    continue;
                                }
                                string newKey = $"{featureClassOther.Name}_{field.Name}";
                                newFeature.Attributes.Add(newKey, oterAttribute.Value);
                            }
                            newFeature.Geometry = newGeometry;
                            newFeatureClass.AddFeature(newFeature);
                        }
                    }
                });
                return(newFeatureClass);
            }
            catch (Exception e)
            {
                LogUtil.Error(e.ToString());
                throw;
            }
        }