Пример #1
0
    public static IEnumerator ParseAsync <T>(StreamReader sr, string filename, ParseTask task, PatchDataLoadedCallback <T> callback) where T : PatchData
    {
        if (parseThread == null)
        {
            taskData = new ParseTaskData();

            parseThread = new Thread(ParseThread)
            {
                Name     = "ParseThread",
                Priority = ThreadPriority.Highest,
            };
            parseThread.Start();
        }

        lock (_lock)
        {
            taskData.sr       = sr;
            taskData.filename = filename;
            taskData.task     = task;

            blockParser = false;
            Monitor.Pulse(_lock);
        }

        while (!blockParser)
        {
            yield return(IEnumeratorExtensions.AvoidRunThru);
        }

        callback(taskData.patch as T);

        // Clear task data
        taskData.Clear();
    }
Пример #2
0
 public static void StopParsingThread()
 {
     if (parseThread != null)
     {
         lock (_lock)
         {
             taskData    = null;
             blockParser = false;
             Monitor.Pulse(_lock);
         }
     }
 }
Пример #3
0
    private static void ParseCsv(ParseTaskData data)
    {
        GraphData graph = new GraphData();

        graph.cellSizeX = double.MaxValue;
        graph.cellSizeY = double.MaxValue;
        graph.west      = GeoCalculator.MaxLongitude;
        graph.east      = GeoCalculator.MinLongitude;
        graph.north     = GeoCalculator.MinLongitude;
        graph.south     = GeoCalculator.MaxLongitude;

        Dictionary <int, GraphNode> nodes = new Dictionary <int, GraphNode>();
        var highwaySet  = new HashSet <int>();
        var highwayList = new List <int>();
        var cultureInfo = CultureInfo.InvariantCulture;

        // Read/skip header
        data.sr.ReadLine();

        // Read each data row at a time
        string line;

        while ((line = data.sr.ReadLine()) != null)
        {
            string[] cells = line.Split(',');

            int sourceId = int.Parse(cells[1]);
            int targetId = int.Parse(cells[2]);

            if (sourceId == targetId)
            {
                continue;
            }

            int classification = int.Parse(cells[7]);

            float  distance = float.Parse(cells[0], cultureInfo);
            double x1       = double.Parse(cells[3], cultureInfo);
            double y1       = double.Parse(cells[4], cultureInfo);
            double x2       = double.Parse(cells[5], cultureInfo);
            double y2       = double.Parse(cells[6], cultureInfo);

            if (classification >= ClassificationValue.Highway)
            {
                // Use a negative sourceId & targetId to indicate another layer
                AddLink(graph, nodes, -sourceId, -targetId, x1, y1, x2, y2, distance, ClassificationValue.Highway);
                classification -= ClassificationValue.Highway;
            }

            if (classification > 0)
            {
                AddLink(graph, nodes, sourceId, targetId, x1, y1, x2, y2, distance, classification);
            }
        }

        AddHalfSizeToGraph(graph);

        // Once the graph is fully loaded, each node's index will be updated
        graph.indexToNode.Clear();

        double kX     = 1.0 / graph.cellSizeX;
        double kY     = 1.0 / graph.cellSizeY;
        int    countX = (int)Math.Round((graph.east - graph.west) * kX);

        for (int i = graph.nodes.Count - 1; i >= 0; i--)
        {
            var node  = graph.nodes[i];
            int index = (int)((node.longitude - graph.west) * kX) + countX * (int)((graph.north - node.latitude) * kY);

            // Highway and other road are on the different layer, they could be overlapped
            if (node.classifications == ClassificationValue.Highway)  // 16
            {
                if (!highwaySet.Contains(index))
                {
                    highwaySet.Add(index);
                    highwayList.Add(index);
                }
                index = -index;
            }

            if (!graph.indexToNode.ContainsKey(index))
            {
                graph.indexToNode.Add(index, node);
            }

            node.index = index;
        }

        // Connect Highways to the other roads with 'HighwayLink' links
        foreach (var idx in highwayList)
        {
            // Does it have both Highway and HighwayLink?
            if (graph.indexToNode.TryGetValue(idx, out GraphNode linkNode) &&
                linkNode.classifications >= ClassificationValue.HighwayLink)
            {
                // Connect highwayNode to linkNode's neighbours (only if the links are HighwayLink)
                var highwayNode = graph.indexToNode[-idx];
                for (int i = linkNode.links.Count - 1; i >= 0; --i)
                {
                    if (linkNode.linkClassifications[i] == ClassificationValue.HighwayLink)
                    {
                        GraphNode.AddLink(highwayNode, linkNode.links[i], linkNode.linkDistances[i], ClassificationValue.HighwayLink);
                        GraphNode.RemoveLink(linkNode, linkNode.links[i], ClassificationValue.HighwayLink);
                    }
                }

                if (linkNode.links.Count > 0)
                {
                    // Remove the 'HighwayLink' classification from the linkNode
                    linkNode.classifications &= ~ClassificationValue.HighwayLink;
                }
                else
                {
                    // Remove the linkNode if all of its links were removed
                    graph.nodes.Remove(linkNode);
                    graph.indexToNode.Remove(idx);
                }
            }
        }

        RemoveExtraLongLinks(graph);

        var grid = new GridData();

        graph.InitGrid(grid);
        graph.CreateDefaultGrid(grid);

        data.patch = graph;
    }
