Extracting data from CSV file (fusion table and kml workaround)

前端 未结 3 1120
难免孤独
难免孤独 2021-01-17 23:04

In Xamarin google maps for Android using C# you can create polygons like so based on this tutorial:

    public void OnMapReady(GoogleMap googleMap)
    {
            


        
3条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-17 23:18

    If I understand correctly, the question is how to parse the above CSV file.

    Each line (except the first one with headers) can be represented with the following class:

    class MapEntry
    {
        public string Description { get; set; }
        public string Name { get; set; }
        public string Label { get; set; }
        public IEnumerable InnerCoordinates { get; set; }
        public IEnumerable OuterCoordinates { get; set; }
    }
    

    Note the Inner and Outer coordinates. They are represented inside the XML by outerBoundaryIs (required) and innerBoundaryIs (optional) elements.

    A side note: the Highland line in your post is incorrect - you seem to trimmed part of the line, leading to incorrect XML (...).

    Here is the code that does the parsing:

    static IEnumerable ParseMap(string csvFile)
    {
        return from line in File.ReadLines(csvFile).Skip(1)
               let tokens = line.Split(new[] { ',' }, 4)
               let xmlToken = tokens[3]
               let xmlText = xmlToken.Substring(1, xmlToken.Length - 2)
               let xmlRoot = XElement.Parse(xmlText)
               select new MapEntry
               {
                   Description = tokens[0],
                   Name = tokens[1],
                   Label = tokens[2],
                   InnerCoordinates = GetCoordinates(xmlRoot.Element("innerBoundaryIs")),
                   OuterCoordinates = GetCoordinates(xmlRoot.Element("outerBoundaryIs")),
               };
    }
    
    static IEnumerable GetCoordinates(XElement node)
    {
        if (node == null) return Enumerable.Empty();
        var element = node.Element("LinearRing").Element("coordinates");
        return from token in element.Value.Split(' ')
               let values = token.Split(',')
               select new LatLng(XmlConvert.ToDouble(values[0]), XmlConvert.ToDouble(values[1]));
    }
    

    I think the code is self explanatory. The only details to be mentioned are:

    let tokens = line.Split(new[] { ',' }, 4)
    

    Here we use the string.Split overload that allows us to specify the maximum number of substrings to return, thus avoiding the trap of processing the commas inside the XML token.

    and:

    let xmlText = xmlToken.Substring(1, xmlToken.Length - 2)
    

    which strips the quotes from the XML token.

    Finally, a sample usage for your case:

    foreach (var entry in ParseMap(csv_file_full_path))
    {
        PolylineOptions geometry = new PolylineOptions()
        foreach (var item in entry.OuterCoordinates)
            geometry.Add(item)
        Polyline polyline = mMap.AddPolyline(geometry);
    }
    

    UPDATE: To make Xamarin happy (as mentioned in the comments), replace the File.ReadLines call with a call to the following helper:

    static IEnumerable ReadLines(string path)
    {
        var sr = new StreamReader(Assets.Open(path));
        try
        {
            string line;
            while ((line = sr.ReadLine()) != null)
                yield return line; 
        }
        finally { sr.Dispose(); }
    }
    

提交回复
热议问题