Esempio n. 1
0
        private Bitmap prepareTrackBmp(Rectangle trackRect, Gps2PixelProjection trackProj, TrackParser td)
        {
            // We need at least a lap to draw something
            if (!td.HasSamples || trackProj == null)
            {
                return(null);
            }

            // We'll draw one of the laps. Just get the first lap.
            TrackParser.Lap currLap = td.Laps[0];

            int    w   = trackRect.Width;
            int    h   = trackRect.Height;
            Bitmap bmp = new Bitmap(w, h);

            using (Graphics g = Graphics.FromImage(bmp)) {
                using (Brush bgColor = new SolidBrush(Color.Gray),
                       trackColor = new SolidBrush(Color.Yellow)) {
                    using (Pen trackPen = new Pen(trackColor, kTrackWidth)) {
                        g.FillRectangle(bgColor, 0, 0, w, h);

                        List <TrackParser.Sample> samples = td.Samples;
                        TrackParser.Sample        s       = samples[0];
                        CPointF last = new CPointF();
                        CPointF next = new CPointF();

                        transformGpsCoord(s.mLongtiude, s.mLatitude, trackProj, last);

                        float px = (float)trackProj.mPixelOffsetX;
                        float py = (float)trackProj.mPixelOffsetY;

                        last.mX -= px;
                        last.mY -= py;

                        for (int i = 1, n = samples.Count; i < n; i++)
                        {
                            s = samples[i];
                            if (s.mLap != currLap)
                            {
                                continue;
                            }

                            transformGpsCoord(s.mLongtiude, s.mLatitude, trackProj, next);
                            next.mX -= px;
                            next.mY -= py;

                            g.DrawLine(trackPen, last.mX, last.mY, next.mX, next.mY);

                            last.mX = next.mX;
                            last.mY = next.mY;
                        }
                    }
                }
            }

            return(bmp);
        }
Esempio n. 2
0
        private void transformGpsCoord(double longitude, double latitude,
                                       Gps2PixelProjection proj,
                                       CPointF outPoint)
        {
            double px = (longitude - proj.mGpsOffsetX) * proj.mGpsScaleX + proj.mPixelOffsetX;
            double py = (latitude - proj.mGpsOffsetY) * proj.mGpsScaleY + proj.mPixelOffsetY;

            outPoint.mX = (float)px;
            outPoint.mY = (float)py;
        }
Esempio n. 3
0
        private void drawTrackPos(Graphics g, Brush posColor,
                                  Rectangle trackRect, Bitmap trackBmp,
                                  Gps2PixelProjection trackProj,
                                  double longitude, double latitude)
        {
            if (trackProj == null)
            {
                return;
            }

            g.DrawImageUnscaled(trackBmp, trackRect);

            transformGpsCoord(longitude, latitude, trackProj, mTempPointF);

            g.FillEllipse(posColor,
                          mTempPointF.mX - kTrackPosRadius, mTempPointF.mY - kTrackPosRadius,
                          kTrackPosRadius * 2, kTrackPosRadius * 2);
        }
Esempio n. 4
0
        // --- GPS to track rect & bitmap ---

        private Gps2PixelProjection prepareTrackProj(Rectangle rect, TrackParser td, out Rectangle trackRect)
        {
            // we need at least one point to do something
            if (!td.HasSamples)
            {
                trackRect = Rectangle.Empty;
                return(null);
            }

            double minLong = Double.PositiveInfinity,
                   maxLong = Double.NegativeInfinity,
                   minLat  = Double.PositiveInfinity,
                   maxLat  = Double.NegativeInfinity;

            foreach (TrackParser.Sample d in td.Samples)
            {
                minLong = Math.Min(minLong, d.mLongtiude);
                maxLong = Math.Max(maxLong, d.mLongtiude);
                minLat  = Math.Min(minLat, d.mLatitude);
                maxLat  = Math.Max(maxLat, d.mLatitude);
            }

            // we want to map the min..maxLong(+X)..Lat(-Y) to the given rect
            // rect top left corner (it's x/y base) corresponds to minLong/maxLat.

            float x = rect.X;
            float y = rect.Y;
            float w = rect.Width;
            float h = rect.Height;

            // currently use a square part of the dest rect
            if (w > h)
            {
                w = h;
            }
            else
            {
                h = w;
            }

            // adjust for track border
            x += kTrackBorder;
            y += kTrackBorder;
            w -= 2 * kTrackBorder;
            h -= 2 * kTrackBorder;

            trackRect = new Rectangle((int)x, (int)y, (int)w, (int)h);

            // Compute offset and scaling to transform a coord point into a screen point

            Gps2PixelProjection proj = new Gps2PixelProjection();

            proj.mGpsOffsetX = minLong;
            proj.mGpsOffsetY = maxLat;

            proj.mPixelOffsetX = x;
            proj.mPixelOffsetY = y;

            proj.mGpsScaleX = (maxLong > minLong) ? w / (maxLong - minLong) : 0;
            proj.mGpsScaleY = (maxLat > minLat) ? h / (minLat - maxLat) : 0;

            return(proj);
        }