Пример #4
0
    private static void ParseCsv(ParseTaskData data)
    {
        GridDataIO.Parameter parameter = null;
        bool[] found = new bool[GridDataIO.Parameters.Length];

        string line = null;

        string[] cells        = null;
        bool     skipLineRead = false;

        GridData grid = new GridData();

        MultiGridData multigrid = null;

        while (true)
        {
            if (!skipLineRead)
            {
                line = data.sr.ReadLine();
            }
            else
            {
                skipLineRead = false;
            }

            if (line == null)
            {
                break;
            }

            cells     = line.Split(',');
            parameter = GridDataIO.CheckParameter(cells[0], cells[1], GridDataIO.Parameters, out bool hasData);

            if (parameter == null)
            {
#if UNITY_EDITOR
                Debug.LogWarning("File " + data.filename + " has unrecognized header parameter " + cells[0] + ". Should it go to the metadata?");
#endif
                if (grid.metadata != null)
                {
                    grid.metadata.Add(cells[0], cells[1]);
                }
                continue;
            }

#if UNITY_EDITOR
            if (found[(int)parameter.id])
            {
                Debug.LogWarning("File " + data.filename + " has duplicate metadata entry: " + parameter.label);
            }
#endif
            found[(int)parameter.id] = true;

            switch (parameter.id)
            {
            case GridDataIO.ParamId.Metadata:
                if (hasData)
                {
                    grid.metadata = PatchDataIO.ReadCsvMetadata(data.sr, GridDataIO.CsvTokens, ref line);
                    skipLineRead  = line != null;
                }
                break;

            //case GridDataIO.ParamId.NameToValue:
            //    if (hasData)
            //    {
            //		nameToValues = GridDataIO.ReadCsvNameToValues(sr, CsvTokens, ref line);
            //        skipLineRead = line != null;
            //    }
            //    break;
            case GridDataIO.ParamId.Categories:
                if (hasData)
                {
                    grid.categories = GridDataIO.ReadCsvCategories(data.sr, data.filename, GridDataIO.CsvTokens, ref line);
                    skipLineRead    = line != null;
                }
                break;

            case GridDataIO.ParamId.Coloring:
            case GridDataIO.ParamId.Colouring:
                try
                {
                    grid.coloring = (GridData.Coloring)Enum.Parse(typeof(GridData.Coloring), cells[1], true);
                }
                catch (Exception)
                {
                    grid.coloring = GridData.Coloring.Single;
                }
                break;

            case GridDataIO.ParamId.West:
                grid.west = double.Parse(cells[1], CultureInfo.InvariantCulture);
                break;

            case GridDataIO.ParamId.North:
                grid.north = double.Parse(cells[1], CultureInfo.InvariantCulture);
                if (grid.north > GeoCalculator.MaxLatitude)
                {
                    Debug.LogWarning("File " + data.filename + " has north above " + GeoCalculator.MaxLatitude + ": " + grid.north);
                }
                break;

            case GridDataIO.ParamId.East:
                grid.east = double.Parse(cells[1], CultureInfo.InvariantCulture);
                break;

            case GridDataIO.ParamId.South:
                grid.south = double.Parse(cells[1], CultureInfo.InvariantCulture);
                if (grid.south < GeoCalculator.MinLatitude)
                {
                    Debug.LogWarning("File " + data.filename + " has south below " + GeoCalculator.MinLatitude + ": " + grid.south);
                }
                break;

            case GridDataIO.ParamId.CountX:
                grid.countX = int.Parse(cells[1]);
                break;

            case GridDataIO.ParamId.CountY:
                grid.countY = int.Parse(cells[1]);
                break;

            case GridDataIO.ParamId.Units:
                grid.units = cells[1];
                break;

            case GridDataIO.ParamId.Values:
                multigrid = new MultiGridData(grid);
                ReadValues(data.sr, multigrid, data.filename);
                break;

            default:
#if UNITY_EDITOR
                Debug.Log("File " + data.filename + " will ignore row: " + line);
#endif
                skipLineRead = false;
                break;
            }
        }

#if UNITY_EDITOR
        foreach (var p in GridDataIO.Parameters)
        {
            if (p.isRequired && !found[(int)p.id])
            {
                Debug.LogError("Didn't find " + p.label + " in " + data.filename);
            }
        }
#endif

        data.patch = multigrid;
    }
