public _3DNode GetGeoCoordinatesForPosition(_2DNode position) { Vector toLocation = new Vector(0, position.Y, position.X); Vector extendedNodeVector = this.camera.Add(toLocation); Vector nodeVector = extendedNodeVector.Scale(1 / extendedNodeVector.GetLength()); return(Functions.VectorTo3DNode(nodeVector)); }
private void MapMouseUp(object sender, MouseEventArgs e) { Point mapCurrent2DLocation = new Point(this.pictureBox1.Left, this.pictureBox1.Top); if (e.Button.ToString().ToLower().Contains("left") && this.allowMovement) { Point locationDifference = new Point(mapCurrent2DLocation.X - mapPrevious2DLocation.X, mapCurrent2DLocation.Y - mapPrevious2DLocation.Y); _2DNode mapCenter = new _2DNode(-locationDifference.X, locationDifference.Y); this.renderCenter = this.renderer.GetGeoCoordinatesForPosition(mapCenter); this.latLngLabel.Text = string.Format("| Lat: {0} Lon: {1}", this.renderCenter.lat, this.renderCenter.lon); this.renderer = new Renderer(this.renderCenter, this.scale, this.coreCount); this.pictureBox1.Image = this.renderer.DrawMap(this.mapGraph, this.pens, this.Width * 3, this.Height * 3); this.pictureBox1.Location = new Point(-this.Width, -this.Height); this.mapPrevious2DLocation = mapCurrent2DLocation; } }
public Bitmap DrawMap(Graph mapGraph, Hashtable pens, int renderWidth, int renderHeight) { Graph.GraphNode[] nodes = mapGraph.GetNodes(); int nodesPerThread = (int)Math.Ceiling(nodes.Length / (double)threads); int activeThreads = threads; int renderedNodes = 0; ConcurrentQueue <Line> draw = new ConcurrentQueue <Line>(); Bitmap render = new Bitmap(renderWidth, renderHeight); Console.WriteLine("Drawing Map..."); for (int thread = 0; thread < threads; thread++) { int startNodeIndex = thread * nodesPerThread; int maxNodeIndex = (thread + 1) * nodesPerThread; new Thread(delegate() { for (; startNodeIndex < maxNodeIndex && startNodeIndex < nodes.Length; startNodeIndex++) { Graph.GraphNode node = nodes[startNodeIndex]; if (Functions.DistanceBetweenNodes(renderCenter, node) * scale < (renderHeight > renderWidth ? renderHeight : renderWidth)) { foreach (Graph.Connection connection in node.connections) { Pen pen = pens[connection.roadType] == null ? (Pen)pens["default"] : (Pen)pens[connection.roadType]; _2DNode _2dfrom = this.GetCoordinatesFromCenter(node.coordinates); _2DNode _2dto; foreach (_3DNode coord in connection.coordinates) { _2dto = this.GetCoordinatesFromCenter(coord); draw.Enqueue(new Line(pen, new _2DNode(_2dfrom.X + (renderWidth / 2), _2dfrom.Y + (renderHeight / 2)), new _2DNode(_2dto.X + (renderWidth / 2), _2dto.Y + (renderHeight / 2)))); _2dfrom = _2dto; } _2dto = this.GetCoordinatesFromCenter(connection.neighbor.coordinates); draw.Enqueue(new Line(pen, new _2DNode(_2dfrom.X + (renderWidth / 2), _2dfrom.Y + (renderHeight / 2)), new _2DNode(_2dto.X + (renderWidth / 2), _2dto.Y + (renderHeight / 2)))); } renderedNodes++; } } activeThreads--; }).Start(); } Console.WriteLine("Total Nodes: {0}", nodes.Length); using (Graphics g = Graphics.FromImage(render)) { while (activeThreads > 0 || draw.Count > 0) { if (draw.Count > 0) { Line line; while (!draw.TryDequeue(out line)) { ; } float halfPenWidth = line.pen.Width / 2; g.FillEllipse(new SolidBrush(line.pen.Color), line.from.X - halfPenWidth, line.from.Y - halfPenWidth, line.pen.Width, line.pen.Width); g.DrawLine(line.pen, line.from.X, line.from.Y, line.to.X, line.to.Y); g.FillEllipse(new SolidBrush(line.pen.Color), line.to.X - halfPenWidth, line.to.Y - halfPenWidth, line.pen.Width, line.pen.Width); } } Console.WriteLine(string.Format("Done :) Total/Rendered Nodes: {0}/{1}", nodes.Length, renderedNodes)); return(render); } }
public static void DrawTiles(string path, string newPath, int tileSize, int scale) { const byte UNKNOWN = 0, NODE = 1, WAY = 2, READINGNODES = 1, NODEREAD = 0; byte nodeType = UNKNOWN, state = NODEREAD; float minLat = float.MaxValue, maxLat = float.MinValue, minLon = float.MaxValue, maxLon = float.MinValue; XmlReaderSettings settings = new XmlReaderSettings() { IgnoreWhitespace = true }; Hashtable nodes = new Hashtable(); using (XmlReader reader = XmlReader.Create(path, settings)) { reader.MoveToContent(); while (reader.Read()) { if (reader.NodeType != XmlNodeType.EndElement && reader.Depth == 1 && reader.Name == "node") { ulong id = Convert.ToUInt64(reader.GetAttribute("id")); float lon = Convert.ToSingle(reader.GetAttribute("lon").Replace(".", ",")); float lat = Convert.ToSingle(reader.GetAttribute("lat").Replace(".", ",")); nodes.Add(id, new _3DNode(lat, lon)); minLat = minLat < lat ? minLat : lat; minLon = minLon < lon ? minLon : lon; maxLat = maxLat > lat ? maxLat : lat; maxLon = maxLon > lon ? maxLon : lon; } } } float latDiff = maxLat - minLat; float lonDiff = maxLon - minLon; _3DNode center = new _3DNode(minLat + latDiff / 2, minLon + lonDiff / 2); Renderer renderer = new Renderer(center, scale); _2DNode topLeft = renderer.GetCoordinatesFromCenter(new _3DNode(maxLat, minLon)); _2DNode bottomRight = renderer.GetCoordinatesFromCenter(new _3DNode(minLat, maxLon)); float xOffset = -topLeft.X; float yOffset = -topLeft.Y; double width = bottomRight.X + xOffset; double height = bottomRight.Y + yOffset; int yAmount = (int)Math.Ceiling(height / tileSize); int xAmount = (int)Math.Ceiling(width / tileSize); Console.WriteLine("Top-Left\tx,y: {0}, {1}", topLeft.X, topLeft.Y); Console.WriteLine("Bottom-Right\tx,y: {0}, {1}", bottomRight.X, bottomRight.Y); Console.WriteLine("Height: {0}px => {2} Tiles \tWidth: {1}px => {3} Tiles", height, width, yAmount, xAmount); List <Line>[,] grid = new List <Line> [xAmount, yAmount]; for (int x = 0; x < xAmount; x++) { for (int y = 0; y < yAmount; y++) { grid[x, y] = new List <Line>(); } } Hashtable pens = new Hashtable(); foreach (string type in File.ReadAllLines("roadRender.txt")) { if (!type.StartsWith("//")) { string key = type.Split(',')[0]; if (!pens.ContainsKey(key)) { pens.Add(key, new Pen(Color.FromName(type.Split(',')[2]), Convert.ToInt32(type.Split(',')[1]))); } } } using (XmlReader reader = XmlReader.Create(path, settings)) { List <ulong> currentNodes = new List <ulong>(); Dictionary <string, string> currentTags = new Dictionary <string, string>(); while (reader.Read()) { if (reader.NodeType != XmlNodeType.EndElement) { if (reader.Depth == 1) { if (state == READINGNODES && nodeType == WAY) { state = NODEREAD; if (currentTags.ContainsKey("highway")) { Pen pen = (Pen)pens[(string)currentTags["highway"]]; if (pen == null) { pen = (Pen)pens["default"]; } for (int i = 1; i < currentNodes.Count; i++) { _2DNode _2dfrom = renderer.GetCoordinatesFromCenter((_3DNode)nodes[currentNodes[i - 1]]); _2DNode _2dto = renderer.GetCoordinatesFromCenter((_3DNode)nodes[currentNodes[i]]); //Console.WriteLine("FROM X {0:0000000.00} + {1:0000000.00} => {2:0000000.00}\t\tY {3:0000000.00} + {4:0000000.00} => {5:0000000.00}", _2dfrom.X, xOffset, _2dfrom.X + xOffset, _2dfrom.Y, yOffset, _2dfrom.Y + yOffset); //Console.WriteLine("TO X {0:0000000.00} + {1:0000000.00} => {2:0000000.00}\t\tY {3:0000000.00} + {4:0000000.00} => {5:0000000.00}", _2dto.X, xOffset, _2dto.X + xOffset, _2dto.Y, yOffset, _2dto.Y + yOffset); int minX = _2dfrom.X < _2dto.X ? (int)Math.Floor((_2dfrom.X + xOffset) / tileSize) : (int)Math.Floor((_2dto.X + xOffset) / tileSize); int maxX = _2dfrom.X > _2dto.X ? (int)Math.Floor((_2dfrom.X + xOffset) / tileSize) : (int)Math.Floor((_2dto.X + xOffset) / tileSize); int minY = _2dfrom.Y < _2dto.Y ? (int)Math.Floor((_2dfrom.Y + yOffset) / tileSize) : (int)Math.Floor((_2dto.Y + yOffset) / tileSize); int maxY = _2dfrom.Y > _2dto.Y ? (int)Math.Floor((_2dfrom.Y + yOffset) / tileSize) : (int)Math.Floor((_2dto.Y + yOffset) / tileSize); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { if (x >= 0 && x < grid.GetLength(0) && y >= 0 && y < grid.GetLength(1)) { grid[x, y].Add(new Line(pen, _2dfrom, _2dto)); } } } } } /*else if (tags.ContainsKey("addr:housenumber") && !neededNodesIds.Contains(currentNodes[0])) * { * //Addresses? * }*/ /*foreach (string key in tags.Keys) * { * //Streetnames? * }*/ } switch (reader.Name) { case "node": nodeType = NODE; break; case "way": currentNodes.Clear(); currentTags.Clear(); nodeType = WAY; break; default: nodeType = UNKNOWN; break; } } else if (reader.Depth == 2 && nodeType == WAY) { state = READINGNODES; switch (reader.Name) { case "nd": currentNodes.Add(Convert.ToUInt64(reader.GetAttribute("ref"))); break; case "tag": currentTags.Add(reader.GetAttribute("k"), reader.GetAttribute("v")); break; } } } } } Directory.CreateDirectory(newPath); File.Copy(path, newPath + "map.osm", true); File.WriteAllLines(newPath + "information", new string[] { "scale:" + scale.ToString(), "minlat:" + minLat.ToString(), "maxlat:" + maxLat.ToString(), "minlon:" + minLon.ToString(), "maxlon:" + maxLon.ToString() }); for (int x = 0; x < xAmount; x++) { Directory.CreateDirectory(newPath + "\\" + x); for (int y = 0; y < yAmount; y++) { using (Bitmap bmp = new Bitmap(tileSize, tileSize)) { using (Graphics g = Graphics.FromImage(bmp)) { foreach (Line line in grid[x, y]) { float tileOffsetX = tileSize * x; float tileOffsetY = tileSize * y; PointF pointFrom = new PointF(line.from.X + xOffset - tileOffsetX, line.from.Y + yOffset - tileOffsetY); PointF pointTo = new PointF(line.to.X + xOffset - tileOffsetX, line.to.Y + yOffset - tileOffsetY); g.FillEllipse(new SolidBrush(line.pen.Color), pointFrom.X - line.pen.Width / 2, pointFrom.Y - line.pen.Width / 2, line.pen.Width, line.pen.Width); g.DrawLine(line.pen, pointFrom, pointTo); g.FillEllipse(new SolidBrush(line.pen.Color), pointTo.X - line.pen.Width / 2, pointTo.Y - line.pen.Width / 2, line.pen.Width, line.pen.Width); } } bmp.Save(newPath + "\\" + x + "\\" + y + ".png", System.Drawing.Imaging.ImageFormat.Png); } } } }
private static void DrawMap() { Console.WriteLine("Path to .osm file (E:\\Desktop\\map.osm)"); string path = Console.ReadLine(); Console.WriteLine("Outputfile (E:\\Desktop\\render.png"); string outputFilePath = Console.ReadLine(); Console.WriteLine("Scale (200)"); int scale = Convert.ToInt32(Console.ReadLine()); Importer importer = new Importer(); importer.OnProgress += (s, e) => { string progressString = string.Format("{0:#0.00}%", e.progress); int consoleLeft = Console.CursorLeft, consoleTop = Console.CursorTop; Console.SetCursorPosition(Console.WindowWidth - progressString.Length, consoleTop); Console.WriteLine(progressString); Console.SetCursorPosition(consoleLeft, consoleTop); }; importer.OnStatusChange += (s, e) => { Console.WriteLine(e.status); }; Graph mapGraph = importer.ImportOSM(path); _3DNode renderCenter = new _3DNode(mapGraph.minLat + (mapGraph.maxLat - mapGraph.minLat) / 2, mapGraph.minLon + (mapGraph.maxLon - mapGraph.minLon) / 2); Hashtable pens = new Hashtable(); foreach (string type in File.ReadAllLines("roadRender.txt")) { if (!type.StartsWith("//")) { string key = type.Split(',')[0]; if (!pens.ContainsKey(key)) { pens.Add(key, new Pen(Color.FromName(type.Split(',')[2]), Convert.ToInt32(type.Split(',')[1]))); } } } int coreCount = 0; foreach (ManagementObject result in new ManagementObjectSearcher("Select * from Win32_Processor").Get()) { coreCount += int.Parse(result["NumberOfCores"].ToString()); } Renderer renderer = new Renderer(renderCenter, scale); _2DNode topLeft = renderer.GetCoordinatesFromCenter(new _3DNode(mapGraph.maxLat, mapGraph.minLon)); _2DNode bottomRight = renderer.GetCoordinatesFromCenter(new _3DNode(mapGraph.minLat, mapGraph.maxLon)); int width = (int)(bottomRight.X - topLeft.X); int height = (int)(bottomRight.Y - topLeft.Y); Bitmap render = renderer.DrawMap(mapGraph, renderCenter, pens, width, height, coreCount); render.Save(outputFilePath); }