public ActionResult Index(string q, string city, string lat, string @long, string miles, string count) { IList<SelectListItem> listOfMiles = new List<SelectListItem> { new SelectListItem {Text = "50", Value = "50"}, new SelectListItem {Text = "100", Value = "100"} }; IList<SelectListItem> listOfCounts = new List<SelectListItem> { new SelectListItem {Text = "10", Value = "10"}, new SelectListItem {Text = "50", Value = "50"}, new SelectListItem {Text = "100", Value = "100"} }; ViewData["Miles"] = listOfMiles; ViewData["Counts"] = listOfCounts; var indexViewModel = new IndexViewModel { q = q, lat = lat, @long = @long }; var analyzer = new StandardAnalyzer(_luceneVersion); Query query; if (string.IsNullOrEmpty(q)) { query = new MatchAllDocsQuery(); } else { var multiFieldQueryParser = new MultiFieldQueryParser(_luceneVersion, _searchFields, analyzer); query = multiFieldQueryParser.Parse(q); } // create a distance query // https://svn.apache.org/repos/asf/incubator/lucene.net/trunk/test/contrib/Spatial/TestCartesian.cs double milesDouble = 100.0; int countInt = 50; double latitudeDouble; double longitudeDouble; if (!String.IsNullOrEmpty(miles)) { Double.TryParse(miles, out milesDouble); } if (!String.IsNullOrEmpty(count)) { int.TryParse(count, out countInt); } Double.TryParse(lat, out latitudeDouble); Double.TryParse(@long, out longitudeDouble); var distanceQuery = new DistanceQueryBuilder(latitudeDouble, longitudeDouble, milesDouble, LuceneIndexFieldMap.LatitudeField, LuceneIndexFieldMap.LongitudeField, CartesianTierPlotter.DefaltFieldPrefix, true); var dsort = new DistanceFieldComparatorSource(distanceQuery.DistanceFilter); var sort = new Sort(new SortField("foo", dsort, false)); var startTime = DateTime.Now; var distanceHelper = new DistanceHelper(); // search for documents { TopDocs topDocs = _indexSearcher.Search(query, distanceQuery.Filter, countInt, sort); indexViewModel.TotalHits = topDocs.TotalHits; foreach (ScoreDoc match in topDocs.ScoreDocs) { Document doc = _indexSearcher.Doc(match.doc); double prefixCodedToDouble = NumericUtils.PrefixCodedToDouble(doc.Get(LuceneIndexFieldMap.LatitudeField)); double codedToDouble = NumericUtils.PrefixCodedToDouble(doc.Get(LuceneIndexFieldMap.LongitudeField)); double distanceInKilometres = distanceHelper.DistanceInKilometres(latitudeDouble, longitudeDouble, prefixCodedToDouble, codedToDouble); var geo = new GeoName { Name = doc.Get(LuceneIndexFieldMap.FirstNameField), Asciiname = doc.Get(LuceneIndexFieldMap.CityField), FeatureClass = doc.Get(LuceneIndexFieldMap.FeatureClassField), FeatureCode = doc.Get(LuceneIndexFieldMap.FeatureCodeField), Latitude = prefixCodedToDouble, Longitude = codedToDouble, Timezone = doc.Get(LuceneIndexFieldMap.TimeZoneField), DistanceInKm = distanceInKilometres }; indexViewModel.SearchResults.Add(geo); } } indexViewModel.SearchTimeMs = DateTime.Now.Subtract(startTime).TotalMilliseconds; return View(indexViewModel); }
private IList<GeoName> GetDestinations(string countryCode) { IList<GeoName> names = new List<GeoName>(); //http://download.geonames.org/export/dump/ HttpContext context = HttpContext.Current; string filePath = context.Server.MapPath(String.Format("~/App_Data/{0}.txt", countryCode)); using (TextReader tr = File.OpenText(filePath)) { string line; while ((line = tr.ReadLine()) != null) { string[] columns = line.Split('\t'); /* The main 'geoname' table has the following fields : --------------------------------------------------- 0 geonameid : integer id of record in geonames database 1 - name : name of geographical point (utf8) varchar(200) 2 - asciiname : name of geographical point in plain ascii characters, varchar(200) 3 - alternatenames : alternatenames, comma separated varchar(5000) 4 - latitude : latitude in decimal degrees (wgs84) 5 - longitude : longitude in decimal degrees (wgs84) 6 - feature class : see http://www.geonames.org/export/codes.html, char(1) 7 - feature code : see http://www.geonames.org/export/codes.html, varchar(10) 8 - country code : ISO-3166 2-letter country code, 2 characters 9 - cc2 : alternate country codes, comma separated, ISO-3166 2-letter country code, 60 characters 10 - admin1 code : fipscode (subject to change to iso code), see exceptions below, see file admin1Codes.txt for display names of this code; varchar(20) 11 - admin2 code : code for the second administrative division, a county in the US, see file admin2Codes.txt; varchar(80) 12 - admin3 code : code for third level administrative division, varchar(20) 13 - admin4 code : code for fourth level administrative division, varchar(20) 14 - population : bigint (8 byte int) 15 - elevation : in meters, integer 16 - gtopo30 : average elevation of 30''x30'' (ca 900mx900m) area in meters, integer 17 - timezone : the timezone id (see file timeZone.txt) 18 - modification date : date of last modification in yyyy-MM-dd format */ var geoName = new GeoName { Asciiname = columns[2].Trim(), FeatureClass = columns[6].Trim(), FeatureCode = columns[7].Trim(), Timezone = columns[17].Trim() }; double latitude; if (Double.TryParse(columns[4], out latitude)) { geoName.Latitude = latitude; } double longitude; if (Double.TryParse(columns[5], out longitude)) { geoName.Longitude = longitude; } names.Add(geoName); } tr.Close(); } return names; }