Пример #5
0
    private static void ParseCsv(ParseTaskData data)
    {
        Parameter parameter = null;

        bool[] found = new bool[Parameters.Length];

        string line = null;

        string[] cells        = null;
        bool     skipLineRead = false;

        PointData pointData = new PointData();

        List <float> nameToValues = null;

        Color[] colors = null;

        while (true)
        {
            if (!skipLineRead)
            {
                line = data.sr.ReadLine();
            }
            else
            {
                skipLineRead = false;
            }

            if (line == null)
            {
                break;
            }

            cells     = line.Split(',');
            parameter = CheckParameter(cells[0], cells[1], Parameters, out bool hasData);

            if (parameter == null)
            {
#if UNITY_EDITOR
                Debug.LogWarning("File " + data.filename + " has unrecognized header parameter " + cells[0] + ". Should it go to the metadata?");
#endif
                if (pointData.metadata != null)
                {
                    pointData.metadata.Add(cells[0], cells[1]);
                }
                continue;
            }

#if UNITY_EDITOR
            if (found[(int)parameter.id])
            {
                Debug.LogWarning("File " + data.filename + " has duplicate metadata entry: " + parameter.label);
            }
#endif
            found[(int)parameter.id] = true;

            switch (parameter.id)
            {
            case ParamId.Metadata:
                if (hasData)
                {
                    pointData.metadata = PatchDataIO.ReadCsvMetadata(data.sr, CsvTokens, ref line);
                    skipLineRead       = line != null;
                }
                break;

            case ParamId.NameToValue:
                if (hasData)
                {
                    nameToValues = ReadCsvNameToValues(data.sr, CsvTokens, ref line);
                    skipLineRead = line != null;
                }
                break;

            case ParamId.Categories:
                if (hasData)
                {
                    pointData.categories = ReadCsvCategories(data.sr, data.filename, CsvTokens, ref line);
                    AssignCustomColors(pointData, ref colors);
                    skipLineRead = line != null;
                }
                break;

            case ParamId.Coloring:
            case ParamId.Colouring:
                try
                {
                    pointData.coloring = (PointData.Coloring)Enum.Parse(typeof(PointData.Coloring), cells[1], true);
                    AssignCustomColors(pointData, ref colors);
                }
                catch (Exception)
                {
                    pointData.coloring = PointData.Coloring.Single;
                }
                break;

            case ParamId.Colors:
            case ParamId.Colours:
                if (hasData)
                {
                    colors = ReadCsvColors(data.sr, CsvTokens, ref line);
                    AssignCustomColors(pointData, ref colors);
                    skipLineRead = line != null;
                }
                break;

            case ParamId.West:
                pointData.west = double.Parse(cells[1], CultureInfo.InvariantCulture);
                //if (pointData.west < GeoCalculator.MinLongitude)
                //    Debug.LogWarning("File " + data.filename + " has west below " + GeoCalculator.MinLongitude + ": " + pointData.west);
                break;

            case ParamId.North:
                pointData.north = double.Parse(cells[1], CultureInfo.InvariantCulture);
                if (pointData.north > GeoCalculator.MaxLatitude)
                {
                    Debug.LogWarning("File " + data.filename + " has north above " + GeoCalculator.MaxLatitude + ": " + pointData.north);
                }
                break;

            case ParamId.East:
                pointData.east = double.Parse(cells[1], CultureInfo.InvariantCulture);
                //if (pointData.east > GeoCalculator.MaxLongitude)
                //    Debug.LogWarning("File " + data.filename + " has east above " + GeoCalculator.MaxLongitude + ": " + pointData.east);
                break;

            case ParamId.South:
                pointData.south = double.Parse(cells[1], CultureInfo.InvariantCulture);
                if (pointData.south < GeoCalculator.MinLatitude)
                {
                    Debug.LogWarning("File " + data.filename + " has south below " + GeoCalculator.MinLatitude + ": " + pointData.south);
                }
                break;

            case ParamId.Count:
                pointData.count = int.Parse(cells[1]);
                break;

            case ParamId.Units:
                pointData.units = cells[1];
                break;

            case ParamId.Values:
                ReadValues(data.sr, data.filename, pointData, nameToValues);
                break;

            default:
#if UNITY_EDITOR
                Debug.Log("File " + data.filename + " will ignore row: " + line);
#endif
                skipLineRead = false;
                break;
            }
        }

#if UNITY_EDITOR
        foreach (var p in Parameters)
        {
            if (p.isRequired && !found[(int)p.id])
            {
                Debug.LogError("Didn't find '" + p.label + "' property in " + data.filename);
            }
        }
#endif

        if (pointData.IsCategorized)
        {
            pointData.RemapCategories(data.filename, false);
        }
        else
        {
            pointData.UpdateDistribution();
        }

        data.patch = pointData;
    }