예제 #1
0
 /// <summary>
 /// Creating a new document using the specified map, route, laps, initial transformation matrix, projection origin and document settings, and adding one new session with the specified route and laps.
 /// </summary>
 /// <param name="map"></param>
 /// <param name="route"></param>
 /// <param name="laps"></param>
 /// <param name="initialTransformationMatrix"></param>
 /// <param name="projectionOrigin"></param>
 /// <param name="settings"></param>
 public Document(Map map, Route route, LapCollection laps, GeneralMatrix initialTransformationMatrix, LongLat projectionOrigin, DocumentSettings settings)
 {
     Map = map;
       sessions.Add(new Session(route, laps, map.Image.Size, initialTransformationMatrix, projectionOrigin, settings.DefaultSessionSettings));
       this.settings = settings;
       UpdateDocumentToCurrentVersion(this);
 }
        public static GeneralMatrix CreateInitialTransformationMatrix(Route route, Size mapSize, LongLat projectionOrigin)
        {
            // create initial adjustment: route should fit in the 75% inner rectangle of the map
              RectangleD routeRectangle = route.BoundingProjectedRectangle(projectionOrigin);
              RectangleD mapRectangle = new RectangleD(1.0 / 8.0 * mapSize.Width, 1.0 / 8.0 * mapSize.Height, 3.0 / 4.0 * mapSize.Width, 3.0 / 4.0 * mapSize.Height);

              // check width/height ratio for each of the rectangles, and adjust the map rectangle to have the same ratio as the route rectangle
              double routeRatio = routeRectangle.Width / routeRectangle.Height;
              double mapRatio = mapRectangle.Width / mapRectangle.Height;
              if (mapRatio < routeRatio)
              {
            // too narrow
            mapRectangle = new RectangleD(mapRectangle.Left, mapRectangle.Center.Y - mapRectangle.Width / routeRatio / 2.0, mapRectangle.Width, mapRectangle.Width / routeRatio);
              }
              else
              {
            // too wide
            mapRectangle = new RectangleD(mapRectangle.Center.X - mapRectangle.Height * routeRatio / 2.0, mapRectangle.Top, mapRectangle.Height * routeRatio, mapRectangle.Height);
              }

              GeneralMatrix t = LinearAlgebraUtil.CalculateTransformationMatrix(routeRectangle.LowerLeft, mapRectangle.UpperLeft, routeRectangle.UpperRight, mapRectangle.LowerRight, null, false);

              return t;
        }
예제 #3
0
 /// <summary>
 /// Creating a new document using the specified map, route, laps, initial transformation matrix and document settings, and adding one new session with the specified route and laps.
 /// </summary>
 /// <param name="map"></param>
 /// <param name="route"></param>
 /// <param name="laps"></param>
 /// <param name="initialTransformationMatrix"></param>
 /// <param name="settings"></param>
 public Document(Map map, Route route, LapCollection laps, GeneralMatrix initialTransformationMatrix, DocumentSettings settings)
     : this(map, route, laps, initialTransformationMatrix, null, settings)
 {
 }
예제 #4
0
 /// <summary>
 /// Creating a new document using the specified map, route, laps, and document settings, and adding one new session with the specified route and laps.
 /// </summary>
 /// <param name="map"></param>
 /// <param name="route"></param>
 /// <param name="laps"></param>
 /// <param name="settings"></param>
 public Document(Map map, Route route, LapCollection laps, DocumentSettings settings)
     : this(map, route, laps, null, settings)
 {
 }
