Пример #1
0
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            DateTime start = DateTime.Now;

            if (this.DesignMode)
            {
                return;
            }

            if (area.LocationMiddle.Lat == 0 && area.LocationMiddle.Lng == 0)
            {
                return;
            }

            try
            {
                base.OnPaint(e);
            }
            catch
            {
                return;
            }

            utmzone = center.GetUTMZone();

            double heightscale = 1;//(step/90.0)*5;

            var campos = convertCoords(center);

            cameraX = campos[0];
            cameraY = campos[1];
            cameraZ = (campos[2] < srtm.getAltitude(center.Lat, center.Lng).alt)
                ? (srtm.getAltitude(center.Lat, center.Lng).alt + 1) * heightscale
                : center.Alt * heightscale; // (srtm.getAltitude(lookZ, lookX, 20) + 100) * heighscale;

            lookX = campos[0] + Math.Sin(MathHelper.Radians(rpy.Z)) * 100;
            lookY = campos[1] + Math.Cos(MathHelper.Radians(rpy.Z)) * 100;
            lookZ = cameraZ;

            var size = 20000;

            // in front
            PointLatLngAlt front = center.newpos(rpy.Z, size);
            // behind
            PointLatLngAlt behind = center.newpos(rpy.Z, -50);
            // left : 90 allows for 180 degree viewing angle
            PointLatLngAlt left = center.newpos(rpy.Z - 45, size);
            // right
            PointLatLngAlt right = center.newpos(rpy.Z + 45, size);

            double maxlat = Math.Max(left.Lat, Math.Max(right.Lat, Math.Max(front.Lat, behind.Lat)));
            double minlat = Math.Min(left.Lat, Math.Min(right.Lat, Math.Min(front.Lat, behind.Lat)));

            double maxlng = Math.Max(left.Lng, Math.Max(right.Lng, Math.Max(front.Lng, behind.Lng)));
            double minlng = Math.Min(left.Lng, Math.Min(right.Lng, Math.Min(front.Lng, behind.Lng)));

            area = RectLatLng.FromLTRB(minlng, maxlat, maxlng, minlat);

            zoom = 20;


            float screenscale = 1;//this.Width/(float) this.Height*1f;

            //if(!Context.IsCurrent)
            MakeCurrent();

            GL.MatrixMode(MatrixMode.Projection);

            OpenTK.Matrix4 projection = OpenTK.Matrix4.CreatePerspectiveFieldOfView((float)(90 * MathHelper.deg2rad), screenscale, 0.00000001f,
                                                                                    (float)20000);
            GL.LoadMatrix(ref projection);

            Console.WriteLine("cam: {0} {1} {2} lookat: {3} {4} {5}", (float)cameraX, (float)cameraY, (float)cameraZ,
                              (float)lookX,
                              (float)lookY, (float)lookZ);

            Matrix4 modelview = Matrix4.LookAt((float)cameraX, (float)cameraY, (float)cameraZ + 100f * 0, (float)lookX,
                                               (float)lookY, (float)lookZ, 0, 0, 1);

            GL.MatrixMode(MatrixMode.Modelview);

            // roll
            modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationZ((float)(rpy.X * MathHelper.deg2rad)));
            // pitch
            modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationX((float)(rpy.Y * -MathHelper.deg2rad)));

            GL.LoadMatrix(ref modelview);

            GL.ClearColor(Color.CornflowerBlue);

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.AccumBufferBit);

            GL.LightModel(LightModelParameter.LightModelAmbient, new float[] { 1f, 1f, 1f, 1f });

            GL.Disable(EnableCap.Fog);
            GL.Enable(EnableCap.Fog);
            //GL.Enable(EnableCap.Lighting);
            //GL.Enable(EnableCap.Light0);

            GL.Fog(FogParameter.FogColor, new float[] { 100 / 255.0f, 149 / 255.0f, 237 / 255.0f, 1f });
            //GL.Fog(FogParameter.FogDensity,0.1f);
            GL.Fog(FogParameter.FogMode, (int)FogMode.Linear);
            GL.Fog(FogParameter.FogStart, (float)4000);
            GL.Fog(FogParameter.FogEnd, (float)size);

            GL.Disable(EnableCap.DepthTest);
            GL.DepthFunc(DepthFunction.Always);

            /*
             * GL.Begin(BeginMode.LineStrip);
             *
             * GL.Color3(Color.White);
             * GL.Vertex3(0, 0, 0);
             *
             * GL.Color3(Color.Red);
             * GL.Vertex3(area.Bottom, 0, area.Left);
             *
             * GL.Color3(Color.Yellow);
             * GL.Vertex3(lookX, lookY, lookZ);
             *
             * GL.Color3(Color.Green);
             * GL.Vertex3(cameraX, cameraY, cameraZ);
             *
             * GL.End();
             */
            /*
             * GL.PointSize(10);
             * GL.Color4(Color.Yellow);
             * GL.LineWidth(5);
             *
             *
             * GL.Begin(PrimitiveType.LineStrip);
             *
             * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, (float)cameraZ);
             * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationRightBottom.Lat, (float)cameraZ);
             * GL.Vertex3(area.LocationRightBottom.Lng, area.LocationRightBottom.Lat, (float)cameraZ);
             * GL.Vertex3(area.LocationRightBottom.Lng, area.LocationTopLeft.Lat, (float)cameraZ);
             * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, (float)cameraZ);
             *
             * GL.End();
             *
             * GL.PointSize((float) (step*1));
             * GL.Color3(Color.Blue);
             * GL.Begin(PrimitiveType.Points);
             * GL.Vertex3(new Vector3((float) center.Lng, (float) center.Lat, (float) cameraZ));
             * GL.End();
             */

            //GL.ClampColor(ClampColorTarget.ClampReadColor, ClampColorMode.True);

            /*
             * GL.Enable(EnableCap.Blend);
             * GL.DepthMask(false);
             * GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.Src1Color);
             * GL.DepthMask(true);
             * GL.Disable(EnableCap.Blend);
             */
            // textureid.Clear();

            core.fillEmptyTiles = true;

            core.LevelsKeepInMemmory = 20;

            core.Provider = type;
            core.Position = center;

            //core.ReloadMap();

            List <tileZoomArea> tileArea = new List <tileZoomArea>();

            for (int a = 10; a <= zoom; a++)
            {
                core.Zoom = a;

                var area2 = new RectLatLng(center.Lat, center.Lng, 0, 0);

                // 200m at max zoom
                // step at 0 zoom
                var distm = MathHelper.map(a, 0, zoom, size, 50);

                var offset = center.newpos(rpy.Z, distm);

                area2.Inflate(Math.Abs(center.Lat - offset.Lat), Math.Abs(center.Lng - offset.Lng));

                var extratile = 0;

                if (a == zoom)
                {
                    extratile = 1;
                }

                var tiles = new tileZoomArea()
                {
                    zoom = a, points = prj.GetAreaTileList(area2, a, extratile), area = area2
                };

                tileArea.Add(tiles);
            }

            //tileArea.Reverse();

            while (textureid.Count > 250)
            {
                var first = textureid.Keys.First();
                GL.DeleteTexture(textureid[first]);
                textureid.Remove(first);
            }

            // get tiles & combine into one
            foreach (var tilearea in tileArea)
            {
                foreach (var p in tilearea.points)
                {
                    core.tileDrawingListLock.AcquireReaderLock();
                    core.Matrix.EnterReadLock();
                    try
                    {
                        GMap.NET.Internals.Tile t = core.Matrix.GetTileWithNoLock(tilearea.zoom, p);

                        if (t.NotEmpty)
                        {
                            foreach (GMapImage img in t.Overlays)
                            {
                                if (img.IsParent)
                                {
                                }

                                if (!textureid.ContainsKey(p))
                                {
                                    try
                                    {
                                        generateTexture(p, (Bitmap)img.Img);
                                    }
                                    catch
                                    {
                                        continue;
                                    }
                                }
                            }
                        }
                        else
                        {
                        }
                    }
                    finally
                    {
                        core.Matrix.LeaveReadLock();
                        core.tileDrawingListLock.ReleaseReaderLock();
                    }

                    if (textureid.ContainsKey(p))
                    {
                        int texture = textureid[p];

                        GL.Enable(EnableCap.Texture2D);
                        GL.BindTexture(TextureTarget.Texture2D, texture);
                    }
                    else
                    {
                        //Console.WriteLine("Missing tile");
                        GL.Disable(EnableCap.Texture2D);
                        continue;
                    }

                    long xr = p.X * prj.TileSize.Width;
                    long yr = p.Y * prj.TileSize.Width;

                    long x2 = (p.X + 1) * prj.TileSize.Width;
                    long y2 = (p.Y + 1) * prj.TileSize.Width;

                    GL.LineWidth(4);
                    GL.Color3(Color.White);

                    GL.Clear(ClearBufferMask.DepthBufferBit);

                    GL.Enable(EnableCap.DepthTest);

                    // generate terrain
                    GL.Begin(PrimitiveType.Points);

                    GL.PointSize((float)(20));

                    //GL.Begin(PrimitiveType.Points);
                    GL.Color3(Color.Blue);

                    var latlng = prj.FromPixelToLatLng(xr, yr, tilearea.zoom);
                    var utm    = convertCoords(latlng);
                    utm[2] = srtm.getAltitude(latlng.Lat, latlng.Lng).alt;

                    GL.TexCoord2(0, 0);
                    GL.Vertex3(utm[0], utm[1], utm[2]);

                    // next down
                    latlng = prj.FromPixelToLatLng(xr, y2, tilearea.zoom);
                    utm    = convertCoords(latlng);
                    utm[2] = srtm.getAltitude(latlng.Lat, latlng.Lng).alt;

                    GL.TexCoord2(0, 1);
                    GL.Vertex3(utm[0], utm[1], utm[2]);

                    // next right
                    latlng = prj.FromPixelToLatLng(x2, yr, tilearea.zoom);
                    utm    = convertCoords(latlng);
                    utm[2] = srtm.getAltitude(latlng.Lat, latlng.Lng).alt;

                    GL.TexCoord2(1, 0);
                    GL.Vertex3(utm[0], utm[1], utm[2]);

                    // next right down
                    latlng = prj.FromPixelToLatLng(x2, y2, tilearea.zoom);
                    utm    = convertCoords(latlng);
                    utm[2] = srtm.getAltitude(latlng.Lat, latlng.Lng).alt;

                    GL.TexCoord2(1, 1);
                    GL.Vertex3(utm[0], utm[1], utm[2]);

                    GL.End();

                    var dist = LocationCenter.GetDistance(latlng);

                    var pxstep = 128;

                    if (dist < 500)
                    {
                        pxstep = 32;
                    }

                    double[] oldutm = null;
                    GL.Begin(PrimitiveType.TriangleStrip);
                    for (long x = xr; x < x2; x += pxstep)
                    {
                        long xnext = x + pxstep;
                        //GL.Begin(PrimitiveType.LineStrip);
                        for (long y = yr; y < y2; y += pxstep)
                        {
                            long ynext = y + pxstep;

                            //GL.Begin(PrimitiveType.Lines);
                            var latlng1 = prj.FromPixelToLatLng(x, y, tilearea.zoom);
                            var utm1    = convertCoords(latlng1);
                            utm1[2] = srtm.getAltitude(latlng1.Lat, latlng1.Lng).alt;

                            var imgx = MathHelper.map(x, xr, x2, 0, 1);
                            var imgy = MathHelper.map(y, yr, y2, 0, 1);

                            GL.TexCoord2(imgx, imgy);
                            GL.Vertex3(utm1[0], utm1[1], utm1[2]);

                            //
                            var latlng2 = prj.FromPixelToLatLng(x, ynext, tilearea.zoom);
                            var utm2    = convertCoords(latlng2);
                            utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt;

                            imgx = MathHelper.map(x, xr, x2, 0, 1);
                            imgy = MathHelper.map(ynext, yr, y2, 0, 1);

                            GL.TexCoord2(imgx, imgy);
                            GL.Vertex3(utm2[0], utm2[1], utm2[2]);

                            //
                            latlng2 = prj.FromPixelToLatLng(xnext, y, tilearea.zoom);
                            utm2    = convertCoords(latlng2);
                            utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt;

                            imgx = MathHelper.map(xnext, xr, x2, 0, 1);
                            imgy = MathHelper.map(y, yr, y2, 0, 1);

                            GL.TexCoord2(imgx, imgy);
                            GL.Vertex3(utm2[0], utm2[1], utm2[2]);

                            //
                            latlng2 = prj.FromPixelToLatLng(xnext, ynext, tilearea.zoom);
                            utm2    = convertCoords(latlng2);
                            utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt;

                            imgx = MathHelper.map(xnext, xr, x2, 0, 1);
                            imgy = MathHelper.map(ynext, yr, y2, 0, 1);

                            GL.TexCoord2(imgx, imgy);
                            GL.Vertex3(utm2[0], utm2[1], utm2[2]);
                        }
                    }

                    GL.End();
                    GL.Disable(EnableCap.Texture2D);
                }
            }

            GL.Flush();

            try
            {
                this.SwapBuffers();


                Context.MakeCurrent(null);
            }
            catch
            {
            }

            //this.Invalidate();

            var delta = DateTime.Now - start;

            Console.WriteLine("OpenGLTest2 {0}", delta.TotalMilliseconds);
        }
