GeoSitesBackend update



As I mentioned in my previous email, much of this code needed to be
moved into utils/geo/gazetteer. This version of the patch fixes this
problem.

I think it's now in good shape; probably the areacode data could do with
some extra fields (e.g. lat/long), but as it stands it generates matches
quite nicely.

dave
--- dashboard/backends/GeoSitesBackend.cs	2004-02-26 16:28:01.445324476 +0000
+++ dashboard-ac/backends/GeoSitesBackend.cs	2004-02-26 16:27:37.082850793 +0000
@@ -27,80 +27,105 @@
 			Console.WriteLine ("GeoSites backend starting");
 			Name = "GeoSites";
 
+			gazetteer = new Gazetteer ();
+
 			this.SubscribeToClues ("latlong");
+			this.SubscribeToClues ("phone");
+				
 			this.Initialized = true;
 
-			gazetteer = new Gazetteer ();
-
 			return true;
 		}
 
-		public Match GetMatch (Clue clue)
+		public ArrayList GetMatch (Clue clue)
 		{
-			string txt = clue.Text;
-			string [] coords = Regex.Split(txt, "\\s*,\\s*");
-
-			if (coords.Length != 2)
-				return null;
-
-			string lat = coords[0];
-			string lng = coords[1];
+			ArrayList points = new ArrayList (), matches = new ArrayList ();
 
-			double dlat = Double.Parse (lat);
-			double dlng = Double.Parse (lng);
+			double dlat = 0, dlng = 0;
+			String lat = "", lng = "";
 
-			int intlat = (int) dlat;
-			int intlng = (int) dlng;
-
-			Point p = gazetteer.NearestCity (dlat, dlng);
-			if (p == null)
-				return null;
-
-			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 null;
+
+				lat = coords[0];
+				lng = coords[1];
+
+				dlat = Double.Parse (lat);
+				dlng = Double.Parse (lng);
+
+				Point p = gazetteer.NearestCity (dlat, dlng);
+				if (p == null)
+					return null;
+				else
+					points.Add(p);
+				break;
+			case "phone":
+				points = gazetteer.LookupAreacode(clue.Text);
+				break;
 			}
 
-			// 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 (Point p in points) {
+				if (clue.Type == "phone") {
+					dlat = p.Latitude;
+					dlng = p.Longitude;
+					lat = Convert.ToString(p.Latitude);
+					lng = Convert.ToString(p.Longitude);
+				}
+				int intlat = (int) dlat;
+				int intlng = (int) dlng;
+
+				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";
+				}
+
+				// 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;
 			
-			// 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 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 terraserverurl = String.Format("http://terraserver.com/coordinates2.asp?y={0}&x={1}";, lat, lng);
+				match ["Terraserver"] = terraserverurl;
 
-			return match;
+				matches.Add (match);
+			}
+			return matches;
 		}
 
 		public override BackendResult ProcessCluePacket (CluePacket cp)
@@ -113,8 +138,9 @@
 			foreach (Clue c in cp.Clues) {
 				if (c.Text.Length == 0)
 					continue;
-
-				result.AddMatch (GetMatch (c));
+				// areacodes can generate multiple results (though they rarely do)
+				foreach (Match m in GetMatch (c))
+					result.AddMatch (m);
 			}
 
 			return result;
diff -Nur --exclude-from=exclude dashboard/util/geo/Makefile.am dashboard-ac/util/geo/Makefile.am
--- dashboard/util/geo/Makefile.am	2003-12-05 09:21:08.000000000 +0000
+++ dashboard-ac/util/geo/Makefile.am	2004-02-26 15:53:00.738244623 +0000
@@ -1,8 +1,11 @@
-
 CSC=mcs
 CSC_FLAGS=-g
 
-LIBS=-resource:cities.txt.gz -r:ICSharpCode.SharpZipLib
+AREACODES    := $(wildcard areacodes/areacodes.*.csv)
+AREACODES_GZ := $(foreach AREA,$(AREACODES),$(AREA).gz)
+AREACODES_RESOURCES := $(foreach AREA,$(AREACODES_GZ),-resource:$(AREA))
+
+LIBS=-resource:cities.txt.gz -r:ICSharpCode.SharpZipLib $(AREACODES_RESOURCES)
 
 DLL=geo.dll
 EXE=test.exe
@@ -15,17 +18,20 @@
 
 all: cities.txt.gz $(DLL) $(EXE) $(COMMON_DAT) $(INSTALL_KLUDGE)
 
-cities.txt.gz: $(srcdir)/cities.txt
-	gzip -c < $(srcdir)/cities.txt > cities.txt.gz
+%.gz: %
+	gzip --best -c < $^ > $@
+
+%.bz2: %
+	bzip2 -c < $^ > $@
 
-$(DLL): $(SRC)
-	$(CSC) $(CSC_FLAGS) $(LIBS) -target:library -out:$@ $^
+$(DLL): $(SRC) $(AREACODES_GZ)
+	$(CSC) $(CSC_FLAGS) $(LIBS) -target:library -out:$@ $<
 
-$(EXE): $(SRC)
-	$(CSC) $(CSC_FLAGS) $(LIBS) -target:exe -out:$@ $^
+$(EXE): $(SRC) $(AREACODES_GZ)
+	$(CSC) $(CSC_FLAGS) $(LIBS) -target:exe -out:$@ $<
 
 clean:
-	-rm -f *.dll *.exe cities.txt.gz
+	-rm -f *.dll *.exe cities.txt.gz $(AREACODES_GZ)
 
 $(INSTALL_KLUDGE): $(DLL)
 	@echo "Installing $(DLL) into ../../engine..."
