
(* :Title: City Data *)

(* :Author: John M. Novak *)

(* :Summary:
	A database for information about cities.  Also, a useful
	model of a database in Mathematica.
*)

(* :Context: Miscellaneous`CityData`;
	also loads Miscellaneous`Geodesy` *)

(* :Package Version: 1.0 *)

(* :History:
	V 1.0, April, 1991, by John M. Novak.
*)

(* :Keywords:
	cities, geography, databases
*)

(* :Sources:
	Map, a Macintosh Control Panel Device V1.1 by Mark Davis.
	Esselte Map Service, Concise Earth Book World Atlas,
		Earthbooks, Inc., 1990
*)

(* :Mathematica Version: 2.0 *)

BeginPackage["Miscellaneous`CityData`",
	"Miscellaneous`Geodesy`"]

CityData::usage =
	"CityData[city,type] will return data of the requested type
	for the city specified. CityData[type] will return a list
	of cities in the database for which information of the specified
	type is available.  CityData[city] will return any information
	on city of types specified in the global variable $CityFields."

$CityFields::usage =
	"Contains a list of data types (fields) in the CityData
	database."

CityPosition::usage =
	"CityPosition is a type of data for CityData.  Position
	information is in the form of latitude and longitude,
	expressed as {lat,long}. Coordinates will be in the form
	{d,m} or {d,m,s}."

CityDistance::usage =
	"CityDistance[city1,city2] returns the distance in km between
	the two cities.  CityDistance[city1,city2,
	CityDistanceMethod->method] finds the distance using the
	function method."

CityDistanceMethod::usage =
	"CityDistanceMethod is an option for CityDistance; it specifies
	a pure function taking two arguments that determines the
	distance between coordinates."

Begin["`Private`"]

$CityFields = {CityPosition};

CityData::alternates =
	"Requested city not in database.  Possible alternatives: `1`";