Пример #2
0
        private void generateTextures()
        {
            core.fillEmptyTiles = false;

            core.LevelsKeepInMemmory = 10;

            core.Provider = type;

            //core.ReloadMap();

            List <tileZoomArea> tileArea = new List <tileZoomArea>();
            //if (center.GetDistance(oldcenter) > 30)
            {
                oldcenter = new PointLatLngAlt(center);
                zoom      = 18;

                for (int a = 12; a <= zoom; a++)
                {
                    var area2 = new RectLatLng(center.Lat, center.Lng, 0, 0);

                    // 200m at max zoom
                    // step at 0 zoom
                    var distm = MathHelper.map(a, 0, zoom, 3000, 10);

                    //Console.WriteLine("tiles z {0} max {1} dist {2}", a, zoom, distm);

                    var offset = center.newpos(rpy.Z, distm);

                    area2.Inflate(Math.Abs(center.Lat - offset.Lat), Math.Abs(center.Lng - offset.Lng));

                    var extratile = 0;

                    if (a == zoom)
                    {
                        extratile = 1;
                    }

                    var tiles = new tileZoomArea()
                    {
                        zoom   = a,
                        points = prj.GetAreaTileList(area2, a, extratile),
                        area   = area2
                    };

                    tileArea.Add(tiles);
                }
            }

            var totaltiles = tileArea.Sum(a => a.points.Count);

            Console.WriteLine(DateTime.Now.Millisecond + " Total tiles " + totaltiles);

            textureid.Where(a => !tileArea.Any(b => b.points.Contains(a.Key))).ForEach(c =>
            {
                this.BeginInvoke((MethodInvoker) delegate
                {
                    Console.WriteLine(DateTime.Now.Millisecond + " tile cleanup");
                    tileInfo temp;
                    textureid.TryRemove(c.Key, out temp);
                    temp?.Cleanup();
                });
            });

            //https://wiki.openstreetmap.org/wiki/Zoom_levels
            var C = 2 * Math.PI * 6378137.000;
            // horizontal distance by each tile square
            var stile = C * Math.Cos(center.Lat) / Math.Pow(2, zoom);

            var pxstep = 2;

            // get tiles & combine into one
            foreach (var tilearea in tileArea)
            {
                stile = C * Math.Cos(center.Lat) / Math.Pow(2, tilearea.zoom);

                if (tilearea.zoom == 20)
                {
                    pxstep = 256;
                }
                if (tilearea.zoom == 19)
                {
                    pxstep = 128;
                }
                if (tilearea.zoom == 18)
                {
                    pxstep = 64;
                }
                if (tilearea.zoom == 17)
                {
                    pxstep = 32;
                }
                if (tilearea.zoom == 16)
                {
                    pxstep = 16;
                }
                if (tilearea.zoom == 15)
                {
                    pxstep = 8;
                }
                if (tilearea.zoom == 14)
                {
                    pxstep = 4;
                }
                if (tilearea.zoom == 13)
                {
                    pxstep = 2;
                }
                if (tilearea.zoom == 12)
                {
                    pxstep = 1;
                }

                foreach (var p in tilearea.points)
                {
                    core.tileDrawingListLock.AcquireReaderLock();
                    core.Matrix.EnterReadLock();

                    long xr = p.X * prj.TileSize.Width;
                    long yr = p.Y * prj.TileSize.Width;

                    long x2 = (p.X + 1) * prj.TileSize.Width;
                    long y2 = (p.Y + 1) * prj.TileSize.Width;

                    try
                    {
                        GMap.NET.Internals.Tile t = core.Matrix.GetTileWithNoLock(tilearea.zoom, p);

                        if (t.NotEmpty)
                        {
                            foreach (GMapImage img in t.Overlays)
                            {
                                if (!textureid.ContainsKey(p))
                                {
                                    try
                                    {
                                        var ti = new tileInfo()
                                        {
                                            point = p,
                                            zoom  = tilearea.zoom,
                                            img   = (Image)img.Img.Clone()
                                        };

                                        for (long x = xr; x < x2; x += pxstep)
                                        {
                                            long xnext = x + pxstep;
                                            for (long y = yr; y < y2; y += pxstep)
                                            {
                                                long ynext = y + pxstep;

                                                var latlng1 = prj.FromPixelToLatLng(x, y, tilearea.zoom);
                                                if (srtm.getAltitude(latlng1.Lat, latlng1.Lng).currenttype == srtm.tiletype.invalid)
                                                {
                                                    ti = null;
                                                    x  = x2;
                                                    y  = y2;
                                                    break;
                                                }

                                                var utm1 = convertCoords(latlng1);
                                                utm1[2] = srtm.getAltitude(latlng1.Lat, latlng1.Lng).alt;

                                                var imgx = MathHelper.map(x, xr, x2, 0, 1);
                                                var imgy = MathHelper.map(y, yr, y2, 0, 1);

                                                ti.texture.Add(new tileInfo.TextureCoords((float)imgx, (float)imgy));
                                                ti.vertex.Add(new tileInfo.Vertex((float)utm1[0], (float)utm1[1],
                                                                                  (float)utm1[2]));

                                                //
                                                var latlng2 = prj.FromPixelToLatLng(x, ynext, tilearea.zoom);
                                                var utm2    = convertCoords(latlng2);
                                                utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt;

                                                imgx = MathHelper.map(x, xr, x2, 0, 1);
                                                imgy = MathHelper.map(ynext, yr, y2, 0, 1);

                                                ti.texture.Add(new tileInfo.TextureCoords((float)imgx, (float)imgy));
                                                ti.vertex.Add(new tileInfo.Vertex((float)utm2[0], (float)utm2[1],
                                                                                  (float)utm2[2]));

                                                //
                                                latlng2 = prj.FromPixelToLatLng(xnext, y, tilearea.zoom);
                                                utm2    = convertCoords(latlng2);
                                                utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt;

                                                imgx = MathHelper.map(xnext, xr, x2, 0, 1);
                                                imgy = MathHelper.map(y, yr, y2, 0, 1);

                                                ti.texture.Add(new tileInfo.TextureCoords((float)imgx, (float)imgy));
                                                ti.vertex.Add(new tileInfo.Vertex((float)utm2[0], (float)utm2[1],
                                                                                  (float)utm2[2]));

                                                //
                                                latlng2 = prj.FromPixelToLatLng(xnext, ynext, tilearea.zoom);
                                                utm2    = convertCoords(latlng2);
                                                utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt;

                                                imgx = MathHelper.map(xnext, xr, x2, 0, 1);
                                                imgy = MathHelper.map(ynext, yr, y2, 0, 1);

                                                ti.texture.Add(new tileInfo.TextureCoords((float)imgx, (float)imgy));
                                                ti.vertex.Add(new tileInfo.Vertex((float)utm2[0], (float)utm2[1],
                                                                                  (float)utm2[2]));
                                            }
                                        }

                                        if (ti != null)
                                        {
                                            textureid[p] = ti;
                                        }
                                    }
                                    catch
                                    {
                                        continue;
                                    }
                                }
                            }
                        }
                    }
                    finally
                    {
                        core.Matrix.LeaveReadLock();
                        core.tileDrawingListLock.ReleaseReaderLock();
                    }
                }
            }
        }