예제 #5
0
        private static Bitmap CreateRouteThumbnail(Route route, Size thumbnailSize, Color routeLineColor, double routeLineWidth)
        {
            var bitmap = new Bitmap(thumbnailSize.Width, thumbnailSize.Width);
              var projectionOrigin = route.CenterLongLat();

              // get coordinates of lines
              double minX = 0, maxX = 0, minY = 0, maxY = 0;
              var lines = new List<List<PointD>>();
              foreach (var segment in route.Segments)
              {
            var vertices = new List<PointD>();
            foreach (var waypoint in segment.Waypoints)
            {
              var vertex = waypoint.LongLat.Project(projectionOrigin);
              vertices.Add(vertex);
              // calculate bounds
              if (lines.Count == 0 && vertices.Count == 0)
              {
            minX = vertex.X;
            minY = vertex.Y;
            maxX = vertex.X;
            maxY = vertex.Y;
              }
              else
              {
            minX = Math.Min(minX, vertex.X);
            minY = Math.Min(minY, vertex.Y);
            maxX = Math.Max(maxX, vertex.X);
            maxY = Math.Max(maxY, vertex.Y);
              }
            }
            lines.Add(vertices);
              }

              var scale = Math.Min((thumbnailSize.Width - 1) / (maxX == minX ? 0 : maxX - minX),
                           (thumbnailSize.Height - 1) / (maxY == minY ? 0 : maxY - minY));
              var offsetX = (thumbnailSize.Width - (maxX - minX) * scale) / 2;
              var offsetY = (thumbnailSize.Height - (maxY - minY) * scale) / 2;

              // map coordinates onto thumbnail
              var mappedLines = new List<List<PointF>>();
              foreach (var line in lines)
              {
            var mappedVertices = new List<PointF>();
            foreach (var vertex in line)
            {
              mappedVertices.Add((PointF)new PointD(
            offsetX + scale * (vertex.X - minX),
            (thumbnailSize.Height - 1) - (offsetY + scale * (vertex.Y - minY))));
            }
            mappedLines.Add(mappedVertices);
              }

              using (var g = Graphics.FromImage(bitmap))
              {
            g.SmoothingMode = SmoothingMode.AntiAlias;
            foreach (var mappedLine in mappedLines)
            {
              if(mappedLine.Count > 1) g.DrawLines(new Pen(routeLineColor, (float)routeLineWidth), mappedLine.ToArray());
            }
              }

              return bitmap;
        }
        private static Session ReadSession(BinaryReader reader, int length)
        {
            List<DateTime> mapReadingList = null;
              Route route = null;
              HandleCollection handles = null;
              LongLat projectionOrigin = null;
              LapCollection laps = null;
              var startPos = reader.BaseStream.Position;
              SessionInfo sessionInfo = null;
              DateTime lastTime;
              while (reader.BaseStream.Position < startPos + length)
              {
            var tag = (Tags)reader.ReadByte();
            var tagLength = Convert.ToInt32(reader.ReadUInt32());
            switch (tag)
            {
              case Tags.Route:
            var attributes = reader.ReadUInt16();
            var extraWaypointAttributesLength = reader.ReadUInt16();
            var routeSegments = new List<RouteSegment>();
            var segmentCount = reader.ReadUInt32();
            lastTime = DateTime.MinValue;
            for (var i = 0; i < segmentCount; i++)
            {
              var rs = new RouteSegment();
              var waypointCount = reader.ReadUInt32();
              for (var j = 0; j < waypointCount; j++)
              {
                var w = new Waypoint();
                w.LongLat = ReadLongLat(reader);
                w.Time = ReadTime(lastTime, reader);
                lastTime = w.Time;
                if ((attributes & (UInt16)WaypointAttribute.HeartRate) == (UInt16)WaypointAttribute.HeartRate)
                {
                  w.HeartRate = reader.ReadByte();
                }
                if ((attributes & (UInt16)WaypointAttribute.Altitude) == (UInt16)WaypointAttribute.Altitude)
                {
                  w.Altitude = reader.ReadInt16();
                }
                reader.BaseStream.Position += extraWaypointAttributesLength; // for forward compatibility
                rs.Waypoints.Add(w);
              }
              routeSegments.Add(rs);
            }
            route = new Route(routeSegments);
            break;

              case Tags.Handles:
            handles = new HandleCollection();
            var handleCount = reader.ReadUInt32();
            var handleMarkerDrawer = SessionSettings.CreateDefaultMarkerDrawers()[MarkerType.Handle];
            for (var i = 0; i < handleCount; i++)
            {
              var handle = new Handle();
              // transformation matrix
              handle.TransformationMatrix = new GeneralMatrix(3, 3);
              for (var j = 0; j < 9; j++)
              {
                handle.TransformationMatrix.SetElement(j / 3, j % 3, reader.ReadDouble());
              }
              // parameterized location
              var segmentIndex = Convert.ToInt32(reader.ReadUInt32());
              var value = reader.ReadDouble();
              handle.ParameterizedLocation = new ParameterizedLocation(segmentIndex, value);

              // pixel location
              handle.Location = new PointD(reader.ReadDouble(), reader.ReadDouble());
              // type
              handle.Type = (Handle.HandleType)reader.ReadInt16();
              // use default marker drawer
              handle.MarkerDrawer = handleMarkerDrawer;

              handles.Add(handle);
            }
            break;

              case Tags.ProjectionOrigin:
            projectionOrigin = ReadLongLat(reader);
            break;

              case Tags.Laps:
            laps = new LapCollection();
            var lapCount = reader.ReadUInt32();
            for (var i = 0; i < lapCount; i++)
            {
              var lap = new Lap();
              lap.Time = DateTime.FromBinary(reader.ReadInt64());
              lap.LapType = (LapType)reader.ReadByte();
              laps.Add(lap);
            }
            break;

              case Tags.SessionInfo:
            sessionInfo = new SessionInfo();
            sessionInfo.Person = new SessionPerson();
            sessionInfo.Person.Name = ReadString(reader);
            sessionInfo.Person.Club = ReadString(reader);
            sessionInfo.Person.Id = reader.ReadUInt32();
            sessionInfo.Description = ReadString(reader);
            // when more fields are added, check so that tagLength is not passed
            break;

              case Tags.MapReadingInfo:
            mapReadingList = new List<DateTime>();
            lastTime = DateTime.MinValue;
            var startPosition = reader.BaseStream.Position;
            while (reader.BaseStream.Position - startPosition < tagLength)
            {
              var time = ReadTime(lastTime, reader);
              mapReadingList.Add(time);
              lastTime = time;
            }
            break;

              default:
            reader.BaseStream.Position += tagLength;
            break;
            }
              }

              if(mapReadingList != null && route != null) route = new Route(Route.AddMapReadingWaypoints(route.Segments, mapReadingList));
              var session = new Session(
            route,
            laps,
            new Size(0, 0),
            handles != null && handles.Count > 0 ? handles[0].TransformationMatrix : null,
            projectionOrigin,
            new SessionSettings());
              if (handles != null)
              {
            foreach (var h in handles)
            {
              session.AddHandle(h);
            }
              }
              if (sessionInfo != null) session.SessionInfo = sessionInfo;

              return session;
        }