CityData[symbol_Symbol] :=
	Map[#[[1,1,1]]&,DownValues[symbol]]

CityData[cit:(_String | {__String})] :=
	Module[{dat,alts},
		dat = Map[{#,#[cit]}&,$CityFields];
		dat = Select[dat,Not[MemberQ[$CityFields,Head[Last[#]]]]&];
		If[dat === {} && ((alts =
				Union @@ Map[checkspell[cit,CityData[#]]&,$CityFields]) =!=
				{}),
			Message[CityData::alternates,alts]
		];
		dat/;dat =!= {}
	]
			
CityData[cit:(_String | {__String}),symbol_Symbol] :=
	Module[{return = symbol[cit],dv,alts},
		If[Head[return] === symbol,
			dv = CityData[symbol];
			If[Length[tmp = checkclose[cit,dv]] === 1,
				return = symbol[First[tmp]],
				If[(alts = checkspell[cit,dv]) =!= {},
					Message[CityData::alternates,alts]
				]
			]
		];
		return/;Head[return] =!= symbol]

checkclose[cit_String,list_List] :=
	Select[list,(Head[#] === List && First[#] === cit)&]

checkclose[cit_List, list_List] :=
	Select[list,(Head[#] === String && # === First[cit])&]

checkspell[cit_,list_List] :=
	Module[{city = If[Head[cit] === List, First[cit],cit]},
		Select[list,If[Head[#] === List,
				StringMatchQ[city,First[#],SpellingCorrection->True,
					IgnoreCase->True],
				StringMatchQ[city,#,SpellingCorrection->True,
					IgnoreCase->True]]&]
	]

Options[CityDistance] =
	{DistanceMethod->SphericalDistance}

CityDistance[city1_,city2_,opts___] :=
	Module[{meth,pos},
		{meth} = {DistanceMethod}/.{opts}/.Options[CityDistance];
		pos = {CityData[city1,CityPosition],
			CityData[city2,CityPosition]};
		N[Apply[meth,pos]]/;VectorQ[Flatten[pos]]
	]

(* City Information *)

CityPosition["Abu Dhabi"] = {{24, 28}, {54, 25}}
 
CityPosition["Addis Ababa"] = {{9, 3}, {38, 42}}
 
CityPosition["Aden"] = {{12, 46}, {45, 1}}
 
CityPosition["Algiers"] = {{36, 50}, {3, 0}}
 
CityPosition["Amman"] = {{31, 57}, {35, 56}}
 
CityPosition["Amsterdam"] = {{52, 21}, {4, 54}}
 
CityPosition["Anchorage"] = {{61, 13}, {-149, -53}}
 
CityPosition["Ankara"] = {{39, 55}, {32, 50}}
 
CityPosition["Asuncion"] = {{-25, -16}, {-57, -40}}
 
CityPosition["Athens"] = {{38, 0}, {23, 44}}
 
CityPosition["Atlanta"] = {{33, 45}, {-84, -23}}
 
CityPosition["Baghdad"] = {{33, 20}, {44, 26}}
 
CityPosition["Bangkok"] = {{13, 44}, {100, 30}}
 
CityPosition["Beijing"] = {{39, 55}, {116, 25}}
 
CityPosition["Beirut"] = {{33, 52}, {35, 30}}
 
CityPosition["Belgrade"] = {{44, 50}, {20, 30}}
 
CityPosition["Beograd"] = {{44, 50}, {20, 30}}
 
CityPosition["Berlin"] = {{52, 31}, {13, 24}}
 
CityPosition["Bern"] = {{46, 57}, {7, 30}}
 
CityPosition["Bogota"] = {{4, 36}, {-74, -5}}

CityPosition["Bombay"] = {{18, 56}, {72, 51}}
 
CityPosition["Bonn"] = {{50, 44}, {7, 6}}
 
CityPosition["Boston"] = {{42, 20}, {-71, -5}}
 
CityPosition["Brasilia"] = {{-15, -47}, {-47, -55}}

CityPosition["Brussels"] = {{50, 50}, {4, 21}}
 
CityPosition["Budapest"] = {{47, 30}, {19, 5}}
 
CityPosition["Buenos Aires"] = {{-34, -37}, {-58, -24}}
 
CityPosition["Cairo"] = {{30, 3}, {31, 15}}
 
CityPosition["Calcutta"] = {{22, 35}, {88, 21}}
 
CityPosition["Cape Town"] = {{-33, -56}, {18, 22}}
 
CityPosition["Caracas"] = {{10, 30}, {-66, -56}}
 
CityPosition["Cardiff"] = {{51, 30}, {-3, -13}}
 
CityPosition["Cayenne"] = {{4, 55}, {-52, -18}}
 
CityPosition["Chicago"] = {{41, 50}, {-87, -45}}
 
CityPosition["Mexico City"] = {{19, 24}, {-99, -9}}

CityPosition["Copenhagen"] = {{55, 43}, {12, 34}}
 
CityPosition["Cupertino"] = {{37, 21}, {-121, -57}}
 
CityPosition["Dacca"] = {{23, 42}, {90, 22}}
 
CityPosition["Dallas"] = {{32, 47}, {-96, -49}}
 
CityPosition["Damascus"] = {{33, 30}, {36, 15}}
 
CityPosition["Denver"] = {{39, 44}, {-104, -59}}
 
CityPosition["Djakarta"] = {{-6, -8}, {106, 45}}
 
CityPosition["Doha"] = {{25, 17}, {51, 32}}
 
CityPosition["Dublin"] = {{53, 20}, {-6, -15}}
 
CityPosition["Edinburgh"] = {{55, 57}, {-3, -13}}
 
CityPosition["Geneva"] = {{46, 10}, {6, 9}}
 
CityPosition["Georgetown"] = {{6, 46}, {-58, -10}}
 
CityPosition["Godthab"] = {{64, 15}, {-51, -40}}

CityPosition["Havana"] = {{22, 8}, {-82, -22}}
 
CityPosition["Helsinki"] = {{60, 10}, {24, 58}}
 
CityPosition["Hong Kong"] = {{22, 15}, {114, 10}}
 
CityPosition["Honolulu"] = {{21, 19}, {-157, -52}}
 
CityPosition["Istanbul"] = {{41, 2}, {28, 59}}
 
CityPosition["Jerusalem"] = {{31, 47}, {35, 14}}
 
CityPosition["Kabul"] = {{34, 30}, {69, 12}}
 
CityPosition["Karachi"] = {{24, 51}, {67, 2}}
 
CityPosition["Khartoum"] = {{15, 36}, {32, 32}}
 
CityPosition["Kuwait"] = {{29, 20}, {48, 0}}
 
CityPosition["Lagos"] = {{6, 27}, {3, 23}}
 
CityPosition["La Habana"] = {{22, 8}, {-82, -22}}
 
CityPosition["La Paz"] = {{-16, -30}, {-68, -9}}
 
CityPosition["Leningrad"] = {{59, 55}, {30, 15}}
 
CityPosition["Lima"] = {{-12, -3}, {-77, -3}}
 
CityPosition["Lisboa"] = {{38, 44}, {-9, -8}}
 
CityPosition["Lisbon"] = {{38, 44}, {-9, -8}}
 
CityPosition["London"] = {{51, 30}, {0, -10}}
 
CityPosition["Los Angeles"] = {{34, 4}, {-118, -15}}
 
CityPosition["Madrid"] = {{40, 25}, {-3, -43}}
 
CityPosition["Manama"] = {{26, 12}, {50, 35}}
 
CityPosition["Manila"] = {{14, 36}, {120, 59}}
 
CityPosition["Mecca"] = {{21, 27}, {39, 49}}
 
CityPosition["Mexico City"] = {{19, 24}, {-99, -9}}
 
CityPosition["Miami"] = {{25, 46}, {-80, -12}}
 
CityPosition["Minneapolis"] = {{44, 59}, {-93, -13}}
 
CityPosition["Mogadisho"] = {{2, 2}, {45, 21}}
 
CityPosition["Montevideo"] = {{-34, -55}, {-56, -10}}
 
CityPosition["Montreal"] = {{45, 30}, {-73, -36}}

CityPosition["Moscow"] = {{55, 45}, {37, 35}}
 
CityPosition["Muscat"] = {{23, 29}, {58, 33}}
 
CityPosition["Nairobi"] = {{-1, -17}, {36, 50}}
 
CityPosition["New Delhi"] = {{28, 37}, {77, 13}}
 
CityPosition["New York"] = {{40, 43}, {-74, -1}}
 
CityPosition["Nouakchott"] = {{18, 9}, {-15, -58}}
 
CityPosition["Osaka"] = {{34, 40}, {135, 30}}
 
CityPosition["Oslo"] = {{59, 56}, {10, 45}}
 
CityPosition["Ottawa"] = {{45, 25}, {-75, -42}}
 
CityPosition["Paramaribo"] = {{5, 52}, {-55, -10}}
 
CityPosition["Paris"] = {{48, 52}, {2, 20}}
 
CityPosition["Peking"] = {{39, 55}, {116, 25}}
 
CityPosition["Perth"] = {{-31, -56}, {115, 50}}
 
CityPosition["Philadelphia"] = {{39, 37}, {-75, -7}}
 
CityPosition["Portland"] = {{45, 33}, {-122, -36}}
 
CityPosition["Prague"] = {{50, 5}, {14, 26}}
 
CityPosition["Quito"] = {{0, -14}, {-78, -30}}
 
CityPosition["Rabat"] = {{34, 2}, {-6, -51}}
 
CityPosition["Reykjavik"] = {{64, 9}, {-21, -57}}

CityPosition["Rio de Janeiro"] = {{-22, -53}, {-43, -17}}
 
CityPosition["Riyadh"] = {{24, 39}, {46, 43}}
 
CityPosition["Rome"] = {{41, 53}, {12, 30}}
 
CityPosition["Saint Louis"] = {{38, 38}, {-90, -11}}
 
CityPosition["Salt Lake City"] = {{40, 46}, {-111, -53}}
 
CityPosition["San Diego"] = {{32, 43}, {-117, -9}}
 
CityPosition["San Francisco"] = {{37, 48}, {-122, -24}}
 
CityPosition["San Jose"] = {{9, 59}, {-84, -4}}

CityPosition["Seoul"] = {{37, 33}, {126, 58}}
 
CityPosition["Shanghai"] = {{31, 14}, {121, 30}}
 
CityPosition["Singapore"] = {{1, 17}, {103, 51}}
 
CityPosition["Sao Paulo"] = {{-23, -33}, {-46, -39}}

CityPosition["Stockholm"] = {{59, 20}, {18, 3}}
 
CityPosition["Sydney"] = {{-33, -52}, {151, 13}}
 
CityPosition["Tehran"] = {{35, 40}, {51, 26}}
 
CityPosition["Tianjin"] = {{39, 8}, {117, 12}}
 
CityPosition["Tokyo"] = {{35, 42}, {139, 46}}
 
CityPosition["Tripoli"] = {{32, 53}, {13, 12}}
 
CityPosition["Tunis"] = {{36, 48}, {10, 11}}
 
CityPosition["Vancouver"] = {{49, 16}, {-123, -7}}
 
CityPosition["Vienna"] = {{48, 13}, {16, 22}}
 
CityPosition["Warsaw"] = {{52, 15}, {21, 0}}
 
CityPosition["Washington"] = {{38, 53}, {-77, 0}}
 
CityPosition["Wellington"] = {{-41, -17}, {174, 47}}
 
CityPosition["Zurich"] = {{47, 23}, {8, 33}}

End[]

EndPackage[]