@@ -37,5 +43,5 @@
 	$(mkinstalldirs) $(DESTDIR)$(dashboardlibdir)
 	$(INSTALL_DATA) $(DLL) $(DESTDIR)$(dashboardlibdir)
 
-EXTRA_DIST = $(SRC) $(srcdir)/cities.txt
+EXTRA_DIST = $(SRC) $(srcdir)/cities.txt $(AREACODES)
 
diff -Nur --exclude-from=exclude dashboard/util/geo/README dashboard-ac/util/geo/README
--- dashboard/util/geo/README	2003-07-27 17:01:21.000000000 +0100
+++ dashboard-ac/util/geo/README	2004-02-26 15:28:46.809707446 +0000
@@ -3,3 +3,5 @@
 
 It is copyright © by Stefan Helders.  For distribution terms, see the
 information given at http://www.world-gazetteer.com/info.htm#copyright
+
+Sources for the areacode data are given in the areacode files themselves.
diff -Nur --exclude-from=exclude dashboard/util/geo/areacodes/areacodes.uk.csv dashboard-ac/util/geo/areacodes/areacodes.uk.csv
--- dashboard/util/geo/areacodes/areacodes.uk.csv	1970-01-01 01:00:00.000000000 +0100
+++ dashboard-ac/util/geo/areacodes/areacodes.uk.csv	2004-02-25 21:29:27.000000000 +0000
@@ -0,0 +1,645 @@
+#United Kingdom
+#+44 0
+# Source: http://www.wiredwales.com/info.htm
+"01224","Aberdeen",""
+"01887","Aberfeldy",""
+"01873","Abergavenny",""
+"01970","Aberystwth",""
+"01235","Abingdon",""
+"01864","Abington",""
+"01339","Aboyne",""
+"01252","Aldershot",""
+"01975","Alford (Aberdeen)",""
+"01507","Alford (Lincs.)",""
+"01259","Alloa",""
+"01665","Alnwick",""
+"01420","Alton",""
+"01269","Ammanford",""
+"01264","Andover",""
+"01461","Annan",""
+"01849","Antrim",""
+"01768","Appleby",""
+"01241","Arbroath",""
+"01863","Ardgay",""
+"01294","Ardrossan",""
+"01861","Armagh",""
+"01301","Arrochar",""
+"01276","Ascot",""
+"01344","Ascot",""
+"01335","Ashbourne",""
+"01364","Ashburton",""
+"01233","Ashford",""
+"01953","Attleborough",""
+"01297","Axminster",""
+"01296","Aylesbury",""
+"01292","Ayr",""
+"01890","Ayton",""
+"01678","Bala",""
+"01855","Ballachulish",""
+"01339","Ballater",""
+"01807","Ballindalloch",""
+"01265","Ballycastle",""
+"01960","Ballyclare",""
+"01662","Ballygawley",""
+"01266","Ballymena",""
+"01265","Ballymoney",""
+"01820","Banbridge",""
+"01295","Banbury",""
+"01330","Banchory",""
+"01261","Banff",""
+"01247","Bangor (Co. Down)",""
+"01248","Bangor (N Wales)",""
+"01341","Barmouth",""
+"01833","Barnard Castle",""
+"01226","Barnsley",""
+"01271","Barnstable",""
+"01229","Barrow-in-Furness",""
+"01446","Barry",""
+"01256","Basingstoke",""
+"01225","Bath",""
+"01506","Bathgate",""
+"01677","Bedale",""
+"01234","Bedford",""
+"01232","Belfast",""
+"01668","Belford",""
+"01434","Bellingham",""
+"01870","Benbecula",""
+"01289","Berwick-on-Tweed",""
+"01690","Betws-y-Coed",""
+"01299","Bewdley",""
+"01869","Bicester",""
+"01237","Bideford",""
+"01899","Biggar",""
+"0121","Birmingham",""
+"01388","Bishop Auckland",""
+"01279","Bishops Stortford",""
+"01254","Blackburn",""
+"01253","Blackpool",""
+"01250","Blairgowrie",""
+"01258","Blandford",""
+"01208","Bodmin",""
+"01204","Bolton",""
+"01423","Boroughbridge",""
+"01205","Boston",""
+"01778","Bourne",""
+"01202","Bournemouth",""
+"01451","Bourton-on-the-Water",""
+"01274","Bradford",""
+"01376","Braintree",""
+"01697","Brampton",""
+"01598","Brayford",""
+"01356","Brechin",""
+"01874","Brecon",""
+"01277","Brentwood",""
+"01656","Bridgend",""
+"01746","Bridgnorth",""
+"01278","Bridgwater",""
+"01262","Bridlington",""
+"01308","Bridport",""
+"01652","Brigg",""
+"01273","Brighton",""
+"0117","Bristol",""
+"01471","Broadford",""
+"01770","Brodick",""
+"01885","Bromyard",""
+"01886","Bromyard",""
+"01508","Brooke",""
+"01280","Buckingham",""
+"01288","Bude",""
+"01395","Budleigh Salterton",""
+"01982","Builth Wells",""
+"01980","Bulford Camp",""
+"01986","Bungay",""
+"01425","Burley",""
+"01282","Burnley",""
+"01543","Burntwood",""
+"01283","Burton-on-Trent",""
+"01284","Bury-St-Edmunds",""
+"01298","Buxton",""
+"01286","Caernarvon",""
+"01223","Cambridge",""
+"01840","Camelford",""
+"01586","Campbeltown",""
+"01227","Canterbury",""
+"029","Cardiff",""
+"01239","Cardigan",""
+"01228","Carlisle",""
+"01267","Carmarthen",""
+"01583","Carradale",""
+"01662","Carrickmore",""
+"01556","Castle Douglas",""
+"01871","Castlebay",""
+"01650","Cemmaes Road",""
+"01300","Cerne Abbas",""
+"01460","Chard",""
+"01245","Chelmsford",""
+"01242","Cheltenham",""
+"01244","Chester",""
+"01246","Chesterfield",""
+"01243","Chichester",""
+"01249","Chippenham",""
+"01608","Chipping Norton",""
+"01694","Church Stretton",""
+"01285","Cirencester",""
+"01255","Clacton-on-Sea",""
+"01200","Clitheroe",""
+"01832","Clopton",""
+"01437","Clynderwen",""
+"01530","Coalville",""
+"01236","Coatbridge",""
+"01206","Colchester",""
+"01890","Coldstream",""
+"01265","Coleraine",""
+"01727","Colney Heath",""
+"01951","Colonsay",""
+"01492","Colwyn Bay",""
+"01260","Congleton",""
+"01207","Consett",""
+"01648","Cookstown",""
+"01257","Coppull",""
+"01490","Corwen",""
+"01828","Coupar Angus",""
+"024","Coventry",""
+"01340","Craigellachie",""
+"01680","Craignure",""
+"01580","Cranbrook",""
+"01588","Craven Arms",""
+"01363","Crediton",""
+"01270","Crewe",""
+"01764","Crieff",""
+"01263","Cromer",""
+"01290","Cumnock",""
+"01838","Dalmally",""
+"01889","Dapple Heath",""
+"01325","Darlington",""
+"01332","Derby",""
+"01362","Dereham",""
+"01380","Devizes",""
+"01349","Dingwall",""
+"01379","Diss",""
+"01485","Docking",""
+"01354","Doddington",""
+"01302","Doncaster",""
+"01305","Dorchester",""
+"01304","Dover",""
+"01366","Downham Market",""
+"01396","Downpatrick",""
+"01377","Driffield",""
+"01398","Dulverton",""
+"01389","Dumbarton",""
+"01387","Dumfries",""
+"01368","Dunbar",""
+"01382","Dundee",""
+"01383","Dunfermline",""
+"01868","Dungannon",""
+"01350","Dunkeld",""
+"01369","Dunoon",""
+"01361","Duns",""
+"01913","Durham",""
+"01453","Dursley",""
+"01347","Easingwold",""
+"01342","East Grinstead",""
+"01355","East Kilbride",""
+"01323","Eastbourne",""
+"01470","Edinbane",""
+"0131","Edinburgh",""
+"01343","Elgin",""
+"01358","Ellon",""
+"01353","Ely",""
+"01365","Enniskillen",""
+"01372","Esher",""
+"01386","Evesham",""
+"01392","Exeter",""
+"01595","Fair Isle",""
+"01328","Fakenham",""
+"01324","Falkirk",""
+"01326","Falmouth",""
+"01329","Fareham",""
+"01367","Faringdon",""
+"01681","Fionnphort",""
+"01348","Fishguard",""
+"01365","Fivemiletown",""
+"01303","Folkestone",""
+"01561","Fordoun",""
+"01307","Forfar",""
+"01309","Forres",""
+"01320","Fort Augustus",""
+"01397","Fort William",""
+"01381","Fortrose",""
+"01595","Foula",""
+"01346","Fraserburgh",""
+"01928","Frodsham",""
+"01373","Frome",""
+"01427","Gainsborough",""
+"01445","Gairloch",""
+"01896","Galashiels",""
+"01995","Garstang",""
+"01465","Girvan",""
+"0141","Glasgow",""
+"01458","Glastonbury",""
+"01972","Glenborrodale",""
+"01456","Glenurquhart",""
+"01457","Glossop",""
+"01452","Gloucester",""
+"01408","Golspie",""
+"01405","Goole",""
+"01946","Gosforth",""
+"01539","Grange over Sands",""
+"01476","Grantham",""
+"01479","Grantown-on-Spey",""
+"01474","Gravesend",""
+"01851","Great Bernera",""
+"01371","Great Dunmow",""
+"01488","Great Shefford",""
+"01493","Great Yarmouth",""
+"01475","Greenock",""
+"01472","Grimsby",""
+"01481","Guernsey",""
+"01483","Guildford",""
+"01287","Guisborough",""
+"01943","Guiseley",""
+"01422","Halifax",""
+"01434","Haltwhistle",""
+"01684","Hanley Swan",""
+"01859","Harris",""
+"01423","Harrogate",""
+"01501","Harthill",""
+"01429","Hartlepool",""
+"01428","Haslemere",""
+"01424","Hastings",""
+"01433","Hathersage",""
+"01437","Haverfordwest",""
+"01440","Haverhill",""
+"01450","Hawick",""
+"01539","Hawkshead",""
+"01497","Hay-on-Wye",""
+"01444","Haywards Heath",""
+"01435","Heathfield",""
+"01436","Helensburgh",""
+"01431","Helmsdale",""
+"01439","Helmsley",""
+"01432","Hereford",""
+"01434","Hexham",""
+"01494","High Wycombe",""
+"01455","Hinckley",""
+"01462","Hitchin",""
+"01992","Hoddesdon",""
+"01406","Holbeach",""
+"01409","Holsworthy",""
+"01407","Holyhead",""
+"01400","Honington",""
+"01404","Honiton",""
+"01524","Hornby",""
+"01964","Hornsea",""
+"01403","Horsham",""
+"01484","Huddersfield",""
+"01482","Hull",""
+"01480","Huntingdon",""
+"01466","Huntly",""
+"01464","Insch",""
+"01499","Inveraray",""
+"01463","Inverness",""
+"01467","Inverurie",""
+"01538","Ipstones",""
+"01473","Ipswich",""
+"01624","Isle of Man",""
+"01753","Iver",""
+"01534","Jersey",""
+"01505","Johnstone",""
+"01535","Keighley",""
+"01542","Keith",""
+"01573","Kelso",""
+"01539","Kendal",""
+"01365","Kesh",""
+"01768","Keswick",""
+"01536","Kettering",""
+"01866","Kilchrenan",""
+"01360","Killearn",""
+"01567","Killin",""
+"01469","Killingholme",""
+"01563","Kilmarnock",""
+"01852","Kilmelford",""
+"01266","Kilrea",""
+"01553","Kings Lynn",""
+"01548","Kingsbridge",""
+"01544","Kington",""
+"01540","Kingussie",""
+"01882","Kinloch Rannoch",""
+"01577","Kinross",""
+"01247","Kircubbin",""
+"01592","Kirkcaldy",""
+"01557","Kirkcudbright",""
+"01856","Kirkwall",""
+"01830","Kirkwhelpington",""
+"01575","Kirriemuir",""
+"01438","Knebworth",""
+"01547","Knighton",""
+"01565","Knutsford",""
+"01599","Kyle",""
+"01337","Ladybank",""
+"01528","Laggan",""
+"01549","Lairg",""
+"01570","Lampeter",""
+"01555","Lanark",""
+"01524","Lancaster",""
+"01387","Langholm",""
+"01564","Lapworth",""
+"01574","Larne",""
+"01578","Lauder",""
+"01566","Launceston",""
+"01926","Leamington Spa",""
+"01531","Ledbury",""
+"0113","Leeds",""
+"0116","Leicester",""
+"01525","Leighton Buzzard",""
+"01568","Leominster",""
+"01595","Lerwick",""
+"01969","Leyburn",""
+"01504","Limavady",""
+"01522","Lincoln",""
+"01846","Lisburn",""
+"01579","Liskeard",""
+"01365","Lisnaskea",""
+"0151","Liverpool",""
+"01545","Llanarth",""
+"01558","Llandeilo",""
+"01550","Llandovery",""
+"01597","Llandrindod Wells",""
+"01559","Llandyssul",""
+"01554","Llanelli",""
+"01686","Llanidloes",""
+"01974","Llanon",""
+"01591","Llanwrtyd Wells",""
+"01520","Lochcarron",""
+"01546","Lochgilphead",""
+"01571","Lochinver",""
+"01876","Lochmaddy",""
+"01576","Lockerbie",""
+"01878","Lohboisdale",""
+"0207","London (Inner Area)",""
+"0208","London (Outer Area)",""
+"01504","Londonderry",""
+"01503","Looe",""
+"01509","Loughborough",""
+"01507","Louth",""
+"01502","Lowestoft",""
+"01584","Ludlow",""
+"01593","Lybster",""
+"01594","Lydney",""
+"01590","Lymington",""
+"01625","Macclesfield",""
+"01654","Machynlleth",""
+"01954","Madingley",""
+"01648","Magherafelt",""
+"01628","Maidenhead",""
+"01622","Maidstone",""
+"01621","Maldon",""
+"01687","Mallaig",""
+"01666","Malmesbury",""
+"01653","Malton",""
+"0161","Manchester",""
+"01623","Mansfield",""
+"01630","Market Drayton",""
+"01858","Market Harborough",""
+"01673","Market Rasen",""
+"01430","Market Weighton",""
+"01672","Marlborough",""
+"01526","Martin",""
+"01266","Martinstown",""
+"01629","Matlock",""
+"01771","Maud",""
+"01655","Maybole",""
+"01634","Medway",""
+"01664","Melton Mowbray",""
+"01676","Meriden",""
+"01737","Merstham",""
+"01685","Merthyr Tydfil",""
+"01957","Mid Yell",""
+"01642","Middlesborough",""
+"01646","Milford Haven",""
+"01229","Millom",""
+"01643","Minehead",""
+"01683","Moffat",""
+"01352","Mold",""
+"01600","Monmouth",""
+"01674","Montrose",""
+"01647","Moretonhampstead",""
+"01670","Morpeth",""
+"01560","Moscow",""
+"01698","Motherwell",""
+"01667","Nairn",""
+"01834","Narberth",""
+"01639","Neath",""
+"01491","Nettlebed",""
+"01644","New Galloway",""
+"01581","New Luce",""
+"01663","New Mills",""
+"01636","Newark",""
+"01635","Newbury",""
+"01396","Newcastle (Co. Down)",""
+"01306","Newdigate",""
+"01638","Newmarket",""
+"01633","Newport",""
+"01637","Newquay (Cornwall)",""
+"01841","New Quay (Dyfed)",""
+"01693","Newry",""
+"01626","Newton Abbot",""
+"01671","Newton Stewart",""
+"01686","Newtown",""
+"01662","Newtown Stewart",""
+"01620","North Berwick",""
+"01430","North Cave",""
+"028","Northern Ireland",""
+"01692","North Walsham",""
+"01609","Northallerton",""
+"01604","Northampton",""
+"01606","Northwich",""
+"01603","Norwich",""
+"0115","Nottingham",""
+"01572","Oakham",""
+"01631","Oban",""
+"01837","Okehampton",""
+"01651","Oldmeldrum",""
+"01662","Omagh",""
+"01691","Oswestry",""
+"01865","Oxford",""
+"01359","Pakenham",""
+"01964","Patrington",""
+"01334","Peat Inn",""
+"01721","Peebles",""
+"01968","Penicuik",""
+"01768","Penrith",""
+"01736","Penzance",""
+"01738","Perth",""
+"01733","Peterborough",""
+"01779","Peterhead",""
+"01730","Petersfield",""
+"01751","Pickering",""
+"01796","Pitlochry",""
+"01752","Plymouth",""
+"01759","Pocklington",""
+"01977","Pontefract",""
+"01495","Pontypool",""
+"01443","Pontypridd",""
+"01768","Pooley Bridge",""
+"01496","Port Ellen",""
+"01762","Portadown",""
+"01766","Porthmadog",""
+"01478","Portree",""
+"023","Portsmouth",""
+"01772","Preston",""
+"01798","Pulborough",""
+"01758","Pwllheli",""
+"01744","Rainford",""
+"01454","Rangeworthy",""
+"01697","Raughton Head",""
+"0118","Reading",""
+"01527","Redditch",""
+"01209","Redruth",""
+"01777","Retford",""
+"01745","Rhyl",""
+"01748","Richmond",""
+"01773","Ripley",""
+"01765","Ripon",""
+"01706","Rochdale",""
+"01725","Rockbourne",""
+"01708","Romford",""
+"01794","Romsey",""
+"01989","Ross-on-Wye",""
+"01693","Rostrevor",""
+"01669","Rothbury",""
+"01709","Rotherham",""
+"01700","Rothesay",""
+"01763","Royston",""
+"01788","Rugby",""
+"01824","Ruthin",""
+"01983","Ryde",""
+"01797","Rye",""
+"01799","Saffron Walden",""
+"01238","Saintfield NI",""
+"01722","Salisbury",""
+"01857","Sanday",""
+"01950","Sandwick",""
+"01767","Sandy",""
+"01659","Sanquhar",""
+"01728","Saxmundham",""
+"01723","Scarborough",""
+"01879","Scarinish",""
+"01720","Scillonia",""
+"01971","Scourie",""
+"01724","Scunthorpe",""
+"01539","Sedbergh",""
+"01740","Sedgefield",""
+"01757","Selby",""
+"01750","Selkirk",""
+"01729","Settle",""
+"01732","Sevenoaks",""
+"01747","Shaftesbury",""
+"01931","Shap",""
+"0114","Sheffield",""
+"01749","Shepton Mallet",""
+"01291","Shirenewton",""
+"01394","Shottisham",""
+"01743","Shrewsbury",""
+"01795","Sittingbourne",""
+"01754","Skegness",""
+"01756","Skipton",""
+"01529","Sleaford",""
+"01769","South Molton",""
+"023","Southampton",""
+"01702","Southend-on-Sea",""
+"01704","Southport",""
+"01775","Spalding",""
+"01507","Spilsby",""
+"01726","St Austell",""
+"01835","St Boswells",""
+"01994","St Clears",""
+"01785","Stafford",""
+"01780","Stamford",""
+"01375","Stanford-le-Hope",""
+"01388","Stanhope",""
+"01786","Stirling",""
+"01984","Stogumber",""
+"01782","Stoke-on-Trent",""
+"01569","Stonehaven",""
+"01851","Stornoway",""
+"01384","Stourbridge",""
+"01449","Stowmarket",""
+"01776","Stranraer",""
+"01789","Stratford-upon-Avon",""
+"01975","Strathdon",""
+"01997","Strathpeffer",""
+"01641","Strathy",""
+"01967","Strontian",""
+"01787","Sudbury",""
+"01760","Swaffham",""
+"01322","Swanley",""
+"01792","Swansea",""
+"01793","Swindon",""
+"01862","Tain",""
+"01827","Tamworth",""
+"01880","Tarbert",""
+"01829","Tarporley",""
+"01823","Taunton",""
+"01822","Tavistock",""
+"01761","Temple Cloud",""
+"01963","Templecombe",""
+"01844","Thame",""
+"01843","Thanet",""
+"01842","Thetford",""
+"01845","Thirsk",""
+"01848","Thornhill",""
+"01847","Thurso",""
+"01884","Tiverton",""
+"01688","Tobermory",""
+"01808","Tomatin",""
+"01809","Tomdoun",""
+"01847","Tongue",""
+"01803","Torquay",""
+"01805","Torrington",""
+"01875","Tranent",""
+"01877","Trossachs",""
+"01872","Truro",""
+"01892","Tunbridge Wells",""
+"01888","Turriff",""
+"0191","Tyneside",""
+"01825","Uckfield",""
+"01854","Ullapool",""
+"01806","Voe",""
+"01924","Wakefield",""
+"01487","Warboys",""
+"01929","Wareham",""
+"01985","Warminster",""
+"01925","Warrington",""
+"01923","Watford",""
+"01915","Wearside",""
+"01327","Weedon",""
+"01933","Wellingborough",""
+"01952","Wellington",""
+"01938","Welshpool",""
+"01939","Wem",""
+"01944","West Heslerton",""
+"01934","Weston-Super-Mare",""
+"01937","Wetherby",""
+"01949","Whatton",""
+"01947","Whitby",""
+"01948","Whitchurch",""
+"01946","Whitehaven",""
+"01955","Wick",""
+"01942","Wigan",""
+"01697","Wigton",""
+"01988","Wigtown",""
+"01962","Winchester",""
+"01945","Wisbech",""
+"01993","Witney",""
+"01902","Wolverhampton",""
+"01908","Wolverton",""
+"01905","Worcester",""
+"01900","Workington",""
+"01909","Worksop",""
+"01981","Wormbridge",""
+"01903","Worthing",""
+"01978","Wrexham",""
+"01661","Wylam",""
+"01935","Yeovil",""
+"01904","York",""
diff -Nur --exclude-from=exclude dashboard/util/geo/areacodes/areacodes.us.csv dashboard-ac/util/geo/areacodes/areacodes.us.csv
--- dashboard/util/geo/areacodes/areacodes.us.csv	1970-01-01 01:00:00.000000000 +0100
+++ dashboard-ac/util/geo/areacodes/areacodes.us.csv	2004-02-26 11:03:54.000000000 +0000
@@ -0,0 +1,332 @@
+#United States of America
+#+1
+# IDD is 011 but numbers are usually written without this (?)
+#Source: http://www.nanpa.com
+"201","","New Jersey"
+"202","","District of Columbia"
+"203","","Connecticut"
+"204","","Manitoba"
+"205","","Alabama"
+"206","","Washington"
+"207","","Maine"
+"208","","Idaho"
+"209","","California"
+"210","","Texas"
+"212","","New York"
+"213","","California"
+"214","","Texas"
+"215","","Pennsylvania"
+"216","","Ohio"
+"217","","Illinois"
+"218","","Minnesota"
+"219","","Indiana"
+"224","","Illinois"
+"225","","Louisiana"
+"228","","Mississippi"
+"229","","Georgia"
+"231","","Michigan"
+"234","","Ohio"
+"239","","Florida"
+"240","","Maryland"
+"242","","Bahamas"
+"246","","Barbados"
+"248","","Michigan"
+"250","","British Columbia"
+"251","","Alabama"
+"252","","North Carolina"
+"253","","Washington"
+"254","","Texas"
+"256","","Alabama"
+"260","","Indiana"
+"262","","Wisconsin"
+"264","","Anguilla"
+"267","","Pennsylvania"
+"268","","Antigua & Barbuda"
+"269","","Michigan"
+"270","","Kentucky"
+"276","","Virginia"
+"281","","Texas"
+"284","","British Virgin Islands"
+"289","","Ontario"
+"301","","Maryland"
+"302","","Delaware"
+"303","","Colorado"
+"304","","West Virginia"
+"305","","Florida"
+"306","","Saskatchewan"
+"307","","Wyoming"
+"308","","Nebraska"
+"309","","Illinois"
+"310","","California"
+"312","","Illinois"
+"313","","Michigan"
+"314","","Missouri"
+"315","","New York"
+"316","","Kansas"
+"317","","Indiana"
+"318","","Louisiana"
+"319","","Iowa"
+"320","","Minnesota"
+"321","","Florida"
+"323","","California"
+"325","","Texas"
+"330","","Ohio"
+"334","","Alabama"
+"336","","North Carolina"
+"337","","Louisiana"
+"339","","Massachusetts"
+"340","","US Virgin Islands"
+"345","","Cayman Islands"
+"347","","New York"
+"351","","Massachusetts"
+"352","","Florida"
+"360","","Washington"
+"361","","Texas"
+"386","","Florida"
+"401","","Rhode Island"
+"402","","Nebraska"
+"403","","Alberta"
+"404","","Georgia"
+"405","","Oklahoma"
+"406","","Montana"
+"407","","Florida"
+"408","","California"
+"409","","Texas"
+"410","","Maryland"
+"412","","Pennsylvania"
+"413","","Massachusetts"
+"414","","Wisconsin"
+"415","","California"
+"416","","Ontario"
+"417","","Missouri"
+"418","","Quebec"
+"419","","Ohio"
+"423","","Tennessee"
+"425","","Washington"
+"430","","Texas"
+"432","","Texas"
+"434","","Virginia"
+"435","","Utah"
+"440","","Ohio"
+"441","","Bermuda"
+"443","","Maryland"
+"450","","Quebec"
+#"456","","NANP area"
+"469","","Texas"
+"473","","Grenada"
+"478","","Georgia"
+"479","","Arkansas"
+"480","","Arizona"
+"484","","Pennsylvania"
+#"500","","NANP area"
+"501","","Arkansas"
+"502","","Kentucky"
+"503","","Oregon"
+"504","","Louisiana"
+"505","","New Mexico"
+"506","","New Brunswick"
+"507","","Minnesota"
+"508","","Massachusetts"
+"509","","Washington"
+"510","","California"
+"512","","Texas"
+"513","","Ohio"
+"514","","Quebec"
+"515","","Iowa"
+"516","","New York"
+"517","","Michigan"
+"518","","New York"
+"519","","Ontario"
+"520","","Arizona"
+"530","","California"
+"540","","Virginia"
+"541","","Oregon"
+"551","","New Jersey"
+"559","","California"
+"561","","Florida"
+"562","","California"
+"563","","Iowa"
+"567","","Ohio"
+"570","","Pennsylvania"
+"571","","Virginia"
+"573","","Missouri"
+"574","","Indiana"
+"580","","Oklahoma"
+"585","","New York"
+"586","","Michigan"
+"600","","Canada"
+"601","","Mississippi"
+"602","","Arizona"
+"603","","New Hampshire"
+"604","","British Columbia"
+"605","","South Dakota"
+"606","","Kentucky"
+"607","","New York"
+"608","","Wisconsin"
+"609","","New Jersey"
+"610","","Pennsylvania"
+"612","","Minnesota"
+"613","","Ontario"
+"614","","Ohio"
+"615","","Tennessee"
+"616","","Michigan"
+"617","","Massachusetts"
+"618","","Illinois"
+"619","","California"
+"620","","Kansas"
+"623","","Arizona"
+"626","","California"
+"630","","Illinois"
+"631","","New York"
+"636","","Missouri"
+"641","","Iowa"
+"646","","New York"
+"647","","Ontario"
+"649","","Turks & Caicos Islands"
+"650","","California"
+"651","","Minnesota"
+"660","","Missouri"
+"661","","California"
+"662","","Mississippi"
+"664","","Montserrat"
+#"670","","CNMI"
+"671","","Guam"
+"678","","Georgia"
+"682","","Texas"
+#"700","","NANP area"
+"701","","North Dakota"
+"702","","Nevada"
+"703","","Virginia"
+"704","","North Carolina"
+"705","","Ontario"
+"706","","Georgia"
+"707","","California"
+"708","","Illinois"
+"709","","Newfoundland"
+#"710","","US"
+"712","","Iowa"
+"713","","Texas"
+"714","","California"
+"715","","Wisconsin"
+"716","","New York"
+"717","","Pennsylvania"
+"718","","New York"
+"719","","Colorado"
+"720","","Colorado"
+"724","","Pennsylvania"
+"727","","Florida"
+"731","","Tennessee"
+"732","","New Jersey"
+"734","","Michigan"
+"740","","Ohio"
+"754","","Florida"
+"757","","Virginia"
+"758","","St. Lucia"
+"760","","California"
+"763","","Minnesota"
+"765","","Indiana"
+"767","","Dominica"
+"770","","Georgia"
+"772","","Florida"
+"773","","Illinois"
+"774","","Massachusetts"
+"775","","Nevada"
+"778","","British Columbia"
+"780","","Alberta"
+"781","","Massachusetts"
+"784","","St. Vincent & Grenadines"
+"785","","Kansas"
+"786","","Florida"
+"787","","Puerto Rico"
+#"800","","NANP area"
+"801","","Utah"
+"802","","Vermont"
+"803","","South Carolina"
+"804","","Virginia"
+"805","","California"
+"806","","Texas"
+"807","","Ontario"
+"808","","Hawaii"
+"809","","Dominican Republic"
+"810","","Michigan"
+"812","","Indiana"
+"813","","Florida"
+"814","","Pennsylvania"
+"815","","Illinois"
+"816","","Missouri"
+"817","","Texas"
+"818","","California"
+"819","","Quebec"
+"828","","North Carolina"
+"830","","Texas"
+"831","","California"
+"832","","Texas"
+"843","","South Carolina"
+"845","","New York"
+"847","","Illinois"
+"848","","New Jersey"
+"850","","Florida"
+"856","","New Jersey"
+"857","","Massachusetts"
+"858","","California"
+"859","","Kentucky"
+"860","","Connecticut"
+"862","","New Jersey"
+"863","","Florida"
+"864","","South Carolina"
+"865","","Tennessee"
+#"866","","NANP area"
+"867","","Yukon"
+"867","","Northwest Territories"
+"868","","Trinidad & Tobago"
+"869","","St. Kitts & Nevis"
+"870","","Arkansas"
+"876","","Jamaica"
+#"877","","NANP area"
+"878","","Pennsylvania"
+#"880","","NANP area"
+#"881","","NANP area"
+#"882","","NANP area"
+#"888","","NANP area"
+#"900","","NANP area"
+"901","","Tennessee"
+"902","","Nova Scotia"
+"903","","Texas"
+"904","","Florida"
+"905","","Ontario"
+"906","","Michigan"
+"907","","Alaska"
+"908","","New Jersey"
+"909","","California"
+"910","","North Carolina"
+"912","","Georgia"
+"913","","Kansas"
+"914","","New York"
+"915","","Texas"
+"916","","California"
+"917","","New York"
+"918","","Oklahoma"
+"919","","North Carolina"
+"920","","Wisconsin"
+"925","","California"
+"928","","Arizona"
+"931","","Tennessee"
+"936","","Texas"
+"937","","Ohio"
+"939","","Puerto Rico"
+"940","","Texas"
+"941","","Florida"
+"947","","Michigan"
+"949","","California"
+"952","","Minnesota"
+"954","","Florida"
+"956","","Texas"
+"970","","Colorado"
+"971","","Oregon"
+"972","","Texas"
+"973","","New Jersey"
+"978","","Massachusetts"
+"979","","Texas"
+"980","","North Carolina"
+"985","","Louisiana"
+"989","","Michigan"
diff -Nur --exclude-from=exclude dashboard/util/geo/gazetteer.cs dashboard-ac/util/geo/gazetteer.cs
--- dashboard/util/geo/gazetteer.cs	2003-07-27 21:35:44.000000000 +0100
+++ dashboard-ac/util/geo/gazetteer.cs	2004-02-26 16:08:08.149804244 +0000
@@ -2,6 +2,8 @@
 // by Edd Dumbill <edd usefulinc com>
 // thanks to Matt Hunt for his help with this.
 //
