public override DVector2 WorldToTilePos(double lon, double lat, int zoom) { lat = DMathUtil.Clamp(lat, MinLatitude, MaxLatitude); lon = DMathUtil.Clamp(lon, MinLongitude, MaxLongitude); lat = lat <MinLatitude?MinLatitude : lat> MaxLatitude ? MaxLatitude : lat; lon = lon <MinLongitude?MinLongitude : lon> MaxLongitude ? MaxLongitude : lon; double rLon = lon * DEG_RAD; // Math.PI / 180; double rLat = lat * DEG_RAD; // Math.PI / 180; double a = 6378137; double k = 0.0818191908426; double z = Math.Tan(MathPiDiv4 + rLat / 2) / Math.Pow((Math.Tan(MathPiDiv4 + Math.Asin(k * Math.Sin(rLat)) / 2)), k); double z1 = Math.Pow(2, 23 - zoom); double DX = ((20037508.342789 + a * rLon) * 53.5865938 / z1) / 256.0; double DY = ((20037508.342789 - a * Math.Log(z)) * 53.5865938 / z1) / 256.0; DVector2 ret = DVector2.Zero; ret.X = DX; ret.Y = DY; return(ret); }
/// <summary> /// /// </summary> /// <param name="game"></param> public GlobeLayer(Game game, LayerServiceConfig config) : base(game, config) { shader = Game.Content.Load <Ubershader>(@"Globe.hlsl"); constBuffer = new ConstBufferGeneric <ConstData>(Game.GraphicsDevice); frame = Game.Content.Load <Texture2D>("redframe.tga"); railRoadsTex = Game.Content.Load <Texture2D>("Urban/Railroads.tga"); UpdateProjectionMatrix(Game.GraphicsDevice.DisplayBounds.Width, Game.GraphicsDevice.DisplayBounds.Height); maxPitch = DMathUtil.DegreesToRadians(87.5); minPitch = DMathUtil.DegreesToRadians(-87.5); GoToPlace(Places.SaintPetersburg_VO); InitDots(); InitAirLines(); Game.GetService <LayerService>().MapLayer.OnProjectionChanged += (s) => { updateTiles = true; }; CreateSphere(100, 50); //AddDebugLine(new DVector3(10000, 0, 0), Color.Red, new DVector3(0, 0, 0), Color.Red); //AddDebugLine(new DVector3(0, 10000, 0), Color.Green, new DVector3(0, 0, 0), Color.Green); //AddDebugLine(new DVector3(0, 0, 10000), Color.Blue, new DVector3(0, 0, 0), Color.Blue); myMiniFactory = new MyMiniFactory(Game, shader); }
void UpdateCamera() { var input = Game.InputDevice; if (input.IsKeyDown(Keys.LeftShift) && input.IsKeyDown(Keys.MiddleButton)) { FreeCamYaw += input.RelativeMouseOffset.X * 0.003; FreeCamPitch -= input.RelativeMouseOffset.Y * 0.003; FreeCamPitch = DMathUtil.Clamp(FreeCamPitch, -Math.PI / 2.01, 0.0); } }
public void DotsAddGeoObject(int objectClass, DVector2 lonLat, Color color, float size) { if (geoObjectOffset >= Dots.Length) { return; } Dots[geoObjectOffset++] = new GeoVert { Color = color, Lon = DMathUtil.DegreesToRadians(lonLat.X), Lat = DMathUtil.DegreesToRadians(lonLat.Y), Position = Vector3.Zero, Tex = new Vector4(objectClass, 0, size, 0) }; }
/// <summary> /// /// </summary> /// <param name="place"></param> public void GoToPlace(Places place) { switch (place) { case Places.SaintPetersburg_VO: Yaw = DMathUtil.DegreesToRadians(30.301419); Pitch = -DMathUtil.DegreesToRadians(59.942562); break; case Places.Vladivostok: Yaw = DMathUtil.DegreesToRadians(131.881642); Pitch = -DMathUtil.DegreesToRadians(43.111248); break; } }
public void LinesAdd(DVector2 lonLatPoint0, DVector2 lonLatPoint1, Color color) { linesBatchVertices.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(lonLatPoint0.X), Lat = DMathUtil.DegreesToRadians(lonLatPoint0.Y), Color = color, Position = new Vector3(), Tex = new Vector4() }); linesBatchVertices.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(lonLatPoint1.X), Lat = DMathUtil.DegreesToRadians(lonLatPoint1.Y), Color = color, Position = new Vector3(), Tex = new Vector4() }); }
void UpdateProjectionMatrix(float width, float height) { viewportWidth = width; viewportHeight = height; double aspect = viewportWidth / viewportHeight; double nearHeight = camNear * Math.Tan(DMathUtil.DegreesToRadians(camFov / 2)); double nearWidth = nearHeight * aspect; //float offset = separation / planeDist * near / 2; frustumWidth = nearWidth; frustumHeight = nearHeight; frustumZNear = camNear; frustumZFar = camFar; projMatrix = DMatrix.PerspectiveOffCenterRH(-nearWidth / 2, nearWidth / 2, -nearHeight / 2, nearHeight / 2, frustumZNear, frustumZFar); }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="args"></param> public void InputDeviceOnMouseDown(object sender, Frame.MouseEventArgs args) { if (args.Key != Keys.LeftButton) { return; } var w = viewportWidth; var h = viewportHeight; var pos = new Vector2(args.X, args.Y); var nearPoint = new DVector3(pos.X, pos.Y, frustumZNear); var farPoint = new DVector3(pos.X, pos.Y, frustumZFar); var vm = DMatrix.LookAtRH(cameraPosition, DVector3.Zero, DVector3.UnitY); var mVP = vm * projMatrix; var near = DVector3.Unproject(nearPoint, 0, 0, w, h, frustumZNear, frustumZFar, mVP); var far = DVector3.Unproject(farPoint, 0, 0, w, h, frustumZNear, frustumZFar, mVP); DVector3[] res; if (LineIntersection(near, far, Config.earthRadius, out res)) { if (res.Length > 0) { double lon, lat; CartesianToSpherical(res[0], out lon, out lat); var lonLat = new DVector2(DMathUtil.RadiansToDegrees(lon), DMathUtil.RadiansToDegrees(lat)); Console.WriteLine(lonLat); } } }
void AddBuildingContour(DVector2[] contourPoints, Color color) { if (contourPoints.Length < 3) { return; } var firstInd = contourBuildingsList.Count; //write first two contourBuildingsList.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(contourPoints[0].X), Lat = DMathUtil.DegreesToRadians(contourPoints[0].Y), Color = color }); contourBuildingsList.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(contourPoints[1].X), Lat = DMathUtil.DegreesToRadians(contourPoints[1].Y), Color = color }); for (int i = 1; i < contourPoints.Length - 1; i++) { var prevInd = contourBuildingsList.Count - 1; contourBuildingsList.Add(contourBuildingsList[prevInd]); contourBuildingsList.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(contourPoints[i + 1].X), Lat = DMathUtil.DegreesToRadians(contourPoints[i + 1].Y), Color = color }); } contourBuildingsList.Add(contourBuildingsList[contourBuildingsList.Count - 1]); contourBuildingsList.Add(contourBuildingsList[firstInd]); }
/// <summary> /// /// </summary> /// <param name="fileName"></param> /// <returns></returns> List <GeoVert> LoadGrid(string fileName) { var verts = new List <GeoVert>(); var sr = new StreamReader(fileName); int i = 0, j = 0; float step = 1.0f / 24.0f; while (!sr.EndOfStream) { var str = sr.ReadLine(); if (str == "") { i++; j = 0; continue; } var strs = str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); verts.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(double.Parse(strs[0])), Lat = DMathUtil.DegreesToRadians(double.Parse(strs[1])), Color = Color.White, Position = Vector3.Zero, Tex = new Vector4(step * j, step * i, 0, 0) }); j++; } sr.Close(); return(verts); }
//action on mouse public void onMouseClick(int mouseX, int mouseY) { foreach (var f in frames) { if (f.GlobalRectangle.Contains(mouseX, mouseY)) { return; } Console.WriteLine("click on frame"); } //if (frames.Count > 1) return; DVector2 mousePosition; ViewLayer.GlobeCamera.ScreenToSpherical(mouseX, mouseY, out mousePosition); var posts = new List <Post>(); Gis.GeoPoint currentpost = new Gis.GeoPoint(); if (globePostsVK != null && globePostsVK.IsVisible) { for (int i = 0; i < Control.PostsVK.Count; i++) { var post = globePostsVK.PointsCpu[i]; if (post.Color.Alpha == 0) { continue; } var distance = GeoHelper.DistanceBetweenTwoPoints(mousePosition, new DVector2(post.Lon, post.Lat)); if (distance < post.Tex0.Z) { if (!(Game.GameInterface is CustomGameInterface)) { return; } posts.Add(Control.PostsVK[i]); currentpost = post; } } } Log.Message(DMathUtil.RadiansToDegrees(mousePosition.X) + ""); Log.Message(DMathUtil.RadiansToDegrees(mousePosition.Y) + ""); var ui = ((CustomGameInterface)Game.GameInterface).ui; if (posts.Count > 0) { //for (int i = 0; i < frames.Count; i++) //{ // var f = frames[i]; // f.Parent.Remove(f); // f = null; //} //frames.Clear(); List <InstagramPost> instPost = new List <InstagramPost>(); foreach (var po in posts) { var ins = new InstagramPost() { Likes = po?.likes?.count > 0? po.likes.count.ToString() : 0.ToString(), Text = po.text, TimeStamp = ConvertFromUnixTimestamp((double)po.date * 1000), Url = String.IsNullOrEmpty(po.photo_url) ? "" : po.photo_url, }; instPost.Add(ins); } var frame = FrameHelper.createWebPhotoFrameGeoTag(ui, mouseX, mouseY, maxImageSize, maxImageSize, "inst_load", posts[0].photo_url, 0, instPost.ToArray(), currentpost); frames.Add(frame); var p = (Panel as GisPanel); p.Frame.Insert(0, frame); } else { for (int i = 0; i < frames.Count; i++) { var f = frames[i]; f.Parent.Remove(f); f = null; } frames.Clear(); } }
private void initPosts() { var frame = (Panel as GisPanel).Frame; // Clear if (VkCurrentLayer != null) { Layers.Remove(VkCurrentLayer); frame.viewLayers.GisLayers.Remove(VkCurrentLayer.Layer); } if (Control.PostsVK == null || Control.PostsVK.Count == 0) { return; } // add new posts globePostsVK = new PointsGisLayer(Game, Control.PostsVK.Count) { ImageSizeInAtlas = new Vector2(128, 128), TextureAtlas = Game.Content.Load <Texture2D>("Train/station_circle.tga") }; globePostsVK.ZOrder = 1000; var id = 0; foreach (var post in Control.PostsVK.FindAll(e => e.geo != null)) { var coordinate = post.geo.coordinates.Split(' '); globePostsVK.PointsCpu[id] = new Gis.GeoPoint { Lon = DMathUtil.DegreesToRadians(double.Parse(coordinate[1])), Lat = DMathUtil.DegreesToRadians(double.Parse(coordinate[0])), Color = new Color(255, 217, 0, maxAlpha), Tex0 = new Vector4(0, 0, 0.05f, 0.0f) }; id++; } VkCurrentLayer = new GisLayerWrapper(globePostsVK); frame.viewLayers.GisLayers.Add(VkCurrentLayer.Layer); Layers.Add(VkCurrentLayer); globePostsVK.UpdatePointsBuffer(); if (frames != null) { for (int i = 0; i < frames.Count; i++) { var f = frames[i]; f.Parent.Remove(f); f = null; } frames.Clear(); } var ui = ((CustomGameInterface)Game.GameInterface).ui; List <InstagramPost> instPost = new List <InstagramPost>(); int idx = 0; if (Control.newPostsVK == null) { return; } foreach (var po in Control.newPostsVK) { var ins = new InstagramPost() { Likes = po?.likes?.count > 0 ? po.likes.count.ToString() : 0.ToString(), Text = po.text, TimeStamp = ConvertFromUnixTimestamp((double)po.date * 1000), Url = String.IsNullOrEmpty(po.photo_url) ? "" : po.photo_url, }; instPost.Add(ins); var geopoint = globePostsVK.PointsCpu[globePostsVK.PointsCount - Control.newPostsVK.Count + idx]; idx++; var cartesianCoor = GeoHelper.SphericalToCartesian(new DVector2(geopoint.Lon, geopoint.Lat)); var screenPosition = ViewLayer.GlobeCamera.CartesianToScreen(cartesianCoor); Console.WriteLine(screenPosition); if (screenPosition.X < 0 || screenPosition.Y < 0) { continue; } var newFrame = FrameHelper.createWebPhotoFrameGeoTag(ui, (int)screenPosition.X, (int)screenPosition.Y, maxImageSize, maxImageSize, "inst_load", ins.Url, 0, instPost.ToArray(), geopoint); frames.Add(newFrame); frame.Add(newFrame); } // clear new posts Control.newPostsVK = null; }
/// <summary> /// /// </summary> void DetermineTiles() { //SetCurrentLevel(); var ms = Game.GetService <LayerService>().MapLayer.CurrentMapSource; var d = Math.Log((Config.CameraDistance - Config.earthRadius) * 1000.0, 2.0); double lod = 28.3 - d; var maxLod = ms.MaxZoom; lowestLod = (int)lod; if (lowestLod > maxLod.Value) { lowestLod = maxLod.Value; } CurrentLevel = lowestLod; if (CurrentLevel < 3) { CurrentLevel = 3; } // Get camera mercator position var lonLat = GetCameraLonLat(); lonLat.X = DMathUtil.RadiansToDegrees(lonLat.X); lonLat.Y = DMathUtil.RadiansToDegrees(lonLat.Y); //var merc = GeoHelper.WorldToTilePos(lonLat.X, lonLat.Y); var merc = ms.Projection.WorldToTilePos(lonLat.X, lonLat.Y, CurrentLevel); // Get tile index under camera int x, y; //GetTileIndexByMerc(merc, CurrentLevel, out x, out y); x = (int)merc.X; y = (int)merc.Y; var key = GenerateKey(x, y, CurrentLevel); //if (key == centerTile) return; centerTile = key; if (updateTiles) { foreach (var tile in tilesToRender) { tilesFree.Add(tile.Key, tile.Value); } updateTiles = false; } else { foreach (var tile in tilesToRender) { tilesOld.Add(tile.Key, tile.Value); } } tilesToRender.Clear(); var info = new TraversalInfo[2]; var centralNode = new Node { Z = CurrentLevel - 2 }; var tileUpper = ms.Projection.WorldToTilePos(lonLat.X, lonLat.Y, centralNode.Z); centralNode.X = (int)tileUpper.X; centralNode.Y = (int)tileUpper.Y; //GetTileIndexByMerc(merc, centralNode.Z, out centralNode.X, out centralNode.Y); info[0].CentralNode = new Node { X = centralNode.X - 7, Y = centralNode.Y - 7, Z = centralNode.Z }; info[0].Offset = 4; info[0].Length = 7; var offNode = new Node { X = info[0].CentralNode.X + info[0].Offset, Y = info[0].CentralNode.Y + info[0].Offset, Z = info[0].CentralNode.Z }; GetChilds(offNode); info[1].CentralNode = offNode.Childs[0]; info[1].Offset = 3; info[1].Length = 8; int tilesNum = 1 << info[0].CentralNode.Z; for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { var nodeX = info[0].CentralNode.X + i; var nodeY = info[0].CentralNode.Y + j; nodeX = nodeX % tilesNum; if (nodeX < 0) { nodeX = tilesNum + nodeX; } if (nodeY < 0 || nodeY >= tilesNum) { continue; } var currNode = new Node { X = nodeX, Y = nodeY, Z = info[0].CentralNode.Z }; QuadTreeTraversalDownTop(info, currNode, 0); } } foreach (var tile in tilesOld) { tilesFree.Add(tile.Key, tile.Value); } tilesOld.Clear(); }
void InitAirLines() { if (!File.Exists("Airlines.txt")) { return; } airDirections = new List <AirDirection>(); var sr = new StreamReader("Airlines.txt"); var dir = new AirDirection(); while (!sr.EndOfStream) { var line = sr.ReadLine(); if (line.Length == 0) { continue; } var lines = line.Split(new char[] { ':', '\'', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries); switch (lines[0]) { case "id": { dir.Id = int.Parse(lines[1]); break; } case "type": { dir.Type = int.Parse(lines[1]); break; } case "name": { dir.Name = lines[1]; break; } case "latitude": { dir.Latitude = double.Parse(lines[1]); break; } case "longitude": { dir.Longitude = double.Parse(lines[1]); airDirections.Add(dir); dir = new AirDirection(); break; } } } sr.Close(); airLines = new GeoVert[2 * airDirections.Count(x => x.Type == 1)]; airLinesVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), airLines.Length); var saintPetersburgPos = new DVector2(DMathUtil.DegreesToRadians(30.270424), DMathUtil.DegreesToRadians(59.800073)); var saintVert = new GeoVert { Lon = saintPetersburgPos.X, Lat = saintPetersburgPos.Y, Position = Vector3.Zero, Tex = new Vector4(1.0f, 0.0f, 0, 0), Color = new Color(0.01f, 0.01f, 0.01f, 0.01f) }; int i = 0; foreach (var airDir in airDirections.Where(x => x.Type == 1)) { airLines[2 * i + 0] = saintVert; airLines[2 * i + 1] = new GeoVert { Lon = DMathUtil.DegreesToRadians(airDir.Longitude), Lat = DMathUtil.DegreesToRadians(airDir.Latitude), Position = Vector3.Zero, Tex = new Vector4(10.0f, 0.0f, 0, 0), Color = new Color(0.8f, 0.8f, 0.8f, 0.8f) }; i++; } airLinesVB.SetData(airLines, 0, airLines.Length); }
void InitBuildingsOSM() { var osm = Game.GetService <LayerService>().OpenStreetMapSource; List <GeoVert> lines = new List <GeoVert>(); List <GeoVert> simple = new List <GeoVert>(); var nodes = osm.allNodes; int k = 0; foreach (var way in osm.allWays) { if (!way.Value.isBuilding) { continue; } var centerMerc = way.Value.BBox.Center(); float width = (way.Value.BBox.Maximum - way.Value.BBox.Minimum).X * 10000.0f; float length = (way.Value.BBox.Maximum - way.Value.BBox.Minimum).Y * 10000.0f; double lon, lat; GeoHelper.TileToWorldPos(centerMerc.X, centerMerc.Y, 0, out lon, out lat); simple.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(lon), Lat = DMathUtil.DegreesToRadians(lat), Color = Color.White, Position = Vector3.Zero, Tex = new Vector4(width, length, 0, 0) }); List <DVector2> buildingVertices = new List <DVector2>(); for (int i = 0; i < way.Value.nodeRef.Length - 1; i++) { var nInds = way.Value.nodeRef; lines.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(nodes[nInds[i]].Longitude), Lat = DMathUtil.DegreesToRadians(nodes[nInds[i]].Latitude), Position = new Vector3(1.0f, 0.0f, 0.0f), Color = Color.Yellow, Tex = Vector4.Zero }); lines.Add(new GeoVert { Lon = DMathUtil.DegreesToRadians(nodes[nInds[i + 1]].Longitude), Lat = DMathUtil.DegreesToRadians(nodes[nInds[i + 1]].Latitude), Position = new Vector3(1.0f, 0.0f, 0.0f), Color = Color.Yellow, Tex = Vector4.Zero }); buildingVertices.Add(new DVector2(nodes[nInds[i]].Longitude, nodes[nInds[i]].Latitude)); } buildingVertices.Add(new DVector2(nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Longitude, nodes[way.Value.nodeRef[way.Value.nodeRef.Length - 1]].Latitude)); ///////////////////////////////////////// var mesh = new Mesh(); mesh.Behavior.Quality = false; mesh.Behavior.MinAngle = 25; mesh.Behavior.Convex = false; var ig = new InputGeometry(); ig.AddPoint(buildingVertices[0].X, buildingVertices[0].Y); for (int v = 1; v < buildingVertices.Count; v++) { ig.AddPoint(buildingVertices[v].X, buildingVertices[v].Y); ig.AddSegment(v - 1, v); } ig.AddSegment(buildingVertices.Count - 1, 0); mesh.Triangulate(ig); int n = mesh.Vertices.Count; mesh.Renumber(); buildings = new GeoVert[mesh.Triangles.Count * 3]; int ind = 0; foreach (var triangle in mesh.Triangles) { buildings[ind++] = new GeoVert { Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).X), Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P0).Y), Position = new Vector3(0.1f, 0.0f, 0.0f), Color = Color.Green, Tex = Vector4.Zero }; buildings[ind++] = new GeoVert { Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).X), Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P1).Y), Position = new Vector3(0.1f, 0.0f, 0.0f), Color = Color.Green, Tex = Vector4.Zero }; buildings[ind++] = new GeoVert { Lon = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).X), Lat = DMathUtil.DegreesToRadians(mesh.Vertices.ElementAt(triangle.P2).Y), Position = new Vector3(0.1f, 0.0f, 0.0f), Color = Color.Green, Tex = Vector4.Zero }; } ///////////////////////////////////////// k++; if (k >= 1) { break; } } simpleBuildings = simple.ToArray(); contourBuildings = lines.ToArray(); contourBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), contourBuildings.Length); contourBuildingsVB.SetData(contourBuildings, 0, contourBuildings.Length); simpleBuildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), simpleBuildings.Length); simpleBuildingsVB.SetData(simpleBuildings, 0, simpleBuildings.Length); buildingsVB = new VertexBuffer(Game.GraphicsDevice, typeof(GeoVert), buildings.Length); buildingsVB.SetData(buildings, 0, buildings.Length); }