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(); }
public static void StopParsingThread() { if (parseThread != null) { lock (_lock) { taskData = null; blockParser = false; Monitor.Pulse(_lock); } } }
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; }
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; }
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; }