private void SimplifyWays() { OSMRoadTypes[] rtArr = new OSMRoadTypes[ways.Count]; ways.Keys.CopyTo(rtArr, 0); foreach (var rt in rtArr) { foreach (Way way in ways[rt]) { var points = new List <Vector2>(); foreach (long pp in way.nodes) { points.Add(nodes[pp]); } List <Vector2> simplified = Douglas.DouglasPeuckerReduction(points, tolerance); if (simplified != null && simplified.Count > 1) { way.Update(fc.FitCurve(simplified.ToArray(), curveError)); } } var newList = new LinkedList <Way>(); foreach (var way in ways[rt]) { if (way.valid) { newList.AddLast(way); } ways[rt] = newList; } } }
public Way(List <long> points, RoadTypes rt, OSMRoadTypes osmrt, int layer, string name) { this.roadType = rt; this.nodes = points; this.layer = layer; this.name = name; this.osmRoadType = osmrt; }
public bool Mapped(osmWay way, ref List <long> points, ref RoadTypes rt, ref OSMRoadTypes osmrt, ref int layer) { if (way.tag == null || way.nd == null || way.nd.Count() < 2) { return(false); } rt = RoadTypes.None; bool oneWay = false; bool invert = false; var surface = ""; foreach (var tag in way.tag) { if (tag.k.Trim().ToLower() == "oneway") { oneWay = true; if (tag.v.Trim() == "-1") { invert = true; } } else if (tag.k.Trim().ToLower() == "bridge") { layer = Math.Max(layer, 1); } else if (tag.k.Trim().ToLower() == "layer") { int.TryParse(tag.v.Trim(), out layer); } else if (tag.k.Trim().ToLower() == "surface") { surface = tag.v.Trim().ToLower(); } else { var kvp = new KeyValuePair <string, string>(tag.k.Trim(), tag.v.Trim()); if (roadTypeMapping.ContainsKey(kvp)) { try { osmrt = (OSMRoadTypes)Enum.Parse(typeof(OSMRoadTypes), kvp.Value.Trim().ToLower()); } catch { osmrt = OSMRoadTypes.none; } rt = roadTypeMapping[kvp]; } } } if (oneWay) { rt = GetOneway(rt); } if (rt != RoadTypes.None) { if (surface != "") { rt = CheckSurface(rt, surface); } points = new List <long>(); if (invert) { for (var i = way.nd.Count() - 1; i >= 0; i -= 1) { points.Add(way.nd[i].@ref); } } else { foreach (var nd in way.nd) { points.Add(nd.@ref); } } return(true); } return(false); }
public IEnumerator MakeRoad(int p, OSMRoadTypes rt) { var nm = Singleton <NetManager> .instance; if (!nm.CheckLimits()) { yield return(null); } var way = osm.ways[rt].ElementAt(p); NetInfo ni = null; if (way.roadType == RoadTypes.None) { yield break; } if (netInfos.ContainsKey(way.roadType)) { ni = netInfos[way.roadType]; } else { Debug.Log("Failed to find net info: " + way.roadType.ToString()); yield return(null); } float elevation = way.layer; if (elevation < 0) { yield return(null); } else if (elevation > 0) { elevation *= 11f; var errors = default(ToolBase.ToolErrors); ni = ni.m_netAI.GetInfo(elevation, elevation, 5f, false, false, false, false, ref errors); } if (!osm.nodes.ContainsKey(way.StartNode) || !osm.nodes.ContainsKey(way.EndNode)) { yield return(null); } ushort startNode; if (nodeMap.ContainsKey(way.StartNode)) { startNode = nodeMap[way.StartNode]; AdjustElevation(startNode, elevation); } else { CreateNode(out startNode, ref rand, ni, osm.nodes[way.StartNode], elevation); AdjustElevation(startNode, elevation); nodeMap.Add(way.StartNode, startNode); } ushort endNode; if (nodeMap.ContainsKey(way.EndNode)) { endNode = nodeMap[way.EndNode]; AdjustElevation(endNode, elevation); } else { CreateNode(out endNode, ref rand, ni, osm.nodes[way.EndNode], elevation); AdjustElevation(endNode, elevation); nodeMap.Add(way.EndNode, endNode); } var currentStartNode = startNode; for (var i = 0; i < way.segments.Count(); i += 1) { var segment = way.segments[i]; ushort currentEndNode; if (i == way.segments.Count() - 1) { currentEndNode = endNode; } else { CreateNode(out currentEndNode, ref rand, ni, segment.endPoint, elevation); AdjustElevation(currentEndNode, elevation); } ushort segmentId; Vector3 position = nm.m_nodes.m_buffer[(int)currentStartNode].m_position; Vector3 position2 = nm.m_nodes.m_buffer[(int)currentEndNode].m_position; if (segment.controlA.x == 0f && segment.controlB.x == 0f) { // Vector3 vector = VectorUtils.NormalizeXZ(segment.endPoint - segment.startPoint); Vector3 vector = position2 - position; vector = VectorUtils.NormalizeXZ(vector); if (nm.CreateSegment(out segmentId, ref rand, ni, currentStartNode, currentEndNode, vector, -vector, Singleton <SimulationManager> .instance.m_currentBuildIndex, Singleton <SimulationManager> .instance.m_currentBuildIndex, false)) { Singleton <SimulationManager> .instance.m_currentBuildIndex += 2u; nm.SetSegmentNameImpl(segmentId, way.name); } } else { var control = new Vector3(segment.controlA.x, 0, segment.controlA.y); //control.y = Singleton<TerrainManager>.instance.SampleRawHeightSmooth(control); var control2 = new Vector3(segment.controlB.x, 0, segment.controlB.y); //control2.y = Singleton<TerrainManager>.instance.SampleRawHeightSmooth(control2); //Vector3 entry = VectorUtils.NormalizeXZ(Bezier3.Tangent(position, segment.controlA, segment.controlB, position2, 0f)); //Vector3 exit = VectorUtils.NormalizeXZ(Bezier3.Tangent(position, segment.controlA, segment.controlB, position2, 1f)); Vector3 entry = VectorUtils.NormalizeXZ(control - position); Vector3 exit = VectorUtils.NormalizeXZ(position2 - control2); if (nm.CreateSegment(out segmentId, ref rand, ni, currentStartNode, currentEndNode, entry, -exit, Singleton <SimulationManager> .instance.m_currentBuildIndex, Singleton <SimulationManager> .instance.m_currentBuildIndex, false)) { Singleton <SimulationManager> .instance.m_currentBuildIndex += 2u; nm.SetSegmentNameImpl(segmentId, way.name); } } currentStartNode = currentEndNode; } yield return(null); }
public void addEnabledRoadTypes(OSMRoadTypes rt) { enabledRoadTypes.Add(rt); }
public override void Update() { Boolean reachedTheEnd = false; if (createRoads && !pauseCreateRoads) { for (int i = 0; i < currentMakeSpeed; i++) { if (currentRoadTypeIndex < roadCheckbox.Count) { OSMRoadTypes rt = roadCheckbox.Keys.ElementAt(currentRoadTypeIndex); int way_count = roadMaker.osm.ways[rt].Count(); if (roadCheckbox[rt].text == CHECKBOX_CHECKED && way_count > 0 && currentIndex < way_count) { SimulationManager.instance.AddAction(roadMaker.MakeRoad(currentIndex, rt)); currentIndex++; var instance = Singleton <NetManager> .instance; makeErrorLabel.text = String.Format("RoadType {0} / {1}; {2} {3} / {4}. Nodes: {5}. Segments: {6}", currentRoadTypeIndex, roadMaker.osm.ways.Count(), rt.ToString(), currentIndex, way_count, instance.m_nodeCount, instance.m_segmentCount); } else { // end of current roadtype if (currentIndex > 0) { setCheckboxBuilt(roadCheckbox[rt], roadCheckboxLabel[rt]); } currentRoadTypeIndex++; currentIndex = 0; } } else { reachedTheEnd = true; i = currentMakeSpeed; // break; } } } if (reachedTheEnd) { var instance = Singleton <NetManager> .instance; int currentNodeCount = instance.m_nodeCount; String s = "You can still add different road-types."; if (currentNodeCount >= maxNodes) { s = "Engine limit reached! You cannot build any more roads!" + Environment.NewLine + "REMOVE A BUNCH OF ROADS TO MAKE THE MAP PLAYABLE!"; makeErrorLabel.textColor = COLOR_ERROR; } else { makeErrorLabel.textColor = COLOR_SUCCESS; } makeErrorLabel.text += Environment.NewLine + "Done. " + s; createRoads = false; reachedTheEnd = false; currentIndex = 0; currentRoadTypeIndex = 0; updateLimits(); } base.Update(); }
private void Init(osm osm) { mapping.InitBoundingBox(osm.bounds, scale); // get nodes from OSM nodes.Clear(); foreach (var node in osm.node) { if (!nodes.ContainsKey(node.id) && node.lat != 0 && node.lon != 0) { Vector2 pos = Vector2.zero; if (mapping.GetPos(node.lon, node.lat, ref pos)) { nodes.Add(node.id, pos); } } } // get ways from OSM ways.Clear(); roadTypeCount.Clear(); foreach (var way in osm.way) { RoadTypes rt = RoadTypes.None; List <long> points = null; int layer = 0; OSMRoadTypes osmrt = OSMRoadTypes.unclassified; string streetName = "noname"; if (way != null && way.tag != null) { foreach (var tag in way.tag) { if (tag != null) { if (tag.k.Trim().ToLower() == "name") { streetName = tag.v; } } } } if (mapping.Mapped(way, ref points, ref rt, ref osmrt, ref layer)) { if (roadTypeCount.ContainsKey(osmrt)) { roadTypeCount[osmrt] += points.Count; } else { roadTypeCount.Add(osmrt, points.Count); } var way_points = new List <long>(); for (var i = 0; i < points.Count; i += 1) { var pp = points[i]; if (nodes.ContainsKey(pp)) { way_points.Add(pp); } else { if (way_points.Count() > 1 || way_points.Contains(pp)) { if (!ways.ContainsKey(osmrt)) { ways.Add(osmrt, new LinkedList <Way>()); } Way w = new Way(way_points, rt, osmrt, layer, streetName); ways[osmrt].AddLast(w); allWays.Add(w); way_points = new List <long>(); } } } if (way_points.Count() > 1) { if (!ways.ContainsKey(osmrt)) { ways.Add(osmrt, new LinkedList <Way>()); } Way w = new Way(way_points, rt, osmrt, layer, streetName); ways[osmrt].AddLast(w); if (allWays.IndexOf(w) == -1) { allWays.Add(w); } } } } allWays = new List <Way>(); foreach (var rt in ways) { foreach (Way way in ways[rt.Key]) { if (allWays.IndexOf(way) == -1) { allWays.Add(way); } } } var intersections = new Dictionary <long, List <Way> >(); var allSplits = new Dictionary <Way, List <int> >(); foreach (var ww in allWays) { foreach (var pp in ww.nodes) { if (!intersections.ContainsKey(pp)) { intersections.Add(pp, new List <Way>()); } intersections[pp].Add(ww); } } foreach (var inter in intersections) { if (inter.Value.Count > 1) { foreach (var way in inter.Value) { if (!allSplits.ContainsKey(way)) { allSplits.Add(way, new List <int>()); } allSplits[way].Add(way.nodes.IndexOf(inter.Key)); } } } foreach (var waySplits in allSplits) { SplitWay(waySplits.Key, waySplits.Value); } BreakWaysWhichAreTooLong(); MergeWaysWhichAreTooShort(); SimplifyWays(); }