Пример #3
0
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            if (this.DesignMode)
            {
                return;
            }

            if (area.LocationMiddle.Lat == 0 && area.LocationMiddle.Lng == 0)
            {
                return;
            }

            try
            {
                base.OnPaint(e);
            }
            catch { return; }

            double heightscale = (step / 90.0) * 1;

            float yawradians = (float)(Math.PI * (rpy.Z * 1) / 180.0f);

            //radians = 0;

            float mouseY = (float)step / 10f;

            cameraX = center.Lng;                                                                                                                                                // -Math.Sin(yawradians) * mouseY;     // multiplying by mouseY makes the
            cameraY = center.Lat;                                                                                                                                                // -Math.Cos(yawradians) * mouseY;    // camera get closer/farther away with mouseY
            cameraZ = (center.Alt < srtm.getAltitude(center.Lat, center.Lng).alt) ? (srtm.getAltitude(center.Lat, center.Lng).alt + 1) * heightscale : center.Alt * heightscale; // (srtm.getAltitude(lookZ, lookX, 20) + 100) * heighscale;

            lookX = center.Lng + Math.Sin(yawradians) * mouseY;
            lookY = center.Lat + Math.Cos(yawradians) * mouseY;
            lookZ = cameraZ;

            // cameraZ += 0.04;

            GMapProvider   type = GMap.NET.MapProviders.GoogleSatelliteMapProvider.Instance;
            PureProjection prj  = type.Projection;

            int size = (int)(cameraZ * 150000);

            // in front
            PointLatLngAlt leftf = center.newpos(rpy.Z, size);
            // behind
            PointLatLngAlt rightf = center.newpos(rpy.Z, 50);
            // left : 90 allows for 180 degree viewing angle
            PointLatLngAlt left = center.newpos(rpy.Z - 90, size);
            // right
            PointLatLngAlt right = center.newpos(rpy.Z + 90, size);

            double maxlat = Math.Max(left.Lat, Math.Max(right.Lat, Math.Max(leftf.Lat, rightf.Lat)));
            double minlat = Math.Min(left.Lat, Math.Min(right.Lat, Math.Min(leftf.Lat, rightf.Lat)));

            double maxlng = Math.Max(left.Lng, Math.Max(right.Lng, Math.Max(leftf.Lng, rightf.Lng)));
            double minlng = Math.Min(left.Lng, Math.Min(right.Lng, Math.Min(leftf.Lng, rightf.Lng)));

            // if (Math.Abs(area.Lat - maxlat) < 0.001)
            {
            }
            // else
            {
                area = RectLatLng.FromLTRB(minlng, maxlat, maxlng, minlat);
            }

            GPoint topLeftPx     = prj.FromLatLngToPixel(area.LocationTopLeft, zoom);
            GPoint rightButtomPx = prj.FromLatLngToPixel(area.Bottom, area.Right, zoom);
            GPoint pxDelta       = new GPoint(rightButtomPx.X - topLeftPx.X, rightButtomPx.Y - topLeftPx.Y);

            zoom      = 21;
            pxDelta.X = 9999;

            int otherzoomlevel = 12;

            // zoom based on pixel density
            while (pxDelta.X > this.Width)
            {
                zoom--;

                // current area
                topLeftPx     = prj.FromLatLngToPixel(area.LocationTopLeft, zoom);
                rightButtomPx = prj.FromLatLngToPixel(area.Bottom, area.Right, zoom);
                pxDelta       = new GPoint(rightButtomPx.X - topLeftPx.X, rightButtomPx.Y - topLeftPx.Y);
            }

            otherzoomlevel = zoom - 4;

            Console.WriteLine("zoom {0}", zoom);

            // update once per seconds - we only read from disk, so need to let cahce settle
            if (lastrefresh.AddSeconds(0.5) < DateTime.Now)
            {
                // get tiles - bg
                core.Provider = type;
                core.Position = LocationCenter;

                // get zoom 10
                core.Zoom = otherzoomlevel;
                core.OnMapSizeChanged(this.Width, this.Height);

                // get actual current zoom
                core.Zoom = zoom;
                core.OnMapSizeChanged(this.Width, this.Height);

                lastrefresh = DateTime.Now;
            }
            else
            {
                //return;
            }

            float screenscale = this.Width / (float)this.Height;

            MakeCurrent();

            GL.MatrixMode(MatrixMode.Projection);

            OpenTK.Matrix4 projection = OpenTK.Matrix4.CreatePerspectiveFieldOfView(120 * deg2rad, screenscale, 0.00001f, (float)step * 20000);
            GL.LoadMatrix(ref projection);

            Matrix4 modelview = Matrix4.LookAt((float)cameraX, (float)cameraY, (float)cameraZ, (float)lookX, (float)lookY, (float)lookZ, 0, 0, 1);

            GL.MatrixMode(MatrixMode.Modelview);

            // roll
            modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationZ(rpy.X * deg2rad));
            // pitch
            modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationX((rpy.Y - 15) * -deg2rad));

            GL.LoadMatrix(ref modelview);

            GL.ClearColor(Color.CornflowerBlue);

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.AccumBufferBit);

            GL.LightModel(LightModelParameter.LightModelAmbient, new float[] { 1f, 1f, 1f, 1f });

            //  GL.Disable(EnableCap.Fog);
            GL.Enable(EnableCap.Fog);
            //GL.Enable(EnableCap.Lighting);
            //GL.Enable(EnableCap.Light0);

            GL.Fog(FogParameter.FogColor, new float[] { 100 / 255.0f, 149 / 255.0f, 237 / 255.0f, 1f });
            //GL.Fog(FogParameter.FogDensity,0.1f);
            GL.Fog(FogParameter.FogMode, (int)FogMode.Linear);
            GL.Fog(FogParameter.FogStart, (float)step * 40);
            GL.Fog(FogParameter.FogEnd, (float)(step * 50));

