コード例 #1
0
ファイル: WorldIndexTests.cs プロジェクト: formist/LinkMe
        public void Within50KmFromMelbourne3000()
        {
            // The region Melbourne was initially defined to be 50km from 3000 so make
            // sure this still holds for now.

            var    locationReference = _locationQuery.ResolveLocation(_australia, "Melbourne");
            Region melbourneMetro    = locationReference.Region;

            locationReference = _locationQuery.ResolveLocation(_australia, "Melbourne VIC 3000");
            Locality melbourne3000 = locationReference.Locality;

            double   distMax    = 0;
            Locality mostRemote = null;

            foreach (Locality locality in _locationQuery.GetLocalities(melbourneMetro))
            {
                double dist = WorldIndex.EarthDistance(
                    melbourne3000.Centroid.Latitude, melbourne3000.Centroid.Longitude,
                    locality.Centroid.Latitude, locality.Centroid.Longitude);

                if (dist > distMax)
                {
                    distMax    = dist;
                    mostRemote = locality;
                }
            }

            Assert.IsTrue(distMax <= 50, "The '" + mostRemote.Name + "' locality has a distance + " + distMax + "km which is more than 50km away from Melbourne VIC 3000.");
        }
コード例 #2
0
ファイル: WorldIndex.cs プロジェクト: formist/LinkMe
        public void BuildUp(ILocationQuery locationQuery, bool includeDistances)
        {
            Clear();

            // Create points in our metric space.
            // The points are Localities and empty Countries.
            // The distance between an empty countries and any other entity is presumed to be infinite.

            var localities     = new List <Locality>();
            var emptyCountries = new List <Country>();

            foreach (var country in locationQuery.GetCountries())
            {
                var countryLocalities = locationQuery.GetLocalities(country);
                if (countryLocalities.Count > 0)
                {
                    localities.AddRange(countryLocalities);
                }
                else
                {
                    emptyCountries.Add(country);
                }
            }

            _localityCount = localities.Count;
            var pointCount = localities.Count + emptyCountries.Count;

            _points = Enumerable.Range(0, pointCount);

            if (includeDistances)
            {
                // Calculate distances between localities.

                _distances = new short[_localityCount][];

                for (var i = 0; i < _localityCount; i++)
                {
                    _distances[i] = new short[i];

                    for (var j = 0; j < i; j++)
                    {
                        _distances[i][j] = (short)Math.Round(EarthDistance(
                                                                 localities[i].Centroid.Latitude,
                                                                 localities[i].Centroid.Longitude,
                                                                 localities[j].Centroid.Latitude,
                                                                 localities[j].Centroid.Longitude));
                    }
                }
            }

            // Add Localities.

            _subsets = new Dictionary <int, HashSet <int> >();

            for (var i = 0; i < _localityCount; i++)
            {
                var subset = new HashSet <int> {
                    i
                };
                _subsets.Add(localities[i].Id, subset);
            }

            // Add empty Countries.

            for (var i = 0; i < emptyCountries.Count; i++)
            {
                var subset = new HashSet <int> {
                    _localityCount + i
                };
                _subsets.Add(emptyCountries[i].Id, subset);
            }

            // Add CountrySubdivisions.

            foreach (var locality in localities)
            {
                foreach (var countrySubdivision in locality.CountrySubdivisions)
                {
                    HashSet <int> subset;
                    if (!_subsets.TryGetValue(countrySubdivision.Id, out subset))
                    {
                        subset = new HashSet <int>();
                        _subsets.Add(countrySubdivision.Id, subset);
                    }

                    subset.Add(GetLocalityPoint(locality.Id));
                }
            }

#if DEBUG
            // Check that there are no empty CountrySubdivisions.

            foreach (var country in locationQuery.GetCountries())
            {
                foreach (var countrySubdivision in locationQuery.GetCountrySubdivisions(country))
                {
                    if (countrySubdivision.Id != 1)
                    {
                        Debug.Assert(_subsets[countrySubdivision.Id].Count > 0);
                    }
                }
            }
#endif

            // Add Countries.

            foreach (var country in locationQuery.GetCountries())
            {
                var subset = new HashSet <int>();

                foreach (var locality in locationQuery.GetLocalities(country))
                {
                    subset.Add(GetLocalityPoint(locality.Id));
                }

                if (subset.Count > 0)
                {
                    _subsets.Add(country.Id, subset);
                }
            }

            // Add Regions.

            foreach (var country in locationQuery.GetCountries())
            {
                foreach (var region in locationQuery.GetRegions(country))
                {
                    var subset = new HashSet <int>();

                    foreach (Locality locality in locationQuery.GetLocalities(region))
                    {
                        subset.Add(GetLocalityPoint(locality.Id));
                    }

                    Debug.Assert(subset.Count > 0);
                    _subsets.Add(region.Id, subset);
                }
            }

            _maxPointSetId = _subsets.Max(kvp => kvp.Key);
        }