Wikipedia:Projekt DotNetWikiBot Framework/Lsjbot/Make-Geonames – Wikipedia
Hoppa till innehållet
Från Wikipedia
Wikipedia:Projekt DotNetWikiBot Framework
Lsjbot
//Originally from [[Wikipedia:Projekt DotNetWikiBot Framework/Lsjbot/Makespecies]]
//Extensively modified by Lsj
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Threading;
using System.Web;
using System.Net;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
//using Catfood.Shapefile;
//using System.Math;
using DotNetWikiBot;
class MyBot : Bot
public static string geonamesfolder = @"C:\dotnwb3\Geonames\"; //will be modified according to computer name
public static string extractdir = @"O:\dotnwb3\extract\"; //will be modified according to computer name
public static string botname = "Lsjbot";
public static string makelang = "sv";
//public static string makecountry = "AD,AE,AF,AG,AI,AL,AM,AO,AQ,AR,AS,AT,AU,AW,AX,AZ,BA,BB,BD,BE,BF,BG,BH,BI,BJ,BL,BM,BN,BO,BQ,BR,BS,BT,BV,BW,BY,BZ,CA,CC,CD,CF,CG,CH,CI,CK,CL,CM,CN,CO,CR,CU,CV,CW,CX,CY,CZ,DE,DJ,DK,DM,DO,DZ,EC,EE,EG,EH,ER,ES,ET,FI,FJ,FK,FM,FO,FR,GA,GB,GD,GE,GF,GG,GH,GI,GL,GM,GN,GP,GQ,GR,GS,GT,GU,GW,GY,HK,HM,HN,HR,HT,HU,ID,IE,IL,IM,IN,IO,IQ,IR,IS,IT,JE,JM,JO,JP,KE,KG,KH,KI,KM,KN,KP,KR,XK,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,LT,LU,LV,LY,MA,MC,MD,ME,MF,MG,MH,MK,ML,MM,MN,MO,MP,MQ,MR,MS,MT,MU,MV,MW,MX,MY,MZ,NA,NC,NE,NF,NG,NI,NL,NO,NP,NR,NU,NZ,OM,PA,PE,PF,PG,PH,PK,PL,PM,PN,PR,PS,PT,PW,PY,QA,RE,RO,RS,RU,RW,SA,SB,SC,SD,SS,SE,SG,SH,SI,SJ,SK,SL,SM,SN,SO,SR,ST,SV,SX,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TL,TM,TN,TO,TR,TT,TV,TW,TZ,UA,UG,UM,US,UY,UZ,VA,VC,VE,VG,VI,VN,VU,WF,WS,YE,YT,ZA,ZM,ZW"; //Can be comma-separated list. Must be same number of components in the following three strings.
//public static string makecountry = "AG,MT,MK,SS,BH,BT,LU,AD,AE,AF,AI,AL,AM,AO,AQ,AR,AS,AT,AU,AW,AX,AZ,BA,BB,BD,BE,BF,BG,BI,BJ,BL,BM,BN,BO,BQ,BR,BS,BV,BW,BY,BZ,CA,CC,CD,CF,CG,CH,CI,CK,CL,CM,CN,CO,CR,CU,CV,CW,CX,CY,CZ,DE,DJ,DK,DM,DO,DZ,EC,EE,EG,EH,ER,ES,ET,FI,FJ,FK,FM,FO,FR,GA,GB,GD,GE,GF,GG,GH,GI,GL,GM,GN,GP,GQ,GR,GS,GT,GU,GW,GY,HK,HM,HN,HR,HT,HU,ID,IE,IL,IM,IN,IO,IQ,IR,IS,IT,JE,JM,JO,JP,KE,KG,KH,KI,KM,KN,KP,KR,XK,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,LT,LU,LV,LY,MA,MC,MD,ME,MF,MG,MH,ML,MM,MN,MO,MP,MQ,MR,MS,MU,MV,MW,MX,MY,MZ,NA,NC,NE,NF,NG,NI,NL,NO,NP,NR,NU,NZ,OM,PA,PE,PF,PG,PH,PK,PL,PM,PN,PR,PS,PT,PW,PY,QA,RE,RO,RS,RU,RW,SA,SB,SC,SD,SE,SG,SH,SI,SJ,SK,SL,SM,SN,SO,SR,ST,SV,SX,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TL,TM,TN,TO,TR,TT,TV,TW,TZ,UA,UG,UM,US,UY,UZ,VA,VC,VE,VG,VI,VN,VU,WF,WS,YE,YT,ZA,ZM,ZW"; //Can be comma-separated list. Must be same number of components in the following three strings.
public static string makecountry = "CA";//,AU,AW,AX,AZ";//"RU,UA,BY,RS,MK,KZ,KG,MN,BG,TJ";
public static string makecountryname = "";//"Afghanistan,Albania,Antarctica,Armenia,Andorra,Burundi,Nicaragua,Bahamas,Macedonia,South Sudan,Bhutan,Luxembourg,Malta,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr,fr"; //Används av Makefork, samma engelska namnform som i namefork-filen
//public static string makecountrywiki = "en";//"ru,ua,be,sr,mk,kk,ky,mn,bg,tg";
//public static string makecountrywiki ="ca,ar,fa,en,en,sq,hy,pt,en,es,en,de,en,nl,fi,az,bs,en,bn,nl,fr,bg,ar,fr,fr,fr,en,ms,es,nl,pt,en,dz,en,en,be,en,en,ms,fr,fr,fr,de,fr,en,es,en,zh,es,es,es,pt,nl,en,el,cs,de,fr,da,en,es,ar,es,et,ar,ar,aa,es,am,fi,en,en,en,fo,fr,fr,en,en,ka,fr,en,en,en,kl,en,fr,fr,es,el,en,es,en,pt,en,zh,en,es,hr,ht,hu,id,en,he,en,en,en,ar,fa,is,it,en,en,ar,ja,en,ky,km,en,ar,en,ko,ko,sq,ar,en,kk,lo,ar,en,de,si,en,en,lt,lb,lv,ar,ar,fr,ro,sr,fr,fr,mh,mk,fr,my,mn,zh,fi,fr,ar,en,mt,en,dv,ny,es,ms,pt,en,fr,fr,en,en,es,nl,no,ne,na,ni,en,ar,es,es,fr,en,tl,ur,pl,fr,en,en,ar,pt,pa,es,ar,fr,ro,sr,ru,rw,ar,en,en,ar,en,sv,cm,en,sl,no,sk,en,it,fr,so,nl,pt,es,nl,ar,en,en,fr,fr,fr,th,tg,tk,te,tk,ar,to,tr,en,tv,zh,sw,uk,en,en,en,es,uz,la,en,es,en,en,vi,bi,wl,sm,ar,fr,zu,en,en"; //Används för iw
public static int resume_at = -1; //-1: run from start; gnid to resume at.
public static int stop_at = -1; //-1: run to end; gnid to stop at.
public static string resume_at_fork = ""; //resume at for fork pages; empty string to run from start
public static string testprefix = "";
//public static string nameforkdate = "20150803";
public static char createclass = ' '; //create only articles with this feature class
public static string createfeature = ""; //create only articles with this feature code
public static string createexceptfeature = ""; //create all articles EXCEPT with this feature code
public static int createunit = -1; //create only articles for place in admin.unit with gnid=createunit; <0 to make all
public static int createexceptunit = -1; //create only articles for place NOT in admin.unit with gnid=createexceptunit; <0 to make all
//======================================================
// Flags setting the main task for a run.
// Unpredictable results if multiple flags are true.
//======================================================
public static bool makearticles = false; //create wiki pages
public static bool makespecificarticles = false; //create specific wiki pages, one by one
public static bool remakearticleset = false; //remake a selected set of articles; overwrite must be true
public static bool altnamesonly = false; //create namefork file
public static bool makefork = false; //create fork pages on wiki
public static bool checkdoubles = false; //create artname file
public static bool checkwikidata = false; //create wikidata-XX files
public static bool makeislands = false; //create islands-XX files
public static bool makelakes = false; //create lakes-XX files
public static bool makeranges = false; //create ranges-XX files
public static bool verifygeonames = false; //doublecheck geonames against wiki
public static bool verifywikidata = false; //doublecheck wikidata
public static bool verifyislands = false; //verify island files, removing duplicates
public static bool verifylakes = false; //verify island files, removing duplicates
public static bool makealtitude = false; //make altitude_XX files
public static bool maketranslit = false; //make translit_XX files
public static bool worldmaponly = false; //create world map
public static bool statisticsonly = false; //gather statistics without actually making anything; can be combined with other options
public static bool savefeaturelink =false; //save a list of what feature codes link to
public static bool savewikilinks = false; //save a list of what the bot wikilinks to
public static bool saveadmlinks = false; //save a list of what the bot wikilinks to
public static bool manualcheck = false; //check name matches manually, if true
public static bool listnative = false; //list article names from native wiki of a country
public static bool forkduplicates = false; //make namefork-duplicates file
public static bool fixsizecats = false; //fix size categories
public static bool testnasa = false; //test nasa data
public static bool retrofitnasa = true; // retrofit existing articles with nasa data
public static bool prefergeonamespop = true; //use population figures from GeoNames rather than wiki
public static bool makedoubles = true; //if suspected double, make article as a copy in doubleprefix folder
public static bool overwrite = false; //if article already exists, overwrite with a new version (if not human-edited)
public static bool reallymake = true; //if false, do dry run without actually loading from or saving to wiki; can be combined with other options
public static bool pauseaftersave = false; //if true, wait for keypress after saving each article
public static bool firstround = true;
public static int maxread = 100000000; //Set to a small number for a limited test run, or to 100000000 for a full run
public class geonameclass //main class for GeoNames entries
public string Name = ""; //main name
public string Name_ml = ""; //name in makelang language
public string asciiname = ""; //name in plain ascii
public List
public double latitude = 0.0;
public double longitude = 0.0;
public char featureclass;
public string featurecode;
//public string countrycode = "XX"; //GeonameID of country in adm[0]!
public List
public List
public List
public int[] adm = new int[5]; // adm[0] = country, adm[1] = province, etc.
public long population = 0; //pop according to geonames
public long population_wd = 0; //pop according to wikipedia
public string population_wd_iw = ""; //language from which pop is taken
public int elevation = 0;
public int elevation_vp = 0;
public int prominence = 0;
public double width = 0; //largest horizontal dimension in km
public int island = 0; //if located on island, gnid of island
public int inlake = 0; //if located in lake, gnid of lake
public int inrange = 0; //if mountain part of range, gnid of range
public List
public double area = 0.0; //area from wikipedia
public int dem = 0;
public string tz = "";
public string moddate = "1901-01-01";
public string articlename = ""; //article name, with disambiguation
public string unfixedarticlename = ""; //article name before fixing oddities
public string oldarticlename = ""; //article name in previous bot run
public string artname2 = ""; //article name in other bot language, for interwiki linking
public int wdid = -1; //wikidata id
public class forkclass //class for entries in a fork page
public int geonameid = 0;
public string featurecode = "";
public string[] admname = new string[3];
public double latitude = 0.0;
public double longitude = 0.0;
public string realname = "*";
public int wdid = -1; //wikidata id
public string iso = "XX"; //country iso code
public string featurename = "";
public class altnameclass //class for alternate names from GeoNames
public int altid = 0;
public string altname = "";
public int ilang = -1;
public string wikilink = "";
public bool official = false;
public bool shortform = false;
public bool colloquial = false;
public bool historic = false;
public class countryclass //class for country data
public string Name = ""; //main name
public string Name_ml = ""; //name in makelang language
public string asciiname = ""; //name in plain ascii
public List
public string iso = "XX";
public string iso3 = "XXX";
public int isonumber = 0;
public string fips = "XX";
public string capital = "";
public int capital_gnid = 0;
public double area = 0.0;
public long population = 0;
public string continent = "EU";
public string tld = ".xx";
public string currencycode = "USD";
public string currencyname = "Dollar";
public string phone = "1-999";
public string postalcode = "#####";
public string nativewiki = "";
public List
public List
public class langclass
public string iso3 = "";
public string iso2 = "";
public Dictionary
public class admclass //names of administrative entities by level, one admclass for each country
public string[] label = new string[5];
public string[] det = new string[5];
public int maxadm = 5;
public class tzclass //time zone class
public string offset = "0";
public string summeroffset = "0";
public string rawoffset = "0";
public string tzname = "";
public string tzsummer = "";
public string tzfull = "";
public string tzfullsummer = "";
public class islandclass //data for each island
public double area = 0;
public double kmew = 0;
public double kmns = 0;
public List
public class rangeclass //data for each MTS/HLLS
public double length = 0;
public string orientation = "....";
public double angle = 0; //polar angle of long axis (radians). 0 or pi = EW, pi/2 or 3pi/2 = NS etc.
public double kmew = 0;
public double kmns = 0;
public int maxheight = 0; //highest point; gnid of peak if negative, height if positive
public double hlat = 999; //latitude/longitude of highest point
public double hlon = 999;
public List
public class lakeclass //data for each lake
public double area = 0;
public double kmew = 0;
public double kmns = 0;
public List
public List
public class Disambigclass //class for disambiguation in article names
public bool existsalready = false;
public bool country = false;
public bool adm1 = false;
public bool adm2 = false;
public bool latlong = false;
public bool fcode = false;
public forkclass fork = new forkclass();
public class wdminiclass //minimal wikidata entry needed for verifying Geonames-links
public int gnid = 0;
public double latitude = 9999.9;
public double longitude = 9999.9;
public List
public double dist = 9999.9;
public bool okdist = false;
public bool okclass = false;
public bool goodmatch = false;
public class existingclass //for existing geography articles on target wiki
public string articlename = "";
public double latitude = 9999.9;
public double longitude = 9999.9;
public class nasaclass
public int landcover = -1; //Landcover code 1-17 http://eospso.nasa.gov/sites/default/files/atbd/atbd_mod12.pdf
public int popdensity = -1; //people per square km
public int temp_average = -999; //average across months and day-night
public int temp_max = -999; //temp of hottest month
public int month_max = -999; //hottest month (1-12)
public int temp_min = -999; //temp of coldest month
public int month_min = -999; //coldest month
public int temp_daynight = -999; //average difference between day and night
public int rainfall = -999; //mm per year
public int rain_max = -999; //rain wettest month
public int rain_month_max = -999; //wettest month (1-12)
public int rain_min = 99999; //rain driest month
public int rain_month_min = -999; //driest month
public double rainfall_double = 0; //mm per year
public int koppen = -1;
public int[] month_temp_day = new int[13] { -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999 };
public int[] month_temp_night = new int[13] { -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999 };
public int[] month_rain = new int[13] { -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999, -999 };
public class chinese_pop_class
public int adm1 = -1;
public long pop = -1;
public long malepop = -1;
public long femalepop = -1;
public long households = -1;
public long pop014 = -1;
public long pop1564 = -1;
public long pop65 = -1;
public class locatorclass //for locator maps
public string locatorname = ""; //country name in locator template on target wiki
public string locatorimage = "";//map image name
public string altlocator = "";
public double latmin = -999;
public double latmax = -999;
public double lonmin = -999;
public double lonmax = -999;
public bool loaded = false;
public string get_locator(double lat,double lon)
if (!loaded)
string templatename = mp(63, null) + mp(72, null).Replace("{{", "") + " " + locatorname;
Console.WriteLine(templatename);
//string imagename = "";
Page ltp = new Page(makesite, templatename);
tryload(ltp, 2);
if (ltp.Exists())
locatorimage = get_pictureparam(ltp);
latmax = get_edgeparam(ltp, "top");
latmin = get_edgeparam(ltp, "bottom");
lonmax = get_edgeparam(ltp, "right");
lonmin = get_edgeparam(ltp, "left");
loaded = true;
if (String.IsNullOrEmpty(altlocator))
if (String.IsNullOrEmpty(locatorname))
if (makelang == "sv")
return "Världen";
else
return "World";
else
return locatorname;
if (latmin < -99) //failed to get edges, probably complicated coordinates
return locatorname;
if (lat < latmin)
return altlocator;
if (lat > latmax)
return altlocator;
if (lon < lonmin)
return altlocator;
if (lon > lonmax)
return altlocator;
return locatorname;
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
//public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
//public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static List
public static Dictionary
public static Dictionary
public static List
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static Dictionary
public static string[] iwlang = { "en", "fr", "de", "es" };
public static Dictionary
public static long minimum_population = 100;
public static double minimum_area = 0.1;
public static int minimum_prominence = 50;
public static DateTime wdtime = new DateTime();
public static DateTime gnfiledate = new DateTime();
public static string dumpdate = "";
public static bool hasnotes = false;
public static Dictionary
public static Dictionary
public static int nwdtot = 0;
public static Exception eglob;
public static bool locatoringeobox = (makelang == "sv"); //only works in Swedish!
public static List
public static Dictionary
public static Dictionary
public static Dictionary
public static List
public static List
public static Dictionary
public static Dictionary
public static int pausetime = 5; //time between saves, modified depending on task
public static Dictionary
public static int resume_at_wdid = -1;
public static string mapfilecache = "NO CACHE";
public static int[,] mapcache = new int[3603,3603];
public static string doubleprefix = "Användare/Lsjbot/Dubletter";
public static Dictionary
public static Dictionary
public static Dictionary
public static Page pconflict = null;
public static Page panomaly = null;
public static bool conflictheadline = false;
public static bool anomalyheadline = false;
public static hbookclass featurehist = new hbookclass();
public static int nedit = 0;
public static DateTime oldtime = DateTime.Now;
public static List
public static string reflist = "
public static string password = "";
public static string tabstring = "\t";
public static char tabchar = tabstring[0];
public static XmlDocument currentxml = new XmlDocument();
//public static XmlNode currentnode;
public static int wdid = -1;
public static Dictionary
public static Site makesite;
public static Site ensite;
public static Site cmsite;
//public static Site wdsite;
public static Page pstats;
public static int badelevation = -99999;
public static CultureInfo culture = CultureInfo.CreateSpecificCulture("sv-SE");
public static CultureInfo culture_en = CultureInfo.CreateSpecificCulture("en-US");
public static NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;
public static NumberFormatInfo nfi_en = new CultureInfo("en-US", false).NumberFormat;
public static NumberFormatInfo nfi_space = new CultureInfo("en-US", false).NumberFormat;
public class rdfclass
public int obj = -1;
public string objstring = "";
public int prop = -1;
public int objlink = -1;
public string value = "";
public class wdtreeclass
public List
public List
public static Dictionary
public class transliterationclass
private string defaultlang = "ru";
private string badreturn = "?";
private string contextdependent = "*";
private List
public List
private Dictionary
public void Addchar(char fromchar, string tochars)
Addchar(fromchar, tochars, defaultlang, false);
public void Addchar(char fromchar, string tochars, bool isvowel)
Addchar(fromchar, tochars, defaultlang, isvowel);
public void Addchar(char fromchar, string tochars, string lang)
Addchar(fromchar, tochars, lang, false);
public void Addchar(char fromchar, string tochars, string lang, bool isvowel)
if (!tldict.ContainsKey(lang))
Dictionary
tldict.Add(lang, csdict);
if (!tldict[lang].ContainsKey(fromchar))
tldict[lang].Add(fromchar, tochars);
if (isvowel)
if (!vowels.Contains(fromchar))
vowels.Add(fromchar);
private string Transchar(char fromchar, char contextbefore, char contextafter, string langparam)
if (Convert.ToInt32(fromchar) <= 0x0041) //punctuation etc.
return fromchar.ToString();
string lang = langparam;
if (!tldict.ContainsKey(lang)) //russian default language
lang = defaultlang;
if ( !tldict[lang].ContainsKey(fromchar))
lang = defaultlang;
if (!tldict[lang].ContainsKey(fromchar))
if (is_latin(fromchar.ToString()))
return fromchar.ToString();
if (!badlist.Contains(fromchar))
badlist.Add(fromchar);
return badreturn;
if (tldict[lang][fromchar] != contextdependent)
return tldict[lang][fromchar];
else //context-dependent:
List
List
if (fromchar == 'Е')
if ((contextbefore == '#') || (vowels.Contains(contextbefore)))
return "Je";
else
return "E";
else if (fromchar == 'е')
if ((contextbefore == '#') || (vowels.Contains(contextbefore)))
return "je";
else
return "e";
else if (fromchar == 'Ё')
if (tszlist.Contains(contextbefore))
return "Io";
else if (jlist.Contains(contextbefore))
return "O";
else
return "Jo";
else if ((fromchar == 'ë') || (fromchar == 'ё'))
if (tszlist.Contains(contextbefore))
return "io";
else if (jlist.Contains(contextbefore))
return "o";
else
return "jo";
else if (fromchar == 'Ю')
if (tszlist.Contains(contextbefore))
return "Iu";
else if (jlist.Contains(contextbefore))
return "U";
else
return "Ju";
else if (fromchar == 'ю')
if (tszlist.Contains(contextbefore))
return "iu";
else if (jlist.Contains(contextbefore))
return "u";
else
return "ju";
else if (fromchar == 'Я')
if (tszlist.Contains(contextbefore))
return "Ia";
else if (jlist.Contains(contextbefore))
return "A";
else
return "Ja";
else if (fromchar == 'я')
if (tszlist.Contains(contextbefore))
return "ia";
else if (jlist.Contains(contextbefore))
return "a";
else
return "ja";
else
if (!badlist.Contains(fromchar))
badlist.Add(fromchar);
return badreturn;
public string Transliterate(string name,string lang)
char[] letters = name.ToCharArray();
string result = "";
for (int ic = 0; ic < letters.Length; ic++)
char contextbefore = '#';
if ( ic > 0 )
contextbefore = letters[ic-1];
char contextafter = '#';
if ( ic < letters.Length-1 )
contextafter = letters[ic+1];
result += Transchar(letters[ic],contextbefore,contextafter,lang);
return result;
public static transliterationclass cyrillic = new transliterationclass();
public static void make_translit()
int icountry = countryid[makecountry];
using (StreamWriter sw = new StreamWriter("translit-" + makecountry + ".txt"))
foreach (int gnid in altdict.Keys)
bool found = false;
string langtouse = countrydict[icountry].nativewiki;
foreach (altnameclass ac in altdict[gnid])
//if (countrydict[icountry].languages.Contains(ac.ilang))
if (langdict.ContainsKey(ac.ilang))
string langname = langdict[ac.ilang].iso2;
if (langname != langtouse)
continue;
string alphabet = get_alphabet(ac.altname);
//Console.WriteLine(ac.altname + ": " + alphabet);
if (alphabet == "cyrillic")
//Console.WriteLine("Transliteration: " + cyrillic.Transliterate(ac.altname, "ru"));
sw.WriteLine(gnid.ToString() + tabstring + ac.altname + tabstring + cyrillic.Transliterate(ac.altname, langname));
found = true;
if ((!found) && ((makecountry == "UA") || (makecountry == "BY")|| (makecountry == "KZ")|| (makecountry == "KG")|| (makecountry == "TJ")))
langtouse = "ru";
foreach (altnameclass ac in altdict[gnid])
//if (countrydict[icountry].languages.Contains(ac.ilang))
if (langdict.ContainsKey(ac.ilang))
string langname = langdict[ac.ilang].iso2;
if (langname != langtouse)
continue;
string alphabet = get_alphabet(ac.altname);
//Console.WriteLine(ac.altname + ": " + alphabet);
if (alphabet == "cyrillic")
//Console.WriteLine("Transliteration: " + cyrillic.Transliterate(ac.altname, "ru"));
sw.WriteLine(gnid.ToString() + tabstring + ac.altname + tabstring + cyrillic.Transliterate(ac.altname, langname));
found = true;
sw.Write("Badlist:");
foreach (char c in cyrillic.badlist)
sw.Write(c);
sw.WriteLine();
altdict.Clear();
public static void fill_cyrillic()
//Swedish transliteration!
cyrillic.Addchar('А', "A", true);
cyrillic.Addchar('а', "a", true);
cyrillic.Addchar('Б', "B");
cyrillic.Addchar('б', "b");
cyrillic.Addchar('В', "V");
cyrillic.Addchar('в', "v");
cyrillic.Addchar('Г', "H", "uk");
cyrillic.Addchar('г', "h", "uk");
cyrillic.Addchar('Г', "H", "be");
cyrillic.Addchar('г', "h", "be");
cyrillic.Addchar('Г', "G");
cyrillic.Addchar('г', "g");
cyrillic.Addchar('Ѓ', "Ǵ");
cyrillic.Addchar('ѓ', "ǵ");
cyrillic.Addchar('Ґ', "G");
cyrillic.Addchar('ґ', "g");
cyrillic.Addchar('Д', "D");
cyrillic.Addchar('д', "d");
cyrillic.Addchar('Ђ', "D");
cyrillic.Addchar('ђ', "đ");
cyrillic.Addchar('Ђ', "Dj","sr");
cyrillic.Addchar('ђ', "dj","sr");
cyrillic.Addchar('Е', "*", true);
cyrillic.Addchar('е', "*", true);
cyrillic.Addchar('Е', "E", "uk", true);
cyrillic.Addchar('е', "e", "uk", true);
cyrillic.Addchar('Е', "E", "bg", true);
cyrillic.Addchar('е', "e", "bg", true);
cyrillic.Addchar('Ё', "*", true);
cyrillic.Addchar('ë', "*", true);
cyrillic.Addchar('ё', "*", true);
cyrillic.Addchar('Є', "Je", true);//є
cyrillic.Addchar('є', "je", true);
cyrillic.Addchar('Ж', "Zj");
cyrillic.Addchar('ж', "zj");
cyrillic.Addchar('Ж', "Ž", "sr");
cyrillic.Addchar('ж', "Ž".ToLower(), "sr");
cyrillic.Addchar('Ж', "Ž", "mk");
cyrillic.Addchar('ж', "Ž".ToLower(), "mk");
cyrillic.Addchar('З', "Z");
cyrillic.Addchar('з', "z");
cyrillic.Addchar('Ѕ', "Dz", "mk");
cyrillic.Addchar('ѕ', "dz", "mk");
cyrillic.Addchar('И', "Y", "uk", true);
cyrillic.Addchar('и', "y", "uk", true);
cyrillic.Addchar('И', "Y", "be", true);
cyrillic.Addchar('и', "y", "be", true);
cyrillic.Addchar('И', "I", true);
cyrillic.Addchar('и', "i", true);
cyrillic.Addchar('Й', "J");
cyrillic.Addchar('й', "j");
cyrillic.Addchar('І', "I", true);
cyrillic.Addchar('і', "і", true);
cyrillic.Addchar('Ї', "Ji", true);
cyrillic.Addchar('ї', "ji", true);
cyrillic.Addchar('J', "J");
cyrillic.Addchar('j', "j");
cyrillic.Addchar('К', "K");//seemingly identical
cyrillic.Addchar('K', "K");//but different unicodes
cyrillic.Addchar('к', "k");
cyrillic.Addchar('Ќ', "Ḱ");
cyrillic.Addchar('ќ', "ḱ");
cyrillic.Addchar('Л', "L");
cyrillic.Addchar('л', "l");
cyrillic.Addchar('Љ', "Lj");
cyrillic.Addchar('љ', "lj");
cyrillic.Addchar('М', "M");
cyrillic.Addchar('м', "m");
cyrillic.Addchar('Н', "N");
cyrillic.Addchar('н', "n");
cyrillic.Addchar('Њ', "Nj");
cyrillic.Addchar('њ', "nj");
cyrillic.Addchar('О', "O", true);
cyrillic.Addchar('о', "o", true);
cyrillic.Addchar('o', "o", true);
cyrillic.Addchar('П', "P");
cyrillic.Addchar('п', "p");
cyrillic.Addchar('Р', "R");
cyrillic.Addchar('р', "r");
cyrillic.Addchar('С', "S");//seemingly identical
cyrillic.Addchar('C', "S");//but different unicodes
cyrillic.Addchar('с', "s");
cyrillic.Addchar('Т', "T");
cyrillic.Addchar('т', "t");
cyrillic.Addchar('Ћ', "Ć");
cyrillic.Addchar('ћ', "ć");
cyrillic.Addchar('У', "U", true);
cyrillic.Addchar('у', "u", true);
cyrillic.Addchar('Ў', "Ŭ", true);
cyrillic.Addchar('ў', "ŭ", true);
cyrillic.Addchar('Ф', "F");
cyrillic.Addchar('ф', "f");
cyrillic.Addchar('Х', "H", "sr");
cyrillic.Addchar('х', "h", "sr");
cyrillic.Addchar('Х', "H", "mk");
cyrillic.Addchar('х', "h", "mk");
cyrillic.Addchar('Х', "Ch");
cyrillic.Addchar('х', "ch");
cyrillic.Addchar('Ц', "Ts");
cyrillic.Addchar('ц', "ts");
cyrillic.Addchar('Ц', "C","sr");
cyrillic.Addchar('ц', "c","sr");
cyrillic.Addchar('Ц', "C","mk");
cyrillic.Addchar('ц', "c","mk");
cyrillic.Addchar('Ч', "Tj");
cyrillic.Addchar('ч', "tj");
cyrillic.Addchar('Ч', "Č","sr");
cyrillic.Addchar('ч', "Č".ToLower(),"sr");
cyrillic.Addchar('Ч', "Č","mk");
cyrillic.Addchar('ч', "Č".ToLower(),"mk");
cyrillic.Addchar('Џ', "Dž");
cyrillic.Addchar('џ', "dž");
cyrillic.Addchar('Ш', "Sj");
cyrillic.Addchar('ш', "sj");
cyrillic.Addchar('Ш', "Š","sr");
cyrillic.Addchar('ш', "Š".ToLower(),"sr");
cyrillic.Addchar('Щ', "Sjt", "bg");
cyrillic.Addchar('щ', "sjt", "bg");
cyrillic.Addchar('Щ', "Sjtj");
cyrillic.Addchar('щ', "sjtj");
cyrillic.Addchar('Ъ', "", true);
cyrillic.Addchar('ъ', "", true);
cyrillic.Addchar('Ъ', "", true);
cyrillic.Addchar('ъ', "", true);
cyrillic.Addchar('Ы', "Y", true);
cyrillic.Addchar('ы', "y", true);
cyrillic.Addchar('Ь', "", true);
cyrillic.Addchar('ь', "", true);
cyrillic.Addchar('Ѣ', "", true);
cyrillic.Addchar('ѣ', "", true);
cyrillic.Addchar('Э', "E", true);
cyrillic.Addchar('э', "e", true);
cyrillic.Addchar('Ю', "*", true);
cyrillic.Addchar('ю', "*", true);
cyrillic.Addchar('Я', "*", true);
cyrillic.Addchar('я', "*", true);
cyrillic.Addchar('Ө', "Ḟ");
cyrillic.Addchar('ө', "ḟ");
cyrillic.Addchar('Ѵ', "Ẏ");
cyrillic.Addchar('ѵ', "ẏ");
cyrillic.Addchar('Ѫ', "A", true);
cyrillic.Addchar('ѫ', "a", true);//“”
cyrillic.Addchar('“', "“");
cyrillic.Addchar('”', "”");
cyrillic.Addchar('«', "«");
cyrillic.Addchar('»', "»");
cyrillic.Addchar('’', "’");
cyrillic.Addchar('„', "„");
cyrillic.Addchar('´', "");//
cyrillic.Addchar('Ғ', "Gh","kk");
cyrillic.Addchar('ғ', "gh");
cyrillic.Addchar('Ə', "Ä","kk",true);
cyrillic.Addchar('ə', "ä","kk",true);
cyrillic.Addchar('İ', "I","kk",true);
cyrillic.Addchar('і', "i","kk",true);
cyrillic.Addchar('Қ', "Q","kk");
cyrillic.Addchar('қ', "q", "kk");
cyrillic.Addchar('қ', "q");
cyrillic.Addchar('Ң', "Ng", "kk");
cyrillic.Addchar('ң', "ng","kk");
cyrillic.Addchar('Ө', "Ö","kk",true);
cyrillic.Addchar('ө', "ö","kk",true);
cyrillic.Addchar('Ү', "Ü","kk",true);
cyrillic.Addchar('ү', "ü","kk",true);
cyrillic.Addchar('Ұ', "U","kk",true);
cyrillic.Addchar('ұ', "u","kk",true);
cyrillic.Addchar('Һ', "H","kk");
cyrillic.Addchar('һ', "h","kk");
cyrillic.Addchar('Ң', "Ng","ky");
cyrillic.Addchar('ң', "ng","ky");
cyrillic.Addchar('Ө', "Ö","ky",true);
cyrillic.Addchar('ө', "ö","ky",true);
cyrillic.Addchar('Ү', "Ü","ky",true);
cyrillic.Addchar('ү', "ü", "ky", true);
cyrillic.Addchar('γ', "ü", true);
cyrillic.Addchar('Ғ', "Gh","tg");
cyrillic.Addchar('ғ', "gh","tg");
cyrillic.Addchar('Ӣ', "Y","tg",true);
cyrillic.Addchar('ӣ', "y","tg",true);
cyrillic.Addchar('Қ', "Q","tg");
cyrillic.Addchar('қ', "q","tg");
cyrillic.Addchar('Ӯ', "Ö","tg",true);
cyrillic.Addchar('ӯ', "ö","tg",true);
cyrillic.Addchar('Ҳ', "H","tg");
cyrillic.Addchar('ҳ', "h","tg");
cyrillic.Addchar('Ҷ', "Dzj","tg");
cyrillic.Addchar('ҷ', "dzj","tg");
cyrillic.Addchar('ж', "j","mn");
cyrillic.Addchar('Ж', "J","mn");
cyrillic.Addchar('З', "Dz","mn");
cyrillic.Addchar('з', "dz","mn");
cyrillic.Addchar('Ы', "Ij","mn");
cyrillic.Addchar('ы', "ij","mn");
cyrillic.Addchar('Ө', "Ö", "mn", true);
cyrillic.Addchar('ө', "ö", "mn", true);
cyrillic.Addchar('Ү', "Ü", "mn", true);
cyrillic.Addchar('ү', "ü", "mn", true);//
cyrillic.Addchar('ј', "j");
cyrillic.Addchar('Ј', "J");
cyrillic.Addchar('ј', "j");
cyrillic.Addchar('ј', "j");
cyrillic.Addchar('ј', "j");
public static int LevenshteinDistance(string src, string dest)
//From http://www.codeproject.com/Articles/36869/Fuzzy-Search
//License CPOL (http://www.codeproject.com/info/cpol10.aspx)
int[,] d = new int[src.Length + 1, dest.Length + 1];
int i, j, cost;
char[] str1 = src.ToCharArray();
char[] str2 = dest.ToCharArray();
for (i = 0; i <= str1.Length; i++)
d[i, 0] = i;
for (j = 0; j <= str2.Length; j++)
d[0, j] = j;
for (i = 1; i <= str1.Length; i++)
for (j = 1; j <= str2.Length; j++)
if (str1[i - 1] == str2[j - 1])
cost = 0;
else
cost = 1;
d[i, j] =
Math.Min(
d[i - 1, j] + 1, // Deletion
Math.Min(
d[i, j - 1] + 1, // Insertion
d[i - 1, j - 1] + cost)); // Substitution
if ((i > 1) && (j > 1) && (str1[i - 1] ==
str2[j - 2]) && (str1[i - 2] == str2[j - 1]))
d[i, j] = Math.Min(d[i, j], d[i - 2, j - 2] + cost);
return d[str1.Length, str2.Length];
public static void test_levenshtein()
while (true)
Console.Write("string 1:");
string s1 = Console.ReadLine();
Console.Write("string 2:");
string s2 = Console.ReadLine();
int dist = LevenshteinDistance(s1, s2);
Console.WriteLine("Distance = " + dist.ToString());
public class hbookclass
private SortedDictionary
private SortedDictionary
private SortedDictionary
private const int MAXBINS = 202;
private double[] binlimits = new double[MAXBINS];
private double binmax = 100;
private double binmin = 0;
private double binwid = 0;
private int nbins = MAXBINS - 2;
public void Add(string key)
if (!shist.ContainsKey(key))
shist.Add(key, 1);
else
shist[key]++;
public void Add(char key)
if (!shist.ContainsKey(key.ToString()))
shist.Add(key.ToString(), 1);
else
shist[key.ToString()]++;
public void Add(int key)
if (!ihist.ContainsKey(key))
ihist.Add(key, 1);
else
ihist[key]++;
private int valuetobin(double key)
int bin = 0;
if (key > binmin)
if (key > binmax)
bin = nbins + 1;
else
bin = (int)((key - binmin) / binwid) + 1;
return bin;
private double bintomin(int bin)
if (bin == 0)
return binmin;
if (bin > nbins)
return binmax;
return binmin + (bin - 1) * binwid;
private double bintomax(int bin)
if (bin == 0)
return binmin;
if (bin > nbins)
return binmax;
return binmin + bin * binwid;
public void Add(double key)
int bin = valuetobin(key);
if (!ihist.ContainsKey(bin))
ihist.Add(bin, 1);
else
ihist[bin]++;
public void SetBins(double min, double max, int nb)
if (nbins > MAXBINS - 2)
Console.WriteLine("Too many bins. Max " + (MAXBINS - 2).ToString());
return;
else
binmax = max;
binmin = min;
nbins = nb;
binwid = (max - min) / nbins;
binlimits[0] = binmin;
for (int i = 1; i <= nbins; i++)
binlimits[i] = binmin + i * binwid;
for (int i = 0; i <= nbins + 1; i++)
if (!ihist.ContainsKey(i))
ihist.Add(i, 0);
public void PrintIHist()
int total = 0;
foreach (int key in ihist.Keys)
Console.WriteLine(key + ": " + ihist[key].ToString());
total += ihist[key];
Console.WriteLine("----Total : " + total.ToString());
public void PrintDHist()
int total = 0;
foreach (int key in ihist.Keys)
Console.WriteLine(bintomin(key).ToString() + " -- " + bintomax(key).ToString() + ": " + ihist[key].ToString());
total += ihist[key];
Console.WriteLine("----Total : " + total.ToString());
public void PrintSHist()
int total = 0;
foreach (string key in shist.Keys)
Console.WriteLine(key + ": " + shist[key].ToString());
total += shist[key];
Console.WriteLine("----Total : " + total.ToString());
//public class hbookclass
//{
// public Dictionary
// public void Add(string key)
// {
// if (!hist.ContainsKey(key))
// hist.Add(key, 1);
// else
// hist[key]++;
// }
// public void PrintHist()
// {
// int total = 0;
// foreach (string key in hist.Keys)
// {
// Console.WriteLine(key + ": " + hist[key].ToString());
// total += hist[key];
// }
// Console.WriteLine("----Total : "+total.ToString());
// }
// public void PrintLarge(int min)
// {
// int total = 0;
// foreach (string key in hist.Keys)
// {
// if (hist[key] > min)
// {
// Console.WriteLine(key + ": " + hist[key].ToString());
// total += hist[key];
// }
// }
// Console.WriteLine("----Total : "+total.ToString());
// }
//}
public static hbookclass fchist = new hbookclass();
public static hbookclass fcbad = new hbookclass();
public static hbookclass fcathist = new hbookclass();
public static hbookclass fclasshist = new hbookclass();
public static hbookclass evarhist = new hbookclass();
public static hbookclass slope1hist = new hbookclass();
public static hbookclass slope5hist = new hbookclass();
public static hbookclass slopermshist = new hbookclass();
public static hbookclass ndirhist = new hbookclass();
public static hbookclass nsameterrhist = new hbookclass();
public static hbookclass terrainhist = new hbookclass();
public static hbookclass terraintexthist = new hbookclass();
public static hbookclass elevdiffhist = new hbookclass();
public static hbookclass nwdhist = new hbookclass();
public static hbookclass foverrephist = new hbookclass();
public class statclass
public List
public int nart = 0;
public int nredirect = 0;
public int ncat = 0;
public int ndonecat = 0;
public int nbot = 0;
public int ntalk = 0;
public int nskip = 0;
public int milestone = 0;
public int milestone_interval = 1000;
public bool skipmilestone = false;
public int ntowait = 0;
public int nwaited = 0;
public void ClearStat()
sizelist.Clear();
nart = 0;
nredirect = 0;
ncat = 0;
nbot = 0;
ntalk = 0;
ndonecat = 0;
nskip = 0;
public int ArticleCount(Site countsite)
//string xmlSrc = countsite.PostDataAndGetResultHTM(countsite.site + "/w/api.php", "action=query&format=xml&meta=siteinfo&siprop=statistics");
string xmlSrc = countsite.PostDataAndGetResult(countsite.address + "/w/api.php", "action=query&format=xml&meta=siteinfo&siprop=statistics");
//Console.WriteLine(xmlSrc);
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlSrc);
string ts = doc.GetElementsByTagName("statistics")[0].Attributes.GetNamedItem("articles").Value;
Console.WriteLine("ts = " + ts);
return Convert.ToInt32(ts);
public void SetMilestone(int mint, Site countsite)
milestone_interval = mint;
int ac = ArticleCount(countsite);
milestone = ((ac / milestone_interval) + 1) * milestone_interval;
Console.WriteLine("Articlecount = " + ac.ToString() + ", milestone = " + milestone.ToString());
if ((milestone - ac) > 100)
ntowait = (milestone - ac) / 2;
else
ntowait = 0;
nwaited = 0;
public void Addskip()
nskip++;
public void Adddonecat()
ndonecat++;
public void Add(string title, string text,bool savemilestone)
if (title.Contains(mp(1, null)))
ncat++;
else if (title.Contains(botname))
nbot++;
else if (text.Contains(mp(2, null)))
nredirect++;
else if (title.Contains(mp(38, null)))
ntalk++;
else if (!title.Contains(":"))
nart++;
sizelist.Add(text.Length);
nwaited++;
if (nwaited >= ntowait)
int ac = ArticleCount(makesite);
if (ac >= milestone)
Console.WriteLine("Milestone reached: ac = " + ac.ToString());
SetMilestone(milestone_interval, makesite);
if (savemilestone)
if (pstats == null)
pstats = new Page(makesite, mp(13, null) + botname + "/Statistik");
pstats.Load();
pstats.text += "\n\nMilstolpe: artikel #" + ac.ToString() + " är [[" + title + "]]\n\n";
trysave(pstats, 3);
Console.WriteLine("Articlecount = " + ac.ToString() + ", milestone = " + milestone.ToString());
if ((milestone - ac) > 10)
ntowait = (milestone - ac) / 2;
else if (!skipmilestone || ((milestone - ac) > 1))
ntowait = 0;
else
while (ac < milestone)
Console.WriteLine("Waiting for milestone...");
Thread.Sleep(60000);//milliseconds
ac = ArticleCount(makesite);
ntowait = 0;
nwaited = 0;
public string GetStat()
string s = "* Antal artiklar: " + (nart+nskip).ToString() + "\n";
//int sum = 0;
SortedDictionary
int isum = 0;
int mean = 0;
foreach (int i in sizelist)
isum += i;
if (hist.ContainsKey(i))
hist[i]++;
else
hist.Add(i, 1);
if (nart > 0)
mean = isum / nart;
else
return s;
int icum = 0;
int median = 0;
foreach (int i in hist.Keys)
icum += hist[i];
if (icum >= (nart / 2))
median = i;
break;
s += "** Medellängd: " + mean.ToString() + " bytes\n";
s += "** Medianlängd: " + median.ToString() + " bytes\n";
if ( nskip == 0 )
s += "* Antal kategorier: " + ncat.ToString() + "\n";
else
s += "* Antal kategorier: " + ndonecat.ToString() + "\n";
s += "* Antal omdirigeringar: " + nredirect.ToString() + "\n";
s += "* Antal diskussionssidor: " + ntalk.ToString() + "\n";
s += "* Antal anomalier: " + nbot.ToString() + "\n";
s += "\n";
return s;
public static statclass stats = new statclass();
public static string getgnidname(int gnid)
if (!gndict.ContainsKey(gnid))
return null;
else
return gndict[gnid].Name_ml;
public static string getartname(int gnid)
if (!gndict.ContainsKey(gnid))
return null;
else
return gndict[gnid].articlename.Replace("*","");
public static string fixcase(string ss)
string s = String.Copy(ss);
for (int i = 1; i < s.Length; i++)
if ((s[i - 1] != ' ') && (s[i - 1] != '.'))
s = s.Remove(i, 1).Insert(i, Char.ToLower(s[i]).ToString());
return s;
public static void read_phrases()
using (StreamReader sr = new StreamReader(geonamesfolder + "phraselist.txt"))
String headline = "";
headline = sr.ReadLine();
int icol = 0;
string[] langs = headline.Split(tabchar);
for (icol = 0; icol < langs.Length; icol++)
if (langs[icol] == makelang)
break;
while (!sr.EndOfStream)
String line = sr.ReadLine();
//Console.WriteLine(line);
string[] words = line.Split(tabchar);
if (words.Length < icol + 1)
continue;
//for (int jj = 1; jj < words.Length; jj++)
//{
// words[jj] = words[jj].Trim();
//}
int ip = tryconvert(words[0]);
phrases.Add(ip, words[icol]);
public static string mp(int np, string[] param)
if (phrases.Count == 0)
read_phrases();
int ip = 0;
string sret = phrases[np];
if (param != null)
foreach (string s in param)
ip++;
sret = sret.Replace("#" + ip.ToString(), s);
return sret;
public static string ReplaceOne(string textparam, string oldt, string newt, int position) //Replace ONE occurrence of oldt in textparam, the first one after position
string text = textparam;
int oldpos = text.IndexOf(oldt, position);
if (oldpos < 0)
return text;
text = text.Remove(oldpos, oldt.Length);
text = text.Insert(oldpos, newt);
return text;
public static List
int start = 0;
int pos = 0;
List
do
pos = text.IndexOf(find, start);
if (pos >= 0)
start = pos + find.Length;
rl.Add(pos);
while (pos >= 0);
return rl;
public static void make_redirect(string frompage, string topage)
make_redirect(frompage, topage, "", -1);
public static void make_redirect(string frompage, string topage, string cat, int ilang)
if (String.IsNullOrEmpty(frompage))
return;
if (String.IsNullOrEmpty(topage))
return;
Page pred = new Page(makesite, frompage);
if (tryload(pred, 1))
if (!pred.Exists())
pred.text = "#" + mp(2, null) + " [[" + topage + "]]\n";
if (makelang == "sv")
if (langdict.ContainsKey(ilang))
pred.text += "{{Omdirigering på annat språk|" + langdict[ilang].iso3 + "}}\n";
if (!is_latin(remove_disambig(pred.title)))
string alph_sv = get_alphabet_sv(get_alphabet(remove_disambig(pred.title)));
Console.WriteLine(alph_sv);
if (!alph_sv.Contains("okänd"))
pred.text += "{{Sidnamn annan skrift|" + alph_sv + "}}\n";
else
Console.WriteLine(pred.title);
Console.WriteLine(remove_disambig(pred.title));
Console.WriteLine(alph_sv);
Console.ReadLine();
if (!String.IsNullOrEmpty(cat))
pred.AddToCategory(cat);
string ec = makesite.defaultEditComment;
makesite.defaultEditComment = mp(60, null) + " " + countryml[makecountryname] + " " + mp(2,null).ToLower();
trysave(pred, 2);
makesite.defaultEditComment = ec;
public static void make_redirect_override(Page pred, string topage, string cat, int ilang)
pred.text = "#" + mp(2, null) + " [[" + topage + "]]\n";
if (makelang == "sv")
if (langdict.ContainsKey(ilang))
pred.text += "{{Omdirigering på annat språk|" + langdict[ilang].iso3 + "}}\n";
if (!is_latin(remove_disambig(pred.title)))
string alph_sv = get_alphabet_sv(get_alphabet(remove_disambig(pred.title)));
if (!alph_sv.Contains("okänd"))
pred.text += "{{Sidnamn annan skrift|" + alph_sv + "}}\n";
else
Console.WriteLine(pred.title);
Console.WriteLine(remove_disambig(pred.title));
Console.WriteLine(alph_sv);
Console.ReadLine();
if (!String.IsNullOrEmpty(cat))
pred.AddToCategory(cat);
string ec = makesite.defaultEditComment;
makesite.defaultEditComment = mp(60, null) + " " + countryml[makecountryname] + " " + mp(2, null).ToLower();
trysave(pred, 2);
makesite.defaultEditComment = ec;
public static void romanian_redirect(string topage)
string frompage = topage;
Dictionary
romchars.Add('ş', 'ș');
romchars.Add('ţ', 'ț');
foreach (char c in romchars.Keys)
frompage = frompage.Replace(c, romchars[c]);
if (frompage != topage)
make_redirect(frompage, topage, "", -1);
frompage = topage;
foreach (char c in romchars.Keys)
frompage = frompage.Replace(romchars[c], c);
if (frompage != topage)
make_redirect(frompage, topage, "", -1);
public static string initialcap(string orig)
if (String.IsNullOrEmpty(orig))
return "";
int initialpos = 0;
if (orig.IndexOf('|') > 0)
initialpos = orig.IndexOf('|') + 1;
else if (orig.IndexOf("[[") >= 0)
initialpos = orig.IndexOf("[[") + 2;
string s = orig.Substring(initialpos, 1);
s = s.ToUpper();
string final = orig;
final = final.Remove(initialpos, 1).Insert(initialpos, s);
//s += orig.Remove(0, 1);
return final;
public static bool tryload(Page p, int iattempt)
int itry = 1;
if (!reallymake)
Console.WriteLine("NOT loading " + p.title);
return true;
if (String.IsNullOrEmpty(p.title))
return false;
while (true)
try
p.Load();
return true;
catch (WebException e)
string message = e.Message;
Console.Error.WriteLine("tl we "+message);
itry++;
if (itry > iattempt)
return false;
else
Thread.Sleep(600000);//milliseconds
catch (NullReferenceException e)
string message = e.Message;
Console.Error.WriteLine("tl ne " + message);
itry++;
if (itry > iattempt)
return false;
else
Thread.Sleep(6000);//milliseconds
public static bool trysave(Page p, int iattempt)
int itry = 1;
if (!reallymake)
return true;
while (true)
try
//Bot.editComment = mp(60, null);
p.Save();
stats.Add(p.title, p.text, (makearticles || makefork));
DateTime newtime = DateTime.Now;
while (newtime < oldtime)
newtime = DateTime.Now;
oldtime = newtime.AddSeconds(pausetime);
if (pauseaftersave)
Console.WriteLine("
Console.ReadKey();
return true;
catch (WebException e)
string message = e.Message;
Console.Error.WriteLine("ts we " + message);
itry++;
if (itry > iattempt)
return false;
else
Thread.Sleep(600000);//milliseconds
catch (WikiBotException e)
string message = e.Message;
Console.Error.WriteLine("ts wbe " + message);
if (message.Contains("Bad title"))
return false;
itry++;
if (itry > iattempt)
return false;
else
Thread.Sleep(600000);//milliseconds
catch (IOException e)
string message = e.Message;
Console.Error.WriteLine("ts ioe " + message);
itry++;
if (itry > iattempt)
return false;
else
Thread.Sleep(600000);//milliseconds
public static int tryconvert(string word)
int i = -1;
try
i = Convert.ToInt32(word);
catch (OverflowException)
Console.WriteLine("i Outside the range of the Int32 type: " + word);
catch (FormatException)
//if ( !String.IsNullOrEmpty(word))
// Console.WriteLine("i Not in a recognizable format: " + word);
return i;
public static long tryconvertlong(string word)
long i = -1;
try
i = Convert.ToInt64(word);
catch (OverflowException)
Console.WriteLine("i Outside the range of the Int64 type: " + word);
catch (FormatException)
Console.WriteLine("i Not in a recognizable long format: " + word);
return i;
public static double tryconvertdouble(string word)
double i = -1;
try
i = Convert.ToDouble(word);
catch (OverflowException)
Console.WriteLine("i Outside the range of the Double type: " + word);
catch (FormatException)
try
i = Convert.ToDouble(word.Replace(".",","));
catch (FormatException)
Console.WriteLine("i Not in a recognizable double format: " + word.Replace(".", ","));
//Console.WriteLine("i Not in a recognizable double format: " + word);
return i;
public static void fill_propdict()
propdict.Add("country",17);
propdict.Add("capital",36);
propdict.Add("commonscat",373);
propdict.Add("coat of arms",94);
propdict.Add("locatormap",242);
propdict.Add("flag",41);
propdict.Add("timezone",421);
propdict.Add("kids",150);
propdict.Add("parent",131);
propdict.Add("iso",300);
propdict.Add("borders",47);
propdict.Add("coordinates",625);
propdict.Add("inception",571);
propdict.Add("head of government",6);
propdict.Add("gnid",1566);
propdict.Add("follows",155);
propdict.Add("category dead",1465);
propdict.Add("category born",1464);
propdict.Add("category from",1792);
propdict.Add("image",18);
propdict.Add("banner",948);
//propdict.Add("sister city",190);
propdict.Add("postal code", 281);
propdict.Add("position", 625);
propdict.Add("population", 1082);
propdict.Add("instance", 31);
propdict.Add("subclass", 279);
propdict.Add("nexttowater", 206);
//propdict.Add("",);
public static void read_adm1()
int n = 0;
using (StreamReader sr = new StreamReader(geonamesfolder + "admin1CodesASCII.txt"))
while (!sr.EndOfStream)
String line = sr.ReadLine();
if (line[0] == '#')
continue;
//if (n > 250)
// Console.WriteLine(line);
string[] words = line.Split(tabchar);
//foreach (string s in words)
// Console.WriteLine(s);
//Console.WriteLine(words[0] + "|" + words[1]);
// public static Dictionary
int geonameid = -1;
geonameid = tryconvert(words[3]);
string[] ww = words[0].Split('.');
if (adm1dict.ContainsKey(ww[0]))
adm1dict[ww[0]].Add(ww[1], geonameid);
else
Dictionary
dd.Add(ww[1], geonameid);
adm1dict.Add(ww[0], dd);
if (ww[0] == makecountry)
Console.WriteLine("adm1:" + words[0] + ":" + geonameid.ToString());
n++;
if ((n % 1000) == 0)
Console.WriteLine("n (adm1) = " + n.ToString());
Console.WriteLine("n (adm1)= " + n.ToString());
//Console.WriteLine("
//Console.ReadLine();
public static void read_adm2()
int n = 0;
using (StreamReader sr = new StreamReader(geonamesfolder + "admin2Codes.txt"))
while (!sr.EndOfStream)
String line = sr.ReadLine();
if (line[0] == '#')
continue;
//if (n > 250)
// Console.WriteLine(line);
string[] words = line.Split(tabchar);
//foreach (string s in words)
// Console.WriteLine(s);
//Console.WriteLine(words[0] + "|" + words[1]);
// public static Dictionary
countryclass country = new countryclass();
int geonameid = -1;
geonameid = tryconvert(words[3]);
string[] ww = words[0].Split('.');
if (!adm2dict.ContainsKey(ww[0]))
Dictionary
adm2dict.Add(ww[0], dd);
if ( adm2dict[ww[0]].ContainsKey(ww[1]))
adm2dict[ww[0]][ww[1]].Add(ww[2], geonameid);
else
Dictionary
ddd.Add(ww[2], geonameid);
adm2dict[ww[0]].Add(ww[1], ddd);
n++;
if ((n % 10000) == 0)
Console.WriteLine("n (adm2) = " + n.ToString());
Console.WriteLine("n (adm2)= " + n.ToString());
public static void read_timezone()
int n = 0;
tzdict.Clear();
tznamedict.Clear();
tzsummerdict.Clear();
tzfulldict.Clear();
tzfullsummerdict.Clear();
string filename = "timezonenames.txt";
//first look if timezone name file exists for specific country...
filename = "timezonenames-" + makecountry + ".txt";
//Console.WriteLine(filename);
//... then for continent...
if ( !File.Exists(geonamesfolder+filename))
if ( ( !String.IsNullOrEmpty(makecountry)) && countryid.ContainsKey(makecountry))
filename = "timezonenames-"+countrydict[countryid[makecountry]].continent+".txt";
//...otherwise default names.
if ( !File.Exists(geonamesfolder+filename))
filename = "timezonenames.txt";
Console.WriteLine(filename);
//Console.ReadLine();
using (StreamReader sr = new StreamReader(geonamesfolder + filename))
//String line = sr.ReadLine();
//line = sr.ReadLine();
while (!sr.EndOfStream)
String line = sr.ReadLine();
//Console.WriteLine(line);
n++;
string[] words = line.Split(tabchar);
if (!String.IsNullOrEmpty(words[1]))
tznamedict.Add(words[0], words[1]);
if (!String.IsNullOrEmpty(words[2]))
tzsummerdict.Add(words[0], words[2]);
if (!String.IsNullOrEmpty(words[3]))
tzfulldict.Add(words[0], words[3]);
if ((words.Length > 4 ) && (!String.IsNullOrEmpty(words[4])))
tzfullsummerdict.Add(words[0], words[4]);
n = 0;
Console.WriteLine("tznamedict.Count = " + tznamedict.Count);
//Console.ReadLine();
if (savewikilinks)
Page pt = new Page(makesite, mp(13, null) + botname + "/timezonelinks");
pt.text = "Timezone links used by Lsjbot\n\n";
foreach (string tz in tznamedict.Keys)
pt.text += "* UTC" + tz + " [[" + tzfulldict[tz] + "|" + tznamedict[tz] + "]]\n";
foreach (string tz in tzsummerdict.Keys)
pt.text += "* UTC" + tz + " [[" + tzfullsummerdict[tz] + "|" + tzsummerdict[tz] + "]]\n";
trysave(pt, 1);
using (StreamReader sr = new StreamReader(geonamesfolder + "timeZones.txt"))
String line = sr.ReadLine();
line = sr.ReadLine();
while (!sr.EndOfStream)
line = sr.ReadLine();
//if (n > 250)
// Console.WriteLine(line);
string[] words = line.Split(tabchar);
//foreach (string s in words)
// Console.WriteLine(s);
//Console.WriteLine(words[0] + "|" + words[1]);
// public static Dictionary
tzclass tzz = new tzclass();
for (int ii = 2; ii < 5; ii++)
if (!words[ii].Contains("+") && !words[ii].Contains("-"))
words[ii] = "+" + words[ii];
words[ii] = words[ii].Replace(".0", "");
words[ii] = words[ii].Replace(".5", ":30");
words[ii] = words[ii].Replace(".75", ":45");
tzz.offset = words[2];
tzz.summeroffset = words[3];
tzz.rawoffset = words[4];
if (tznamedict.ContainsKey(tzz.offset))
tzz.tzname = tznamedict[tzz.offset];
else
Console.WriteLine("No tzname for |" + tzz.offset + "|");
if (tzfulldict.ContainsKey(tzz.offset))
tzz.tzfull = tzfulldict[tzz.offset];
if ((tzz.summeroffset != tzz.offset) && (tzsummerdict.ContainsKey(tzz.summeroffset)))
tzz.tzsummer = tzsummerdict[tzz.summeroffset];
tzz.tzfullsummer = tzfullsummerdict[tzz.summeroffset];
tzdict.Add(words[1], tzz);
n++;
if ((n % 1000) == 0)
Console.WriteLine("n (timezone) = " + n.ToString());
Console.WriteLine("n (timezone)= " + n.ToString());
//Console.ReadLine();
public static void addnamefork(int geonameid, string Name)
string nn = Name.Trim();
if (String.IsNullOrEmpty(nn))
return;
//Skip numbers and acronyms:
if (tryconvert(Name) > 0)
return;
if ((Name.Length <= 3 ) && (Name == Name.ToUpper()))
return;
if (namefork.ContainsKey(Name))
if (!namefork[Name].Contains(geonameid))
namefork[Name].Add(geonameid);
else
List
ll.Add(geonameid);
namefork.Add(Name, ll);
public static void read_existing_coord()
int n = 0;
using (StreamReader sr = new StreamReader(geonamesfolder + "coord-" + makelang + ".txt"))
while (!sr.EndOfStream)
String line = sr.ReadLine();
//Console.WriteLine(line);
n++;
string[] words = line.Split(tabchar);
if (words.Length < 3)
continue;
existingclass ex = new existingclass();
ex.articlename = words[0];
ex.latitude = tryconvertdouble(words[1]);
ex.longitude = tryconvertdouble(words[2]);
existingdict.Add(n, ex);
addexistinglatlong(ex.latitude, ex.longitude, n);
public static void read_existing_adm1()
//public static Dictionary
PageList pl = new PageList(makesite);
pl.FillAllFromCategory("Kategori:Regionala politiska indelningar");
int n = 0;
foreach (Page p in pl)
string tit = remove_disambig(p.title.Replace("Kategori:", ""));
string country = "";
if (tit.Contains("s "))
country = tit.Substring(0, tit.IndexOf("s "));
else
continue;
PageList pl1 = new PageList(makesite);
pl1.FillAllFromCategory(p.title);
foreach (Page p1 in pl1)
string tit1 = p1.title.Replace("Kategori:", "");
if (!existing_adm1.ContainsKey(country))
List
existing_adm1.Add(country, ll);
Console.WriteLine("country = " + country);
existing_adm1[country].Add(tit1);
n++;
Console.WriteLine("n(adm1) = " + n.ToString());
public static void addexistinglatlong(double lat, double lon, int exid)
int ilat = Convert.ToInt32(Math.Truncate(lat));
int ilong = Convert.ToInt32(Math.Truncate(lon));
if (!exlatlong.ContainsKey(ilat))
Dictionary
exlatlong.Add(ilat, dd);
if (!exlatlong[ilat].ContainsKey(ilong))
List
exlatlong[ilat].Add(ilong, ll);
if (!exlatlong[ilat][ilong].Contains(exid))
exlatlong[ilat][ilong].Add(exid);
public static List
List
double kmdeg = 40000 / 360; //km per degree at equator
double r2 = radius * radius / (kmdeg * kmdeg);
double scale = Math.Cos(lat * 3.1416 / 180); //latitude-dependent longitude scale
int ilat = Convert.ToInt32(Math.Truncate(lat));
int ilong = Convert.ToInt32(Math.Truncate(lon));
int cells = Convert.ToInt32(radius / kmdeg + 1);
for (int u = -cells; u < (cells + 1); u++)
for (int v = -cells; v < (cells + 1); v++)
if (exlatlong.ContainsKey(ilat + u))
if (exlatlong[ilat + u].ContainsKey(ilong + v))
foreach (int gnn in exlatlong[ilat + u][ilong + v])
if (!existingdict.ContainsKey(gnn))
continue;
//if ((existingdict[gnn].latitude == lat) && (existingdict[gnn].longitude == lon))
// continue;
double dlat = existingdict[gnn].latitude - lat;
double dlon = (existingdict[gnn].longitude - lon) * scale;
if ((dlat * dlat + dlon * dlon) < r2)
ll.Add(gnn);
return ll;
public static void addlatlong(double lat, double lon, int gnid)
int ilat = Convert.ToInt32(Math.Truncate(lat));
int ilong = Convert.ToInt32(Math.Truncate(lon));
if (!latlong.ContainsKey(ilat))
Dictionary
latlong.Add(ilat, dd);
if (!latlong[ilat].ContainsKey(ilong))
List
latlong[ilat].Add(ilong, ll);
if (!latlong[ilat][ilong].Contains(gnid))
latlong[ilat][ilong].Add(gnid);
public static bool getghostneighbors(double lat, double lon, double radius)
double kmdeg = 40000 / 360; //km per degree at equator
double r2 = radius * radius / (kmdeg * kmdeg);
double scale = Math.Cos(lat * 3.1416 / 180); //latitude-dependent longitude scale
foreach (int gnn in ghostdict.Keys)
double dlat = ghostdict[gnn].latitude - lat;
double dlon = (ghostdict[gnn].longitude - lon) * scale;
if ((dlat * dlat + dlon * dlon) < r2)
return true;
return false;
public static List
List
double kmdeg = 40000 / 360; //km per degree at equator
double r2 = radius * radius / (kmdeg * kmdeg);
double scale = Math.Cos(lat * 3.1416 / 180); //latitude-dependent longitude scale
int ilat = Convert.ToInt32(Math.Truncate(lat));
int ilong = Convert.ToInt32(Math.Truncate(lon));
int cells = Convert.ToInt32(radius / kmdeg + 1);
for (int u = -cells; u < (cells + 1); u++)
for (int v = -cells; v < (cells + 1); v++)
if (latlong.ContainsKey(ilat + u))
if (latlong[ilat + u].ContainsKey(ilong + v))
foreach (int gnn in latlong[ilat + u][ilong + v])
if (!gndict.ContainsKey(gnn))
continue;
if ((gndict[gnn].latitude == lat ) && (gndict[gnn].longitude == lon))
continue;
double dlat = gndict[gnn].latitude - lat;
double dlon = (gndict[gnn].longitude - lon) * scale;
if ((dlat * dlat + dlon * dlon) < r2)
ll.Add(gnn);
return ll;
public static List
List
if (!gndict.ContainsKey(gnid))
return ll;
double lat = gndict[gnid].latitude;
double lon = gndict[gnid].longitude;
ll = getneighbors(lat, lon, radius);
return ll;
public static void read_geoboxes()
int n = 0;
foreach (string geotype in geoboxlist)
string filename = geonamesfolder + "geobox-"+geotype+"-"+makelang+".txt";
using (StreamReader sr = new StreamReader(filename))
geoboxtemplates.Add(geotype, sr.ReadToEnd());
n++;
Console.WriteLine("Read " + n.ToString() + " geoboxes.");
public static void read_categories()
int n = 0;
string filename = geonamesfolder + "categories.txt";
using (StreamReader sr = new StreamReader(filename))
String headline = "";
headline = sr.ReadLine();
int icol = 0;
string[] langs = headline.Split(tabchar);
for (icol = 0; icol < langs.Length; icol++)
if (langs[icol] == makelang)
break;
//public static Dictionary
//public static Dictionary
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
if (words.Length < icol+1)
continue;
parentcategory.Add(words[0], words[1]);
categoryml.Add(words[0], words[icol]);
n++;
if ((n % 100) == 0)
Console.WriteLine("n (categories) = " + n.ToString());
if (n >= 100000000)
break;
Console.WriteLine("n (categories)= " + n.ToString());
public static void read_catstat()
int n = 0;
double nctot = 0;
string filename = geonamesfolder + "catstat.txt";
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(':');
if (words.Length < 2)
continue;
int nc = tryconvert(words[1].Trim());
catstatdict.Add(words[0], nc);
nctot += nc;
n++;
if ((n % 100) == 0)
Console.WriteLine("n (categories) = " + n.ToString());
if (n >= 100000000)
break;
Console.WriteLine("n (categories)= " + n.ToString());
foreach (string s in catstatdict.Keys)
catnormdict.Add(s, catstatdict[s] / nctot);
public static void read_featurecodes()
int n = 0;
int nbad = 0;
string filename = geonamesfolder + "featureCodes.txt";
string lf = "";
using (StreamReader sr = new StreamReader(filename))
String headline = "";
headline = sr.ReadLine();
int icol = 0;
string[] langs = headline.Split(tabchar);
for (icol = 0; icol < langs.Length; icol++)
if (langs[icol] == makelang)
break;
string oldfc0 = "X";
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
string[] fc = words[0].Split('.');
if (words[1] == "0")
nbad++;
continue;
//Console.WriteLine(fc[1]);
featuredict.Add(fc[1], words[icol]);
char fchar = fc[0].ToCharArray()[0];
featureclassdict.Add(fc[1], fchar);
string geotype = words[2];
if ( String.IsNullOrEmpty(geotype))
geotype = "alla";
geoboxdict.Add(fc[1], geotype);
if (!geoboxlist.Contains(geotype))
geoboxlist.Add(geotype);
string catname = words[3];
if (String.IsNullOrEmpty(catname))
catname = "landforms";
categorydict.Add(fc[1], catname);
featurepointdict.Add(fc[1], (words[4] == "1"));
if (savefeaturelink)
if ((!fc[1].Contains("ADM")) && (!fc[1].Contains("PPLA")))
if (fc[0] != oldfc0)
oldfc0 = fc[0];
lf += "\n\n== " + fc[0] + " ==\n\n";
lf += "* " + words[0] +": " + linkfeature(fc[1], -1);
if (words.Length > 8)
lf += " (" + words[8] + ")";
lf += "\n";
n++;
if ((n % 100) == 0)
Console.WriteLine("n (featurecodes) = " + n.ToString());
if (n >= 100000000)
break;
Console.WriteLine("n (featurecodes)= " + n.ToString());
Console.WriteLine("nbad (featurecodes)= " + nbad.ToString());
if ( savefeaturelink )
Console.WriteLine(lf);
Page plf = new Page(makesite,mp(13,null)+botname+"/linkfeatures");
plf.text = lf;
trysave(plf,1);
Console.ReadLine();
read_specialfeatures();
public static void read_specialfeatures()
int n = 0;
string filename = geonamesfolder + "specialfeatures-"+makelang+".txt";
if (!File.Exists(filename))
return;
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
if (words.Length < 2)
continue;
int gnid = tryconvert(words[0]);
if (gnid < 0)
continue;
if (!specialfeaturedict.ContainsKey(gnid))
specialfeaturedict.Add(gnid, words[1]);
if (words.Length >= 3)
if (!admtodet.ContainsKey(words[1]))
admtodet.Add(words[1],words[2]);
n++;
if ((n % 100) == 0)
Console.WriteLine("n (specialfeatures) = " + n.ToString());
if (n >= 100000000)
break;
Console.WriteLine("n (specialfeatures)= " + n.ToString());
public static void make_altitude_files()
elevdiffhist.SetBins(-1000.0, 1000.0, 200);
using (StreamWriter sw = new StreamWriter("altitude-" + makecountry + ".txt"))
int ngnid = gndict.Count;
foreach (int gnid in gndict.Keys)
Console.WriteLine("=====" + makecountry + "======== " + ngnid.ToString() + " remaining. ===========");
ngnid--;
if ((ngnid % 1000) == 0)
Console.WriteLine("Garbage collection:");
GC.Collect();
if ((resume_at > 0) && (resume_at != gnid))
stats.Addskip();
continue;
else
resume_at = -1;
int altitude = get_altitude(gnid);
Console.WriteLine(gndict[gnid].Name + ", " + gndict[gnid].featureclass + "." + gndict[gnid].featurecode + ": " + altitude.ToString());
if (gndict[gnid].elevation > 0)
elevdiffhist.Add(1.0 * (gndict[gnid].elevation - altitude));
if (altitude != 0)
sw.WriteLine(gnid.ToString() + tabstring + altitude.ToString());
elevdiffhist.PrintDHist();
//Console.ReadLine();
public static void read_chinese_pop()
Console.WriteLine("read_chinese_pop");
string filepath = geonamesfolder + @"\China population\";
string filekeyname = filepath + "filekey.txt";
Dictionary
int nkeys = 0;
using (StreamReader sr = new StreamReader(filekeyname))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
int fn = tryconvert(words[0]);
if (fn > 0)
int gnid = tryconvert(words[2]);
if (gnid > 0)
nkeys++;
filekeys.Add(fn, gnid);
Console.WriteLine("nkeys = " + nkeys);
//public class chinese_pop_class
//{
//public int adm1 = -1;
//public long pop = -1;
//public long malepop = -1;
//public long femalepop = -1;
//public long households = -1;
//public long pop014 = -1;
//public long pop1564 = -1;
//public long pop65 = -1;
//}
foreach (int fn in filekeys.Keys)
string filename = filepath + "China" + fn.ToString() + ".txt";
Console.WriteLine(filename);
if (!File.Exists(filename))
continue;
int npop = 0;
using (StreamReader sr = new StreamReader(filename))
bool started = false;
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
if (!started) //skip preamble in file
if (words[0] == "start")
started = true;
continue;
chinese_pop_class cc = new chinese_pop_class();
cc.adm1 = filekeys[fn];
if (words.Length <= 1)
continue;
cc.pop = tryconvertlong(words[1]);
if (cc.pop < 0)
continue;
if (words.Length > 9)
cc.malepop = tryconvertlong(words[2]);
cc.femalepop = tryconvertlong(words[3]);
cc.households = tryconvertlong(words[4]);
cc.pop014 = tryconvertlong(words[7]);
cc.pop1564 = tryconvertlong(words[8]);
cc.pop65 = tryconvertlong(words[9]);
if (!chinese_pop_dict.ContainsKey(words[0]))
List
chinese_pop_dict.Add(words[0], cl);
chinese_pop_dict[words[0]].Add(cc);
npop++;
Console.WriteLine("npop = " + npop);
public static void chinese_special()
read_chinese_pop();
int nfdouble = 0;
foreach (int gnid in gndict.Keys)
if (( gndict[gnid].featureclass == 'A' ) || (gndict[gnid].featureclass == 'P' ))
int nfcc = 0;
foreach (string an in gndict[gnid].altnames)
if (chinese_pop_dict.ContainsKey(an))
foreach (chinese_pop_class cc in chinese_pop_dict[an])
if (cc.adm1 == gndict[gnid].adm[1])
nfcc++;
if (nfcc == 1)
chinese_pop_dict2.Add(gnid, cc);
else if ( nfcc == 2)
Console.WriteLine("pop1 = " + cc.pop);
Console.WriteLine("pop2 = " + chinese_pop_dict2[gnid].pop);
chinese_pop_dict2.Remove(gnid);
nfdouble++;
if ( nfcc > 0 )
Console.WriteLine("nfcc = " + nfcc);
Console.WriteLine("chinese pop found: " + chinese_pop_dict2.Count);
Console.WriteLine("nfdouble = "+nfdouble);
Console.ReadLine();
public static void read_geonames(string countrycode)
int n = 0;
int nbad = 0;
Console.WriteLine("read_geonames "+countrycode);
string filename = geonamesfolder;
if ( countrycode == "" )
filename += "allCountries.txt";
else
filename += "Countries//"+countrycode+".txt";
gnfiledate = File.GetLastWriteTime(@filename);
dumpdate = gnfiledate.ToString("yyyy-MM-dd");
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
if (line[0] == '#')
continue;
//if (n > 250)
// Console.WriteLine(line);
string[] words = line.Split(tabchar);
bool badone = false;
//foreach (string s in words)
// Console.WriteLine(s);
//Console.WriteLine(words[0] + "|" + words[1]);
int geonameid = -1;
geonameclass gn = new geonameclass();
words[1] = initialcap(words[1]);
gn.Name = words[1];
gn.Name_ml = words[1];
gn.articlename = "XXX";
geonameid = tryconvert(words[0]);
if (geonameid <= 0)
continue;
gn.asciiname = words[2];
foreach (string ll in words[3].Split(','))
gn.altnames.Add(initialcap(ll));
gn.latitude = tryconvertdouble(words[4]);
gn.longitude = tryconvertdouble(words[5]);
if ( words[6].Length > 0 )
gn.featureclass = words[6][0];
gn.featurecode = words[7];
if (!featuredict.ContainsKey(gn.featurecode))
badone = true;
for (int ii=0;ii<4;ii++)
gn.adm[ii] = -1;
if ( countryid.ContainsKey(words[8]))
gn.adm[0] = countryid[words[8]];
if ( !altnamesonly)
foreach (string ll in words[9].Split(','))
if ((ll != words[8]) && ( countryid.ContainsKey(ll)))
gn.altcountry.Add(countryid[ll]);
if (adm1dict.ContainsKey(words[8]))
if (adm1dict[words[8]].ContainsKey(words[10]))
gn.adm[1] = adm1dict[words[8]][words[10]];
else if (adm1dict[words[8]].ContainsKey("0"+words[10]))
gn.adm[1] = adm1dict[words[8]]["0"+words[10]];
if ( adm2dict.ContainsKey(words[8]))
if ( adm2dict[words[8]].ContainsKey(words[10]))
if ( adm2dict[words[8]][words[10]].ContainsKey(words[11]))
gn.adm[2] = adm2dict[words[8]][words[10]][words[11]];
gn.adm[3] = tryconvert(words[12]);
gn.adm[4] = tryconvert(words[13]);
for (int ii = 1; ii < 4; ii++)
if ( gn.adm[ii] == geonameid )
gn.adm[ii] = -1;
gn.population = tryconvertlong(words[14]);
gn.elevation = tryconvert(words[15]);
gn.dem = tryconvert(words[16]);
if ((gn.elevation <= 0) && (gn.dem > 0))
gn.elevation = gn.dem;
gn.tz = words[17];
gn.moddate = words[18];
//if ((gn.featureclass == 'P') && (gn.population <= 0) && (!checkwikidata))
// badone = true;
bool skipnoheight = false;
if (skipnoheight)
if ((gn.featureclass == 'T') && (gn.elevation <= 0) && (gn.dem <= 0))
switch (gn.featurecode)
case "HLL":
badone = true;
break;
case "HLLS":
badone = true;
break;
case "MT":
badone = true;
break;
case "MTS":
badone = true;
break;
case "MESA":
badone = true;
break;
case "MND":
badone = true;
break;
case "PK":
badone = true;
break;
case "PKS":
badone = true;
break;
case "RDGE":
badone = true;
break;
default:
break;
if (gn.featurecode == "PPLC") //Capital
if (countrydict.ContainsKey(gn.adm[0]))
countrydict[gn.adm[0]].capital_gnid = geonameid;
if (statisticsonly)
//Console.WriteLine(gn.featurecode);
fchist.Add(gn.featurecode);
if (badone)
fcbad.Add(gn.featurecode);
fclasshist.Add(gn.featureclass);
if ( !badone && categorydict.ContainsKey(gn.featurecode))
fcathist.Add(categorydict[gn.featurecode]);
// public static Dictionary
if (!badone)
//if (altnamesonly)
//{
// addnamefork(geonameid, gn.Name);
// addnamefork(geonameid, gn.asciiname);
// foreach (string nm in gn.altnames)
// addnamefork(geonameid, nm);
//}
if (!altnamesonly)
addlatlong(gn.latitude, gn.longitude, geonameid);
if ((geonameid > 0) && (!badone))// && (!statisticsonly))
gndict.Add(geonameid, gn);
else
nbad++;
n++;
if ((n % 10000) == 0)
Console.WriteLine("n (geonames) = " + n.ToString());
Console.WriteLine("nbad (geonames) = " + nbad.ToString());
if (n >= maxread)
break;
Console.WriteLine("n (geonames) = " + n.ToString());
Console.WriteLine("nbad (geonames) = " + nbad.ToString());
if ((!verifywikidata) && (!checkwikidata))
read_wd_files(countrycode); //files for individual countries, with pop and area
if ( checkwikidata)
read_good_wd_file(); //file for all countries, with id match only
if (makecountry == "CN")
chinese_special();
//clear away villages without population:
if ((!verifywikidata) && (!checkwikidata))
List
foreach (int gnid in gndict.Keys)
if ((gndict[gnid].featureclass == 'P') && (gndict[gnid].population <= minimum_population) && (gndict[gnid].population_wd <= minimum_population))
ghosts.Add(gnid);
else if ((gndict[gnid].featurecode == "PPLQ" ) && (gndict[gnid].population > 0 ))
ghosts.Add(gnid);
foreach (int gnid in ghosts)
existingclass gh = new existingclass();
gh.articlename = gndict[gnid].Name_ml;
gh.latitude = gndict[gnid].latitude;
gh.longitude = gndict[gnid].longitude;
ghostdict.Add(gnid, gh);
gndict.Remove(gnid);
read_islands(countrycode); //which place is on which island?
read_lakes(countrycode); //which place is in or near which lake?
read_ranges(countrycode); //which mountain is in which mountain range?
read_altitudes(countrycode);
//get proper country names
foreach (int gnid in countrydict.Keys)
if (gndict.ContainsKey(gnid))
gndict[gnid].Name_ml = countrydict[gnid].Name_ml;
Console.WriteLine("read_geonames done");
public static bool is_latin(string name)
return (get_alphabet(name) == "latin");
public static string get_alphabet(string name)
char[] letters = remove_disambig(name).ToCharArray();
int n = 0;
int sum = 0;
//int nlatin = 0;
Dictionary
foreach (char c in letters)
int uc = Convert.ToInt32(c);
sum += uc;
string alphabet = "none";
if (uc <= 0x0040) alphabet = "none";
//else if ((uc >= 0x0030) && (uc <= 0x0039)) alphabet = "number";
//else if ((uc >= 0x0020) && (uc <= 0x0040)) alphabet = "punctuation";
else if ((uc >= 0x0041) && (uc <= 0x007F)) alphabet = "latin";
else if ((uc >= 0x00A0) && (uc <= 0x00FF)) alphabet = "latin";
else if ((uc >= 0x0100) && (uc <= 0x017F)) alphabet = "latin";
else if ((uc >= 0x0180) && (uc <= 0x024F)) alphabet = "latin";
else if ((uc >= 0x0250) && (uc <= 0x02AF)) alphabet = "phonetic";
else if ((uc >= 0x02B0) && (uc <= 0x02FF)) alphabet = "spacing modifier letters";
else if ((uc >= 0x0300) && (uc <= 0x036F)) alphabet = "combining diacritical marks";
else if ((uc >= 0x0370) && (uc <= 0x03FF)) alphabet = "greek and coptic";
else if ((uc >= 0x0400) && (uc <= 0x04FF)) alphabet = "cyrillic";
else if ((uc >= 0x0500) && (uc <= 0x052F)) alphabet = "cyrillic";
else if ((uc >= 0x0530) && (uc <= 0x058F)) alphabet = "armenian";
else if ((uc >= 0x0590) && (uc <= 0x05FF)) alphabet = "hebrew";
else if ((uc >= 0x0600) && (uc <= 0x06FF)) alphabet = "arabic";
else if ((uc >= 0x0700) && (uc <= 0x074F)) alphabet = "syriac";
else if ((uc >= 0x0780) && (uc <= 0x07BF)) alphabet = "thaana";
else if ((uc >= 0x0900) && (uc <= 0x097F)) alphabet = "devanagari";
else if ((uc >= 0x0980) && (uc <= 0x09FF)) alphabet = "bengali";
else if ((uc >= 0x0A00) && (uc <= 0x0A7F)) alphabet = "gurmukhi";
else if ((uc >= 0x0A80) && (uc <= 0x0AFF)) alphabet = "gujarati";
else if ((uc >= 0x0B00) && (uc <= 0x0B7F)) alphabet = "oriya";
else if ((uc >= 0x0B80) && (uc <= 0x0BFF)) alphabet = "tamil";
else if ((uc >= 0x0C00) && (uc <= 0x0C7F)) alphabet = "telugu";
else if ((uc >= 0x0C80) && (uc <= 0x0CFF)) alphabet = "kannada";
else if ((uc >= 0x0D00) && (uc <= 0x0D7F)) alphabet = "malayalam";
else if ((uc >= 0x0D80) && (uc <= 0x0DFF)) alphabet = "sinhala";
else if ((uc >= 0x0E00) && (uc <= 0x0E7F)) alphabet = "thai";
else if ((uc >= 0x0E80) && (uc <= 0x0EFF)) alphabet = "lao";
else if ((uc >= 0x0F00) && (uc <= 0x0FFF)) alphabet = "tibetan";
else if ((uc >= 0x1000) && (uc <= 0x109F)) alphabet = "myanmar";
else if ((uc >= 0x10A0) && (uc <= 0x10FF)) alphabet = "georgian";
else if ((uc >= 0x1100) && (uc <= 0x11FF)) alphabet = "korean";
else if ((uc >= 0x1200) && (uc <= 0x137F)) alphabet = "ethiopic";
else if ((uc >= 0x13A0) && (uc <= 0x13FF)) alphabet = "cherokee";
else if ((uc >= 0x1400) && (uc <= 0x167F)) alphabet = "unified canadian aboriginal syllabics";
else if ((uc >= 0x1680) && (uc <= 0x169F)) alphabet = "ogham";
else if ((uc >= 0x16A0) && (uc <= 0x16FF)) alphabet = "runic";
else if ((uc >= 0x1700) && (uc <= 0x171F)) alphabet = "tagalog";
else if ((uc >= 0x1720) && (uc <= 0x173F)) alphabet = "hanunoo";
else if ((uc >= 0x1740) && (uc <= 0x175F)) alphabet = "buhid";
else if ((uc >= 0x1760) && (uc <= 0x177F)) alphabet = "tagbanwa";
else if ((uc >= 0x1780) && (uc <= 0x17FF)) alphabet = "khmer";
else if ((uc >= 0x1800) && (uc <= 0x18AF)) alphabet = "mongolian";
else if ((uc >= 0x1900) && (uc <= 0x194F)) alphabet = "limbu";
else if ((uc >= 0x1950) && (uc <= 0x197F)) alphabet = "tai le";
else if ((uc >= 0x19E0) && (uc <= 0x19FF)) alphabet = "khmer";
else if ((uc >= 0x1D00) && (uc <= 0x1D7F)) alphabet = "phonetic";
else if ((uc >= 0x1E00) && (uc <= 0x1EFF)) alphabet = "latin";
else if ((uc >= 0x1F00) && (uc <= 0x1FFF)) alphabet = "greek and coptic";
else if ((uc >= 0x2000) && (uc <= 0x206F)) alphabet = "none";
else if ((uc >= 0x2070) && (uc <= 0x209F)) alphabet = "none";
else if ((uc >= 0x20A0) && (uc <= 0x20CF)) alphabet = "none";
else if ((uc >= 0x20D0) && (uc <= 0x20FF)) alphabet = "combining diacritical marks for symbols";
else if ((uc >= 0x2100) && (uc <= 0x214F)) alphabet = "letterlike symbols";
else if ((uc >= 0x2150) && (uc <= 0x218F)) alphabet = "none";
else if ((uc >= 0x2190) && (uc <= 0x21FF)) alphabet = "none";
else if ((uc >= 0x2200) && (uc <= 0x22FF)) alphabet = "none";
else if ((uc >= 0x2300) && (uc <= 0x23FF)) alphabet = "none";
else if ((uc >= 0x2400) && (uc <= 0x243F)) alphabet = "none";
else if ((uc >= 0x2440) && (uc <= 0x245F)) alphabet = "optical character recognition";
else if ((uc >= 0x2460) && (uc <= 0x24FF)) alphabet = "enclosed alphanumerics";
else if ((uc >= 0x2500) && (uc <= 0x257F)) alphabet = "none";
else if ((uc >= 0x2580) && (uc <= 0x259F)) alphabet = "none";
else if ((uc >= 0x25A0) && (uc <= 0x25FF)) alphabet = "none";
else if ((uc >= 0x2600) && (uc <= 0x26FF)) alphabet = "none";
else if ((uc >= 0x2700) && (uc <= 0x27BF)) alphabet = "none";
else if ((uc >= 0x27C0) && (uc <= 0x27EF)) alphabet = "none";
else if ((uc >= 0x27F0) && (uc <= 0x27FF)) alphabet = "none";
else if ((uc >= 0x2800) && (uc <= 0x28FF)) alphabet = "braille";
else if ((uc >= 0x2900) && (uc <= 0x297F)) alphabet = "none";
else if ((uc >= 0x2980) && (uc <= 0x29FF)) alphabet = "none";
else if ((uc >= 0x2A00) && (uc <= 0x2AFF)) alphabet = "none";
else if ((uc >= 0x2B00) && (uc <= 0x2BFF)) alphabet = "none";
else if ((uc >= 0x2E80) && (uc <= 0x2EFF)) alphabet = "chinese/japanese";
else if ((uc >= 0x2F00) && (uc <= 0x2FDF)) alphabet = "chinese/japanese";
else if ((uc >= 0x2FF0) && (uc <= 0x2FFF)) alphabet = "none";
else if ((uc >= 0x3000) && (uc <= 0x303F)) alphabet = "chinese/japanese";
else if ((uc >= 0x3040) && (uc <= 0x309F)) alphabet = "chinese/japanese";
else if ((uc >= 0x30A0) && (uc <= 0x30FF)) alphabet = "chinese/japanese";
else if ((uc >= 0x3100) && (uc <= 0x312F)) alphabet = "bopomofo";
else if ((uc >= 0x3130) && (uc <= 0x318F)) alphabet = "korean";
else if ((uc >= 0x3190) && (uc <= 0x319F)) alphabet = "chinese/japanese";
else if ((uc >= 0x31A0) && (uc <= 0x31BF)) alphabet = "bopomofo";
else if ((uc >= 0x31F0) && (uc <= 0x31FF)) alphabet = "chinese/japanese";
else if ((uc >= 0x3200) && (uc <= 0x32FF)) alphabet = "chinese/japanese";
else if ((uc >= 0x3300) && (uc <= 0x33FF)) alphabet = "chinese/japanese";
else if ((uc >= 0x3400) && (uc <= 0x4DBF)) alphabet = "chinese/japanese";
else if ((uc >= 0x4DC0) && (uc <= 0x4DFF)) alphabet = "none";
else if ((uc >= 0x4E00) && (uc <= 0x9FFF)) alphabet = "chinese/japanese";
else if ((uc >= 0xA000) && (uc <= 0xA48F)) alphabet = "chinese/japanese";
else if ((uc >= 0xA490) && (uc <= 0xA4CF)) alphabet = "chinese/japanese";
else if ((uc >= 0xAC00) && (uc <= 0xD7AF)) alphabet = "korean";
else if ((uc >= 0xD800) && (uc <= 0xDB7F)) alphabet = "high surrogates";
else if ((uc >= 0xDB80) && (uc <= 0xDBFF)) alphabet = "high private use surrogates";
else if ((uc >= 0xDC00) && (uc <= 0xDFFF)) alphabet = "low surrogates";
else if ((uc >= 0xE000) && (uc <= 0xF8FF)) alphabet = "private use area";
else if ((uc >= 0xF900) && (uc <= 0xFAFF)) alphabet = "chinese/japanese";
else if ((uc >= 0xFB00) && (uc <= 0xFB4F)) alphabet = "alphabetic presentation forms";
else if ((uc >= 0xFB50) && (uc <= 0xFDFF)) alphabet = "arabic";
else if ((uc >= 0xFE00) && (uc <= 0xFE0F)) alphabet = "variation selectors";
else if ((uc >= 0xFE20) && (uc <= 0xFE2F)) alphabet = "combining half marks";
else if ((uc >= 0xFE30) && (uc <= 0xFE4F)) alphabet = "chinese/japanese";
else if ((uc >= 0xFE50) && (uc <= 0xFE6F)) alphabet = "small form variants";
else if ((uc >= 0xFE70) && (uc <= 0xFEFF)) alphabet = "arabic";
else if ((uc >= 0xFF00) && (uc <= 0xFFEF)) alphabet = "halfwidth and fullwidth forms";
else if ((uc >= 0xFFF0) && (uc <= 0xFFFF)) alphabet = "specials";
else if ((uc >= 0x10000) && (uc <= 0x1007F)) alphabet = "linear b";
else if ((uc >= 0x10080) && (uc <= 0x100FF)) alphabet = "linear b";
else if ((uc >= 0x10100) && (uc <= 0x1013F)) alphabet = "aegean numbers";
else if ((uc >= 0x10300) && (uc <= 0x1032F)) alphabet = "old italic";
else if ((uc >= 0x10330) && (uc <= 0x1034F)) alphabet = "gothic";
else if ((uc >= 0x10380) && (uc <= 0x1039F)) alphabet = "ugaritic";
else if ((uc >= 0x10400) && (uc <= 0x1044F)) alphabet = "deseret";
else if ((uc >= 0x10450) && (uc <= 0x1047F)) alphabet = "shavian";
else if ((uc >= 0x10480) && (uc <= 0x104AF)) alphabet = "osmanya";
else if ((uc >= 0x10800) && (uc <= 0x1083F)) alphabet = "cypriot syllabary";
else if ((uc >= 0x1D000) && (uc <= 0x1D0FF)) alphabet = "byzantine musical symbols";
else if ((uc >= 0x1D100) && (uc <= 0x1D1FF)) alphabet = "musical symbols";
else if ((uc >= 0x1D300) && (uc <= 0x1D35F)) alphabet = "tai xuan jing symbols";
else if ((uc >= 0x1D400) && (uc <= 0x1D7FF)) alphabet = "none";
else if ((uc >= 0x20000) && (uc <= 0x2A6DF)) alphabet = "chinese/japanese";
else if ((uc >= 0x2F800) && (uc <= 0x2FA1F)) alphabet = "chinese/japanese";
else if ((uc >= 0xE0000) && (uc <= 0xE007F)) alphabet = "none";
bool ucprint = false;
if (alphabet != "none")
n++;
if (!alphdir.ContainsKey(alphabet))
alphdir.Add(alphabet, 0);
alphdir[alphabet]++;
else if (uc != 0x0020)
//Console.Write("c=" + c.ToString() + ", uc=0x" + uc.ToString("x5") + "|");
//ucprint = true;
if ( ucprint )
Console.WriteLine();
int nmax = 0;
string alphmax = "none";
foreach (string alph in alphdir.Keys)
//Console.WriteLine("ga:" + alph + " " + alphdir[alph].ToString());
if (alphdir[alph] > nmax)
nmax = alphdir[alph];
alphmax = alph;
if ( letters.Length > 2*n) //mostly non-alphabetic
return "none";
else if ( nmax > n/2 ) //mostly same alphabet
return alphmax;
else
return "mixed"; //mixed alphabets
public static string get_alphabet_sv(string alph_en)
Console.WriteLine("gas:" + alph_en);
if (alphabet_sv.Count == 0)
alphabet_sv.Add("bopomofo", "zhuyin");
alphabet_sv.Add("halfwidth and fullwidth forms", "");
alphabet_sv.Add("syriac", "syriska alfabetet");
alphabet_sv.Add("thaana", "tāna");
alphabet_sv.Add("lao", "laotisk skrift");
alphabet_sv.Add("khmer", "khmerisk skrift");
alphabet_sv.Add("gurmukhi", "gurmukhi");
alphabet_sv.Add("myanmar", "burmesisk skrift");
alphabet_sv.Add("tibetan", "tibetansk skrift");
alphabet_sv.Add("sinhala", "singalesisk skrift");
alphabet_sv.Add("ethiopic", "etiopisk skrift");
alphabet_sv.Add("oriya", "oriya-skrift");
alphabet_sv.Add("kannada", "kannada");
alphabet_sv.Add("malayalam", "malayalam");
alphabet_sv.Add("telugu", "teluguskrift");
alphabet_sv.Add("tamil", "tamilska alfabetet");
alphabet_sv.Add("gujarati", "gujarati");
alphabet_sv.Add("bengali", "bengalisk skrift");
alphabet_sv.Add("armenian", "armeniska alfabetet");
alphabet_sv.Add("georgian", "georgiska alfabetet");
alphabet_sv.Add("devanagari", "devanāgarī");
alphabet_sv.Add("korean", "hangul");
alphabet_sv.Add("hebrew", "hebreiska alfabetet");
alphabet_sv.Add("greek and coptic", "grekiska alfabetet");
alphabet_sv.Add("chinese/japanese", "kinesiska tecken");
alphabet_sv.Add("thai", "thailändska alfabetet");
alphabet_sv.Add("cyrillic", "kyrilliska alfabetet");
alphabet_sv.Add("arabic", "arabiska alfabetet");
alphabet_sv.Add("latin", "latinska alfabetet");
if (alphabet_sv.ContainsKey(alph_en))
return alphabet_sv[alph_en];
else
return "okänd skrift";
public static void add_nameforks()
int ntot = gndict.Count;
Console.WriteLine("Add_nameforks: " + ntot.ToString() + " to do.");
foreach (int gnid in gndict.Keys)
addnamefork(gnid, gndict[gnid].Name);
addnamefork(gnid, gndict[gnid].Name_ml);
addnamefork(gnid, gndict[gnid].asciiname);
if (altdict.ContainsKey(gnid))
foreach (altnameclass ac in altdict[gnid])
addnamefork(gnid, ac.altname);
//else
//{
// foreach (string nm in gndict[gnid].altnames)
// addnamefork(gnid, nm);
//}
//if (gndict[gnid].wdid > 0)
//{
// XmlDocument cx = get_wd_xml(wdid);
// if (cx != null)
// {
// Dictionary
// foreach (string sw in rd.Keys)
// addnamefork(gnid, rd[sw]);
// }
//}
ntot--;
if ( (ntot % 1000) == 0 )
Console.WriteLine("=== " + ntot.ToString() + " left ===");
public static void read_island_file(string wdcountry)
string filename = geonamesfolder+ @"islands\islands-" + wdcountry + ".txt";
islanddict.Clear();
try
int nislands = 0;
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
//sw.Write(gnid.ToString() + tabstring + area.ToString() + tabstring + kmew.ToString() + tabstring + kmns.ToString());
//foreach (int oi in onisland)
// sw.Write(tabstring + oi.ToString());
//sw.WriteLine();
if (words.Length < 4)
continue;
int gnid = tryconvert(words[0]);
if (!gndict.ContainsKey(gnid))
continue;
double area = tryconvertdouble(words[1]);
if ((area > 0) && (gndict[gnid].area <= 0 ))
gndict[gnid].area = area;
islandclass isl = new islandclass();
isl.area = area;
double scale = Math.Cos(gndict[gnid].latitude * 3.1416 / 180);
double pixkmx = scale * 40000 / (360 * 1200);
double pixkmy = 40000.0 / (360.0 * 1200.0);
isl.kmew = tryconvertdouble(words[2])+pixkmx;
isl.kmns = tryconvertdouble(words[3])+pixkmy;
for (int i = 4; i < words.Length; i++)
int oi = tryconvert(words[i]);
if (gndict.ContainsKey(oi))
isl.onisland.Add(oi);
//if (gndict[oi].island <= 0)
//{
// gndict[oi].island = gnid;
//}
//else //on two islands - error
//{
// otherisland = gndict[oi].island;
// gndict[oi].island = 0;
//}
//if (islanddict.ContainsKey(otherisland))
// islanddict.Remove(otherisland);
//else
islanddict.Add(gnid,isl);
nislands++;
Console.WriteLine("# islands = " + nislands.ToString());
Dictionary
//List
Dictionary
//identify stuff that's listed as on two islands:
foreach (int gnid in islanddict.Keys)
//first add island itself as "on" itself...
if (oindex.ContainsKey(gnid))
if (!badlist.ContainsKey(oindex[gnid]))
List
badlist.Add(oindex[gnid], bl);
if (!badlist[oindex[gnid]].Contains(gnid))
badlist[oindex[gnid]].Add(gnid);
else
oindex.Add(gnid, gnid);
//... then add everything else on the island.
foreach (int oi in islanddict[gnid].onisland)
if (oindex.ContainsKey(oi))
if (!badlist.ContainsKey(oindex[oi]))
List
badlist.Add(oindex[oi], bl);
if (!badlist[oindex[oi]].Contains(gnid))
badlist[oindex[oi]].Add(gnid);
else
oindex.Add(oi, gnid);
if (verifyislands) //Go through and find best island for stuff with double location,
{ //then make new island file.
int nbad = 0;
foreach (int badi in badlist.Keys)
long bestdist = seed_center_dist(badi);
long best2dist = 99999999;
int best = badi;
foreach (int badg in badlist[badi])
long scdist = seed_center_dist(badg);
if (scdist < bestdist)
best2dist = bestdist;
bestdist = scdist;
best = badg;
if (bestdist * 3 > best2dist) //require 3 times better to "promote" one of the islands
best = -1;
if (badi != best)
islanddict.Remove(badi);
nbad++;
foreach (int badg in badlist[badi])
if (badg != best)
islanddict.Remove(badg);
nbad++;
Console.WriteLine("# islands = " + nislands.ToString());
Console.WriteLine("# bad islands = " + nbad.ToString());
using (StreamWriter sw = new StreamWriter("islands-" + makecountry + ".txt"))
foreach (int gnid in islanddict.Keys)
sw.Write(gnid.ToString() + tabstring + islanddict[gnid].area.ToString() + tabstring + islanddict[gnid].kmew.ToString() + tabstring + islanddict[gnid].kmns.ToString());
foreach (int oi in islanddict[gnid].onisland)
sw.Write(tabstring + oi.ToString());
sw.WriteLine();
else //just remove the duplicate islands
foreach (int badi in badlist.Keys)
islanddict.Remove(badi);
foreach (int badg in badlist[badi])
islanddict.Remove(badg);
foreach (int gnid in islanddict.Keys)
foreach (int oi in islanddict[gnid].onisland)
gndict[oi].island = gnid;
catch (IOException e)
string message = e.Message;
Console.Error.WriteLine(message);
public static void read_range_file(string wdcountry)
string filename = geonamesfolder + @"ranges\ranges-" + wdcountry + ".txt";
rangedict.Clear();
try
int nranges = 0;
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
//sw.Write(gnid.ToString() + tabstring + area.ToString() + tabstring + kmew.ToString() + tabstring + kmns.ToString());
//foreach (int oi in onrange)
// sw.Write(tabstring + oi.ToString());
//sw.WriteLine();
if (words.Length < 6)
continue;
int gnid = tryconvert(words[0]);
if (!gndict.ContainsKey(gnid))
continue;
double length = tryconvertdouble(words[1]);
rangeclass isl = new rangeclass();
isl.length = length;
double scale = Math.Cos(gndict[gnid].latitude * 3.1416 / 180);
double pixkmx = scale * 40000 / (360 * 1200);
//double pixkmy = 40000.0 / (360.0 * 1200.0);
//public class rangeclass //data for each MTS/HLLS
//{
// public double length = 0;
// public string orientation = "....";
// public double angle = 0; //polar angle of long axis (radians). 0 or pi = EW, pi/2 or 3pi/2 = NS etc.
// public double kmew = 0;
// public double kmns = 0;
// public int maxheight = 0; //highest point; gnid of peak if negative, height if positive
// public double hlat = 999; //latitude/longitude of highest point
// public double hlon = 999;
// public List
//}
isl.kmew = tryconvertdouble(words[2]);
isl.kmns = tryconvertdouble(words[3]);
isl.angle = tryconvertdouble(words[4]);
isl.maxheight = tryconvert(words[5]);
isl.hlat = tryconvertdouble(words[6]);
isl.hlon = tryconvertdouble(words[7]);
for (int i = 8; i < words.Length; i++)
int oi = tryconvert(words[i]);
if (gndict.ContainsKey(oi))
isl.inrange.Add(oi);
//if (rangedict.ContainsKey(otherrange))
// rangedict.Remove(otherrange);
//else
rangedict.Add(gnid, isl);
nranges++;
Console.WriteLine("# ranges = " + nranges.ToString());
foreach (int gnid in rangedict.Keys)
foreach (int oi in rangedict[gnid].inrange)
gndict[oi].inrange = gnid;
catch (IOException e)
string message = e.Message;
Console.Error.WriteLine(message);
public static void read_islands(string countrycode)
if (countrycode == "")
foreach (int gnid in countrydict.Keys)
read_island_file(countrydict[gnid].iso);
else
read_island_file(countrycode);
public static void read_ranges(string countrycode)
if (countrycode == "")
foreach (int gnid in countrydict.Keys)
read_range_file(countrydict[gnid].iso);
else
read_range_file(countrycode);
public static void read_lake_file(string wdcountry)
string filename = geonamesfolder + @"lakes\lakes-" + wdcountry + ".txt";
lakedict.Clear();
try
int nlakes = 0;
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
//sw.Write(gnid.ToString() + tabstring + area.ToString() + tabstring + kmew.ToString() + tabstring + kmns.ToString());
//foreach (int oi in onisland)
// sw.Write(tabstring + oi.ToString());
//sw.WriteLine();
if (words.Length < 6)
continue;
int gnid = tryconvert(words[0]);
if (!gndict.ContainsKey(gnid))
continue;
double area = tryconvertdouble(words[1]);
if ((area > 0) && (gndict[gnid].area <= 0))
gndict[gnid].area = area;
lakeclass lake = new lakeclass();
lake.area = area;
double scale = Math.Cos(gndict[gnid].latitude * 3.1416 / 180);
double pixkmx = scale * 40000 / (360 * 1200);
double pixkmy = 40000.0 / (360.0 * 1200.0);
lake.kmew = tryconvertdouble(words[2]);
lake.kmns = tryconvertdouble(words[3]);
if (verifylakes)
lake.kmew += pixkmx;
lake.kmns += pixkmy;
int iw = 5;
while ((iw < words.Length) && (words[iw] != "around"))
int ii = tryconvert(words[iw]);
if (gndict.ContainsKey(ii))
lake.inlake.Add(ii);
iw++;
while (iw < words.Length)
int ii = tryconvert(words[iw]);
if (gndict.ContainsKey(ii))
lake.atlake.Add(ii);
iw++;
lakedict.Add(gnid, lake);
nlakes++;
Console.WriteLine("# lakes = " + nlakes.ToString());
Dictionary
//List
Dictionary
//identify stuff that's listed as on two lakes:
foreach (int gnid in lakedict.Keys)
//first add lake itself as "in" itself...
if (oindex.ContainsKey(gnid))
if (!badlist.ContainsKey(oindex[gnid]))
List
badlist.Add(oindex[gnid], bl);
if (!badlist[oindex[gnid]].Contains(gnid))
badlist[oindex[gnid]].Add(gnid);
else
oindex.Add(gnid, gnid);
//... then add everything else in the lake.
foreach (int oi in lakedict[gnid].inlake)
if (oindex.ContainsKey(oi))
if (!badlist.ContainsKey(oindex[oi]))
List
badlist.Add(oindex[oi], bl);
if (!badlist[oindex[oi]].Contains(gnid))
badlist[oindex[oi]].Add(gnid);
else
oindex.Add(oi, gnid);
if (verifylakes) //Go through and find best lake for stuff with double location,
{ //then make new lake file.
int nbad = 0;
foreach (int badi in badlist.Keys)
long bestdist = seed_center_dist(badi);
long best2dist = 99999999;
int best = badi;
foreach (int badg in badlist[badi])
long scdist = seed_center_dist(badg);
if (scdist < bestdist)
best2dist = bestdist;
bestdist = scdist;
best = badg;
if (bestdist * 3 > best2dist) //require 3 times better to "promote" one of the lakes
best = -1;
if (badi != best)
lakedict.Remove(badi);
nbad++;
foreach (int badg in badlist[badi])
if (badg != best)
lakedict.Remove(badg);
nbad++;
Console.WriteLine("# lakes = " + nlakes.ToString());
Console.WriteLine("# bad lakes = " + nbad.ToString());
using (StreamWriter sw = new StreamWriter("lakes-" + makecountry + ".txt"))
foreach (int gnid in lakedict.Keys)
Console.WriteLine(gndict[gnid].Name + "; " + lakedict[gnid].area.ToString() + "; " + lakedict[gnid].kmew.ToString() + "; " + lakedict[gnid].kmns.ToString() + "; " + lakedict[gnid].inlake.Count.ToString() + "; " + lakedict[gnid].atlake.Count.ToString());
sw.Write(gnid.ToString() + tabstring + lakedict[gnid].area.ToString() + tabstring + lakedict[gnid].kmew.ToString() + tabstring + lakedict[gnid].kmns.ToString() + tabstring + "in");
foreach (int il in lakedict[gnid].inlake)
sw.Write(tabstring + il.ToString());
Console.WriteLine(gndict[il].Name + " in lake");
sw.Write(tabstring + "around");
foreach (int al in lakedict[gnid].atlake)
sw.Write(tabstring + al.ToString());
Console.WriteLine(gndict[al].Name + " around lake");
sw.WriteLine();
else //just remove the duplicate lakes
foreach (int badi in badlist.Keys)
lakedict.Remove(badi);
foreach (int badg in badlist[badi])
lakedict.Remove(badg);
foreach (int gnid in lakedict.Keys)
foreach (int ii in lakedict[gnid].inlake)
gndict[ii].inlake = gnid;
foreach (int ai in lakedict[gnid].atlake)
gndict[ai].atlakes.Add(gnid);
catch (IOException e)
string message = e.Message;
Console.Error.WriteLine(message);
public static void read_lakes(string countrycode)
if (countrycode == "")
foreach (int gnid in countrydict.Keys)
read_lake_file(countrydict[gnid].iso);
else
read_lake_file(countrycode);
public static void read_altitude_file(string wdcountry)
string filename = geonamesfolder + @"altitudes\altitude-" + wdcountry + ".txt";
try
int nalt = 0;
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
if (words.Length < 2)
continue;
int gnid = tryconvert(words[0]);
if (!gndict.ContainsKey(gnid))
continue;
int altitude = tryconvert(words[1]);
if (altitude < 9000)
gndict[gnid].elevation_vp = altitude;
if (gndict[gnid].elevation <= 0)
gndict[gnid].elevation = altitude;
nalt++;
Console.WriteLine("# altitudes = " + nalt.ToString());
catch (IOException e)
string message = e.Message;
Console.Error.WriteLine(message);
public static void read_altitudes(string countrycode)
if (countrycode == "")
foreach (int gnid in countrydict.Keys)
read_altitude_file(countrydict[gnid].iso);
else
read_altitude_file(countrycode);
public static void read_altnames()
int n = 0;
int nbad = 0;
Console.WriteLine("read_altnames");
string filename = geonamesfolder + "alternateNames.txt";
using (StreamReader sr = new StreamReader(filename))
//public class altnameclass
//{
// public int altid = 0;
// public string altname = "";
// public int ilang = 0;
// public string wikilink = "";
// public bool official = false;
// public bool shortform = false;
// public bool colloquial = false;
// public bool historic = false;
//}
while (!sr.EndOfStream)
String line = sr.ReadLine();
bool goodname = false;
string[] words = line.Split(tabchar);
altnameclass an = new altnameclass();
an.altid = tryconvert(words[0]);
int gnid = tryconvert(words[1]);
if (!checkdoubles && !gndict.ContainsKey(gnid))
continue;
int country = -1;
if (gndict.ContainsKey(gnid))
country = gndict[gnid].adm[0];
//if (gnid == 3039154)
// Console.WriteLine(line);
if (words[2] == "link")
an.wikilink = words[3];
goodname = true;
else if (words[2] == "iata")
if (!iatadict.ContainsKey(gnid))
iatadict.Add(gnid, words[3]);
else if (words[2] == "icao")
if (!icaodict.ContainsKey(gnid))
icaodict.Add(gnid, words[3]);
else
an.altname = initialcap(words[3]);
if (langtoint.ContainsKey(words[2]))
an.ilang = langtoint[words[2]];
else if (langtoint.ContainsKey(words[2].Split('-')[0]))
an.ilang = langtoint[words[2].Split('-')[0]];
else if (words[2].Length > 3)
an.ilang = -1;
continue;
//Console.WriteLine("lang:" + an.ilang.ToString() + ", " + words[2]);
if (words[2] == makelang)
if (gndict.ContainsKey(gnid))
if ( !gndict[gnid].articlename.Contains("*"))
gndict[gnid].Name_ml = words[3];
if (countrydict.ContainsKey(country))
if (countrydict[country].languages.Contains(an.ilang))
goodname = true;
string script = get_alphabet(an.altname);
if ((an.ilang < 0) && (script == "latin"))
goodname = true;
if (((makecountry == "CN") || (makecountry == "JP") || (makecountry == "TW")) && (script == "chinese/japanese"))
goodname = true;
if ((words.Length > 4) && (words[4] == "1"))
an.official = true;
if ((words.Length > 5) && (words[5] == "1"))
an.shortform = true;
if ((words.Length > 6) && (words[6] == "1"))
an.colloquial = true;
if ((words.Length > 7) && (words[7] == "1"))
an.historic = true;
//if (an.official || an.shortform || an.colloquial || an.historic)
// goodname = true;
//if (langdict.ContainsKey(an.ilang))
// Console.Write(langdict[an.ilang].iso2 + ":");
//else
// Console.Write("--:");
//Console.WriteLine(an.altname + ": is_latin = " + is_latin(an.altname).ToString()+", goodname = "+goodname.ToString());
if (goodname)
if (!altdict.ContainsKey(gnid))
List
altdict.Add(gnid, anl);
altdict[gnid].Add(an);
if ( !String.IsNullOrEmpty(an.altname))
n++;
else
nbad++;
if ((n % 1000000) == 0)
Console.WriteLine("n (altnames) = " + n.ToString());
if (n >= 1000000000)
break;
Console.WriteLine("n (altnames)= " + n.ToString());
Console.WriteLine("nbad (altnames)= " + nbad.ToString());
if (statisticsonly)
hbookclass althist = new hbookclass();
hbookclass altuniquehist = new hbookclass();
foreach (int gnid in altdict.Keys)
althist.Add(altdict[gnid].Count);
List
foreach (altnameclass ac in altdict[gnid])
if (!al.Contains(ac.altname))
al.Add(ac.altname);
altuniquehist.Add(al.Count);
if (al.Count > 100)
Console.Write(al.Count.ToString() + ": ");
foreach (string s in al)
Console.Write(s + " | ");
Console.WriteLine();
althist.PrintIHist();
altuniquehist.PrintIHist();
Console.ReadLine();
if (makelang == "sv")
if (makecountry == "")
read_translit("BG");
read_translit("BY");
read_translit("KZ");
read_translit("MK");
read_translit("RS");
read_translit("RU");
read_translit("UA");
read_translit("MN");
read_translit("KG");
read_translit("TJ");
read_translit("RS");
else
read_translit(makecountry);
read_handtranslated();
public static void read_handtranslated()
string filename = geonamesfolder + @"handtranslated-" + makelang + ".txt";
int n = 0;
if (File.Exists(filename))
Console.WriteLine("read_handtranslated " + filename);
using (StreamReader sr = new StreamReader(filename))
//public class altnameclass
//{
// public int altid = 0;
// public string altname = "";
// public int ilang = 0;
// public string wikilink = "";
// public bool official = false;
// public bool shortform = false;
// public bool colloquial = false;
// public bool historic = false;
//}
while (!sr.EndOfStream)
String line = sr.ReadLine();
//bool goodname = false;
string[] words = line.Split(tabchar);
if (words.Length < 2)
continue;
altnameclass an = new altnameclass();
an.altid = -1;
int gnid = tryconvert(words[0]);
if (!checkdoubles && !gndict.ContainsKey(gnid))
continue;
an.altname = remove_disambig(words[1].Replace("*", ""));
an.ilang = langtoint[makelang];
if (gndict.ContainsKey(gnid))
gndict[gnid].Name_ml = an.altname;
if (words[1].Contains("*"))
gndict[gnid].articlename = words[1];
//else
if (!artnamedict.ContainsKey(gnid))
artnamedict.Add(gnid, words[1]);
else if (!artnamedict[gnid].Contains("*"))
artnamedict[gnid] = words[1];
if (!altdict.ContainsKey(gnid))
List
altdict.Add(gnid, anl);
altdict[gnid].Add(an);
if (!String.IsNullOrEmpty(an.altname))
n++;
Console.WriteLine("Names found in handtranslated: " + n.ToString());
else
Console.WriteLine("File not found! " + filename);
public static void read_translit(string tlcountry)
string filename = geonamesfolder + @"translit\translit-" + tlcountry + ".txt";
int n = 0;
if (File.Exists(filename))
Console.WriteLine("read_translit " + filename);
using (StreamReader sr = new StreamReader(filename))
//public class altnameclass
//{
// public int altid = 0;
// public string altname = "";
// public int ilang = 0;
// public string wikilink = "";
// public bool official = false;
// public bool shortform = false;
// public bool colloquial = false;
// public bool historic = false;
//}
while (!sr.EndOfStream)
String line = sr.ReadLine();
//bool goodname = false;
string[] words = line.Split(tabchar);
if (words.Length < 3)
continue;
altnameclass an = new altnameclass();
an.altid = -1;
int gnid = tryconvert(words[0]);
if (!checkdoubles && !gndict.ContainsKey(gnid))
continue;
an.altname = words[2];
an.ilang = langtoint["sv"];
if (makelang == "sv")
if (gndict.ContainsKey(gnid))
if (gndict[gnid].Name_ml == gndict[gnid].Name)
gndict[gnid].Name_ml = an.altname;
if (!altdict.ContainsKey(gnid))
List
altdict.Add(gnid, anl);
altdict[gnid].Add(an);
if (!String.IsNullOrEmpty(an.altname))
n++;
else
Console.WriteLine("File not found! " + filename);
Console.WriteLine("Names found in translit: " + n.ToString());
public static string getdatestring()
DateTime thismonth = DateTime.Now;
string monthstring = thismonth.Month.ToString();
while (monthstring.Length < 2)
monthstring = "0" + monthstring;
string daystring = thismonth.Day.ToString();
while (daystring.Length < 2)
daystring = "0" + daystring;
return thismonth.Year.ToString() + monthstring + daystring;
public static void list_nameforks()
int nfork = 0;
int nfork2 = 0;
int nfork10 = 0;
int nfork100 = 0;
int nfork500 = 0;
int nfork1000 = 0;
int maxfork = 0;
string maxforkname = "xxx";
//string datestring = getdatestring();
Console.WriteLine("list_nameforks");
using (StreamWriter sw = new StreamWriter("namefork-" + getdatestring() + ".csv"))
foreach (string s in namefork.Keys)
if (namefork[s].Count > 0)
nfork++;
if (namefork[s].Count > maxfork)
maxfork = namefork[s].Count;
maxforkname = s;
if (namefork[s].Count >= 2)
nfork2++;
if (namefork[s].Count >= 10)
nfork10++;
if (namefork[s].Count >= 100)
nfork100++;
if (namefork[s].Count >= 500)
nfork500++;
if (namefork[s].Count >= 1000)
nfork1000++;
sw.WriteLine(s);
foreach (int i in namefork[s])
if (!gndict.ContainsKey(i))
sw.WriteLine("Bad geonameid " + i.ToString());
continue;
sw.Write(i.ToString() + ";" + gndict[i].featurecode + ";");
if (countrydict.ContainsKey(gndict[i].adm[0]))
//Console.WriteLine(gndict[i].adm[0].ToString() + " " + countrydict[gndict[i].adm[0]].Name);
sw.Write(countrydict[gndict[i].adm[0]].Name);
else if (gndict.ContainsKey(gndict[i].adm[0]))
sw.Write(gndict[gndict[i].adm[0]].Name);
sw.Write(";");
if (gndict.ContainsKey(gndict[i].adm[1]))
sw.Write(gndict[gndict[i].adm[1]].Name_ml);
sw.Write(";");
if (gndict.ContainsKey(gndict[i].adm[2]))
sw.Write(gndict[gndict[i].adm[2]].Name_ml);
sw.Write(";");
sw.Write(gndict[i].latitude.ToString() + ";" + gndict[i].longitude.ToString() + ";");
if (gndict[i].Name_ml == s)
sw.Write("*");
else
sw.Write(gndict[i].Name_ml);
sw.Write(";" + gndict[i].wdid.ToString());
sw.WriteLine();
sw.WriteLine("#");
//sw.WriteLine();
Console.WriteLine("nfork = " + nfork.ToString());
Console.WriteLine("maxfork = " + maxfork.ToString());
Console.WriteLine("maxforkname = |" + maxforkname + "|");
Console.WriteLine("nfork2 = " + nfork2.ToString());
Console.WriteLine("nfork10 = " + nfork10.ToString());
Console.WriteLine("nfork100 = " + nfork100.ToString());
Console.WriteLine("nfork500 = " + nfork100.ToString());
Console.WriteLine("nfork1000 = " + nfork100.ToString());
public static PageList get_geotemplates()
PageList pl = new PageList(makesite);
pl.FillAllFromCategoryTree(mp(74, null));
//Skip all namespaces except templates (ns = 10):
Console.WriteLine("pl.Count = "+pl.Count().ToString());
//pl.RemoveNamespaces(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 100, 101 });
Console.WriteLine("pl.Count = " + pl.Count().ToString());
coordparams.Add("coord");
coordparams.Add("Coord");
coordparams.Add("lat_d");
coordparams.Add("lat_g");
coordparams.Add("latitude");
coordparams.Add("latitud");
return pl;
public static double coordlat(string coordstring)
//{{Coord|42|33|18|N|1|31|59|E|region:AD_type:city|display=title,inline}}
string[] cs = coordstring.Split('|');
if (cs.Length <= 2)
return 9999.9;
else
int ins = -1;
int iew = -1;
int iregion = -1;
for (int i = 1; i < cs.Length; i++)
if ((cs[i].ToUpper() == "N") || (cs[i].ToUpper() == "S"))
ins = i;
if ((cs[i].ToUpper() == "E") || (cs[i].ToUpper() == "W"))
iew = i;
if (cs[i].ToLower().Contains("region"))
iregion = i;
if (ins < 0)
return tryconvertdouble(cs[1]);
else
double lat = 0.0;
double scale = 1.0;
for (int i = 1; i < ins; i++)
double lx = tryconvertdouble(cs[i]);
if (lx < 90.0)
lat += lx / scale;
scale *= 60.0;
if (cs[ins].ToUpper() == "S")
lat = -lat;
return lat;
//else if (cs.Length < 9)
//{
// return tryconvertdouble(cs[1]);
//}
//else
//{
// double lat = tryconvertdouble(cs[1]) + tryconvertdouble(cs[2]) / 60 + tryconvertdouble(cs[3]) / 3600;
// if (cs[4].ToUpper() == "S")
// lat = -lat;
// return lat;
//}
public static double coordlong(string coordstring)
//{{Coord|42|33|18|N|1|31|59|E|region:AD_type:city|display=title,inline}}
string[] cs = coordstring.Split('|');
if (cs.Length <= 2)
return 9999.9;
else
int ins = -1;
int iew = -1;
int iregion = -1;
for (int i = 1; i < cs.Length; i++)
if ((cs[i].ToUpper() == "N") || (cs[i].ToUpper() == "S"))
ins = i;
if ((cs[i].ToUpper() == "E") || (cs[i].ToUpper() == "W"))
iew = i;
if (cs[i].ToLower().Contains("region"))
iregion = i;
if (iew < 0)
return tryconvertdouble(cs[2]);
else
double lon = 0.0;
double scale = 1.0;
for (int i = ins + 1; i < iew; i++)
double lx = tryconvertdouble(cs[i]);
if (lx < 180.0)
lon += lx / scale;
scale *= 60.0;
if (cs[iew].ToUpper() == "W")
lon = -lon;
return lon;
//else
//{
// double lon = tryconvertdouble(cs[5]) + tryconvertdouble(cs[6]) / 60 + tryconvertdouble(cs[7]) / 3600;
// if (cs[8].ToUpper() == "W")
// lon = -lon;
// return lon;
//}
public static string removearticle(string s)
string rs = s;
if (makelang == "sv")
if (s.IndexOf("en ") == 0)
rs = s.Remove(0,3);
else if (s.IndexOf("ett ") == 0)
rs = s.Remove(0,4);
else if (makelang == "ceb")
if (s.IndexOf("ang ") == 0)
rs = s.Remove(0,4);
return rs;
public static string getwikilink(string s)
int i1 = s.IndexOf("[[");
int i2 = s.IndexOf("]]");
if (i1 < 0)
return "";
if (i2 < i1 + 2)
return "";
return s.Substring(i1+2, i2 - i1 - 2);
public static void fill_featurearticle()
if (featurearticle.ContainsKey("vik"))
return;
if (makelang == "sv")
featurearticle.Add("vik", "havsvik");
featurearticle.Add("samhälle", "samhälle (geografi)");
featurearticle.Add("udde", "halvö");
featurearticle.Add("ö", "ö (landområde)");
featurearticle.Add("kulle", "kulle (landform)");
featurearticle.Add("del av lagun", "lagun");
//featurearticle.Add("periodisk sjö", "sjö");
//featurearticle.Add("periodisk saltsjö", "saltsjö");
//featurearticle.Add("periodisk korvsjö", "korvsjö");
featurearticle.Add("periodiska sjöar", "periodisk sjö");
featurearticle.Add("periodiska saltsjöar", "periodisk saltsjö");
featurearticle.Add("saltsjöar", "saltsjö");
featurearticle.Add("del av en sjö", "sjö");
featurearticle.Add("del av ett rev", "rev");
featurearticle.Add("trångt sund", "sund");
//featurearticle.Add("saltträsk", "våtmark");
featurearticle.Add("fors", "fors (vattendrag)");
featurearticle.Add("periodisk reservoar", "vattenmagasin");
featurearticle.Add("sabkha", "saltöken");
featurearticle.Add("grund", "grund (sjöfart)");
featurearticle.Add("källa", "vattenkälla");
featurearticle.Add("periodiskt vattendrag", "vattendrag");
featurearticle.Add("wadier", "wadi");
featurearticle.Add("periodisk våtmark", "våtmark");
featurearticle.Add("reservat", "indianreservat");
featurearticle.Add("övergiven gruva", "gruva");
featurearticle.Add("kitteldalar", "kitteldal");
featurearticle.Add("sänka", "bäcken (geografi)");
featurearticle.Add("klippöken", "öken");
featurearticle.Add("del av en ö", "ö (landområde)");
featurearticle.Add("karstområde", "karst");
featurearticle.Add("höjd", "kulle (landform)");
featurearticle.Add("undervattenshöjd", "kulle (landform)");
featurearticle.Add("morän", "morän (landform)");
featurearticle.Add("nunataker", "nunatak");
featurearticle.Add("sänkor", "bäcken (geografi)");
featurearticle.Add("del av halvö", "halvö");
featurearticle.Add("bergstoppar", "bergstopp");
featurearticle.Add("klippa", "klippa (geologi)");
featurearticle.Add("åmynning", "flodmynning");
featurearticle.Add("militärt övningsområde", "övningsfält");
featurearticle.Add("mangroveö", "mangrove");
featurearticle.Add("del av en halvö", "halvö");
featurearticle.Add("del av en platå", "platå");
featurearticle.Add("del av en slätt", "slätt");
featurearticle.Add("uddar", "halvö");
featurearticle.Add("stenöken", "öken");
featurearticle.Add("bankar", "sandbank");
featurearticle.Add("bank", "sandbank");
featurearticle.Add("sandbankar", "sandbank");
featurearticle.Add("dalar", "dal");
//featurearticle.Add("sadelpass", "bergspass");
featurearticle.Add("del av en lagun", "lagun");
featurearticle.Add("del av en ort", "stadsdel");
featurearticle.Add("delta", "floddelta");
featurearticle.Add("plattform", "massrörelse (geologi)");
featurearticle.Add("veckterräng", "veckning");
featurearticle.Add("bassäng", "bassäng (geologi)");
featurearticle.Add("kanjoner", "kanjon");
featurearticle.Add("fossil skog", "förstenat trä");
featurearticle.Add("åsar", "ås");
featurearticle.Add("undervattensåsar", "ås");
featurearticle.Add("undervattensås", "ås");
featurearticle.Add("orter", "ort");
featurearticle.Add("hög udde", "halvö");
featurearticle.Add("del av en dal", "dal");
featurearticle.Add("liten undervattenskulle", "kulle (landform)");
featurearticle.Add("små undervattenskullar", "kulle (landform)");
featurearticle.Add("undervattenskulle", "kulle (landform)");
featurearticle.Add("undervattenskullar", "kulle (landform)");
featurearticle.Add("tröskel", "tröskelfjord");
featurearticle.Add("kontinentalsluttning", "kontinentalbranten");
featurearticle.Add("undervattensdal", "dal");
featurearticle.Add("undervattensdalar", "dal");
featurearticle.Add("utlöpare", "utlöpare (landform)");
featurearticle.Add("guyoter", "guyot");
featurearticle.Add("terass", "terass (landform)");
featurearticle.Add("å", "å (vattendrag)");
featurearticle.Add("klint", "klint (landform)");
featurearticle.Add("ekonomisk region", "ekonomisk region (Finland)");
featurearticle.Add("", "");
public static string comment(string incomment)
return "";
public static List
List
Match m;
Regex HeaderPattern = new Regex("");
try
m = HeaderPattern.Match(text);
while (m.Success)
//Console.WriteLine("Found comment " + m.Groups[1] + " at " + m.Groups[1].Index);
rl.Add(m.Groups[1].Value);
m = m.NextMatch();
catch (Exception e)
Console.WriteLine(e.Message);
return rl;
public static string get_fcode(string text)
List
foreach (string c in comments)
string[] c2 = c.Split('.');
if (c2.Length == 2)
if (c2[0].Length == 1)
if ( c2[1].ToUpper() == c2[1] )
return c2[1];
return "";
public static string linkfeature(string fcode,int gnid)
fill_featurearticle();
string s = getfeaturelabelindet(makecountry,fcode,gnid);
Console.WriteLine("linkfeature " + fcode + " " + s);
//if (fcode.Contains("ADM"))
//{
// //Console.WriteLine("linkfeature ADM");
// int admlevel = -1;
// if (fcode.Length >= 4)
// admlevel = tryconvert(fcode.Substring(3, 1));
// if (admlevel > 0)
// s = getadmindet(makecountry, admlevel,gnid);
//}
string rs = s;
if (makelang == "sv")
if (s.IndexOf("en ") == 0)
rs = s.Insert(3, "[[");
//rs = s.Replace("en ", "en [[");
else if (s.IndexOf("ett ") == 0)
rs = s.Insert(4, "[[");
//rs = s.Replace("ett ", "ett [[");
else if (makelang == "ceb")
if (s.IndexOf("ang ") == 0)
rs = s.Insert(4, "[[");
if (s.IndexOf("mga ") == 0)
rs = s.Insert(4, "[[");
if (!rs.Contains("[["))
rs = "[[" + rs;
rs = rs + "]]";
Console.WriteLine("rs = " + rs);
string gw = getwikilink(rs);
Console.WriteLine("gw = " + gw);
if (featurearticle.ContainsKey(gw))
rs = rs.Replace(gw, featurearticle[gw] + "|" + gw);
rs = comment(featureclassdict[fcode].ToString() + "." + fcode) + rs;
return rs;
public static string fix_artname(string artname)
string rs = artname;
if (funny_quotes.Count == 0)
funny_quotes.Add("„", "“");//„...“ (makedonska m.m.)
funny_quotes.Add("“", "”");//“…” (engelska m.m.)
funny_quotes.Add("«", "»");//«…» (franska m.m.)
foreach (string q1 in funny_quotes.Keys)
if ( rs.Contains(q1) && rs.Contains(funny_quotes[q1]))
rs = rs.Replace(q1, "\"").Replace(funny_quotes[q1], "\"");
rs = rs.Replace("’", "'");
rs = rs.Replace("[", "").Replace("]", "");
rs = rs.Replace("{", "").Replace("}", "");
bool hascomma = rs.Contains(",");
rs = Regex.Replace(rs, @"[\u0000-\u001F]|[\u00AD]", string.Empty); //Ta bort nonprintable. \u00AD är mjukt bindestreck.
bool stillhascomma = rs.Contains(",");
if (hascomma != stillhascomma)
Console.WriteLine(rs);
Console.WriteLine("Comma removed
Console.ReadLine();
return rs;
public static void fix_names()
foreach (int gnid in gndict.Keys)
gndict[gnid].Name = fix_artname(gndict[gnid].Name);
gndict[gnid].Name_ml = fix_artname(gndict[gnid].Name_ml);
public static void read_artname2_file(string filename)
int nartname = 0;
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
string s = sr.ReadLine();
string[] words = s.Split(tabchar);
if (words.Length < 2)
continue;
nartname++;
int gnid = tryconvert(words[0]);
string aname = fix_artname(words[1]);
if ((gndict.Count > 0) && !checkdoubles)
if (gndict.ContainsKey(gnid))
gndict[gnid].artname2 = aname.Replace("*","");
if ((nartname % 1000000) == 0)
Console.WriteLine("nartname2 = " + nartname.ToString());
Console.WriteLine("nartname2 = " + nartname.ToString());
public static void read_oldartname_file(string filename)
int nartname = 0;
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
string s = sr.ReadLine();
string[] words = s.Split(tabchar);
if (words.Length < 2)
continue;
nartname++;
int gnid = tryconvert(words[0]);
string aname = fix_artname(words[1]);
if ((gndict.Count > 0) && !checkdoubles)
if (gndict.ContainsKey(gnid))
if ( gndict[gnid].articlename != aname )
gndict[gnid].oldarticlename = aname;
if (checkdoubles)
if (!oldartnamedict.ContainsKey(gnid))
oldartnamedict.Add(gnid, aname);
if ((nartname % 1000000) == 0)
Console.WriteLine("noldartname = " + nartname.ToString());
Console.WriteLine("noldartname = " + nartname.ToString());
public static void read_artname_file(string filename)
int nartname = 0;
int nparish = 0;
Console.WriteLine("artname: " + filename);
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
string s = sr.ReadLine();
string[] words = s.Split(tabchar);
if (words.Length < 2)
continue;
nartname++;
int gnid = tryconvert(words[0]);
string aname = fix_artname(words[1]);
//if ((makecountry == "AZ") && (filename.Contains("missing")) && (makelang == "sv")) //kludge to get around weird Azerbadjan bug
//{
// Page pz = new Page(makesite, aname.Replace("*", ""));
// tryload(pz, 1);
// if (is_fork(pz) && pz.text.Contains("Azerbajdzjan"))
// {
// aname += " (distrikt i Azerbajdzjan)";
// Console.WriteLine(aname);
// }
//}
if ((gndict.Count > 0) && !checkdoubles)
if (gndict.ContainsKey(gnid))
if (makecountry == "BE")
if (aname.Contains("(församling"))
aname = aname.Replace("(församling)", "(kommun i Belgien)");
aname = aname.Replace("(församling i", "(kommun i");
aname = aname.Replace("(församling,", "(kommun i Belgien,");
aname = aname.Replace("(församlingshuvudort", "(kommunhuvudort");
if (aname.Contains("(församling"))
nparish++;
Console.WriteLine(aname);
if (makecountry == "CW")
if (aname.Contains("Curacao"))
aname = aname.Replace("Curacao", "Curaçao");
if (makecountry == "FI")
if (aname.Contains("Åboland-Turunmaa"))
aname = aname.Replace("Åboland-Turunmaa", "Åboland");
if ((!gndict[gnid].articlename.Contains("*")) || (aname.Contains("*")) || filename.Contains("missing"))
gndict[gnid].articlename = aname;
if (words[1] != aname)
gndict[gnid].unfixedarticlename = words[1];
if ((aname.Contains("*")) || (gndict[gnid].Name == gndict[gnid].Name_ml) || filename.Contains("missing"))
gndict[gnid].Name_ml = remove_disambig(aname.Replace("*", ""));
if (aname.Contains("Östprovinsen"))
Console.WriteLine(gnid.ToString() + ": " + aname);
//else
if (!artnamedict.ContainsKey(gnid))
artnamedict.Add(gnid, aname);
else if (!artnamedict[gnid].Contains("*"))
artnamedict[gnid] = aname;
if ((nartname % 1000000) == 0)
Console.WriteLine("nartname = " + nartname.ToString());
Console.WriteLine("nartname = " + nartname.ToString());
Console.WriteLine("nparish = " + nparish.ToString());
public static void read_artname()
Console.WriteLine("read_artname");
string filename = "artname-" + makelang + ".txt"; //use current file
if ( checkdoubles )
filename = "artname-" + makelang + "-checkwiki.txt"; //use the file that really was checked against wiki
read_artname_file(filename);
if ( makelang == "sv" ) //fil med diverse handfixade namn på svenska
read_artname_file("missing-adm1-toartname.txt");
//Console.ReadLine();
if (makelang == "sv")
filename = "artname-ceb.txt";
else
filename = "artname-sv.txt";
read_artname2_file(filename);
//filename = "artname-"+makelang+"-old.txt";
//read_oldartname_file(filename);
public static string remove_disambig(string title)
string tit = title;
if (tit.IndexOf("(") > 0)
tit = tit.Remove(tit.IndexOf("(")).Trim();
else if (tit.IndexOf(",") > 0)
tit = tit.Remove(tit.IndexOf(",")).Trim();
//if (tit != title)
// Console.WriteLine(title + " |" + tit + "|");
return tit;
public static bool is_disambig(string title)
return (title != remove_disambig(title));
public static void fill_donecountries()
if (makelang == "sv")
donecountries.Add("BT");
donecountries.Add("AG");
donecountries.Add("BH");
donecountries.Add("MK");
donecountries.Add("MT");
donecountries.Add("SS");
donecountries.Add("NI");
donecountries.Add("LU");
public static void check_doubles()
int ndouble = 0;
int ndouble_ow = 0;
int ndouble_cw = 0;
int ndouble_coord = 0;
int ndouble_iw = 0;
int nfuzzy = 0;
int nadm1 = 0;
int nalldisambig = 0;
List
bool checkwiki = false;
hbookclass scripthist = new hbookclass();
Console.WriteLine("Check doubles");
//PageList geolist = get_geotemplates();
//foreach (Page p in geolist)
// Console.WriteLine("Template " + p.title);
Dictionary
int np = 0;
using (StreamWriter swfuzz = new StreamWriter("manualmatch-ADM1-" + makelang + "-" + getdatestring() + ".txt"))
using (StreamWriter sw = new StreamWriter("artname-" + makelang + "-" + getdatestring() + ".txt"))
using (StreamReader sr = new StreamReader("namefork-"+makelang+".csv"))
while (!sr.EndOfStream)
string s = sr.ReadLine();
s = s.Trim(';');
//scripthist.Add(get_alphabet(s));
if (get_alphabet(s) == "none")
Console.WriteLine("none:"+s+"|");
//Console.ReadLine();
List
string countryname = "";
string adm1name = "";
string adm2name = "";
string fcode = "";
int nrealnames = 0;
int nnames = 0;
int imakelang = langtoint[makelang];
while (true)
string line = sr.ReadLine();
if (line[0] == '#')
break;
string[] words = line.Split(';');
//public class forkclass
//{
// public int geonameid = 0;
// public string featurecode = "";
// public string[] admname = new string[3];
// public double latitude = 0.0;
// public double longitude = 0.0;
//}
forkclass fc = new forkclass();
fc.geonameid = tryconvert(words[0]);
fc.featurecode = words[1];
fc.admname[0] = words[2];
if ( countryml.ContainsKey(words[2]))
fc.admname[0] = countryml[words[2]];
if ( countryiso.ContainsKey(words[2]))
fc.iso = countryiso[words[2]];
fc.admname[1] = words[3];
fc.admname[2] = words[4];
fc.latitude = tryconvertdouble(words[5]);
fc.longitude = tryconvertdouble(words[6]);
fc.realname = words[7];
fc.wdid = tryconvert(words[8]);
fc.featurename = getfeaturelabel(fc.iso, fc.featurecode, fc.geonameid);
if (altdict.ContainsKey(fc.geonameid))
foreach (altnameclass ac in altdict[fc.geonameid])
if (ac.ilang == imakelang)
if (ac.altname == s)
fc.realname = "*";
else
fc.realname = ac.altname;
nnames++;
if (fc.realname == "*")
nrealnames++;
fl.Add(fc);
countryname = words[2];
adm1name = words[3];
adm2name = words[4];
fcode = words[1];
bool allsamecountry = true;
//bool allsamefcode = true;
bool allsameadm1 = true;
bool allsameadm2 = true;
bool somesamecountry = false;
bool somesamefcode = false;
bool somesameadm1 = false;
bool somesameadm2 = false;
foreach (forkclass ff in fl)
if (ff.realname == "*")
if (ff.admname[0] != countryname)
allsamecountry = false;
if (ff.admname[1] != adm1name)
allsameadm1 = false;
if (ff.admname[2] != adm2name)
allsameadm2 = false;
//if (ff.featurecode != fcode)
// allsamefcode = false;
if (String.IsNullOrEmpty(ff.admname[1]))
somesameadm1 = true;
if (String.IsNullOrEmpty(ff.admname[2]))
somesameadm2 = true;
foreach (forkclass ff2 in fl)
if ((ff2.realname == "*") && (ff.geonameid != ff2.geonameid))
if (ff.admname[0] == ff2.admname[0])
somesamecountry = true;
if (ff.admname[1] == ff2.admname[1])
somesameadm1 = true;
if (ff.admname[2] == ff2.admname[2])
somesameadm2 = true;
if (ff.featurecode == ff2.featurecode)
somesamefcode = true;
if (ff.featurename == ff2.featurename)
somesamefcode = true;
if (nrealnames == 0)
continue;
//bool geotemplatefound = false;
bool coordfound = false;
bool pagefound = false;
string namefound = "";
double lat = 999.0;
double lon = 999.0;
//foreach (forkclass fc in fl)
// if (fc.realname == "*")
// {
// List
// foreach (int nb in enb)
// {
// if (existingdict.ContainsKey(nb))
// {
// if ( remove_disambig(existingdict[nb].articlename) == s)
// {
// pagefound = true;
// coordfound = true;
// namefound = existingdict[nb].articlename;
// lat = fc.latitude;
// lon = fc.longitude;
// break;
// }
// }
// }
// }
if (checkwiki)
Page oldpage = new Page(makesite, s);
//Page forkpage = new Page(makesite, testprefix + s + " (" + mp(67, null) + ")");
if (tryload(oldpage, 1))
if (oldpage.Exists())
pagefound = true;
if (oldpage.IsRedirect())
oldpage.title = oldpage.RedirectsTo();
tryload(oldpage, 1);
pagefound = oldpage.Exists();
if (is_fork(oldpage))
pagefound = false;
if (pagefound)
//geotemplatefound = false;
coordfound = false;
double[] latlong = get_article_coord(oldpage);
if (latlong[0] + latlong[1] < 720.0)
coordfound = true;
Console.WriteLine(latlong[0].ToString() + "|" + latlong[1].ToString());
lat = latlong[0];
lon = latlong[1];
namefound = oldpage.title;
ndouble_cw++;
else //check against old artname-file
bool alldisambig = true;
foreach (forkclass fc in fl)
if (fc.realname == "*")
if (artnamedict.ContainsKey(fc.geonameid))
if (artnamedict[fc.geonameid].Contains("*"))
pagefound = true;
coordfound = true;
namefound = artnamedict[fc.geonameid].Replace("*", "");
lat = fc.latitude;
lon = fc.longitude;
alldisambig = false;
ndouble_ow++;
break;
else if (!artnamedict[fc.geonameid].Contains("("))
alldisambig = false;
else
Console.WriteLine("gnid missing in artnamedict! " + s);
//Console.ReadLine();
if ((alldisambig) && (nrealnames == 1 )) //page with that name exists but doesn't match any place
pagefound = true;
coordfound = false;
nalldisambig++;
Dictionary
//public class disambigclass
//{
// bool existsalready = false;
// bool country = false;
// bool adm1 = false;
// bool adm2 = false;
// bool latlong = false;
// bool fcode = false;
//}
//Now we know if page exists:
if (pagefound)
//ndouble++;
if (nrealnames == 1)
foreach (forkclass fc in fl)
if (fc.realname == "*")
Disambigclass da = new Disambigclass();
da.fork = fc;
if (coordfound)
double dist = get_distance_latlong(lat, lon, fc.latitude, fc.longitude);
if (dist < 5.0) //Probably same object
da.existsalready = true;
//sw.WriteLine(fc.geonameid + tabstring + "*"+s);
else
da.fcode = true;
da.country = true;
//sw.WriteLine(fc.geonameid + tabstring + s + " (" + removearticle(featuredict[fc.featurecode]) + " " + mp(75, null) + " " + fc.admname[0] + ")");
else //no coordinates
da.fcode = true;
da.country = true;
//sw.WriteLine(fc.geonameid + tabstring + s + " (" + removearticle(featuredict[fc.featurecode]) + " " + mp(75, null) + " " + fc.admname[0] + ")");
dadict.Add(fc.geonameid, da);
else //several realnames, pagefound
if (coordfound)
foreach (forkclass fc in fl)
if (fc.realname == "*")
Disambigclass da = new Disambigclass();
da.fork = fc;
double dist = get_distance_latlong(lat, lon, fc.latitude, fc.longitude);
if (dist < 5.0) //Probably same object
da.existsalready = true;
//sw.WriteLine(fc.geonameid + tabstring + "X");
else
//sw.Write(fc.geonameid + tabstring + s + " (");
//sw.Write(removearticle(featuredict[fc.featurecode]));
da.fcode = true;
if (somesamefcode)
//sw.Write(" " + mp(75, null) + " " + fc.admname[0]);
da.country = !allsamecountry && !String.IsNullOrEmpty(da.fork.admname[0]);
if (somesamecountry)
//sw.Write(", ");
//if (!allsameadm1)
da.adm1 = !allsameadm1 && !String.IsNullOrEmpty(da.fork.admname[1]); // sw.Write(fc.admname[1]);
if (somesameadm1)
//if (!allsameadm1 && !String.IsNullOrEmpty(fc.admname[1]))
// sw.Write(", ");
//if (!allsameadm2)
// sw.Write(fc.admname[2]);
da.adm2 = !allsameadm2 && !String.IsNullOrEmpty(da.fork.admname[2]);
if (somesameadm2)
da.latlong = true;
//if (!allsameadm2 && !String.IsNullOrEmpty(fc.admname[2]))
// sw.Write(", ");
//sw.Write("lat " + fc.latitude.ToString("F2") + ", long " + fc.longitude.ToString("F2"));
//sw.WriteLine(")");
dadict.Add(fc.geonameid, da);
else //no coordinates, several realnames, page found
foreach (forkclass fc in fl)
if (fc.realname == "*")
Disambigclass da = new Disambigclass();
da.fork = fc;
//sw.Write(fc.geonameid + tabstring + s + " (");
//sw.Write(removearticle(featuredict[fc.featurecode]));
da.fcode = true;
if (somesamefcode)
//sw.Write(" " + mp(75, null) + " " + fc.admname[0]);
da.country = !allsamecountry && !String.IsNullOrEmpty(da.fork.admname[0]);
if (somesamecountry)
//sw.Write(", ");
//if (!allsameadm1)
da.adm1 = !allsameadm1 && !String.IsNullOrEmpty(da.fork.admname[1]); // sw.Write(fc.admname[1]);
if (somesameadm1)
//if (!allsameadm1 && !String.IsNullOrEmpty(fc.admname[1]))
// sw.Write(", ");
//if (!allsameadm2)
// sw.Write(fc.admname[2]);
da.adm2 = !allsameadm2 && !String.IsNullOrEmpty(da.fork.admname[2]);
if (somesameadm2)
da.latlong = true;
//if (!allsameadm2 && !String.IsNullOrEmpty(fc.admname[2]))
// sw.Write(", ");
//sw.Write("lat " + fc.latitude.ToString("F2") + ", long " + fc.longitude.ToString("F2"));
//sw.WriteLine(")");
dadict.Add(fc.geonameid, da);
else //page not found
if (nrealnames == 1)
foreach (forkclass fc in fl)
if (fc.realname == "*")
//sw.WriteLine(fc.geonameid + tabstring + s);
Disambigclass da = new Disambigclass();
da.fork = fc;
if (nnames > 1)
da.fcode = true;
da.country = true;
dadict.Add(fc.geonameid, da);
else //several realnames, page not found
foreach (forkclass fc in fl)
if (fc.realname == "*")
Disambigclass da = new Disambigclass();
da.fork = fc;
//sw.Write(fc.geonameid + tabstring + s + " (");
//sw.Write(removearticle(featuredict[fc.featurecode]));
da.fcode = true;
if (somesamefcode)
//sw.Write(" " + mp(75, null) + " " + fc.admname[0]);
da.country = !allsamecountry && !String.IsNullOrEmpty(da.fork.admname[0]);
if (somesamecountry)
//sw.Write(", ");
//if (!allsameadm1)
da.adm1 = !allsameadm1 && !String.IsNullOrEmpty(da.fork.admname[1]); // sw.Write(fc.admname[1]);
if (somesameadm1)
//if (!allsameadm1 && !String.IsNullOrEmpty(fc.admname[1]))
// sw.Write(", ");
//if (!allsameadm2)
// sw.Write(fc.admname[2]);
da.adm2 = !allsameadm2 && !String.IsNullOrEmpty(da.fork.admname[2]);
if (somesameadm2)
da.latlong = true;
//if (!allsameadm2 && !String.IsNullOrEmpty(fc.admname[2]))
// sw.Write(", ");
//sw.Write("lat " + fc.latitude.ToString("F2") + ", long " + fc.longitude.ToString("F2"));
//sw.WriteLine(")");
dadict.Add(fc.geonameid, da);
foreach (int gnid in dadict.Keys)
if (nrealnames > 1)
bool uniquecountry = !String.IsNullOrEmpty(dadict[gnid].fork.admname[0]);
bool uniqueadm1 = !String.IsNullOrEmpty(dadict[gnid].fork.admname[1]);
bool uniqueadm2 = !String.IsNullOrEmpty(dadict[gnid].fork.admname[2]);
bool uniquefcode = true;
foreach (forkclass ff2 in fl)
if ((ff2.realname == "*") && (ff2.geonameid != gnid))
if (dadict[gnid].fork.admname[0] == ff2.admname[0])
uniquecountry = false;
if (dadict[gnid].fork.admname[1] == ff2.admname[1])
uniqueadm1 = false;
if (dadict[gnid].fork.admname[2] == ff2.admname[2])
uniqueadm2 = false;
if (dadict[gnid].fork.featurecode == ff2.featurecode)
uniquefcode = false;
if (dadict[gnid].fcode && uniquefcode)
dadict[gnid].country = false;
dadict[gnid].adm1 = false;
dadict[gnid].adm2 = false;
dadict[gnid].latlong = false;
else if (dadict[gnid].country && uniquecountry)
dadict[gnid].adm1 = false;
dadict[gnid].adm2 = false;
dadict[gnid].latlong = false;
else if (dadict[gnid].adm1 && uniqueadm1)
dadict[gnid].adm2 = false;
dadict[gnid].latlong = false;
else if (dadict[gnid].adm2 && uniqueadm2)
dadict[gnid].latlong = false;
//if (!gndict.ContainsKey(gnid))
// continue;
string artname = "";
if (countrydict.ContainsKey(gnid))
artname = "*" + countrydict[gnid].Name_ml;
if (checkwiki && String.IsNullOrEmpty(artname)) //Look for interwiki matches
if (dadict[gnid].fork.wdid > 0)
XmlDocument cx = get_wd_xml(wdid);
if (cx != null)
Dictionary
foreach (string wiki in rd.Keys)
string ssw = wiki.Replace("wiki", "");
if (ssw == makelang)
artname = "*" + rd[wiki];
ndouble_iw++;
break;
if ((String.IsNullOrEmpty(artname)) && (dadict[gnid].fork.featurecode == "ADM1")) //Look for ADM1 in category:
Console.WriteLine("Checking for ADM1 match " + s + ", " + dadict[gnid].fork.admname[0]);
if (existing_adm1.ContainsKey(dadict[gnid].fork.admname[0]))
Console.WriteLine("Country found; count = " + existing_adm1[dadict[gnid].fork.admname[0]].Count.ToString());
if (existing_adm1[dadict[gnid].fork.admname[0]].Contains(s))
artname = "*" + s;
else
foreach (string es in existing_adm1[dadict[gnid].fork.admname[0]])
if (remove_disambig(es) == "s")
artname = "*" + es;
nadm1++;
break;
if (String.IsNullOrEmpty(artname)) //Look for fuzzy matches:
int mindist = 999;
if (s.Length < 4)
mindist = 1;
else if (s.Length < 7)
mindist = 3;
else if (s.Length < 20)
mindist = 4;
else
mindist = 5;
int distmax = mindist;
mindist = 999;
string mindistname = "";
foreach (string es in existing_adm1[dadict[gnid].fork.admname[0]])
string tit = remove_disambig(es);
int dist = LevenshteinDistance(s, tit);
//Console.WriteLine(s+" | "+tit + ": "+dist.ToString());
if (dist < mindist)
mindist = dist;
mindistname = es;
if (mindist < distmax)
Console.WriteLine("Fuzzy match: " + s + " | " + mindistname + ": " + mindist.ToString());
//Console.ReadLine();
nadm1++;
fuzzylist.Add(gnid.ToString() + ": " + s + " | " + mindistname + ": " + mindist.ToString());
artname = "*" + mindistname;
else if (manualcheck && (!String.IsNullOrEmpty(mindistname)))
Console.WriteLine("Fuzzy match: " + s + " | " + mindistname + ": " + mindist.ToString());
Console.Write("OK? (y/n)");
char yn = Console.ReadKey().KeyChar;
if (yn == 'y')
nadm1++;
fuzzylist.Add(gnid.ToString() + ": " + s + " | " + mindistname + ": " + mindist.ToString());
artname = "*" + mindistname;
Console.WriteLine("Saving " + artname);
swfuzz.WriteLine(gnid.ToString() + tabstring + artname);
else
Console.WriteLine(yn.ToString());
//Console.ReadLine();
if (String.IsNullOrEmpty(artname)) //Look for fuzzy matches:
int mindist = 999;
if (s.Length < 4)
mindist = 0;
else if (s.Length < 7)
mindist = 2;
else if (s.Length < 20)
mindist = 3;
else
mindist = 4;
int distmax = mindist;
string mindistname = "";
List
foreach (int nb in enb)
if (existingdict.ContainsKey(nb))
string cleanart = remove_disambig(existingdict[nb].articlename);
if (cleanart == s)
artname = "*" + existingdict[nb].articlename;
ndouble_coord++;
break;
else
int dist = LevenshteinDistance(s, cleanart);
//Console.WriteLine(s+" | "+cleanart + ": "+dist.ToString());
if (dist < mindist)
mindist = dist;
mindistname = existingdict[nb].articlename;
if (String.IsNullOrEmpty(artname))
if (mindist < distmax)
Console.WriteLine("Fuzzy match: " + s+" | "+mindistname + ": "+mindist.ToString());
//Console.ReadLine();
nfuzzy++;
fuzzylist.Add(gnid.ToString() + ": " + s + " | " + mindistname + ": " + mindist.ToString());
artname = "*" + mindistname;
if (String.IsNullOrEmpty(artname))
if (dadict[gnid].existsalready)
artname = "*" + s;
else
bool daneeded = dadict[gnid].fcode || dadict[gnid].country || dadict[gnid].adm1 || dadict[gnid].adm2 || dadict[gnid].latlong;
if (!daneeded)
artname = s;
else
if (String.IsNullOrEmpty(dadict[gnid].fork.admname[0]))
dadict[gnid].country = false;
artname = s + " (";
bool needscomma = false;
if (dadict[gnid].fcode)
artname += removearticle(getfeaturelabel(dadict[gnid].fork.iso, dadict[gnid].fork.featurecode, gnid));
//if (dadict[gnid].fork.featurecode.Contains("ADM"))
//{
// int admlevel = tryconvert(dadict[gnid].fork.featurecode.Replace("ADM",""));
// if ( admlevel > 0 )
// s += getadmlabel(dadict[gnid].fork.iso, admlevel);
// else
// s += removearticle(featuredict[dadict[gnid].fork.featurecode]);
//}
//else
//{
// s += removearticle(featuredict[dadict[gnid].fork.featurecode]);
//}
if (dadict[gnid].adm1 || dadict[gnid].adm2 || dadict[gnid].country)
artname += " " + mp(75, null) + " ";
else
needscomma = true;
if (dadict[gnid].country)
if (needscomma)
artname += ", ";
artname += dadict[gnid].fork.admname[0];
needscomma = true;
if (dadict[gnid].adm1)
if (needscomma)
artname += ", ";
artname += dadict[gnid].fork.admname[1];
needscomma = true;
if (dadict[gnid].adm2)
if (needscomma)
artname += ", ";
artname += dadict[gnid].fork.admname[2];
needscomma = true;
if (dadict[gnid].latlong)
if (needscomma)
artname += ", ";
artname += "lat " + dadict[gnid].fork.latitude.ToString("F2") + ", long " + dadict[gnid].fork.longitude.ToString("F2");
needscomma = true;
artname += ")";
if (donecountries.Contains(dadict[gnid].fork.iso))
if (oldartnamedict.ContainsKey(gnid))
string fname = removearticle(getfeaturelabel(dadict[gnid].fork.iso, dadict[gnid].fork.featurecode, gnid));
if ( !oldartnamedict[gnid].Contains("(") || oldartnamedict[gnid].Contains(fname))
artname = oldartnamedict[gnid];
sw.WriteLine(gnid.ToString() + tabstring + artname);
np++;
if (artname.Contains("*"))
ndouble++;
if ((np % 1000) == 0)
Console.WriteLine("np = " + np.ToString()+", "+countryname);
if ((ndouble % 100) == 0)
Console.WriteLine("n (doubles) = " + ndouble.ToString());
//while (s[0] != '#')
// s = sr.ReadLine();
//continue;
foreach (string ss in fuzzylist)
Console.WriteLine(ss);
Console.WriteLine("n (doubles) = " + ndouble.ToString());
Console.WriteLine("n (checkwiki) = " + ndouble_cw.ToString());
Console.WriteLine("n (oldwiki) = " + ndouble_ow.ToString());
Console.WriteLine("n (coord) = " + ndouble_coord.ToString());
Console.WriteLine("n (wikidata) = " + ndouble_iw.ToString());
Console.WriteLine("n (fuzzy match) = " + nfuzzy.ToString());
Console.WriteLine("n (ADM1-match) = " + nadm1.ToString());
Console.WriteLine("n (alldisambig) = " + nalldisambig.ToString());
//scripthist.PrintSHist();
//foreach (string gt in geotempdict.Keys)
// Console.WriteLine(gt + ":" + geotempdict[gt].ToString());
public static string make_coord_template(string countrycode, string fcode, double lat, double lon,string artname)
string rs = "{{Coord|";
rs += lat.ToString(culture_en) + "|";
rs += lon.ToString(culture_en) + "|";
//rs += "display=inline|";
string typecode = "landmark";
//Console.WriteLine("fcode = " + fcode);
string cat = categorydict[fcode];
if (fcode == "ADM1")
typecode = "adm1st";
else if (fcode == "ADM2")
typecode = "adm2nd";
else if (fcode.Contains("ADM"))
typecode = "adm3rd";
else
switch (cat)
case "populated places":
typecode = "city";
break;
case "areas":
case "plains":
case "deserts":
typecode = "adm1st";
break;
case "navigation":
case "wetlands":
case "seabed":
case "lakes":
case "coasts":
case "straits":
case "bays":
typecode = "waterbody";
break;
case "mountains":
case "hills":
case "volcanoes":
case "rock formations":
case "valleys":
typecode = "mountain";
break;
case "islands":
case "peninsulas":
typecode = "isle";
break;
case "forests":
typecode = "forest";
break;
case "streams":
typecode = "river";
break;
case "ice":
typecode = "glacier";
break;
default:
typecode = "landmark";
break;
rs += "region:" + countrycode + "_type:" + typecode;
rs += "|name="+artname+"}}";
return rs;
public static bool is_fork(Page p)
if (!p.Exists())
return false;
if (makelang == "ceb")
if (p.text.ToLower().Contains("{{giklaro"))
return true;
else if (makelang == "war")
if (p.text.ToLower().Contains("{{pansayod"))
return true;
else if (makelang == "sv")
if (forktemplates.Count == 0)
PageList pl = new PageList(makesite);
pl.FillFromCategory("Förgreningsmallar");
foreach (Page pp in pl)
forktemplates.Add(pp.title.Replace("Mall:","").ToLower());
foreach (string ft in forktemplates)
if (p.text.ToLower().Contains("{{" + ft))
return true;
return false;
public static string saveconflict(string thisname,string othername)
if (thisname == othername)
return "";
string rs = "";
string[] p9 = new string[2] { othername, getmonthstring() };
rs = mp(9, p9) + "\n";
if (pconflict == null)
pconflict = new Page(makesite, mp(13, null) + botname + "/Namnkonflikter-PRIVAT");
tryload(pconflict, 1);
string ptt = "*[[" + thisname + "]] [[" + othername + "]]\n";
if (!pconflict.text.Contains(ptt))
if (!conflictheadline)
pconflict.text += "\n\n== " + countryml[makecountryname] + " ==\n";
conflictheadline = true;
pconflict.text += "\n" + ptt;
trysave(pconflict, 1);
return rs;
public static string saveanomaly(string thisname, string reason)
string rs = "";
string[] p196 = new string[1] { reason };
rs = mp(196, p196) + "\n";
if (panomaly == null)
panomaly = new Page(makesite, mp(13, null) + botname + "/Anomalier-PRIVAT");
tryload(panomaly, 1);
string ptt = "*[[" + thisname + "]] " + reason;
if (!panomaly.text.Contains(ptt))
if (!anomalyheadline)
panomaly.text += "\n\n== " + countryml[makecountryname] + " ==\n";
anomalyheadline = true;
panomaly.text += "\n" + ptt;
trysave(panomaly, 1);
return rs;
public static void find_duplicate_forks()
Dictionary
using (StreamReader sw = new StreamReader("namefork-" + makelang + ".csv"))
while (!sw.EndOfStream)
string s = sw.ReadLine();
s = s.Trim(';');
List
string countryname = "";
string gnidstring = "";
int nreal = 0;
while (true)
string line = sw.ReadLine();
if (line[0] == '#')
break;
string[] words = line.Split(';');
//public class forkclass
//{
// public int geonameid = 0;
// public string featurecode = "";
// public string[] admname = new string[3];
// public double latitude = 0.0;
// public double longitude = 0.0;
//}
forkclass fc = new forkclass();
fc.geonameid = tryconvert(words[0]);
gnidstring += " " + fc.geonameid;
fc.featurecode = words[1];
fc.admname[0] = words[2];
fc.admname[1] = words[3];
fc.admname[2] = words[4];
fc.latitude = tryconvertdouble(words[5]);
fc.longitude = tryconvertdouble(words[6]);
fc.realname = words[7];
if (fc.realname == "*")
fc.realname = s;
nreal++;
//if (artnamedict.ContainsKey(fc.geonameid))
// fc.realname = artnamedict[fc.geonameid];
fl.Add(fc);
countryname = words[2];
if (fl.Count < 2)
continue;
gnidstring = gnidstring.Trim();
if (forkdict.ContainsKey(gnidstring))
Console.WriteLine(s + ";" + nreal.ToString());
forkdict[gnidstring].Add(s + ";" + nreal.ToString());
else
List
ll.Add(s + ";" + nreal.ToString());
forkdict.Add(gnidstring, ll);
using (StreamWriter sw = new StreamWriter("namefork-duplicates-" + makelang + getdatestring() + ".txt"))
foreach (string gnidstring in forkdict.Keys)
if (forkdict[gnidstring].Count > 1)
int nrmax = -1;
string srmax = "";
foreach (string ss in forkdict[gnidstring])
string[] sss = ss.Split(';');
int nreal = tryconvert(sss[1]);
if (nreal > nrmax)
nrmax = nreal;
srmax = sss[0];
if (nrmax > 0)
sw.Write(srmax);
foreach (string ss in forkdict[gnidstring])
string[] sss = ss.Split(';');
if (sss[0] != srmax)
sw.Write(";" + sss[0]);
sw.WriteLine();
public static void makeforkpages()
int nfork = 0;
List
int nu2019 = 0;
makesite.defaultEditComment = mp(69, null);
if ( !String.IsNullOrEmpty(makecountry))
makesite.defaultEditComment += " " + countryml[makecountryname];
if (pstats == null)
pstats = new Page(makesite, mp(13, null) + botname + "/Statistik");
pstats.Load();
pstats.text += "\n\n== [[" + countryml[makecountryname] + "]] grensidor ==\n\n";
trysave(pstats, 1);
Dictionary
using (StreamReader sw = new StreamReader("namefork-duplicates-" + makelang + ".txt"))
while (!sw.EndOfStream)
string s = sw.ReadLine();
string[] ss = s.Split(';');
if (ss.Length < 2)
continue;
for (int i = 1; i < ss.Length; i++)
if (!forkduplicatedict.ContainsKey(ss[i]))
forkduplicatedict.Add(ss[i], ss[0]); //dictionary from duplicate name to proper name
using (StreamReader sw = new StreamReader("namefork-" + makelang + ".csv"))
while (!sw.EndOfStream)
string s = sw.ReadLine();
s = s.Trim(';');
int nbranches = 0;
List
string countryname = "";
int nsartname = 0;
while (true)
string line = sw.ReadLine();
if (line[0] == '#')
break; //normal exit from the loop
string[] words = line.Split(';');
//public class forkclass
//{
// public int geonameid = 0;
// public string featurecode = "";
// public string[] admname = new string[3];
// public double latitude = 0.0;
// public double longitude = 0.0;
//}
forkclass fc = new forkclass();
fc.geonameid = tryconvert(words[0]);
fc.featurecode = words[1];
fc.admname[0] = words[2];
fc.admname[1] = words[3];
fc.admname[2] = words[4];
fc.latitude = tryconvertdouble(words[5]);
fc.longitude = tryconvertdouble(words[6]);
fc.realname = words[7];
if (fc.realname == "*")
fc.realname = s;
//if (artnamedict.ContainsKey(fc.geonameid))
// fc.realname = artnamedict[fc.geonameid];
fl.Add(fc);
countryname = words[2];
if (artnamedict.ContainsKey(fc.geonameid))
if (s == artnamedict[fc.geonameid].Replace("*", ""))
nsartname++;
//bool allsamecountry = true;
bool hasmakecountry = false;
bool hasanomaly = false;
string anomalytext = "";
//Console.WriteLine("# names in fork page = " + fl.Count.ToString());
if (fl.Count < 2)
continue;
foreach (forkclass ff in fl)
//if (ff.admname[0] != countryname)
// allsamecountry = false;
if (ff.admname[0] == makecountryname)
hasmakecountry = true;
if (!hasmakecountry)
Console.WriteLine("No place in makecountry");
continue;
if (!String.IsNullOrEmpty(resume_at_fork))
if (s != resume_at_fork)
stats.Addskip();
continue;
else
resume_at_fork = "";
Console.WriteLine("nsartname = " + nsartname.ToString());
if (nsartname >= 2)
Console.WriteLine(s+" Too many places link to same!");
//Console.ReadLine();
bool alreadyfork = false;
string alreadyforktitle = "";
string forkpagename = testprefix + s;
Page forkpage = new Page(makesite, forkpagename);
if (tryload(forkpage, 1))
if (forkpage.Exists() || (nsartname > 0 ))
if (!forkpage.Exists())
forkpage.text = "";
if (forkpage.text.Contains(mp(69, null))) //botmade fork; don't make again unless overwrite is set
if (!overwrite || human_touched(forkpage, makesite))
continue;
else
alreadyfork = false;
else
if (is_fork(forkpage))
alreadyfork = true;
alreadyforktitle = forkpage.title;
forkpage.title += " (" + mp(67, null) + ")";
if (tryload(forkpage, 1))
if (forkpage.Exists())
alreadyfork = true;
alreadyforktitle = forkpage.title;
if (forkpage.text.Contains(mp(69, null))) //botmade fork; don't make again
if (!overwrite || human_touched(forkpage, makesite))
continue;
else
alreadyfork = false;
else
forkpage.title = forkpage.title.Replace(")", " 2)");
if (tryload(forkpage, 1))
if (forkpage.Exists())
continue;
if (forkduplicatedict.ContainsKey(s))
if ( forkpage.title == remove_disambig(forkpage.title))
make_redirect_override(forkpage, forkduplicatedict[s],"",-1);
Console.WriteLine("duplicate fork " + forkpage.title + " - " + forkduplicatedict[s]);
//Console.ReadLine();
continue;
string origtext = forkpage.text;
forkpage.text = "";
if (alreadyfork)
forkpage.text += saveconflict(forkpage.title,alreadyforktitle);
forkpage.text += mp(120, null) + "\n\n";
string[] p68 = new string[1] { s };
forkpage.text += mp(68, p68)+":";
if (makelang == "sv")
forkpage.text = mp(142, null) + "\n" + forkpage.text;
forkpage.text += "\n" + comment("NOTERA: Om platser läggs till, tas bort eller ordningen på platserna ändras, bör också mallen Kartposition under samma rubrik korrigeras för att kartan ska förbli rättvisande.") + "\n";
string[] p71 = new string[1] { countryname };
//if (allsamecountry)
//{
// if (fl.Count > 2)
// forkpage.text += mp(71, p71);
// else
// forkpage.text += mp(78, p71);
//}
forkpage.text += "\n\n";
//if (allsamecountry)
//{
// string countrynameml = countryname;
// if (countryml.ContainsKey(countryname))
// countrynameml = countryml[countryname];
// string[] p73 = new string[2] { countrynameml, s };
// if (locatordict.ContainsKey(countryname))
// {
// forkpage.text += mp(72, null) + "+|" + locatordict[countryname] + "\n |caption = " + mp(73, p73) + "\n |float = right\n |width=300\n | places =";
// int inum = 0;
// foreach (forkclass ff in fl)
// {
// inum++;
// forkpage.text += mp(72, null) + "~|" + locatordict[countryname] + "| label = " + inum.ToString() + "| mark =Blue_pog.svg|position=right|background=white|lat=" + ff.latitude.ToString(culture_en) + "|long=" + ff.longitude.ToString(culture_en) + "|caption=|float=}}\n";
// }
// forkpage.text += "}}\n";
// }
// foreach (forkclass ff in fl)
// {
// string artname = s;
// if (artnamedict.ContainsKey(ff.geonameid))
// {
// if (artnamedict[ff.geonameid] != "X")
// artname = artnamedict[ff.geonameid];
// }
// string ss = "# [[" + artname + "]], ";
// if (!artname.Contains("(" + featuredict[ff.featurecode]))
// ss += featuredict[ff.featurecode];
// if (!String.IsNullOrEmpty(ff.admname[1]) && !artname.Contains(ff.admname[1]))
// ss += ", " + ff.admname[1];
// if (!String.IsNullOrEmpty(ff.admname[2]) && !artname.Contains(ff.admname[2]))
// ss += ", " + ff.admname[2];
// if (!artname.Contains(" lat "))
// {
// ss += ", lat. " + ff.latitude.ToString("F1", culture);
// ss += ", long. " + ff.longitude.ToString("F1", culture);
// }
// forkpage.text += ss + "\n";
// nbranches++;
// }
//}
//else
//{
Dictionary
SortedDictionary
foreach (forkclass ff in fl)
string sortcountry = ff.admname[0];
if (countryml.ContainsKey(ff.admname[0]))
sortcountry = countryml[ff.admname[0]];
string locatorkey = ff.admname[0];
if ((String.IsNullOrEmpty(sortcountry)) || (countrydict.ContainsKey(ff.geonameid)))
sortcountry = mp(166, null);
locatorkey = "";
if ( !scountry.ContainsKey(sortcountry))
scountry.Add(sortcountry, locatorkey);
if (!fd.ContainsKey(locatorkey))
List
fd.Add(locatorkey, ffl);
fd[locatorkey].Add(ff);
int ncountries = 0;
int maxpercountry = 0;
int nplaces = 0;
foreach (string cs in fd.Keys)
ncountries++;
nplaces += fd[cs].Count;
if (fd[cs].Count > maxpercountry)
maxpercountry = fd[cs].Count;
bool worldmaponly = ((ncountries > 4) && (maxpercountry < 4));
if (worldmaponly)
int mapsize = 450;
string caption = "";
if (makelang == "sv")
string ifcollapsed = "";//" mw-collapsed";
string collapseintro = "{| class=\"mw-collapsible" + ifcollapsed + "\" data-expandtext=\"Visa karta\" data-collapsetext=\"Dölj karta\" style=\"float:right; clear:right;\"\n|-\n!\n|-\n|\n";
forkpage.text += collapseintro;
forkpage.text += mp(72, null) + "+|" + locatordict[""].locatorname + "\n |caption = " + caption + "\n |float = right\n |width=" + mapsize.ToString() + "\n | places =";
int inum = 0;
foreach (string csl in scountry.Keys)
string cs = scountry[csl];
foreach (forkclass ff in fd[cs])
inum++;
forkpage.text += mp(72, null) + "~|" + locatordict[""].locatorname + "| label = " + inum.ToString() + "| mark =Blue_pog.svg|position=right|background=white|lat=" + ff.latitude.ToString(culture_en) + "|long=" + ff.longitude.ToString(culture_en) + "}}\n";
forkpage.text += "}}\n";
if (makelang == "sv")
forkpage.text += "|}\n"; //collapse-end
foreach (string csl in scountry.Keys)
forkpage.text += "== " + csl + " ==\n";
string cs = scountry[csl];
string ciso = "";
string locname = csl;
if (countryiso.ContainsKey(cs))
ciso = countryiso[cs];
locname = linkcountry(ciso);
if (locatordict.ContainsKey(cs) && !worldmaponly)
int mapsize = 300;
if (fd[cs].Count > 40)
mapsize = 600;
else if (fd[cs].Count > 8)
mapsize = 450;
else if (fd[cs].Count == 1)
mapsize = 150;
string[] p73 = new string[2] { locname, s };
string caption = mp(73, p73);
if (csl == mp(166, null))
caption = csl;
if (makelang == "sv")
string ifcollapsed = "";//" mw-collapsed";
string collapseintro = "{| class=\"mw-collapsible"+ifcollapsed+"\" data-expandtext=\"Visa karta\" data-collapsetext=\"Dölj karta\" style=\"float:right; clear:right;\"\n|-\n!\n|-\n|\n";
forkpage.text += collapseintro;
forkpage.text += mp(72, null) + "+|" + locatordict[cs].locatorname + "\n |caption = " + caption + "\n |float = right\n |width="+mapsize.ToString()+"\n | places =";
int inum = 0;
foreach (forkclass ff in fd[cs])
inum++;
forkpage.text += mp(72, null) + "~|" + locatordict[cs].locatorname + "| label = " + inum.ToString() + "| mark =Blue_pog.svg|position=right|background=white|lat=" + ff.latitude.ToString(culture_en) + "|long=" + ff.longitude.ToString(culture_en) + "}}\n";
forkpage.text += "}}\n";
if (makelang == "sv")
forkpage.text += "|}\n"; //collapse-end
List
foreach (forkclass ff in fd[cs])
string artname = s;
if (artnamedict.ContainsKey(ff.geonameid))
//if (artnamedict[ff.geonameid] != "X")
// artname = artnamedict[ff.geonameid];
artname = artnamedict[ff.geonameid].Replace("*", "");
if (artnames.Contains(artname))
string existing = "";
if (artnamedict[ff.geonameid].Contains("*"))
existing = "*";
if (!forkdoubles.Contains(existing + s))
forkdoubles.Add(existing + s);
hasanomaly = true;
//forkpage.text = saveanomaly(forkpage.title, mp(201, null)) + forkpage.text;
if (!String.IsNullOrEmpty(anomalytext))
anomalytext += " ";
anomalytext += mp(201, null) + " [["+artname+"]]";
else
artnames.Add(artname);
foreach (forkclass ff2 in fd[cs])
if (ff2 != ff)
if (get_distance_latlong(ff.latitude, ff.longitude, ff2.latitude, ff2.longitude) < 1.0)
//forkpage.text = saveanomaly(forkpage.title, mp(202, null)) + forkpage.text;
hasanomaly = true;
string artname2 = "";
if (artnamedict.ContainsKey(ff.geonameid))
artname2 = artnamedict[ff2.geonameid].Replace("*", "");
if (!String.IsNullOrEmpty(anomalytext))
anomalytext += " ";
anomalytext += mp(202, null) + " [[" + artname + "]]" + " [[" + artname2 + "]]";
break;
else
break;
string ss = "# [[" + artname.Replace("*", "") + "]], ";
if (!artname.Contains("(" + getfeaturelabel(ciso, ff.featurecode, ff.geonameid)))
ss += getfeaturelabel(ciso, ff.featurecode, ff.geonameid) + ", ";
if (!String.IsNullOrEmpty(ff.admname[1]) && !artname.Contains(ff.admname[1]))
ss += ff.admname[1] + ", ";
if (!String.IsNullOrEmpty(ff.admname[2]) && !artname.Contains(ff.admname[2]))
ss += ff.admname[2] + ", ";
//if (!artname.Contains(" lat "))
//{
// ss += ", lat. " + ff.latitude.ToString("F1", culture);
// ss += ", long. " + ff.longitude.ToString("F1", culture);
//}
//Console.WriteLine(make_coord_template(ciso, ff.featurecode, ff.latitude, ff.longitude));
//Console.ReadLine();
ss += make_coord_template(ciso, ff.featurecode, ff.latitude, ff.longitude, artname.Replace("*", ""));
ss += comment("Geonames ID " + ff.geonameid.ToString());
forkpage.text += ss + "\n";
nbranches++;
//}
forkpage.text += "\n{{" + mp(69, null) + "}}\n";
//forkpage.text += "[[" + mp(70, null) + "]]\n";
if ((makelang == "sv") && (!is_latin(forkpage.title)))
string alph_sv = get_alphabet_sv(get_alphabet(remove_disambig(forkpage.title)));
if (!alph_sv.Contains("okänd"))
forkpage.text += "{{Sidnamn annan skrift|" + alph_sv + "}}\n";
else
Console.WriteLine(forkpage.title);
Console.WriteLine(remove_disambig(forkpage.title));
Console.WriteLine(alph_sv);
//Console.ReadLine();
string[] p215 = new string[] { "",getmonthstring() };
forkpage.AddToCategory(mp(215, p215).Trim());
p215[1] = "";
foreach (string csl in scountry.Keys)
p215[0] = csl;
forkpage.AddToCategory(mp(215, p215).Trim());
if (nbranches > 1)
if ( hasanomaly )
forkpage.text = saveanomaly(forkpage.title, anomalytext) + forkpage.text;
if ( forkpage.text != origtext )
trysave(forkpage, 2);
nfork++;
//if ( s == "Andorra" )
// Console.ReadLine();
Console.WriteLine("nfork = " + nfork.ToString());
romanian_redirect(forkpage.title);
Console.WriteLine(stats.GetStat());
if (pstats == null)
pstats = new Page(makesite, mp(13, null) + botname + "/Statistik");
pstats.Load();
//pstats.text += "\n\n== [[" + countryml[makecountryname] + "]] grensidor ==\n\n";
pstats.text += stats.GetStat();
trysave(pstats, 1);
stats.ClearStat();
Console.WriteLine("nfork = " + nfork.ToString());
foreach (string fd in forkdoubles)
Console.WriteLine(fd);
using (StreamWriter sw = new StreamWriter("forkdoubles.txt"))
foreach (string ul in forkdoubles)
sw.WriteLine(ul);
Console.WriteLine("forkdoubles = " + forkdoubles.Count.ToString());
Console.WriteLine("nu2019 = " + nu2019.ToString());
public static void print_geonameid(int id)
if (gndict.ContainsKey(id))
Console.WriteLine("Name = "+gndict[id].Name);
Console.WriteLine("Country = " + gndict[gndict[id].adm[0]].Name);
Console.WriteLine("Province = " + gndict[gndict[id].adm[1]].Name);
public static void read_locatorlist()
int n = 0;
using (StreamReader sr = new StreamReader(geonamesfolder + "locatorlist.txt"))
int makelangcol = -1;
int altcol = -1;
while (!sr.EndOfStream)
String line = sr.ReadLine();
if (line[0] == '#')
continue;
//if (n > 250)
// Console.WriteLine(line);
string[] words = line.Split(tabchar);
//foreach (string s in words)
// Console.WriteLine(s);
//Console.WriteLine(words[0] + "|" + words[1]);
if (words[0] == "en") //headline
for (int i = 1; i < words.Length; i++)
if (words[i] == makelang)
makelangcol = i;
if (words[i] == makelang + "-alt")
altcol = i;
Console.WriteLine("makelangcol = " + makelangcol.ToString());
Console.WriteLine("altcol = " + altcol.ToString());
continue;
//Console.WriteLine("wl = " + words.Length.ToString());
locatorclass lc = new locatorclass();
lc.locatorname = words[makelangcol];
if ((words.Length > altcol) && (!String.IsNullOrEmpty(words[altcol])))
lc.altlocator = words[altcol];
if ((words.Length > makelangcol) && (!String.IsNullOrEmpty(words[makelangcol])))
locatordict.Add(words[0], lc);
n++;
if ((n % 10) == 0)
Console.WriteLine("n (locatorlist) = " + n.ToString());
Console.WriteLine("n (locatorlist)= " + n.ToString());
public static void fill_admcap()
if (admcap.Count != 0)
return;
if (makelang == "ceb")
for (int i = 1; i < 5; i++)
foreach (string mc in admdict.Keys)
if ((!String.IsNullOrEmpty(admdict[mc].label[i - 1])) && (!admcap.ContainsKey(admdict[mc].label[i - 1])))
admcap.Add(admdict[mc].label[i - 1], "kapital sa " + admdict[mc].label[i - 1]);
else if (makelang == "sv")
admcap.Add("administrativ atoll", "atollhuvudort");
admcap.Add("administrativ by", "byhuvudort");
admcap.Add("administrativ enhet", "enhetshuvudort");
admcap.Add("administrativ ö", "öhuvudort");
admcap.Add("administrativt område", "områdeshuvudort");
admcap.Add("arrondissement", "arrondissementhuvudort");
admcap.Add("barrio", "barriohuvudort");
admcap.Add("byutvecklingskommitté", "byutvecklingskommittéhuvudort");
admcap.Add("community", "communityhuvudort");
admcap.Add("constituency", "constituencyhuvudort");
admcap.Add("corregimiento", "corregimientohuvudort");
admcap.Add("county", "countyhuvudort");
admcap.Add("delegation", "delegationshuvudort");
admcap.Add("delstat", "delstatshuvudstad");
admcap.Add("departement", "departementshuvudort");
admcap.Add("distrikt", "distriktshuvudort");
admcap.Add("division", "divisionshuvudort");
admcap.Add("emirat", "emirathuvudstad");
admcap.Add("entitet", "entitetshuvudort");
admcap.Add("fylke", "fylkeshuvudort");
admcap.Add("förbundsland", "förbundslandshuvudstad");
admcap.Add("församling", "församlingshuvudort");
admcap.Add("gemenskap", "gemenskapshuvudort");
admcap.Add("gewog", "gewoghuvudort");
admcap.Add("grannskap", "grannskapshuvudort");
admcap.Add("grevskap", "grevskapshuvudort");
admcap.Add("guvernement", "guvernementshuvudort");
admcap.Add("härad", "häradshuvudort");
admcap.Add("hövdingadöme", "hövdingadömeshuvudort");
admcap.Add("hövdingaråd", "hövdingarådshuvudort");
admcap.Add("kabupaten", "kabupatenhuvudort");
admcap.Add("kanton", "kantonhuvudstad");
admcap.Add("klan", "klanhuvudort");
admcap.Add("kommun", "kommunhuvudort");
admcap.Add("krets", "kretshuvudort");
admcap.Add("kungadöme", "kungadömeshuvudstad");
admcap.Add("kvarter", "kvartershuvudort");
admcap.Add("lokalstyresområde", "lokalstyresområdeshuvudort");
admcap.Add("län", "länshuvudort");
admcap.Add("mahaliyya", "mahaliyyahuvudort");
admcap.Add("mukim", "mukimhuvudort");
admcap.Add("oblast", "oblasthuvudort");
admcap.Add("oblyst", "oblysthuvudort");
admcap.Add("område", "områdeshuvudort");
admcap.Add("opština", "opštinahuvudort");
admcap.Add("parroqui", "parroquihuvudort");
admcap.Add("powiat", "powiathuvudort");
admcap.Add("prefektur", "prefekturhuvudort");
admcap.Add("provins", "provinshuvudstad");
admcap.Add("rajon", "rajonhuvudort");
admcap.Add("region", "regionhuvudort");
admcap.Add("autonom region", "regionhuvudort");
admcap.Add("regeringsdistrikt", "regeringsdistriktshuvudort");
admcap.Add("riksdel", "riksdelshuvudstad");
admcap.Add("rote", "rotehuvudort");
admcap.Add("rådsområde", "rådsområdeshuvudort");
admcap.Add("samhällsutvecklingsråd", "samhällsutvecklingsrådshuvudort");
admcap.Add("sektor", "sektorshuvudort");
admcap.Add("shehia", "shehiahuvudort");
admcap.Add("socken", "sockenhuvudort");
admcap.Add("stad", "stadshuvudort");
admcap.Add("stadsdel", "stadsdelshuvudort");
admcap.Add("subbarrio", "subbarriohuvudort");
admcap.Add("subdistrikt", "subdistriktshuvudort");
admcap.Add("subprefektur", "subprefekturhuvudort");
admcap.Add("sýsla", "sýslahuvudort");
admcap.Add("tehsil", "tehsilhuvudort");
admcap.Add("territorium", "territoriehuvudort");
admcap.Add("tidigare kommun", "huvudort för tidigare kommun");
admcap.Add("underdistrikt", "underdistriktshuvudort");
admcap.Add("utvecklingsregion", "utvecklingsregionshuvudort");
admcap.Add("ward", "wardhuvudort");
admcap.Add("voblast", "voblasthuvudort");
admcap.Add("vojvodskap", "vojvodskapshuvudort");
admcap.Add("zon", "zonhuvudort");
admcap.Add("åldermannaskap", "åldermannaskapshuvudort");
admcap.Add("ö och specialkommun", "öhuvudort");
admcap.Add("ögrupp", "ögruppshuvudort");
admcap.Add("öområde", "öområdeshuvudort");
admcap.Add("öråd", "örådshuvudort");
admcap.Add("parish", "parishhuvudort");
admcap.Add("parroquia", "parroquiahuvudort");
admcap.Add("freguesia", "freguesiahuvudort");
admcap.Add("kraj", "krajhuvudort");
admcap.Add("delrepublik", "delrepublikhuvudstad");
admcap.Add("autonomt distrikt", "distriktshuvudort");
public static void read_adm()
int n = 0;
List
string lf = "";
if (firstround)
using (StreamReader sr = new StreamReader(geonamesfolder + "adm-" + makelang + ".txt"))
while (!sr.EndOfStream)
String line = sr.ReadLine();
//if (n > 250)
//Console.WriteLine(line);
string[] words = line.Split(tabchar);
while (words.Length < 11)
line += tabstring;
words = line.Split(tabchar);
//Console.WriteLine("wl = " + words.Length.ToString());
admclass ad = new admclass();
int maxlabel = 0;
for (int i = 0; i < 5; i++)
ad.label[i] = words[i + 1];
if (!String.IsNullOrEmpty(words[i + 1]))
maxlabel = i + 1;
if (!uniquelabels.Contains(words[i + 1]))
uniquelabels.Add(words[i + 1]);
ad.det[i] = words[i + 6];
if (!admtodet.ContainsKey(ad.label[i]))
admtodet.Add(ad.label[i], ad.det[i]);
ad.maxadm = maxlabel;
if ( words[0] == makecountry )
Console.WriteLine(words[0] + ": maxadm = " + maxlabel.ToString());
admdict.Add(words[0], ad);
if ( saveadmlinks)
lf += "* " + linkcountry(words[0]) + "\n";
for (int i = 0; i < 5; i++)
if ( !String.IsNullOrEmpty(ad.label[i]))
lf += ":* ADM"+(i+1).ToString()+": [["+ad.label[i]+"]]\n";
n++;
if ((n % 10) == 0)
Console.WriteLine("n (adm) = " + n.ToString());
if (makelang == "sv")
if (!admtodet.ContainsKey("kraj"))
admtodet.Add("kraj", "krajen");
if (!admtodet.ContainsKey("autonomt distrikt"))
admtodet.Add("autonomt distrikt", "det autonoma distriktet");
if (!admtodet.ContainsKey("delrepublik"))
admtodet.Add("delrepublik", "delrepubliken");
Console.WriteLine("n (adm)= " + n.ToString());
if ( saveadmlinks)
Page pf = new Page(makesite,mp(13,null)+botname+"/linkadmin");
pf.text = lf;
trysave(pf,1);
//using (StreamWriter sw = new StreamWriter("uniquelabels.txt"))
//{
// foreach (string ul in uniquelabels)
// sw.WriteLine(ul);
//}
//Console.WriteLine("unique labels written");
//Console.ReadLine();
fill_admcap();
if (makecountry != "")
if (admdict.ContainsKey(makecountry))
string[] p167 = new string[1] { countryml[countrydict[countryid[makecountry]].Name] };
string admlink = mp(167,p167);
for (int i = 1; i < 5; i++)
if (!String.IsNullOrEmpty(admdict[makecountry].label[i - 1]))
if (!featurearticle.ContainsKey(admdict[makecountry].label[i - 1]))
featurearticle.Add(admdict[makecountry].label[i - 1], admlink);
else
featurearticle[admdict[makecountry].label[i - 1]] = admlink;
string fc = "PPLA";
if (i > 1)
fc += i.ToString();
if (admcap.ContainsKey(admdict[makecountry].label[i - 1]))
featuredict[fc] = admcap[admdict[makecountry].label[i - 1]];
if (!featurearticle.ContainsKey(admcap[admdict[makecountry].label[i - 1]]))
featurearticle.Add(admcap[admdict[makecountry].label[i - 1]], admlink);
//Console.ReadLine();
public static string getfeaturelabel(string countrycode, string fcode, int gnid)
return removearticle(getfeaturelabelindet(countrycode,fcode,gnid));
public static string getfeaturelabelindet(string countrycode, string fcode, int gnid)
if (!featuredict.ContainsKey(fcode))
return "unknown feature";
if (specialfeaturedict.ContainsKey(gnid))
return specialfeaturedict[gnid];
if (fcode.Contains("PPLA"))
int level = 1;
if (fcode != "PPLA")
level = tryconvert(fcode.Replace("PPLA", ""));
if ((level > 0) && (level <= 5))
string admlabel = getadmlabel(countrycode, level, gnid);
if (admcap.ContainsKey(admlabel))
if (makelang == "sv")
return "en " + admcap[admlabel];
else
return admcap[admlabel];
else
return featuredict[fcode];
else
return featuredict[fcode];
else if ( fcode.Contains("ADM"))
int level = tryconvert(fcode.Replace("ADM", ""));
if ((level > 0) && (level <= 5))
return getadmindet(countrycode, level, gnid);
return featuredict[fcode];
public static bool is_zhen(int gnid)
bool zhenfound = false;
if (gndict[gnid].Name.ToLower().Contains(" zhen"))
zhenfound = true;
else
if (altdict.ContainsKey(gnid))
foreach (altnameclass ac in altdict[gnid])
if (ac.altname.ToLower().Contains(" zhen"))
zhenfound = true;
break;
return zhenfound;
public static string getadmlabel(string countrycode, int level, int gnid)
string rs = "";
if (specialfeaturedict.ContainsKey(gnid))
rs = specialfeaturedict[gnid];
else if (admdict.ContainsKey(countrycode))
if (level <= admdict[countrycode].maxadm)
rs = admdict[countrycode].label[level - 1];
else
switch (countrycode)
case "MY":
if ((gndict.ContainsKey(gnid)) && (gndict[gnid].longitude > 106.0))
rs = getadmlabel("MY2", level, gnid);
else
rs = getadmlabel("MY1", level, gnid);
break;
case "GB": //different for different kingdoms in United Kingdom
int kingdom = 6269131;
if (gndict.ContainsKey(gnid))
kingdom = gndict[gnid].adm[1];
switch (kingdom)
case 6269131: //England
rs = getadmlabel("GB1", level, gnid);
break;
case 2641364: //Northern Ireland
rs = getadmlabel("GB2", level, gnid);
break;
case 2638360: //Scotland
rs = getadmlabel("GB3", level, gnid);
break;
case 2634895: //Wales
rs = getadmlabel("GB4", level, gnid);
break;
default:
rs = getadmlabel("GB1", level, gnid);
break;
break;
case "RU":
if (level == 1)
if (gndict.ContainsKey(gnid))
if (gndict[gnid].Name.Contains(" Oblast"))
rs = "oblast";
else if ((gndict[gnid].Name.Contains(" Krai")) || (gndict[gnid].Name.Contains(" Kray")))
rs = "kraj";
else if (gndict[gnid].Name.Contains(" Okrug"))
rs = "autonomt distrikt";
else
rs = "delrepublik";
else
rs = "oblast";
else
rs = (admdict["RU1"].label[level - 1]);
break;
case "CN":
if (level == 4)
if (gndict.ContainsKey(gnid))
bool zhenfound = is_zhen(gnid);
if (zhenfound)
rs = mp(297,null);
else
rs = (admdict["CN1"].label[level - 1]);
else
rs = (admdict["CN1"].label[level - 1]);
else
rs = (admdict["CN1"].label[level - 1]);
break;
default:
rs = (admdict["default"].label[level - 1]);
break;
return rs;
public static string getadmindet(string countrycode, int level, int gnid)
string rs = getadmlabel(countrycode, level, gnid);
if (makelang == "sv")
if (getadmdet(countrycode, level, gnid).EndsWith("t"))
rs = "ett " + rs;
else
rs = "en " + rs;
return rs;
public static string getadmdet(string countrycode, int level, int gnid)
string rs = getadmlabel(countrycode, level, gnid);
if (admtodet.ContainsKey(rs))
rs = admtodet[rs];
if (makelang == "ceb")
rs += " sa";
return rs;
public static double get_distance(int gnidfrom, int gnidto)
double gnidlat = gndict[gnidto].latitude;
double gnidlong = gndict[gnidto].longitude;
double countrylat = gndict[gnidfrom].latitude;
double countrylong = gndict[gnidfrom].longitude;
return get_distance_latlong(countrylat,countrylong,gnidlat,gnidlong);
public static double get_distance_latlong(double fromlat, double fromlong, double tolat, double tolong) //returns distance in km
double kmdeg = 40000 / 360; //km per degree at equator
double scale = Math.Cos(fromlat * 3.1416 / 180); //latitude-dependent longitude scale
double dlat = (tolat - fromlat) * kmdeg;
double dlong = (tolong - fromlong) * kmdeg * scale;
double dist = Math.Sqrt(dlat * dlat + dlong * dlong);
if (dist > 1000.0) //use great circle distance (Haversine formula)
double f1 = fromlat * Math.PI / 180.0; //convert to radians
double f2 = tolat * Math.PI / 180.0;
double l1 = fromlong * Math.PI / 180.0;
double l2 = tolong * Math.PI / 180.0;
double r = 6371.0; //Earth radius
double underroot = Math.Pow(Math.Sin((f2 - f1) / 2), 2) + Math.Cos(f1) * Math.Cos(f2) * Math.Pow(Math.Sin((l2 - l1) / 2), 2);
double root = Math.Sqrt(underroot);
if (root > 1)
root = 1;
dist = 2 * r * Math.Asin(root);
return dist;
public static double[] get_article_coord(Page p)
double lat = 9999.9;
double lon = 9999.9;
double[] latlong = { lat, lon };
int ncoord = 0;
if (coordparams.Count == 0)
coordparams.Add("Coord");
coordparams.Add("coord");
coordparams.Add("lat_d");
coordparams.Add("lat_g");
coordparams.Add("latitude");
coordparams.Add("latitud");
coordparams.Add("nordliggrad");
coordparams.Add("sydliggrad");
coordparams.Add("breddgrad");
Dictionary
//string template = mp(63, null);
foreach (string tt in p.GetTemplates(true, true))
if (tt.Length < 5)
continue;
string cleantt = tt.Replace("\n", "").Trim().Substring(0, 5).ToLower();
Console.WriteLine("cleantt = |" + cleantt + "|");
//if (true)//(geolist.Contains(template + cleantt))
//{
//geotemplatefound = true;
//Console.WriteLine("Possible double");
if (!geotempdict.ContainsKey(cleantt))
geotempdict.Add(cleantt, 1);
else
geotempdict[cleantt]++;
bool foundwithparams = false;
//foreach (string ttt in p.GetTemplates(true, true))
// if (ttt.IndexOf(tt) == 0)
//{
foundwithparams = true;
//Console.WriteLine("foundwithparams");
if (cleantt == "coord")
Console.WriteLine("found {{coord}}");
string coordstring = tt;
if (coordstring.Length > 10)
double newlat = coordlat(coordstring);
double newlon = coordlong(coordstring);
if (newlat + newlon < 720.0)
if (ncoord == 0)
lat = newlat;
lon = newlon;
else if ((Math.Abs(newlat - lat) + Math.Abs(newlon - lon) > 0.01)) //two different coordinates in article; skip!
lat = 9999;
lon = 9999;
ncoord = 9999;
break;
else
lat = newlat;
lon = newlon;
if (lat + lon < 720.0)
ncoord++;
if (ncoord > 3)
break;
else
Dictionary
foreach (string cp in coordparams)
Console.WriteLine("cp = " + cp);
double oldlat = lat;
double oldlon = lon;
if (pdict.ContainsKey(cp))
//coordfound = true;
Console.WriteLine("found coordparams");
switch (cp)
case "latitude":
case "latitud":
lat = tryconvertdouble(pdict[cp]);
if (pdict.ContainsKey("longitude"))
lon = tryconvertdouble(pdict["longitude"]);
else if (pdict.ContainsKey("longitud"))
lon = tryconvertdouble(pdict["longitud"]);
else
Console.WriteLine("latitude but no longitude");
break;
case "nordliggrad":
case "sydliggrad":
lat = tryconvertdouble(pdict[cp]);
if (pdict.ContainsKey("östliggrad"))
lon = tryconvertdouble(pdict["östliggrad"]);
else if (pdict.ContainsKey("västliggrad"))
lon = tryconvertdouble(pdict["västliggrad"]);
else
Console.WriteLine("latitude but no longitude");
break;
case "breddgrad":
lat = tryconvertdouble(pdict[cp]);
if (pdict.ContainsKey("längdgrad"))
lon = tryconvertdouble(pdict["längdgrad"]);
else
Console.WriteLine("latitude but no longitude");
break;
case "lat_d":
case "latd":
case "lat_g":
double llat = 0.0;
llat = tryconvertdouble(pdict[cp]);
if (llat > 0)
lat = llat;
if (pdict.ContainsKey("long_d"))
lon = tryconvertdouble(pdict["long_d"]);
else if (pdict.ContainsKey("longd"))
lon = tryconvertdouble(pdict["longd"]);
else if (pdict.ContainsKey("long_g"))
lon = tryconvertdouble(pdict["long_g"]);
if (pdict.ContainsKey("lat_m"))
lat += tryconvertdouble(pdict["lat_m"]) / 60;
if (pdict.ContainsKey("long_m"))
lon += tryconvertdouble(pdict["long_m"]) / 60;
if (pdict.ContainsKey("lat_s"))
lat += tryconvertdouble(pdict["lat_s"]) / 3600;
if (pdict.ContainsKey("long_s"))
lon += tryconvertdouble(pdict["long_s"]) / 3600;
if (pdict.ContainsKey("lat_NS"))
if (pdict["lat_NS"].ToUpper() == "S")
lat = -lat;
if (pdict.ContainsKey("long_EW"))
if (pdict["long_EW"].ToUpper() == "W")
lon = -lon;
break;
case "Coord":
case "coord": //{{Coord|42|33|18|N|1|31|59|E|region:AD_type:city|display=title,inline}}
string coordstring = pdict[cp];
if (coordstring.Length > 10)
lat = coordlat(coordstring);
lon = coordlong(coordstring);
break;
default:
Console.WriteLine("coord-default:" + tt);
break;
if (lat + lon < 720.0)
if ((Math.Abs(oldlat - lat) + Math.Abs(oldlon - lon) > 0.01)) //two different coordinates in article; skip!
lat = 9999;
lon = 9999;
ncoord = 9999;
break;
else
lat = oldlat;
lon = oldlon;
if (lat + lon < 720.0)
ncoord++;
if (ncoord > 3)
break;
//}
if (!foundwithparams)
Console.WriteLine("Params not found");
Console.WriteLine("lat = " + lat.ToString());
Console.WriteLine("lon = " + lon.ToString());
//}
if (ncoord > 4) //several coordinate sets, probably a list or something; return failure
return latlong;
latlong[0] = lat;
latlong[1] = lon;
return latlong;
//public static double[] get_article_coord_old(Page p)
//{
// double lat = 9999.9;
// double lon = 9999.9;
// double[] latlong = { lat, lon };
// if (coordparams.Count == 0)
// {
// coordparams.Add("coord");
// coordparams.Add("lat_d");
// coordparams.Add("lat_g");
// coordparams.Add("latitude");
// coordparams.Add("latitud");
// }
// Dictionary
// string template = mp(63, null);
// foreach (string tt in p.GetTemplates(false, true))
// {
// string cleantt = initialcap(tt.Replace("\n", "").Trim());
// Console.WriteLine("tt = |" + cleantt + "|");
// if (true)//(geolist.Contains(template + cleantt))
// {
// //geotemplatefound = true;
// Console.WriteLine("Possible double");
// if (!geotempdict.ContainsKey(cleantt))
// geotempdict.Add(cleantt, 1);
// else
// geotempdict[cleantt]++;
// bool foundwithparams = false;
// foreach (string ttt in p.GetTemplates(true, true))
// if (ttt.IndexOf(tt) == 0)
// {
// foundwithparams = true;
// Console.WriteLine("foundwithparams");
// if (cleantt == "Coord")
// {
// Console.WriteLine("found {{coord}}");
// string coordstring = ttt;
// if (coordstring.Length > 10)
// {
// lat = coordlat(coordstring);
// lon = coordlong(coordstring);
// }
// }
// else
// {
// Dictionary
// foreach (string cp in coordparams)
// {
// Console.WriteLine("cp = " + cp);
// if (pdict.ContainsKey(cp))
// {
// //coordfound = true;
// Console.WriteLine("found coordparams");
// switch (cp)
// {
// case "latitude":
// case "latitud":
// lat = tryconvertdouble(pdict[cp]);
// if (pdict.ContainsKey("longitude"))
// lon = tryconvertdouble(pdict["longitude"]);
// else if (pdict.ContainsKey("longitud"))
// lon = tryconvertdouble(pdict["longitud"]);
// else
// Console.WriteLine("latitude but no longitude");
// break;
// case "lat_d":
// case "latd":
// case "lat_g":
// double llat = 0.0;
// llat = tryconvertdouble(pdict[cp]);
// if (llat > 0)
// {
// lat = llat;
// if (pdict.ContainsKey("long_d"))
// lon = tryconvertdouble(pdict["long_d"]);
// else if (pdict.ContainsKey("longd"))
// lon = tryconvertdouble(pdict["longd"]);
// else if (pdict.ContainsKey("long_g"))
// lon = tryconvertdouble(pdict["long_g"]);
// if (pdict.ContainsKey("lat_m"))
// lat += tryconvertdouble(pdict["lat_m"]) / 60;
// if (pdict.ContainsKey("long_m"))
// lon += tryconvertdouble(pdict["long_m"]) / 60;
// if (pdict.ContainsKey("lat_s"))
// lat += tryconvertdouble(pdict["lat_s"]) / 3600;
// if (pdict.ContainsKey("long_s"))
// lon += tryconvertdouble(pdict["long_s"]) / 3600;
// if (pdict.ContainsKey("lat_NS"))
// {
// if (pdict["lat_NS"].ToUpper() == "S")
// lat = -lat;
// }
// if (pdict.ContainsKey("long_EW"))
// {
// if (pdict["long_EW"].ToUpper() == "W")
// lon = -lon;
// }
// }
// break;
// case "coord": //{{Coord|42|33|18|N|1|31|59|E|region:AD_type:city|display=title,inline}}
// string coordstring = pdict["coord"];
// if (coordstring.Length > 10)
// {
// lat = coordlat(coordstring);
// lon = coordlong(coordstring);
// }
// break;
// default:
// Console.WriteLine("coord-default:" + ttt);
// break;
// }
// }
// }
// }
// }
// if (!foundwithparams)
// Console.WriteLine("Params not found");
// Console.WriteLine("lat = " + lat.ToString());
// Console.WriteLine("lon = " + lon.ToString());
// }
// }
// latlong[0] = lat;
// latlong[1] = lon;
// return latlong;
//}
public static int get_direction_latlong(double fromlat, double fromlong, double tolat, double tolong)
double kmdeg = 40000.0 / 360.0; //km per degree at equator
double scale = Math.Cos(fromlat * 3.1416 / 180); //latitude-dependent longitude scale
double dlat = (tolat - fromlat) * kmdeg;
double dlong = (tolong - fromlong) * kmdeg * scale;
//Console.WriteLine("dlat,dlong = " + dlat.ToString() + " " + dlong.ToString());
if (dlat * dlat > 4.0 * dlong * dlong)
if (dlat > 0) // north
return 1;
else //south
return 2;
else if (dlong * dlong > 4.0 * dlat * dlat)
if (dlong > 0) // east
return 4;
else //west
return 3;
else if (dlong > 0)
if (dlat > 0) //northeast
return 5;
else //southeast
return 6;
else
if (dlat > 0) //northwest
return 7;
else //southwest
return 8;
// 1
// 7 5
// 3 4
// 8 6
// 2
public static int get_direction(int gnidfrom, int gnidto)
double tolat = gndict[gnidto].latitude;
double tolong = gndict[gnidto].longitude;
double fromlat = gndict[gnidfrom].latitude;
double fromlong = gndict[gnidfrom].longitude;
return get_direction_latlong(fromlat, fromlong, tolat,tolong);
public static int get_pix_direction(int x, int y, int x0, int y0, double scale)
double dlat = y0 - y; //reverse sign; +y=south!
double dlong = (x-x0) * scale;
//Console.WriteLine("dlat,dlong = " + dlat.ToString() + " " + dlong.ToString());
if (dlat * dlat > 4.0 * dlong * dlong)
if (dlat > 0) // north
return 1;
else //south
return 2;
else if (dlong * dlong > 4.0 * dlat * dlat)
if (dlong > 0) // east
return 4;
else //west
return 3;
else if (dlong > 0)
if (dlat > 0) //northeast
return 5;
else //southeast
return 6;
else
if (dlat > 0) //northwest
return 7;
else //southwest
return 8;
// 1
// 7 5
// 3 4
// 8 6
// 2
public static int[] getdircoord(int dir) //translate from direction codes of get_pix_direction() into +/-1 x +/-1 y
int[] rc = new int[2] {0,0};
switch (dir)
case 1:
rc[1] = 1;
break;
case 2:
rc[1] = -1;
break;
case 3:
rc[0] = -1;
break;
case 4:
rc[0] = 1;
break;
case 5:
rc[0] = 1;
rc[1] = 1;
break;
case 6:
rc[0] = 1;
rc[1] = -1;
break;
case 7:
rc[0] = -1;
rc[1] = 1;
break;
case 8:
rc[0] = -1;
rc[1] = -1;
break;
return rc;
public static int getcountrypart(int gnid)
double gnidlat = gndict[gnid].latitude;
double gnidlong = gndict[gnid].longitude;
double countrylat = gndict[gndict[gnid].adm[0]].latitude;
double countrylong = gndict[gndict[gnid].adm[0]].longitude;
double area = countrydict[gndict[gnid].adm[0]].area;
double kmdeg = 40000 / 360; //km per degree at equator
double scale = Math.Cos(0.5*(countrylat+gnidlat)*3.1416/180); //latitude-dependent longitude scale
double dlat = (gnidlat - countrylat)*kmdeg;
double dlong = (gnidlong - countrylong)*kmdeg * scale;
if (countrylat < -80) //Antarctica
if (gnidlat < -86) //central part
return 82;
if ((gnidlat > -61) && ((gnidlong > -47) && (gnidlong < -44))) //South Orkney Islands
return 84;
if (gnidlong > -45) //East Antarctica
return 86;
else //West Antarctica
if ((gnidlong > -64) && (gnidlong < -52))
if (((gnidlong < -60) && (gnidlat > -64)) || ((gnidlong >= -60) && (gnidlat > -62.8))) //South Shetland Islands
return 83;
else
return 85;
else
return 85;
if ((dlat * dlat + dlong * dlong) < (area / 9)) //central part
return 82;
if (dlat * dlat > 4 * dlong * dlong)
if (dlat > 0) // northern part
return 83;
else //southern part
return 84;
else if (dlong * dlong > 4 * dlat * dlat)
if (dlong > 0) // eastern part
return 86;
else //western part
return 85;
else if (dlong > 0)
if (dlat > 0) //northeastern
return 87;
else //southeastern
return 88;
else
if (dlat > 0) //northwestern
return 89;
else //southwestern
return 90;
public static void fill_motherdict() //mother countries of colonies
if (motherdict.Count > 0)
return;
motherdict.Add("AN", "NL");
motherdict.Add("AS", "US");
motherdict.Add("AW", "NL");
motherdict.Add("AX", "FI");
motherdict.Add("BL", "FR");
motherdict.Add("BV", "NO");
motherdict.Add("CK", "NZ");
motherdict.Add("CX", "AU");
motherdict.Add("FK", "GB");
motherdict.Add("FM", "US");
motherdict.Add("FO", "DK");
motherdict.Add("GF", "FR");
motherdict.Add("GG", "GB");
motherdict.Add("GI", "GB");
motherdict.Add("GL", "DK");
motherdict.Add("GP", "FR");
motherdict.Add("GU", "US");
motherdict.Add("HK", "CN");
motherdict.Add("HM", "AU");
motherdict.Add("IM", "GB");
motherdict.Add("IO", "GB");
motherdict.Add("JE", "GB");
motherdict.Add("MF", "FR");
motherdict.Add("MH", "US");
motherdict.Add("MO", "CN");
motherdict.Add("MP", "US");
motherdict.Add("MQ", "FR");
motherdict.Add("MS", "GB");
motherdict.Add("NU", "NZ");
motherdict.Add("PF", "FR");
motherdict.Add("PM", "FR");
motherdict.Add("PN", "GB");
motherdict.Add("PR", "US");
motherdict.Add("RE", "FR");
motherdict.Add("SH", "GB");
motherdict.Add("SJ", "NO");
motherdict.Add("TC", "GB");
motherdict.Add("TF", "FR");
motherdict.Add("TK", "NZ");
motherdict.Add("UM", "US");
motherdict.Add("VG", "GB");
motherdict.Add("VI", "US");
motherdict.Add("WF", "FR");
motherdict.Add("YT", "FR");
motherdict.Add("SX", "NL");
motherdict.Add("CC", "AU");
motherdict.Add("BM", "GB");
motherdict.Add("CW", "NL");
motherdict.Add("GS", "GB");
motherdict.Add("KY", "GB");
motherdict.Add("NC", "FR");
motherdict.Add("NF", "AU");
Console.WriteLine("Motherdict: " + motherdict.Count.ToString());
public static void read_country_info()
int n = 0;
using (StreamReader sr = new StreamReader(geonamesfolder + "countryInfo.txt"))
int makelangcol = -1;
while (!sr.EndOfStream)
String line = sr.ReadLine();
if (line[0] == '#')
continue;
//if (n > 250)
// Console.WriteLine(line);
string[] words = line.Split(tabchar);
//foreach (string s in words)
// Console.WriteLine(s);
//Console.WriteLine(words[0] + "|" + words[1]);
if (words[0] == "ISO") //headline
for (int i = 1;i
makelangcol = i;
continue;
int geonameid = -1;
countryclass country = new countryclass();
country.Name = words[4];
geonameid = tryconvert(words[16]);
country.iso = words[0];
country.iso3 = words[1];
country.isonumber = tryconvert(words[2]);
country.fips = words[3];
country.capital = words[5];
country.area = tryconvertdouble(words[6]);
country.population = tryconvertlong(words[7]);
country.continent = words[8];
country.tld = words[9];
country.currencycode = words[10];
country.currencyname = words[11];
country.phone = words[12];
country.postalcode = words[13];
foreach (string ll in words[15].Split(','))
//Console.WriteLine("ll.Split('-')[0] = " + ll.Split('-')[0]);
string lcode = ll.Split('-')[0];
if (String.IsNullOrEmpty(country.nativewiki))
country.nativewiki = lcode;
if ( langtoint.ContainsKey(lcode))
country.languages.Add(langtoint[lcode]);
foreach (string ll in words[17].Split(','))
country.bordering.Add(ll);
if (makelangcol > 0)
country.Name_ml = words[makelangcol];
else
country.Name_ml = country.Name;
countryml.Add(country.Name, country.Name_ml);
countryiso.Add(country.Name, country.iso);
if (geonameid > 0)
countryid.Add(country.iso, geonameid);
countrydict.Add(geonameid, country);
//Console.WriteLine(country.iso+":"+geonameid.ToString());
n++;
if ((n % 10) == 0)
Console.WriteLine("n (country_info) = " + n.ToString());
Console.WriteLine("n (country_info)= " + n.ToString());
if (savewikilinks)
Page pt = new Page(makesite, mp(13, null) + botname + "/countrylinks");
pt.text = "Country links used by Lsjbot\n\n";
foreach (string cn in countryml.Keys)
pt.text += "* [[" + countryml[cn] + "]]\n";
trysave(pt, 1);
fill_motherdict();
public static string countrytitle(int gnid)
string rs = "";
string iso = "";
if (countrydict.ContainsKey(gnid))
iso = countrydict[gnid].iso;
if (makelang != "sv")
return rs;
switch (iso)
case "MT":
case "IE":
case "IS":
rs = "republiken ";
break;
case "FK":
rs = "territoriet ";
break;
default:
rs = "";
break;
return rs;
public static string linkcountry(int gnid)
if (countrydict.ContainsKey(gnid))
return linkcountry(countrydict[gnid].iso);
else
return "";
public static string linkcountry(string ciso)
if (!countryid.ContainsKey(ciso))
return ciso;
int gnid = countryid[ciso];
string rt = "[[" + countryml[countrydict[gnid].Name] + "]]";
if (motherdict.ContainsKey(ciso))
//int mothergnid = countryid[motherdict[ciso]];
string mama = linkcountry(motherdict[ciso]);
if (((motherdict[ciso] == "DK")||(motherdict[ciso] == "NL")) && (makelang == "sv"))
mama = mama.Replace("[[", "[[Kungariket ");
rt += " (" + mama + ")";
return rt;
public static void get_country_iw(string langcode)
//Console.WriteLine("get country iw " + langcode);
//using (StreamWriter sw = new StreamWriter("countrynames-" + langcode + ".csv"))
//{
// foreach (int gnid in countrydict.Keys)
// {
// string langname = countrydict[gnid].Name;
// List
// foreach (string iws in iwlist)
// {
// string[] ss = iws.Split(':');
// string iwcode = ss[0];
// string iwtitle = ss[1];
// //Console.WriteLine("iw - " + iwcode + ":" + iwtitle);
// if (iwcode == langcode)
// langname = iwtitle;
// }
// sw.WriteLine(countrydict[gnid].Name + ";" + langname);
// Console.WriteLine(countrydict[gnid].Name + ";" + langname);
// }
//}
public static List
//Borrowed from http://sv.wikipedia.org/wiki/Wikipedia:Projekt_DotNetWikiBot_Framework/Innocent_bot/Addbotkopia
List
XmlDocument doc = new XmlDocument();
string url = "action=wbgetentities&sites=enwiki&titles=" + HttpUtility.UrlEncode(title) + "&languages=en&format=xml";
//string tmpStr = site.PostDataAndGetResultHTM(site.site+"/w/api.php", url);
try
//string tmpStr = site.PostDataAndGetResultHTM(site.site + "/w/api.php", url);
string tmpStr = site.PostDataAndGetResult(site.address + "/w/api.php", url);
doc.LoadXml(tmpStr);
for (int i = 0; i < doc.GetElementsByTagName("sitelink").Count; i++)
string s = doc.GetElementsByTagName("sitelink")[i].Attributes.GetNamedItem("site").Value;
string t = doc.GetElementsByTagName("sitelink")[i].Attributes.GetNamedItem("title").Value;
s = s.Replace("_", "-");
string t2 = s.Substring(0, s.Length - 4) + ":" + t;
//Console.WriteLine(t2);
r.Add(t2);
catch (WebException e)
string message = e.Message;
Console.Error.WriteLine(message);
return r;
public static string fnum(double x)
string rt = "{{formatnum:";
if (x < 1.0)
rt += x.ToString("F2",culture_en);
else if ( x < 30.0 )
rt += x.ToString("F1", culture_en);
else
rt += x.ToString("F0", culture_en);
rt += "}}";
return rt;
public static string fnum(long i)
return "{{formatnum:" + i.ToString() + "}}";
public static string fnum(int i)
return "{{formatnum:" + i.ToString() + "}}";
public static void fill_kids_features()
foreach (int gnid in gndict.Keys)
int parent = 0;
for (int i = 0; i < 5; i++)
if ((gndict[gnid].adm[i] > 0) && (gndict[gnid].adm[i] != gnid))
parent = gndict[gnid].adm[i];
if ((gndict[gnid].featureclass == 'A') && (gndict[gnid].featurecode.Contains("ADM")) && (!gndict[gnid].featurecode.Contains("ADMD")) && (!gndict[gnid].featurecode.Contains("H")))
if (gndict.ContainsKey(parent))
gndict[parent].children.Add(gnid);
else
if (gndict.ContainsKey(parent))
gndict[parent].features.Add(gnid);
public static void makeworldmap()
Bitmap map = new Bitmap(3600, 1800);
int n = 0;
string filename = geonamesfolder;
filename += "allCountries.txt";
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
if (line[0] == '#')
continue;
//if (n > 250)
// Console.WriteLine(line);
string[] words = line.Split(tabchar);
double lat = tryconvertdouble(words[4]);
double lon = tryconvertdouble(words[5]);
double scale = 0.5 + 0.5 * Math.Cos(lat * 3.1416 / 180); //latitude-dependent longitude scale
int x = Convert.ToInt32((lon * scale + 180) * 10);
int y = 1800 - Convert.ToInt32((lat + 90) * 10);
if ((x >= 0) && (x < 3600) && (y >= 0) && (y < 1800))
Color oldcol = map.GetPixel(x, y);
Color newcol = Color.White;
if (oldcol.GetBrightness() < 1.0)
int nargb = oldcol.ToArgb() +0x00030303;
newcol = Color.FromArgb(nargb);
map.SetPixel(x, y, newcol);
else
Console.WriteLine("lat,lon,x,y = " + lat.ToString() + " " + lon.ToString() + " " + x.ToString() + " " + y.ToString());
n++;
if ((n % 10000) == 0)
Console.WriteLine("n (world map) = " + n.ToString());
//if (n >= 500000)
// break;
map.Save(geonamesfolder + "worldmap.jpg", ImageFormat.Jpeg);
map.Dispose();
public static void read_languageiso()
//public class langclass
//{
// public string iso3 = "";
// public string iso2 = "";
// public Dictionary
//}
//public static Dictionary
//public static Dictionary
int n = 0;
using (StreamReader sr = new StreamReader(geonamesfolder + "language-iso.txt"))
//int makelangcol = -1;
String headline = sr.ReadLine();
string[] heads = headline.Split(tabchar);
Dictionary
for (int i = 0; i < heads.Length; i++)
if ((heads[i].Length == 2) || (heads[i].Length == 3))
ld.Add(i, heads[i]);
while (!sr.EndOfStream)
String line = sr.ReadLine();
if (line[0] == '#')
continue;
//if (n > 250)
//Console.WriteLine(line);
string[] words = line.Split(tabchar);
if (words.Length < 3)
continue;
n++;
//foreach (string s in words)
// Console.WriteLine(s);
//Console.WriteLine(words[0] + "|" + words[1]);
langclass lc = new langclass();
lc.iso3 = words[0].Trim();
lc.iso2 = words[1].Trim();
for (int i = 2; i < words.Length; i++)
if ( !String.IsNullOrEmpty(words[i].Trim()))
if ( ld.ContainsKey(i))
if (!lc.name.ContainsKey(ld[i]))
lc.name.Add(ld[i],words[i].Trim());
if (!String.IsNullOrEmpty(lc.iso3))
if ( !langtoint.ContainsKey(lc.iso3))
langtoint.Add(lc.iso3, n);
if (!String.IsNullOrEmpty(lc.iso2))
if (!langtoint.ContainsKey(lc.iso2))
langtoint.Add(lc.iso2, n);
langdict.Add(n, lc);
if ((n % 100) == 0)
Console.WriteLine("n (language-iso) = " + n.ToString());
Console.WriteLine("n (language-iso)= " + n.ToString());
using (StreamReader sr = new StreamReader(geonamesfolder + "langnames-" + makelang + ".txt"))
n = 0;
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
if (words.Length < 2)
continue;
string iso = words[0];
string langname = words[1];
if (makelang == "sv")
langname = langname.ToLower();
if (langtoint.ContainsKey(iso))
int langcode = langtoint[iso];
if ((langdict.ContainsKey(langcode)) && (!langdict[langcode].name.ContainsKey(makelang)))
langdict[langcode].name.Add(makelang, langname);
n++;
if ((n % 100) == 0)
Console.WriteLine("n (langname-makelang) = " + n.ToString());
Console.WriteLine("n (langname-makelang)= " + n.ToString());
if (savewikilinks)
Page pt = new Page(makesite, mp(13, null) + botname + "/languagelinks");
pt.text = "Language links used by Lsjbot\n\n";
foreach (int ilang in langdict.Keys)
if ( langdict[ilang].name.ContainsKey(makelang))
pt.text += "* " + langdict[ilang].iso3 + " [[" + langdict[ilang].name[makelang] + "]]\n";
else
pt.text += "* " + langdict[ilang].iso3+"\n";
trysave(pt, 1);
public static string addref(string rn, string rstring)
if (String.IsNullOrEmpty(rn) || String.IsNullOrEmpty(rstring))
return "";
string refname = "\"" + rn + "\"";
if (!refnamelist.Contains(refname))
refnamelist.Add(refname);
string refref = "" + rstring + "";
reflist += "\n" + refref;
string shortref = "";
return shortref;
public static string addnote(string notestring)
//if (makelang != "sv")
// return "";
hasnotes = true;
Console.WriteLine("addnote:" + notestring);
return mp(174,null) + notestring + "}}";
public static void get_lang_iw(string langcode)
Console.WriteLine("get lang iw " + langcode);
using (StreamWriter sw = new StreamWriter("langnames-" + langcode + ".csv"))
foreach (int gnid in langdict.Keys)
string langname = langdict[gnid].name["en"];
string[] names = langname.Split(';');
foreach (string ln in names)
Page ep = new Page(ensite, ln);
tryload(ep, 2);
if (!ep.Exists())
continue;
if ( ep.IsRedirect())
ep.title = ep.RedirectsTo();
tryload(ep, 2);
if (!ep.Exists())
continue;
langname = ln;
List
foreach (string iws in iwlist)
string[] ss = iws.Split(':');
string iwcode = ss[0];
string iwtitle = ss[1];
//Console.WriteLine("iw - " + iwcode + ":" + iwtitle);
if (iwcode == langcode)
langname = iwtitle;
sw.WriteLine(langdict[gnid].iso3 + ";" + langname);
Console.WriteLine(ln + ";" + langname);
public static string cleanup_text(string text)
Dictionary
cleanstring.Add(". ", ". ");
cleanstring.Add(", ", ", ");
cleanstring.Add("\n ", "\n");
string rs = text;
foreach (string cs in cleanstring.Keys)
while (rs.Contains(cs))
rs = rs.Replace(cs, cleanstring[cs]);
return rs;
public static string fill_geobox(int gnid)
string fc = gndict[gnid].featurecode;
int icountry = gndict[gnid].adm[0];
List
string boxtype = "alla";
if (geoboxdict.ContainsKey(fc))
boxtype = geoboxdict[fc];
if (!geoboxtemplates.ContainsKey(boxtype))
Console.WriteLine("XXXXXXXXX Bad box type: " + boxtype);
return "";
//creates dummy page, in order to use DNWB tools for template handling
Page dummy = new Page(makesite, "dummy");
dummy.text = geoboxtemplates[boxtype];
//Console.WriteLine("Före:"+dummy.text.Substring(0,30));
dummy.SetTemplateParameter("geobox","name",gndict[gnid].Name_ml,true);
//Console.WriteLine("1:" + dummy.text.Substring(0, 30));
allnames.Add(gndict[gnid].Name_ml);
int othernames = 0;
if ( gndict[gnid].Name != gndict[gnid].Name_ml)
dummy.SetTemplateParameter("geobox","other_name",gndict[gnid].Name,true);
allnames.Add(gndict[gnid].Name);
othernames++;
if ( altdict.ContainsKey(gnid))
int nativenames = 0;
foreach (altnameclass ac in altdict[gnid])
if (!allnames.Contains(ac.altname))
if (countrydict[icountry].languages.Contains(ac.ilang))
nativenames++;
if (ac.official)
dummy.SetTemplateParameter("geobox", "official_name", ac.altname, true);
allnames.Add(ac.altname);
if (ac.colloquial)
dummy.SetTemplateParameter("geobox", "nickname", ac.altname, true);
allnames.Add(ac.altname);
if ( nativenames > 0)
//bool nativeset = false;
foreach (altnameclass ac in altdict[gnid])
if (!allnames.Contains(ac.altname))
if (countrydict[icountry].languages.Contains(ac.ilang))
dummy.SetTemplateParameter("geobox", "native_name", ac.altname, true);
allnames.Add(ac.altname);
break; //set only once
foreach (altnameclass ac in altdict[gnid])
if (!allnames.Contains(ac.altname))
//if ( !countrydict[icountry].languages.Contains(ac.ilang))
string order = "";
if (othernames > 0)
order = othernames.ToString();
if ((!String.IsNullOrEmpty(ac.altname)) && (!allnames.Contains(ac.altname)))
dummy.SetTemplateParameter("geobox", "other_name" + order, ac.altname, true);
allnames.Add(ac.altname);
othernames++;
else
foreach (altnameclass ac in altdict[gnid])
if (!allnames.Contains(ac.altname))
string order = "";
if (othernames > 0)
order = othernames.ToString();
if (!allnames.Contains(ac.altname))
dummy.SetTemplateParameter("geobox", "other_name" + order, ac.altname, true);
allnames.Add(ac.altname);
othernames++;
//Console.WriteLine("2:" + dummy.text.Substring(0, 30));
string latstring = gndict[gnid].latitude.ToString(culture_en);
if ( !latstring.Contains("."))
latstring += ".0";
string lonstring = gndict[gnid].longitude.ToString(culture_en);
if ( !lonstring.Contains("."))
lonstring += ".0";
dummy.SetTemplateParameter("geobox","lat_d",latstring,true);
dummy.SetTemplateParameter("geobox","long_d",lonstring,true);
string cat = initialcap(getfeaturelabel(countrydict[icountry].iso, gndict[gnid].featurecode, gnid));
dummy.SetTemplateParameter("geobox", "category", cat, true);
string countrynameml = countrydict[icountry].Name;
if (countryml.ContainsKey(countrynameml))
countrynameml = countryml[countrynameml];
if (makelang == "sv")
dummy.SetTemplateParameter("geobox","country",countrynameml,true);
dummy.SetTemplateParameter("geobox","country_flag","true",true);
else
dummy.SetTemplateParameter("geobox","country","{{flag|"+countrynameml+"}}",true);
int nc = 0;
int mamagnid = -1;
if ( motherdict.ContainsKey(makecountry))
string mama = motherdict[makecountry];
mamagnid = countryid[mama];
nc++;
string acml = countrydict[mamagnid].Name;
if (countryml.ContainsKey(acml))
acml = countryml[acml];
if (makelang == "sv")
dummy.SetTemplateParameter("geobox", "country"+nc.ToString(), acml, true);
dummy.SetTemplateParameter("geobox", "country_flag" + nc.ToString(), "true", true);
else
dummy.SetTemplateParameter("geobox", "country" + nc.ToString(), "{{flag|" + acml + "}}", true);
dummy.SetTemplateParameter("geobox", "country_type", mp(294,null), true);
foreach (int ic in gndict[gnid].altcountry)
nc++;
if ( ic == mamagnid )
continue;
string acml = countrydict[ic].Name;
if (countryml.ContainsKey(acml))
acml = countryml[acml];
if (makelang == "sv")
dummy.SetTemplateParameter("geobox", "country"+nc.ToString(), acml, true);
dummy.SetTemplateParameter("geobox", "country_flag" + nc.ToString(), "true", true);
else
dummy.SetTemplateParameter("geobox", "country" + nc.ToString(), "{{flag|" + acml + "}}", true);
if (!string.IsNullOrEmpty(getgnidname(gndict[gnid].adm[1])))
dummy.SetTemplateParameter("geobox", "state", makegnidlink(gndict[gnid].adm[1]), true);
dummy.SetTemplateParameter("geobox", "state_type", initialcap(removearticle(getadmlabel(makecountry, 1, gndict[gnid].adm[1]))), true);
if (!string.IsNullOrEmpty(getgnidname(gndict[gnid].adm[2])))
dummy.SetTemplateParameter("geobox", "region", makegnidlink(gndict[gnid].adm[2]), true);
dummy.SetTemplateParameter("geobox", "region_type", initialcap(getadmlabel(makecountry, 2,gndict[gnid].adm[2])), true);
if (!string.IsNullOrEmpty(getgnidname(gndict[gnid].adm[3])))
dummy.SetTemplateParameter("geobox", "district", makegnidlink(gndict[gnid].adm[3]), true);
dummy.SetTemplateParameter("geobox", "district_type", initialcap(getadmlabel(makecountry, 3, gndict[gnid].adm[3])), true);
if (!string.IsNullOrEmpty(getgnidname(gndict[gnid].adm[4])))
dummy.SetTemplateParameter("geobox", "municipality", makegnidlink(gndict[gnid].adm[4]), true);
dummy.SetTemplateParameter("geobox", "municipality_type", initialcap(getadmlabel(makecountry, 4, gndict[gnid].adm[4])), true);
int elev = gndict[gnid].elevation;
if ( elev < 0 )
elev = gndict[gnid].dem;
string category = "";
if (categorydict.ContainsKey(fc))
category = categorydict[fc];
if ((category == "oceans") || (category == "seabed") || (category == "reefs") || (category == "navigation"))
elev = -9999;
if (elev > 0)
dummy.SetTemplateParameter("geobox", "elevation", elev.ToString("N0", nfi_en), true);
if (is_height(gndict[gnid].featurecode))
double width = 0;
int prom = get_prominence(gnid, out width);
if ( prom <= 0 )
//int nearhigh = -1;
int altitude = -1;
double nbradius = 3.0;
List
bool otherpeak = false;
Console.WriteLine("farlist = " + farlist.Count.ToString());
foreach (int nbgnid in farlist)
if (nbgnid != gnid)
if (is_height(gndict[nbgnid].featurecode) && (gndict[nbgnid].elevation > gndict[gnid].elevation))
otherpeak = true;
Console.WriteLine(gndict[nbgnid].Name);
if (!otherpeak)
Console.WriteLine("No other peak");
nbradius = 2.0;
double slat = 9999.9;
double slon = 9999.9;
altitude = get_summit(gnid, out slat, out slon);
Console.WriteLine("get summit " + slat.ToString() +" " + slon.ToString() + ": " + altitude.ToString());
double nhdist = get_distance_latlong(gndict[gnid].latitude, gndict[gnid].longitude, slat, slon);
Console.WriteLine("nhdist = " + nhdist.ToString());
if ((nhdist < nbradius) && ( nhdist > 0.1 ) && (altitude > elev))
gndict[gnid].latitude = slat;
gndict[gnid].longitude = slon;
gndict[gnid].elevation = altitude;
gndict[gnid].elevation_vp = altitude;
elev = altitude;
latstring = gndict[gnid].latitude.ToString("F4",culture_en);
if (!latstring.Contains("."))
latstring += ".0";
lonstring = gndict[gnid].longitude.ToString("F4",culture_en);
if (!lonstring.Contains("."))
lonstring += ".0";
dummy.SetTemplateParameter("geobox", "elevation", elev.ToString("N0", nfi_en), true);
dummy.SetTemplateParameter("geobox", "lat_d", latstring, true);
dummy.SetTemplateParameter("geobox", "long_d", lonstring, true);
dummy.SetTemplateParameter("geobox", "coordinates_note", addnote(mp(213, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null)), true);
prom = get_prominence(gnid, out width);
if (prom > minimum_prominence)
dummy.SetTemplateParameter("geobox", "height", prom.ToString("N0", nfi_en), true);
dummy.SetTemplateParameter("geobox", "width", fnum(width), true);
dummy.SetTemplateParameter("geobox", "width_unit", "km", true);
dummy.SetTemplateParameter("geobox", "highest_elevation", elev.ToString("N0", nfi_en), true);
dummy.SetTemplateParameter("geobox", "elevation", (elev - prom).ToString("N0", nfi_en), true);
gndict[gnid].prominence = prom;
gndict[gnid].width = width;
if (gndict.ContainsKey(gndict[gnid].inrange))
dummy.SetTemplateParameter("geobox", "range", makegnidlink(gndict[gnid].inrange), true);
bool haspop = false;
if (prefergeonamespop)
if (gndict[gnid].population > minimum_population)
dummy.SetTemplateParameter("geobox", "population", gndict[gnid].population.ToString(), true);
haspop = true;
if (gndict[gnid].population == gndict[gnid].population_wd)
dummy.SetTemplateParameter("geobox", "population_note", "" + mp(131, null) + " " + gndict[gnid].population_wd_iw + "wiki", true);
else
dummy.SetTemplateParameter("geobox", "population_note", geonameref(gnid), true);
dummy.SetTemplateParameter("geobox", "population_date", gndict[gnid].moddate, true);
else if ((wdid > 0) && (!String.IsNullOrEmpty(get_wd_prop(propdict["population"], currentxml))))
dummy.SetTemplateParameter("geobox", "population", wdlink("population"), true);
haspop = true;
dummy.SetTemplateParameter("geobox", "population_note", "" + mp(131, null) + " Wikidata", true);
long wdpop = tryconvert(get_wd_prop(propdict["population"], currentxml));
if (wdpop > 0)
gndict[gnid].population_wd = wdpop;
if ((gndict[gnid].population < minimum_population) || (!prefergeonamespop))
gndict[gnid].population = wdpop;
gndict[gnid].population_wd_iw = "Wikidata";
else if (gndict[gnid].population_wd > minimum_population)
dummy.SetTemplateParameter("geobox", "population", gndict[gnid].population_wd.ToString(), true);
haspop = true;
//dummy.SetTemplateParameter("geobox", "population_date", gndict[gnid].moddate, true);
dummy.SetTemplateParameter("geobox", "population_note", "" + mp(131, null) + " " + gndict[gnid].population_wd_iw + "wiki", true);
else
if ((wdid > 0) && (!String.IsNullOrEmpty(get_wd_prop(propdict["population"], currentxml))))
dummy.SetTemplateParameter("geobox", "population", wdlink("population"), true);
haspop = true;
dummy.SetTemplateParameter("geobox", "population_note", "" + mp(131, null) + " Wikidata", true);
long wdpop = tryconvert(get_wd_prop(propdict["population"], currentxml));
if (wdpop > 0)
gndict[gnid].population_wd = wdpop;
if ((gndict[gnid].population < minimum_population) || (!prefergeonamespop))
gndict[gnid].population = wdpop;
gndict[gnid].population_wd_iw = "Wikidata";
else if (gndict[gnid].population_wd > minimum_population)
dummy.SetTemplateParameter("geobox", "population", gndict[gnid].population_wd.ToString(), true);
haspop = true;
//dummy.SetTemplateParameter("geobox", "population_date", gndict[gnid].moddate, true);
dummy.SetTemplateParameter("geobox", "population_note", "" + mp(131, null) + " " + gndict[gnid].population_wd_iw + "wiki", true);
else if (gndict[gnid].population > minimum_population)
dummy.SetTemplateParameter("geobox", "population", gndict[gnid].population.ToString(), true);
haspop = true;
dummy.SetTemplateParameter("geobox", "population_date", gndict[gnid].moddate, true);
dummy.SetTemplateParameter("geobox", "population_note", geonameref(gnid), true);
if (gndict[gnid].area > minimum_area)
dummy.SetTemplateParameter("geobox", "area", gndict[gnid].area.ToString("N2", nfi_en), true);
if ( haspop )
dummy.SetTemplateParameter("geobox", "population_density", "auto", true);
if ( tzdict.ContainsKey(gndict[gnid].tz))
dummy.SetTemplateParameter("geobox", "timezone_label", gndict[gnid].tz, true);
dummy.SetTemplateParameter("geobox", "utc_offset", tzdict[gndict[gnid].tz].offset, true);
if ( tzdict[gndict[gnid].tz].summeroffset != tzdict[gndict[gnid].tz].offset )
dummy.SetTemplateParameter("geobox", "utc_offset_DST", tzdict[gndict[gnid].tz].summeroffset, true);
if (!String.IsNullOrEmpty(tzdict[gndict[gnid].tz].tzname))
dummy.SetTemplateParameter("geobox", "timezone", "[[" + tzdict[gndict[gnid].tz].tzfull+"|"+tzdict[gndict[gnid].tz].tzname+"]]", true);
if (tzdict[gndict[gnid].tz].summeroffset != tzdict[gndict[gnid].tz].offset)
dummy.SetTemplateParameter("geobox", "timezone_DST", "[[" + tzdict[gndict[gnid].tz].tzfullsummer + "|" + tzdict[gndict[gnid].tz].tzsummer + "]]", true);
if (wdid > 0) //get various stuff from Wikidata:
Console.WriteLine("Filling geobox from wikidata");
if (!String.IsNullOrEmpty(get_wd_prop(propdict["coat of arms"], currentxml)))
string imagename = get_wd_prop(propdict["coat of arms"], currentxml);
if ( exists_at_commons(imagename))
dummy.SetTemplateParameter("geobox", "symbol", imagename, true);
if (!String.IsNullOrEmpty(get_wd_prop(propdict["flag"], currentxml)))
dummy.SetTemplateParameter("geobox", "flag", get_wd_prop(propdict["flag"], currentxml), true);
//if (!String.IsNullOrEmpty(get_wd_prop(propdict("capital", currentxml))))
// dummy.SetTemplateParameter("geobox", "capital", wdlink("capital"));
if (!String.IsNullOrEmpty(get_wd_prop(propdict["locatormap"], currentxml)))
dummy.SetTemplateParameter("geobox", "map2", get_wd_prop(propdict["locatormap"], currentxml), true);
if (!String.IsNullOrEmpty(get_wd_prop(propdict["iso"], currentxml)))
dummy.SetTemplateParameter("geobox", "iso_code", wdlink("iso"), true);
//if (!String.IsNullOrEmpty(get_wd_prop(propdict("head of government", currentxml))))
// dummy.SetTemplateParameter("geobox", "leader", wdlink("head of government"));
if (!String.IsNullOrEmpty(get_wd_prop(propdict["postal code"], currentxml)))
dummy.SetTemplateParameter("geobox", "postal_code", wdlink("postal code"), true);
if (!String.IsNullOrEmpty(get_wd_prop(propdict["image"], currentxml)))
string imagename = get_wd_prop(propdict["image"], currentxml);
if (exists_at_commons(imagename))
dummy.SetTemplateParameter("geobox", "image", imagename, true);
else if (!String.IsNullOrEmpty(get_wd_prop(propdict["banner"], currentxml)))
string imagename = get_wd_prop(propdict["banner"], currentxml);
if (exists_at_commons(imagename))
dummy.SetTemplateParameter("geobox", "image", imagename, true);
foreach (int ic in get_wd_prop_idlist(propdict["capital"], currentxml))
dummy.SetTemplateParameter("geobox", "capital", get_wd_name(ic), true);
foreach (int ic in get_wd_prop_idlist(propdict["head of government"], currentxml))
dummy.SetTemplateParameter("geobox", "leader", get_wd_name(ic), true);
if (String.IsNullOrEmpty(get_wd_prop(propdict["gnid"], currentxml))) //if gnid NOT in wikidata, set it manually
dummy.SetTemplateParameter("geobox", "geonames", gnid.ToString(), true);
else //wdid missing, set geonames ID in template
dummy.SetTemplateParameter("geobox", "geonames", gnid.ToString(), true);
if (gndict[gnid].inrange > 0)
dummy.SetTemplateParameter("geobox", "range", makegnidlink(gndict[gnid].inrange), true);
else if (rangedict.ContainsKey(gnid))
//public class rangeclass //data for each MTS/HLLS
//{
// public double length = 0;
// public string orientation = "....";
// public double angle = 0; //polar angle of long axis (radians). 0 or pi = EW, pi/2 or 3pi/2 = NS etc.
// public double kmew = 0;
// public double kmns = 0;
// public int maxheight = 0; //highest point; gnid of peak if negative, height if positive
// public double hlat = 999; //latitude/longitude of highest point
// public double hlon = 999;
// public List
//}
dummy.SetTemplateParameter("geobox", "length", rangedict[gnid].length.ToString("N0", nfi_en), true);
dummy.SetTemplateParameter("geobox", "length_orientation", get_nsew(rangedict[gnid].angle), true);
int hmax = rangedict[gnid].maxheight;
int hgnid = -1;
if (hmax < 0)
if (gndict.ContainsKey(-hmax))
hgnid = -hmax;
hmax = gndict[hgnid].elevation;
if (hmax > 0)
string hlatstring = rangedict[gnid].hlat.ToString(culture_en);
if (!hlatstring.Contains("."))
hlatstring += ".0";
string hlonstring = rangedict[gnid].hlon.ToString(culture_en);
if (!hlonstring.Contains("."))
hlonstring += ".0";
if ( hgnid > 0 )
dummy.SetTemplateParameter("geobox", "highest_location", makegnidlink(hgnid), true);
dummy.SetTemplateParameter("geobox", "highest_elevation", hmax.ToString("N0", nfi_en), true);
dummy.SetTemplateParameter("geobox", "highest_lat_d", hlatstring, true);
dummy.SetTemplateParameter("geobox", "highest_long_d", hlonstring, true);
//Airport codes:
if (makelang == "sv")
if (iatadict.ContainsKey(gnid))
dummy.SetTemplateParameter("geobox", "IATA-kod", iatadict[gnid], true);
if (icaodict.ContainsKey(gnid))
dummy.SetTemplateParameter("geobox", "ICAO-kod", icaodict[gnid], true);
else
if (iatadict.ContainsKey(gnid))
dummy.SetTemplateParameter("geobox", "free", iatadict[gnid], true);
dummy.SetTemplateParameter("geobox", "free_type", "[[IATA]]", true);
if (icaodict.ContainsKey(gnid))
dummy.SetTemplateParameter("geobox", "free1", icaodict[gnid], true);
dummy.SetTemplateParameter("geobox", "free1_type", "[[ICAO]]", true);
//Console.WriteLine("3:" + dummy.text.Substring(0, 30));
if (locatoringeobox) //only works in Swedish!
string countryname = countrydict[icountry].Name;
//if (String.IsNullOrEmpty(locatordict[countryname].locatorimage))
//{
//string templatename = mp(63,null)+mp(72, null).Replace("{{", "") + " " + locatordict[countryname];
//Console.WriteLine(templatename);
//string imagename = "";
//Page ltp = new Page(makesite, templatename);
//tryload(ltp, 2);
//if (ltp.Exists())
//{
// imagename = get_pictureparam(ltp);
//}
//if (!String.IsNullOrEmpty(imagename))
//{
// locatordict[countryname].locatorimage = imagename;
//}
//}
if (locatordict.ContainsKey(countryname))
string templatestart = mp(72, null) + " " + locatordict[countryname].get_locator(gndict[gnid].latitude, gndict[gnid].longitude);
string imagename = "{{xxx|reliefkarta_om_den_finns}}".Replace("{{xxx", templatestart).Replace("bild", mp(171, null));
//string imagename = "{{#if:xxx|bild1}}|xxx|bild1}}|xxx|bild}}}}".Replace("xxx", templatestart).Replace("bild", mp(171, null));
string[] p143 = new string[1] { countrynameml };
dummy.SetTemplateParameter("geobox", "map", imagename, true);
dummy.SetTemplateParameter("geobox", "map_locator", locatordict[countryname].get_locator(gndict[gnid].latitude, gndict[gnid].longitude), true);
dummy.SetTemplateParameter("geobox", "map_caption", mp(143,p143), true);
//Console.WriteLine("Efter:" + dummy.text.Substring(0, 30));
return dummy.text;
public static string get_pictureparam(Page ltp)
string imagename = "";
string[] param = ltp.text.Split('|');
foreach (string par in param)
if (((par.Trim().ToLower().IndexOf("bild") == 0) || (par.Trim().ToLower().IndexOf("image") == 0)) && (par.Contains("=")))
imagename = par.Split('=')[1].Trim();
if (imagename.Contains("}}"))
imagename = imagename.Remove(imagename.IndexOf("}}")).Trim();
//Console.WriteLine("imagename = " + imagename);
break;
return imagename;
public static double get_edgeparam(Page ltp,string edgepar)
string imagename = "";
string[] param = ltp.text.Split('|');
foreach (string par in param)
if ((par.Trim().ToLower().IndexOf(edgepar) == 0) && (par.Contains("=")))
imagename = par.Split('=')[1].Trim();
if (imagename.Contains("}}"))
imagename = imagename.Remove(imagename.IndexOf("}}")).Trim();
//Console.WriteLine("imagename = " + imagename);
break;
return tryconvertdouble(imagename);
public static bool exists_at_commons(string imagename)
string res = cmsite.indexPath + "?title=" +
HttpUtility.UrlEncode("File:" + imagename);
//Console.WriteLine("commonsres = " + res);
string src = "";
try
src = cmsite.GetWebPage(res); // cmsite.GetPageHTM(res);
Console.WriteLine("Found at Commons: " + imagename);
return true;
catch (WebException e)
//newpix[newpic] = "/// NOT FOUND ON COMMONS";
string message = e.Message;
if (message.Contains(": (404) "))
{ // Not Found
Console.Error.WriteLine(Bot.Msg("Page \"{0}\" doesn't exist."), imagename);
Console.WriteLine("Image not found: " + imagename);
//continue;
else
Console.Error.WriteLine(message);
//continue;
return false;
public static void fix_positionmaps()
//https://tools.wmflabs.org/magnus-toolserver/commonsapi.php?image=Bhutan_location_map.svg
Dictionary
Dictionary
replacedict1.Add("|topp", "| topp");
replacedict1.Add(" topp=", " topp =");
replacedict1.Add("|botten", "| botten");
replacedict1.Add(" botten=", " botten =");
replacedict1.Add("|vänster", "| vänster");
replacedict1.Add(" vänster=", " vänster =");
replacedict1.Add("|höger", "| höger");
replacedict1.Add(" höger=", " höger =");
replacedict1.Add("|bild", "| bild");
replacedict1.Add(" bild=", " bild =");
replacedict2.Add("| topp ", "| topp|top ");
replacedict2.Add("| botten ", "| botten|bottom ");
replacedict2.Add("| vänster ", "| vänster|left ");
replacedict2.Add("| höger ", "| höger|right ");
foreach (string countryname in locatordict.Keys)
Console.WriteLine("countryname = " + countryname);
string templatename = mp(63, null) + mp(72, null).Replace("{{", "") + " " + locatordict[countryname].locatorname;
Console.WriteLine(templatename);
string imagename = "";
Page ltp = new Page(makesite, templatename);
tryload(ltp, 2);
if (ltp.Exists())
if (ltp.text.Contains("topp|top"))
continue;
imagename = get_pictureparam(ltp);
if (!String.IsNullOrEmpty(imagename))
foreach (KeyValuePair
ltp.text = ltp.text.Replace(replacepair.Key, replacepair.Value);
foreach (KeyValuePair
ltp.text = ltp.text.Replace(replacepair.Key, replacepair.Value);
XmlDocument xd = new XmlDocument();
string cmurl = "https://tools.wmflabs.org/magnus-toolserver/commonsapi.php?image=" + imagename;
string s = get_webpage(cmurl);
if (!String.IsNullOrEmpty(s))
//Console.WriteLine(s);
xd.LoadXml(s);
XmlNodeList elemlist1 = xd.GetElementsByTagName("width");
double width = -1;
foreach (XmlNode ee in elemlist1)
width = tryconvertdouble(ee.InnerXml);
XmlNodeList elemlist2 = xd.GetElementsByTagName("height");
double height = -1;
foreach (XmlNode ee in elemlist2)
height = tryconvertdouble(ee.InnerXml);
Console.WriteLine("w,h = " + width.ToString() + ", " + height.ToString());
double ratio = height / width;
if ( !ltp.text.Contains("ratio"))
ltp.text = ltp.text.Replace("| bild ", "| ratio = " + ratio.ToString(culture_en) + "\n| bild ");
trysave(ltp, 2);
string redirectname = mp(63, null) + "Geobox locator " + locatordict[countryname].locatorname;
make_redirect(redirectname, templatename, "Geobox locator|" + locatordict[countryname].locatorname,-1);
//Mall:Geobox locator Andorra
//#OMDIRIGERING[[Mall:Kartposition Andorra]]
//[[Kategori:Geobox locator|Andorra]]
//Console.WriteLine("
//Console.ReadLine();
Console.WriteLine("Done!");
Console.ReadLine();
public static void get_page_area_pop_height(Page p, out double areaout, out long popout, out int heightout)
areaout = -1;
popout = -1;
heightout = -1;
List
List
List
List
popparams.Add("population");
popparams.Add("population_total");
popparams.Add("population_urban");
popparams.Add("population_metro");
popparams.Add("befolkning");
urbanparams.Add("population_urban");
urbanparams.Add("population_metro");
urbanparams.Add("población_urb");
areaparams.Add("area_total_km2");
areaparams.Add("area");
areaparams.Add("fläche");
areaparams.Add("superficie");
areaparams.Add("yta");
heightparams.Add("highest_elevation");
heightparams.Add("elevation");
bool foundpop = false;
bool foundurban = false;
bool foundarea = false;
//bool foundheight = false;
bool foundhighest = false;
bool preferurban = true;
long popwdurban = -1;
foreach (string ttt in p.GetTemplates(true, true))
//Console.WriteLine(ttt);
Dictionary
foreach (string param in pdict.Keys)
if (popparams.Contains(param) && !foundpop)
long popwd = tryconvertlong(pdict[param]);
if (popwd <= 0)
popwd = tryconvertlong(pdict[param].Split()[0]);
if (popwd > 0)
foundpop = true;
popout = popwd;
if (urbanparams.Contains(param) && !foundurban)
long popwd = tryconvertlong(pdict[param]);
if (popwd > 0)
foundurban = true;
popwdurban = popwd;
if (areaparams.Contains(param) && !foundarea)
double areawd = tryconvertdouble(pdict[param]);
if (areawd <= 0)
areawd = tryconvertdouble(pdict[param].Split()[0]);
Console.WriteLine("areaparam = " + pdict[param]);
Console.WriteLine("areawd = " + areawd.ToString());
if (areawd > 0)
foundarea = true;
areaout = areawd;
if (heightparams.Contains(param) && !foundhighest)
int heightwd = tryconvert(pdict[param]);
if (heightwd <= 0)
heightwd = tryconvert(pdict[param].Split()[0]);
Console.WriteLine("heightparam = " + param);
Console.WriteLine("heightwd = " + heightwd.ToString());
if (heightwd > 0)
//foundheight = true;
heightout = heightwd;
if (param.Contains("highest"))
foundhighest = true;
if (preferurban && foundurban)
popout = popwdurban;
public static void get_wd_area_pop(int wdid, XmlDocument cx, out double areawdout, out long popwdout, out string iwsout, bool preferurban)
areawdout = -1.0;
popwdout = -1;
iwsout = "";
long popwdurban = -1;
string iwsurban = "";
List
List
List
List
popparams.Add("population");
popparams.Add("population_total");
popparams.Add("population_urban");
popparams.Add("population_metro");
popparams.Add("poblacion");
popparams.Add("población");
popparams.Add("población_urb");
popparams.Add("einwohner");
urbanparams.Add("population_urban");
urbanparams.Add("population_metro");
urbanparams.Add("población_urb");
areaparams.Add("area_total_km2");
areaparams.Add("area");
areaparams.Add("fläche");
areaparams.Add("superficie");
paramlangs.Add("en");
paramlangs.Add("de");
paramlangs.Add("fr");
paramlangs.Add("es");
if (!paramlangs.Contains(countrydict[countryid[makecountry]].nativewiki) && !String.IsNullOrEmpty(countrydict[countryid[makecountry]].nativewiki))
paramlangs.Add(countrydict[countryid[makecountry]].nativewiki);
string badlang = "";
foreach (string iwl in paramlangs)
if ((!iwsites.ContainsKey(iwl)) && (iwl != makelang))
Console.WriteLine(iwl);
try
Site ssite = new Site("https://" + iwl + ".wikipedia.org", botname, password);
iwsites.Add(iwl, ssite);
catch (WebException e)
string message = e.Message;
Console.Error.WriteLine(message);
badlang = iwl;
catch (WikiBotException e)
string message = e.Message;
Console.Error.WriteLine(message);
badlang = iwl;
if (!String.IsNullOrEmpty(badlang))
paramlangs.Remove(badlang);
if (cx == null)
cx = get_wd_xml(wdid);
if (cx == null)
Console.WriteLine("cx = null");
return;
Dictionary
bool foundpop = false;
bool foundurban = false;
bool foundarea = false;
foreach (string iws in iwdict.Keys)
string iwss = iws.Replace("wiki", "");
Console.WriteLine(iwss + ":" + iwdict[iws]);
if ((paramlangs.Contains(iwss))&&(iwsites.ContainsKey(iwss)))
Console.WriteLine(iws + ":" + iwdict[iws] + " Paramlang!");
Page iwpage = new Page(iwsites[iwss], iwdict[iws]);
if (tryload(iwpage, 1))
if (iwpage.Exists())
foreach (string ttt in iwpage.GetTemplates(true, true))
//Console.WriteLine(ttt);
Dictionary
foreach (string param in pdict.Keys)
if (popparams.Contains(param) && !foundpop)
long popwd = tryconvertlong(pdict[param]);
if (popwd > 0)
foundpop = true;
popwdout = popwd;
iwsout = iwss;
if (urbanparams.Contains(param) && !foundurban)
long popwd = tryconvertlong(pdict[param]);
if (popwd > 0)
foundurban = true;
popwdurban = popwd;
iwsurban = iwss;
if (areaparams.Contains(param) && !foundarea)
double areawd = tryconvertdouble(pdict[param]);
if (areawd <= 0)
areawd = tryconvertdouble(pdict[param].Split()[0]);
Console.WriteLine("areaparam = " + pdict[param]);
Console.WriteLine("areawd = " + areawd.ToString());
if (areawd > 0)
foundarea = true;
areawdout = areawd;
if (foundarea && foundpop && (foundurban || !preferurban))
break;
if (preferurban && foundurban)
popwdout = popwdurban;
iwsout = iwsurban;
public static void check_wikidata()
int nwd = 0;
int npop = 0;
int narea = 0;
using (StreamWriter sw = new StreamWriter("wikidata-" + makecountry + ".txt"))
int ngnid = gndict.Count;
foreach (int gnid in gndict.Keys)
Console.WriteLine("====="+makecountry+"======== "+ngnid.ToString()+" remaining. ===========");
ngnid--;
if ((ngnid % 1000) == 0)
Console.WriteLine("Garbage collection:");
GC.Collect();
//wdid = get_wd_item(gnid);
if (gndict[gnid].wdid <= 0)
continue;
else
wdid = gndict[gnid].wdid;
Console.WriteLine(gndict[gnid].Name + ": " + wdid.ToString());
if (wdid > 0)
nwd++;
double areawd = -1.0;
long popwd = -1;
string iwss = "";
bool preferurban = (gndict[gnid].featureclass == 'P');
get_wd_area_pop(wdid, null, out areawd, out popwd, out iwss, preferurban);
if (popwd > 0)
Console.WriteLine("popwd = " + popwd.ToString());
gndict[gnid].population_wd = popwd;
gndict[gnid].population_wd_iw = iwss;
npop++;
if (areawd > 0)
gndict[gnid].area = areawd;
narea++;
//Console.WriteLine("
//Console.ReadLine();
sw.WriteLine(gnid.ToString() + tabstring + wdid.ToString() + tabstring + gndict[gnid].area.ToString() + tabstring + gndict[gnid].population_wd.ToString() + tabstring + gndict[gnid].population_wd_iw);
Console.WriteLine("nwd = " + nwd.ToString());
Console.WriteLine("npop = " + npop.ToString());
Console.WriteLine("narea = " + narea.ToString());
Console.WriteLine("gndict = " + gndict.Count.ToString());
nwdhist.PrintSHist();
public static void read_good_wd_file()
Console.WriteLine("read_good_wd_file");
int nwdtot = 0;
if (!File.Exists("wikidata-good.nt"))
return;
using (StreamReader sr = new StreamReader("wikidata-good.nt"))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
if (words.Length < 2)
continue;
nwdtot++;
int gnid = tryconvert(words[0]);
if (!gndict.ContainsKey(gnid))
continue;
int wdid = tryconvert(words[1]);
if (wdid <= 0)
continue;
gndict[gnid].wdid = wdid;
if (!wdgniddict.ContainsKey(wdid))
wdgniddict.Add(wdid, gnid);
else if (wdgniddict[wdid] != gnid)
{// negative numbers count how many duplicates
if (wdgniddict[wdid] > 0)
wdgniddict[wdid] = -2;
else
wdgniddict[wdid]--;
if (( nwdtot % 10000 ) == 0 )
Console.WriteLine("nwdtot = " + nwdtot.ToString());
Console.WriteLine("nwdtot = " + nwdtot.ToString());
public static Dictionary
Dictionary
string filename = geonamesfolder + "wikidata\\wikidata-" + wdcountry + ".txt";
string filename_override = geonamesfolder + "wikidata\\wikidata-" + wdcountry + "-override.txt";
if (!File.Exists(filename))
Console.WriteLine("No file " + filename);
return rdict;
Dictionary
if (File.Exists(filename_override)) //use to override wd assignments in case of systematic errors in main wd run
int nover = 0;
using (StreamReader sr = new StreamReader(filename_override))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
if (words.Length < 2)
continue;
int gnid0 = tryconvert(words[0]);
int gnid1 = tryconvert(words[1]);
if ((gnid0 <= 0) || (gnid1 <= 0))
continue;
if (overridedict.ContainsKey(gnid0))
continue;
overridedict.Add(gnid0, gnid1);
nover++;
Console.WriteLine("noverride = " + nover.ToString());
try
List
//first pass, in order to doublecheck overridedict
if (overridedict.Count > 0)
Console.WriteLine("First pass...");
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
//sw.WriteLine(gnid.ToString() + tabstring + wdid.ToString() + tabstring + gndict[gnid].area.ToString() + tabstring + gndict[gnid].population_wd.ToString() + tabstring + gndict[gnid].population_wd_iw);
if (words.Length < 4)
continue;
int gnid = tryconvert(words[0]);
withwd.Add(gnid);
foreach (int gnid in withwd) //remove from overridedict those where both have wd match
if (overridedict.ContainsKey(gnid))
if (withwd.Contains(overridedict[gnid]))
overridedict.Remove(gnid);
Console.WriteLine("Remaining in overridedict: " + overridedict.Count.ToString());
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
//sw.WriteLine(gnid.ToString() + tabstring + wdid.ToString() + tabstring + gndict[gnid].area.ToString() + tabstring + gndict[gnid].population_wd.ToString() + tabstring + gndict[gnid].population_wd_iw);
if (words.Length < 4)
continue;
int gnid = tryconvert(words[0]);
if (overridedict.ContainsKey(gnid))
Console.WriteLine("Overriding " + gnid.ToString() + " with " + overridedict[gnid].ToString());
gnid = overridedict[gnid];
int wdid = tryconvert(words[1]);
if (wdid <= 0)
continue;
nwdtot++;
rdict.Add(gnid, wdid);
catch (IOException e)
string message = e.Message;
Console.Error.WriteLine(message);
return rdict;
public static void read_wd_file(string wdcountry)
string filename = geonamesfolder + "wikidata\\wikidata-" + wdcountry + ".txt";
string filename_override = geonamesfolder + "wikidata\\wikidata-" + wdcountry + "-override.txt";
if (!File.Exists(filename))
Console.WriteLine("No file " + filename);
return;
Dictionary
if (File.Exists(filename_override)) //use to override wd assignments in case of systematic errors in main wd run
int nover = 0;
using (StreamReader sr = new StreamReader(filename_override))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
if (words.Length < 2)
continue;
int gnid0 = tryconvert(words[0]);
int gnid1 = tryconvert(words[1]);
if ((gnid0 <= 0) || (gnid1 <= 0))
continue;
if (overridedict.ContainsKey(gnid0))
continue;
overridedict.Add(gnid0, gnid1);
nover++;
Console.WriteLine("noverride = "+nover.ToString());
try
wdtime = File.GetCreationTime(@filename);
Console.WriteLine("wdtime = "+wdtime.ToString());
//Console.WriteLine("
//Console.ReadLine();
List
//first pass, in order to doublecheck overridedict
if (overridedict.Count > 0)
Console.WriteLine("First pass...");
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
//sw.WriteLine(gnid.ToString() + tabstring + wdid.ToString() + tabstring + gndict[gnid].area.ToString() + tabstring + gndict[gnid].population_wd.ToString() + tabstring + gndict[gnid].population_wd_iw);
if (words.Length < 4)
continue;
int gnid = tryconvert(words[0]);
withwd.Add(gnid);
foreach (int gnid in withwd) //remove from overridedict those where both have wd match
if (overridedict.ContainsKey(gnid))
if (withwd.Contains(overridedict[gnid]))
overridedict.Remove(gnid);
Console.WriteLine("Remaining in overridedict: " + overridedict.Count.ToString());
using (StreamReader sr = new StreamReader(filename))
while (!sr.EndOfStream)
String line = sr.ReadLine();
string[] words = line.Split(tabchar);
//sw.WriteLine(gnid.ToString() + tabstring + wdid.ToString() + tabstring + gndict[gnid].area.ToString() + tabstring + gndict[gnid].population_wd.ToString() + tabstring + gndict[gnid].population_wd_iw);
if (words.Length < 4)
continue;
int gnid = tryconvert(words[0]);
if (overridedict.ContainsKey(gnid))
Console.WriteLine("Overriding " + gnid.ToString() + " with " + overridedict[gnid].ToString());
gnid = overridedict[gnid];
if (!gndict.ContainsKey(gnid))
continue;
int wdid = tryconvert(words[1]);
if (wdid <= 0)
continue;
nwdtot++;
gndict[gnid].wdid = wdid;
if (!wdgniddict.ContainsKey(wdid))
wdgniddict.Add(wdid, gnid);
else if ( wdgniddict[wdid] != gnid)
{// negative numbers count how many duplicates
if (wdgniddict[wdid] > 0)
wdgniddict[wdid] = -2;
else
wdgniddict[wdid]--;
double area = tryconvertdouble(words[2]);
if (area > 0)
//Console.WriteLine("area>0");
if (verifygeonames && (gndict[gnid].area > 0))
//Console.WriteLine("gnid-area>0");
double eps = 0;
while (areavsarea.ContainsKey(area + eps))
eps += 0.00001;
areavsarea.Add(area + eps, gndict[gnid].area + eps);
gndict[gnid].area = area;
long pop = tryconvertlong(words[3]);
if (pop > 0)
if (verifygeonames && (gndict[gnid].population > 10 ))
Console.WriteLine("pop.vs.pop:"+gndict[gnid].population.ToString() + tabstring+ pop.ToString());
int j=0;
while (popvspop.ContainsKey(pop+j))
j++;
popvspop.Add(pop+j,gndict[gnid].population+j);
if ( ((gndict[gnid].population < minimum_population) || !prefergeonamespop) && !verifygeonames )
gndict[gnid].population = pop;
gndict[gnid].population_wd = pop;
if (words.Length >= 5)
gndict[gnid].population_wd_iw = words[4];
//Console.WriteLine(gndict[gnid].Name + ": " + gndict[gnid].population_wd.ToString() + gndict[gnid].population_wd_iw);
//public static Dictionary
//public static Dictionary
//public static Dictionary
catch (IOException e)
string message = e.Message;
Console.Error.WriteLine(message);
public static void read_wd_files(string countrycode)
if (countrycode == "")
foreach (int gnid in countrydict.Keys)
read_wd_file(countrydict[gnid].iso);
else
read_wd_file(countrycode);
public static String stripNonValidXMLCharacters(string textIn)
StringBuilder textOut = new StringBuilder(); // Used to hold the output.
char current; // Used to reference the current character.
if (textIn == null || textIn == string.Empty) return string.Empty; // vacancy test.
for (int i = 0; i < textIn.Length; i++)
current = textIn[i];
if ((current == 0x9 || current == 0xA || current == 0xD) ||
((current >= 0x20) && (current <= 0xD7FF)) ||
((current >= 0xE000) && (current <= 0xFFFD)))
//|| ((current >= 0x10000) && (current <= 0x10FFFF)))
textOut.Append(current);
return textOut.ToString();
public static string get_webpage(string url)
WebClient client = new WebClient();
// Add a user agent header in case the
// requested URI contains a query.
client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
try
Stream data = client.OpenRead(url);
StreamReader reader = new StreamReader(data);
string s = reader.ReadToEnd();
data.Close();
reader.Close();
return s;
catch (WebException e)
string message = e.Message;
Console.Error.WriteLine(message);
return "";
public static string getxmlpar(string par, XmlNode node)
foreach (XmlNode xn in node.ChildNodes)
if (xn.Name == par)
string s = xn.InnerXml;
return s;
return "";
public static List
List
XmlDocument propx = new XmlDocument();
XmlNode propnode = get_property_node(propid, cx);
if (propnode == null)
return rl;
propx.AppendChild(propx.ImportNode(propnode, true));
// teamDoc.AppendChild(teamDoc.ImportNode(teamNode, true));
XmlNodeList mslist = propx.GetElementsByTagName("mainsnak");
foreach (XmlNode msn in mslist)
XmlDocument msx = new XmlDocument();
msx.AppendChild(msx.ImportNode(msn, true));
XmlNodeList elemlist = msx.GetElementsByTagName("value");
foreach (XmlNode ee in elemlist)
try
int rs = tryconvert(ee.Attributes.GetNamedItem("numeric-id").Value);
if (rs > 0)
rl.Add(rs);
catch (NullReferenceException e)
Console.Error.WriteLine(e.Message);
return rl;
public static string get_wd_prop(int propid, XmlDocument cx)
XmlNode propnode = get_property_node(propid, cx);
if (propnode == null)
return "";
//Console.WriteLine("propnode = " + propnode.ToString());
XmlDocument propx = new XmlDocument();
propx.AppendChild(propx.ImportNode(propnode,true));
XmlNodeList elemlist = propx.GetElementsByTagName("datavalue");
string rs = "";
foreach (XmlNode ee in elemlist)
try
rs = ee.Attributes.GetNamedItem("value").Value;
catch (NullReferenceException e)
Console.Error.WriteLine(e.Message);
Console.WriteLine("get_wd_prop:rs: " + rs);
return rs;
public static double[] get_wd_position(XmlDocument cx)
double[] rl = { 9999.0, 9999.0 };
XmlNode propnode = get_property_node(propdict["position"], cx);
if (propnode == null)
return rl;
//Console.WriteLine("propnode = " + propnode.ToString());
XmlDocument propx = new XmlDocument();
propx.AppendChild(propx.ImportNode(propnode, true));
XmlNodeList elemlist = propx.GetElementsByTagName("value");
//string rs = "";
foreach (XmlNode ee in elemlist)
try
rl[0] = tryconvertdouble(ee.Attributes.GetNamedItem("latitude").Value);
rl[1] = tryconvertdouble(ee.Attributes.GetNamedItem("longitude").Value);
catch (NullReferenceException e)
Console.Error.WriteLine(e.Message);
Console.WriteLine("get_wd_prop:rl: " + rl[0].ToString() + " | " + rl[1].ToString());
return rl;
public static string wdlink(string prop)
if (!propdict.ContainsKey(prop))
Console.WriteLine("Invalid property: " + prop);
return "";
string s = "{{#property:P"+propdict[prop].ToString()+"}}";
return s;
public static XmlDocument get_wd_xml(int wdid)
string url = "https://www.wikidata.org/w/api.php?action=wbgetentities&format=xml&ids=Q" + wdid.ToString() + "&redirects=yes";
XmlDocument xd = new XmlDocument();
string s = get_webpage(url);
if (String.IsNullOrEmpty(s))
return null;
//Console.WriteLine(s);
try
xd.LoadXml(s);
catch (XmlException e)
string message = e.Message;
Console.Error.WriteLine("tl we " + message);
return null;
return xd;
public static int get_wd_gnid(int wdid)
XmlDocument cx = get_wd_xml(wdid);
if (cx == null)
return -1;
else
return tryconvert(get_wd_prop(propdict["gnid"], cx));
public static XmlNode get_property_node(int propid, XmlDocument cx)
XmlNodeList elemlist = cx.GetElementsByTagName("property");
//Console.WriteLine("get_property_node: elemlist: " + elemlist.Count.ToString());
foreach (XmlNode ee in elemlist)
try
string id = ee.Attributes.GetNamedItem("id").Value;
//Console.WriteLine("id = " + id);
if (id == "P" + propid.ToString())
//Console.WriteLine("get_property_node: found!");
return ee;
catch (NullReferenceException e)
Console.Error.WriteLine(e.Message);
//Console.WriteLine("get_property_node: not found");
return null;
public static List
List
List
XmlDocument ee = new XmlDocument();
XmlNode propnode = get_property_node(150, cx);
if (propnode == null)
return rl;
ee.AppendChild(ee.ImportNode(propnode, true));
//ee.DocumentElement.AppendChild(propnode);
//XmlNode ee = get_property_node(150, cx);
if ( ee == null )
return rl;
XmlNodeList elemlist = ee.GetElementsByTagName("value");
Console.WriteLine("get-wd_kids: elemlist " + elemlist.Count.ToString());
foreach (XmlNode eee in elemlist)
Console.WriteLine("eee.Attributes: " + eee.Attributes.ToString());
try
string etype = eee.Attributes.GetNamedItem("entity-type").Value;
Console.WriteLine("etype = " + etype);
if (etype == "item")
string id = eee.Attributes.GetNamedItem("numeric-id").Value;
Console.WriteLine("id = " + id);
int iid = tryconvert(id);
if (iid > 0)
if (!rl.Contains(iid))
rl.Add(iid);
else if ( !rldouble.Contains(iid))
rldouble.Add(iid);
catch (NullReferenceException e)
Console.WriteLine(e);
foreach (int ii in rldouble)
rl.Remove(ii);
return rl;
public static Dictionary
Dictionary
XmlNodeList elemlist = cx.GetElementsByTagName("sitelink");
foreach (XmlNode ee in elemlist)
try
string lang = ee.Attributes.GetNamedItem("site").Value;
string value = ee.Attributes.GetNamedItem("title").Value;
//Console.WriteLine("get_wd_sitelinks: lang,value : " + lang + " " + value);
if (!rd.ContainsKey(lang))
rd.Add(lang, value);
catch (NullReferenceException e)
eglob = e;
return rd;
public static string iwlinks(XmlDocument cx)
Dictionary
string iws = "\n\n";
foreach (string sw in rd.Keys)
string s = sw.Replace("wiki", "");
if (s == makelang)
return "Exists already:"+rd[sw];
if ((s.Length == 2) || (s.Length == 3))
iws += "[[" + s + ":" + rd[sw] + "]]\n";
//Console.WriteLine("iwlinks: " + iws);
return iws;
public static Dictionary
Dictionary
XmlNodeList elemlist = cx.GetElementsByTagName("label");
foreach (XmlNode ee in elemlist)
try
string lang = ee.Attributes.GetNamedItem("language").Value;
string value = ee.Attributes.GetNamedItem("value").Value;
if (!rd.ContainsKey(lang))
rd.Add(lang, value);
catch (NullReferenceException e)
Console.Error.WriteLine(e.Message);
return rd;
public static string get_wd_name_from_xml(XmlDocument cx)
return get_wd_name_from_xml(cx, makelang);
public static string get_wd_name_from_xml(XmlDocument cx, string mainlang)
Dictionary
if (cx == null)
return "";
XmlNodeList elemlist = cx.GetElementsByTagName("label");
Console.WriteLine("elemlist " + elemlist.Count.ToString());
foreach (XmlNode ee in elemlist)
try
string lang = ee.Attributes.GetNamedItem("language").Value;
string value = ee.Attributes.GetNamedItem("value").Value;
//Console.WriteLine("lang,value = " + lang +"|"+ value);
if (!rd.ContainsKey(lang))
if (lang == mainlang)
return value;
else
rd.Add(lang, value);
catch (NullReferenceException e)
//Console.Error.WriteLine(e.Message);
eglob = e;
//Pick the most common form:
Dictionary
foreach (string lang in rd.Keys)
if (!namestats.ContainsKey(rd[lang]))
namestats.Add(rd[lang], 0);
namestats[rd[lang]]++;
string name = "";
int maxuse = 0;
foreach (string nn in namestats.Keys)
Console.WriteLine(nn);
if (namestats[nn] > maxuse)
maxuse = namestats[nn];
name = nn;
Console.WriteLine("maxuse = " + maxuse.ToString());
Console.WriteLine("get_wd_name_from_xml " + name);
return name;
public static string get_wd_name(int wdid)
string url = "https://www.wikidata.org/w/api.php?action=wbgetentities&ids=Q" + wdid.ToString() + "&props=labels&format=xml";
string xmlitem = get_webpage(url);
//Console.WriteLine(xmlitem);
if (String.IsNullOrEmpty(xmlitem))
return "";
XmlDocument cx = new XmlDocument();
cx.LoadXml(xmlitem);
return get_wd_name_from_xml(cx);
public static int get_wd_item_direct(int gnid)
//http://wdq.wmflabs.org/api?q=string[1566:"2715459"]&format=xml
string url0 = "http://wdq.wmflabs.org/api?q=string[1566:\"" + gnid.ToString() + "\"]";
string hit = get_webpage(url0);
string s = "";
if (hit.IndexOf("items\":[") > 0)
s = hit.Substring(hit.IndexOf("items\":[") + 8);
if (s.IndexOf("]") > 0)
s = s.Substring(0, s.IndexOf("]"));
//Console.WriteLine("get_wd_item; s = " + s);
string[] items0 = s.Split(',');
//Console.WriteLine("Direct gnid query");
foreach (string item in items0)
if (tryconvert(item) > 0)
nwdhist.Add("direct gnid");
if (!wdgniddict.ContainsKey(tryconvert(item)))
wdgniddict.Add(tryconvert(item), gnid);
return tryconvert(item);
return -1;
public static int get_wd_item(int gnid)
int wdid = get_wd_item_direct(gnid);
if (wdid > 0)
return wdid;
string url1 = "http://wdq.wmflabs.org/api?q=around[625," + gndict[gnid].latitude.ToString(culture_en) + "," + gndict[gnid].longitude.ToString(culture_en) + ",2]";
string around = get_webpage(url1);
string s = "";
if (around.IndexOf("items\":[") >= 0)
s = around.Substring(around.IndexOf("items\":[") + 8);
if (s.IndexOf("]") > 0)
s = s.Substring(0, s.IndexOf("]"));
string[] items = s.Split(',');
//List
//Console.WriteLine("Search by location and gnid");
//foreach (string item in items)
//{
// Console.WriteLine("item = " + item);
// string url2 = "https://www.wikidata.org/w/api.php?action=wbgetclaims&entity=Q" + item + "&format=xml&property=p1566";
// string xmlitem = get_webpage(url2);
// if (String.IsNullOrEmpty(xmlitem))
// continue;
// XmlDocument cx = new XmlDocument();
// cx.LoadXml(xmlitem);
// XmlNodeList elemlist = cx.GetElementsByTagName("datavalue");
// foreach (XmlNode ee in elemlist)
// {
// try
// {
// string value = ee.Attributes.GetNamedItem("value").Value;
// Console.WriteLine("value = " + value);
// if (tryconvert(value) == gnid)
// {
// nwdhist.Add("loc&gnid");
// if (!wdgniddict.ContainsKey(wdid))
// wdgniddict.Add(tryconvert(item), gnid);
// return tryconvert(item);
// }
// else if (tryconvert(value) > 0)
// withgnid.Add(item);
// }
// catch (NullReferenceException e)
// {
// }
// }
//}
Console.WriteLine("Search by name at location");
foreach (string item in items)
//if (withgnid.Contains(item))
// continue;
XmlDocument cx = get_wd_xml(tryconvert(item));
if (cx == null)
continue;
XmlNodeList elemlist = cx.GetElementsByTagName("label");
foreach (XmlNode ee in elemlist)
try
string value = ee.Attributes.GetNamedItem("value").Value;
//Console.WriteLine("value = " + value);
if (value == gndict[gnid].Name)
nwdhist.Add("name at loc");
if (!wdgniddict.ContainsKey(tryconvert(item)))
wdgniddict.Add(tryconvert(item), gnid);
return tryconvert(item);
catch (NullReferenceException e)
Console.Error.WriteLine(e.Message);
Console.WriteLine("Search by article name in iwlangs");
string sites = "";
foreach (string iws in iwlang)
if ( !String.IsNullOrEmpty(sites))
sites += "|";
if (iws != makelang)
sites += iws + "wiki";
else if (!String.IsNullOrEmpty(countrydict[countryid[makecountry]].nativewiki))
sites += countrydict[countryid[makecountry]].nativewiki + "wiki";
List
titlist.Add(gndict[gnid].Name);
if (!titlist.Contains(gndict[gnid].Name_ml))
titlist.Add(gndict[gnid].Name_ml);
foreach (string an in gndict[gnid].altnames)
if (!titlist.Contains(an))
titlist.Add(an);
string titles = "";
foreach (string tit in titlist)
if (!String.IsNullOrEmpty(tit))
if (!String.IsNullOrEmpty(titles))
titles += "|";
titles += tit;
//https://www.wikidata.org/w/api.php?action=wbgetentities&format=xml&sites=enwiki&titles=Austurland&redirects=yes&props=labels
string url3 = "https://www.wikidata.org/w/api.php?action=wbgetentities&format=xml&sites="+sites+"&titles="+titles+"&redirects=yes&props=claims";
//Console.WriteLine(url3);
string xmlitem3 = get_webpage(url3);
if (!String.IsNullOrEmpty(xmlitem3))
XmlDocument cx = new XmlDocument();
cx.LoadXml(xmlitem3);
XmlNodeList elemlist = cx.GetElementsByTagName("entity");
foreach (XmlNode ee in elemlist)
try
int entid = tryconvert(ee.Attributes.GetNamedItem("id").Value.Replace("Q",""));
Console.WriteLine("entid = " + entid.ToString());
if (entid > 0)
XmlDocument ex = new XmlDocument();
ex.AppendChild(ex.ImportNode(ee, true));
double[] latlong = get_wd_position(ex);
if (latlong[0] + latlong[1] > 360.0)
continue;
double dist = get_distance_latlong(latlong[0], latlong[1], gndict[gnid].latitude, gndict[gnid].longitude);
Console.WriteLine("dist = " + dist.ToString());
Console.WriteLine("gnid-latlong = " + gndict[gnid].latitude.ToString() + " | " + gndict[gnid].longitude.ToString());
//Console.WriteLine("
//Console.ReadLine();
if (dist < 100.0)
nwdhist.Add("iw");
if (!wdgniddict.ContainsKey(entid))
wdgniddict.Add(entid, gnid);
return entid;
catch (NullReferenceException e)
Console.Error.WriteLine(e.Message);
Console.WriteLine("Nothing found");
return -1;
public static string get_name_from_wdid(int wdid)
int nbgnid = -1;
if (wdgniddict.ContainsKey(wdid))
nbgnid = wdgniddict[wdid];
else
nbgnid = get_wd_gnid(wdid);
if (gndict.ContainsKey(nbgnid))
return makegnidlink(nbgnid);
else
return get_wd_name(wdid);
public static void verify_wd()
read_rdf_tree();
Dictionary
List
int maxreadrdf = 10000000;
int n = 0;
//int n1566 = 0;
int n625 = 0;
//public class wdminiclass //minimal wikidata entry needed for verifying Geonames-links
//{
// public int gnid = 0;
// public double latitude = 9999.9;
// public double longitude = 9999.9;
// public List
//public double dist = 9999.9;
//public bool okdist = false;
//public bool okclass = false;
//public bool goodmatch = false;
//}
Dictionary
//Console.WriteLine("First pass");
//using (StreamReader sr = new StreamReader("wikidata-simple-statements.nt"))
using (StreamReader sr = new StreamReader("wikidata-only1566.nt"))
while (!sr.EndOfStream)
String line = sr.ReadLine();
if ( line.Contains("P1566"))
Console.WriteLine(line);
rdfclass rc = rdf_parse(line);
n++;
if ((n % 10000) == 0)
Console.WriteLine("n = " + n.ToString());
if (n > maxreadrdf)
break;
if (rc.obj > 0)
if (!wdminidict.ContainsKey(rc.obj))
wdminiclass wdm = new wdminiclass();
wdminidict.Add(rc.obj, wdm);
if (rc.prop == propdict["gnid"])
wdminidict[rc.obj].gnid = tryconvert(rc.value);
Console.WriteLine("gnid = "+wdminidict[rc.obj].gnid.ToString());
else if (rc.prop == propdict["coordinates"])
if (!latlongobjects.ContainsKey(rc.value))
latlongobjects.Add(rc.value, rc.obj);
n625++;
//else
// Console.WriteLine("Repeated latlong " + rc.value);
else if (rc.prop == propdict["instance"])
if (!wdminidict[rc.obj].instance_of.Contains(rc.objlink))
wdminidict[rc.obj].instance_of.Add(rc.objlink);
else
if (latlongobjects.ContainsKey(rc.objstring))
if (!wdminidict.ContainsKey(latlongobjects[rc.objstring]))
wdminiclass wdm = new wdminiclass();
wdminidict.Add(latlongobjects[rc.objstring], wdm);
if (rc.prop == 6250001)
wdminidict[latlongobjects[rc.objstring]].latitude = tryconvertdouble(rc.value);
else if (rc.prop == 6250002)
wdminidict[latlongobjects[rc.objstring]].longitude = tryconvertdouble(rc.value);
Console.WriteLine("wdminidict: " + wdminidict.Count.ToString());
Dictionary
Dictionary
int nmountains = 0;
int nranges = 0;
int nrangesgood = 0;
foreach (int wdid in wdminidict.Keys)
Console.WriteLine(wdid.ToString() + "; " + wdminidict[wdid].gnid.ToString() + "; " + wdminidict[wdid].latitude.ToString() + "; " + wdminidict[wdid].longitude.ToString());
int gnid = wdminidict[wdid].gnid;
if (gndict.ContainsKey(gnid))
if (!wdgniddict.ContainsKey(wdid))
wdgniddict.Add(wdid, gnid);
else if (wdgniddict[wdid] != gnid)
{// negative numbers count how many duplicates
if (wdgniddict[wdid] > 0)
wdgniddict[wdid] = -2;
else
wdgniddict[wdid]--;
if (!gnidwddict.ContainsKey(gnid))
gnidwddict.Add(gnid, wdid);
else if (gnidwddict[gnid] != wdid)
if (!wddoubles.ContainsKey(gnid))
List
wddoubles.Add(gnid, dlist);
if (gnidwddict[gnid] > 0)
wddoubles[gnid].Add(gnidwddict[gnid]);
wddoubles[gnid].Add(wdid);
Console.WriteLine("Double!");
if (gnidwddict[gnid] > 0)
gnidwddict[gnid] = -2;
else
gnidwddict[gnid]--;
wdminidict[wdid].dist = get_distance_latlong(gndict[gnid].latitude, gndict[gnid].longitude, wdminidict[wdid].latitude, wdminidict[wdid].longitude);
Console.WriteLine("dist = " + wdminidict[wdid].dist.ToString("F2"));
string fcode = gndict[gnid].featurecode;
double maxdist = 10.0; //maximum acceptable distance for a match
if (!featurepointdict[fcode]) //... hundred times larger for non-point features
maxdist = 300 * maxdist;
wdminidict[wdid].okdist = (wdminidict[wdid].dist < maxdist);
Console.WriteLine("dist = " + wdminidict[wdid].dist.ToString("F2") + ", " + wdminidict[wdid].okdist.ToString());
int target = 0;
bool foundtarget = false;
string category = "default";
if (categorydict.ContainsKey(fcode))
category = categorydict[fcode];
Console.WriteLine("category = " + category + ", instances: " + wdminidict[wdid].instance_of.Count.ToString());
if (category == "subdivisions")
target = catwdclass["subdivision1"];
foreach (int inst in wdminidict[wdid].instance_of)
if (search_rdf_tree(target, inst, 0))
foundtarget = true;
break;
if (!foundtarget)
target = catwdclass["subdivision2"];
foreach (int inst in wdminidict[wdid].instance_of)
if (search_rdf_tree(target, inst, 0))
foundtarget = true;
break;
if (!foundtarget)
target = catwdclass["subdivision3"];
foreach (int inst in wdminidict[wdid].instance_of)
if (search_rdf_tree(target, inst, 0))
foundtarget = true;
break;
else if (category == "mountains")
Console.WriteLine("mountains " + fcode);
nmountains++;
if (fcode == "MTS")
nranges++;
target = catwdclass["mountains1"];
foreach (int inst in wdminidict[wdid].instance_of)
if (search_rdf_tree(target, inst, 0))
foundtarget = true;
break;
if (!foundtarget)
target = catwdclass["mountains2"];
foreach (int inst in wdminidict[wdid].instance_of)
if (search_rdf_tree(target, inst, 0))
foundtarget = true;
break;
if (foundtarget)
nrangesgood++;
else
if (!catwdclass.ContainsKey(category))
category = "default";
target = catwdclass[category];
foreach (int inst in wdminidict[wdid].instance_of)
if (search_rdf_tree(target, inst, 0))
foundtarget = true;
break;
wdminidict[wdid].okclass = foundtarget;
else
Console.WriteLine("gnid not found");
int ngood = 0;
foreach (int wdid in wdminidict.Keys)
wdminidict[wdid].goodmatch = (wdminidict[wdid].okclass && wdminidict[wdid].okdist);
foreach (int gnid in wddoubles.Keys)
int nokclass = 0;
int idok = -1;
double bestdist = 9999.9;
int idbestdist = -1;
foreach (int wdid in wddoubles[gnid])
if (wdminidict[wdid].okclass)
nokclass++;
idok = wdid;
if (wdminidict[wdid].okdist && (wdminidict[wdid].dist < bestdist))
idbestdist = wdid;
bestdist = wdminidict[wdid].dist;
if (nokclass > 1)
idok = idbestdist;
foreach (int wdid in wddoubles[gnid])
wdminidict[wdid].goodmatch = (wdid == idok);
Console.WriteLine("wdminidict: " + wdminidict.Count.ToString());
using (StreamWriter sw = new StreamWriter("wikidata-good.nt"))
foreach (int wdid in wdminidict.Keys)
if (wdminidict[wdid].goodmatch)
sw.WriteLine(wdminidict[wdid].gnid.ToString() + tabstring + wdid.ToString());
ngood++;
Console.WriteLine("ngood = " + ngood.ToString());
Page pbad = new Page(makesite, "Användare:Lsjbot/Bad P1566 in Wikidata");
pbad.text = "This is a list of wikidata items with dubious links to GeoNames (P1566)\n\n";
pbad.text += "== Wrong type of object ==\n";
pbad.text += "Feature code on GeoNames does not match InstanceOf (P31) on Wikidata\n\n";
int nwrongtype = 0;
foreach (int wdid in wdminidict.Keys)
if ((!wdminidict[wdid].okclass) && (wdminidict[wdid].okdist))
pbad.text += "* [[:d:Q" + wdid.ToString() + "]]\n";
nwrongtype++;
Console.WriteLine("nwrongtype = " + nwrongtype.ToString());
pbad.text += "== Position mismatch ==\n";
pbad.text += "Latitude/longitude on GeoNames does not match latitude/longitude (P625) on Wikidata\n\n";
int nwrongpos = 0;
foreach (int wdid in wdminidict.Keys)
if ((!wdminidict[wdid].okdist) && (wdminidict[wdid].okclass))
pbad.text += "* [[:d:Q" + wdid.ToString() + "]]\n";
nwrongpos++;
Console.WriteLine("nwrongpos = " + nwrongpos.ToString());
pbad.text += "== Both position and type mismatch ==\n";
pbad.text += "Latitude/longitude on GeoNames does not match latitude/longitude (P625) on Wikidata ''and'' ";
pbad.text += "feature code on GeoNames does not match InstanceOf (P31) on Wikidata\n\n";
int nwrongboth = 0;
foreach (int wdid in wdminidict.Keys)
if ((!wdminidict[wdid].okdist) && (!wdminidict[wdid].okclass))
pbad.text += "* [[:d:Q" + wdid.ToString() + "]]\n";
nwrongboth++;
Console.WriteLine("nwrongboth = " + nwrongboth.ToString());
pbad.text += "== Duplicate entries ==\n";
pbad.text += "Several Wikidata objects have P1566 pointing to same GeoNames entry\n\n";
int ndup = 0;
foreach (int gnid in wddoubles.Keys)
pbad.text += "* GeoNames ID " + gnid.ToString() + "\n";
foreach (int wdid in wddoubles[gnid])
pbad.text += "** [[:d:Q" + wdid.ToString() + "]]\n";
ndup++;
Console.WriteLine("ndup = " + ndup.ToString());
Console.WriteLine("nmountains = " + nmountains.ToString());
Console.WriteLine("nranges = " + nranges.ToString());
Console.WriteLine("nrangesgood = " + nrangesgood.ToString());
//trysave(pbad,3);
using (StreamWriter sw = new StreamWriter("wikidata-bad.txt"))
sw.WriteLine(pbad.text);
public static void verify_wd_online()
Dictionary
foreach (int gnid in gndict.Keys)
if (gndict[gnid].wdid < 0)
continue;
XmlDocument cx = get_wd_xml(gndict[gnid].wdid);
int gnidwd = tryconvert(get_wd_prop(propdict["gnid"], cx));
if ((gnidwd > 0) && (gnidwd != gnid))
Console.WriteLine("Different gnid in wikidata");
continue;
double[] latlong = get_wd_position(cx);
double dist = get_distance_latlong(gndict[gnid].latitude, gndict[gnid].longitude, latlong[0], latlong[1]);
Console.WriteLine("distance = " + dist.ToString());
string wdname = get_wd_name_from_xml(cx);
Console.WriteLine(gndict[gnid].Name+" / "+ wdname);
List
foreach (int inst in instances)
XmlDocument cxi = get_wd_xml(inst);
string instancename = get_wd_name_from_xml(cxi, "en");
if (!wdclass.ContainsKey(gndict[gnid].featurecode))
Dictionary
wdclass.Add(gndict[gnid].featurecode, dd);
if (!wdclass[gndict[gnid].featurecode].ContainsKey(instancename))
wdclass[gndict[gnid].featurecode].Add(instancename, 0);
wdclass[gndict[gnid].featurecode][instancename]++;
List
int k = 0;
do
subclassof.Clear();
subclassof = get_wd_prop_idlist(propdict["subclass"], cxi);
foreach (int sc in subclassof)
cxi = get_wd_xml(sc);
string scname = get_wd_name_from_xml(cxi, "en");
Console.WriteLine("scname = " + scname);
if (!wdclass.ContainsKey(gndict[gnid].featurecode))
Dictionary
wdclass.Add(gndict[gnid].featurecode, dd);
if (!wdclass[gndict[gnid].featurecode].ContainsKey(scname))
wdclass[gndict[gnid].featurecode].Add(scname, 0);
wdclass[gndict[gnid].featurecode][scname]++;
k++;
while ((k<7) && (subclassof.Count > 0));
using (StreamWriter sw = new StreamWriter("gnvswiki-instance.txt"))
foreach (string fc in wdclass.Keys)
sw.WriteLine(fc);
foreach (string sc in wdclass[fc].Keys)
sw.WriteLine(" " + sc + " " + wdclass[fc][sc].ToString());
//propdict.Add("instance", 31);
//propdict.Add("subclass", 279);
public static bool climb_wd_class_tree(int wdid, string targetclass, int depth)
if (depth > 7)
return false;
//bool found = false;
XmlDocument cxi = get_wd_xml(wdid);
string scname = get_wd_name_from_xml(cxi, "en");
if (scname == targetclass)
return true;
else
List
foreach (int sc in subclassof)
if (climb_wd_class_tree(sc, targetclass, depth + 1))
return true;
return false;
public static string get_terrain_type2(List
string terrain_type = "unknown";
//int n = 0;
//int nelev = 0;
//double elevationsum = 0.0;
//double elevationvar = 0.0;
//double elevationsquare = 0.0;
//double elevationmean = 0.0;
//double[] elevdirsum = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
//double[] elevdirmean = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
//int[] nelevdir = { 0, 0, 0, 0, 0, 0, 0, 0 };
//foreach (int nb in farlist)
//{
// if (!gndict.ContainsKey(nb))
// continue;
// n++;
// if (gndict[nb].elevation > 0)
// {
// nelev++;
// elevationsum += gndict[nb].elevation;
// elevationsquare += gndict[nb].elevation * gndict[nb].elevation;
// int dir = get_direction(gnid, nb);
// if (dir > 0)
// {
// nelevdir[dir - 1]++;
// elevdirsum[dir - 1] += gndict[nb].elevation;
// }
// }
//}
//if (nelev > 10)
//{
// elevationmean = elevationsum / nelev;
// elevationvar = elevationsquare / nelev - elevationmean * elevationmean;
// Console.WriteLine("elevation mean, var = " + elevationmean.ToString() + ", " + elevationvar.ToString());
// if (statisticsonly)
// evarhist.Add(elevationvar);
// terrain_type = terrain_label(elevationvar,elevationmean);
// if (gndict[gnid].elevation > 0)
// {
// if (elevationmean - gndict[gnid].elevation > 500)
// terrain_type += " valley";
// else if (elevationmean - gndict[gnid].elevation < -500)
// terrain_type += " peak";
// }
// // 1
// // 7 5
// // 3 4
// // 8 6
// // 2
// int ndir = 0;
// if (nelev > 20)
// {
// for (int i = 0; i < 8; i++)
// {
// if (nelevdir[i] > 0)
// {
// elevdirmean[i] = elevdirsum[i] / nelevdir[i];
// ndir++;
// }
// else
// elevdirmean[i] = -1.0;
// }
// }
// if (statisticsonly)
// ndirhist.Add(ndir);
//}
//if (statisticsonly)
//{
// Console.WriteLine(gndict[gnid].Name + ": " + terrain_type);
// terrainhist.Add(terrain_type);
//}
return terrain_type;
public static int get_altitude(int gnid)
string dir = extractdir;
double lat = gndict[gnid].latitude;
double lon = gndict[gnid].longitude;
string filename = make_hgt_filename(lat, lon);
int[,] map = get_hgt_array(dir + filename);
int mapsize = map.GetLength(0);
double xfraction = lon - Math.Floor(lon);
int pixx = Convert.ToInt32(mapsize * xfraction); //x counted in positive longitude direction
double yfraction = lat - Math.Floor(lat);
int pixy = mapsize - Convert.ToInt32(mapsize * yfraction); //y counted in negative latitude direction
if (pixx >= mapsize)
pixx = mapsize - 1;
if (pixy >= mapsize)
pixy = mapsize - 1;
//Console.WriteLine(gnid.ToString() + ": " + pixx.ToString() + ", " + pixy.ToString());
int alt = map[pixx, pixy];
if (alt == 32768) //bad pixel
alt = 0;
return alt;
public static string classify_terrain(double elevationvar,double elevationmean)
string terrain_type = "";
if (elevationvar < 2500.0) //rms < 50
terrain_type = "flat";
if ( elevationvar < 100) //rms < 10
terrain_type = "very "+terrain_type;
if (elevationmean > 1500) //average higher than 1500
terrain_type += " high";
else if (elevationvar < 62500.0) //rms < 250
terrain_type = "hilly";
if ( elevationvar < 20000) //rms < 140
terrain_type = "somewhat "+terrain_type;
if (elevationmean > 1500) //average higher than 1500
terrain_type += " high";
else if (elevationvar < 122500.0) //rms < 350
terrain_type = "low-mountains";
else if (elevationvar < 250000.0) //rms < 500
terrain_type = "medium-mountains";
else
terrain_type = "high-mountains";
return terrain_type;
public static int next_dir(int dir)
// 1
// 7 5
// 3 4
// 8 6
// 2
switch (dir)
case 1:
return 5;
case 5:
return 4;
case 4:
return 6;
case 6:
return 2;
case 2:
return 8;
case 8:
return 3;
case 3:
return 7;
case 7:
return 1;
default:
return -1;
public static void put_mountains_on_map(ref int[,] map, double lat, double lon)
int mapsize = map.GetLength(0);
List
foreach (int nb in farlist)
if (is_height(gndict[nb].featurecode))
int xnb = get_x_pixel(gndict[nb].longitude, lon);
if ((xnb < 0) || (xnb >= mapsize))
continue;
int ynb = get_y_pixel(gndict[nb].latitude, lat);
if ((ynb < 0) || (ynb >= mapsize))
continue;
map[xnb, ynb] = nb;
public static int get_summit(int gnid, out double slat, out double slon) //seeks proper DEM summit of a mountain.
Console.WriteLine("get_summit");
double lat = gndict[gnid].latitude;
double lon = gndict[gnid].longitude;
int[,] map = get_3x3map(lat, lon);
int mapsize = map.GetLength(0);
//double scale = Math.Cos(lat * 3.1416 / 180);
//double pixkmx = scale * 40000 / (360 * 1200);
//double pixkmy = 40000.0 / (360.0 * 1200.0);
int x0 = get_x_pixel(lon, lon);
int y0 = get_y_pixel(lat, lat);
int[,] donemap = new int[mapsize, mapsize];
for (int i = 0; i < mapsize; i++)
for (int j = 0; j < mapsize; j++)
donemap[i, j] = 0;
put_mountains_on_map(ref donemap, lat, lon);
donemap[x0, y0] = -1; //negative for done, positive for mountain gnid
int tolerance = -1; //maximum dip before going up
int xhout = -1;
int yhout = -1;
//Console.WriteLine("x0,yo = " + x0.ToString() + " " + y0.ToString());
int mtgnid = seek_highest(ref map, ref donemap, x0, y0, tolerance,out xhout,out yhout);
//Console.WriteLine("xh,yh = " + xhout.ToString() + " " + yhout.ToString());
double one1200 = 1.0 / 1200.0;
double dlon = (xhout - x0) * one1200;
double dlat = -(yhout - y0) * one1200; //reverse sign because higher pixel number is lower latitude
slat = gndict[gnid].latitude + dlat;
slon = gndict[gnid].longitude + dlon;
if (mtgnid > 0) //Another mountain on summit
return -1;
else if (xhout < 0)
return -1;
else
return map[xhout, yhout];
public static int seek_highest(ref int[,] map, ref int[,] donemap, int x0, int y0, int tolerance, out int xhout, out int yhout)
//Find nearest mountain from x0,y0.
//Assumes donemap contains gnid of mountains in appropriate cells.
//Donemap = 0: untouched empty cell
//Donemap = -1: cell touched here
//Donemap = -2: cell to skip
//Tolerance = permitted dip before terrain turns upwards (negative!)
Console.WriteLine("seek_highest");
int mapsize = map.GetLength(0);
int maxx = x0;
int maxy = y0;
int minx = x0;
int miny = y0;
int xhigh = x0;
int yhigh = y0;
int xhighest = -1;
int yhighest = -1;
xhout = 0;
yhout = 0;
int x = x0;
int y = y0;
int newhigh = map[x0, y0];
int highesthigh = newhigh;
int nsame = 0;
int nround = 0;
int maxround = 1000;
int maxsame = 1000;
int[] xh = new int[maxsame];
int[] yh = new int[maxsame];
while (((newhigh - map[x0, y0]) >= tolerance) && (newhigh - highesthigh >= 5 * tolerance))
nround++;
//Console.WriteLine("nround = " + nround.ToString());
if (nround > maxround)
break;
newhigh = tolerance - 1;
for (int i = minx; i <= maxx; i++)
for (int j = miny; j <= maxy; j++)
if (donemap[i, j] == -1)
//Console.WriteLine("i,j=" + i.ToString() +","+ j.ToString());
for (int u = -1; u <= 1; u++)
if ((i + u > 0) && (i + u < mapsize))
for (int v = -1; v <= 1; v++)
if ((j + v > 0) && (j + v < mapsize))
if (donemap[i + u, j + v] >= 0)
if (map[i + u, j + v] > newhigh)
newhigh = map[i + u, j + v];
xhigh = i + u;
yhigh = j + v;
nsame = 0;
else if (map[i + u, j + v] == newhigh)
if (nsame < maxsame)
xh[nsame] = i + u;
yh[nsame] = j + v;
nsame++;
//xyh.Add(Tuple.Create(i + u,j+v));
//Console.WriteLine("newhigh = " + newhigh.ToString());
if (newhigh > highesthigh)
highesthigh = newhigh;
xhighest = xhigh;
yhighest = yhigh;
Console.WriteLine("seek_highest: highesthigh " + highesthigh.ToString() + " xh,yh = " + xhighest.ToString() + ", " + yhighest.ToString());
if ((newhigh - map[x0, y0]) > tolerance)
if (donemap[xhigh, yhigh] > 0)
break;
donemap[xhigh, yhigh] = -1;
if (nsame > 0)
//Console.WriteLine("seek_highest: nsame = " + nsame.ToString());
//foreach (Tuple xy in xyh)
// donemap[xy.Item1,xy.Item2] = nround;
for (int isame = 0; isame < nsame; isame++)
donemap[xh[isame], yh[isame]] = -1;
if (xhigh > maxx)
maxx = xhigh;
Console.WriteLine("maxx = " + maxx.ToString());
if (maxx >= mapsize)
newhigh = -9999;
if (maxx >= x0 + 500)
newhigh = -9999;
if (xhigh < minx)
minx = xhigh;
Console.WriteLine("minx = " + minx.ToString());
if (minx <= 0)
newhigh = -9999;
if (minx <= x0 - 500)
newhigh = -9999;
if (yhigh > maxy)
maxy = yhigh;
Console.WriteLine("maxy = " + maxy.ToString());
if (maxy >= mapsize)
newhigh = -9999;
if (maxy >= y0 + 500)
newhigh = -9999;
if (yhigh < miny)
miny = yhigh;
Console.WriteLine("miny = " + miny.ToString());
if (miny <= 0)
newhigh = -9999;
if (miny <= y0 - 500)
newhigh = -9999;
if (newhigh <= 0)
break;
//Console.WriteLine("xhigh,yhigh = " + xhigh.ToString() + ", " + yhigh.ToString());
xhout = xhighest;
yhout = yhighest;
return donemap[xhigh, yhigh];
public static int seek_mountain(ref int[,] map, ref int[,] donemap, int x0, int y0, int tolerance)
//Find nearest mountain from x0,y0.
//Assumes donemap contains gnid of mountains in appropriate cells.
//Donemap = 0: untouched empty cell
//Donemap = -1: cell touched here
//Donemap = -2: cell to skip
//Tolerance = permitted dip before terrain turns upwards (negative!)
Console.WriteLine("seek_mountain");
int mapsize = map.GetLength(0);
int maxx = x0;
int maxy = y0;
int minx = x0;
int miny = y0;
int xhigh = 0;
int yhigh = 0;
int x = x0;
int y = y0;
int newhigh = map[x0, y0];
int highesthigh = newhigh;
int nsame = 0;
int nround = 0;
int maxround = 10000;
int maxsame = 1000;
int[] xh = new int[maxsame];
int[] yh = new int[maxsame];
while (donemap[x, y] <= 0 && ((newhigh - map[x0, y0]) > tolerance) && (newhigh - highesthigh > 5*tolerance))
nround++;
if (nround > maxround)
break;
newhigh = tolerance - 1;
for (int i = minx; i <= maxx; i++)
for (int j = miny; j <= maxy; j++)
if (donemap[i, j] == -1)
for (int u = -1; u <= 1; u++)
if ((i + u > 0) && (i + u < mapsize))
for (int v = -1; v <= 1; v++)
if ((j + v > 0) && (j + v < mapsize))
if (donemap[i + u, j + v] >= 0)
if (map[i + u, j + v] > newhigh)
newhigh = map[i + u, j + v];
xhigh = i + u;
yhigh = j + v;
nsame = 0;
else if (map[i + u, j + v] == newhigh)
if (nsame < maxsame)
xh[nsame] = i + u;
yh[nsame] = j + v;
nsame++;
//xyh.Add(Tuple.Create(i + u,j+v));
if (newhigh > highesthigh)
highesthigh = newhigh;
if ((newhigh - map[x0, y0]) > tolerance)
if (donemap[xhigh, yhigh] > 0)
break;
donemap[xhigh, yhigh] = -1;
if (nsame > 0)
Console.WriteLine("seek_mountain: nsame = " + nsame.ToString());
//foreach (Tuple xy in xyh)
// donemap[xy.Item1,xy.Item2] = nround;
for (int isame = 0; isame < nsame; isame++)
donemap[xh[isame], yh[isame]] = -1;
if (xhigh > maxx)
maxx = xhigh;
Console.WriteLine("maxx = " + maxx.ToString());
if (maxx >= mapsize)
newhigh = -9999;
if (maxx >= x0+500)
newhigh = -9999;
if (xhigh < minx)
minx = xhigh;
Console.WriteLine("minx = " + minx.ToString());
if (minx <= 0)
newhigh = -9999;
if (minx <= x0-500)
newhigh = -9999;
if (yhigh > maxy)
maxy = yhigh;
Console.WriteLine("maxy = " + maxy.ToString());
if (maxy >= mapsize)
newhigh = -9999;
if (maxy >= y0+500)
newhigh = -9999;
if (yhigh < miny)
miny = yhigh;
Console.WriteLine("miny = " + miny.ToString());
if (miny <= 0)
newhigh = -9999;
if (miny <= y0-500)
newhigh = -9999;
if (newhigh <= 0)
break;
//Console.WriteLine("xhigh,yhigh = " + xhigh.ToString() + ", " + yhigh.ToString());
return donemap[xhigh, yhigh];
public static bool between_mountains(int gnid, out int mgnid1, out int mgnid2) //calculates whether gnid is part of a mountain. Intended for use with spurs etc.
Console.WriteLine("Between_mountains");
double lat = gndict[gnid].latitude;
double lon = gndict[gnid].longitude;
int[,] map = get_3x3map(lat, lon);
int mapsize = map.GetLength(0);
//double scale = Math.Cos(lat * 3.1416 / 180);
//double pixkmx = scale * 40000 / (360 * 1200);
//double pixkmy = 40000.0 / (360.0 * 1200.0);
mgnid1 = -1;
mgnid2 = -1;
int x0 = get_x_pixel(lon, lon);
int y0 = get_y_pixel(lat, lat);
int[,] donemap = new int[mapsize, mapsize];
for (int i = 0; i < mapsize; i++)
for (int j = 0; j < mapsize; j++)
donemap[i, j] = 0;
put_mountains_on_map(ref donemap, lat, lon);
if (donemap[x0, y0] > 0)
return false;
donemap[x0, y0] = -1; //negative for done, positive for mountain gnid
int tolerance = -10; //maximum dip before going up
mgnid1 = seek_mountain(ref map, ref donemap, x0, y0, tolerance);
if (!gndict.ContainsKey(mgnid1))
return false;
double dlat = gndict[mgnid1].latitude - lat;
double dlon = gndict[mgnid1].longitude - lon;
if (Math.Abs(dlat) > Math.Abs(dlon))
if (dlat > 0) //North (smaller y!)
for (int i = 0; i < y0; i++)
for (int j = 0; j < mapsize; j++)
donemap[j,i] = -2;
else //South (larger y!)
for (int i = y0+1; i < mapsize; i++)
for (int j = 0; j < mapsize; j++)
donemap[j,i] = -2;
else
if ( dlon > 0 ) //East
for (int i = x0+1; i < mapsize; i++)
for (int j = 0; j < mapsize; j++)
donemap[i, j] = -2;
else //West
for (int i = 0; i < x0; i++)
for (int j = 0; j < mapsize; j++)
donemap[i, j] = -2;
mgnid2 = seek_mountain(ref map, ref donemap, x0, y0, tolerance);
if (!gndict.ContainsKey(mgnid2))
return false;
return true;
public static int attach_to_mountain(int gnid) //calculates whether gnid is part of a mountain. Intended for use with spurs etc.
Console.WriteLine("attach_to_mountain");
double lat = gndict[gnid].latitude;
double lon = gndict[gnid].longitude;
int[,] map = get_3x3map(lat, lon);
int mapsize = map.GetLength(0);
//double scale = Math.Cos(lat * 3.1416 / 180);
//double pixkmx = scale * 40000 / (360 * 1200);
//double pixkmy = 40000.0 / (360.0 * 1200.0);
int x0 = get_x_pixel(lon, lon);
int y0 = get_y_pixel(lat, lat);
int[,] donemap = new int[mapsize, mapsize];
for (int i = 0; i < mapsize; i++)
for (int j = 0; j < mapsize; j++)
donemap[i, j] = 0;
put_mountains_on_map(ref donemap, lat, lon);
if (donemap[x0, y0] > 0)
return donemap[x0, y0];
donemap[x0, y0] = -1; //negative for done, positive for mountain gnid
int tolerance = -10; //maximum dip before going up
return seek_mountain(ref map,ref donemap, x0, y0, tolerance);
public static int get_prominence(int gnid, out double width) //calculates the topographic prominence of a mountain
Console.WriteLine("get_prominence");
double lat = gndict[gnid].latitude;
double lon = gndict[gnid].longitude;
//Console.WriteLine("lat, lon = " + lat.ToString() + " " + lon.ToString());
int[,] map = get_3x3map(lat, lon);
int mapsize = map.GetLength(0);
double scale = Math.Cos(lat * 3.1416 / 180);
double pixkmx = scale * 40000 / (360 * 1200);
double pixkmy = 40000.0 / (360.0 * 1200.0);
width = 0;
int x0 = get_x_pixel(lon, lon);
int y0 = get_y_pixel(lat, lat);
int[,] donemap = new int[mapsize, mapsize];
bool higherfound = false;
for (int i = 0; i < mapsize; i++)
for (int j = 0; j < mapsize; j++)
donemap[i, j] = 0;
if (map[i, j] > gndict[gnid].elevation)
higherfound = true;
if (!higherfound) //if highest point in map, algorithm won't work
return -1;
donemap[x0, y0] = 1;
int maxx = x0;
int maxy = y0;
int minx = x0;
int miny = y0;
int lowesthigh = 9999;
int newhigh = -1;
int badhigh = 9999;
int xhigh = 0;
int yhigh = 0;
int nround = 1;
int nroundlow = -1;
int nsame = 0;
int ntotal = 0;
int maxtotal = 100000;
//Dictionary
//List
int maxsame = 1000;
int[] xh = new int[maxsame];
int[] yh = new int[maxsame];
while ((newhigh < gndict[gnid].elevation) || (nround < 6)) //disregards the first 5 pixels, in case of slight position mismatch
newhigh = -1;
for (int i = minx; i <= maxx; i++)
for (int j = miny; j <= maxy; j++)
if (donemap[i, j] > 0)
for (int u = -1; u <= 1; u++)
if ((i + u > 0) && (i + u < mapsize))
for (int v = -1; v <= 1; v++)
if ((j + v > 0) && (j + v < mapsize))
if (donemap[i + u, j + v] == 0)
if (map[i + u, j + v] > newhigh)
newhigh = map[i + u, j + v];
xhigh = i + u;
yhigh = j + v;
nsame = 0;
else if (map[i + u, j + v] == newhigh)
if (nsame < maxsame)
xh[nsame] = i + u;
yh[nsame] = j + v;
nsame++;
//xyh.Add(Tuple.Create(i + u,j+v));
nround++;
Console.WriteLine("get_prominence: nround,ntotal,newhigh = " + nround.ToString()+", "+ntotal+", "+newhigh);
ntotal += nsame + 1;
if (ntotal > maxtotal)
newhigh = badhigh;
donemap[xhigh, yhigh] = nround;
if (nsame > 0)
//Console.WriteLine("get_prominence: nsame = " + nsame.ToString());
//foreach (Tuple xy in xyh)
// donemap[xy.Item1,xy.Item2] = nround;
for (int isame = 0; isame < nsame; isame++)
donemap[xh[isame], yh[isame]] = nround;
if (newhigh < lowesthigh)
lowesthigh = newhigh;
nroundlow = nround;
if (xhigh > maxx)
maxx = xhigh;
if ( maxx >= mapsize )
newhigh = badhigh;
if (xhigh < minx)
minx = xhigh;
if ( minx <= 0 )
newhigh = badhigh;
if (yhigh > maxy)
maxy = yhigh;
if ( maxy >= mapsize )
newhigh = badhigh;
if (yhigh < miny)
miny = yhigh;
if ( miny <= 0 )
newhigh = badhigh;
if ( newhigh <= 0 )
newhigh = badhigh;
double r2max = 0;
int xr2max = 0;
int yr2max = 0;
int npix = 0;
for (int i = minx; i <= maxx; i++)
for (int j = miny; j <= maxy; j++)
if (( donemap[i,j] > 0 ) && (donemap[i,j] < nroundlow))
npix++;
double r2 = scale*scale*(i-x0)*(i-x0)+(j-y0)*(j-y0);
if ( r2 > r2max )
r2max = r2;
xr2max = i;
yr2max = j;
Console.WriteLine("get_promince: npix = " + npix.ToString());
if ( npix <= 1 )
return -1;
if (newhigh == badhigh)
return -1;
r2max = 0;
int xw = 0;
int yw = 0;
for (int i = minx; i <= maxx; i++)
for (int j = miny; j <= maxy; j++)
if (( donemap[i,j] > 0 ) && (donemap[i,j] < nroundlow))
double r2 = scale*scale*(i-xr2max)*(i-xr2max)+(j-yr2max)*(j-yr2max);
if ( r2 > r2max )
r2max = r2;
xw = i;
yw = j;
width = Math.Sqrt(r2max)*pixkmy;
Console.WriteLine("get_promince: nroundfinal = " + nround.ToString());
if (lowesthigh < gndict[gnid].elevation)
return gndict[gnid].elevation-lowesthigh;
else
return -1;
public static string get_terrain_type3(int gnid, double radius)
string terrain_type = get_terrain_type_latlong(ref gndict[gnid].elevation, gndict[gnid].latitude, gndict[gnid].longitude,radius);
if (statisticsonly)
Console.WriteLine(gndict[gnid].Name + ": " + terrain_type);
string[] tp = terrain_type.Split('|');
foreach (string ttp in tp)
terrainhist.Add(ttp);
return terrain_type;
public static string get_terrain_type_latlong(ref int elevation, double lat,double lon,double radius)
string terrain_type = "unknown";
Console.WriteLine("get_terrain_type3");
//int n = 0;
int nelev = 0;
int ndry = 0;
int nocean = 0;
int ncentral = 0;
double elevationsum = 0.0;
double elevationvar = 0.0;
double elevationsquare = 0.0;
double elevationmean = 0.0;
double centralsum = 0.0;
double centralvar = 0.0;
double centralsquare = 0.0;
double centralmean = 0.0;
double r2ocean = 9999.9;
int oceanmindir = -1;
int[,] map = get_3x3map(lat,lon);
int mapsize = map.GetLength(0);
int x0 = get_x_pixel(lon,lon);
int y0 = get_y_pixel(lat,lat);
Console.WriteLine(lat.ToString() + " " + lon.ToString() + " " + x0.ToString() + " " + y0.ToString());
if (elevation <= 0)
elevation = map[x0, y0];
else if (statisticsonly)
elevdiffhist.Add(1.0 * (elevation - map[x0, y0]));
double scale = Math.Cos(lat * 3.1416 / 180);
double pixkmx = scale * 40000 / (360 * 1200);
double pixkmy = 40000.0 / (360.0 * 1200.0);
double[] elevdirsum = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
double[] elevdirmean = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
double[] elevdirsquare = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
double[] elevdirvar = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
int[] nelevdir = { 0, 0, 0, 0, 0, 0, 0, 0 };
int[] noceandir = { 0, 0, 0, 0, 0, 0, 0, 0 };
int[] ndrydir = { 0, 0, 0, 0, 0, 0, 0, 0 };
double slope1sum = 0;
double slope5sum = 0;
double slope1mean = 0;
double slope5mean = 0;
int nslope = 0;
int r = Convert.ToInt32(radius/pixkmx);
double r2max = radius/pixkmy * radius/pixkmy;
double r2central = r2max/16; //central part is one quarter the radius
for (int x = x0-r; x < x0+r; x++)
if (( x > 0 ) && (x < mapsize-1))
for (int y = y0-r; y < y0+r; y++)
if ((y > 0) && (y < mapsize-1))
double r2 = scale * scale * (x - x0) * (x - x0) + (y - y0) * (y - y0);
if (r2 < r2max)
int weight = 1;
if (4 * r2 < r2max)
weight = 4;
else if (3 * r2 < r2max)
weight = 3;
else if (2 * r2 < r2max)
weight = 2;
int dir = get_pix_direction(x, y, x0, y0, scale);
if (map[x, y] != 0) //not ocean
if (map[x, y] != 32768) //bad pixel
nelev++;
ndry += weight;
elevationsum += map[x, y];
elevationsquare += map[x, y] * map[x, y];
if ( dir > 0 )
ndrydir[dir - 1] += weight;
if ( r2 < r2central )
centralsum += map[x, y];
centralsquare += map[x, y] * map[x, y];
ncentral++;
else if (dir > 0)
nelevdir[dir - 1]++;
elevdirsum[dir - 1] += map[x, y];
elevdirsquare[dir - 1] += map[x, y]*map[x, y];
slope1sum += Math.Abs(0.001*(map[x,y]-map[x,y-1]))/pixkmy; //0.001 because vertical meters and horizontal km
slope1sum += Math.Abs(0.001*(map[x,y]-map[x-1,y]))/pixkmx;
if ( y>5 )
slope5sum += Math.Abs(0.0002*(map[x,y]-map[x,y-5]))/pixkmy; //0.0002 = 0.001/5 bec
if ( x>5)
slope5sum += Math.Abs(0.0002*(map[x,y]-map[x-5,y]))/pixkmx;
nslope +=2;
else
nocean += weight;
if (dir > 0)
noceandir[dir - 1] += weight;
if (r2 < r2ocean)
r2ocean = r2;
oceanmindir = dir;
if (nelev > 10)
elevationmean = elevationsum / nelev;
elevationvar = elevationsquare / nelev - elevationmean * elevationmean;
slope1mean = slope1sum / nslope;
slope5mean = slope5sum / nslope;
if (statisticsonly)
double sloperms = 10000 * slope1mean / (Math.Sqrt(elevationvar)+20);
Console.WriteLine(sloperms.ToString());
slopermshist.Add(sloperms);
Console.WriteLine("elevation mean, var = " + elevationmean.ToString() + ", " + elevationvar.ToString());
Console.WriteLine("slope mean1,mean5 = " + slope1mean.ToString() + ", " + slope5mean.ToString());
if (statisticsonly)
evarhist.Add(elevationvar);
if (elevation > 0)
evarhist.Add(1.0 * (elevation - map[x0, y0]));
slope1hist.Add(100.0*slope1mean);
slope5hist.Add(100.0*slope5mean);
terrain_type = classify_terrain(elevationvar,elevationmean);
// 1
// 7 5
// 3 4
// 8 6
// 2
int ndir = 0;
string[] terrtype_sector = new string[9];
if (ncentral > 10)
centralmean = centralsum / ncentral;
centralvar = centralsquare / ncentral - centralmean * centralmean;
Console.WriteLine("Central elevation mean, var = " + centralmean.ToString() + ", " + centralvar.ToString());
terrtype_sector[8] = classify_terrain(centralvar, centralmean);
terrain_type += "|central " + terrtype_sector[8];
if (nelev > 20)
//Dictionary
for (int i = 0; i < 8; i++)
terrtype_sector[i] = "";
if (nelevdir[i] > 10)
elevdirmean[i] = elevdirsum[i] / nelevdir[i];
//elevationvar = elevationsquare / nelev - elevationmean * elevationmean;
elevdirvar[i] = elevdirsquare[i]/ nelevdir[i] - elevdirmean[i]*elevdirmean[i];
terrtype_sector[i] = classify_terrain(elevdirvar[i],elevdirmean[i]);
//if (!terrtype.ContainsKey(terrtype_sector[i]))
// terrtype.Add(terrtype_sector[i], 0);
//terrtype[terrtype_sector[i]]++;
terrain_type += "|dir"+(i+1).ToString()+" "+terrtype_sector[i];
ndir++;
else
elevdirmean[i] = -99999.0;
//if (!terrtype.ContainsKey(terrtype_sector[8]))
// terrtype.Add(terrtype_sector[8], 0);
//terrtype[terrtype_sector[8]]++;
//Console.WriteLine("Types in sectors: " + terrtype.Count.ToString());
//if (statisticsonly)
// nsameterrhist.Add(terrtype.Count.ToString());
//int[] getdircoord(int dir)
if (statisticsonly)
ndirhist.Add(ndir);
int nwet = 0;
int nbitwet = 0;
if (nocean > 10)
int iwet = -1;
for (int i = 0; i < 8; i++)
if (noceandir[i] > ndrydir[i])
nwet++;
iwet = i;
else if (2*noceandir[i] > ndrydir[i])
nbitwet++;
if (nwet > 0) //at least one sector has mostly ocean
terrain_type += "|ocean ";
if ((nwet == 1) && (nbitwet == 0))
terrain_type += "bay " + (iwet+1).ToString();
else
int xsum = 0;
int ysum = 0;
for (int i = 0; i < 8; i++)
if (noceandir[i] > ndrydir[i])
int[] cdir = getdircoord(i + 1);
xsum += cdir[0];
ysum += cdir[1];
terrain_type += "coast" + get_NSEW_from_xysum(xsum, ysum);
if (nwet == 0)
double triggerdiff = Math.Sqrt(elevationvar); //enough height difference to call it a terrain feature; more needed in rugged terrain
if (triggerdiff < 20)
triggerdiff = 20;
Console.WriteLine("triggerdiff = " + triggerdiff.ToString());
if (elevation > 0)
if (elevationmean - elevation > triggerdiff)
terrain_type += "|valley ";
else if (elevationmean - elevation < -triggerdiff)
terrain_type += "|peak ";
double xsum = 0; //measures east-west slope
double ysum = 0; //measure north-south slope
double x0sum = 0; //centerline NS altitude
double y0sum = 0; //centerline EW altitude
double x2sum = 0; //periphery NS altitude
double y2sum = 0; //periphery EW altitude
double xysum = 0;
for (int i = 0; i < 8; i++)
int[] cdir = getdircoord(i + 1);
xsum += cdir[0] * (elevdirmean[i]-elevationmean) / 6;
ysum += cdir[1] * (elevdirmean[i]-elevationmean) / 6;
x0sum += (1 - cdir[0] * cdir[0]) * (elevdirmean[i]-elevationmean) / 2;
y0sum += (1 - cdir[1] * cdir[1]) * (elevdirmean[i]-elevationmean) / 2;
x2sum += cdir[0] * cdir[0] * (elevdirmean[i]-elevationmean) / 6;
y2sum += cdir[1] * cdir[1] * (elevdirmean[i]-elevationmean) / 6;
xysum += cdir[0] * cdir[1] * (elevdirmean[i]-elevationmean) / 4;
//xsum -= elevationmean;
//ysum -= elevationmean;
//x0sum -= elevationmean;
//y0sum -= elevationmean;
//x2sum -= elevationmean;
//y2sum -= elevationmean;
//xysum -= elevationmean;
double nsridge = x0sum - x2sum; // centerline > periphery
double ewridge = y0sum - y2sum; // centerline > periphery
if (terrain_type.Contains("valley"))
Console.WriteLine("xsum = " + xsum.ToString());
Console.WriteLine("ysum = " + ysum.ToString());
Console.WriteLine("x0sum = " + x0sum.ToString());
Console.WriteLine("y0sum = " + y0sum.ToString());
Console.WriteLine("x2sum = " + x2sum.ToString());
Console.WriteLine("y2sum = " + y2sum.ToString());
Console.WriteLine("xysum = " + xysum.ToString());
if ((nsridge < -triggerdiff) && (ewridge > -triggerdiff / 2))
terrain_type += "NS.."; //North-south valley
else if ((ewridge < -triggerdiff) && (nsridge > -triggerdiff / 2))
terrain_type += "EW..";
else if (xysum > triggerdiff)
terrain_type += "SWNE";
else if (xysum < -triggerdiff)
terrain_type += "SENW";
//Console.WriteLine(terrain_type);
//Console.ReadLine();
else if (terrain_type.Contains("peak"))
if ((nsridge > triggerdiff) && (ewridge < triggerdiff / 2))
terrain_type += "NS.."; //North-south ridge
else if ((ewridge > triggerdiff) && (nsridge < triggerdiff / 2))
terrain_type += "EW..";
else if (xysum > triggerdiff)
terrain_type += "SENW";
else if (xysum < -triggerdiff)
terrain_type += "SWNE";
else if ( Math.Abs(elevationmean - elevation) < triggerdiff/2 )
if (Math.Abs(xsum) > 3*Math.Abs(ysum)+triggerdiff/5)
if (xsum > 0)
terrain_type += "|slope E"; //upwards to the East
else
terrain_type += "|slope W";
if (Math.Abs(xsum) > triggerdiff)
terrain_type += " steep";
else if (Math.Abs(ysum) > 3 * Math.Abs(xsum) + triggerdiff / 5)
if (ysum > 0)
terrain_type += "|slope N";
else
terrain_type += "|slope S";
if (Math.Abs(ysum) > triggerdiff+100)
terrain_type += " steep";
return terrain_type;
public static string get_terrain_type(int gnid,double radius)
//List
//return get_terrain_type2(farlist,gnid);
return get_terrain_type3(gnid,radius);
public static string get_terrain_type_island(int gnid)
string terrain_type = "unknown";
Console.WriteLine("get_terrain_type_island");
//int n = 0;
int nelev = 0;
//int nocean = 0;
double elevationsum = 0.0;
double elevationvar = 0.0;
double elevationsquare = 0.0;
double elevationmean = 0.0;
double elevationmax = 0.0;
//double r2ocean = 9999.9;
//int oceanmindir = -1;
int[,] map = get_3x3map(gndict[gnid].latitude, gndict[gnid].longitude);
int mapsize = map.GetLength(0);
int x0 = get_x_pixel(gndict[gnid].longitude, gndict[gnid].longitude);
int y0 = get_y_pixel(gndict[gnid].latitude, gndict[gnid].latitude);
if (gndict[gnid].elevation <= 0)
gndict[gnid].elevation = map[x0, y0];
else if (statisticsonly)
elevdiffhist.Add(1.0 * (gndict[gnid].elevation - map[x0, y0]));
byte[,] fillmap = new byte[mapsize, mapsize];
for (int x = 0; x < mapsize; x++)
for (int y = 0; y < mapsize; y++)
fillmap[x, y] = 1;
floodfill(ref fillmap, ref map, x0,y0, 0, 0, false);
if (fillmap[0, 0] == 3) //fill failure
return terrain_type;
double scale = Math.Cos(gndict[gnid].latitude * 3.1416 / 180);
//double pixkmx = scale * 40000 / (360 * 1200);
//double pixkmy = 40000.0 / (360.0 * 1200.0);
double[] elevdirsum = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
double[] elevdirmean = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
int[] nelevdir = { 0, 0, 0, 0, 0, 0, 0, 0 };
int[] noceandir = { 0, 0, 0, 0, 0, 0, 0, 0 };
//int r = Convert.ToInt32(radius / pixkmx);
//double r2max = radius / pixkmy * radius / pixkmy;
for (int x = 0; x < mapsize; x++)
for (int y = 0; y < mapsize; y++)
if (fillmap[x, y] == 2)
if (map[x, y] != 32768) //bad pixel
int dir = get_pix_direction(x, y, x0, y0, scale);
nelev++;
elevationsum += map[x, y];
elevationsquare += map[x, y] * map[x, y];
if (map[x, y] > elevationmax)
elevationmax = map[x, y];
if (dir > 0)
nelevdir[dir - 1]++;
elevdirsum[dir - 1] += map[x, y];
if (nelev > 10)
elevationmean = elevationsum / nelev;
elevationvar = elevationsquare / nelev - elevationmean * elevationmean;
Console.WriteLine("elevation mean, var = " + elevationmean.ToString() + ", " + elevationvar.ToString());
if (statisticsonly)
evarhist.Add(elevationvar);
if (gndict[gnid].elevation > 0)
evarhist.Add(1.0 * (gndict[gnid].elevation - map[x0, y0]));
terrain_type = classify_terrain(elevationvar, elevationmean);
// 1
// 7 5
// 3 4
// 8 6
// 2
int ndir = 0;
if (nelev > 20)
for (int i = 0; i < 8; i++)
if (nelevdir[i] > 0)
elevdirmean[i] = elevdirsum[i] / nelevdir[i];
ndir++;
else
elevdirmean[i] = -99999.0;
//int[] getdircoord(int dir)
if (statisticsonly)
ndirhist.Add(ndir);
if (elevationmax > 0)
terrain_type += "|elevation_max " + elevationmax.ToString();
if (statisticsonly)
Console.WriteLine(gndict[gnid].Name + ": " + terrain_type);
terrainhist.Add(terrain_type);
return terrain_type;
public static int get_direction_from_NSEW(string NSEW)
switch (NSEW.Trim())
case "N.":
return 1;
case "S.":
return 2;
case ".W":
return 3;
case ".E":
return 4;
case "NE":
return 5;
case "SE":
return 6;
case "NW":
return 7;
case "SW":
return 8;
default:
return -1;
public static string get_NSEW_from_xysum(int xsum, int ysum)
string rs = "";
if (xsum > 0)
if (ysum > 0)
rs = " NE";
else if (ysum < 0)
rs = " SE";
else
rs = " .E";
else if (xsum < 0)
if (ysum > 0)
rs = " NW";
else if (ysum < 0)
rs = " SW";
else
rs = " .W";
else if (ysum > 0)
rs = " N.";
else if (ysum < 0)
rs = " S.";
else
rs = " C.";
return rs;
public static string terrain_label(string terr)
string rt = "";
if (terr.Contains("flat"))
if (terr.Contains("high"))
rt = mp(183, null);
else if (terr.Contains("very "))
rt = mp(182, null);
else
rt = mp(109, null);
else if (terr.Contains("hilly"))
if (terr.Contains("somewhat"))
rt = mp(184, null);
else
rt = mp(111, null);
else if (terr.Contains("high-mountains"))
rt = mp(112, null);
else if (terr.Contains("low-mountains"))
rt = mp(185, null);
else if (terr.Contains("mountains"))
rt = mp(110, null);
else
rt = mp(186,null);
return rt;
public static bool is_height(string fcode)
if (fcode == "MTS")
return false;
else if (fcode == "HLLS")
return false;
else if (fcode == "NTKS")
return false;
else if (fcode == "PKS")
return false;
else if (categorydict[fcode] == "mountains")
return true;
else if (categorydict[fcode] == "hills")
return true;
else if (categorydict[fcode] == "volcanoes")
return true;
else
return false;
public static int imp_mountainpart(string fcode)
switch (fcode)
case "SPUR":
case "PROM":
return 197;
case "BNCH":
case "CLF":
case "RKFL":
case "SLID":
case "TAL":
case "CRQ":
case "CRQS":
return 203;
default:
return -1;
public static bool human_touched(Page p, Site site) //determines if an article has been edited by a human user with account (not ip or bot)
string xmlSrc;
bool ht = false;
try
xmlSrc = site.PostDataAndGetResult(site.address + "/w/api.php", "action=query&format=xml&prop=revisions&titles=" + HttpUtility.UrlEncode(p.title) + "&rvlimit=20&rvprop=user");
catch (WebException e)
string message = e.Message;
Console.Error.WriteLine(message);
return true;
XmlDocument xd = new XmlDocument();
xd.LoadXml(xmlSrc);
XmlNodeList elemlist = xd.GetElementsByTagName("rev");
Console.WriteLine("elemlist.Count = " + elemlist.Count);
//Console.WriteLine(xmlSrc);
foreach (XmlNode ee in elemlist)
try
string username = ee.Attributes.GetNamedItem("user").Value;
Console.WriteLine(username);
if (!username.ToLower().Contains("bot") && (get_alphabet(username) != "none"))
ht = true;
break;
catch (NullReferenceException e)
string message = e.Message;
Console.Error.WriteLine(message);
return ht;
public static string terrain_text(string terrain_type, int gnid)
if (terrain_type == "")
return "";
if (terrain_type == "unknown")
return "";
string rt = "";
string[] p98 = { gndict[gnid].Name_ml };
string[] words = terrain_type.Split('|');
string main_terrain = words[0];
Dictionary
List
maintype.Add("flat");
maintype.Add("hilly");
maintype.Add("mountains");
int nsector = 0;
string centralterrain = "";
string majorterrain = "";
string minorterrain = "";
foreach (string w in words)
if ((w.IndexOf("dir") == 0) || (w.IndexOf("central") == 0))
foreach (string ttype in maintype)
if (w.Contains(ttype))
if (!terrsector.ContainsKey(ttype))
terrsector.Add(ttype, 0);
terrsector[ttype]++;
nsector++;
if (w.IndexOf("central") == 0)
centralterrain = ttype;
bool allsame = false;
bool varied = false;
bool singlediff = false;
int tmax = -1;
string tmaxtype = "";
string tmintype = "";
//string dirterrain = "";
if (terrsector.Count <= 1)
allsame = true;
else if ( terrsector.Count == 2)
foreach (string ttype in terrsector.Keys)
if (terrsector[ttype] > tmax)
tmax = terrsector[ttype];
tmaxtype = ttype;
if (2 * tmax >= nsector) //at least half are same type
int xsum = 0;
int ysum = 0;
foreach (string ttype in terrsector.Keys)
if (ttype != tmaxtype)
tmintype = ttype;
if (nsector - tmax == 1) //a single sector different
singlediff = true;
foreach (string w in words)
if ((w.IndexOf("dir") == 0) && (w.Contains(tmintype)))
int i = tryconvert(w.Substring(3, 1));
int[] cdir = getdircoord(i);
xsum += cdir[0];
ysum += cdir[1];
minorterrain = tmintype + get_NSEW_from_xysum(xsum, ysum);
majorterrain = tmaxtype;
else //minority more than a single sector
xsum = 0;
ysum = 0;
foreach (string w in words)
if ((w.IndexOf("dir") == 0) && (w.Contains(tmaxtype)))
int i = tryconvert(w.Substring(3, 1));
int[] cdir = getdircoord(i);
xsum += cdir[0];
ysum += cdir[1];
string major_NSEW = get_NSEW_from_xysum(xsum, ysum);
int majordir = get_direction_from_NSEW(major_NSEW);
if (majordir <= 0)
varied = true;
main_terrain = "mixed";
else
bool rightmajor = false;
foreach (string w in words)
if (w.Contains("dir" + majordir.ToString()))
if (w.Contains(tmaxtype))
rightmajor = true;
if (!rightmajor)
varied = true;
main_terrain = "mixed";
else
majorterrain = tmaxtype + major_NSEW;
xsum = 0;
ysum = 0;
foreach (string w in words)
if ((w.IndexOf("dir") == 0) && (w.Contains(tmintype)))
int i = tryconvert(w.Substring(3, 1));
int[] cdir = getdircoord(i);
xsum += cdir[0];
ysum += cdir[1];
minorterrain = tmintype + get_NSEW_from_xysum(xsum, ysum);
else
varied = true;
main_terrain = "mixed";
else
varied = true;
main_terrain = "mixed";
Console.WriteLine("majorterrain=" + majorterrain);
Console.WriteLine("minorterrain=" + minorterrain);
//terrain header:
bool peakvalley = true; //true if it should be written that something is on a peak or in a valley
if (categorydict[gndict[gnid].featurecode] == "peninsulas")
rt = mp(170, p98) + " "; //terrain landwards from a peninsula
peakvalley = false;
else if (categorydict[gndict[gnid].featurecode] == "islands")
rt = mp(194, p98) + " "; //terrain ON an island
peakvalley = false;
else if (featurepointdict[gndict[gnid].featurecode])
rt = mp(98, p98) + " "; //terrain around a point
peakvalley = !is_height(gndict[gnid].featurecode);
else
rt = mp(141, p98) + " "; //terrain in an area
peakvalley = false;
//terrain label:
if (allsame)
if (terrain_type.Contains("peak") || terrain_type.Contains("valley")) //add "mostly" if peak or valley. Sounds funny if combined with "flat" otherwise.
rt += mp(187, null) + " ";
rt += terrain_label(main_terrain); //main terrain
else if (singlediff)
rt += mp(187, null) + " " + terrain_label(tmaxtype); //mostly
if (minorterrain.Contains(centralterrain))
rt += ", " + mp(188, null) + " " + terrain_label(centralterrain);
else
string NSEW = minorterrain.Replace(tmintype, "").Trim();
int dir = get_direction_from_NSEW(NSEW);
if (dir > 0)
string[] p189 = new string[] { mp(120 + dir, null) };
rt += ", " + mp(189, p189) + " " + terrain_label(tmintype);
else if (varied)
rt += terrain_label("mixed");
else
string major_NSEW = majorterrain.Replace(tmaxtype, "").Trim();
string minor_NSEW = minorterrain.Replace(tmintype, "").Trim();
int majordir = get_direction_from_NSEW(major_NSEW);
int minordir = get_direction_from_NSEW(minor_NSEW);
if (majordir <= 0)
rt += terrain_label("mixed");
else
rt += terrain_label(majorterrain) + " " + mp(120 + majordir, null); //main terrain
if (minordir > 0)
string[] p189 = new string[] { mp(120 + minordir, null) };
rt += ", " + mp(189, p189) + " " + terrain_label(minorterrain);
//coast, peak/valley:
if (featurepointdict[gndict[gnid].featurecode])
foreach (string w in words)
if (w.Contains("ocean"))
if (w.Contains("coast"))
string NSEW = w.Substring(w.IndexOf("coast") + 6, 2);
int dir = get_direction_from_NSEW(NSEW);
if (dir > 0)
if (!String.IsNullOrEmpty(rt))
rt += ". ";
string[] p144 = new string[2] { gndict[gnid].Name_ml, mp(120 + dir, null) };
rt += initialcap(mp(144, p144));
else if (w.Contains("bay"))
string NSEW = w.Substring(w.IndexOf("bay") + 4, 1);
int dir = tryconvert(NSEW);
if (dir > 0)
if (!String.IsNullOrEmpty(rt))
rt += ". ";
string[] p144 = new string[2] { gndict[gnid].Name_ml, mp(120 + dir, null) };
rt += initialcap(mp(145, null) + " " + mp(144, p144));
else if ((w.Contains("peak")) || w.Contains("valley"))
string[] p205 = new string[1] { get_nsew(w) };
if (peakvalley || !String.IsNullOrEmpty(p205[0]))
if (w.Contains("peak"))
if (!String.IsNullOrEmpty(rt))
rt += ". ";
rt += mp(154, p98);
if (!String.IsNullOrEmpty(p205[0]))
rt += " " + mp(205, p205);
else if (w.Contains("valley"))
//if ((nsridge < -triggerdiff) && (ewridge > -triggerdiff / 2))
// terrain_type += "NS.."; //North-south valley
//else if ((ewridge < -triggerdiff) && (nsridge > -triggerdiff / 2))
// terrain_type += "EW..";
//else if (xysum > triggerdiff)
// terrain_type += "SWNE";
//else if (xysum < -triggerdiff)
// terrain_type += "SENW";
if (!String.IsNullOrEmpty(rt))
rt += ". ";
rt += mp(149, p98);
//string[] p205 = new string[1] { get_nsew(w) };
if (!String.IsNullOrEmpty(p205[0]))
rt += " " + mp(205, p205);
else if (w.Contains("slope"))
if (!String.IsNullOrEmpty(rt) && (allsame || varied))
rt += ", " + mp(147, null);
else
if (!String.IsNullOrEmpty(rt))
rt += ". ";
rt += mp(146, p98);
if (w.Contains("steep"))
rt += " " + mp(148, null);
if (w.Contains("N"))
rt += " " + mp(122, null); //reverse because NSEW-coding is upwards and text should be downwards slope
else if (w.Contains("S"))
rt += " " + mp(121, null);
else if (w.Contains("E"))
rt += " " + mp(123, null);
else if (w.Contains("W"))
rt += " " + mp(124, null);
if ( !String.IsNullOrEmpty(rt))
rt += ".";
return rt;
public static string get_nsew(double angle) //compass angle in radians. East = 0.
double ang = angle;
if (ang < 0)
ang += Math.PI;
ang *= 180.0/Math.PI; //convert to degrees
if ((ang < 25) || (ang > 155))
return get_nsew("EW..");
else if ((ang >= 25) && (ang <= 65))
return get_nsew("SWNE");
else if ((ang > 65) && (ang < 115))
return get_nsew("NS..");
else if ((ang >= 115) && (ang <= 155))
return get_nsew("SENW");
else
return "";
public static string get_nsew(string nsew)
string rt = "";
if (nsew.Contains("NS.."))
rt = mp(150, null);
else if (nsew.Contains("EW.."))
rt = mp(151, null);
else if (nsew.Contains("SWNE"))
rt = mp(152, null);
else if (nsew.Contains("SENW"))
rt = mp(153, null);
return rt;
public static string get_overrep(double lat, double lon,double nbradius)
//double nbradius = 20.0;
List
int nnb = 0;
Dictionary
foreach (int nb in farlist)
if (!gndict.ContainsKey(nb))
continue;
if (catnormdict.ContainsKey(categorydict[gndict[nb].featurecode]))
nnb++;
if (!nbcount.ContainsKey(categorydict[gndict[nb].featurecode]))
nbcount.Add(categorydict[gndict[nb].featurecode], 0);
nbcount[categorydict[gndict[nb].featurecode]]++;
Console.WriteLine("nnb = " + nnb.ToString());
List
//int nbsum = 0;
foreach (string scat in nbcount.Keys)
//nbsum += nbcount[scat];
//Console.WriteLine(scat + ": " + (nbcount[scat] / (1.0*nnb)).ToString("F", culture) + " (" + catnormdict[scat].ToString("F", culture) + ")");
if ((nbcount[scat] > 3 * catnormdict[scat]*nnb) && (nbcount[scat] > (catnormdict[scat] * nnb + 5)))
Console.WriteLine("Overrepresented! " + scat);
overrep.Add(categoryml[scat]);
foverrephist.Add(scat);
//Console.WriteLine("nbsum = " + nbsum);
string overlist = "";
if (overrep.Count > 0)
int noo = 0;
foreach (string oo in overrep)
noo++;
if (noo > 1)
if (noo == overrep.Count)
overlist += mp(97, null);
else
overlist += ",";
overlist += " " + oo;
return overlist.Trim();
public static string get_overrep(int gnid,double nbradius)
string overlist = get_overrep(gndict[gnid].latitude, gndict[gnid].longitude,nbradius);
Console.WriteLine("overlist = " + overlist);
if (String.IsNullOrEmpty(overlist))
return "";
string[] p133 = { gndict[gnid].Name_ml, overlist };
string[] p138 = { nbradius.ToString("F0") };
string text = " " + mp(133, p133) + addnote(mp(138, p138) + geonameref(gnid));
return text;
public static double[] get_nearhigh(int gnid, List
nearhigh = -1;
altitude = 0;
double[] latlong = { 9999.9, 9999.9 };
if (!gndict.ContainsKey(gnid))
return latlong;
double emax = 0.0;
double emin = 9999.9;
int nmax = 0;
int nmin = 0;
double maxelevation = 0.0;
double elevation = 0.0;
//double minradius = 1.0;
foreach (int nb in farlist)
if (!gndict.ContainsKey(nb))
continue;
if (gndict[nb].elevation > 0)
if (gndict[nb].elevation > emax)
emax = gndict[nb].elevation;
nmax = nb;
if (gndict[nb].elevation < emin)
emin = gndict[nb].elevation;
nmin = nb;
if ((gndict[gnid].elevation > 0) && (gndict[gnid].elevation < gndict[nb].elevation))
double dist = get_distance(gnid, nb);
if (dist > minradius)
elevation = (gndict[nb].elevation - gndict[gnid].elevation) / dist;
if (elevation > maxelevation)
maxelevation = elevation;
nearhigh = nb;
int[,] map = get_3x3map(gndict[gnid].latitude, gndict[gnid].longitude);
int mapsize = map.GetLength(0);
int x0 = get_x_pixel(gndict[gnid].longitude, gndict[gnid].longitude);
int y0 = get_y_pixel(gndict[gnid].latitude, gndict[gnid].latitude);
double scale = Math.Cos(gndict[gnid].latitude * 3.1416 / 180);
double pixkmx = scale * 40000 / (360 * 1200);
double pixkmy = 40000.0 / (360.0 * 1200.0);
double[] elevdirsum = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
double[] elevdirmean = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
int[] nelevdir = { 0, 0, 0, 0, 0, 0, 0, 0 };
int[] noceandir = { 0, 0, 0, 0, 0, 0, 0, 0 };
int r = Convert.ToInt32(radius / pixkmx);
double r2max = radius / pixkmy * radius / pixkmy;
double r2min = minradius / pixkmy * minradius / pixkmy;
double maxelevationdem = 0;
for (int x = x0 - r; x < x0 + r; x++)
if ((x > 0) && (x < mapsize))
for (int y = y0 - r; y < y0 + r; y++)
if ((y > 0) && (y < mapsize))
double r2 = scale * scale * (x - x0) * (x - x0) + (y - y0) * (y - y0);
if ((r2 < r2max) && (r2 > r2min ))
if (map[x, y] != 0) //not ocean
if (map[x, y] != 32768) //bad pixel
double dist = Math.Sqrt(r2) * pixkmy;
elevation = (map[x,y] - gndict[gnid].elevation) / dist;
if (elevation > maxelevationdem)
maxelevationdem = elevation;
double one1200 = 1.0 / 1200.0;
double dlon = (x - x0) * one1200;
double dlat = -(y - y0) * one1200; //reverse sign because higher pixel number is lower latitude
latlong[0] = gndict[gnid].latitude + dlat;
latlong[1] = gndict[gnid].longitude + dlon;
altitude = map[x, y];
if (maxelevationdem > 1.1 * maxelevation)
nearhigh = -1;
else if ( gndict.ContainsKey(nearhigh))
latlong[0] = gndict[nearhigh].latitude;
latlong[1] = gndict[nearhigh].longitude;
altitude = gndict[nearhigh].elevation;
return latlong;
public static double[] get_highest(int gnid, double radius, out int altitude)
//Find highest DEM point within radius
altitude = 0;
double[] latlong = { 9999.9, 9999.9 };
if (!gndict.ContainsKey(gnid))
return latlong;
double elevation = 0.0;
int[,] map = get_3x3map(gndict[gnid].latitude, gndict[gnid].longitude);
int mapsize = map.GetLength(0);
int x0 = get_x_pixel(gndict[gnid].longitude, gndict[gnid].longitude);
int y0 = get_y_pixel(gndict[gnid].latitude, gndict[gnid].latitude);
double scale = Math.Cos(gndict[gnid].latitude * 3.1416 / 180);
double pixkmx = scale * 40000 / (360 * 1200);
double pixkmy = 40000.0 / (360.0 * 1200.0);
double[] elevdirsum = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
double[] elevdirmean = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
int[] nelevdir = { 0, 0, 0, 0, 0, 0, 0, 0 };
int[] noceandir = { 0, 0, 0, 0, 0, 0, 0, 0 };
int r = Convert.ToInt32(radius / pixkmx);
double r2max = radius / pixkmy * radius / pixkmy;
//double r2min = minradius / pixkmy * minradius / pixkmy;
double maxelevationdem = 0;
Console.WriteLine("pixkmx = " + pixkmx.ToString());
Console.WriteLine("r = " + r.ToString());
Console.WriteLine("r2max = " + r2max.ToString());
for (int x = x0 - r; x < x0 + r; x++)
if ((x > 0) && (x < mapsize))
for (int y = y0 - r; y < y0 + r; y++)
if ((y > 0) && (y < mapsize))
double r2 = scale * scale * (x - x0) * (x - x0) + (y - y0) * (y - y0);
if (r2 < r2max)
if (map[x, y] != 0) //not ocean
if (map[x, y] != 32768) //bad pixel
//double dist = Math.Sqrt(r2) * pixkmy;
elevation = map[x, y];
if (elevation > maxelevationdem)
maxelevationdem = elevation;
double one1200 = 1.0 / 1200.0;
double dlon = (x - x0) * one1200;
double dlat = -(y - y0) * one1200; //reverse sign because higher pixel number is lower latitude
latlong[0] = gndict[gnid].latitude + dlat;
latlong[1] = gndict[gnid].longitude + dlon;
altitude = map[x, y];
return latlong;
public static string make_town(int gnid)
string text = "";
//List
double nbradius = 20.0;
List
double ttradius = 10.0;
string terrain_type = get_terrain_type3(gnid,ttradius);
string[] p158 = {ttradius.ToString("F0")};
text += "\n\n" + terrain_text(terrain_type, gnid) + addnote(mp(158, p158) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
//Dictionary
//Dictionary
//double nnb = 0;
long popmax = gndict[gnid].population;
long pop3 = 3 * gndict[gnid].population;
long totalpop = gndict[gnid].population;
int npopmax = 0;
int npopnear = 0;
int nppl = 0;
double popmindist = 9999.9;
foreach (int nb in farlist)
if (!gndict.ContainsKey(nb))
continue;
//if (catnormdict.ContainsKey(categorydict[gndict[nb].featurecode]))
//{
// nnb += 1;
// if (!nbcount.ContainsKey(categorydict[gndict[nb].featurecode]))
// nbcount.Add(categorydict[gndict[nb].featurecode], 0);
// nbcount[categorydict[gndict[nb].featurecode]]++;
//}
if (gndict[nb].featureclass == 'P')
nppl++;
totalpop += gndict[nb].population;
if (gndict[nb].population > popmax)
popmax = gndict[nb].population;
npopmax = nb;
if (gndict[nb].population > pop3)
double dist = get_distance(gnid, nb);
if (dist < popmindist)
popmindist = dist;
npopnear = nb;
string[] p113 = { gndict[gnid].Name_ml };
int nhalt = 0;
int nearhigh = -1;
double[] nhlatlong = get_nearhigh(gnid, farlist, nbradius, 1.0, out nearhigh, out nhalt);
if (nearhigh > 0)
string[] p116 = { makegnidlink(nearhigh), fnum(gndict[nearhigh].elevation) };
text += " " + mp(116, p116) + ", " + fnum(get_distance(gnid, nearhigh)) + " km " + mp(100 + get_direction(gnid, nearhigh), null) + " " + gndict[gnid].Name_ml + "." + addnote(mp(137, null) + geonameref(gnid));
else if (gndict[gnid].elevation > nhalt)
text += " " + mp(165, p113) + ".";
else if ( nhlatlong[0]+nhlatlong[1] < 720.0 )
string[] p172 = { fnum(nhalt) };
text += " " + mp(172, p172) + ", " + fnum(get_distance_latlong(gndict[gnid].latitude, gndict[gnid].longitude, nhlatlong[0], nhlatlong[1])) + " km " + mp(100 + get_direction_latlong(gndict[gnid].latitude, gndict[gnid].longitude, nhlatlong[0], nhlatlong[1]), null) + " " + gndict[gnid].Name_ml + "." + addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200,null));
//double popdensity = totalpop / (3.14 * nbradius * nbradius);
//if (popdensity < 10.0)
//{
// text += " " + mp(117, null) + ".";
//}
//else if (popdensity > 100.0)
//{
// text += " " + mp(118, null) + ".";
//}
//else if (popdensity > 400.0)
//{
// text += " " + mp(119, null) + ".";
//}
text += make_popdensity(gnid);
if (nppl == 0)
if (getghostneighbors(gndict[gnid].latitude, gndict[gnid].longitude, 0.5 * nbradius))
text += " " + mp(115, null) + ".";
else if (npopmax > 0)
int nbig = npopmax;
if (npopnear > 0)
if (gndict[nbig].population < 3 * gndict[npopnear].population)
nbig = npopnear;
string[] p114 = { makegnidlink(nbig) };
text += " " + mp(114, p114) + ", " + fnum(get_distance(gnid, nbig)) + " km " + mp(100 + get_direction(gnid, nbig), null) + " " + gndict[gnid].Name_ml + ".";
else
text += " " + mp(113, p113) + ".";
text += make_landcover(gnid);
text += get_overrep(gnid,20.0);
//public static double get_distance(int gnidfrom, int gnidto)
//public static int get_direction(int gnidfrom, int gnidto)
//public static Dictionary
//public static Dictionary
//public static Dictionary
return text;
public static string viewfinder_ref()
if (makelang == "sv")
return "{{Webbref |url= {{Viewfinderlänk}}|titel= Viewfinder Panoramas Digital elevation Model|hämtdatum= 2015-06-21|format= |verk= }}";
else
return "{{Cite web |url= {{Viewfinderlink}}|title= Viewfinder Panoramas Digital elevation Model|date= 2015-06-21|format= }}";
public static string make_point(int gnid) //make any pointlike place, from mountains to oases
string text = "";
//List
double nbradius = 20.0;
List
if (!(categorydict[gndict[gnid].featurecode] == "seabed") && !(categorydict[gndict[gnid].featurecode] == "navigation") && !(categorydict[gndict[gnid].featurecode] == "bays") && !(categorydict[gndict[gnid].featurecode] == "reefs"))
double ttradius = 10.0;
string terrain_type = get_terrain_type3(gnid, ttradius);
string[] p158 = { ttradius.ToString("F0") };
text += "\n\n" + terrain_text(terrain_type, gnid) + addnote(mp(158, p158) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
//Dictionary
//Dictionary
//double nnb = 0;
long popmax = 0;
long pop3 = 3000;
long totalpop = 0;
int npopmax = 0;
int npopnear = 0;
int nppl = 0;
int nbpop = -1;
double popmindist = 9999.9;
foreach (int nb in farlist)
if (!gndict.ContainsKey(nb))
continue;
//if (catnormdict.ContainsKey(categorydict[gndict[nb].featurecode]))
//{
// nnb += 1;
// if (!nbcount.ContainsKey(categorydict[gndict[nb].featurecode]))
// nbcount.Add(categorydict[gndict[nb].featurecode], 0);
// nbcount[categorydict[gndict[nb].featurecode]]++;
//}
if ((gndict[nb].featureclass == 'P')||(gndict[nb].featurecode == "STNB"))
nppl++;
nbpop = nb;
totalpop += gndict[nb].population;
if (gndict[nb].population > popmax)
popmax = gndict[nb].population;
npopmax = nb;
if (gndict[nb].population > pop3)
double dist = get_distance(gnid, nb);
if (dist < popmindist)
popmindist = dist;
npopnear = nb;
string[] p113 = { gndict[gnid].Name_ml };
int nhalt = 0;
int nearhigh = -1;
double[] nhlatlong = get_nearhigh(gnid, farlist, nbradius, 1.0, out nearhigh, out nhalt);
if (nearhigh > 0)
string[] p116 = { makegnidlink(nearhigh), fnum(gndict[nearhigh].elevation) };
text += " " + mp(116, p116) + ", " + fnum(get_distance(gnid, nearhigh)) + " km " + mp(100 + get_direction(gnid, nearhigh), null) + " " + gndict[gnid].Name_ml + "." + addnote(mp(137, null) + geonameref(gnid));
else if (gndict[gnid].elevation > nhalt)
text += " " + mp(165, p113) + ".";
else if (nhlatlong[0] + nhlatlong[1] < 720.0)
string[] p172 = { fnum(nhalt) };
text += " " + mp(172, p172) + ", " + fnum(get_distance_latlong(gndict[gnid].latitude, gndict[gnid].longitude, nhlatlong[0], nhlatlong[1])) + " km " + mp(100 + get_direction_latlong(gndict[gnid].latitude, gndict[gnid].longitude, nhlatlong[0], nhlatlong[1]), null) + " " + gndict[gnid].Name_ml + "." + addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
Console.WriteLine("nhlatlong = " + nhlatlong[0].ToString() + " " + nhlatlong[1].ToString());
//double popdensity = totalpop / (3.14 * nbradius * nbradius);
//if (popdensity < 10.0)
//{
// text += " " + mp(117, null) + ".";
//}
//else if (popdensity > 100.0)
//{
// text += " " + mp(118, null) + ".";
//}
//else if (popdensity > 400.0)
//{
// text += " " + mp(119, null) + ".";
//}
text += make_popdensity(gnid);
if (nppl == 0)
if (!getghostneighbors(gndict[gnid].latitude, gndict[gnid].longitude, 0.5*nbradius))
text += " " + mp(169, null) + ".";
else if (npopmax > 0)
int nbig = npopmax;
if (npopnear > 0)
if (gndict[nbig].population < 3 * gndict[npopnear].population)
nbig = npopnear;
string[] p114 = { makegnidlink(nbig) };
text += " " + mp(114, p114) + ", " + fnum(get_distance(gnid, nbig)) + " km " + mp(100 + get_direction(gnid, nbig), null) + " " + gndict[gnid].Name_ml + ".";
else if (nbpop > 0)
string[] p212 = { makegnidlink(nbpop) };
text += " " + mp(212, p212) + ", " + fnum(get_distance(gnid, nbpop)) + " km " + mp(100 + get_direction(gnid, nbpop), null) + " " + gndict[gnid].Name_ml + ".";
else
Console.WriteLine("Should never come here. make_point
Console.ReadLine();
text += make_landcover(gnid);
int imp = imp_mountainpart(gndict[gnid].featurecode);
if ( imp > 0)
int mtgnid = attach_to_mountain(gnid);
if (gndict.ContainsKey(mtgnid))
text += " " + gndict[gnid].Name_ml + " " + mp(imp, null) + " " + makegnidlink(mtgnid) + "." + addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
if (categorydict[gndict[gnid].featurecode] == "passes")
int mtgnid1 = -1;
int mtgnid2 = -1;
if (between_mountains(gnid, out mtgnid1, out mtgnid2))
string[] p199 = { makegnidlink(mtgnid1), makegnidlink(mtgnid2) };
text += " " + mp(199, p199) + "." + addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
text += get_overrep(gnid, 20.0);
//public static double get_distance(int gnidfrom, int gnidto)
//public static int get_direction(int gnidfrom, int gnidto)
//public static Dictionary
//public static Dictionary
//public static Dictionary
return text;
public static string make_adm(int gnid)
string text = "";
Dictionary
fc.Add('H',0);
fc.Add('L',0);
fc.Add('A',0);
fc.Add('P',0);
fc.Add('S',0);
fc.Add('T',0);
fc.Add('U',0);
fc.Add('V',0);
string[] p79 = new string[1] { gndict[gnid].Name_ml };
//bordering:
if (wdid > 0)
List
if (neighbors.Count > 1)
text += " " + mp(96, p79);
int i = 0;
foreach (int wdnb in neighbors)
i++;
if (i == neighbors.Count)
text += mp(97, null);
else if (i > 1)
text += ",";
text += " " + get_name_from_wdid(wdnb);
text += ". ";
else if (neighbors.Count == 1)
text += " " + mp(96, p79);
text += " " + get_name_from_wdid(neighbors[0]);
text += ".";
//terrain type
if (gndict[gnid].area > 0)
double nbradius = Math.Sqrt(gndict[gnid].area);
string terrain_type = get_terrain_type3(gnid, nbradius);
//string[] p136 = { nbradius.ToString("F0") };
text += "\n\n" + terrain_text(terrain_type, gnid);
//if ( makelang == "sv" )
text += addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
//administrative subdivisions:
if (gndict[gnid].children.Count > 1)
Console.WriteLine("Subdivisions from gnid-kids");
text += "\n\n" + mp(79, p79) + "\n";
foreach (int kid in gndict[gnid].children)
text += "* " + makegnidlink(kid) + "\n";
else if ( wdid > 0)
List
Console.WriteLine("Subdivisions from wikidata-kids, "+kidlist.Count.ToString());
if (kidlist.Count > 0)
text += "\n\n" + mp(79, p79) + "\n";
foreach (int kid in kidlist)
text += "* " + get_name_from_wdid(kid) + "\n";
//feature lists:
if (gndict[gnid].features.Count > 0)
foreach (int ff in gndict[gnid].features)
fc[gndict[ff].featureclass]++;
// H: vatten
// L: diverse människoskapade områden
// P: samhällen
// S: Byggnadsverk
// T: diverse naturfenomen; berg, dalar, öar...
// U: undervattensfenomen
// V: växtlighet; skogar, hedar...
SortedDictionary
if (fc['P'] > 0)
text += "\n\n" + mp(80, p79) + "\n";
foreach (int ff in gndict[gnid].features)
if (gndict[ff].featureclass == 'P')
long pop = gndict[ff].population;
while (flist.ContainsKey(pop))
pop++;
flist.Add(pop, ff);
string sorted = "";
foreach (int fpop in flist.Keys)
//sorted = "\n* " + makegnidlink(flist[fpop]) + " (" + fpop.ToString("N0",nfi) + " " + mp(81, null) + ")" + sorted; //With pop
sorted = "\n* " + makegnidlink(flist[fpop]) + sorted; //Without pop
text += sorted;
SortedDictionary
if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 10)
//public static Dictionary
//public static Dictionary
//public static Dictionary
text += "\n\n" + mp(91, p79) + "\n";
foreach (string cat in categoryml.Keys)
fl2.Clear();
foreach (int ff in gndict[gnid].features)
if ((gndict[ff].featureclass == 'H') || (gndict[ff].featureclass == 'T') || (gndict[ff].featureclass == 'U') || (gndict[ff].featureclass == 'V'))
if (categorydict[gndict[ff].featurecode] == cat)
string ffname = gndict[ff].Name_ml;
while (fl2.ContainsKey(ffname))
ffname += " ";
fl2.Add(ffname, ff);
if (fl2.Count > 0)
text += "\n\n* " + initialcap(categoryml[cat]) + ":\n";
string sorted = "";
foreach (string fname in fl2.Keys)
sorted += "\n:* " + makegnidlink(fl2[fname]) + " (" + linkfeature(gndict[fl2[fname]].featurecode,fl2[fname]) + ")";
text += sorted;
else if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 0)
fl2.Clear();
text += "\n\n" + mp(91, p79) + "\n";
foreach (int ff in gndict[gnid].features)
if ((gndict[ff].featureclass == 'H') || (gndict[ff].featureclass == 'T') || (gndict[ff].featureclass == 'U') || (gndict[ff].featureclass == 'V'))
string ffname = gndict[ff].Name_ml;
while (fl2.ContainsKey(ffname))
ffname += " ";
fl2.Add(ffname, ff);
string sorted = "";
foreach (string fname in fl2.Keys)
sorted += "\n* " + makegnidlink(fl2[fname]) + " (" + linkfeature(gndict[fl2[fname]].featurecode, fl2[fname]) + ")";
text += sorted;
return text;
public static string make_island(int gnid, Page p)
string text = "";
Dictionary
fc.Add('H', 0);
fc.Add('L', 0);
fc.Add('A', 0);
fc.Add('P', 0);
fc.Add('S', 0);
fc.Add('T', 0);
fc.Add('U', 0);
fc.Add('V', 0);
string[] p79 = new string[1] { gndict[gnid].Name_ml };
//terrain type
if (gndict[gnid].area > 0)
//double nbradius = Math.Sqrt(gndict[gnid].area);
string terrain_type = get_terrain_type_island(gnid);
//string[] p136 = { nbradius.ToString("F0") };
string tt = terrain_text(terrain_type, gnid);
if (!String.IsNullOrEmpty(tt))
text += "\n\n" + tt;
//if (makelang == "sv")
text += addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
string heightmarker = "|elevation_max";
if (terrain_type.Contains(heightmarker))
string elmax = terrain_type.Substring(terrain_type.IndexOf(heightmarker) + heightmarker.Length + 1);
int maxheight = tryconvert(elmax);
if (maxheight > gndict[gnid].elevation)
string[] p163 = { fnum(maxheight) };
text += " " + mp(163, p163);
p.SetTemplateParameter("geobox", "highest_elevation", elmax, true);
if ((islanddict.ContainsKey(gnid)) && ((islanddict[gnid].kmns + islanddict[gnid].kmew) > 1.0))
string[] p164 = { islanddict[gnid].kmns.ToString("F1", culture), islanddict[gnid].kmew.ToString("F1", culture) };
text += " " + mp(164, p164);
//if (makelang == "sv")
text += addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
if (islanddict[gnid].kmew > 2 * islanddict[gnid].kmns)
p.SetTemplateParameter("geobox", "length", islanddict[gnid].kmew.ToString(), true);
p.SetTemplateParameter("geobox", "width", islanddict[gnid].kmns.ToString(), true);
p.SetTemplateParameter("geobox", "length_orientation", "EW", true);
p.SetTemplateParameter("geobox", "width_orientation", "NS", true);
else if (islanddict[gnid].kmns > 2 * islanddict[gnid].kmew)
p.SetTemplateParameter("geobox", "length", islanddict[gnid].kmns.ToString(), true);
p.SetTemplateParameter("geobox", "width", islanddict[gnid].kmew.ToString(), true);
p.SetTemplateParameter("geobox", "length_orientation", "NS", true);
p.SetTemplateParameter("geobox", "width_orientation", "EW", true);
if ( gndict[gnid].area < 300 )
text += " " + make_landcover(gnid);
//feature lists:
if (islanddict.ContainsKey(gnid))
if (islanddict[gnid].onisland.Count > 0)
foreach (int ff in islanddict[gnid].onisland)
if (!categorydict.ContainsKey(gndict[ff].featurecode))
Console.WriteLine(gndict[ff].featurecode + " missing in categorydict");
Console.ReadLine();
continue;
if (categorydict[gndict[ff].featurecode] != "islands") //Not island on island
fc[gndict[ff].featureclass]++;
// H: vatten
// L: diverse människoskapade områden
// P: samhällen
// S: Byggnadsverk
// T: diverse naturfenomen; berg, dalar, öar...
// U: undervattensfenomen
// V: växtlighet; skogar, hedar...
SortedDictionary
if (fc['P'] > 0)
text += "\n\n" + mp(159, p79) + "\n";
foreach (int ff in islanddict[gnid].onisland)
if (gndict[ff].featureclass == 'P')
long pop = gndict[ff].population;
while (flist.ContainsKey(pop))
pop++;
flist.Add(pop, ff);
string sorted = "";
foreach (int fpop in flist.Keys)
//sorted = "\n* " + makegnidlink(flist[fpop]) + " (" + fpop.ToString("N0",nfi) + " " + mp(81, null) + ")" + sorted;
sorted = "\n* " + makegnidlink(flist[fpop]) + sorted;
text += sorted;
SortedDictionary
if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 10)
//public static Dictionary
//public static Dictionary
//public static Dictionary
text += "\n\n" + mp(160, p79) + "\n";
foreach (string cat in categoryml.Keys)
if (cat == "islands") //not island on island
continue;
fl2.Clear();
foreach (int ff in islanddict[gnid].onisland)
if ((gndict[ff].featureclass == 'H') || (gndict[ff].featureclass == 'T') || (gndict[ff].featureclass == 'U') || (gndict[ff].featureclass == 'V'))
if (categorydict[gndict[ff].featurecode] == cat)
string ffname = gndict[ff].Name_ml;
while (fl2.ContainsKey(ffname))
ffname += " ";
fl2.Add(ffname, ff);
if (fl2.Count > 0)
text += "\n* " + initialcap(categoryml[cat]) + ":\n";
string sorted = "";
foreach (string fname in fl2.Keys)
sorted += "\n** " + makegnidlink(fl2[fname]) + " (" + linkfeature(gndict[fl2[fname]].featurecode, fl2[fname]) + ")";
text += sorted;
else if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 0)
fl2.Clear();
text += "\n\n" + mp(160, p79) + "\n";
foreach (int ff in islanddict[gnid].onisland)
if ((gndict[ff].featureclass == 'H') || (gndict[ff].featureclass == 'T') || (gndict[ff].featureclass == 'U') || (gndict[ff].featureclass == 'V'))
if (categorydict[gndict[ff].featurecode] != "islands") //Not island on island
continue;
string ffname = gndict[ff].Name_ml;
while (fl2.ContainsKey(ffname))
ffname += " ";
fl2.Add(ffname, ff);
string sorted = "";
foreach (string fname in fl2.Keys)
sorted += "\n* " + makegnidlink(fl2[fname]) + " (" + linkfeature(gndict[fl2[fname]].featurecode, fl2[fname]) + ")";
text += sorted;
return text;
public static string make_range(int gnid, Page p)
string text = "";
Dictionary
fc.Add('H', 0);
fc.Add('L', 0);
fc.Add('A', 0);
fc.Add('P', 0);
fc.Add('S', 0);
fc.Add('T', 0);
fc.Add('U', 0);
fc.Add('V', 0);
if (rangedict.ContainsKey(gnid))
string[] p207 = new string[3] { gndict[gnid].Name_ml, fnum(rangedict[gnid].length), get_nsew(rangedict[gnid].angle) };
text += "\n\n" + mp(207, p207) + addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
if (rangedict[gnid].maxheight > 0)
string[] p208 = new string[1] { fnum(rangedict[gnid].maxheight) };
text += " " + mp(208,p208);
else if ( gndict.ContainsKey(-rangedict[gnid].maxheight))
int hgnid = -rangedict[gnid].maxheight;
string[] p209 = new string[2] { makegnidlink(hgnid),fnum(gndict[hgnid].elevation) };
text += " " + mp(209, p209);
string[] p79 = new string[1] { gndict[gnid].Name_ml };
//feature lists:
if (rangedict[gnid].inrange.Count > 0)
foreach (int ff in rangedict[gnid].inrange)
fc[gndict[ff].featureclass]++;
// H: vatten
// L: diverse människoskapade områden
// P: samhällen
// S: Byggnadsverk
// T: diverse naturfenomen; berg, dalar, öar...
// U: undervattensfenomen
// V: växtlighet; skogar, hedar...
SortedDictionary
if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 0)
text += "\n\n" + mp(206, p79) + "\n";
foreach (int ff in rangedict[gnid].inrange)
if ((gndict[ff].featureclass == 'H') || (gndict[ff].featureclass == 'T') || (gndict[ff].featureclass == 'U') || (gndict[ff].featureclass == 'V'))
string ffname = gndict[ff].Name_ml;
while (fl2.ContainsKey(ffname))
ffname += " ";
fl2.Add(ffname, ff);
string sorted = "";
foreach (string fname in fl2.Keys)
sorted += "\n* " + makegnidlink(fl2[fname]);
text += sorted;
return text;
public static string make_lake(int gnid,Page p)
string text = "";
Dictionary
fc.Add('H', 0);
fc.Add('L', 0);
fc.Add('A', 0);
fc.Add('P', 0);
fc.Add('S', 0);
fc.Add('T', 0);
fc.Add('U', 0);
fc.Add('V', 0);
if (lakedict.ContainsKey(gnid))
if ((lakedict[gnid].kmns + lakedict[gnid].kmew < 5.0) && (lakedict[gnid].kmns + lakedict[gnid].kmew > 0))
int nhalt = 0;
int nearhigh = -1;
double nbradius = 20.0;
List
double[] nhlatlong = get_nearhigh(gnid, farlist, nbradius, 1.0, out nearhigh, out nhalt);
if (nearhigh > 0)
string[] p116 = { makegnidlink(nearhigh), fnum(gndict[nearhigh].elevation) };
text += " " + mp(116, p116) + ", " + fnum(get_distance(gnid, nearhigh)) + " km " + mp(100 + get_direction(gnid, nearhigh), null) + " " + gndict[gnid].Name_ml + "." + addnote(mp(137, null) + geonameref(gnid));
else if (nhlatlong[0] + nhlatlong[1] < 720.0)
string[] p172 = { fnum(nhalt) };
text += " " + mp(172, p172) + ", " + fnum(get_distance_latlong(gndict[gnid].latitude, gndict[gnid].longitude, nhlatlong[0], nhlatlong[1])) + " km " + mp(100 + get_direction_latlong(gndict[gnid].latitude, gndict[gnid].longitude, nhlatlong[0], nhlatlong[1]), null) + " " + gndict[gnid].Name_ml + "." + addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
text += make_landcover(gnid);
string[] p79 = new string[1] { gndict[gnid].Name_ml };
if (lakedict[gnid].kmns + lakedict[gnid].kmew > 1.0)
string[] p164 = { lakedict[gnid].kmns.ToString("F1", culture), lakedict[gnid].kmew.ToString("F1", culture) };
text += " " + mp(164, p164);
if (lakedict[gnid].kmew > 2 * lakedict[gnid].kmns)
p.SetTemplateParameter("geobox", "length", lakedict[gnid].kmew.ToString(), true);
p.SetTemplateParameter("geobox", "width", lakedict[gnid].kmns.ToString(), true);
p.SetTemplateParameter("geobox", "length_orientation", "EW", true);
p.SetTemplateParameter("geobox", "width_orientation", "NS", true);
else if (lakedict[gnid].kmns > 2 * lakedict[gnid].kmew)
p.SetTemplateParameter("geobox", "length", lakedict[gnid].kmns.ToString(), true);
p.SetTemplateParameter("geobox", "width", lakedict[gnid].kmew.ToString(), true);
p.SetTemplateParameter("geobox", "length_orientation", "NS", true);
p.SetTemplateParameter("geobox", "width_orientation", "EW", true);
//feature lists:
if (lakedict[gnid].inlake.Count > 0)
text += "\n\n" + mp(91, p79) + "\n";
foreach (int il in lakedict[gnid].inlake)
text += "\n* " + makegnidlink(il) + " (" + linkfeature(gndict[il].featurecode, il) + ")";
text += "\n\n";
if (lakedict[gnid].atlake.Count > 0)
foreach (int ff in lakedict[gnid].atlake)
fc[gndict[ff].featureclass]++;
// H: vatten
// L: diverse människoskapade områden
// P: samhällen
// S: Byggnadsverk
// T: diverse naturfenomen; berg, dalar, öar...
// U: undervattensfenomen
// V: växtlighet; skogar, hedar...
SortedDictionary
if (fc['P'] > 0)
text += "\n\n" + mp(161, p79) + "\n";
foreach (int ff in lakedict[gnid].atlake)
if (gndict[ff].featureclass == 'P')
long pop = gndict[ff].population;
while (flist.ContainsKey(pop))
pop++;
flist.Add(pop, ff);
string sorted = "";
foreach (int fpop in flist.Keys)
sorted = "\n* " + makegnidlink(flist[fpop]) + " (" + fpop.ToString("N0", nfi) + " " + mp(81, null) + ")" + sorted;
text += sorted;
SortedDictionary
if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 10)
//public static Dictionary
//public static Dictionary
//public static Dictionary
text += "\n\n" + mp(162, p79) + "\n";
foreach (string cat in categoryml.Keys)
fl2.Clear();
foreach (int ff in lakedict[gnid].atlake)
if ((gndict[ff].featureclass == 'H') || (gndict[ff].featureclass == 'T') || (gndict[ff].featureclass == 'U') || (gndict[ff].featureclass == 'V'))
if (categorydict[gndict[ff].featurecode] == cat)
string ffname = gndict[ff].Name_ml;
while (fl2.ContainsKey(ffname))
ffname += " ";
fl2.Add(ffname, ff);
if (fl2.Count > 0)
text += "\n* " + initialcap(categoryml[cat]) + ":\n";
string sorted = "";
foreach (string fname in fl2.Keys)
sorted += "\n** " + makegnidlink(fl2[fname]) + " (" + linkfeature(gndict[fl2[fname]].featurecode, fl2[fname]) + ")";
text += sorted;
else if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 0)
fl2.Clear();
text += "\n\n" + mp(168, p79) + "\n";
foreach (int ff in lakedict[gnid].atlake)
if ((gndict[ff].featureclass == 'H') || (gndict[ff].featureclass == 'T') || (gndict[ff].featureclass == 'U') || (gndict[ff].featureclass == 'V'))
string ffname = gndict[ff].Name_ml;
while (fl2.ContainsKey(ffname))
ffname += " ";
fl2.Add(ffname, ff);
string sorted = "";
foreach (string fname in fl2.Keys)
sorted += "\n* " + makegnidlink(fl2[fname]) + " (" + linkfeature(gndict[fl2[fname]].featurecode, fl2[fname]) + ")";
text += sorted;
return text;
public static string geonameref(int gnid)
//string gn = "[http://www.geonames.org/gnidgnid/asciiascii.html " + gndict[gnid].Name + "] at [http://www.geonames.org/about.html Geonames.Org (cc-by)]; updated "+gndict[gnid].moddate;
string gn = "[{{" + mp(173, null) + "|gnid=" + gnid.ToString() + "|name=" + gndict[gnid].asciiname.ToLower().Replace(" ", "%20").Replace("\"", "%22") + "}} " + gndict[gnid].Name + "] "+mp(293,null)+" [{{Geonamesabout}} Geonames.org (cc-by)]; post " + mp(179, null) + " " + gndict[gnid].moddate + "; " + mp(180, null) + " " + dumpdate;
//gn = gn.Replace("gnidgnid", gnid.ToString());
//gn = gn.Replace("asciiascii", gndict[gnid].asciiname.ToLower().Replace(" ", "%20"));
return addref("gn" + gnid.ToString(), gn);
public static string nasaref()
string gn = "";
if (makelang == "sv")
gn = "{{webbref |url= http://neo.sci.gsfc.nasa.gov/dataset_index.php|titel= NASA Earth Observations Data Set Index|hämtdatum=30 januari 2016 |efternamn= |förnamn= |datum= |verk= |utgivare= NASA}}";
else
gn = "{{Cite web |url= http://neo.sci.gsfc.nasa.gov/dataset_index.php|title= NASA Earth Observations Data Set Index|access-date = 30 Enero 2016 |publisher= NASA}}";
//{{Webbref |url= |titel= |hämtdatum= |författare= |efternamn= |förnamn= |författarlänk= |efternamn2= |förnamn2= |datum= |år= |månad= |format= |verk= |utgivare= |sid= |språk= |doi= |arkivurl= |arkivdatum= |citat= |ref= }}
return addref("nasa", gn);
public static string nasapopref()
string gn = "";
if (makelang == "sv")
gn = "{{webbref |url= http://neo.sci.gsfc.nasa.gov/view.php?datasetId=SEDAC_POP|titel= NASA Earth Observations: Population Density|hämtdatum=30 januari 2016 |efternamn= |förnamn= |datum= |verk= |utgivare= NASA/SEDAC}}";
else
gn = "{{Cite web |url= http://neo.sci.gsfc.nasa.gov/view.php?datasetId=SEDAC_POP|title= NASA Earth Observations: Population Density|access-date = 30 Enero 2016 |publisher= NASA/SEDAC}}";
//{{Webbref |url= |titel= |hämtdatum= |författare= |efternamn= |förnamn= |författarlänk= |efternamn2= |förnamn2= |datum= |år= |månad= |format= |verk= |utgivare= |sid= |språk= |doi= |arkivurl= |arkivdatum= |citat= |ref= }}
return addref("nasapop", gn);
public static string nasarainref()
string gn = "";
if (makelang == "sv")
gn = "{{webbref |url= http://neo.sci.gsfc.nasa.gov/view.php?datasetId=TRMM_3B43M&year=2014|titel= NASA Earth Observations: Rainfall (1 month - TRMM)|hämtdatum=30 januari 2016 |efternamn= |förnamn= |datum= |verk= |utgivare= NASA/Tropical Rainfall Monitoring Mission}}";
else
gn = "{{Cite web |url= http://neo.sci.gsfc.nasa.gov/view.php?datasetId=TRMM_3B43M&year=2014|title= NASA Earth Observations: Rainfall (1 month - TRMM)|access-date = 30 Enero 2016 |publisher= NASA/Tropical Rainfall Monitoring Mission}}";
//{{Webbref |url= |titel= |hämtdatum= |författare= |efternamn= |förnamn= |författarlänk= |efternamn2= |förnamn2= |datum= |år= |månad= |format= |verk= |utgivare= |sid= |språk= |doi= |arkivurl= |arkivdatum= |citat= |ref= }}
return addref("nasarain", gn);
public static string nasalandcoverref()
string gn = "";
if (makelang == "sv")
gn = "{{webbref |url= http://neo.sci.gsfc.nasa.gov/view.php?datasetId=MCD12C1_T1|titel= NASA Earth Observations: Land Cover Classification|hämtdatum=30 januari 2016 |efternamn= |förnamn= |datum= |verk= |utgivare= NASA/MODIS}}";
else
gn = "{{Cite web |url= http://neo.sci.gsfc.nasa.gov/view.php?datasetId=MCD12C1_T1|title= NASA Earth Observations: Land Cover Classification|access-date = 30 Enero 2016 |publisher= NASA/MODIS}}";
//{{Webbref |url= |titel= |hämtdatum= |författare= |efternamn= |förnamn= |författarlänk= |efternamn2= |förnamn2= |datum= |år= |månad= |format= |verk= |utgivare= |sid= |språk= |doi= |arkivurl= |arkivdatum= |citat= |ref= }}
return addref("nasalandcover", gn);
public static string koppenref()
string gn = "";
if (makelang == "sv")
gn = "{{Tidskriftsref | författare = | redaktör = | rubrik = Updated world map of the Köppen-Geiger climate classification| url = http://www.hydrol-earth-syst-sci.net/11/1633/2007/hess-11-1633-2007.html| år = 2007| tidskrift = Hydrology and Earth System Sciences| volym = 11| utgivningsort = | utgivare = | nummer = | sid = 1633-1644| hämtdatum = 2016-01-30| id = | doi = 10.5194/hess-11-1633-2007| issn = | citat = | språk = | förnamn =M C| förnamn2 = B L| förnamn3 = T A| efternamn = Peel| efternamn2 = Finlayson| efternamn3 =McMahon| ref = }}";
else
gn = "{{cite journal |last= Peel|first= M C|last2= Finlayson|first2= B L|date= |title= Updated world map of the Köppen-Geiger climate classification| url = http://www.hydrol-earth-syst-sci.net/11/1633/2007/hess-11-1633-2007.html |journal= Hydrology and Earth System Sciences|publisher= |volume= 11|issue= |pages= 1633-1644|doi= 10.5194/hess-11-1633-2007|access-date=30 Enero 2016}}";
return addref("koppen", gn);
public static string wikiref(string iwlang)
Console.WriteLine("wikiref " + iwlang);
if ((iwlang == "Wikidata") || (iwlang == "wd"))
return addref(iwlang, "(" + mp(130, null) + " " + iwlang + DateTime.Now.ToString("yyyy-MM-dd") + ")");
else
return addref(iwlang + "wiki", "(" + mp(130, null) + " " + iwlang + "wiki " + wdtime.ToString("yyyy-MM-dd") + ")");
public static string makegnidlink(int gnid)
string link = "[[";
if (!gndict.ContainsKey(gnid))
Console.WriteLine("Bad gnid in makegnidlink " + gnid.ToString());
return "";
string aname = gndict[gnid].articlename;
if (aname == "XXX")
return "[["+gndict[gnid].Name_ml+"]]"; //no article name - return Name_ml linked!
if ( aname.Contains("*"))
aname = aname.Replace("*","");
if (gndict[gnid].Name_ml == aname)
link += aname;
else
link += aname + "|" + gndict[gnid].Name_ml;
link += "]]";
return link;
public static string make_catname(string catcode, string adm, bool countrylevel)
string catname = "";
if (countrylevel)
catname = mp(1, null) + initialcap(categoryml[catcode]) + " " + mp(75, null) + " " + adm;
if ((makelang == "sv") && ((catcode == "geography") || (catcode == "islands")))
catname = mp(1, null) + adm + "s " + categoryml[catcode];
if (catname.Contains("ss " + categoryml[catcode]))
catname = catname.Replace("ss " + categoryml[catcode], "s " + categoryml[catcode]);
if (catname.Contains("zs " + categoryml[catcode]))
catname = catname.Replace("zs " + categoryml[catcode], "z " + categoryml[catcode]);
else
catname = mp(1, null) + initialcap(categoryml[catcode]) + " " + mp(75, null) + " " + adm;
return catname;
public static void make_x_in_country(string catcode, string countrynameml)
string catname = make_catname(catcode, countrynameml, true);
if (donecats.Contains(catname))
return;
else
stats.Adddonecat();
donecats.Add(catname);
Page pc = new Page(makesite, catname);
tryload(pc, 1);
if (pc.Exists())
return;
string[] p95 = new string[1] { categoryml[catcode] };
if (parentcategory[catcode] == "top")
pc.text = mp(120, null);
pc.AddToCategory(initialcap(mp(95, p95))+"|"+countrynameml);
pc.AddToCategory(countrynameml);
trysave(pc, 2);
Page pc1 = new Page(makesite, mp(1, null) + mp(95, p95));
tryload(pc1, 1);
if (!pc1.Exists())
pc1.text = mp(120, null);
pc1.AddToCategory(initialcap(categoryml[catcode]));
trysave(pc1, 2);
else
pc.text = mp(120, null);
pc.AddToCategory(make_catname(parentcategory[catcode], countrynameml, true));
pc.AddToCategory(initialcap(mp(95, p95)) + "|" + countrynameml);
trysave(pc, 2);
make_x_in_country(parentcategory[catcode], countrynameml);
public static void make_x_in_adm1(string catcode, int admgnid,string countrynameml)
string admname = getartname(admgnid);
string catname = make_catname(catcode,admname,false);
Console.WriteLine(catname);
if (donecats.Contains(catname))
return;
else
stats.Adddonecat();
donecats.Add(catname);
Page pc = new Page(makesite,catname);
if (!tryload(pc, 1))
return;
if (pc.Exists())
return;
if (parentcategory[catcode] == "top")
pc.text = mp(120, null);
string[] p93 = new string[3] { categoryml[catcode], countrynameml, getadmlabel(makecountry, 1,admgnid) };
pc.AddToCategory(initialcap(mp(93, p93)));
//pc.AddToCategory(getgnidname(admgnid));
trysave(pc, 2);
Page pc1 = new Page(makesite, mp(1,null)+mp(93,p93));
tryload(pc1, 1);
if (!pc1.Exists())
pc1.text = mp(120, null);
pc1.AddToCategory(make_catname(catcode,countrynameml,true));
trysave(pc1, 2);
Page pc2 = new Page(makesite, make_catname(catcode, countrynameml, true));
tryload(pc2, 1);
if (!pc2.Exists())
pc2.text = mp(120, null);
pc2.AddToCategory(countrynameml);
trysave(pc2, 2);
else
string parentcat = make_catname(parentcategory[catcode], admname, false);
Console.WriteLine(parentcat);
pc.text = mp(120, null);
pc.AddToCategory(parentcat);
pc.AddToCategory(make_catname(catcode, countrynameml, true));
trysave(pc, 2);
make_x_in_adm1(parentcategory[catcode], admgnid, countrynameml);
make_x_in_country(catcode, countrynameml);
public static void merge_refs(Page p, string refstring)
//Console.WriteLine(refstring);
if (!p.text.Contains(""))
Console.WriteLine("no ");
return;
p.text = p.text.Replace("", refstring.Replace("
//Reference list:
//if (hasnotes)
// p.text += mp(175, null).Replace("XX", "\n\n");
//reflist += "\n\n\n";
//p.text += "\n\n== " + mp(51, null) + " ==\n\n" + reflist;
public static void retrofit_nasa(int gnid)
Console.WriteLine("============");
hasnotes = false;
if (!gndict.ContainsKey(gnid))
Console.WriteLine("Bad gnid in retrofit_nasa " + gnid.ToString());
return;
Console.WriteLine(gndict[gnid].featureclass.ToString() + "." + gndict[gnid].featurecode);
if (createclass != ' ')
if (gndict[gnid].featureclass != createclass)
Console.WriteLine("Wrong class in retrofit_nasa");
return;
if (createfeature != "")
if (gndict[gnid].featurecode != createfeature)
Console.WriteLine("Wrong feature in retrofit_nasa");
return;
if (createexceptfeature != "")
if (gndict[gnid].featurecode == createexceptfeature)
Console.WriteLine("Wrong feature in retrofit_nasa");
return;
if (createunit > 0)
bool admfound = false;
for (int i = 0; i < 5; i++)
if (gndict[gnid].adm[i] == createunit)
admfound = true;
if (!admfound)
Console.WriteLine("Wrong adm-unit in retrofit_nasa");
return;
if (createexceptunit > 0)
bool admfound = false;
for (int i = 0; i < 5; i++)
if (gndict[gnid].adm[i] == createexceptunit)
admfound = true;
if (admfound)
Console.WriteLine("Wrong adm-unit in retrofit_nasa");
return;
string prefix = testprefix;
//string maintitle = "";
if (gndict[gnid].articlename == "XXX")
Console.WriteLine("No articlename");
gndict[gnid].articlename = gndict[gnid].Name_ml;
//return;
if (String.IsNullOrEmpty(gndict[gnid].articlename))
Console.WriteLine("Null articlename");
gndict[gnid].articlename = gndict[gnid].Name_ml;
return;
Console.WriteLine("gnid = " + gnid);
string countryname = "";
int icountry = -1;
if (countrydict.ContainsKey(gndict[gnid].adm[0]))
icountry = gndict[gnid].adm[0];
countryname = countrydict[gndict[gnid].adm[0]].Name;
//Console.WriteLine("country name = " + countryname);
//Console.WriteLine("Native wiki = "+countrydict[icountry].nativewiki);
else
Console.WriteLine("Invalid country " + gndict[gnid].adm[0].ToString());
string countrynameml = countryname;
if (countryml.ContainsKey(countryname))
countrynameml = countryml[countryname];
string cleanname = remove_disambig(gndict[gnid].articlename);
string oldname = gndict[gnid].articlename.Replace("*","");
if (!is_latin(cleanname))
string latinname = gndict[gnid].asciiname;
if ((get_alphabet(cleanname) == "cyrillic") && (makelang == "sv"))
latinname = cyrillic.Transliterate(cleanname, countrydict[icountry].nativewiki);
gndict[gnid].articlename = gndict[gnid].articlename.Replace(cleanname, latinname);
if (!is_latin(gndict[gnid].Name_ml))
gndict[gnid].Name_ml = latinname;
Page p = new Page(makesite, prefix + getartname(gnid));
tryload(p, 3);
string origtext = "";
if (p.Exists())
if (!p.text.Contains(mp(195, null)))
Console.WriteLine("Not botmade");
return;
if (!p.text.Contains(gnid.ToString()))
Console.WriteLine("Wrong gnid in old article");
return;
if (p.text.Contains("NASA Earth"))
Console.WriteLine("Already done");
return;
origtext = p.text;
string mp117 = mp(117, null);
string mp118 = mp(118, null);
string mp119 = mp(119, null);
string mpop = make_popdensity(gnid).Trim();
bool popdone = false;
if (!String.IsNullOrEmpty(mpop))
if (p.text.Contains(mp117))
p.text = p.text.Replace(mp117, mpop);
popdone = true;
else if (p.text.Contains(mp118))
p.text = p.text.Replace(mp118, mpop);
popdone = true;
else if (p.text.Contains(mp119))
p.text = p.text.Replace(mp119, mpop);
popdone = true;
string climate = make_climate(gnid);
string lc = make_landcover(gnid);
string total = lc;
if ( !popdone && !String.IsNullOrEmpty(mpop))
if (!String.IsNullOrEmpty(total))
total += " ";
total += mpop;
if (!String.IsNullOrEmpty(climate))
if (!String.IsNullOrEmpty(total))
total += " ";
total += climate;
total = total.Trim();
string mp175 = mp(175, null).Replace("XX","").Substring(0,11);
string replacekey = "XXXX";
if (p.text.Contains(mp(51, null)))
replacekey = "== " + mp(51, null);
if (p.text.Contains(mp175))
replacekey = mp175;
Console.WriteLine("replacekey = " + replacekey);
p.text = p.text.Replace(replacekey, total + "\n\n" + replacekey);
merge_refs(p, reflist);
p.text = p.text.Replace("Mer om algoritmen finns här: [[Användare:Lsjbot/Algoritmer]].", "{{Lsjbot-algoritmnot}}").Replace("\n\n\n","\n\n");
p.text = p.text.Replace("at [{{Geonames", mp(293,null)+" [{{Geonames");
//Reference list:
//if (hasnotes)
// p.text += mp(175, null).Replace("XX", "\n\n");
//reflist += "\n\n\n";
//p.text += "\n\n== " + mp(51, null) + " ==\n\n" + reflist;
if (p.text != origtext)
trysave(p, 3);
public static void retrofit_nasa()
makesite.defaultEditComment = mp(219, null) + " " + countryml[makecountryname];
int iremain = gndict.Count;
int iremain0 = iremain;
foreach (int gnid in gndict.Keys)
iremain--;
if ((resume_at > 0) && (resume_at != gnid))
stats.Addskip();
continue;
else
resume_at = -1;
if (stop_at == gnid)
break;
reflist = "
refnamelist.Clear();
retrofit_nasa(gnid);
Console.WriteLine(iremain.ToString() + " remaining.");
if (firstround && (iremain0 - iremain < 5))
Console.WriteLine("
Console.ReadLine();
public static void test_nasa()
foreach (int gnid in gndict.Keys)
make_climate(gnid);
foreach (string s in climatemismatchdict.Keys)
Console.WriteLine(s+": "+ climatemismatchdict[s]);
while (true)
Console.WriteLine("Latitude:");
double lat = tryconvertdouble(Console.ReadLine());
Console.WriteLine("Longitude:");
double lon = tryconvertdouble(Console.ReadLine());
Console.WriteLine("Climate: " + make_climate(lat, lon));
Console.WriteLine("Landcover: " + make_landcover(lat, lon));
Console.WriteLine("Pop density: " + make_popdensity(lat, lon));
public static string make_climate_chart(nasaclass nc, string name)
string s = mp(220,null);
if (String.IsNullOrEmpty(s))
return s;
s = "{| border=\"1\"\n" + s + "\n| " + name + "\n";
int rainmax = 0;
bool validrain = true;
for (int i = 1; i < 13; i++)
if ((nc.month_temp_day[i] < -100) || (nc.month_temp_night[i] < -100))
Console.WriteLine("Invalid temperature data in make_climate_chart");
return "";
else if (nc.month_rain[i] < 0)
validrain = false;
for (int i = 1; i < 13; i++)
s += "| " + nc.month_temp_night[i].ToString(culture_en) + "| " + nc.month_temp_day[i].ToString(culture_en);
if ( validrain)
s += "| " + nc.month_rain[i].ToString() + "\n";
else
s += "| 0\n";
if (nc.month_rain[i] > rainmax)
rainmax = nc.month_rain[i];
if (rainmax > 750)
s += "|maxprecip = " + rainmax.ToString() + "\n";
s += "|float=left\n|clear=left\n|source = " + nasaref() + "\n}}\n|}";
//|maxprecip =
//|float =
//|clear =
//|units =
//|source =
//}}
return s;
public static void read_nasa()
string fname = geonamesfolder + @"nasa.txt";
Console.WriteLine("read_nasa " + fname);
if (!File.Exists(fname))
return;
//if (stats)
//{
// pophist.SetBins(0.0, 10000.0, 100);
// rainhist.SetBins(0.0, 10000.0, 100);
// rainminmaxhist.SetBins(0.0, 2000.0, 20);
// daynighthist.SetBins(-20.0, 40.0, 30);
//}
using (StreamReader sr = new StreamReader(fname))
int n = 0;
while (!sr.EndOfStream)
String line = sr.ReadLine();
//if (n > 250)
// Console.WriteLine(line);
string[] words = line.Split(tabchar);
//foreach (string s in words)
// Console.WriteLine(s);
//Console.WriteLine(words[0] + "|" + words[1]);
// public static Dictionary
int code = tryconvert(words[0]);
//Console.WriteLine("code = " + code);
if (code < 0)
continue;
n++;
nasaclass nc = new nasaclass();
//public class nasaclass
//{
// public int landcover = -1; //Landcover code 1-17 http://eospso.nasa.gov/sites/default/files/atbd/atbd_mod12.pdf
// public int popdensity = -1; //people per square km
// public int temp_average = -999; //average across months and day-night
// public int temp_max = -999; //temp of hottest month
// public int month_max = -999; //hottest month (1-12)
// public int temp_min = -999; //temp of coldest month
// public int month_min = -999; //coldest month
// public int temp_daynight = -999; //average difference between day and night
// public int rainfall = -999; //mm per year
//}
nc.landcover = tryconvert(words[1]);
nc.popdensity = tryconvert(words[2]);
nc.temp_average = tryconvert(words[3]);
nc.temp_max = tryconvert(words[4]);
nc.month_max = tryconvert(words[5]);
nc.temp_min = tryconvert(words[6]);
nc.month_min = tryconvert(words[7]);
nc.temp_daynight = tryconvert(words[8]);
nc.rainfall = tryconvert(words[9]);
nc.rain_max = tryconvert(words[10]);
nc.rain_month_max = tryconvert(words[11]);
nc.rain_min = tryconvert(words[12]);
nc.rain_month_min = tryconvert(words[13]);
nc.koppen = tryconvert(words[14]);
if (words.Length > 15)
for (int i = 0; i < 13; i++)
nc.month_temp_day[i] = tryconvert(words[15 + i]);
for (int i = 0; i < 13; i++)
nc.month_temp_night[i] = tryconvert(words[28 + i]);
for (int i = 0; i < 13; i++)
nc.month_rain[i] = tryconvert(words[41 + i]);
int ndaynight = 0;
double daynightdiff = 0;
for (int i = 1; i < 13; i++) //remove zeroes that might be invalid
//if ( Math.Abs(nc.month_temp_day[i]) < 0.01 )
// nc.month_temp_day[i] = -999;
//if (Math.Abs(nc.month_temp_night[i]) < 0.01)
// nc.month_temp_night[i] = -999;
if ((nc.month_temp_day[i] > -100) && (nc.month_temp_night[i] > -100) && (Math.Abs(nc.month_temp_day[i]) > 0.01) && (Math.Abs(nc.month_temp_night[i]) > 0.01))
daynightdiff += nc.month_temp_day[i] - nc.month_temp_night[i];
ndaynight++;
if (ndaynight > 0)
nc.temp_daynight = Convert.ToInt32(daynightdiff / (1.0 * ndaynight));
if (ndaynight < 12)
for (int i = 1; i < 13; i++) //remove zeroes that might be invalid, if expected temp outside +-2
if (Math.Abs(nc.month_temp_day[i]) < 0.01)
if (nc.month_temp_night[i] > -100)
double expected = nc.month_temp_night[i] + nc.temp_daynight;
if (Math.Abs(expected) > 2)
nc.month_temp_day[i] = -999;
else
nc.month_temp_day[i] = -999;
if (Math.Abs(nc.month_temp_night[i]) < 0.01)
if (nc.month_temp_day[i] > -100)
double expected = nc.month_temp_day[i] - nc.temp_daynight;
if (Math.Abs(expected) > 2)
nc.month_temp_night[i] = -999;
else
nc.month_temp_night[i] = -999;
int ntemp = 0;
double tempsum = 0;
nc.temp_max = -999;
nc.month_max = -1;
nc.temp_min = 999;
nc.month_min = -1;
for (int i = 1; i < 13; i++) //estimate missing values
if ((nc.month_temp_day[i] > -100) && (nc.month_temp_night[i] > -100))
tempsum += nc.month_temp_day[i];
tempsum += nc.month_temp_night[i];
ntemp += 2;
double tmean = 0.5*(nc.month_temp_day[i]+nc.month_temp_night[i]);
if (tmean > nc.temp_max)
nc.temp_max = Convert.ToInt32(tmean);
nc.month_max = i;
if (tmean < nc.temp_min)
nc.temp_min = Convert.ToInt32(tmean);
nc.month_min = i;
else if (nc.month_temp_day[i] > -100)
tempsum += nc.month_temp_day[i];
tempsum += nc.month_temp_day[i] - nc.temp_daynight;
ntemp += 2;
else if (nc.month_temp_night[i] > -100)
tempsum += nc.month_temp_night[i];
tempsum += nc.month_temp_night[i] + nc.temp_daynight;
ntemp += 2;
if ( ntemp > 0 )
nc.temp_average = Convert.ToInt32(tempsum / (1.0*ntemp));
nasadict.Add(code, nc);
//if (stats)
//{
// pophist.Add(Convert.ToDouble(nc.popdensity));
// rainhist.Add(Convert.ToDouble(nc.rainfall));
// rainminmaxhist.Add(Convert.ToDouble(nc.rain_max - nc.rain_min));
// daynighthist.Add(Convert.ToDouble(nc.temp_daynight));
//}
Console.WriteLine("readnasa " + n);
//if (stats)
//{
// Console.WriteLine("Pophist:");
// pophist.PrintDHist();
// Console.ReadLine();
// Console.WriteLine("Rainhist:");
// rainhist.PrintDHist();
// Console.ReadLine();
// Console.WriteLine("Rainminmaxhist:");
// rainminmaxhist.PrintDHist();
// Console.ReadLine();
// Console.WriteLine("Daynighthist:");
// daynighthist.PrintDHist();
// Console.ReadLine();
//}
public static string make_popdensity(int gnid)
if (gndict.ContainsKey(gnid))
return " " + make_popdensity(gndict[gnid].latitude, gndict[gnid].longitude).Replace("XXX", gndict[gnid].Name_ml);
else
return "";
public static string make_popdensity(double lat, double lon)
int row = Convert.ToInt32(10 * (90 - lat));
int col = Convert.ToInt32(10 * (180 + lon));
int code = 10000 * row + col;
if (!nasadict.ContainsKey(code))
return "";
if (nasadict[code].popdensity >= 0)
if (nasadict[code].popdensity < 2)
return " " + mp(239, null) + nasapopref();
else
int[] poplevels = { 7, 20, 50, 250, 1000, 99999 };
int i = 0;
while (poplevels[i] < nasadict[code].popdensity)
i++;
string[] p238 = new string[] { mp(240 + i, null), fnum(nasadict[code].popdensity) };
return mp(238, p238) + nasapopref();
return "";
public static string make_landcover(int gnid)
if (gndict.ContainsKey(gnid))
return " " + make_landcover(gndict[gnid].latitude, gndict[gnid].longitude).Replace("XXX", gndict[gnid].Name_ml);
else
return "";
public static string make_landcover(double lat, double lon)
int row = Convert.ToInt32(10 * (90 - lat));
int col = Convert.ToInt32(10 * (180 + lon));
int code = 10000 * row + col;
if (!nasadict.ContainsKey(code))
return "";
if ((nasadict[code].landcover > 0) && (nasadict[code].landcover <= 17))
return mp(220 + nasadict[code].landcover, null)+nasalandcoverref();
return "";
public static string make_climate(int gnid)
if (gndict.ContainsKey(gnid))
return " " + make_climate(gndict[gnid].latitude, gndict[gnid].longitude, gndict[gnid].elevation, gndict[gnid].Name_ml).Replace("XXX", gndict[gnid].Name_ml);
else
return "";
public static string make_climate(double lat, double lon)
return make_climate(lat, lon, 0,"");
public static string make_climate(double lat, double lon, int altitude,string name)
Dictionary
koppendict.Add(1, "rainforest");
koppendict.Add(2,"monsoon");
koppendict.Add(3,"savanna");
koppendict.Add(4,"desert hot");
koppendict.Add(5,"desert cold");
koppendict.Add(6,"steppe hot");
koppendict.Add(7,"steppe cold");
koppendict.Add(8,"mediterranean");
koppendict.Add(9,"mediterranean");
koppendict.Add(10,"subalpine");
koppendict.Add(11,"humid subtropical");
koppendict.Add(12,"Cwb");
koppendict.Add(13, "Cwc");
koppendict.Add(14, "humid subtropical");
koppendict.Add(15,"oceanic");
koppendict.Add(16,"Cfc");
koppendict.Add(17,"continental");
koppendict.Add(18,"hemiboreal");
koppendict.Add(19,"boreal");
koppendict.Add(20,"continental subarctic");
koppendict.Add(21, "continental");
koppendict.Add(22, "hemiboreal");
koppendict.Add(23, "boreal");
koppendict.Add(24, "continental subarctic");
koppendict.Add(25, "continental");
koppendict.Add(26, "hemiboreal");
koppendict.Add(27, "boreal");
koppendict.Add(28, "continental subarctic");
koppendict.Add(29, "tundra");
koppendict.Add(30, "arctic");
string s = "";
//string dummyname = "XXX";
int row = Convert.ToInt32(10 * (90 - lat));
int col = Convert.ToInt32(10 * (180 + lon));
int code = 10000 * row + col;
Console.WriteLine("lat,lon = " + lat + ", " + lon);
Console.WriteLine("row,col,code = " + row + ", " + col + ", " + code);
if (!nasadict.ContainsKey(code))
return "";
string climate = "unknown";
string koppenclimate = "";
Console.WriteLine("koppen = " + nasadict[code].koppen);
if (nasadict[code].koppen > 0)
koppenclimate = koppendict[nasadict[code].koppen];
if (koppenclimate.Contains("Cw"))
if (Math.Abs(lat) < 30)
koppenclimate = "tropical highland";
else
koppenclimate = "oceanic";
if ( koppenclimate == "Cfc")
if (Math.Abs(lat) > 60)
koppenclimate = "subarctic oceanic";
else
koppenclimate = "oceanic";
if (koppenclimate == "tundra")
if (nasadict[code].temp_max > 13)
koppenclimate = "unknown";
if ( koppenclimate == "subalpine" )
if (altitude < 500 )
koppenclimate = "unknown";
//{{cite journal | author=Peel, M. C. and Finlayson, B. L. and McMahon, T. A. | year=2007 | title= Updated world map of the Köppen-Geiger climate classification | journal=Hydrol. Earth Syst. Sci. | volume=11 | pages=1633-1644 | url=http://www.hydrol-earth-syst-sci.net/11/1633/2007/hess-11-1633-2007.html | issn = 1027-5606}}
if (nasadict[code].rainfall >= 0)
if (nasadict[code].temp_average > -100)
if (nasadict[code].temp_min >= 18) //Tropical
if (nasadict[code].rain_min > 60)
climate = "rainforest";
else if (nasadict[code].rain_min > 100 - nasadict[code].rainfall / 25)
climate = "monsoon";
else
int potevapo = 20 * nasadict[code].temp_average;
if (Math.Abs(nasadict[code].rain_month_max - nasadict[code].month_max) <= 5)
potevapo += 280 - 56 * Math.Abs(nasadict[code].rain_month_max - nasadict[code].month_max);
if (nasadict[code].rainfall < 0.5 * potevapo)
climate = "desert";
else if (nasadict[code].rainfall < potevapo)
climate = "steppe";
else
climate = "savanna";
else if (nasadict[code].temp_max < 0) //Arctic
climate = "arctic";
else if (nasadict[code].temp_max < 10) //Tundra
climate = "tundra";
else
int potevapo = 20 * nasadict[code].temp_average;
if (Math.Abs(nasadict[code].rain_month_max - nasadict[code].month_max) <= 5)
potevapo += 280 - 56 * Math.Abs(nasadict[code].rain_month_max - nasadict[code].month_max);
if (nasadict[code].rainfall < 0.5 * potevapo)
climate = "desert";
else if (nasadict[code].rainfall < potevapo)
climate = "steppe";
else
if (nasadict[code].temp_min > -3)
climate = "temperate";
else
climate = "continental";
else if (String.IsNullOrEmpty(koppenclimate)) //temperature and Köppen unknown
int[] rainlevels = { 300, 1000, 99999 };
int i = 0;
while (rainlevels[i] < nasadict[code].rainfall)
i++;
//string[] p238 = new string[] { mp(240 + i, null), fnum(nasadict[code].popdensity) };
//s += " " + mp(238, p238);
if (i == 0)
climate = "dry";
else if (i >= 2)
climate = "wet";
else if (nasadict[code].temp_average > -100)
if (nasadict[code].temp_min >= 18) //Tropical
climate = "tropical";
else if (nasadict[code].temp_max < 0) //Arctic
climate = "arctic";
else if (nasadict[code].temp_max < 10) //Tundra
climate = "tundra";
else
if (nasadict[code].temp_min > -3)
climate = "temperate";
else
climate = "continental";
Console.WriteLine("koppen, climate 1 = " + koppenclimate + ", " + climate);
if (!String.IsNullOrEmpty(koppenclimate)) //check consistency
if (koppenclimate.Contains(climate))
climate = koppenclimate;
else if (climate == "unknown")
climate = koppenclimate;
else
if (climate == "temperate")
if (((nasadict[code].koppen == 5)||(nasadict[code].koppen >= 7)) && (nasadict[code].koppen <= 28))
climate = koppenclimate;
else
Console.WriteLine("Koppen = " + koppenclimate + ", climate = " + climate);
string kc = koppenclimate + " - "+climate;
if ( !climatemismatchdict.ContainsKey(kc))
climatemismatchdict.Add(kc,0);
climatemismatchdict[kc]++;
climate = "unknown";
else if (climate == "continental")
if ((nasadict[code].koppen == 5) || ((nasadict[code].koppen >= 7) && (nasadict[code].koppen <= 10)) || ((nasadict[code].koppen >= 15) && (nasadict[code].koppen <= 29)))
climate = koppenclimate;
else
Console.WriteLine("Koppen = " + koppenclimate + ", climate = " + climate);
string kc = koppenclimate + " - "+climate;
if ( !climatemismatchdict.ContainsKey(kc))
climatemismatchdict.Add(kc,0);
climatemismatchdict[kc]++;
climate = "unknown";
else if ((climate == "desert") || (climate == "steppe"))
if (koppenclimate.Contains("desert") || koppenclimate.Contains("steppe"))
climate = koppenclimate;
else if (( koppenclimate.Contains("cold")) && ((climate == "tundra" )|| (climate == "continental")))
climate = koppenclimate;
else if (koppenclimate == "mediterranean")
climate = koppenclimate;
else
Console.WriteLine("Koppen = " + koppenclimate + ", climate = " + climate);
string kc = koppenclimate + " - " + climate;
if (!climatemismatchdict.ContainsKey(kc))
climatemismatchdict.Add(kc, 0);
climatemismatchdict[kc]++;
climate = "unknown";
else if ((climate == "tropical") || (climate == "rainforest") || (climate == "monsoon"))
if (koppenclimate.Contains("tropical") || koppenclimate.Contains("rainforest") || koppenclimate.Contains("monsoon") || koppenclimate.Contains("savanna"))
climate = koppenclimate;
else
Console.WriteLine("Koppen = " + koppenclimate + ", climate = " + climate);
string kc = koppenclimate + " - " + climate;
if (!climatemismatchdict.ContainsKey(kc))
climatemismatchdict.Add(kc, 0);
climatemismatchdict[kc]++;
climate = "unknown";
else if (climate == "savanna")
if ((koppenclimate == "steppe hot")||(koppenclimate == "mediterranean")||(koppenclimate == "monsoon")||(koppenclimate == "humid subtropical"))
climate = koppenclimate;
else
Console.WriteLine("Koppen = " + koppenclimate + ", climate = " + climate);
string kc = koppenclimate + " - " + climate;
if (!climatemismatchdict.ContainsKey(kc))
climatemismatchdict.Add(kc, 0);
climatemismatchdict[kc]++;
climate = "unknown";
else if (climate == "tundra")
if (koppenclimate.Contains("boreal") || koppenclimate.Contains("suba"))
climate = koppenclimate;
else
Console.WriteLine("Koppen = " + koppenclimate + ", climate = " + climate);
string kc = koppenclimate + " - " + climate;
if (!climatemismatchdict.ContainsKey(kc))
climatemismatchdict.Add(kc, 0);
climatemismatchdict[kc]++;
climate = "unknown";
else if ((climate == "dry") || (climate == "wet"))
climate = koppenclimate;
else
Console.WriteLine("Koppen = " + koppenclimate + ", climate = " + climate);
string kc = koppenclimate + " - " + climate;
if (!climatemismatchdict.ContainsKey(kc))
climatemismatchdict.Add(kc, 0);
climatemismatchdict[kc]++;
climate = "unknown";
Console.WriteLine("koppen, climate 2 = " + koppenclimate + ", " + climate);
if ( climate != "unknown")
switch (climate)
case "rainforest":
s = mp(250, null);
break;
case "monsoon":
s = mp(251, null);
break;
case "savanna":
s = mp(252, null);
break;
case "desert":
s = mp(253, null);
break;
case "desert hot":
s = mp(254, null);
break;
case "desert cold":
s = mp(255, null);
break;
case "steppe":
s = mp(256, null);
break;
case "steppe hot":
s = mp(257, null);
break;
case "steppe cold":
s = mp(258, null);
break;
case "mediterranean":
s = mp(259, null);
break;
case "subalpine":
s = mp(260, null);
break;
case "humid subtropical":
s = mp(261, null);
break;
case "oceanic":
s = mp(262, null);
break;
case "subarctic oceanic":
s = mp(263, null);
break;
case "tropical highland":
s = mp(264, null);
break;
case "continental":
s = mp(265, null);
break;
case "hemiboreal":
s = mp(266, null);
break;
case "boreal":
s = mp(267, null);
break;
case "continental subarctic":
s = mp(268, null);
break;
case "tundra":
s = mp(269, null);
break;
case "arctic":
s = mp(270, null);
break;
case "tropical":
s = mp(271, null);
break;
case "dry":
s = mp(272, null);
break;
case "wet":
s = mp(273, null);
break;
case "temperate":
s = mp(274, null);
break;
default:
break;
if (climate == koppenclimate)
s += koppenref();
if (nasadict[code].temp_average > -100)
string[] p248 = new string[] { fnum(nasadict[code].temp_average) };
s += " " + mp(248, p248);
if (nasadict[code].month_max > 0)
string[] p249 = new string[] { mp(280 + nasadict[code].month_max, null), fnum(nasadict[code].temp_max), mp(280 + nasadict[code].month_min, null), fnum(nasadict[code].temp_min) };
s += " " + mp(249, p249);
s += nasaref();
if (nasadict[code].rainfall >= 0)
string[] p246 = new string[] { fnum(nasadict[code].rainfall) };
s += " " + mp(246, p246);
if (nasadict[code].rain_month_max > 0)
string[] p247 = new string[] { mp(280 + nasadict[code].rain_month_max, null), fnum(nasadict[code].rain_max), mp(280 + nasadict[code].rain_month_min, null), fnum(nasadict[code].rain_min) };
s += " " + mp(247, p247);
s += nasarainref();
if (nasadict[code].temp_average > -100)
s += "\n\n" + make_climate_chart(nasadict[code],name);
return s.Trim();
public static string from_capital(int gnid)
string fromcapital = "";;
int capitalgnid = countrydict[gndict[gnid].adm[0]].capital_gnid;
if (capitalgnid == gnid) //capital itself is not far from capital :)
return fromcapital;
if (gndict.ContainsKey(capitalgnid))
double dist = get_distance(gnid, capitalgnid);
double mindistcapital = 1.5 + 0.004*Math.Sqrt(gndict[capitalgnid].population);
if (dist > mindistcapital)
int intdist = Convert.ToInt32(dist);
if (intdist > 300)
intdist = 100 * Convert.ToInt32(0.01 * dist);
else if (intdist > 30)
intdist = 10 * Convert.ToInt32(0.1 * dist);
fromcapital = ", " + fnum(intdist) + " km " + mp(100 + get_direction(capitalgnid, gnid), null) + " " + mp(132, null) + " " + makegnidlink(capitalgnid);
else //coinciding with capital location
if (gndict[gnid].featureclass == 'A')
fromcapital = ". " + initialcap(mp(132, null)) + " " + makegnidlink(capitalgnid) + " " + mp(77,null) + " " + gndict[gnid].Name_ml;
else if (featurepointdict[gndict[gnid].featurecode])
fromcapital = ", " + mp(198,null) + " " + mp(132, null) + " " + makegnidlink(capitalgnid);
return fromcapital;
public static string getmonthstring()
DateTime thismonth = DateTime.Now;
string monthstring = thismonth.Month.ToString();
while (monthstring.Length < 2)
monthstring = "0" + monthstring;
return thismonth.Year.ToString() + "-" + monthstring;
public static void fill_wdid_buffer()
foreach (int gnid in gndict.Keys)
if ((resume_at_wdid > 0) && (resume_at_wdid != gnid))
continue;
else
resume_at_wdid = -1;
if (createclass != ' ')
if (gndict[gnid].featureclass != createclass)
Console.WriteLine("Wrong class in thread");
continue;
if (createfeature != "")
if (gndict[gnid].featurecode != createfeature)
Console.WriteLine("Wrong feature in thread");
continue;
if (createexceptfeature != "")
if (gndict[gnid].featurecode == createexceptfeature)
Console.WriteLine("Wrong feature in thread");
continue;
if (gndict[gnid].wdid <= 0)
int wdid = get_wd_item_direct(gnid);
Console.WriteLine("THREAD: gnid,wdid: " + gnid.ToString() + ", " + wdid.ToString());
if (!wdid_buffer.ContainsKey(wdid))
wdid_buffer.Add(gnid, wdid);
Console.WriteLine("End of fill_wdid_buffer");
public static void make_article(int gnid)
Console.WriteLine("============");
hasnotes = false;
if (!gndict.ContainsKey(gnid))
Console.WriteLine("Bad gnid in make_article " + gnid.ToString());
return;
Console.WriteLine(gndict[gnid].featureclass.ToString() + "." + gndict[gnid].featurecode);
if (createclass != ' ')
if (gndict[gnid].featureclass != createclass)
Console.WriteLine("Wrong class in make_article");
return;
if (createfeature != "")
if (gndict[gnid].featurecode != createfeature)
Console.WriteLine("Wrong feature in make_article");
return;
if (createexceptfeature != "")
if (gndict[gnid].featurecode == createexceptfeature)
Console.WriteLine("Wrong feature in make_article");
return;
if ((gndict[gnid].featureclass == 'A') && (gndict[gnid].featurecode.Length > 3) && (gndict[gnid].featurecode.Contains("ADM"))) //check so ADMx supported
int iadm = tryconvert(gndict[gnid].featurecode.Substring(3, 1));
Console.WriteLine("iadm = " + iadm.ToString());
if (String.IsNullOrEmpty(getadmlabel(makecountry,iadm,gnid)))
//if (iadm > admdict[makecountry].maxadm)
Console.WriteLine("Unsupported ADM-label in make_article");
//Console.ReadLine();
return;
if (createunit > 0)
bool admfound = false;
for (int i = 0; i < 5; i++)
if (gndict[gnid].adm[i] == createunit)
admfound = true;
if (!admfound)
Console.WriteLine("Wrong adm-unit in make_article");
return;
if (createexceptunit > 0)
bool admfound = false;
for (int i = 0; i < 5; i++)
if (gndict[gnid].adm[i] == createexceptunit)
admfound = true;
if (admfound)
Console.WriteLine("Wrong adm-unit in make_article");
return;
string prefix = testprefix;
string maintitle = "";
if (gndict[gnid].articlename.Contains("*"))
Console.WriteLine("Exists already");
if (makedoubles)
prefix = doubleprefix;
maintitle = getartname(gnid);
Page pmain = new Page(makesite,maintitle);
if (tryload(pmain,1))
if (!pmain.Exists())
prefix = testprefix;
maintitle = "";
else if (pmain.text.Contains(mp(195, null)) && !human_touched(pmain, makesite))
prefix = testprefix;
maintitle = "";
else
return;
if (gndict[gnid].articlename == "XXX")
Console.WriteLine("No articlename");
gndict[gnid].articlename = gndict[gnid].Name_ml;
//return;
if (String.IsNullOrEmpty(gndict[gnid].articlename))
Console.WriteLine("Null articlename");
gndict[gnid].articlename = gndict[gnid].Name_ml;
return;
string countryname = "";
int icountry = -1;
if (countrydict.ContainsKey(gndict[gnid].adm[0]))
icountry = gndict[gnid].adm[0];
countryname = countrydict[gndict[gnid].adm[0]].Name;
//Console.WriteLine("country name = " + countryname);
//Console.WriteLine("Native wiki = "+countrydict[icountry].nativewiki);
else
Console.WriteLine("Invalid country " + gndict[gnid].adm[0].ToString());
Console.WriteLine("gnid = " + gnid);
string countrynameml = countryname;
if (countryml.ContainsKey(countryname))
countrynameml = countryml[countryname];
string cleanname = remove_disambig(gndict[gnid].articlename);
string oldname = gndict[gnid].articlename.Replace("*","");
if (!is_latin(cleanname))
string latinname = gndict[gnid].asciiname;
if ((get_alphabet(cleanname) == "cyrillic") && (makelang == "sv"))
latinname = cyrillic.Transliterate(cleanname, countrydict[icountry].nativewiki);
gndict[gnid].articlename = gndict[gnid].articlename.Replace(cleanname, latinname);
if (!is_latin(gndict[gnid].Name_ml))
gndict[gnid].Name_ml = latinname;
if (gndict[gnid].articlename != oldname)
int ilang = -1;
if (langtoint.ContainsKey(countrydict[icountry].nativewiki))
ilang = langtoint[countrydict[icountry].nativewiki];
make_redirect(oldname, getartname(gnid), "", ilang);
//TEMPORARY!
//if (getartname(gnid).Contains(","))
//{
// string namenocomma = getartname(gnid).Replace(",", "");
// Page pagenc = new Page(makesite, namenocomma);
// tryload(pagenc, 1);
// if ( pagenc.Exists())
// if (pagenc.text.Contains("obotskapad") && (pagenc.text.Contains(gnid.ToString())))
// {
// make_redirect_override(pagenc, getartname(gnid),"",-1);
// //Console.ReadLine();
// }
//}
//TEMPORARY!
Page p = new Page(makesite, prefix + getartname(gnid));
tryload(p, 3);
bool ok_to_overwrite = false;
string origtext = "";
if (p.Exists())
Console.WriteLine("Exists already 1: " + p.title);
if ((overwrite && ( p.text.Contains(mp(195, null)) && !p.text.Contains(mp(69,null)) ) || p.IsRedirect()) && !human_touched(p, makesite) && p.text.Contains(gnid.ToString()))
//p.text = "";
ok_to_overwrite = true;
else if (makedoubles && !p.text.Contains(mp(195,null)))
prefix = doubleprefix;
maintitle = p.title;
p.title = doubleprefix + p.title;
Console.WriteLine("Prefix 1: "+p.title);
else
return;
if ((makecountry == "CN") && (gndict[gnid].featurecode == "ADM4"))
if (is_zhen(gnid))
gndict[gnid].oldarticlename = gndict[gnid].articlename;
gndict[gnid].articlename = gndict[gnid].articlename.Replace("("+mp(298,null),"("+mp(297,null));
if ((!String.IsNullOrEmpty(gndict[gnid].oldarticlename)) && (gndict[gnid].oldarticlename.Replace("*", "") != gndict[gnid].articlename.Replace("*", "")))
Page pold = new Page(makesite, gndict[gnid].oldarticlename.Replace("*", ""));
tryload(pold, 1);
if (pold.Exists())
if (human_touched(pold, makesite)) //old article exists and is edited; don't make new, redirect and return instead
make_redirect(getartname(gnid), pold.title, "", -1);
return;
else if (!is_fork(pold))
make_redirect_override(pold, getartname(gnid), "", -1); //redirect from old to new
//if ( gndict[gnid].wdid <= 0 )
// gndict[gnid].wdid = get_wd_item_direct(gnid);
if (gndict[gnid].wdid <= 0)
if (makespecificarticles)
gndict[gnid].wdid = get_wd_item_direct(gnid);
else
int nwait = 0;
while (!wdid_buffer.ContainsKey(gnid) && (nwait < 10))
Console.WriteLine("Waiting for wdid thread.");
Thread.Sleep(5000);//milliseconds
nwait++;
if (wdid_buffer.ContainsKey(gnid))
gndict[gnid].wdid = wdid_buffer[gnid];
Console.WriteLine("Getting from wdid thread.");
wdid = gndict[gnid].wdid;
if (wdid > 0)
currentxml = get_wd_xml(wdid);
if (currentxml == null)
wdid = -1;
if (wdid > 0)
double areawd = -1.0;
long popwd = -1;
string iwss = "";
bool preferurban = (gndict[gnid].featureclass == 'P');
get_wd_area_pop(wdid, currentxml, out areawd, out popwd, out iwss,preferurban);
if (popwd > 0)
Console.WriteLine("popwd = " + popwd.ToString());
gndict[gnid].population_wd = popwd;
if (( gndict[gnid].population < minimum_population ) || (!prefergeonamespop))
gndict[gnid].population = popwd;
gndict[gnid].population_wd_iw = iwss;
//npop++;
if (areawd > 0)
gndict[gnid].area = areawd;
//narea++;
else
currentxml = null;
//Console.WriteLine(gndict[gnid].Name + ": " + gndict[gnid].population_wd.ToString() + gndict[gnid].population_wd_iw);
Console.WriteLine("wdid = " + wdid.ToString());
string commonscat = "";
if (wdid > 0)
Console.WriteLine("get_wd_sitelinks");
Dictionary
foreach (string lang in sitelinks.Keys)
if (lang == makelang + "wiki")
Console.WriteLine("Already iw to makelang (1)");
if (String.IsNullOrEmpty(prefix))
make_redirect(getartname(gnid), sitelinks[lang], "", -1);
if (makedoubles)
Page psl = new Page(makesite, sitelinks[lang]);
tryload(psl, 2);
if ( psl.Exists() && !psl.IsRedirect())
if ((p.title != sitelinks[lang]) || !ok_to_overwrite )
Console.WriteLine("Setting double");
prefix = doubleprefix;
if (!p.title.Contains(doubleprefix))
p.title = doubleprefix + p.title;
maintitle = sitelinks[lang];
Console.WriteLine("Prefix 2: " + p.title);
else
return;
if (lang == "commonswiki")
commonscat = sitelinks[lang];
Console.WriteLine("get_wd_commonscat");
if ( String.IsNullOrEmpty(commonscat))
commonscat = get_wd_prop(propdict["commonscat"], currentxml);
string[] p10 = new string[3] { botname, countrynameml, getmonthstring() };
origtext = p.text;
p.text = mp(10, p10) + "\n";
if (is_disambig(p.title)) //top link to disambig page
string forktitle = "";
Page pfork = new Page(makesite, remove_disambig(p.title));
if (tryload(pfork, 1))
if (is_fork(pfork))
forktitle = pfork.title;
else
pfork.title += " (" + mp(67, null) + ")";
pfork.text = null;
if (tryload(pfork, 1))
if (pfork.Exists())
forktitle = pfork.title;
if (!String.IsNullOrEmpty(forktitle))
String[] p181 = { forktitle };
p.text += mp(181, p181) + "\n";
//pauseaftersave = true;
if (p.title.Contains(""))
saveanomaly(p.title, "Contains broken html?");
if ((gndict[gnid].featureclass != 'P') && (gndict[gnid].featureclass != 'A'))
gndict[gnid].population = 0;
gndict[gnid].population_wd = 0;
if (gndict[gnid].featureclass == 'P')
gndict[gnid].area = 0;
p.text += fill_geobox(gnid) + "\n\n";
//Native names:
Dictionary
if ((icountry > 0 ) && (altdict.ContainsKey(gnid)))
foreach (altnameclass ac in altdict[gnid])
if (ac.altname != gndict[gnid].Name_ml)
if (countrydict[icountry].languages.Contains(ac.ilang))
if (!nativenames.ContainsKey(ac.altname))
nativenames.Add(ac.altname, ac.ilang);
string nativestring = "";
if (nativenames.Count > 0)
int nname = 0;
bool commaneeded = false;
nativestring = "(";
int prevlang = -1;
foreach (string nn in nativenames.Keys)
int ilang = nativenames[nn];
if (langdict.ContainsKey(ilang))
if (langdict[ilang].name.ContainsKey(makelang))
if (commaneeded)
nativestring += ", ";
if (ilang != prevlang)
nativestring += "[[" + langdict[ilang].name[makelang] + "]]: ";
nativestring += "'''" + nn + "'''";
nname++;
commaneeded = true;
prevlang = ilang;
if (nname > 0)
nativestring += ") ";
else
nativestring = "";
bool namestart = false; //true if previous sentence started with article name; used to avoid repetitive language.
string sent = "";
string pronoun = gndict[gnid].Name_ml;
string flabel = getfeaturelabelindet(makecountry, gndict[gnid].featurecode, gnid);
if (makelang == "sv")
if (flabel.StartsWith("en "))
pronoun = "den";
else if (flabel.StartsWith("ett "))
pronoun = "det";
else
pronoun = "de";
else if (makelang == "ceb")
if (featuredict[gndict[gnid].featurecode].StartsWith("mga "))
pronoun = "sila";
else
pronoun = "siya";
/// X är en Y i landet Z
sent += "'''"+gndict[gnid].Name_ml + "''' " + nativestring + mp(4,null) + " " + linkfeature(gndict[gnid].featurecode,gnid);
if (countrydict.ContainsKey(gndict[gnid].adm[0]))
sent += " " + mp(75,null) + " " + countrytitle(gndict[gnid].adm[0]) + linkcountry(gndict[gnid].adm[0]);
if (gndict[gnid].altcountry.Count > 0)
string countrylist = "";
int noo = 0;
foreach (int oo in gndict[gnid].altcountry)
if (countrydict.ContainsKey(oo))
if ( motherdict.ContainsKey(makecountry))
if ( oo == countryid[motherdict[makecountry]] )
continue;
noo++;
if (noo > 1)
if (noo == gndict[gnid].altcountry.Count)
countrylist += mp(97, null);
else
countrylist += ",";
countrylist += " " + countrydict[oo].Name_ml;
if (noo > 0)
sent += ", " + mp(134, null) + countrylist;
p.text += sent + "." + geonameref(gnid);
namestart = true;
// X ligger i (kommun), (provins) och (region)
sent = "";
int maxadm = 0;
int minadm = 999;
for (int i = 4; i > 0; i--)
if (!String.IsNullOrEmpty(getgnidname(gndict[gnid].adm[i])) && (gndict[gnid].adm[i] != gnid))
if (i > maxadm)
maxadm = i;
if (i < minadm)
minadm = i;
//int capitalgnid = -1;
string fromcapital = "";
if (countrydict.ContainsKey(gndict[gnid].adm[0]))
fromcapital = from_capital(gnid);
string countrypart = mp(getcountrypart(gnid),null);
if ((makelang == "sv") && (motherdict.ContainsKey(makecountry)))
countrypart = countrypart.Replace("delen av landet","delen av "+countrynameml);
if (maxadm > 0)
sent += " " + mp(135,null) + " " + gndict[gnid].Name_ml + " " + mp(77, null) + " ";
for (int i = 4; i > 0; i--)
if (!String.IsNullOrEmpty(getgnidname(gndict[gnid].adm[i])))
sent += getadmdet(makecountry, i, gndict[gnid].adm[i]) + " " + comment("ADM"+i.ToString())+ makegnidlink(gndict[gnid].adm[i]);
if (i > minadm)
if (i == minadm + 1)
sent += " " + mp(3, null) + " ";
else
sent += ", ";
sent += ", " + countrypart + fromcapital + ".";
else
sent += " " + gndict[gnid].Name_ml + " " + mp(92, null) + " " + countrypart + fromcapital + ".";
if (!String.IsNullOrEmpty(sent))
if (sent.Trim().StartsWith(gndict[gnid].Name_ml))
if (namestart)
sent = ReplaceOne(sent, gndict[gnid].Name_ml, initialcap(pronoun), 0);
namestart = false;
else
namestart = true;
else
namestart = false;
p.text += sent;
//population & elevation & area
string[] p99 = new string[2] { gndict[gnid].Name_ml, fnum(gndict[gnid].elevation) };
string[] p100 = new string[1] { comment("pop")+fnum(gndict[gnid].population) };
string[] p100wd = new string[1] { comment("pop") + fnum(gndict[gnid].population_wd) };
sent = "";
Console.WriteLine("elevation/population");
if ((gndict[gnid].elevation > 0) && ((categorydict[gndict[gnid].featurecode] != "peninsulas")) && (featurepointdict[gndict[gnid].featurecode] || (categorydict[gndict[gnid].featurecode] == "lakes")))
string heightref = geonameref(gnid);
if ((gndict[gnid].elevation > 0) && (gndict[gnid].elevation == gndict[gnid].elevation_vp))
heightref = addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
if (gndict[gnid].population > minimum_population)
if ( gndict[gnid].population_wd == gndict[gnid].population )
sent += " " + mp(99, p99) + heightref + mp(97, null) + " " + mp(100, p100wd) + "." + wikiref(gndict[gnid].population_wd_iw);
else
sent += " " + mp(99, p99) + heightref + mp(97, null) + " " + mp(100, p100) + "." + geonameref(gnid);
else
if (gndict[gnid].population_wd > minimum_population)
p100[0] = gndict[gnid].population_wd.ToString();
sent += " " + mp(99, p99) + heightref + mp(97, null) + " " + mp(100, p100wd) + "." + wikiref(gndict[gnid].population_wd_iw);
else
int imp = 99;
bool peak = is_height(gndict[gnid].featurecode);
if (peak)
imp = 178;
//switch (categorydict[gndict[gnid].featurecode])
//{
// case "mountains":
// case "hills":
// case "volcanoes":
// imp = 178;
// break;
// default:
// imp = 99;
// break;
//}
sent += " " + mp(imp, p99);
if ((peak) && (gndict[gnid].prominence > minimum_prominence ))
sent += "," + heightref;
string[] p190 = new string[1] { fnum(gndict[gnid].prominence)};
sent += " " + mp(190, p190);
sent += addnote(mp(191, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
string[] p192 = new string[1] { fnum(gndict[gnid].width) };
sent += ". " + mp(192, p192) + "." + addnote(mp(193,null));
else
sent += "." + heightref;
else if (gndict[gnid].population > minimum_population)
sent += " " + initialcap(mp(100, p100)) + ".";
if (gndict[gnid].population_wd == gndict[gnid].population)
sent += wikiref(gndict[gnid].population_wd_iw);
else
sent += geonameref(gnid);
else if (gndict[gnid].population_wd > minimum_population)
//p100[0] = comment("pop") + fnum(gndict[gnid].population_wd);
sent += " " + initialcap(mp(100, p100wd)) + "." + wikiref(gndict[gnid].population_wd_iw);
Console.WriteLine("area");
if (gndict[gnid].area > minimum_area)
string[] p129 = new string[2] { gndict[gnid].Name_ml, fnum(gndict[gnid].area) };
sent += " " + mp(129, p129);
if (!String.IsNullOrEmpty(sent))
if (sent.Trim().StartsWith(gndict[gnid].Name_ml))
if (namestart)
sent = ReplaceOne(sent, gndict[gnid].Name_ml, initialcap(pronoun), 0);
namestart = false;
else
namestart = true;
else
namestart = false;
p.text += sent;
sent = "";
if ((gndict[gnid].island > 0) && (categorydict[gndict[gnid].featurecode] != "islands")) //On island; not island-on-island
if (gndict[gndict[gnid].island].area > gndict[gnid].area) //Only if island is bigger than gnid
string[] p139 = new string[2] { gndict[gnid].Name_ml, makegnidlink(gndict[gnid].island) };
sent += " " + mp(139, p139);
//if (makelang == "sv")
sent += addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
if (!String.IsNullOrEmpty(sent))
if (sent.Trim().StartsWith(gndict[gnid].Name_ml))
if (namestart)
sent = ReplaceOne(sent, gndict[gnid].Name_ml, initialcap(pronoun), 0);
namestart = false;
else
namestart = true;
else
namestart = false;
p.text += sent;
sent = "";
if ((gndict[gnid].inlake > 0) && (categorydict[gndict[gnid].featurecode] != "lakes"))//In a lake (mainly islands); not lake-in-lake
if (gndict[gndict[gnid].inlake].area > gndict[gnid].area) //Only if lake is bigger than gnid
string[] p155 = new string[2] { gndict[gnid].Name_ml, makegnidlink(gndict[gnid].inlake) };
sent += " " + mp(155, p155);
if (makelang == "sv")
sent += addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
if (!String.IsNullOrEmpty(sent))
if (sent.Trim().StartsWith(gndict[gnid].Name_ml))
if (namestart)
sent = ReplaceOne(sent, gndict[gnid].Name_ml, initialcap(pronoun), 0);
namestart = false;
else
namestart = true;
else
namestart = false;
p.text += sent;
sent = "";
if (gndict[gnid].atlakes.Count > 0) //Near one or more lakes
if (gndict[gnid].atlakes.Count == 1)
if (gndict[gndict[gnid].atlakes[0]].area > gndict[gnid].area) //Only if lake is bigger than gnid
string[] p156 = new string[2] { gndict[gnid].Name_ml, makegnidlink(gndict[gnid].atlakes[0]) };
sent += " " + mp(156, p156);
if (makelang == "sv")
sent += addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
else
string lakes = "";
int ilakes = 0;
foreach (int lg in gndict[gnid].atlakes)
ilakes++;
if (ilakes == gndict[gnid].atlakes.Count)
lakes += mp(97, null);
lakes += " " + makegnidlink(lg);
string[] p157 = new string[2] { gndict[gnid].Name_ml, lakes };
sent += " " + mp(157, p157);
//if (makelang == "sv")
sent += addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
if (!String.IsNullOrEmpty(sent))
if (sent.Trim().StartsWith(gndict[gnid].Name_ml))
if (namestart)
sent = ReplaceOne(sent, gndict[gnid].Name_ml, initialcap(pronoun), 0);
namestart = false;
else
namestart = true;
else
namestart = false;
p.text += sent;
sent = "";
string rangecat = "";
if ((gndict[gnid].inrange > 0) && (gndict.ContainsKey(gndict[gnid].inrange)))//Part of a mountain range
sent = " " + gndict[gnid].Name_ml + " " + mp(204,null) + " " +makegnidlink(gndict[gnid].inrange) + ".";
sent += addnote(mp(140, null) + addref("vp", viewfinder_ref()) + " " + mp(200, null));
rangecat = getartname(gndict[gnid].inrange);
if (!String.IsNullOrEmpty(sent))
if (sent.Trim().StartsWith(gndict[gnid].Name_ml))
if (namestart)
sent = ReplaceOne(sent, gndict[gnid].Name_ml, initialcap(pronoun), 0);
namestart = false;
else
namestart = true;
else
namestart = false;
p.text += sent;
sent = "";
//p.text += "\n\n";
//separate for different types of features:
Console.WriteLine("Feature-specific");
if ((gndict[gnid].featureclass == 'A') && (gndict[gnid].featurecode.Contains("ADM")) && (!gndict[gnid].featurecode.Contains("ADMD")))
p.text += make_adm(gnid);
else if (gndict[gnid].featureclass == 'P')
if (gndict[gnid].population > minimum_population)
p.text += make_town(gnid);
else
Console.WriteLine("Below minimum population.");
return;
else if (categorydict[gndict[gnid].featurecode] == "islands")
p.text += make_island(gnid,p);
else if (categorydict[gndict[gnid].featurecode] == "lakes")
p.text += make_lake(gnid,p);
else if ((gndict[gnid].featurecode == "MTS")||(gndict[gnid].featurecode == "HLLS"))
p.text += make_range(gnid,p);
else if (featurepointdict[gndict[gnid].featurecode])
p.text += make_point(gnid);
else //Nothing type-specific to add
if (gndict[gnid].featurecode != "ADM1")
p.text += "\n\n" + make_climate(gnid);
//locator map:
if (!locatoringeobox)
string[] p73 = new string[2] { countrynameml, gndict[gnid].Name_ml };
p.text += "\n\n" + mp(72, null) + "|" + locatordict[countryname].get_locator(gndict[gnid].latitude, gndict[gnid].longitude) + " |float = right |width=300 |";
if (makelang != "sv")
p.text += " caption = " + mp(73, p73) + " | ";
p.text += mp(76, null) + " = " + gndict[gnid].Name_ml + "|position=right|background=white|lat=" + gndict[gnid].latitude.ToString(culture_en) + "|long=" + gndict[gnid].longitude.ToString(culture_en);
p.text += "}}\n";
//Reference list:
if (hasnotes)
p.text += mp(175,null).Replace("XX","\n\n");
reflist += "\n\n\n";
p.text += "\n\n== " + mp(51, null) + " ==\n\n" + reflist;
//External links:
if ( !String.IsNullOrEmpty(commonscat))
if (commonscat.Contains("Category:"))
commonscat = commonscat.Replace("Category:", "");
p.text += "\n\n== "+mp(52,null)+"==\n\n{{commonscat|" + commonscat + "|"+ gndict[gnid].Name_ml + "}}\n";
//If testrun only, inactivate categories and iw:
if (!String.IsNullOrEmpty(prefix))
p.text += "\n";
//Categories:
string catcode = categorydict[gndict[gnid].featurecode];
string catname = "";
if (!String.IsNullOrEmpty(getartname(gndict[gnid].adm[1])))
//catname = categoryml[catcode] + " " + mp(75, null) + " " + getgnidname(gndict[gnid].adm[1]);
catname = make_catname(catcode, getartname(gndict[gnid].adm[1]), false);
if (String.IsNullOrEmpty(prefix))
make_x_in_adm1(catcode, gndict[gnid].adm[1], countrynameml);
else
catname = make_catname(catcode, countrynameml, true);
if (String.IsNullOrEmpty(prefix))
make_x_in_country(catcode, countrynameml);
if (!String.IsNullOrEmpty(rangecat))
p.AddToCategory(initialcap(rangecat));
Page rcp = new Page(makesite, mp(1, null) + rangecat);
tryload(rcp, 1);
if (!rcp.Exists())
rcp.text = mp(120, null) + "\n";
rcp.AddToCategory(initialcap(catname));
trysave(rcp, 2);
else if (!rcp.text.Contains(catname))
rcp.AddToCategory(initialcap(catname));
trysave(rcp, 2);
p.AddToCategory(initialcap(catname));
switch (catcode)
case "lakes":
case "islands":
cat_by_size(p, catcode, countrynameml, gndict[gnid].area);
break;
case "mountains":
case "hills":
case "volcanoes":
cat_by_size(p, "mountains", countrynameml, gndict[gnid].elevation);
break;
case "populated places":
double dpop = gndict[gnid].population;
cat_by_size(p, "populated places", countrynameml, dpop, false);
break;
default:
break;
p.text += "\n\n";
//Interwiki:
if (wdid > 0)
string iwl = iwlinks(currentxml);
if (!iwl.Contains("Exists already"))
p.text += "\n"+iwl;
//else
//{
// string oldtit = iwl.Split(':')[1];
// if (!makedoubles)
// {
// make_redirect(prefix + gndict[gnid].articlename, oldtit, "", -1);
// return;
// }
// else
// {
// if ((p.title != oldtit) || !ok_to_overwrite)
// {
// if (!p.title.Contains(doubleprefix))
// p.title = doubleprefix + p.title;
// maintitle = oldtit;
// }
// }
//}
else
if (!String.IsNullOrEmpty(gndict[gnid].artname2))
string iwl = "\n[[";
if (makelang == "sv")
iwl += "ceb:";
else
iwl += "sv:";
iwl += gndict[gnid].artname2 + "]]\n";
p.text += iwl;
if (!String.IsNullOrEmpty(prefix))
p.text += "\n";
if (makedoubles && !String.IsNullOrEmpty(maintitle))
p.text = saveconflict(p.title, maintitle) + p.text;
if (p.text.Contains(mp(213,null)))
p.AddToCategory(mp(214,null));
countryspecials(p,gnid,catcode);
//Clean and save:
p.text = p.text.Replace("{{geobox\n| 0 ", "{{geobox\n| 1 ");
p.text = p.text.Replace("=