//            GL.Enable(EnableCap.DepthTest);
            GL.DepthFunc(DepthFunction.Always);

            /*
             * GL.Begin(BeginMode.LineStrip);
             *
             * GL.Color3(Color.White);
             * GL.Vertex3(0, 0, 0);
             *
             * //GL.Color3(Color.Red);
             * GL.Vertex3(area.Bottom, 0, area.Left);
             *
             * //GL.Color3(Color.Yellow);
             * GL.Vertex3(lookX, lookY, lookZ);
             *
             * //GL.Color3(Color.Green);
             * GL.Vertex3(cameraX, cameraY, cameraZ);
             *
             * GL.End();
             */
            /*
             * GL.PointSize(10);
             * GL.Color4(Color.Yellow);
             * GL.LineWidth(5);
             *
             *
             * GL.Begin(PrimitiveType.LineStrip);
             *
             * //GL.Vertex3(new Vector3((float)center.Lng,(float)center.Lat,(float)(center.Alt * heightscale)));
             * //GL.Vertex3(new Vector3(0, 0, 0));
             * //GL.Vertex3(new Vector3((float)cameraX, (float)cameraY, (float)cameraZ));
             * //GL.Color3(Color.Green);
             * //GL.Vertex3(new Vector3((float)lookX, (float)lookY, (float)lookZ));
             *
             * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, (float)cameraZ);
             * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationRightBottom.Lat, (float)cameraZ);
             * GL.Vertex3(area.LocationRightBottom.Lng, area.LocationRightBottom.Lat, (float)cameraZ);
             * GL.Vertex3(area.LocationRightBottom.Lng, area.LocationTopLeft.Lat, (float)cameraZ);
             * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, (float)cameraZ);
             *
             * GL.End();
             */
            GL.Finish();

            GL.PointSize((float)(step * 1));
            GL.Color3(Color.Blue);
            GL.Begin(PrimitiveType.Points);
            GL.Vertex3(new Vector3((float)center.Lng, (float)center.Lat, (float)cameraZ));
            GL.End();



            //GL.ClampColor(ClampColorTarget.ClampReadColor, ClampColorMode.True);

            /*
             * GL.Enable(EnableCap.Blend);
             * GL.DepthMask(false);
             * GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.Src1Color);
             * GL.DepthMask(true);
             * GL.Disable(EnableCap.Blend);
             */
            // textureid.Clear();

            // get level 10 tiles
            List <GPoint> tileArea1 = prj.GetAreaTileList(area, otherzoomlevel, 1);

            // get type list at new zoom level
            List <GPoint> tileArea2 = prj.GetAreaTileList(area, zoom, 2);

            List <GPoint> tileArea = new List <GPoint>();

            tileArea.AddRange(tileArea1);
            tileArea.AddRange(tileArea2);

            // get tiles & combine into one
            foreach (var p in tileArea)
            {
                int localzoom = zoom;

                core.tileDrawingListLock.AcquireReaderLock();
                core.Matrix.EnterReadLock();
                try
                {
                    if (tileArea1.Contains(p))
                    {
                        localzoom = otherzoomlevel;
                    }

                    topLeftPx = prj.FromLatLngToPixel(area.LocationTopLeft, localzoom);

                    GMap.NET.Internals.Tile t = core.Matrix.GetTileWithNoLock(localzoom, p);

                    if (t.NotEmpty)
                    {
                        foreach (GMapImage img in t.Overlays)
                        {
                            if (!textureid.ContainsKey(p))
                            {
                                generateTexture(p, (Bitmap)img.Img);
                            }
                        }
                    }
                    else
                    {
                    }
                }
                finally
                {
                    core.Matrix.LeaveReadLock();
                    core.tileDrawingListLock.ReleaseReaderLock();
                }

                //GMapImage tile = ((PureImageCache)Maps.MyImageCache.Instance).GetImageFromCache(type.DbId, p, zoom) as GMapImage;

                //if (tile != null && !textureid.ContainsKey(p))
                {
                    //  generateTexture(p, (Bitmap)tile.Img);
                }

                if (textureid.ContainsKey(p))
                {
                    int texture = textureid[p];

                    GL.Enable(EnableCap.Texture2D);
                    GL.BindTexture(TextureTarget.Texture2D, texture);
                }
                else
                {
                    //Console.WriteLine("Missing tile");
                    continue;
                }

                long x = p.X * prj.TileSize.Width - topLeftPx.X;
                long y = p.Y * prj.TileSize.Width - topLeftPx.Y;

                long xr = p.X * prj.TileSize.Width;
                long yr = p.Y * prj.TileSize.Width;

                long x2 = (p.X + 1) * prj.TileSize.Width;
                long y2 = (p.Y + 1) * prj.TileSize.Width;


                GL.LineWidth(0);
                GL.Color3(Color.White);

                // generate terrain
                GL.Begin(PrimitiveType.TriangleStrip);

                var latlng = prj.FromPixelToLatLng(xr, yr, localzoom);

                double heightl = srtm.getAltitude(latlng.Lat, latlng.Lng).alt;
                if (localzoom == 10)
                {
                    heightl = 0;
                }

                //xr - topLeftPx.X, yr - topLeftPx.Y
                GL.TexCoord2(0, 0);
                GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale);


                // next down
                latlng = prj.FromPixelToLatLng(xr, y2, localzoom);

                heightl = srtm.getAltitude(latlng.Lat, latlng.Lng).alt;
                if (localzoom == 10)
                {
                    heightl = 0;
                }

                GL.TexCoord2(0, 1);
                GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale);


                // next right
                latlng = prj.FromPixelToLatLng(x2, yr, localzoom);

                heightl = srtm.getAltitude(latlng.Lat, latlng.Lng).alt;
                if (localzoom == 10)
                {
                    heightl = 0;
                }

                GL.TexCoord2(1, 0);
                GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale);


                // next right down
                latlng = prj.FromPixelToLatLng(x2, y2, localzoom);

                heightl = srtm.getAltitude(latlng.Lat, latlng.Lng).alt;
                if (localzoom == 10)
                {
                    heightl = 0;
                }

                GL.TexCoord2(1, 1);
                GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale);

                GL.End();
            }

            GL.Flush();

            try
            {
                this.SwapBuffers();


                Context.MakeCurrent(null);
            }
            catch { }

            //this.Invalidate();

            return;
        }
