Esempio n. 1
0
        /// <summary>
        /// Given a normalized coordinate in multiple dimensions, calculate its derived key for given level
        /// </summary>
        private long?DerivedValueFor(long[] normalizedValues, int level)
        {
            AssertValidLevel(level);
            long derivedValue = 0;
            long mask         = 1L << (_maxLevel - 1);

            // The starting curve depends on the dimensions
            CurveRule currentCurve = RootCurve();

            for (int i = 1; i <= _maxLevel; i++)
            {
                int bitIndex = _maxLevel - i;
                int npoint   = 0;

                foreach (long val in normalizedValues)
                {
                    npoint = npoint << 1 | ( int )((val & mask) >> bitIndex);
                }

                int derivedIndex = currentCurve.IndexForNPoint(npoint);
                derivedValue = (derivedValue << _nbrDim) | derivedIndex;
                mask         = mask >> 1;
                currentCurve = currentCurve.ChildAt(derivedIndex);
            }

            if (level < _maxLevel)
            {
                derivedValue = derivedValue << (_nbrDim * _maxLevel - level);
            }
            return(derivedValue);
        }
Esempio n. 2
0
        /// <summary>
        /// Given a derived key, find the normalized coordinate it corresponds to on a specific level
        /// </summary>
        internal virtual long[] NormalizedCoordinateFor(long derivedValue, int level)
        {
            AssertValidLevel(level);
            long mask = _initialNormMask;

            long[] coordinate = new long[_nbrDim];

            // First level is a single curveUp
            CurveRule currentCurve = RootCurve();

            for (int i = 1; i <= level; i++)
            {
                int bitIndex = _maxLevel - i;

                int   derivedIndex = ( int )((derivedValue & mask) >> bitIndex * _nbrDim);
                int   npoint       = currentCurve.NpointForIndex(derivedIndex);
                int[] bitValues    = bitValues(npoint);

                for (int dim = 0; dim < _nbrDim; dim++)
                {
                    coordinate[dim] = coordinate[dim] << 1 | bitValues[dim];
                }

                mask         = mask >> _nbrDim;
                currentCurve = currentCurve.ChildAt(derivedIndex);
            }

            if (level < _maxLevel)
            {
                for (int dim = 0; dim < _nbrDim; dim++)
                {
                    coordinate[dim] = coordinate[dim] << _maxLevel - level;
                }
            }

            return(coordinate);
        }
Esempio n. 3
0
        private void AddTilesIntersectingEnvelopeAt(SpaceFillingCurveConfiguration config, SpaceFillingCurveMonitor monitor, int depth, int maxDepth, SearchEnvelope search, SearchEnvelope currentExtent, CurveRule curve, long left, long right, List <LongRange> results)
        {
            if (right - left == 1)
            {
                long[] coord = NormalizedCoordinateFor(left, _maxLevel);
                if (search.Contains(coord))
                {
                    LongRange current = (results.Count > 0) ? results[results.Count - 1] : null;
                    if (current != null && current.Max == left - 1)
                    {
                        current.ExpandToMax(left);
                    }
                    else
                    {
                        current = new LongRange(left);
                        results.Add(current);
                    }
                    if (monitor != null)
                    {
                        monitor.AddRangeAtDepth(depth);
                        monitor.AddToCoveredArea(currentExtent.Area);
                    }
                }
            }
            else if (search.Intersects(currentExtent))
            {
                double overlap = search.FractionOf(currentExtent);
                if (config.StopAtThisDepth(overlap, depth, maxDepth))
                {
                    // Note that LongRange upper bound is inclusive, hence the '-1' in several places
                    LongRange current = (results.Count > 0) ? results[results.Count - 1] : null;
                    if (current != null && current.Max == left - 1)
                    {
                        current.ExpandToMax(right - 1);
                    }
                    else
                    {
                        current = new LongRange(left, right - 1);
                        results.Add(current);
                    }
                    if (monitor != null)
                    {
                        monitor.AddRangeAtDepth(depth);
                        monitor.AddToCoveredArea(currentExtent.Area);
                    }
                }
                else
                {
                    long width = (right - left) / _quadFactor;
                    for (int i = 0; i < _quadFactor; i++)
                    {
                        int npoint = curve.NpointForIndex(i);

                        SearchEnvelope quadrant = currentExtent.Quadrant(BitValues(npoint));
                        AddTilesIntersectingEnvelopeAt(config, monitor, depth + 1, maxDepth, search, quadrant, curve.ChildAt(i), left + i * width, left + (i + 1) * width, results);
                    }
                }
            }
        }