Esempio n. 1
0
        static async Task Main(string[] args)
        {
            Console.WriteLine("All data generated by this script is contained in scripts/unitinfo.js");
            Console.Write("Enter URL of target XML (Leave empty if using the same URL as previous run): ");
            string serviceUrl     = Console.ReadLine();
            string executablePath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
            Dictionary <string, string> overrideTable = GetOverrideTable(ref serviceUrl, executablePath);

            if (serviceUrl.ToLower() == "amend")
            {
                await Amender.AmendUnitInfo(overrideTable, executablePath);

                Console.ReadLine();
                return;
            }
            Console.WriteLine("XML request sent");
            XDocument serviceRoot = await RequestServiceXml(serviceUrl);

            XNamespace xmlnsUrl = Regex.Match(serviceRoot.Document.Root.Name.ToString(),
                                              @"(?<={)(https?://[^}]*)(?=})").Value;

            Console.WriteLine("Parsing address");
            Tuple <int[], string[], Tuple <int, int> > resultList = ParseAddress(serviceRoot, xmlnsUrl,
                                                                                 overrideTable, executablePath);

            Console.WriteLine("Requesting for geospatial information");
            await BatchReq(resultList.Item1, resultList.Item2, serviceRoot,
                           xmlnsUrl, resultList.Item3, overrideTable, executablePath);

            Console.WriteLine("Executed getinfo succesfully");
            Console.ReadLine();
        }
Esempio n. 2
0
        // take in valid address list and perform API request
        private static async Task BatchReq(int[] parsedIndex, string[] parsedAddress, XDocument root,
                                           XNamespace xmlnsUrl, Tuple <int, int> ratio, Dictionary <string, string> overrideTable, string executablePath)
        {
            string lookupUrl = "https://www.als.ogcio.gov.hk/lookup?n=1&q=";

            // allocate full length longlat list
            XElement[]             unitList    = root.Descendants(xmlnsUrl + "serviceUnit").ToArray();
            Tuple <float, float>[] longlatList = new Tuple <float, float> [unitList.Length]
                                                 .Select(t => new Tuple <float, float>(0, -91)).ToArray();
            // encode and request multiple URL simultaneously
            IEnumerable <string> requestGen = parsedAddress.Select((s, i) =>
                                                                   lookupUrl + HttpUtility.UrlEncode(s) + "&i=" + parsedIndex[i]);
            StreamWriter overrideStream = new StreamWriter(executablePath + "/../override.csv", true, Encoding.UTF8);
            Pacer        estimatePacer  = new Pacer(parsedIndex.Length);

            Task <GeoInfo>[] taskResponse;
            for (int batchStart = 0; batchStart < parsedIndex.Length; batchStart += batchSize)
            {
                taskResponse = requestGen.Skip(batchStart).Take(batchSize)
                               .Select(s => GeoInfo.FromUrl(s, estimatePacer)).ToArray();
                await Task.WhenAll(taskResponse);

                estimatePacer.Stop();
                foreach (GeoInfo response in taskResponse.Select(t => t.Result))
                {
                    // check district correctness
                    int      unitIndex      = int.Parse(response.requestKey);
                    XElement targetUnit     = unitList[unitIndex];
                    string   parsedDistrict = targetUnit.Descendants(xmlnsUrl + "districtEnglish").First().Value;
                    parsedDistrict = parsedDistrict.ToUpper().Replace(" AND ", " & ");
                    string longlatDistrict = response.root.Descendants("DcDistrict").First().Value;
                    string name            = targetUnit.Descendants(xmlnsUrl + "nameTChinese").First().Value.ToUpper();
                    // append to override table if district test failed and no entry exists
                    if (!longlatDistrict.Contains(parsedDistrict) && !overrideTable.ContainsKey(name))
                    {
                        Console.WriteLine("District test failed for " + response.address);
                        string tcaddress = targetUnit.Descendants(xmlnsUrl + "addressTChinese").First().Value;
                        overrideStream.Write($"\n{name}\t[NO OVERRIDE]\t0\t0\t{tcaddress}");
                        ratio = new Tuple <int, int>(ratio.Item1 - 1, ratio.Item2 + 1);
                        continue;
                    }
                    longlatList[unitIndex] = response.longlat;
                }
            }
            Console.WriteLine($"Query ratio is {ratio.Item1}:{ratio.Item2}");
            overrideStream.Close();

            (Dictionary <string, Tuple <float, float> > longlatOverrideTable, _) = await Amender.RequestOverrideLonglat(overrideTable);

            Console.WriteLine("Applying override table");
            List <Dictionary <string, string> > unitDictList = new List <Dictionary <string, string> >();

            foreach (XElement unit in root.Descendants(xmlnsUrl + "serviceUnit"))
            {
                Dictionary <string, string> propDict = new Dictionary <string, string>();
                foreach (XElement prop in unit.Descendants())
                {
                    propDict.Add(prop.Name.LocalName, prop.Value);
                }
                unitDictList.Add(propDict);
            }
            for (int index = 0; index < unitDictList.Count; index++)
            {
                // define None for default address override
                unitDictList[index].Add("addressOverride", "");
                string nameKey = unitDictList[index]["nameTChinese"].ToUpper();
                if (longlatOverrideTable.ContainsKey(nameKey))
                {
                    longlatList[index] = longlatOverrideTable[nameKey];
                    unitDictList[index]["addressOverride"] = overrideTable[nameKey].Split('\t')[0];
                }
            }
            Amender.PatchUnitInfo(longlatList, unitDictList[0].Keys,
                                  unitDictList.Select(d => d.Values.ToArray()).ToArray(), executablePath);
        }