+// Areacode stuff by Dave Rodgman <davidr sucs org>
+//
 // TODO:
 //   Get nearest airport details and add a gazetteer for those too.
 
@@ -35,6 +37,17 @@
 		{
 		}
 
+		public Point (string city, string adminregion, string country) {
+			this.City = city;
+			this.Adminregion = adminregion;
+			this.Country = country;
+
+			this.Id = 0;
+			this.Latitude  = -1.0;
+			this.Longitude = -1.0;
+			this.Isocode = null;
+		}
+
 		public Point (int id, double latitude, double longitude,
 				string city,
 				string adminregion,
@@ -119,6 +132,8 @@
 	public class Gazetteer {
 		
 		private ArrayList points = new ArrayList ();
+		private Hashtable pointsByCity = new Hashtable (); // copy of above, indexed by city
+	
 		private ArrayList latindex = new ArrayList ();
 		private ArrayList lngindex = new ArrayList ();
 		
@@ -127,10 +142,82 @@
 			Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly ();
 
 			System.IO.Stream s = assembly.GetManifestResourceStream ("cities.txt.gz");
-			Load (new GZip.GZipInputStream (s));
+			LoadCities (new GZip.GZipInputStream (s));
+			LoadAreacodes ();
+		}
+
+		private void LoadAreacodes () {
+			StreamReader sr;
+			SortedList table;
+
+			lock (Areacodes) {
+				if (Areacodes.Count > 0)
+					return;
+	
+				Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly ();
+				foreach (String areaFile in assembly.GetManifestResourceNames ()) {
+					if (!(areaFile.StartsWith ("areacodes/areacodes.") && areaFile.EndsWith (".csv.gz")))
+						continue;
+
+					System.IO.Stream s = assembly.GetManifestResourceStream (areaFile);
+					String country;
+					try {
+						sr = new StreamReader (new GZip.GZipInputStream (s));
+
+						country = sr.ReadLine ().Substring (1).Trim (null);
+						if (!Areacodes.ContainsKey (country))
+							Areacodes.Add (country, new SortedList ());
+						table = (SortedList) Areacodes [country];
+
+						RegularExpressions.Match intlCodes = Regex.Match (sr.ReadLine (), @"#\+(\d+)\s*(\d*)");
+						table.Add ("CountryCode",   intlCodes.Groups [1].Captures [0].ToString ());
+						table.Add ("CountryPrefix", intlCodes.Groups [2].Captures [0].ToString ());
+					}
+					catch (Exception e) {
+						Console.WriteLine ("Gazetteer: Could not load area codes database: " + areaFile);
+						continue;
+					}
+
+					String line, code, city, adminregion;
+					Regex extractData = new Regex (@"\x22(?<code>\d+)\x22,\x22(?<city>[^\x22]*)\x22,\x22(?<adminregion>[^\x22]*)\x22", RegexOptions.Compiled);
+
+					while ((line = sr.ReadLine ()) != null) {
+						if (line [0] == '#')
+							continue;
+
+						try {
+							RegularExpressions.Match m = extractData.Match (line);
+
+							code = m.Groups ["code"].Captures [0].ToString ();
+							city = m.Groups ["city"].Captures [0].ToString ();
+							adminregion = m.Groups ["adminregion"].Captures [0].ToString ();
+
+							if ((city.Length == 0 && adminregion.Length == 0) || (code.Length == 0))
+								throw new Exception ();
+						} catch (Exception e) {
+							Console.WriteLine ("Gazetteer: error in {0} areacode data, line: {1}", country, line);
+							continue;
+						}
+
+						if (code.Length < minAreacodeLength)
+							minAreacodeLength = code.Length;
+
+						Point p = GetLatLong (city, adminregion, country);
+
+						// We permit multiple towns per area code
+						if (!table.ContainsKey (code))
+							table.Add (code, new ArrayList ());
+						((ArrayList) (table [code])).Add (p);
+					}
+					Console.WriteLine ("Gazetteer: Loaded {0} area codes", country);
+				}
+			}
 		}
 
-		public void Load (System.IO.Stream s)
+		private static Hashtable Areacodes = new Hashtable();
+		private static int minAreacodeLength = 999999;
+
+		public void LoadCities (System.IO.Stream s)
 		{
 			Encoding e = Encoding.GetEncoding ("iso-8859-1");
 			StreamReader f = new StreamReader (s, e);
@@ -171,6 +258,11 @@
 						vals[1], vals[3], vals[4], vals[5]);
 
 				points.Add (p);
+
+				if (!pointsByCity.ContainsKey (p.City))
+					pointsByCity.Add (p.City, new ArrayList ());
+				((ArrayList) pointsByCity [p.City]).Add (p);
+
 				latindex.Add ( p);
 				lngindex.Add ( p);
 				l = f.ReadLine();
@@ -182,6 +274,69 @@
 			// Console.WriteLine ("Read {0} cities.", i);
 		}
 