Пример #4
0
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            if (this.DesignMode)
            {
                return;
            }

            if (area.LocationMiddle.Lat == 0 && area.LocationMiddle.Lng == 0)
            {
                return;
            }

            try
            {
                base.OnPaint(e);
            }
            catch { return; }

            double heightscale = (step / 90.0) * 3;

            float yawradians = (float)(Math.PI * (rpy.Z * 1) / 180.0f);

            //radians = 0;

            float mouseY = (float)(0.0025);

            cameraX = area.LocationMiddle.Lng;                                                                                                                                           // -Math.Sin(yawradians) * mouseY;     // multiplying by mouseY makes the
            cameraY = area.LocationMiddle.Lat;                                                                                                                                           // -Math.Cos(yawradians) * mouseY;    // camera get closer/farther away with mouseY
            cameraZ = (LocationCenter.Alt < srtm.getAltitude(center.Lat, center.Lng)) ? (srtm.getAltitude(center.Lat, center.Lng) + 1) * heightscale : LocationCenter.Alt * heightscale; // (srtm.getAltitude(lookZ, lookX, 20) + 100) * heighscale;

            lookX = area.LocationMiddle.Lng + Math.Sin(yawradians) * mouseY;
            lookY = area.LocationMiddle.Lat + Math.Cos(yawradians) * mouseY;
            lookZ = cameraZ;

            // cameraZ += 0.04;

            GMapProvider   type = GMap.NET.MapProviders.GoogleSatelliteMapProvider.Instance;
            PureProjection prj  = type.Projection;


            PointLatLngAlt leftf  = center.newpos(rpy.Z, 500);
            PointLatLngAlt rightf = center.newpos(rpy.Z, 10);
            PointLatLngAlt left   = center.newpos(rpy.Z - 90, 500);
            PointLatLngAlt right  = center.newpos(rpy.Z + 90, 500);

            double maxlat = Math.Max(left.Lat, Math.Max(right.Lat, Math.Max(leftf.Lat, rightf.Lat)));
            double minlat = Math.Min(left.Lat, Math.Min(right.Lat, Math.Min(leftf.Lat, rightf.Lat)));

            double maxlng = Math.Max(left.Lng, Math.Max(right.Lng, Math.Max(leftf.Lng, rightf.Lng)));
            double minlng = Math.Min(left.Lng, Math.Min(right.Lng, Math.Min(leftf.Lng, rightf.Lng)));

            area = RectLatLng.FromLTRB(minlng, maxlat, maxlng, minlat);

            GPoint topLeftPx     = prj.FromLatLngToPixel(area.LocationTopLeft, zoom);
            GPoint rightButtomPx = prj.FromLatLngToPixel(area.Bottom, area.Right, zoom);
            GPoint pxDelta       = new GPoint(rightButtomPx.X - topLeftPx.X, rightButtomPx.Y - topLeftPx.Y);

            zoom = 17;

            // zoom based on pixel density
            while (pxDelta.X > 2000)
            {
                zoom--;

                // current area
                topLeftPx     = prj.FromLatLngToPixel(area.LocationTopLeft, zoom);
                rightButtomPx = prj.FromLatLngToPixel(area.Bottom, area.Right, zoom);
                pxDelta       = new GPoint(rightButtomPx.X - topLeftPx.X, rightButtomPx.Y - topLeftPx.Y);
            }

            // update once per seconds - we only read from disk, so need to let cahce settle
            if (lastrefresh.AddSeconds(.6) < DateTime.Now)
            {
                // get tiles - bg
                core.Provider = type;
                core.Position = LocationCenter;
                core.Zoom     = zoom;
                core.OnMapSizeChanged(this.Width, this.Height);

                lastrefresh = DateTime.Now;
            }
            else
            {
                //return;
            }

            MakeCurrent();


            GL.MatrixMode(MatrixMode.Projection);

            OpenTK.Matrix4 projection = OpenTK.Matrix4.CreatePerspectiveFieldOfView(130 * deg2rad, 1f, 0.00001f, (float)step * 100);
            GL.LoadMatrix(ref projection);

            Matrix4 modelview = Matrix4.LookAt((float)cameraX, (float)cameraY, (float)cameraZ, (float)lookX, (float)lookY, (float)lookZ, 0, 0, 1);

            GL.MatrixMode(MatrixMode.Modelview);

            // roll
            modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationZ(rpy.X * deg2rad));
            // pitch
            modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationX((rpy.Y - 10) * -deg2rad));

            GL.LoadMatrix(ref modelview);

            GL.ClearColor(Color.LightBlue);

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            GL.LightModel(LightModelParameter.LightModelAmbient, new float[] { 1f, 1f, 1f, 1f });

            GL.Enable(EnableCap.Fog);
            // GL.Enable(EnableCap.Lighting);
            // GL.Enable(EnableCap.Light0);

            GL.Fog(FogParameter.FogColor, new float[] { 0.5f, 0.5f, 0.5f, 1f });
            //GL.Fog(FogParameter.FogDensity,0.1f);
            GL.Fog(FogParameter.FogMode, (int)FogMode.Linear);
            GL.Fog(FogParameter.FogStart, (float)step * 1);
            GL.Fog(FogParameter.FogEnd, (float)(step * 7));

            /*
             * GL.Begin(BeginMode.LineStrip);
             *
             * GL.Color3(Color.White);
             * GL.Vertex3(0, 0, 0);
             *
             * GL.Vertex3(area.Bottom, 0, area.Left);
             *
             * GL.Vertex3(lookX, lookY, lookZ);
             *
             * //GL.Vertex3(cameraX, cameraY, cameraZ);
             *
             * GL.End();
             */

            GL.Begin(PrimitiveType.LineStrip);
            GL.PointSize(200);
            GL.Color3(Color.Red);
            //GL.Vertex3(new Vector3((float)center.Lng,(float)center.Lat,(float)(center.Alt * heightscale)));
            //GL.Vertex3(new Vector3(0, 0, 0));
            //GL.Vertex3(new Vector3((float)cameraX, (float)cameraY, (float)cameraZ));
            //GL.Color3(Color.Green);
            //GL.Vertex3(new Vector3((float)lookX, (float)lookY, (float)lookZ));

            GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, 0);
            GL.Vertex3(area.LocationTopLeft.Lng, area.LocationRightBottom.Lat, 0);
            GL.Vertex3(area.LocationRightBottom.Lng, area.LocationRightBottom.Lat, 0);
            GL.Vertex3(area.LocationRightBottom.Lng, area.LocationTopLeft.Lat, 0);
            GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, 0);

            GL.End();

            GL.Begin(PrimitiveType.LineStrip);
            GL.PointSize(200);
            GL.Color3(Color.Red);
            GL.Vertex3(new Vector3((float)center.Lng, (float)center.Lat, 0));
            GL.Vertex3(new Vector3((float)leftf.Lng, (float)leftf.Lat, 0));

            GL.End();

            GL.Begin(PrimitiveType.Points);
            GL.PointSize(100);
            GL.Color3(Color.Blue);
            GL.Vertex3(new Vector3((float)center.Lng, (float)center.Lat, 0));
            GL.End();

            //textureid.Clear();

            // get type list at new zoom level
            List <GPoint> tileArea = prj.GetAreaTileList(area, zoom, 0);

            // get tiles & combine into one
            foreach (var p in tileArea)
            {
                core.tileDrawingListLock.AcquireReaderLock();
                core.Matrix.EnterReadLock();
                try
                {
                    GMap.NET.Internals.Tile t = core.Matrix.GetTileWithNoLock(core.Zoom, p);

                    if (t.NotEmpty)
                    {
                        foreach (GMapImage img in t.Overlays)
                        {
                            if (!textureid.ContainsKey(p))
                            {
                                generateTexture(p, (Bitmap)img.Img);
                            }
                        }
                    }
                    else
                    {
                    }
                }
                finally
                {
                    core.Matrix.LeaveReadLock();
                    core.tileDrawingListLock.ReleaseReaderLock();
                }

                //GMapImage tile = ((PureImageCache)Maps.MyImageCache.Instance).GetImageFromCache(type.DbId, p, zoom) as GMapImage;

                //if (tile != null && !textureid.ContainsKey(p))
                {
                    //  generateTexture(p, (Bitmap)tile.Img);
                }

                if (textureid.ContainsKey(p))
                {
                    int texture = textureid[p];

                    GL.Enable(EnableCap.Texture2D);
                    GL.BindTexture(TextureTarget.Texture2D, texture);
                }
                else
                {
                    GL.Disable(EnableCap.Texture2D);
                }

                long x = p.X * prj.TileSize.Width - topLeftPx.X;
                long y = p.Y * prj.TileSize.Width - topLeftPx.Y;

                long xr = p.X * prj.TileSize.Width;
                long yr = p.Y * prj.TileSize.Width;

                long x2 = (p.X + 1) * prj.TileSize.Width;
                long y2 = (p.Y + 1) * prj.TileSize.Width;

                // generate terrain
                GL.Begin(PrimitiveType.TriangleStrip);

                var latlng = prj.FromPixelToLatLng(xr, yr, zoom);

                double heightl = srtm.getAltitude(latlng.Lat, latlng.Lng);

                GL.Color3(Color.White);
                //xr - topLeftPx.X, yr - topLeftPx.Y
                GL.TexCoord2(0, 0);
                GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale);


                // next down
                latlng = prj.FromPixelToLatLng(xr, y2, zoom);

                heightl = srtm.getAltitude(latlng.Lat, latlng.Lng);

                GL.TexCoord2(0, .99);
                GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale);


                // next right
                latlng = prj.FromPixelToLatLng(x2, yr, zoom);

                heightl = srtm.getAltitude(latlng.Lat, latlng.Lng);

                GL.TexCoord2(.99, 0);
                GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale);


                // next right down
                latlng = prj.FromPixelToLatLng(x2, y2, zoom);

                heightl = srtm.getAltitude(latlng.Lat, latlng.Lng);

                GL.TexCoord2(.99, .99);
                GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale);

                GL.End();
            }


            GL.Enable(EnableCap.Blend);
            GL.DepthMask(false);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);
            GL.DepthMask(true);
            GL.Disable(EnableCap.Blend);

            GL.Flush();

            try
            {
                this.SwapBuffers();


                Context.MakeCurrent(null);
            }
            catch { }

            return;
        }