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;
        }