<%// Написано Павлом Атнашевым 27 января 2008 года развлечения ради.%> <%@ Assembly Src="Lib.cs" %> <%@ Import Namespace="Glonass" %> <%@ Import Namespace="System.IO" %> <%@ Import Namespace="System.Drawing" %> <%@ Import Namespace="System.Drawing.Imaging" %> <% int i, j; string[] Values; int x, y; DateTime dt; double PDOP = 6.0; if ((Values = Request.QueryString.GetValues("pdop")) != null) PDOP = double.Parse(Values[0], System.Globalization.CultureInfo.InvariantCulture.NumberFormat); double Elevation = 5.0; if ((Values = Request.QueryString.GetValues("elev")) != null) Elevation = double.Parse(Values[0], System.Globalization.CultureInfo.InvariantCulture.NumberFormat); byte[] Data = (byte[])Cache["Current/" + PDOP.ToString() + "/" + Elevation.ToString()]; if (Data == null) { NKA[] Glonass = (NKA[])Application["Glonass"]; DateTime UpdateDate = (DateTime)Application["UpdateDate"]; dt = DateTime.UtcNow; int t = (int)(dt - UpdateDate).TotalSeconds + 10800; Vector[] poses = new Vector[24]; for (i = 0; i < 24; i++) if (Glonass[i] != null) poses[i] = Glonass[i].GetPos(t); Bitmap world = new Bitmap(Request.PhysicalApplicationPath + @"\world.png"); Bitmap cov = new Bitmap(world.Width, world.Height + 32); Point output = new Point(0, 32); Vector[] vis = new Vector[24]; int count; Matrix m; Vector s, u; double cosElev = Math.Cos((90 - Elevation)/180*Math.PI); for (y = 0; y < world.Height; y++) for (x = 0; x < world.Width; x++) { Color c1 = world.GetPixel(x, y); double b = (world.Height/2.0 - y + 0.5)/(world.Height + 1)*Math.PI; double l = (x - world.Width/2.0 + 0.5)/(world.Width + 1)*2*Math.PI; s.X = (float)(NKA.ae*Math.Cos(l)*Math.Cos(-b)); s.Y = (float)(NKA.ae*Math.Sin(l)*Math.Cos(-b)); s.Z = (float)(-NKA.ae*Math.Sin(-b)); s.D = (float)NKA.ae; count = 0; for (i = 0; i < 24; i++) if (Glonass[i] != null) { u = new Vector(poses[i].X - s.X, poses[i].Y - s.Y, poses[i].Z - s.Z); if (u.DotNormal(s) > cosElev) { u.Normalize(); vis[count] = u; count++; } } if (count >= 4) { m = Matrix.Zero; for (i = 0; i < count; i++) { u = vis[i]; m.M11 += u.X*u.X; m.M12 += u.X*u.Y; m.M13 += u.X*u.Z; m.M14 += u.X; m.M21 += u.Y*u.X; m.M22 += u.Y*u.Y; m.M23 += u.Y*u.Z; m.M24 += u.Y; m.M31 += u.Z*u.X; m.M32 += u.Z*u.Y; m.M33 += u.Z*u.Z; m.M34 += u.Z; m.M41 += u.X; m.M42 += u.Y; m.M43 += u.Z; m.M44 += 1; } if (!m.InvertDiagonal() || m.M11 + m.M22 + m.M33 < 0 || Math.Sqrt(m.M11 + m.M22 + m.M33) > PDOP) c1 = Color.FromArgb((c1.R + 255)/2, c1.G/2, c1.B/2); } if (count > 5) count = 5; double cf = 1.0 - count/5.0; Color c2 = Color.Blue; if (count == 0) { cf = 0.75; c2 = Color.Black; } Color c = Color.FromArgb((int)(c1.R*(1 - cf) + c2.R*cf), (int)(c1.G*(1 - cf) + c2.G*cf), (int)(c1.B*(1 - cf) + c2.B*cf)); cov.SetPixel(output.X + x, output.Y + y, c); } Brush brush = new SolidBrush(Color.Black); Pen pen = new Pen(brush, 1); Graphics graph = Graphics.FromImage(cov); graph.FillRectangle(new SolidBrush(Color.White), 0, 0, cov.Width, 32); graph.DrawLine(pen, 0, 31, cov.Width, 31); StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; graph.DrawString(String.Format("{0} UTC", dt.ToString("g")), new Font("Verdana", 14), brush, new Rectangle(0, 0, cov.Width, 32), format); Font font = new Font("System", 8); System.Drawing.Drawing2D.GraphicsPath sats = new System.Drawing.Drawing2D.GraphicsPath(); for (i = 0; i < 24; i++) if (Glonass[i] != null) { s = poses[i]; s.Normalize(); x = (int)((Math.Atan2(s.Y, s.X)/Math.PI + 1.0)/2.0*world.Width); y = (int)((0.5 - Math.Asin(s.Z)/Math.PI)*world.Height) + 32; sats.AddEllipse(x - 8, y - 8, 16, 16); graph.DrawString(String.Format("{0}", i + 1), font, brush, new Rectangle(x - 8, y - 7, 16, 16), format); } graph.DrawPath(pen, sats); graph.ExcludeClip(new Region(sats)); for (i = 0; i < 24; i++) if (Glonass[i] != null) { for (j = 1; j < 8 && (Glonass[(i & 24) + (((i & 7) + j) & 7)] == null); j++); j = (i & 24) + (((i & 7) + j) & 7); s = poses[i]; s.Normalize(); for (float f = 0.025f; f < 1.0f; f += 0.025f) { u = poses[i]*(1.0f - f) + poses[j]*f; u.Normalize(); float x0 = (float)((Math.Atan2(s.Y, s.X)/Math.PI + 1.0)/2.0*world.Width); float y0 = (float)((0.5 - Math.Asin(s.Z)/Math.PI)*world.Height) + 32; float x1 = (float)((Math.Atan2(u.Y, u.X)/Math.PI + 1.0)/2.0*world.Width); float y1 = (float)((0.5 - Math.Asin(u.Z)/Math.PI)*world.Height) + 32; if ((s.X > 0 || s.Y*u.Y > 0)) graph.DrawLine(pen, x0, y0, x1, y1); else { graph.DrawLine(pen, x0, y0, x1 - world.Width, y1); graph.DrawLine(pen, x0 + world.Width, y0, x1, y1); } s = u; } } MemoryStream ms = new MemoryStream(); cov.Save(ms, ImageFormat.Png); Data = ms.ToArray(); Cache.Add("Current/" + PDOP.ToString() + "/" + Elevation.ToString(), Data, null, DateTime.Now + TimeSpan.FromMinutes(1), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); Application["LastCurrent"] = dt; } else { dt = (DateTime)Application["LastCurrent"]; if ((Values = Request.Headers.GetValues("If-Modified-Since")) != null) { string modstr = Values[0]; i = modstr.IndexOf(';'); if (i >= 0) modstr = modstr.Substring(0, i); i = modstr.IndexOf("GMT"); if (i >= 0) modstr = modstr.Substring(0, i + 3); DateTime Modified = DateTime.Parse(modstr); if (Modified - dt >= TimeSpan.FromSeconds(-30)) { Response.StatusCode = 304; Response.End(); } } } Response.Cache.SetLastModified(dt); Response.Cache.SetCacheability(HttpCacheability.Public); Response.ContentType = "image/png"; Response.BinaryWrite(Data); %>