예제 #1
0
 public void TestRemoveSTRtree()
 {
     var tree = new STRtree<string>();
     tree.Insert(new Envelope(0, 10, 0, 10), "1");
     tree.Insert(new Envelope(5, 15, 5, 15), "2");
     tree.Insert(new Envelope(10, 20, 10, 20), "3");
     tree.Insert(new Envelope(15, 25, 15, 25), "4");
     Assert.DoesNotThrow(() => tree.Remove(new Envelope(10, 20, 10, 20), "4"));
     Assert.AreEqual(3, tree.Count);
 }
 // ReSharper restore InconsistentNaming
 /// <summary>
 /// 
 /// </summary>
 /// <param name="g"></param>
 /// <returns></returns>
 public static STRtree<FacetSequence> BuildSTRtree(IGeometry g)
 {
     var tree = new STRtree<FacetSequence>(STRtreeNodeCapacity);
     var sections = ComputeFacetSequences(g);
     foreach (var section in sections)
     {
         tree.Insert(section.Envelope, section);
     }
     tree.Build();
     return tree;
 }
    public async Task Initialize(string supplier, string countryCode, CancellationToken cancellationToken)
    {
        NotSupplierAccommodationsTree = new STRtree <SlimAccommodationData>();
        _supplierActiveAccommodations.Clear();
        _supplierInvalidAccommodations.Clear();
        _supplierDeprecatedToActivateAccommodations.Clear();

        await InitializeNotSupplierAccommodationsTree(supplier, countryCode, cancellationToken);
        await InitializeSupplierAccommodations(supplier, countryCode, cancellationToken);
        await InitializeActiveUncertainMatches(supplier, countryCode, cancellationToken);
    }
예제 #4
0
        public void TestRemoveSTRtree()
        {
            var tree = new STRtree <string>();

            tree.Insert(new Envelope(0, 10, 0, 10), "1");
            tree.Insert(new Envelope(5, 15, 5, 15), "2");
            tree.Insert(new Envelope(10, 20, 10, 20), "3");
            tree.Insert(new Envelope(15, 25, 15, 25), "4");
            Assert.DoesNotThrow(() => tree.Remove(new Envelope(10, 20, 10, 20), "4"));
            Assert.AreEqual(3, tree.Count);
        }
