Hi all, I've rejiggled the geosites updates as per Edd's suggestions. No new functionality; the main change is the introduction of a Locale class (and subclasses) which represent a place, and contain at least a city,region,country. This is used by e.g. the GeoSites backend. I've incorporated Clement's fix for US two-letter state codes (but I've moved it into the Locale class, since it might be generally useful to code that is interested in Locales). Finally, the GeoSites backend now chains placenames (as keywords). I think we ought to introduce a "place" cluetype for this kind of thing; nothing else is exactly appropriate. Feedback appreciated. My next plan is to do some work on the renderer (currently there doesn't seem to be one). Edd, do you have any suggestions (or code - I believe you had this going at one stage) for this one? Ideas welcome. dave
--- dashboard/backends/GeoSitesBackend.cs 2004-02-17 03:06:06.000000000 +0000 +++ dashboard-geo/backends/GeoSitesBackend.cs 2004-03-01 18:31:53.421069807 +0000 @@ -21,86 +21,134 @@ class GeoSites : Backend { private Gazetteer gazetteer; + private PostalDistrict postcodes; + private PhoneDistrict areacodes; public override bool Startup () { Console.WriteLine ("GeoSites backend starting"); Name = "GeoSites"; - this.SubscribeToClues ("latlong"); - this.Initialized = true; - gazetteer = new Gazetteer (); - return true; - } - - public Match GetMatch (Clue clue) - { - string txt = clue.Text; - string [] coords = Regex.Split(txt, "\\s*,\\s*"); + // ensure phone / postal district data gets loaded immediately + // this takes too long (a minute or so on a 1.2 GHz machine): FIXME + PhoneDistrict tmpPhone = new PhoneDistrict (""); + PostalDistrict tmpPostal = new PostalDistrict (""); - if (coords.Length != 2) - return null; + Console.WriteLine ("GeoSites backend ready"); - string lat = coords[0]; - string lng = coords[1]; + this.SubscribeToClues ("latlong", "phone", "address"); + this.Initialized = true; - double dlat = Double.Parse (lat); - double dlng = Double.Parse (lng); + return true; + } - int intlat = (int) dlat; - int intlng = (int) dlng; + public void GetMatches (Clue clue, BackendResult result) + { + ArrayList points = new ArrayList (); - Point p = gazetteer.NearestCity (dlat, dlng); - if (p == null) - return null; + double dlat = 0, dlng = 0; + String lat = "", lng = ""; - Match match = new Match ("Location", clue); - match ["City"] = p.City; - match ["Admin region"] = p.Adminregion; - match ["Country"] = p.Country; - - String vicinityurl = String.Format("http://www.vicinity.com/myblast/map.mb?CMD=LFILL&CT={0}:{1}:90000", lat, lng); - match ["MapBlast"] = vicinityurl; - - // yawn, special case for mapquest - if (p.Country == "United States of America") - { - p.Country = "United States"; + switch (clue.Type) { + case "latlong": + string txt = clue.Text; + string [] coords = Regex.Split(txt, "\\s*,\\s*"); + + if (coords.Length != 2) + return; + + lat = coords[0]; + lng = coords[1]; + + dlat = Double.Parse (lat); + dlng = Double.Parse (lng); + + City p = gazetteer.NearestCity (new LatLongPair (dlat, dlng)); + if (p == null) + return; + else + points.Add (p); + break; + case "phone": + /* FIXME: need to pass in country from the address if possible */ + points.Add (new PhoneDistrict (clue.Text)); + break; + case "address": + /* FIXME: need to pass in country from the address if possible */ + points.Add (new PostalDistrict (clue.Text)); + break; + default: + return; } - // FIXME: MapQuest requires the state name as a two - // letter code where the US is concerned. - String mapquesturl = String.Format ( - "http://www.mapquest.com/maps/map.adp?city={0}&state={1}&country={2}&zoom=5", - HttpUtility.UrlEncode(p.City), - HttpUtility.UrlEncode(p.Adminregion), - HttpUtility.UrlEncode(p.Country)); - match ["MapQuest"] = mapquesturl; + foreach (Locale p in points) { + // for debugging + Console.WriteLine("{0}",p.City); + Console.WriteLine("{0}",p.Adminregion); + Console.WriteLine("{0}",p.Country); + if (p.Position != null) + Console.WriteLine("{0},{1}",p.Position.Latitude, p.Position.Longitude); + + // core stuff + Match match = new Match ("Location", clue); + match ["City"] = p.City; + match ["Admin region"] = p.Adminregion; + match ["Country"] = p.Country; + + // stuff derived from lat/long + if (p.Position != null) { + dlat = p.Position.Latitude; + dlng = p.Position.Longitude; + + lat = Convert.ToString(dlat); + lng = Convert.ToString(dlng); + + int intlat = (int) dlat; + int intlng = (int) dlng; + + String vicinityurl = String.Format("http://www.vicinity.com/myblast/map.mb?CMD=LFILL&CT={0}:{1}:90000", lat, lng); + match ["MapBlast"] = vicinityurl; + + String degreeconfluenceurl = String.Format( + "http://www.confluence.org/confluence.php?lat={0}&lon={1}&visit=1", intlat, intlng); + match ["Degree Confluence"] = degreeconfluenceurl; + + String terraserverurl = String.Format("http://terraserver.com/coordinates2.asp?y={0}&x={1}", lat, lng); + match ["Terraserver"] = terraserverurl; + } + + String mapquesturl = "http://www.mapquest.com/maps/map.adp?city=" + HttpUtility.UrlEncode (p.City); + // yawn, special case for mapquest + if (p.Country == "United States of America") { + mapquesturl += "&state=" + HttpUtility.UrlEncode ((string)Locale.us_states [p.Adminregion]); + } else + mapquesturl += "&state=" + HttpUtility.UrlEncode (p.Adminregion); + mapquesturl += "&country=" + HttpUtility.UrlEncode (p.Country == "United States of America" ? "United States" : p.Country) + "&zoom=5"; + match ["MapQuest"] = mapquesturl; - // yawn, special case for wunderground - // what is it with US-centricity? ;-p - String searchstring; - if (p.Country == "United States") - { - searchstring = String.Format("{0}, {1}", p.City, p.Adminregion); - } else { - searchstring = String.Format("{0}, {1}", p.City, p.Country); - } - String wundergroundurl = String.Format( - "http://www.wunderground.com/cgi-bin/findweather/getForecast?query={0}", - HttpUtility.UrlEncode(searchstring)); - match ["Weather"] = wundergroundurl; + // yawn, special case for wunderground + // what is it with US-centricity? ;-p + String searchstring; + if (p.Country == "United States") + { + searchstring = String.Format("{0}, {1}", p.City, p.Adminregion); + } else { + searchstring = String.Format("{0}, {1}", p.City, p.Country); + } + String wundergroundurl = String.Format( + "http://www.wunderground.com/cgi-bin/findweather/getForecast?query={0}", + HttpUtility.UrlEncode(searchstring)); + match ["Weather"] = wundergroundurl; - String degreeconfluenceurl = String.Format( - "http://www.confluence.org/confluence.php?lat={0}&lon={1}&visit=1", intlat, intlng); - match ["Degree Confluence"] = degreeconfluenceurl; - - String terraserverurl = String.Format("http://terraserver.com/coordinates2.asp?y={0}&x={1}", lat, lng); - match ["Terraserver"] = terraserverurl; + // Chain the city name as a new clue + // FIXME: we need to decide on the best cluetype, maybe "place" ? + Clue c = new Clue ("keyword", p.City + ", " + p.Adminregion, clue.Relevance, clue); + result.AddChainedClue (c); - return match; + result.AddMatch (match); + } } public override BackendResult ProcessCluePacket (CluePacket cp) @@ -114,7 +162,7 @@ if (c.Text.Length == 0) continue; - result.AddMatch (GetMatch (c)); + GetMatches (c, result); } return result; @@ -122,7 +170,7 @@ public static string Header (string title) { return String.Format ( - " <table border=\"0\" height=\"100%\" width=\"100%\" valign=\"center\"> <tr> <td>" + + " <table border=\"0\" height=\"100%\" width=\"100%\" valign=\"center\"> <tr> <td>" + " <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" align=\"center\" width=\"100%\">" + " <tr bgcolor=\"#000000\"> <td>" + " <table border=\"0\" cellspacing=\"1\" cellpadding=\"0\" width=\"100%\">" +
Attachment:
geo.patch.bz2
Description: application/bzip