Esempio n. 5
0
        private void threadEntryPoint()
        {
            int         fps = mFps;
            int         msx = mMovieSx;
            int         msy = mMovieSy;
            int         tsx = mTrackSx;
            int         tsy = mTrackSy;
            TrackParser td  = mTrackData;

            using (Graphics g = Graphics.FromImage(mAviBmp)) {
                using (Brush chromaColor = new SolidBrush(Color.Blue),
                       bgColor = new SolidBrush(Color.Gray),
                       posColor = new SolidBrush(Color.Red),
                       textColor = new SolidBrush(Color.Orange)) {
                    Rectangle bgRect = new Rectangle(msx - tsx, msy - tsy, tsx, tsy);

                    int nbFrames = (int)(mTrackData.TotalTime * fps);

                    // prepare track drawing (map GPS coord => screen coord: offset + scale)
                    Rectangle           trackRect;
                    Gps2PixelProjection trackProj = prepareTrackProj(bgRect, td, out trackRect);
                    Bitmap trackBmp = prepareTrackBmp(trackRect, trackProj, td);

                    // prepare g-meter pos

                    // prepare text positions

                    PointF[] textPos;
                    using (Font labelFont = prepareText(bgRect, out textPos),
                           numFont = new Font(FontFamily.GenericMonospace, labelFont.Size, FontStyle.Bold)) {
                        Interpolator interp = new Interpolator(td);

                        double invFps = 1 / (double)fps;

                        bool userStopRequested = false;

                        for (int frame = 0, updateFps = 0;
                             frame < nbFrames && !userStopRequested;
                             frame++, updateFps++)
                        {
                            double currTime = (double)frame * invFps;

                            TrackParser.Sample currSample = interp.GoTo(currTime);

                            double currLapTime = interp.CurrLapTime;

                            // keep track of current dot & interpolate between dots

                            // draw background

                            g.FillRectangle(chromaColor, 0, 0, msx, msy);

                            g.FillRectangle(bgColor, bgRect);

                            // draw track + current pos
                            drawTrackPos(g, posColor, trackRect, trackBmp, trackProj,
                                         currSample.mLongtiude, currSample.mLatitude);

                            // draw bearing

                            // TODO

                            // draw text
                            drawText(g, textColor, labelFont, numFont, textPos,
                                     currSample.mSpeed, currSample.mAccel, currSample.mLateralAccel,
                                     currTime,
                                     currLapTime, interp.CurrLapIndex, interp.LastLapDuration);

                            // finally dump frame and update preview/progress
                            MainModule.MainForm.Invoke(mAddFrameFunc);

                            if (updateFps == fps)
                            {
                                updateFps = 0;
                            }
                            if (updateFps == 0)
                            {
                                // Update status, progress, etc.
                                userStopRequested = syncUpdate(frame, nbFrames, new Bitmap(mAviBmp));
                            }

                            if (mThreadMustStop)
                            {
                                break;
                            }
                        }
                    } // using Font

                    // Make sure to tell owner that the generator is done
                    // This one must be async -- this thread will quit and the owner will
                    // try to join to wait for the thread to finish.
                    asyncUpdate(nbFrames, nbFrames, new Bitmap(mAviBmp));
                } // using Brush
            }     // using Graphics
        }