예제 #5
0
        private STRtree <Geometry> CreateTree(Geometry items)
        {
            var tree = new STRtree <Geometry>();

            for (int i = 0; i < items.NumGeometries; i++)
            {
                var item = items.GetGeometryN(i);
                tree.Insert(item.EnvelopeInternal, item);
            }

            return(tree);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static STRtree <FacetSequence> BuildSTRtree(Geometry g)
// ReSharper restore InconsistentNaming
        {
            var tree     = new STRtree <FacetSequence>(STRtreeNodeCapacity);
            var sections = ComputeFacetSequences(g);

            foreach (var section in sections)
            {
                tree.Insert(section.Envelope, section);
            }
            tree.Build();
            return(tree);
        }
        public void LoadMap()
        {
            using (var wad = WadReader.Read("freedoom2-udmf.wad"))
            {
                _map = new MapGeometry(MapData.LoadFrom(wad.GetTextmapStream("MAP28")));
            }

            _sectorBounds = new STRtree <int>();
            for (int sectorId = 0; sectorId < _map.Sectors.Length; sectorId++)
            {
                _sectorBounds.Insert(_map.GetSectorMinimumBoundingRectangle(sectorId), sectorId);
            }
            _sectorBounds.Build();
        }
        private static STRtree<IGeometry> BuildSTRtree(IGeometry geom)
        {
            var index = new STRtree<IGeometry>();
            geom.Apply(new DelegateGeometryFilter
            {
                DoFilter = delegate(IGeometry tmpGeometry)
                {
                    // only insert atomic geometries
                    if (tmpGeometry is IGeometryCollection) return;
                    index.Insert(tmpGeometry.EnvelopeInternal, tmpGeometry);
                }
            });

            return index;
        }
예제 #9
0
        //public static ISpatialIndex<IFeature> spatialIndex(IFeatureSet set)
        //{
        //    var tree = new STRtree<IFeature>(set.NumRows());

        //    foreach (var m in set.Features)
        //    {
        //        tree.Insert(m.Geometry.EnvelopeInternal, m);
        //    }

        //    tree.Build();
        //    return tree;
        //}

        public static ISpatialIndex <IFeature> spatialIndex(params IFeatureSet[] set)
        {
            var tree = new STRtree <IFeature>();

            foreach (var fs in set)
            {
                foreach (var m in fs.Features)
                {
                    tree.Insert(m.Geometry.EnvelopeInternal, m);
                }
            }

            tree.Build();
            return(tree);
        }
예제 #10
0
        public override void StartRun(int size)
        {
            Console.WriteLine($"----- Tree size: {size}");

            _index = new STRtree <object>(NODE_SIZE);
            int side = (int)Math.Sqrt(size);

            LoadGrid(side, _index);

            var sw = new Stopwatch();

            sw.Start();
            _index.Build();
            sw.Stop();
            Console.WriteLine($"Build time = {sw.ElapsedMilliseconds}ms");
        }
예제 #11
0
        public async Task <STRtree <SlimAccommodationData> > GetCountryAccommodationsTree(string countryCode,
                                                                                          string supplier, CancellationToken cancellationToken)
        {
            var countryAccommodations = new List <SlimAccommodationData>();
            var accommodations        = new List <SlimAccommodationData>();
            var skip = 0;

            do
            {
                accommodations = await _context.Accommodations.Where(ac => ac.CountryCode == countryCode &&
                                                                     !EF.Functions.JsonExists(ac.SupplierAccommodationCodes, supplier) &&
                                                                     ac.IsActive)
                                 .OrderBy(ac => ac.Id)
                                 .Skip(skip)
                                 .Take(_batchSize)
                                 .Select(ac => new SlimAccommodationData
                {
                    HtId    = ac.Id,
                    KeyData = ac.KeyData,
                    SupplierAccommodationCodes = ac.SupplierAccommodationCodes
                })
                                 .ToListAsync(cancellationToken);

                skip += _batchSize;
                countryAccommodations.AddRange(accommodations);
            } while (accommodations.Count > 0);

            if (!countryAccommodations.Any() || countryAccommodations.Count == 1)
            {
                return(new STRtree <SlimAccommodationData>());
            }

            var tree = new STRtree <SlimAccommodationData>(countryAccommodations.Count);

            foreach (var ac in countryAccommodations)
            {
                if (!ac.KeyData.Coordinates.IsEmpty() && ac.KeyData.Coordinates.IsValid())
                {
                    tree.Insert(new Point(ac.KeyData.Coordinates.Longitude,
                                          ac.KeyData.Coordinates.Latitude).EnvelopeInternal, ac);
                }
            }

            tree.Build();
            return(tree);
        }
예제 #12
0
        public void TestStrIndex()
        {
            STRtree ndx = new STRtree();

            foreach (var v in CreateTestGeometries(1000, 0.0, 0.0, 3000.0, 3000.0))
            {
                ndx.Insert(v.EnvelopeInternal, v);
            }

            ndx.Build();
            IEnvelope queryExtents = new Envelope(100.0, 120.0, 100.0, 120.0);
            IList     matches      = ndx.Query(queryExtents);

            foreach (IGeometry list in matches)
            {
                Assert.IsTrue(list.EnvelopeInternal.Intersects(queryExtents), "a result from the index does not intersect the query bounds");
            }
        }
예제 #13
0
        private static STRtree <Geometry> BuildSTRtree(Geometry geom)
        {
            var index = new STRtree <Geometry>();

            geom.Apply(new DelegateGeometryFilter
            {
                DoFilter = delegate(Geometry tmpGeometry)
                {
                    // only insert atomic geometries
                    if (tmpGeometry is GeometryCollection)
                    {
                        return;
                    }
                    index.Insert(tmpGeometry.EnvelopeInternal, tmpGeometry);
                }
            });

            return(index);
        }
예제 #14
0
        public static STRtree <string> Build(IEnumerable <NatureAreaDto> natureAreas)
        {
            var stRtree = new STRtree <string>();

            var parsedEnvelopes = new ConcurrentDictionary <string, Envelope>();

            Parallel.ForEach(natureAreas, (na) =>
            {
                var envelopeGeometry = ReadWkt(na.Envelope);
                parsedEnvelopes.TryAdd(CodePrefixes.GetNatureAreaCode(na.Id), envelopeGeometry);
            });

            foreach (var kvp in parsedEnvelopes)
            {
                stRtree.Insert(kvp.Value, kvp.Key);
            }

            return(stRtree);
        }
예제 #15
0
        /// <summary>
        /// Setup for element-search
        /// </summary>
        public void SetupElementSearch()
        {
#if NTS173
            _elementSearchTree = new STRtree();
#else
            _elementSearchTree = new STRtree <MeshElement>();
#endif
            for (int i = 0; i < _mesh.Elements.Count; i++)
            {
                MeshElement element = _mesh.Elements[i];
                double      x       = element.Nodes[0].X;
                double      y       = element.Nodes[0].Y;
                Envelope    extent  = new Envelope(x, x, y, y);
                for (int j = 1; j < element.Nodes.Count; j++)
                {
                    extent.ExpandToInclude(element.Nodes[j].X, element.Nodes[j].Y);
                }
                _elementSearchTree.Insert(extent, element);
            }
        }
예제 #16
0
        internal PointCollection RemoveNear(LineGraph roads, double minDis)
        {
            if (roads.nodes.Count == 0)
            {
                return(this);
            }
            var rtree = new STRtree <LineString>();

            foreach (var node in roads.nodes)
            {
                foreach (var next in node.nextConnections)
                {
                    Coordinate[] coords = new Coordinate[] { new Coordinate(node.pos.X, node.pos.Y), new Coordinate(next.pos.X, next.pos.Y) };
                    LineString   ls     = new LineString(coords);
                    rtree.Insert(ls.EnvelopeInternal, ls);
                }
            }
            rtree.Build();
            List <Vector2d> newpoints = new List <Vector2d>();

            foreach (var x in points)
            {
                bool isNear = false;
                foreach (var ls in rtree.Query(new Envelope(x.X - minDis, x.X + minDis, x.Y - minDis, x.Y + minDis)))
                {
                    if (ls.IsWithinDistance(new NetTopologySuite.Geometries.Point(x.X, x.Y), minDis))
                    {
                        isNear = true;
                        break;
                    }
                }
                if (!isNear)
                {
                    newpoints.Add(x);
                }
            }
            points = newpoints;
            return(this);
        }
예제 #17
0
        public static void AddGeomToCache(string table, int id, SqlGeometry geom)
        {
            if (!_geomCacheByTableThenId.ContainsKey(table))
            {
                _geomCacheByTableThenId[table]             = new Dictionary <int, SqlGeometry>();
                _geomEnvelopeAreaCacheByTableThenId[table] = new Dictionary <int, double>();
                _geomCentroidCacheByTableThenId[table]     = new Dictionary <int, Models.Geometry.Point>();
                _spatialIndexSTR[table] = new STRtree <int>();
            }

            SqlGeometry envelope = geom.STEnvelope();
            Envelope    env      = new Envelope(envelope.STPointN(1).STX.Value, envelope.STPointN(3).STX.Value, envelope.STPointN(1).STY.Value, envelope.STPointN(3).STY.Value);

            _geomCacheByTableThenId[table][id]             = geom;
            _geomEnvelopeAreaCacheByTableThenId[table][id] = envelope.STArea().Value;

            SqlGeometry envelopeCentroid = envelope.STCentroid().STPointN(1);

            _geomCentroidCacheByTableThenId[table][id] = new Models.Geometry.Point((float)envelopeCentroid.STX.Value, (float)envelopeCentroid.STY.Value);


            _spatialIndexSTR[table].Insert(env, id);
        }
예제 #18
0
        private void CheckPiles(List <Pile> piles)
        {
            STRtree <Pile> rtree = new STRtree <Pile> ();

            foreach (var p in piles)
            {
                var r = getPileEnvelope(p);
                rtree.Insert(r, p);
            }

            var minLenAbs = Options.PileSide * PileOptions.PileRatioLmin;
            var minLen    = minLenAbs - 0.1;

            List <Pile> pilesErrMinLen = new List <Pile>();

            foreach (var p in piles)
            {
                var envelope    = new Envelope(p.Position.X - minLen, p.Position.X + minLen, p.Position.Y - minLen, p.Position.Y + minLen);
                var pilesMinLen = rtree.Query(envelope);
                foreach (var item in pilesMinLen)
                {
                    if (p == item)
                    {
                        continue;
                    }
                    if (p.Position.DistanceTo(item.Position) < minLen)
                    {
                        pilesErrMinLen.Add(p);
                    }
                }
            }
            foreach (var item in pilesErrMinLen)
            {
                Inspector.AddError($"Нарушено минимальное расстояние между сваями - Сторона сваи * {PileOptions.PileRatioLmin} = {minLenAbs}. Точка вставки сваи {item.Position}",
                                   item.IdBlRef, System.Drawing.SystemIcons.Warning);
            }
        }
예제 #19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MCIndexPointSnapper"/> class.
 /// </summary>
 /// <param name="index"></param>
 public MCIndexPointSnapper(ISpatialIndex <MonotoneChain> index)
 {
     //_monoChains = monoChains;
     _index = (STRtree <MonotoneChain>)index;
 }
 /// <summary>
 /// Creates a new distance-finding instance for a given target <see cref="Geometry"/>.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Distances will be computed to all facets of the input geometry.
 /// The facets of the geometry are the discrete segments and points
 /// contained in its components.  </para>
 /// <para>
 /// In the case of <see cref="ILineal"/> and <see cref="IPuntal"/> inputs,
 /// this is equivalent to computing the conventional distance.
 /// </para><para>
 /// In the case of <see cref="IPolygonal"/> inputs, this is equivalent
 /// to computing the distance to the polygon boundaries.
 /// </para>
 /// </remarks>
 /// <param name="g1">A Geometry, which may be of any type.</param>
 public IndexedFacetDistance(Geometry g1)
 {
     baseGeometry = g1;
     _cachedTree  = FacetSequenceTreeBuilder.BuildSTRtree(g1);
 }
        /// <summary>
        /// Computes the union of the input geometries.
        /// </summary>
        /// <returns>
        /// <remarks>
        /// This method discards the input geometries as they are processed.
        /// In many input cases this reduces the memory retained
        /// as the operation proceeds. 
        /// Optimal memory usage is achieved 
        /// by disposing of the original input collection 
        /// before calling this method.
        /// </remarks>
        /// The union of the input geometries,
        /// or <c>null</c> if no input geometries were provided
        /// </returns>
        /// <exception cref="InvalidOperationException">if this method is called more than once</exception>
        public IGeometry Union()
        {
            if (_inputPolys == null)
                throw new InvalidOperationException("Union() method cannot be called twice");
            if (_inputPolys.Count == 0)
                return null;
            _geomFactory = Factory();

            /*
             * A spatial index to organize the collection
             * into groups of close geometries.
             * This makes unioning more efficient, since vertices are more likely 
             * to be eliminated on each round.
             */
            var index = new STRtree<object>(StrtreeNodeCapacity);
            foreach (IGeometry item in _inputPolys)
                index.Insert(item.EnvelopeInternal, item);

            // To avoiding holding memory remove references to the input geometries,
            _inputPolys = null;

            var itemTree = index.ItemsTree();
            var unionAll = UnionTree(itemTree);
            return unionAll;
        }
예제 #22
0
 protected override void Init_internal()
 {
     NTSSTRTreeCellTree = new STRtree <Cell>();
 }
예제 #23
0
 // TODO: somehow merge this with DoIntersections all in one pass elegantly
 // this method is called before all of these maps get added together
 // it will detect and remove shapes found inside each other
 public static void FixLoops(List<SectorConstrainedOSMAreaGraph> addingMaps, BlobCollection blobs)
 {
     // TODO: I think we still need to exclude intersecting loops from our thing
     STRtree<LoopRef> rtree = new STRtree<LoopRef>();
     List<MainLoopRef> mainLoopRefs = new List<MainLoopRef>();
     HashSet<AreaNode> explored = new HashSet<AreaNode>();
     foreach (var addingMap in addingMaps)
     {
         foreach (var nodeList in addingMap.nodes.Values)
         {
             foreach (var node in nodeList)
             {
                 if (explored.Contains(node)) continue;
                 List<AreaNode> newLoop = new List<AreaNode>();
                 AreaNode curr = node;
                 while (true)
                 {
                     newLoop.Add(curr);
                     explored.Add(curr);
                     if (curr.next == node)
                     {
                         mainLoopRefs.Add(new MainLoopRef() { nodes = newLoop, graph = addingMap });
                         break;
                     }
                     curr = curr.next;
                 }
             }
         }
     }
     foreach (var loopRef in mainLoopRefs)
     {
         loopRef.isCW = GetArea(loopRef.nodes, blobs) < 0;
     }
     foreach (var loopRef in mainLoopRefs)
     {
         for (int i = 0; i < loopRef.nodes.Count; i++)
         {
             Vector2d pos1 = blobs.nodes[loopRef.nodes[i].id];
             Vector2d pos2 = blobs.nodes[loopRef.nodes[(i + 1) % loopRef.nodes.Count].id];
             var env = new Envelope(Math.Min(pos1.X, pos2.X), Math.Max(pos1.X, pos2.X), Math.Min(pos1.Y, pos2.Y), Math.Max(pos1.Y, pos2.Y));
             rtree.Insert(env, new LoopRef() { nodes = loopRef.nodes, graph = loopRef.graph, v1 = pos1, v2 = pos2, n1 = loopRef.nodes[i].id, n2 = loopRef.nodes[(i + 1) % loopRef.nodes.Count].id, isCW = loopRef.isCW });
         }
     }
     rtree.Build();
     List<MainLoopRef> remove = new List<MainLoopRef>();
     foreach (var loopRef in mainLoopRefs)
     {
         HashSet<long> nodesLookup = new HashSet<long>();
         foreach (var n in loopRef.nodes) nodesLookup.Add(n.id);
         var node = blobs.nodes[loopRef.nodes.First().id];
         Vector2d v1 = new Vector2d(node.X, 10);
         Vector2d v2 = new Vector2d(node.X, -10);
         var env = new Envelope(node.X, node.X, -10, 10);
         var intersections = rtree.Query(env);
         bool doRemove = false;
         foreach (var group in intersections.GroupBy(x => x.graph))
         {
             bool isOwnGraph = group.First().graph == loopRef.graph;
             if (!isOwnGraph && group.Any(x => x.nodes.Any(y => nodesLookup.Contains(y.id)))) continue; // let's ignore WHOLE GRAPHS that intersect with us (might need to revise this thinking)
             var lessfiltered = group.Where(x => x.v1.X != x.v2.X).ToList(); // skip vertical intersections
             var sorted = lessfiltered.Where(x => Math.Min(x.v1.X, x.v2.X) != node.X).ToList(); // on perfect-overlap of adjoining lines, this will count things appropriately
             sorted = sorted.OrderBy(x => -Intersect(v1, v2, x.v1, x.v2).Y).ToList(); // order from bottom to top
             sorted = sorted.Where(x => x.nodes != loopRef.nodes).ToList(); // ignore our own loop
             List<int> prevSwaps = new List<int>();
             for (int i = 1; i < sorted.Count; i++)
             {
                 // swap perfectly adjacent if necessary
                 if ((sorted[i - 1].v2 == sorted[i].v1 && sorted[i - 1].v2.X == node.X && sorted[i - 1].V1Y() < sorted[i].V2Y()) || (sorted[i - 1].v1 == sorted[i].v2 && sorted[i - 1].v1.X == node.X && sorted[i - 1].V2Y() < sorted[i].V1Y()))
                 {
                     var temp = sorted[i - 1];
                     sorted[i - 1] = sorted[i];
                     sorted[i] = temp;
                     prevSwaps.Add(i - 1);
                 }
             }
             var validateStack = new List<LoopRef>();
             var contains = new List<LoopRef>();
             if (sorted.Count % 2 != 0) throw new NotImplementedException(); // malformed shape
             for (int i = 0; i < sorted.Count; i++)
             {
                 bool outer = !sorted[i].isCW; // we will no longer be checking for outers immediately within outers, etc. because sometimes people mess up
                 bool opens = outer == sorted[i].IsLeftToRight();
                 if (opens)
                 {
                     validateStack.Add(sorted[i]);
                 }
                 else
                 {
                     if (validateStack.Last().nodes != sorted[i].nodes) throw new NotImplementedException(); // malformed shape
                     if (Intersect(v1, v2, validateStack.Last().v1, validateStack.Last().v2).Y > node.Y && Intersect(v1, v2, sorted[i].v1, sorted[i].v2).Y < node.Y)
                     {
                         contains.Add(sorted[i]); // add the one that's above it, sure
                     }
                     validateStack.RemoveAt(validateStack.Count - 1);
                 }
             }
             if (validateStack.Count > 0) throw new NotImplementedException(); // malformed shape
             // remove duplicates that overlap perfectly
             for (int i = sorted.Count - 1; i > 0; i--)
             {
                 if (sorted[i].ContainsNode(sorted[i - 1].v1) || sorted[i].ContainsNode(sorted[i - 1].v2))
                 {
                     Vector2d inCommon = sorted[i].ContainsNode(sorted[i - 1].v1) ? sorted[i - 1].v1 : sorted[i - 1].v2;
                     if (inCommon.X == node.X)
                     {
                         sorted.RemoveRange(i - 1, 2);
                         i -= 2;
                     }
                 }
             }
             if (contains.Count == 0 && isOwnGraph && loopRef.isCW) doRemove = true;
             if (contains.Count == 0) continue;
             var immediate = contains.First();
             if (isOwnGraph && immediate.isCW == loopRef.isCW) doRemove = true; // remove the outermost invalid loop
             if (!isOwnGraph && !immediate.isCW) doRemove = true; // remove anything immediately contained by an outer
         }
         if (doRemove) remove.Add(loopRef);
     }
     foreach (var r in remove)
     {
         foreach (var node in r.nodes)
         {
             r.graph.nodes[node.id].Remove(node);
             if (r.graph.nodes[node.id].Count == 0) r.graph.nodes.Remove(node.id);
         }
     }
 }
예제 #24
0
        public void TestKNearestNeighbors()
        {
            int topK               = 1000;
            int totalRecords       = 10000;
            var geometryFactory    = new GeometryFactory();
            var coordinate         = new Coordinate(10.1, -10.1);
            var queryCenter        = geometryFactory.CreatePoint(coordinate);
            int valueRange         = 1000;
            var testDataset        = new List <Geometry>();
            var correctData        = new List <Geometry>();
            var random             = new Random();
            var distanceComparator = new GeometryDistanceComparer(queryCenter, true);

            /*
             * Generate the random test data set
             */
            for (int i = 0; i < totalRecords; i++)
            {
                coordinate = new Coordinate(-100 + random.Next(valueRange) * 1.1, random.Next(valueRange) * (-5.1));
                var spatialObject = geometryFactory.CreatePoint(coordinate);
                testDataset.Add(spatialObject);
            }

            /*
             * Sort the original data set and make sure the elements are sorted in an ascending order
             */
            testDataset.Sort(distanceComparator);

            /*
             * Get the correct top K
             */
            for (int i = 0; i < topK; i++)
            {
                correctData.Add(testDataset[i]);
            }

            var strtree = new STRtree <Geometry>();

            for (int i = 0; i < totalRecords; i++)
            {
                strtree.Insert(testDataset[i].EnvelopeInternal, testDataset[i]);
            }

            /*
             * Shoot a random query to make sure the STR-Tree is built.
             */
            strtree.Query(new Envelope(1 + 0.1, 1 + 0.1, 2 + 0.1, 2 + 0.1));

            /*
             * Issue the KNN query.
             */
            var testTopK = strtree.NearestNeighbour(queryCenter.EnvelopeInternal, queryCenter,
                                                    new GeometryItemDistance(), topK);
            var topKList = new List <Geometry>(testTopK);

            topKList.Sort(distanceComparator);

            /*
             * Check the difference between correct result and test result. The difference should be 0.
             */
            int difference = 0;

            for (int i = 0; i < topK; i++)
            {
                if (distanceComparator.Compare(correctData[i], topKList[i]) != 0)
                {
                    difference++;
                }
            }

            Assert.That(difference, Is.Zero);
        }
예제 #25
0
 public STRtreeIndex(int nodeCapacity)
 {
     _index = new STRtree <T>(nodeCapacity);
 }
예제 #26
0
 internal static void DoIntersections(BlobCollection blobs)
 {
     Dictionary<string, long> uids = new Dictionary<string, long>(); // finally decided I needed something to guarantee uniqueness like this TODO: can probably eliminate this
     long uidCounter = -1000;
     List<Way> ways = TempGetWays(blobs);
     ways.Add(blobs.borderWay);
     List<WayRef> wayRefs = new List<WayRef>();
     STRtree<WayRef> rtree = new STRtree<WayRef>();
     foreach (var way in ways)
     {
         for (int i = 1; i < way.refs.Count; i++)
         {
             WayRef wayRef = new WayRef() { wayRef = way, nodePos = i - 1 };
             wayRefs.Add(wayRef);
             Vector2d pos1 = blobs.nodes[way.refs[i - 1]];
             Vector2d pos2 = blobs.nodes[way.refs[i]];
             var env = new Envelope(Math.Min(pos1.X, pos2.X), Math.Max(pos1.X, pos2.X), Math.Min(pos1.Y, pos2.Y), Math.Max(pos1.Y, pos2.Y));
             rtree.Insert(env, wayRef);
         }
     }
     rtree.Build();
     Dictionary<Way, List<NewIntersection>> intersections = new Dictionary<Way, List<NewIntersection>>();
     foreach (var n1 in wayRefs)
     {
         Vector2d pos1 = blobs.nodes[n1.wayRef.refs[n1.nodePos]];
         Vector2d pos2 = blobs.nodes[n1.wayRef.refs[n1.nodePos + 1]];
         var env = new Envelope(Math.Min(pos1.X, pos2.X), Math.Max(pos1.X, pos2.X), Math.Min(pos1.Y, pos2.Y), Math.Max(pos1.Y, pos2.Y));
         foreach (var n2 in rtree.Query(env))
         {
             if (n1.GetHashCode() <= n2.GetHashCode()) continue; // as a way of preventing the same query twice
             long Aid = n1.wayRef.refs[n1.nodePos];
             long Bid = n1.wayRef.refs[n1.nodePos + 1];
             long Cid = n2.wayRef.refs[n2.nodePos];
             long Did = n2.wayRef.refs[n2.nodePos + 1];
             Vector2d A = blobs.nodes[Aid];
             Vector2d B = blobs.nodes[Bid];
             Vector2d C = blobs.nodes[Cid];
             Vector2d D = blobs.nodes[Did];
             if (Math.Min(A.X, B.X) > Math.Max(C.X, D.X)) continue;
             if (Math.Max(A.X, B.X) < Math.Min(C.X, D.X)) continue;
             if (Math.Min(A.Y, B.Y) > Math.Max(C.Y, D.Y)) continue;
             if (Math.Max(A.Y, B.Y) < Math.Min(C.Y, D.Y)) continue;
             string intersectionKey = Aid + "," + Cid;
             // TODO: we're going to treat -1 as always matching for now
             bool ACSame = Aid == Cid;
             bool ADSame = Aid == Did;
             bool BCSame = Bid == Cid;
             bool BDSame = Bid == Did;
             // a subset of possible tiny angles that can cause rounding errors
             // only thing that changes between these is the condition, line direction, and the newpoint id
             // TODO: is this really what fixed the nonsense at 240202043? the angleDiff was only 0.009, which seems too big to cause an issue
             bool someCollinear = false;
             bool isBorderIntersection = Aid < 0 || Bid < 0 || Cid < 0 || Did < 0;
             someCollinear |= CheckCollinear(Aid, n2.nodePos, n2.nodePos + 1, n2, intersections, blobs, true, isBorderIntersection);
             someCollinear |= CheckCollinear(Bid, n2.nodePos, n2.nodePos + 1, n2, intersections, blobs, true, isBorderIntersection);
             someCollinear |= CheckCollinear(Cid, n1.nodePos, n1.nodePos + 1, n1, intersections, blobs, true, isBorderIntersection);
             someCollinear |= CheckCollinear(Did, n1.nodePos, n1.nodePos + 1, n1, intersections, blobs, true, isBorderIntersection);
             if (!ACSame && !ADSame && !BCSame && !BDSame) // proper intersection
             {
                 if (someCollinear)
                 {
                     if (n1.wayRef.id == n2.wayRef.id)
                     {
                         n1.wayRef.selfIntersects = true; // mark for destruction, probably
                     }
                 }
                 else
                 {
                     // let's sort these lines to guarantee duplicates by value
                     long[] ns = new long[] { Aid, Bid, Cid, Did };
                     if (ns[0] >= ns[2]) ns = ns.Reverse().ToArray();
                     if (ns[0] >= ns[1])
                     {
                         var t = ns[1];
                         ns[1] = ns[0];
                         ns[0] = t;
                     }
                     if (ns[2] >= ns[3])
                     {
                         var t = ns[3];
                         ns[3] = ns[2];
                         ns[2] = t;
                     }
                     Vector2d intersection = Intersect(blobs.nodes[ns[0]], blobs.nodes[ns[1]], blobs.nodes[ns[2]], blobs.nodes[ns[3]]);
                     if (intersection != null)
                     {
                         long intersectionID;
                         if (uids.ContainsKey(intersectionKey))
                         {
                             intersectionID = uids[intersectionKey];
                         }
                         else
                         {
                             intersectionID = uidCounter--;
                             uids[intersectionKey] = intersectionID;
                         }
                         NewIntersection newNode1 = new NewIntersection() { nodeID = intersectionID, wayRef = n1.wayRef, nodePos = n1.nodePos + 1 };
                         NewIntersection newNode2 = new NewIntersection() { nodeID = intersectionID, wayRef = n2.wayRef, nodePos = n2.nodePos + 1 };
                         blobs.nodes[intersectionID] = intersection;
                         if (!intersections.ContainsKey(n1.wayRef)) intersections.Add(n1.wayRef, new List<NewIntersection>());
                         intersections[n1.wayRef].Add(newNode1);
                         if (!intersections.ContainsKey(n2.wayRef)) intersections.Add(n2.wayRef, new List<NewIntersection>());
                         intersections[n2.wayRef].Add(newNode2);
                         if (n1.wayRef.id == n2.wayRef.id)
                         {
                             n1.wayRef.selfIntersects = true; // mark for destruction, probably
                         }
                     }
                 }
             }
         }
     }
     List<long> wayids = new List<long>();
     foreach (var pair in intersections)
     {
         if (wayids.Contains(pair.Key.id)) throw new NotImplementedException();
         wayids.Add(pair.Key.id);
     }
     foreach (var pair in intersections)
     {
         foreach (var intersection in pair.Value)
         {
             intersection.sortRank = Sorter(intersection, blobs);
         }
     }
     foreach (var pair in intersections)
     {
         var sorted = pair.Value.OrderBy(x => x.sortRank).ToList();
         // get rid of duplicates
         for (int i = sorted.Count - 1; i > 0; i--)
         {
             if (sorted[i].nodeID == sorted[i - 1].nodeID) sorted.RemoveAt(i);
         }
         // now insert them
         for (int i = sorted.Count - 1; i >= 0; i--)
         {
             pair.Key.refs.Insert(sorted[i].nodePos, sorted[i].nodeID);
         }
     }
     RemoveDuplicates(blobs); // remove duplicates at the end to also remove duplicate intersections
 }
예제 #27
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MCIndexPointSnapper"/> class.
 /// </summary>
 /// <param name="monoChains"></param>
 /// <param name="index"></param>
 public MCIndexPointSnapper(IList monoChains, ISpatialIndex index)
 {
     this.monoChains = monoChains;
     this.index      = (STRtree)index;
 }
예제 #28
0
 protected override void Clean_internal()
 {
     NTSSTRTreeCellTree = null;
 }
예제 #29
0
        // special case for streets

        public static bool CheckForIntersection(Geometry geometry, STRtree <Geometry> possibleIntersections)
        {
            return(possibleIntersections.Query(geometry.EnvelopeInternal).Any(x => x.Intersects(geometry)));
        }