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."); }
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); }