Wikipedia:Projekt DotNetWikiBot Framework/Lsjbot/Make-Geonames
Utseende
//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<string> altnames = new List<string>(); //alternative names 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<int> altcountry = new List<int>(); public List<int> children = new List<int>(); //index of children public List<int> features = new List<int>(); //index of features in adm-unit 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<int> atlakes = new List<int>(); //near the shore of lake(s) in 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<string> altnames = new List<string>(); //alternative names 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<int> languages = new List<int>(); public List<string> bordering = new List<string>(); } public class langclass { public string iso3 = ""; public string iso2 = ""; public Dictionary<string,string> name = new Dictionary<string,string>(); //name of language in different languages. Iso -> name. } 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<int> onisland = new List<int>(); //list of GeoNames id of entities located on the island. } 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<int> inrange = new List<int>(); //list of GeoNames id of mountains in the range. } public class lakeclass //data for each lake { public double area = 0; public double kmew = 0; public double kmns = 0; public List<int> inlake = new List<int>(); //list of GeoNames id of entities located in the lake (mainly islands). public List<int> atlake = new List<int>(); //list of GeoNames id of entities located around the lake. } 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<int> instance_of = new List<int>(); 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<int, geonameclass> gndict = new Dictionary<int, geonameclass>(); public static Dictionary<int, countryclass> countrydict = new Dictionary<int, countryclass>(); //from geoname ID to country info public static Dictionary<string, int> countryid = new Dictionary<string, int>(); //from ISO code to geoname ID for countries public static Dictionary<string, string> countryml = new Dictionary<string, string>(); // from English name to makelang name public static Dictionary<string, string> countryiso = new Dictionary<string, string>(); // from English name to ISO public static Dictionary<string, locatorclass> locatordict = new Dictionary<string, locatorclass>(); // from English name to locator map name //public static Dictionary<string, string> locatorimage = new Dictionary<string, string>(); //from English name to locator map image public static Dictionary<string, List<int>> namefork = new Dictionary<string, List<int>>(); //names with list of corresponding geonameid(s) public static Dictionary<string,Dictionary<string,int>> adm1dict = new Dictionary<string,Dictionary<string,int>>(); public static Dictionary<string,Dictionary<string,Dictionary<string,int>>> adm2dict = new Dictionary<string,Dictionary<string,Dictionary<string,int>>>(); public static Dictionary<int, Dictionary<int, List<int>>> latlong = new Dictionary<int, Dictionary<int, List<int>>>(); //List of all places in same square degree public static Dictionary<int, Dictionary<int, List<int>>> exlatlong = new Dictionary<int, Dictionary<int, List<int>>>(); //List of all places in same square degree public static Dictionary<string, string> featuredict = new Dictionary<string, string>(); //From featurecode to feature name in makelang public static Dictionary<string, char> featureclassdict = new Dictionary<string, char>(); //From featurecode to feature class public static Dictionary<string, string> geoboxdict = new Dictionary<string, string>(); //From featurecode to geobox type public static Dictionary<string, string> geoboxtemplates = new Dictionary<string, string>(); //From geobox type to geobox template public static Dictionary<string, string> categorydict = new Dictionary<string, string>(); //from featurecode to category public static Dictionary<string, string> parentcategory = new Dictionary<string, string>(); //from category to parent category public static Dictionary<string, string> categoryml = new Dictionary<string, string>(); //from category to category name in makelang public static Dictionary<string, int> catstatdict = new Dictionary<string, int>(); //category statistics public static Dictionary<string, double> catnormdict = new Dictionary<string, double>(); //category statistics public static Dictionary<string, bool> featurepointdict = new Dictionary<string, bool>(); //true if feature is pointlike, false if extended public static Dictionary<int, islandclass> islanddict = new Dictionary<int, islandclass>(); public static Dictionary<int, rangeclass> rangedict = new Dictionary<int, rangeclass>(); public static Dictionary<int, lakeclass> lakedict = new Dictionary<int, lakeclass>(); public static Dictionary<int, int> wdgniddict = new Dictionary<int, int>(); // from wdid to gnid //public static Dictionary<int, int> wdgnid = new Dictionary<int, int>(); //from wikidata id to geonames id; negative counts duplicates public static Dictionary<string, int> catwdclass = new Dictionary<string, int>(); //from category to appropriate wd top class public static Dictionary<string, List<string>> catwdinstance = new Dictionary<string, List<string>>(); //from category to list of appropriate wd instance_of public static Dictionary<string, string> admcap = new Dictionary<string, string>(); //names in makelang of capitals of various types of administrative units public static Dictionary<int, existingclass> existingdict = new Dictionary<int, existingclass>(); //already existing articles public static Dictionary<int, existingclass> ghostdict = new Dictionary<int, existingclass>(); //towns with no known population public static Dictionary<string, string> motherdict = new Dictionary<string, string>(); //for overseas possessions: from territory ISO to mother country ISO public static Dictionary<int, string> specialfeaturedict = new Dictionary<int, string>(); //for places that are exceptions to the usual feature labels public static Dictionary<string, List<chinese_pop_class>> chinese_pop_dict = new Dictionary<string, List<chinese_pop_class>>(); public static Dictionary<int, chinese_pop_class> chinese_pop_dict2 = new Dictionary<int, chinese_pop_class>(); public static Dictionary<int,string> iatadict = new Dictionary<int,string>(); public static Dictionary<int, string> icaodict = new Dictionary<int, string>(); public static Dictionary<int, List<altnameclass>> altdict = new Dictionary<int, List<altnameclass>>(); public static List<string> geoboxlist = new List<string>(); //List of geobox types used public static Dictionary<int,langclass> langdict = new Dictionary<int,langclass>(); //main language table public static Dictionary<string, int> langtoint = new Dictionary<string, int>(); //from iso to integer code. Both iso2 and iso3 used as keys to the same int public static List<string> coordparams = new List<string>(); //possible template parameters for latitude/longitude public static Dictionary<int, string> artnamedict = new Dictionary<int, string>(); public static Dictionary<int, string> oldartnamedict = new Dictionary<int, string>(); public static Dictionary<string, tzclass> tzdict = new Dictionary<string, tzclass>(); //Time zone dictionary public static Dictionary<string, string> tznamedict = new Dictionary<string, string>(); //from timezone offset to timezone acronym (standard time) public static Dictionary<string, string> tzsummerdict = new Dictionary<string, string>(); //from timezone offset to timezone acronym (summer time) public static Dictionary<string, string> tzfulldict = new Dictionary<string, string>(); //from timezone offset to timezone full name (standard time) public static Dictionary<string, string> tzfullsummerdict = new Dictionary<string, string>(); //from timezone offset to timezone full name (summer time) public static Dictionary<string, int> propdict = new Dictionary<string, int>(); //from wikidata property name to property id public static string[] iwlang = { "en", "fr", "de", "es" }; public static Dictionary<string, Site> iwsites = new Dictionary<string, Site>(); 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<long, long> popvspop = new Dictionary<long, long>(); //comparing population for same place, wd vs gn public static Dictionary<double, double> areavsarea = new Dictionary<double, double>(); //comparing area for same place, wd vs gn public static int nwdtot = 0; public static Exception eglob; public static bool locatoringeobox = (makelang == "sv"); //only works in Swedish! public static List<string> forktemplates = new List<string>(); public static Dictionary<string, string> featurearticle = new Dictionary<string, string>();//from feature name to article name for feature public static Dictionary<string, string> alphabet_sv = new Dictionary<string, string>();//from English name to Swedish name of alphabets public static Dictionary<string, string> funny_quotes = new Dictionary<string, string>(); public static List<string> donecountries = new List<string>(); public static List<string> donecats = new List<string>(); public static Dictionary<int, nasaclass> nasadict = new Dictionary<int, nasaclass>(); public static Dictionary<string, int> climatemismatchdict = new Dictionary<string, int>(); public static int pausetime = 5; //time between saves, modified depending on task public static Dictionary<int, int> wdid_buffer = new Dictionary<int, int>(); 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<string, admclass> admdict = new Dictionary<string, admclass>(); public static Dictionary<string, string> admtodet = new Dictionary<string, string>(); //from base form to determinate form of adm labels public static Dictionary<string, List<string>> existing_adm1 = new Dictionary<string, List<string>>(); 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<string> refnamelist = new List<string>(); public static string reflist = "<references>"; 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<int, string> phrases = new Dictionary<int, string>(); 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<int> uplinks = new List<int>(); public List<int> downlinks = new List<int>(); } public static Dictionary<int, wdtreeclass> wdtree = new Dictionary<int, wdtreeclass>(); public class transliterationclass { private string defaultlang = "ru"; private string badreturn = "?"; private string contextdependent = "*"; private List<char> vowels = new List<char>(); public List<char> badlist = new List<char>(); private Dictionary<string, Dictionary<char, string>> tldict = new Dictionary<string, Dictionary<char, string>>(); 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<char, string> csdict = new Dictionary<char, string>(); 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<char> tszlist = new List<char> {'С','с','Т','т','З','з'}; List<char> jlist = new List<char> { 'Ж', 'ж', 'Љ', 'љ', 'Ш', 'ш', 'Щ', 'щ', 'Й', 'й', 'Ч', 'ч'}; 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<string, int> shist = new SortedDictionary<string, int>(); private SortedDictionary<int, int> ihist = new SortedDictionary<int, int>(); private SortedDictionary<double, int> dhist = new SortedDictionary<double, int>(); 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<string, int> hist = new Dictionary<string, int>(); // 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<int> sizelist = new List<int>(); 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, int> hist = new SortedDictionary<int, int>(); 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> IndexOfAll(string text, string find) //Return a list with ALL occurrences of find in text { int start = 0; int pos = 0; List<int> rl = new List<int>(); 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<char, char> romchars = new Dictionary<char, char>(); 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("<ret>"); 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<string,Dictionary<string,int>> adm1dict = new Dictionary<string,Dictionary<string,int>>(); 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<string, int> dd = new Dictionary<string, int>(); 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("<cr>"); //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<string,Dictionary<string,int>> adm1dict = new Dictionary<string,Dictionary<string,int>>(); countryclass country = new countryclass(); int geonameid = -1; geonameid = tryconvert(words[3]); string[] ww = words[0].Split('.'); if (!adm2dict.ContainsKey(ww[0])) { Dictionary<string, Dictionary<string, int>> dd = new Dictionary<string, Dictionary<string, int>>(); adm2dict.Add(ww[0], dd); } if ( adm2dict[ww[0]].ContainsKey(ww[1])) adm2dict[ww[0]][ww[1]].Add(ww[2], geonameid); else { Dictionary<string, int> ddd = new Dictionary<string, int>(); 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<string,Dictionary<string,int>> adm1dict = new Dictionary<string,Dictionary<string,int>>(); 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<int> ll = new List<int>(); 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<string, List<string>> existing_adm1 = new Dictionary<string, List<string>>(); 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<string> ll = new List<string>(); 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<int, List<int>> dd = new Dictionary<int, List<int>>(); exlatlong.Add(ilat, dd); } if (!exlatlong[ilat].ContainsKey(ilong)) { List<int> ll = new List<int>(); exlatlong[ilat].Add(ilong, ll); } if (!exlatlong[ilat][ilong].Contains(exid)) exlatlong[ilat][ilong].Add(exid); } public static List<int> getexisting(double lat, double lon, double radius) { List<int> ll = new List<int>(); 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<int, List<int>> dd = new Dictionary<int, List<int>>(); latlong.Add(ilat, dd); } if (!latlong[ilat].ContainsKey(ilong)) { List<int> ll = new List<int>(); 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<int> getneighbors(double lat, double lon, double radius) { List<int> ll = new List<int>(); 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<int> getneighbors(int gnid, double radius) //radius in km! { List<int> ll = new List<int>(); 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<string, string> parentcategory = new Dictionary<string, string>(); //from category to parent category //public static Dictionary<string, string> categoryml = new Dictionary<string, string>(); //from category to category name in makelang 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, int> filekeys = new Dictionary<int, int>(); 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_class> cl = new List<chinese_pop_class>(); 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<string, List<int>> namefork = new Dictionary<string, List<int>>(); //names with list of corresponding geonameid(s) 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<int> ghosts = new List<int>(); 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<string,int> alphdir = new Dictionary<string,int>(); 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<string, string> rd = get_wd_sitelinks(cx); // 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<int,int> oindex = new Dictionary<int,int>(); //List<int> badlist = new List<int>(); Dictionary<int, List<int>> badlist = new Dictionary<int, List<int>>(); //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<int> bl = new List<int>(); 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<int> bl = new List<int>(); 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<int> inrange = new List<int>(); //list of GeoNames id of mountains in the range. //} 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<int, int> oindex = new Dictionary<int, int>(); //List<int> badlist = new List<int>(); Dictionary<int, List<int>> badlist = new Dictionary<int, List<int>>(); //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<int> bl = new List<int>(); 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<int> bl = new List<int>(); 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<altnameclass> anl = new List<altnameclass>(); 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<string> al = new List<string>(); 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<altnameclass> anl = new List<altnameclass>(); 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<altnameclass> anl = new List<altnameclass>(); 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 "<!--" + incomment + "-->"; } public static List<string> getcomments(string text) { List<string> rl = new List<string>(); 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<string> comments = getcomments(text); 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 <cr>"); 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<string> fuzzylist = new List<string>(); 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<string, int> geotempdict = new Dictionary<string, int>(); 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<forkclass> fl = new List<forkclass>(); 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<int> enb = getexistingneighbors(fc.latitude, fc.longitude, 10.0); // 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<int, Disambigclass> dadict = new Dictionary<int, Disambigclass>(); //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<string, string> rd = get_wd_sitelinks(cx); 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<int> enb = getexisting(dadict[gnid].fork.latitude, dadict[gnid].fork.longitude, 10.0); 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<string, List<string>> forkdict = new Dictionary<string, List<string>>(); using (StreamReader sw = new StreamReader("namefork-" + makelang + ".csv")) { while (!sw.EndOfStream) { string s = sw.ReadLine(); s = s.Trim(';'); List<forkclass> fl = new List<forkclass>(); 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<string> ll = new List<string>(); 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<string> forkdoubles = new List<string>(); 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<string, string> forkduplicatedict = new Dictionary<string, string>(); 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<forkclass> fl = new List<forkclass>(); 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<string, List<forkclass>> fd = new Dictionary<string, List<forkclass>>(); SortedDictionary<string, string> scountry = new SortedDictionary<string, string>(); 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<forkclass> ffl = new List<forkclass>(); 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<string> artnames = new List<string>(); 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> uniquelabels = new List<string>(); 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, int> geotempdict = new Dictionary<string, int>(); //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<string, string> pdict = Page.ParseTemplate(tt); 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, int> geotempdict = new Dictionary<string, int>(); // 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<string, string> pdict = makesite.ParseTemplate(ttt); // 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<words.Length;i++) { if (words[i] == makelang) 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<string> iwlist = Interwiki(wdsite, countrydict[gnid].Name); // 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<string> Interwiki(Site site, string title) //Borrowed from http://sv.wikipedia.org/wiki/Wikipedia:Projekt_DotNetWikiBot_Framework/Innocent_bot/Addbotkopia { List<string> r = new List<string>(); 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<string,string> name = new Dictionary<string,string>(); //name of language in different language. Iso -> name. //} //public static Dictionary<int,langclass> langdict = new Dictionary<int,langclass>(); //main language table //public static Dictionary<string, int> langtoint = new Dictionary<string, int>(); //from iso to integer code. Both iso2 and iso3 used as keys to the same int 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<int, string> ld = new Dictionary<int, string>(); 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 = "<ref name = " + refname + ">" + rstring + "</ref>"; reflist += "\n" + refref; } string shortref = "<ref name = " + refname + "/>"; 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<string> iwlist = ep.GetInterLanguageLinks(); 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<string,string> cleanstring = new Dictionary<string,string>(); 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> allnames = new List<string>(); 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<int> farlist = getneighbors(gnid, nbradius); 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", "<sup>" + mp(131, null) + " " + gndict[gnid].population_wd_iw + "wiki</sup>", 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", "<sup>" + mp(131, null) + " Wikidata</sup>", 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", "<sup>" + mp(131, null) + " " + gndict[gnid].population_wd_iw + "wiki</sup>", 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", "<sup>" + mp(131, null) + " Wikidata</sup>", 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", "<sup>" + mp(131, null) + " " + gndict[gnid].population_wd_iw + "wiki</sup>", 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<int> inrange = new List<int>(); //list of GeoNames id of mountains in the range. //} 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<string, string> replacedict1 = new Dictionary<string, string>(); Dictionary<string, string> replacedict2 = new Dictionary<string, string>(); 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<string, string> replacepair in replacedict1) { ltp.text = ltp.text.Replace(replacepair.Key, replacepair.Value); } foreach (KeyValuePair<string, string> replacepair in replacedict2) { 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("<ret>"); //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<string> popparams = new List<string>(); List<string> urbanparams = new List<string>(); List<string> areaparams = new List<string>(); List<string> heightparams = new List<string>(); 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<string, string> pdict = Page.ParseTemplate(ttt); 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<string> popparams = new List<string>(); List<string> urbanparams = new List<string>(); List<string> areaparams = new List<string>(); List<string> paramlangs = new List<string>(); 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<string, string> iwdict = get_wd_sitelinks(cx); 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<string, string> pdict = Page.ParseTemplate(ttt);// iwsites[iwss].ParseTemplate(ttt); 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("<ret>"); //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<int,int> read_wd_dict(string wdcountry) { Dictionary<int, int> rdict = new Dictionary<int, int>(); 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<int, int> overridedict = new Dictionary<int, int>(); 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<int> withwd = new List<int>(); //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<int, int> overridedict = new Dictionary<int, int>(); 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("<ret>"); //Console.ReadLine(); List<int> withwd = new List<int>(); //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<int, int> wdgnid = new Dictionary<int, int>(); //from wikidata id to geonames id; negative counts duplicates //public static Dictionary<long, long> popvspop = new Dictionary<long, long>(); //comparing population for same place, wd vs gn //public static Dictionary<double, double> areavsarea = new Dictionary<double, double>(); //comparing area for same place, wd vs gn } } } 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<int> get_wd_prop_idlist(int propid, XmlDocument cx) { List<int> rl = new List<int>(); 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<int> get_wd_kids(XmlDocument cx) { List<int> rl = new List<int>(); List<int> rldouble = new List<int>(); 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<string, string> get_wd_sitelinks(XmlDocument cx) { Dictionary<string, string> rd = new Dictionary<string, string>(); 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, string> rd = get_wd_sitelinks(cx); 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<string, string> get_wd_name_dictionary(XmlDocument cx) { Dictionary<string, string> rd = new Dictionary<string, string>(); 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<string, string> rd = new Dictionary<string, string>(); 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<string, int> namestats = new Dictionary<string, int>(); 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<string> withgnid = new List<string>(); //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<string> titlist = new List<string>(); 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("<ret>"); //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<string, int> latlongobjects = new Dictionary<string, int>(); List<int> withprop = new List<int>(); 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<int> instance_of = new List<int>(); //public double dist = 9999.9; //public bool okdist = false; //public bool okclass = false; //public bool goodmatch = false; //} Dictionary<int, wdminiclass> wdminidict = new Dictionary<int, wdminiclass>(); //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<int, List<int>> wddoubles = new Dictionary<int, List<int>>(); Dictionary<int, int> gnidwddict = new Dictionary<int, int>(); 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<int> dlist = new List<int>(); 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<string, Dictionary<string, int>> wdclass = new Dictionary<string, Dictionary<string, int>>(); 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<int> instances = get_wd_prop_idlist(propdict["instance"], cx); 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<string, int> dd = new Dictionary<string, int>(); 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> subclassof = new List<int>(); 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<string, int> dd = new Dictionary<string, int>(); 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<int> subclassof = get_wd_prop_idlist(propdict["subclass"], cxi); 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<int> farlist, int gnid) { 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<int> farlist = getneighbors(lat, lon, 20.0); 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<int,int> xyhdict = new Dictionary<int,int>(); //List<Tuple<int, int>> xyh = new List<Tuple<int, int>>(); 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<string, int> terrtype = new Dictionary<string, int>(); 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<int> farlist = getneighbors(gnid, 20.0); //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<string, int> terrsector = new Dictionary<string, int>(); List<string> maintype = new List<string>(); 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> farlist = getneighbors(lat,lon, nbradius); int nnb = 0; Dictionary<string, int> nbcount = new Dictionary<string, int>(); 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<string> overrep = new List<string>(); //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<int> farlist, double radius, double minradius, out int nearhigh, out int altitude) { 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<int> nearlist = getneighbors(gnid, 10.0); double nbradius = 20.0; List<int> farlist = getneighbors(gnid, nbradius); 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<string, int> nbcount = new Dictionary<string, int>(); //Dictionary<string, int> catcount = new Dictionary<string, int>(); //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<string, string> categorydict = new Dictionary<string, string>(); //from featurecode to category //public static Dictionary<string, string> parentcategory = new Dictionary<string, string>(); //from category to parent category //public static Dictionary<string, string> categoryml = new Dictionary<string, string>(); //from category to category name in makelang 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<int> nearlist = getneighbors(gnid, 10.0); double nbradius = 20.0; List<int> farlist = getneighbors(gnid, nbradius); 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<string, int> nbcount = new Dictionary<string, int>(); //Dictionary<string, int> catcount = new Dictionary<string, int>(); //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 <ret>"); 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<string, string> categorydict = new Dictionary<string, string>(); //from featurecode to category //public static Dictionary<string, string> parentcategory = new Dictionary<string, string>(); //from category to parent category //public static Dictionary<string, string> categoryml = new Dictionary<string, string>(); //from category to category name in makelang return text; } public static string make_adm(int gnid) { string text = ""; Dictionary<char, int> fc = new Dictionary<char, int>(); 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<int> neighbors = get_wd_prop_idlist(propdict["borders"], currentxml); 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<int> kidlist = get_wd_kids(currentxml); 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<long, int> flist = new SortedDictionary<long, int>(); 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<string, int> fl2 = new SortedDictionary<string, int>(); if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 10) { //public static Dictionary<string, string> categorydict = new Dictionary<string, string>(); //from featurecode to category //public static Dictionary<string, string> parentcategory = new Dictionary<string, string>(); //from category to parent category //public static Dictionary<string, string> categoryml = new Dictionary<string, string>(); //from category to category name in makelang 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<char, int> fc = new Dictionary<char, int>(); 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<long, int> flist = new SortedDictionary<long, int>(); 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<string, int> fl2 = new SortedDictionary<string, int>(); if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 10) { //public static Dictionary<string, string> categorydict = new Dictionary<string, string>(); //from featurecode to category //public static Dictionary<string, string> parentcategory = new Dictionary<string, string>(); //from category to parent category //public static Dictionary<string, string> categoryml = new Dictionary<string, string>(); //from category to category name in makelang 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<char, int> fc = new Dictionary<char, int>(); 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<string, int> fl2 = new SortedDictionary<string, int>(); 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<char, int> fc = new Dictionary<char, int>(); 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<int> farlist = getneighbors(gnid, nbradius); 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<long, int> flist = new SortedDictionary<long, int>(); 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<string, int> fl2 = new SortedDictionary<string, int>(); if (fc['H'] + fc['T'] + fc['U'] + fc['V'] > 10) { //public static Dictionary<string, string> categorydict = new Dictionary<string, string>(); //from featurecode to category //public static Dictionary<string, string> parentcategory = new Dictionary<string, string>(); //from category to parent category //public static Dictionary<string, string> categoryml = new Dictionary<string, string>(); //from category to category name in makelang 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("</references>")) { Console.WriteLine("no </references>"); return; } p.text = p.text.Replace("</references>", refstring.Replace("<references>", "") + "\n</references>"); //Reference list: //if (hasnotes) // p.text += mp(175, null).Replace("XX", "\n\n"); //reflist += "\n</references>\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</references>\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 = "<references>"; refnamelist.Clear(); retrofit_nasa(gnid); Console.WriteLine(iremain.ToString() + " remaining."); if (firstround && (iremain0 - iremain < 5)) { Console.WriteLine("<cr>"); 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 = <!--- supply largest monthly precipitation, in case it's > 750 mm (30 in.) ---> //|float = <!--- left, right, or none ---> //|clear = <!--- left, right, both, or none ---> //|units = <!--- set to "imperial" if the values are in °F and inches ---> //|source = <!--- source of the data ---> //}} 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<string,Dictionary<string,int>> adm1dict = new Dictionary<string,Dictionary<string,int>>(); 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<int, string> koppendict = new Dictionary<int, string>(); 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<string, string> sitelinks = get_wd_sitelinks(currentxml); 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<string,int> nativenames = new Dictionary<string,int>(); 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</references>\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("= <!--", "=\n<!--"); p.text = cleanup_text(p.text); if ( p.text != origtext ) trysave(p,4); //Redirects: //if (!String.IsNullOrEmpty(testprefix)) //{ //make_redirect(testprefix + gndict[gnid].Name, gndict[gnid].articlename, ""); if ( gndict[gnid].Name != getartname(gnid) ) make_redirect(testprefix + gndict[gnid].Name, getartname(gnid), "", -1); if (gndict[gnid].asciiname != getartname(gnid)) make_redirect(testprefix + gndict[gnid].asciiname, getartname(gnid), "", -1); if (altdict.ContainsKey(gnid)) { foreach (altnameclass ac in altdict[gnid]) { if ((!String.IsNullOrEmpty(ac.altname)) && (tryconvert(ac.altname) <= 0)) make_redirect(testprefix + ac.altname, getartname(gnid), "", ac.ilang); } } //} romanian_redirect(getartname(gnid)); if ( !String.IsNullOrEmpty(gndict[gnid].unfixedarticlename)) make_redirect(gndict[gnid].unfixedarticlename.Replace("*", ""), getartname(gnid), "", -1); //Console.WriteLine("<ret>"); //Console.ReadLine(); } public static void countryspecials(Page p,int gnid,string catcode) { if (makecountry == "AQ") //specials for Antarctica: { p.SetTemplateParameter("geobox", "timezone", "", true); p.SetTemplateParameter("geobox", "timezone_label", "", true); p.SetTemplateParameter("geobox", "utc_offset", "", true); p.SetTemplateParameter("geobox", "timezone_DST", "", true); p.SetTemplateParameter("geobox", "utc_offset_DST", "", true); string sectortext = antarctic_sector(gndict[gnid].longitude); if (makelang == "sv") { p.text = p.text.Replace("Trakten är glest befolkad. Det finns inga samhällen i närheten.", "Trakten är obefolkad. Det finns inga samhällen i närheten."); p.text = p.text.Replace("delen av landet.", "delen av kontinenten. " + sectortext); p.text = p.text.Replace(" Närmaste större samhälle ", " Närmaste befolkade plats "); p.text = p.text.Replace("den östra delen av kontinenten", "[[Östantarktis]]"); p.text = p.text.Replace("den västra delen av kontinenten", "[[Västantarktis]]"); p.text = p.text.Replace("den norra delen av kontinenten", "[[Sydshetlandsöarna]]"); p.text = p.text.Replace("den södra delen av kontinenten", "[[Sydorkneyöarna]]"); if (p.text.Contains("[[Östantarktis]]")) p.AddToCategory(make_catname(catcode, "Östantarktis", false)); if (p.text.Contains("[[Västantarktis]]")) p.AddToCategory(make_catname(catcode, "Västantarktis", false)); if (p.text.Contains("[[Sydshetlandsöarna]]")) p.AddToCategory("Sydshetlandsöarna"); if (p.text.Contains("[[Sydorkneyöarna]]")) p.AddToCategory("Sydorkneyöarna"); if (p.text.Contains("[[Norge]]")) p.AddToCategory("Norges anspråk i Antarktis"); if (p.text.Contains("[[Storbritannien]]")) p.AddToCategory("Storbritanniens anspråk i Antarktis"); if (p.text.Contains("[[Chile]]")) p.AddToCategory("Chiles anspråk i Antarktis"); if (p.text.Contains("[[Argentina]]")) p.AddToCategory("Argentinas anspråk i Antarktis"); if (p.text.Contains("[[Frankrike]]")) p.AddToCategory("Frankrikes anspråk i Antarktis"); if (p.text.Contains("[[Australien]]")) p.AddToCategory("Australiens anspråk i Antarktis"); if (p.text.Contains("[[Nya Zeeland]]")) p.AddToCategory("Nya Zeelands anspråk i Antarktis"); if (p.text.Contains("Kategori:Landformer på havets botten") || p.text.Contains("Kategori:Antarktis ö")) { p.text = p.text.Replace("Den ligger i ", "Den ligger i havet utanför "); p.text = p.text.Replace("Det ligger i ", "Det ligger i havet utanför "); } p.SetTemplateParameter("geobox", "country_type", "Kontinent", true); } else if (makelang == "ceb") { p.text = p.text.Replace("bahin sa nasod.", "bahin sa kontinente. " + sectortext); p.SetTemplateParameter("geobox", "country_type", "Kontinente", true); } } } public static string enumeration(List<string> namelist) { int n = namelist.Count; if (n == 0) return ""; else if (n == 1) return namelist[0]; else { string rs = ""; foreach (string name in namelist) { if (n == 1) rs += mp(97, null)+" "; else if (n < namelist.Count) rs += ", "; rs += name; n--; } return rs; } } public static string antarctic_sector(double lon) { List<string> claims = new List<string>(); if ((lon <= -150) || (lon >= 160)) claims.Add("NZ"); if ((lon <= -25) && (lon >= -74)) claims.Add("AR"); if ((lon >= 142 ) && (lon <= 160)) claims.Add("AU"); if ((lon >= 45) && (lon <= 136)) claims.Add("AU"); if ((lon >= 136) && (lon <= 142)) claims.Add("FR"); if ((lon >= -20) && (lon <= 45)) claims.Add("NO"); if ((lon <= -28) && (lon >= -53)) claims.Add("BR"); if ((lon <= -53) && (lon >= -90)) claims.Add("CL"); if ((lon <= -20) && (lon >= -80)) claims.Add("GB"); List<string> claimnames = new List<string>(); foreach (string cc in claims) { string countrynameml = countrydict[countryid[cc]].Name; if (countryml.ContainsKey(countrynameml)) countrynameml = countryml[countrynameml]; claimnames.Add("[["+countrynameml+"]]"); } string[] p210 = new string[1] {mp(211,null)}; if (claimnames.Count > 0) p210[0] = enumeration(claimnames); return mp(210, p210); } public static void fix_sizecats() { int icountry = countryid[makecountry]; string countrynameml = countrydict[icountry].Name; if (countryml.ContainsKey(countrynameml)) countrynameml = countryml[countrynameml]; string towncat = make_catname("populated places", countrynameml, true); PageList pl = new PageList(makesite); PageList pl1 = new PageList(makesite); pl.FillFromCategoryTree(towncat); foreach (Page p in pl) { tryload(p, 2); string origtext = p.text; double areaout = -1; long popout = -1; int heightout = -1; get_page_area_pop_height(p, out areaout, out popout, out heightout); double dpop = popout; cat_by_size(p, "populated places", countrynameml, dpop, false); if (origtext != p.text) { trysave(p, 2); //Console.WriteLine("<ret>"); //Console.ReadLine(); } } } public static void fix_sizecats2() { int icountry = countryid[makecountry]; string countrynameml = countrydict[icountry].Name; if (countryml.ContainsKey(countrynameml)) countrynameml = countryml[countrynameml]; string towncat = make_catname("populated places", countrynameml, true); string tcbad1 = "Orter i "+countrynameml+" större än 100 kvadratkilometer"; string tcbad2 = "Orter i "+countrynameml+" större än 1000 kvadratkilometer"; PageList pl = new PageList(makesite); PageList pl1 = new PageList(makesite); pl.FillFromCategoryTree(towncat); foreach (Page p in pl) { tryload(p, 2); string origtext = p.text; double areaout = -1; long popout = -1; int heightout = -1; get_page_area_pop_height(p, out areaout, out popout, out heightout); p.RemoveFromCategory(tcbad1); p.RemoveFromCategory(tcbad2); double dpop = popout; cat_by_size(p, "populated places", countrynameml, dpop, false); if (origtext != p.text) { trysave(p, 2); //Console.WriteLine("<ret>"); //Console.ReadLine(); } } } public static string oldsizecat(Page p, string catcode, string countrynameml, double size, bool is_area) { double[] heightsize = { 200.0, 500.0, 1000.0, 2000.0, 4000.0, 6000.0 }; int sizecat = -1; double catsize = -1; int imax = heightsize.Length; for (int i = 0; i < imax; i++) { if (size >= heightsize[i]) { sizecat = i; catsize = heightsize[i]; } } if (sizecat < 0) return ""; //Console.WriteLine("catcode = " + catcode); string[] p176 = { categoryml[catcode], countrynameml, catsize.ToString("F0", nfi) }; string catname = ""; int imp = 177; catname = initialcap(mp(imp, p176)); return catname; } public static string tostringsize(double size) { if ( size > 9000.0 ) return size.ToString("N0", nfi_space); else return size.ToString("F0", nfi); } public static void cat_by_size(Page p, string catcode, string countrynameml, double size, bool is_area) { double[] areasize = { 1.0, 2.0, 5.0, 10.0, 100.0, 1000.0 }; //double[] heightsize = { 200.0, 500.0, 1000.0, 2000.0, 4000.0, 6000.0 }; double[] heightsize = { 200.0, 500.0, 1000.0, 2000.0, 3000.0, 4000.0, 5000.0, 6000.0, 7000.0, 8000.0 }; double[] popsize = { 3000.0, 10000.0, 30000.0, 100000.0, 300000.0, 1000000.0 }; //Console.WriteLine("popsize[5].ToString() "+popsize[5].ToString()); //Console.WriteLine("popsize[5].ToString(nfi) " + popsize[5].ToString(nfi)); //Console.WriteLine("popsize[5].ToString(F0,nfi) " + popsize[5].ToString("F0",nfi)); //Console.WriteLine("popsize[5].ToString(F0,nfi_en) " + popsize[5].ToString("F0", nfi_en)); //Console.WriteLine("popsize[5].ToString(N0,nfi) " + popsize[5].ToString("N0", nfi)); //Console.WriteLine("popsize[5].ToString(N0,nfi_space) " + popsize[5].ToString("N0", nfi_space)); //Console.WriteLine("popsize[0].ToString(N0,nfi_space) " + popsize[0].ToString("N0", nfi_space)); //Console.ReadLine(); int sizecat = -1; double catsize = -1; int imax = popsize.Length; if (is_area) imax = areasize.Length; else if (catcode == "mountains") imax = heightsize.Length; for (int i = 0; i < imax; i++) { if (is_area) { if (size > areasize[i]) { sizecat = i; catsize = areasize[i]; } } else if (catcode == "mountains") { if (size >= heightsize[i]) { sizecat = i; catsize = heightsize[i]; } } else { if (size >= popsize[i]) { sizecat = i; catsize = popsize[i]; } } } if ( sizecat < 0 ) return; string[] p176 = { categoryml[catcode], countrynameml, tostringsize(catsize) }; string catname = ""; int imp = 217; if (is_area) imp = 217; else if (catcode == "mountains") imp = 218; else imp = 216; catname = initialcap(mp(imp,p176)); p.AddToCategory(catname); catname = mp(1, null) + catname; while (sizecat >= 0) { Page pcat = new Page(makesite, catname); tryload(pcat, 1); if (pcat.Exists()) break; string incat = ""; if (sizecat > 0) { if (is_area) { p176[2] = tostringsize(areasize[sizecat - 1]); } else if (catcode == "mountains") { p176[2] = tostringsize(heightsize[sizecat - 1]); } else { p176[2] = tostringsize(popsize[sizecat - 1]); } incat = mp(imp, p176); } else incat = make_catname(catcode, countrynameml, true)+ "| "; incat = initialcap(incat); pcat.text = mp(120,null); pcat.AddToCategory(incat); string worldcat = catname.Replace(mp(75,null)+" "+countrynameml,"")+"|"+countrynameml; pcat.AddToCategory(worldcat); trysave(pcat, 2); catname = mp(1,null)+incat; sizecat--; } } public static void cat_by_size(Page p, string catcode, string countrynameml, double area) { cat_by_size(p, catcode, countrynameml, area, true); } public static void cat_by_size(Page p, string catcode, string countrynameml, int elevation) { double elev = elevation; cat_by_size(p, catcode, countrynameml, elev, false); } public static void make_articles() { makesite.defaultEditComment = mp(60, null) + " " + countryml[makecountryname]; if (pstats == null) { pstats = new Page(makesite, mp(13, null) + botname + "/Statistik"); pstats.Load(); } pstats.text += "\n\n== [[" + countryml[makecountryname] + "]] ==\n\n"; trysave(pstats, 1); string[] p295 = new string[]{countryml[makecountryname]}; Page pcat = new Page(makesite, mp(1, null) + mp(295, p295)); tryload(pcat, 1); if (!pcat.Exists()) { pcat.text = "[[" + mp(1, null) + mp(296, p295) + "]]"; trysave(pcat, 2); } if ( makecountry == "AQ" ) //Antarctica minimum_population = 5; else minimum_population = 100; 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 = "<references>"; refnamelist.Clear(); make_article(gnid); Console.WriteLine(iremain.ToString()+" remaining."); if (firstround && (iremain0 - iremain < 5)) { Console.WriteLine("<cr>"); Console.ReadLine(); } } Console.WriteLine(stats.GetStat()); if (pstats == null) { pstats = new Page(makesite, mp(13, null) + botname + "/Statistik"); pstats.Load(); } //pstats.text += "\n\n== [[" + countryml[makecountryname] + "]] ==\n\n"; pstats.text += stats.GetStat(); trysave(pstats, 1); stats.ClearStat(); } public static void make_specific_articles() { makesite.defaultEditComment = mp(60, null) + " " + countryml[makecountryname]; while (true) { Console.Write("Gnid: "); string gnidstring = Console.ReadLine(); reflist = "<references>"; refnamelist.Clear(); make_article(tryconvert(gnidstring)); //Console.WriteLine("<cr>"); //Console.ReadLine(); } } public static void remake_article_set() { Console.WriteLine("In remake_article_set"); PageList pl = new PageList(makesite); PageList pl1 = new PageList(makesite); //Find articles from a category //pl.FillAllFromCategoryTree("Geografi i Goiás"); //pl1.FillAllFromCategoryTree("Eufriesea"); //foreach (Page p in pl1) // pl.Add(p); //pl1.FillAllFromCategoryTree("Euglossa"); //foreach (Page p in pl1) // pl.Add(p); //pl1.FillAllFromCategoryTree("Eulaema"); //foreach (Page p in pl1) // pl.Add(p); //pl1.FillAllFromCategoryTree("Exaerete"); //foreach (Page p in pl1) // pl.Add(p); //pl.FillFromCategory("Robotskapade Finlandförgreningar"); //Find subcategories of a category //pl.FillSubsFromCategory("Svampars vetenskapliga namn"); //Find articles from all the links to an article, mostly useful on very small wikis //pl.FillFromLinksToPage("Användare:Lsjbot/Algoritmer"); //Find articles containing a specific string pl.FillFromSearchResults("insource:/, [A-Z][a-z]+språkiga Wikipedia(, | och )/", 4999); //pl.FillFromSearchResults("insource:\"http://www.itis.gov;http://\"", 4999); //Set specific article: //Page pp = new Page(site, "Citrontrogon");pl.Add(pp); //Skip all namespaces except articles: pl.RemoveNamespaces(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 100, 101 }); Console.WriteLine("In remake_article_set. Pl.Count = "+pl.Count()); foreach (Page p in pl) { tryload(p, 2); if (!p.Exists()) continue; if (!p.text.Contains("obotskapad")) continue; int gnid = get_gnid_from_article(p); if (!gndict.ContainsKey(gnid)) continue; if (human_touched(p,makesite)) continue; reflist = "<references>"; refnamelist.Clear(); make_article(gnid); } } public static int get_gnid_from_article(Page p) { foreach (string gs in p.GetTemplateParameter(mp(173, null), "gnid")) if (tryconvert(gs) > 0) return tryconvert(gs); return -1; } public static void verify_geonames() { int n = 0; int n1 = 0; int ngnid = 0; using (StreamWriter sw = new StreamWriter("gnvswiki_pop.txt")) { foreach (int gnid in gndict.Keys) { ngnid++; if ((gndict[gnid].population > 0) && (gndict[gnid].population_wd > 0)) { n1++; sw.WriteLine(gndict[gnid].Name + tabstring+ gndict[gnid].population_wd.ToString() + tabstring + gndict[gnid].population.ToString()); if ((n1 % 1000) == 0) Console.WriteLine("n1 = " + n1.ToString()); } } if ((n % 100000) == 0) Console.WriteLine("n = " + n.ToString()); } Console.WriteLine("n (pop) = " + n1.ToString()); n = 0; using (StreamWriter sw = new StreamWriter("gnvswiki_area.txt")) { foreach (double wdarea in areavsarea.Keys) { n++; sw.WriteLine(wdarea.ToString() + tabstring + areavsarea[wdarea].ToString()); } if ((n % 10000) == 0) Console.WriteLine("n = " + n.ToString()); } Console.WriteLine("n(area) = " + n.ToString()); n = 0; using (StreamWriter sw = new StreamWriter("gnvswiki_duplicates.txt")) { foreach (int wdid in wdgniddict.Keys) { if (wdgniddict[wdid] < 0) { n++; sw.WriteLine(wdid.ToString()+tabstring+(-wdgniddict[wdid]).ToString()); } } if ((n % 10000) == 0) Console.WriteLine("n = " + n.ToString()); } Console.WriteLine("n(duplicate) = " + n.ToString()); Console.WriteLine("nwdtot = " + nwdtot.ToString()); Console.WriteLine("ngnid = " + ngnid.ToString()); //verify_wd(); } public static int[,] get_hgt_array(string filename) { //Console.WriteLine("get_hgt_array: " + filename); int pixvalue = 0; int oldpix = 0; int mapsize = 1201; int[,] map = new int[mapsize, mapsize]; try { byte[] pixels = File.ReadAllBytes(filename); int x = 0; int y = 0; bool odd = true; //bool negative = false; foreach (byte b in pixels) { if (odd) { //if (b < 128) pixvalue = b; //else //{ // negative = true; // pixvalue = b - 128; //} odd = !odd; } else { //if ( b < 128 ) pixvalue = pixvalue * 256 + b; //else // pixvalue = -(pixvalue * 256 + b - 128); //if (negative) // pixvalue = -pixvalue; if (pixvalue > 32768) pixvalue = pixvalue - 65536; else if (pixvalue > 9000) pixvalue = oldpix; //Console.WriteLine(pixvalue); map[x, y] = pixvalue; oldpix = pixvalue; x++; if (x >= mapsize) { x = 0; y++; } odd = !odd; //negative = false; } } } catch (FileNotFoundException e) { Console.Error.WriteLine(e.Message); //Console.WriteLine("Not found!"); for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x, y] = 0; } return map; } public static string padint(int n, int len) { string s = n.ToString(); while (s.Length < len) s = "0" + s; return s; } public static string nexthgt(string filenamepar,string dir) { //Console.WriteLine("nexthgt: filename before = " + filenamepar); string filename = filenamepar; switch (dir) { case "north": if (filename.Contains("N")) { int lat = tryconvert(filename.Substring(1, 2)); lat++; filename = filename.Replace(filename.Substring(0, 3), "N" + padint(lat, 2)); } else //"S" { int lat = tryconvert(filename.Substring(1, 2)); if (lat > 1) { lat--; filename = filename.Replace(filename.Substring(0, 3), "S" + padint(lat, 2)); } else { filename = filename.Replace(filename.Substring(0, 3), "N00"); } } break; case "south": if (filename.Contains("S")) { int lat = tryconvert(filename.Substring(1, 2)); lat++; filename = filename.Replace(filename.Substring(0, 3), "S" + padint(lat, 2)); } else //"N" { int lat = tryconvert(filename.Substring(1, 2)); if (lat > 0) { lat--; filename = filename.Replace(filename.Substring(0, 3), "N" + padint(lat, 2)); } else { filename = filename.Replace(filename.Substring(0, 3), "S01"); } } break; case "east": if (filename.Contains("E")) { int lon = tryconvert(filename.Substring(4, 3)); lon++; if ( lon >= 180 ) filename = filename.Replace(filename.Substring(3, 4), "W180"); else filename = filename.Replace(filename.Substring(3, 4), "E" + padint(lon, 3)); } else //"W" { int lon = tryconvert(filename.Substring(4,3)); if (lon > 1) { lon--; filename = filename.Replace(filename.Substring(3, 4), "W" + padint(lon, 3)); } else { filename = filename.Replace(filename.Substring(3, 4), "E000"); } } break; case "west": if (filename.Contains("W")) { int lon = tryconvert(filename.Substring(4, 3)); lon++; if (lon > 180) filename = filename.Replace(filename.Substring(3, 4), "E179"); else filename = filename.Replace(filename.Substring(3, 4), "W" + padint(lon, 3)); } else //"E" { int lon = tryconvert(filename.Substring(4, 3)); if (lon > 0) { lon--; filename = filename.Replace(filename.Substring(3, 4), "E" + padint(lon, 3)); } else { filename = filename.Replace(filename.Substring(3, 4), "W001"); } } break; } //Console.WriteLine("nexthgt: filename after = " + filename); return filename; } public static string make_hgt_filename(double lat, double lon) { int intlat = Convert.ToInt32(Math.Abs(Math.Floor(lat))); int intlon = Convert.ToInt32(Math.Abs(Math.Floor(lon))); string filename = "N00E999.hgt"; if (lat < 0) filename = filename.Replace('N', 'S'); if (lon < 0) filename = filename.Replace('E', 'W'); filename = filename.Replace("00", padint(intlat, 2)); filename = filename.Replace("999", padint(intlon, 3)); return filename; } public static int[,] get_3x3map(double lat, double lon) { int mapsize = 1201; string dir = extractdir; string filename = make_hgt_filename(lat, lon); int[,] map; if (filename == mapfilecache) map = mapcache; else { mapfilecache = filename; map = new int[3 * mapsize, 3 * mapsize]; for (int x = 0; x < 3 * mapsize; x++) for (int y = 0; y < 3 * mapsize; y++) map[x, y] = 0; // ... // .x. // ... int[,] map0 = get_hgt_array(dir + filename); int xoff = mapsize; int yoff = mapsize; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; // ... // x.. // ... filename = nexthgt(filename, "west"); map0 = get_hgt_array(dir + filename); xoff = 0; yoff = mapsize; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; // x.. // ... // ... filename = nexthgt(filename, "north"); map0 = get_hgt_array(dir + filename); xoff = 0; yoff = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; // .x. // ... // ... filename = nexthgt(filename, "east"); map0 = get_hgt_array(dir + filename); xoff = mapsize; yoff = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; // ..x // ... // ... filename = nexthgt(filename, "east"); map0 = get_hgt_array(dir + filename); xoff = 2 * mapsize; yoff = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; // ... // ..x // ... filename = nexthgt(filename, "south"); map0 = get_hgt_array(dir + filename); xoff = 2 * mapsize; yoff = mapsize; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; // ... // ... // ..x filename = nexthgt(filename, "south"); map0 = get_hgt_array(dir + filename); xoff = 2 * mapsize; yoff = 2 * mapsize; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; // ... // ... // .x. filename = nexthgt(filename, "west"); map0 = get_hgt_array(dir + filename); xoff = mapsize; yoff = 2 * mapsize; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; // ... // ... // x.. filename = nexthgt(filename, "west"); map0 = get_hgt_array(dir + filename); xoff = 0; yoff = 2 * mapsize; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) map[x + xoff, y + yoff] = map0[x, y]; mapcache = map; } return map; } public static int get_x_pixel(double lon, double orilon) { double fraction = lon - Math.Floor(lon); int mapsize = 1201; int pix = Convert.ToInt32((Math.Floor(lon)-Math.Floor(orilon)+1)*mapsize + mapsize * fraction); return pix; } public static int get_y_pixel(double lat, double orilat) { double fraction = lat - Math.Floor(lat); int mapsize = 1201; int pix = 3*mapsize - Convert.ToInt32((Math.Floor(lat) - Math.Floor(orilat) + 1) * mapsize + mapsize * fraction); return pix; } public static long seed_center_dist(int gnid) //verify island by calculating distance between seed point and center of gravity { double lat = gndict[gnid].latitude; double lon = gndict[gnid].longitude; double scale = Math.Cos(lat * 3.1416 / 180); double pixkmx = scale * 40000 / (360 * 1200); double pixkmy = 40000.0 / (360.0 * 1200.0); Console.WriteLine("scale,pixkmx,pixkmy = " + scale.ToString() + "; " + pixkmx.ToString() + "; " + pixkmy.ToString()); int[,] mainmap = get_3x3map(lat, lon); int mapsize = mainmap.GetLength(0); byte[,] fillmap = new byte[mapsize, mapsize]; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) fillmap[x, y] = 1; int x0 = get_x_pixel(lon, lon); int y0 = get_y_pixel(lat, lat); floodfill(ref fillmap, ref mainmap, x0, y0, 0, 0, false); if (fillmap[0, 0] == 3) //fill failure return 99999999; long xsum = 0; long ysum = 0; int nfill = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) if (fillmap[x, y] == 2) { nfill++; xsum += x; ysum += y; } if (nfill == 0) //fill failure return 99999999; long xc = xsum / nfill; long yc = ysum / nfill; return (x0 - xc) * (x0 - xc) + (y0 - yc) * (y0 - yc); } public static bool inmap(int x, int y, int size, int margin) { if (x < margin) return false; if (y < margin) return false; if (x > size - margin - 1) return false; if (y > size - margin - 1) return false; return true; } public static bool filldirland(ref byte[,] fillmap, ref int[,] mainmap, int xx, int yy, int dirx, int diry, ref int nnew, int level) { bool atedge = false; if ((fillmap[xx + dirx, yy + diry] == 1) && (mainmap[xx + dirx, yy + diry] > level)) { fillmap[xx + dirx, yy + diry] = 2; nnew++; int u = 2; while (inmap(xx + u * dirx, yy + u * diry, mainmap.GetLength(0), 2) && (mainmap[xx + u * dirx, yy + u * diry] > level)) { fillmap[xx + u * dirx, yy + u * diry] = 2; nnew++; u++; } if (!inmap(xx + u * dirx, yy + u * diry, mainmap.GetLength(0), 2)) atedge = true; } return atedge; } public static bool filldirlake(ref byte[,] fillmap, ref int[,] mainmap, int xx, int yy, int dirx, int diry, ref int nnew, int level) { bool atedge = false; if ((fillmap[xx + dirx, yy + diry] == 1) && (mainmap[xx + dirx, yy + diry] == level)) { fillmap[xx + dirx, yy + diry] = 2; nnew++; int u = 2; while (inmap(xx + u * dirx, yy + u * diry, mainmap.GetLength(0), 2) && (mainmap[xx + u * dirx, yy + u * diry] == level)) { fillmap[xx + u * dirx, yy + u * diry] = 2; nnew++; u++; } if (!inmap(xx + u * dirx, yy + u * diry, mainmap.GetLength(0), 2)) atedge = true; } return atedge; } public static void floodfill(ref byte[,] fillmap, ref int[,] mainmap, int x, int y, int level, int depth, bool exactlevel) { Console.WriteLine("flood " + x.ToString() + " " + y.ToString() + " " + mainmap[x, y].ToString() + " " + depth); if ((x < 0) || (x >= mainmap.GetLength(0))) { fillmap[0, 0] = 3; //bad fill Console.WriteLine("Invalid x"); return; } if ((y < 0) || (y >= mainmap.GetLength(1))) { fillmap[0, 0] = 3; //bad fill Console.WriteLine("Invalid y"); return; } if (fillmap[x, y] != 1) //1 = unchecked { Console.WriteLine("Starting point checked."); return; } bool atedge = false; if (exactlevel) //find all at same level { if (mainmap[x, y] == level) { fillmap[x, y] = 2; //2 = filled int nnew = 0; int nfill = 0; do { nnew = 0; nfill = 0; for (int xx = 1; xx < mainmap.GetLength(0) - 1; xx++) for (int yy = 1; yy < mainmap.GetLength(0) - 1; yy++) { if (fillmap[xx, yy] == 2) { nfill++; if (!inmap(xx, yy, mainmap.GetLength(0), 2)) atedge = true; if (!atedge) { atedge = atedge || filldirlake(ref fillmap, ref mainmap, xx, yy, 1, 0, ref nnew,level); atedge = atedge || filldirlake(ref fillmap, ref mainmap, xx, yy, -1, 0, ref nnew, level); atedge = atedge || filldirlake(ref fillmap, ref mainmap, xx, yy, 0, 1, ref nnew, level); atedge = atedge || filldirlake(ref fillmap, ref mainmap, xx, yy, 0, -1, ref nnew, level); } } } Console.WriteLine("nnew = " + nnew.ToString() + ", nfill = " + nfill.ToString()); } while ((nnew > 0) && (!atedge)); } else fillmap[x, y] = 0; //0 = checked but wrong level } else //find all ABOVE the given level { if (mainmap[x, y] > level) { fillmap[x, y] = 2; //floodfill(x - 1, y, level, depth + 1); //floodfill(x + 1, y, level, depth + 1); //floodfill(x, y - 1, level, depth + 1); //floodfill(x, y + 1, level, depth + 1); int nnew = 0; int nfill = 0; do { nnew = 0; nfill = 0; for (int xx = 1; xx < mainmap.GetLength(0) - 1; xx++) for (int yy = 1; yy < mainmap.GetLength(0) - 1; yy++) { if (fillmap[xx, yy] == 2) { nfill++; if (!inmap(xx, yy, mainmap.GetLength(0), 2)) atedge = true; if (!atedge) { atedge = atedge || filldirland(ref fillmap, ref mainmap, xx, yy, 1, 0, ref nnew, level); atedge = atedge || filldirland(ref fillmap, ref mainmap, xx, yy, -1, 0, ref nnew, level); atedge = atedge || filldirland(ref fillmap, ref mainmap, xx, yy, 0, 1, ref nnew, level); atedge = atedge || filldirland(ref fillmap, ref mainmap, xx, yy, 0, -1, ref nnew, level); } } } Console.WriteLine("nnew = " + nnew.ToString() + ", nfill = " + nfill.ToString()); } while ((nnew > 0) && (!atedge)); } else fillmap[x, y] = 0; } if (atedge) fillmap[0, 0] = 3; } public static void make_lakes() //create lakes-XX file for a country { int nlake = 0; //int npop = 0; //int narea = 0; using (StreamWriter sw = new StreamWriter("lakes-" + 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)) continue; else resume_at = -1; if (categorydict[gndict[gnid].featurecode] == "lakes") { nlake++; double area = -1.0; double lat = gndict[gnid].latitude; double lon = gndict[gnid].longitude; double scale = Math.Cos(lat * 3.1416 / 180); double pixkmx = scale * 40000 / (360 * 1200); double pixkmy = 40000.0 / (360.0 * 1200.0); //Console.WriteLine("scale,pixkmx,pixkmy = " + scale.ToString() + "; " + pixkmx.ToString() + "; " + pixkmy.ToString()); int[,] mainmap = get_3x3map(lat, lon); int mapsize = mainmap.GetLength(0); byte[,] fillmap = new byte[mapsize, mapsize]; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) fillmap[x, y] = 1; int x0 = get_x_pixel(lon, lon); int y0 = get_y_pixel(lat, lat); floodfill(ref fillmap, ref mainmap, x0, y0, mainmap[x0,y0], 0, true); if (fillmap[0, 0] == 3) //fill failure continue; int xmax = -1; int ymax = -1; int xmin = 99999; int ymin = 99999; double r2max = -1; int nfill = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) if (fillmap[x, y] == 2) { nfill++; if (x > xmax) xmax = x; if (y > ymax) ymax = y; if (x < xmin) xmin = x; if (y < ymin) ymin = y; double r2 = scale * scale * (x - x0) * (x - x0) + (y - y0) * (y - y0); if (r2 > r2max) r2max = r2; } double kmew = (xmax - xmin + 1) * pixkmx; double kmns = (ymax - ymin + 1) * pixkmy; Console.WriteLine("nfill = " + nfill.ToString()); if (nfill == 0) continue; //area per pixel: double km2perpixel = pixkmx * pixkmy; area = nfill * km2perpixel; double rmax = Math.Sqrt(r2max) * pixkmy + 2; //r2max in pixels; rmax in km Console.WriteLine("r2max, rmax = " + r2max.ToString() + "; " + rmax.ToString()); List<int> nblist = getneighbors(gnid, rmax); List<int> inlake = new List<int>(); List<int> aroundlake = new List<int>(); foreach (int nb in nblist) //first find islands and stuff in lake { if ((categorydict[gndict[nb].featurecode] != "islands") && (categorydict[gndict[nb].featurecode] != "seabed")) continue; 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; if (fillmap[xnb, ynb] == 2) inlake.Add(nb); else { bool atedge = false; int u=0; while (( xnb+u < mapsize) && (fillmap[xnb+u,ynb] != 2 )) u++; if (xnb + u >= mapsize) atedge = true; else { u = 0; while ((xnb - u >= 0) && (fillmap[xnb - u, ynb] != 2)) u--; if (xnb - u < 0) atedge = true; else { u = 0; while ((ynb + u < mapsize) && (fillmap[xnb, ynb + u] != 2)) u++; if (ynb + u >= mapsize) atedge = true; else { u = 0; while ((ynb - u >= 0) && (fillmap[xnb, ynb - u] != 2)) u--; if (ynb - u < 0) atedge = true; } } } if (!atedge) inlake.Add(nb); } } int maxdist = 20; //count things up to maxdist pixels away from the lake as "around" the lake if (r2max < 300) //smaller zone "around" if lake is smaller maxdist = 10; if (r2max < 30) maxdist = 5; for (byte step = 3; step < maxdist + 3; step++) //start at 3, because base level at 2. { for (int x = 1; x < mapsize-1; x++) for (int y = 1; y < mapsize-1; y++) if (fillmap[x, y] == step-1) { for (int uu=-1; uu<=1;uu++) for (int vv = -1; vv <= 1; vv++) { if (fillmap[x + uu, y + vv] < 2) fillmap[x + uu, y + vv] = step; } } } foreach (int nb in nblist) //now things around the lake { if ((categorydict[gndict[nb].featurecode] == "islands") || (categorydict[gndict[nb].featurecode] == "seabed")) continue; 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; if (fillmap[xnb, ynb] > 2) aroundlake.Add(nb); } //fillmap.Dispose(); //Console.WriteLine("<ret>"); //Console.ReadLine(); Console.WriteLine(gndict[gnid].Name + "; " + area.ToString() + "; " + kmew.ToString() + "; " + kmns.ToString() + "; " + inlake.Count.ToString() + "; " + aroundlake.Count.ToString()); sw.Write(gnid.ToString() + tabstring + area.ToString() + tabstring + kmew.ToString() + tabstring + kmns.ToString() + tabstring + "in"); foreach (int il in inlake) { sw.Write(tabstring + il.ToString()); Console.WriteLine(gndict[il].Name + " in lake"); } sw.Write(tabstring + "around"); foreach (int al in aroundlake) { sw.Write(tabstring + al.ToString()); Console.WriteLine(gndict[al].Name + " around lake"); } sw.WriteLine(); //Console.ReadLine(); } } } } public static void check_islands() //create islands-XX file for a country { int nisl = 0; //int npop = 0; //int narea = 0; using (StreamWriter sw = new StreamWriter("islands-" + 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)) continue; else resume_at = -1; if (categorydict[gndict[gnid].featurecode] == "islands") { nisl++; double area = -1.0; double lat = gndict[gnid].latitude; double lon = gndict[gnid].longitude; double scale = Math.Cos(lat * 3.1416 / 180); double pixkmx = scale * 40000 / (360 * 1200); double pixkmy = 40000.0 / (360.0 * 1200.0); Console.WriteLine("scale,pixkmx,pixkmy = " + scale.ToString() + "; " + pixkmx.ToString() + "; " + pixkmy.ToString()); int[,] mainmap = get_3x3map(lat, lon); int mapsize = mainmap.GetLength(0); byte[,] fillmap = new byte[mapsize, mapsize]; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) fillmap[x, y] = 1; int x0 = get_x_pixel(lon, lon); int y0 = get_y_pixel(lat, lat); floodfill(ref fillmap, ref mainmap, x0, y0, 0, 0, false); if (fillmap[0, 0] == 3) //fill failure continue; int xmax = -1; int ymax = -1; int xmin = 99999; int ymin = 99999; double r2max = -1; int nfill = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) if (fillmap[x, y] == 2) { nfill++; if (x > xmax) xmax = x; if (y > ymax) ymax = y; if (x < xmin) xmin = x; if (y < ymin) ymin = y; double r2 = scale * scale * (x - x0) * (x - x0) + (y - y0) * (y - y0); if (r2 > r2max) r2max = r2; } double kmew = (xmax - xmin + 1) * pixkmx; double kmns = (ymax - ymin + 1) * pixkmy; Console.WriteLine("nfill = " + nfill.ToString()); if (nfill == 0) continue; double rmax = Math.Sqrt(r2max) * pixkmy; //r2max in pixels; rmax in km Console.WriteLine("r2max, rmax = " + r2max.ToString() + "; " + rmax.ToString()); List<int> nblist = getneighbors(gnid, rmax); List<int> onisland = new List<int>(); foreach (int nb in nblist) { 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; if (fillmap[xnb, ynb] == 2) onisland.Add(nb); } //area per pixel: double km2perpixel = pixkmx * pixkmy; area = nfill * km2perpixel; //fillmap.Dispose(); //Console.WriteLine("<ret>"); //Console.ReadLine(); Console.WriteLine(gndict[gnid].Name + "; " + area.ToString() + "; " + kmew.ToString() + "; " + kmns.ToString() + "; " + onisland.Count.ToString()); 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(); } } } } public static void make_ranges() //create ranges-XX file for a country { int nrange = 0; int nisland = 0; //int npop = 0; //int narea = 0; using (StreamWriter swname = new StreamWriter("rangenames-" + makecountry + ".txt")) using (StreamWriter sw = new StreamWriter("ranges-" + makecountry + ".txt")) { int ngnid = gndict.Count; foreach (int gnid in gndict.Keys) { if ((gndict[gnid].featurecode == "MTS") || (gndict[gnid].featurecode == "HLLS")) { nrange++; } else if (categorydict[gndict[gnid].featurecode] == "islands") { nisland++; } } if (nrange == 0) return; foreach (int gnid in gndict.Keys) { //if (gnid != 2700827) // continue; Console.WriteLine("=====" + makecountry + "======== " + ngnid.ToString() + " remaining. ==========="); ngnid--; if ((ngnid % 1000) == 0) { Console.WriteLine("Garbage collection:"); GC.Collect(); } if ((resume_at > 0) && (resume_at != gnid)) continue; else resume_at = -1; if ((gndict[gnid].featurecode == "MTS")||(gndict[gnid].featurecode == "HLLS")) { //nrange++; //double area = -1.0; double lat = gndict[gnid].latitude; double lon = gndict[gnid].longitude; double scale = Math.Cos(lat * 3.1416 / 180); double pixkmx = scale * 40000 / (360 * 1200); double pixkmy = 40000.0 / (360.0 * 1200.0); //Console.WriteLine("scale,pixkmx,pixkmy = " + scale.ToString() + "; " + pixkmx.ToString() + "; " + pixkmy.ToString()); int[,] mainmap = get_3x3map(lat, lon); int mapsize = mainmap.GetLength(0); byte[,] fillmap = new byte[mapsize, mapsize]; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) fillmap[x, y] = 1; int x0 = get_x_pixel(lon, lon); int y0 = get_y_pixel(lat, lat); long hsum = 0; int nh = 0; for (int x = 0; x < mapsize; x++) { for (int y = 0; y < mapsize; y++) { hsum += mainmap[x, y]; nh++; } } double kmew = -1; double kmns = -1; double maxlength = -1; List<int> inrange = new List<int>(); string rangedir = "...."; double angle = 999.9; int hmax = -1; double hlat = 999; double hlon = 999; int sealevel = 0; int h0 = mainmap[x0,y0]; if (h0 <= 0) //range below sea level continue; long haverage = hsum / nh; double levelfraction = -0.3; //suitable for mainland ranges if (nrange == 1) //countries with single range; don't count the whole country levelfraction = 0.2; if (haverage < 10) //likely lots of ocean around; start higher levelfraction = 0.2; double levelstep = 0.1; do { do { if (h0 > haverage) { sealevel = (int)(levelfraction * h0 + (1 - levelfraction) * haverage); } else { sealevel = Convert.ToInt32(h0 * levelfraction); } if (sealevel < 0) levelfraction += levelstep; } while (sealevel < 0); Console.WriteLine("Base altitude = " + sealevel.ToString()); floodfill(ref fillmap, ref mainmap, x0, y0, sealevel, 0, false); if (fillmap[0, 0] == 3) //fill failure { Console.WriteLine("Fill failure"); levelfraction += levelstep; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) fillmap[x, y] = 1; continue; } int xmax = -1; int ymax = -1; int xmin = 99999; int ymin = 99999; int xr2max = -1; int yr2max = -1; double r2max = -1; double l2max = -1; maxlength = -1; int nfill = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) if (fillmap[x, y] == 2) { nfill++; if (x > xmax) xmax = x; if (y > ymax) ymax = y; if (x < xmin) xmin = x; if (y < ymin) ymin = y; double r2 = scale * scale * (x - x0) * (x - x0) + (y - y0) * (y - y0); if (r2 > r2max) { r2max = r2; xr2max = x; yr2max = y; } } kmew = (xmax - xmin + 1) * pixkmx; kmns = (ymax - ymin + 1) * pixkmy; int xfar = 0; int yfar = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) if (fillmap[x, y] == 2) { double r2 = scale * scale * (x - xr2max) * (x - xr2max) + (y - yr2max) * (y - yr2max); if (r2 > l2max) { l2max = r2; xfar = x; yfar = y; } } if (l2max > 0) { maxlength = (Math.Sqrt(l2max) + 1) * pixkmy; double roundarea = maxlength*maxlength * Math.PI / 4; //area of circle with diameter maxlength double realarea = nfill * pixkmx * pixkmy; //actual area of range double fillfraction = realarea / roundarea; //smaller fillfraction = elongate shape //double one1200 = 1.0 / 1200.0; double dx = (xfar - xr2max)*scale; double dy = -(yfar - yr2max); //reverse sign because higher pixel number is lower latitude angle = Math.Atan2(dy, dx); //if (fillfraction < 0.5) //{ // if (Math.Abs(dx) > 2 * Math.Abs(dy)) // rangedir = "EW.."; // else if (Math.Abs(dy) > 2 * Math.Abs(dx)) // rangedir = "NS.."; // else if (dx * dy > 0) // rangedir = "SWNE"; // else // rangedir = "SENW"; //} } Console.WriteLine("Maxlength = " + maxlength.ToString()); Console.WriteLine("nfill = " + nfill.ToString()); if (nfill == 0) continue; double rmax = Math.Sqrt(r2max) * pixkmy; //r2max in pixels; rmax in km Console.WriteLine("r2max, rmax = " + r2max.ToString() + "; " + rmax.ToString()); List<int> nblist = getneighbors(gnid, rmax); inrange.Clear(); bool badrange = false; foreach (int nb in nblist) { if ((gndict[nb].featurecode == "MTS") || (gndict[nb].featurecode == "HLLS")) { badrange = true; Console.WriteLine("Range in range"); break; } if (!is_height(gndict[nb].featurecode)) continue; 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; if (fillmap[xnb, ynb] == 2) inrange.Add(nb); } if (badrange) { levelfraction += levelstep; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) fillmap[x, y] = 1; continue; } hmax = 0; int xhmax = 0; int yhmax = 0; for (int x = 0; x < mapsize; x++) for (int y = 0; y < mapsize; y++) { if (fillmap[x,y] == 2) if (mainmap[x, y] > hmax) { hmax = mainmap[x, y]; xhmax = x; yhmax = y; } } int hnbmax = 0; int nbmax = -1; foreach (int nb in inrange) { if (!is_height(gndict[nb].featurecode)) continue; if (gndict[nb].elevation > hnbmax) { hnbmax = gndict[nb].elevation; nbmax = nb; } int xnb = get_x_pixel(gndict[nb].longitude, lon); if (xnb == xhmax) { int ynb = get_y_pixel(gndict[nb].latitude, lat); if (ynb == yhmax) hmax = -nb; //negative to distinguish from heights } } if (hnbmax >= 0.9*hmax) hmax = -nbmax; if (hmax > 0) { double one1200 = 1.0 / 1200.0; //degrees per pixel double dlon = (xhmax - x0) * one1200; double dlat = -(yhmax - y0) * one1200; //reverse sign because higher pixel number is lower latitude hlat = lat + dlat; hlon = lon + dlon; } else if ( gndict.ContainsKey(-hmax)) { hlat = gndict[-hmax].latitude; hlon = gndict[-hmax].longitude; } break; } while (sealevel < h0); //area per pixel: //double km2perpixel = pixkmx * pixkmy; //area = nfill * km2perpixel; //fillmap.Dispose(); //Console.WriteLine("<ret>"); //Console.ReadLine(); if (sealevel < h0) { Console.WriteLine(gndict[gnid].Name + "; " + maxlength.ToString() + "; " + kmew.ToString() + "; " + kmns.ToString() + "; " + inrange.Count.ToString()); if (inrange.Count > 1) { sw.Write(gnid.ToString() + tabstring + maxlength.ToString() + tabstring + kmew.ToString() + tabstring + kmns.ToString() + tabstring + angle.ToString() + tabstring + hmax.ToString() + tabstring + hlat.ToString() + tabstring + hlon.ToString()); foreach (int oi in inrange) sw.Write(tabstring + oi.ToString()); sw.WriteLine(); swname.Write("* [["+gndict[gnid].Name_ml+"]]: " + maxlength.ToString("N1") + " km lång. Riktning: "+rangedir+ " Berg: "); foreach (int oi in inrange) swname.Write(", [[" + gndict[oi].Name_ml+"]]"); swname.WriteLine(); } } //if (gnid == 2700827) // Console.ReadLine(); } } } } public static int rdf_getentity(string wordpar,string prefix) { string word = wordpar.Replace("<http://www.wikidata.org/entity/", ""); word = word.Replace(prefix, "").Replace("c", ""); return tryconvert(word); } public static string get_in_quotes(string wordpar) { int i1 = wordpar.IndexOf('"'); if ((i1 < 0) || (i1 + 1 >= wordpar.Length)) return ""; int i2 = wordpar.IndexOf('"', i1 + 1); if (i2 < i1 + 2) return ""; return wordpar.Substring(i1 + 1, i2 - i1 - 1); } public static rdfclass rdf_parse(string line) { rdfclass rc = new rdfclass(); string[] words = line.Split('>'); if (words.Length < 3) //not a triplet return rc; int o1 = rdf_getentity(words[0],"Q"); if (o1 < 0) //triplet doesn't start with object id. { rc.objstring = words[0].Replace("<http://www.wikidata.org/entity/", ""); //Console.WriteLine("objstring = " + rc.objstring); } rc.obj = o1; int prop = rdf_getentity(words[1],"P"); if (prop > 0) rc.prop = prop; else { if (words[1].Contains("rdf-schema#")) { if (words[1].Contains("subClassOf")) rc.prop = 279; else Console.WriteLine(words[1]); } else if (words[1].Contains("ontology#")) { if (words[1].Contains("latitude")) rc.prop = 6250001; else if (words[1].Contains("longitude")) rc.prop = 6250002; } } //<http://www.wikidata.org/entity/Q7743> //<http://www.w3.org/2000/01/rdf-schema#subClassOf> //<http://www.w3.org/2002/07/owl#Class> . int o2 = rdf_getentity(words[2],"Q"); if (o2 > 0) rc.objlink = o2; else { rc.value = get_in_quotes(words[2]); if (String.IsNullOrEmpty(rc.value)) { if (words[2].Contains("wikidata.org")) rc.value = words[2].Replace("<http://www.wikidata.org/entity/", "").Trim(); } } return rc; } public static bool search_rdf_tree(int target,int wdid,int depth) { int maxdepth = 10; if (wdid == target) { Console.WriteLine("search_rdf_tree " + target.ToString() + ", " + wdid.ToString() + ", " + depth.ToString()); return true; } if (depth > maxdepth) return false; if (!wdtree.ContainsKey(wdid)) return false; foreach (int upl in wdtree[wdid].uplinks) if (search_rdf_tree(target, upl, depth + 1)) return true; return false; } public static void read_rdf_tree() { Console.WriteLine("read_rdf_tree"); using (StreamReader sr = new StreamReader("wikidata-taxonomy.nt")) { while (!sr.EndOfStream) { String line = sr.ReadLine(); rdfclass rc = rdf_parse(line); if (rc.obj < 0) continue; if (rc.prop != 279) continue; if (rc.objlink < 0) continue; if (!wdtree.ContainsKey(rc.obj)) { wdtreeclass wtc = new wdtreeclass(); wdtree.Add(rc.obj, wtc); } Console.WriteLine("Added " + rc.obj.ToString()); wdtree[rc.obj].uplinks.Add(rc.objlink); } } List<int> dummy = new List<int>(); foreach (int wdid in wdtree.Keys) dummy.Add(wdid); foreach (int wdid in dummy) { foreach (int uplink in wdtree[wdid].uplinks) if (wdtree.ContainsKey(uplink)) wdtree[uplink].downlinks.Add(wdid); } //using (StreamWriter sw = new StreamWriter("wdtree.txt")) //{ // foreach (int wdid in wdtree.Keys) // { // sw.WriteLine(wdid.ToString()); // sw.Write("up"); // foreach (int uplink in wdtree[wdid].uplinks) // sw.Write(tabstring + uplink.ToString()); // sw.WriteLine(); // sw.Write("down"); // foreach (int downlink in wdtree[wdid].downlinks) // sw.Write(tabstring + downlink.ToString()); // sw.WriteLine(); // } //} Console.WriteLine("read_rdf_tree done"); } public static void test_article_coord() { while (true) { Console.Write("Page: "); string title = Console.ReadLine(); Page oldpage = new Page(makesite, title); tryload(oldpage, 1); if (oldpage.Exists()) { double[] latlong = get_article_coord(oldpage); Console.WriteLine(latlong[0].ToString() + "|" + latlong[1].ToString()); } } } public static void fill_catwd() { //populated places //public static Dictionary<string, string> catwdclass = new Dictionary<string, string>(); //from category to appropriate wd top class //public static Dictionary<string, List<string>> catwdinstance = new Dictionary<string, List<string>>(); //from category to list of appropriate wd instance_of catwdclass.Add("populated places", 486972); //"human settlement" catwdclass.Add("subdivision1", 56061);//administrative territorial entity catwdclass.Add("subdivision2", 1048835);//political territorial entity catwdclass.Add("subdivision3", 15916867);//administrative territorial entity of a single country catwdclass.Add("lakes", 23397); //lake catwdclass.Add("canals", 355304); //watercourse catwdclass.Add("streams", 355304); //watercourse catwdclass.Add("bays", 15324); //body of water catwdclass.Add("wetlands", 170321); //wetland catwdclass.Add("waterfalls", 34038); //waterfall catwdclass.Add("ice", 23392); //ice catwdclass.Add("default", 618123); //geographical object catwdclass.Add("landforms", 271669); //landform catwdclass.Add("plains", 160091); //plain catwdclass.Add("straits", 37901); //strait catwdclass.Add("military", 18691599); //military facility catwdclass.Add("coasts", 19817101); //coastal landform catwdclass.Add("aviation", 62447); //aerodrome catwdclass.Add("constructions", 811430); //construction catwdclass.Add("caves", 35509); //cave catwdclass.Add("islands", 23442); //island catwdclass.Add("mountains1", 8502); //mountains catwdclass.Add("mountains2", 1437459); //mountain system catwdclass.Add("hills", 8502); //mountains catwdclass.Add("volcanoes", 8502); //mountains catwdclass.Add("peninsulas", 271669); //landform catwdclass.Add("valleys", 271669); //landform catwdclass.Add("deserts", 271669); //landform catwdclass.Add("forests", 4421); //forest } public static void list_nativenames() { List<string> nativename_countries = new List<string>(); //countries with special iw treatment nativename_countries.Add("EE"); nativename_countries.Add("LT"); nativename_countries.Add("LV"); using (StreamWriter sw = new StreamWriter("nativenames-" + getdatestring() + ".txt")) { foreach (string nc in nativename_countries) { int icountry = countryid[nc]; string nwiki = countrydict[icountry].nativewiki; Console.WriteLine(nc + " " + nwiki); int nnames = 0; Dictionary<int, int> wddict = read_wd_dict(nc); foreach (int gnid in wddict.Keys) { int wdid = wddict[gnid]; string artname = ""; XmlDocument cx = get_wd_xml(wdid); if (cx != null) { Dictionary<string, string> rd = get_wd_sitelinks(cx); foreach (string wiki in rd.Keys) { string ssw = wiki.Replace("wiki", ""); if (ssw == nwiki) { artname = remove_disambig(rd[wiki]); } else if (ssw == makelang) { artname = ""; break; } } } if (!String.IsNullOrEmpty(artname)) { sw.WriteLine(gnid.ToString() + tabstring + artname); Console.WriteLine(gnid.ToString() + ", " + artname); nnames++; } } Console.WriteLine("nnames = " + nnames.ToString()); } } } public static void list_missing_adm1() { using (StreamWriter sw = new StreamWriter("missing-adm1-" + makecountry + getdatestring() + ".txt")) { foreach (int gnid in gndict.Keys) { if (gndict[gnid].featurecode == "ADM1") { if (!gndict[gnid].articlename.Contains("*")) { string country = ""; if (gndict.ContainsKey(gndict[gnid].adm[0])) country = gndict[gndict[gnid].adm[0]].Name_ml; sw.WriteLine(gnid.ToString() + tabstring + country + tabstring + gndict[gnid].Name_ml); Console.WriteLine(gnid.ToString() + tabstring + gndict[gnid].Name_ml); } } } } Console.WriteLine("Done"); Console.ReadLine(); } public static void set_folders() { Console.WriteLine(Environment.MachineName); if (Environment.MachineName == "HP2011") { geonamesfolder = @"C:\dotnwb3\Geonames\"; extractdir = @"O:\dotnwb3\extract\"; } else if (Environment.MachineName == "KOMPLETT2015") { geonamesfolder = @"D:\dotnwb3\Geonames\"; extractdir = @"D:\dotnwb3\extract\"; } else { geonamesfolder = @"C:\dotnwb3\Geonames\"; extractdir = @"C:\dotnwb3\extract\"; } Console.WriteLine(geonamesfolder); Console.WriteLine(extractdir); } public static void Main() { DateTime starttime = DateTime.Now; Console.Write("Password: "); password = Console.ReadLine(); set_folders(); makesite = new Site("https://" + makelang + ".wikipedia.org", botname, password); //wdsite = new Site("http://wikidata.org", botname, password); if (makearticles) { ensite = new Site("https://en.wikipedia.org", botname, password); cmsite = new Site("https://commons.wikimedia.org", botname, password); } //Wikidata login: get_webpage("https://www.wikidata.org/w/api.php?action=login&lgname=" + botname + "&lgpassword=" + password); makesite.defaultEditComment = mp(60, null); makesite.minorEditByDefault = false; if (makearticles || makefork) pausetime = 5; else pausetime = 7; stats.SetMilestone(10000, makesite); if (makelang == "sv") { culture = CultureInfo.CreateSpecificCulture("sv-SE"); nfi = culture.NumberFormat; nfi.NumberGroupSeparator = " "; //nfi_space = culture.NumberFormat.Copy(); nfi_space.NumberGroupSeparator = " "; } else { culture = CultureInfo.CreateSpecificCulture("en-US"); nfi = culture.NumberFormat; nfi_space = culture.NumberFormat; } nfi_en.NumberGroupSeparator = ""; if (makedoubles) { doubleprefix = mp(13, null) + botname; if (makelang == "sv") doubleprefix += "/Dubletter/"; else doubleprefix += "/Duplicates/"; } string[] makecountries = makecountry.Split(','); //string[] makecountrynames = makecountryname.Split(','); //string[] makecountrywikis = makecountrywiki.Split(','); //============================== // Read country-independent stuff: //============================== fill_propdict(); fill_catwd(); fill_cyrillic(); fill_donecountries(); read_languageiso(); read_featurecodes(); read_adm1(); read_adm2(); read_country_info(); if (saveadmlinks) read_adm(); read_locatorlist(); if (makearticles || testnasa || retrofitnasa) read_nasa(); //fix_positionmaps(); //get_lang_iw("ceb"); //get_country_iw("sv"); read_categories(); read_catstat(); int mclength = makecountries.Length; if (makecountry == "") mclength = 1; //============================== // Loop over countries: //============================== for (int icountry = 0; icountry < mclength; icountry++) { if (makecountry != "") { makecountry = makecountries[icountry]; makecountryname = countrydict[countryid[makecountry]].Name;//makecountrynames[icountry]; //makecountrywiki = makecountrywikis[icountry]; anomalyheadline = false; conflictheadline = false; } //============================== // Read country-dependent stuff: //============================== read_adm(); read_timezone(); if (!makefork && !checkdoubles && !forkduplicates) read_geonames(makecountry); if (makearticles && !makespecificarticles) //Set off wdid thread { resume_at_wdid = resume_at; ThreadStart ts_wdid = new ThreadStart(fill_wdid_buffer); Thread wdid_thread = new Thread(ts_wdid); wdid_thread.Start(); } else if (checkdoubles) { //countries with special treatment in getadmlabel read_geonames("MY"); read_geonames("GB"); read_geonames("RU"); read_existing_coord(); if (makelang == "sv") read_existing_adm1(); } if (makearticles || checkwikidata || makeislands || makelakes || makeranges || retrofitnasa) { if (firstround) read_geoboxes(); fill_kids_features(); if (!makeislands && !makelakes && !makeranges) { read_artname(); read_altnames(); fix_names(); } if ( manualcheck) list_missing_adm1(); } //============================== // Do stuff: //============================== if (makearticles) { if (makespecificarticles) make_specific_articles(); else if (remakearticleset) remake_article_set(); else make_articles(); } if (altnamesonly) { read_altnames(); read_artname(); add_nameforks(); list_nameforks(); } if (maketranslit) { read_altnames(); make_translit(); } if (checkdoubles) { read_altnames(); read_artname(); check_doubles(); } if (checkwikidata) //identify wd links from geonames check_wikidata(); if (verifywikidata) //doublecheck geonames links in wikidata verify_wd(); if (makeislands) check_islands(); if (makelakes) make_lakes(); if (makeranges) make_ranges(); if (verifygeonames) verify_geonames(); if (makealtitude) make_altitude_files(); if (makefork) { //read_altnames(); read_artname(); makeforkpages(); } if (forkduplicates) find_duplicate_forks(); if (listnative) list_nativenames(); if (fixsizecats) fix_sizecats2(); if (testnasa) test_nasa(); if (retrofitnasa) retrofit_nasa(); //if ( worldmaponly ) // makeworldmap(); if (statisticsonly) { fchist.PrintSHist(); Console.WriteLine("=================================Print bad"); fcbad.PrintSHist(); //Console.WriteLine("=================================Print large"); //fchist.PrintLarge(1000); evarhist.SetBins(0.0, 500000.0, 10); slope1hist.SetBins(0.0, 30.0, 30); slope5hist.SetBins(0.0, 30.0, 30); slope5hist.SetBins(0.0, 50.0, 50); slopermshist.SetBins(0.0, 50.0, 50); elevdiffhist.SetBins(-500.0, 500.0, 100); foreach (int gnid in gndict.Keys) { string tt = get_terrain_type(gnid,10); string ttext = terrain_text(tt, gnid); Console.WriteLine(ttext); terraintexthist.Add(ttext.Replace(gndict[gnid].Name_ml,"XXX")); } Console.WriteLine("gndict: "+gndict.Count.ToString()); evarhist.PrintDHist(); Console.WriteLine("Slope1:"); slope1hist.PrintDHist(); Console.WriteLine("Slope5:"); slope5hist.PrintDHist(); Console.WriteLine("Slope/RMS:"); slopermshist.PrintDHist(); ndirhist.PrintIHist(); nsameterrhist.PrintIHist(); terrainhist.PrintSHist(); terraintexthist.PrintSHist(); //fclasshist.PrintSHist(); //fcathist.PrintSHist(); //elevdiffhist.PrintDHist(); //foreach (int gnid in gndict.Keys) //{ // get_overrep(gnid,10.0); //} //foverrephist.PrintSHist(); } firstround = false; gndict.Clear(); ghostdict.Clear(); wdid_buffer.Clear(); } if (resume_at > 0) Console.WriteLine("Never reached resume_at"); DateTime endtime = DateTime.Now; Console.WriteLine("starttime = " + starttime.ToString()); Console.WriteLine("endtime = " + endtime.ToString()); } }