+		// generate list of Points (usually only one) from an area code
+		// some areacodes cover more than one city though
+		public ArrayList LookupAreacode(String phoneNumber) {
+			ArrayList result = new ArrayList ();
+
+			String number = Regex.Replace (phoneNumber, @"[^\d\+]", "");
+
+			if (number.Length == 0)
+				return result;
+
+			IDictionaryEnumerator ie = Areacodes.GetEnumerator ();
+			while (ie.MoveNext ()) {
+				SortedList table = (SortedList) (ie.Value);
+				String code;
+
+				// deal with international prefixes
+				if (number [0] == '+') {
+					code = number.Substring (1);
+					if (!code.StartsWith ((String) (table ["CountryCode"])))
+						continue;
+					code = table ["CountryPrefix"] + code.Substring (((String) (table ["CountryCode"])).Length);
+				} else
+					code = number;
+
+				String key = null;
+				for (int len = minAreacodeLength; len <= code.Length; len++) {
+					int i = table.IndexOfKey (code.Substring (0, len));
+					if (i == -1)
+						continue;
+					key = code.Substring (0, len);
+				}
+
+				if (key == null) continue;
+
+				result.AddRange ((ArrayList) table [key]);
+			}
+			return result;
+	
+		}
+
+		// given a city name, region, country, generate a point which
+		// includes lat/long data if we have it
+		public Point GetLatLong (string city, string adminregion, string country) {
+			Point q = null;
+
+			// exact match on city name
+			if (city != null && pointsByCity.ContainsKey (city))
+				foreach (Point r in ((ArrayList) pointsByCity [city]))
+					if ((r.Adminregion == adminregion || adminregion == "") &&
+						r.Country == country)
+							return r;
+
+			// search all looking for biggest city (population == point.Id)
+			// in specified region. cities are sorted by pop. so just take first match
+			if (adminregion != "")
+				foreach (Point r in points)
+					if (r.Adminregion == adminregion && r.Country == country)
+						return r;
+
+			// no match
+			return new Point(city, adminregion, country);
+		}
+
 		public ArrayList NearestCities (double latitude, double longitude) {
 			Point p = new Point ();
 			double minlat, maxlat, minlng, maxlng;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]