Subversion Repositories Projects

Rev

Rev 1565 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package dongfang.mkt.ui.offscreendisplay;

/*
 * u/l:         geotagged geo:lat=47.327450 geo:lon=8.521657
 * l/r:         geotagged geo:lat=47.321749 geo:lon=8.534403
 * house:       geotagged geo:lat=47.324614 geo:lon=8.528202
 */


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.Formatter;
import java.util.Locale;

import javax.swing.JPanel;

import dongfang.mkt.datatype.GPSPosition;
import dongfang.mkt.frames.OSDDataResponseFrame;

public class MapImageView extends JPanel implements OSDDataConsumer {
        private Image mapImage;
        private Image copterImage;

        private static final int MAPWIDTH = (int)(1132);
        private static final int MAPHEIGHT = (int)(977);

        // It is assumed the map is north/south oriented!
        private GPSPosition upperLeft;
        private GPSPosition lowerRight;

        private GPSPosition copterPosition;
        private GPSPosition homePosition;
       
        private int noseDirection;
        private int flightDirection;
        private double speed;
        private double height;
       
        private static final double degToRadianFactor = 360 / 2 / Math.PI;

        private double relativeX(GPSPosition pos) {
                double lon = pos.getLongitude();
                // The sign should be OK here (positive) both east and west.
                double span = lowerRight.getLongitude() - upperLeft.getLongitude();
                double offset = lon - upperLeft.getLongitude();
                double result = offset / span;
                if (result<0) result = 0; else if(result>1) result=1;
                return result;
        }

        private double relativeY(GPSPosition pos) {
                double lat = pos.getLatitude();
                // The sign should be OK here (positive) both east and west.
                double span = lowerRight.getLatitude() - upperLeft.getLatitude();
                double offset = lat - upperLeft.getLatitude();
                double result = offset / span;
                if (result<0) result = 0; else if(result>1) result=1;
                return result;
        }

        public void paintComponent(Graphics g) {
                int size = 32;
                int noseDotSize = 10;

                Graphics2D g2d = (Graphics2D)g;
                g2d.setStroke(new BasicStroke(5));
               
                // Draw our Image object.

                g2d.drawImage(mapImage, 0, 0, MAPWIDTH, MAPHEIGHT, this); // at location
               
                if (homePosition != null) {
                        g.setColor(Color.blue);
                        int x = (int)(MAPWIDTH * relativeX(homePosition) + 0.5);
                        int y = (int)(MAPHEIGHT * relativeY(homePosition) + 0.5);
                        g.drawRect(x-size/2, y-size/2, size, size);
                }

                if (copterPosition != null) {
                        int x = (int)(MAPWIDTH * relativeX(copterPosition) + 0.5);
                        int y = (int)(MAPHEIGHT * relativeY(copterPosition) + 0.5);

                        //g2d.clearRect(x-100, y-100, 200, 200);

                        double speedfactor = 15;
                       
                        int speedArrowX = x + (int)(speedfactor * speed * Math.cos((90 - flightDirection) / degToRadianFactor));
                        int speedArrowY = y - (int)(speedfactor * speed * Math.sin((90 - flightDirection) / degToRadianFactor));

                        int noseDotX = x + (int)(size/2 * Math.cos((90 - noseDirection) / degToRadianFactor));
                        int noseDotY = y - (int)(size/2 * Math.sin((90 - noseDirection) / degToRadianFactor));
                        int noseDotEndX = x + (int)(size * Math.cos((90 - noseDirection) / degToRadianFactor));
                        int noseDotEndY = y - (int)(size * Math.sin((90 - noseDirection) / degToRadianFactor));
                       
                        g2d.setColor(Color.yellow);
                        g.drawLine(x, y, speedArrowX, speedArrowY);

                        g2d.setColor(Color.red);
                        g.drawArc(x-size/2, y-size/2, size, size, 0, 360);
                       
                        //g2d.setStroke(new BasicStroke(5));
                        g.drawLine(noseDotX, noseDotY, noseDotEndX, noseDotEndY);
                       
                        String heightFormatString = "%+10.1f";
                        StringBuilder sb = new StringBuilder();
                        Formatter formatter = new Formatter(sb, Locale.US);
                        formatter.format(heightFormatString, height);

                        g.setColor(Color.green);
                        Font f = g2d.getFont();
                        f = f.deriveFont(18.0f);
                        f = f.deriveFont(Font.BOLD);
                        g2d.setFont(f);
                        g.drawString(sb.toString(), x-120, y);
                }
        }
       
        public void update(OSDDataResponseFrame data, long timestamp) {
                if (data==null) return;
                copterPosition = data.getCurrentPosition();
                homePosition = data.getHomePosition();
                speed = data.getGroundSpeed();
                height = data.getHeightByPressure();
                noseDirection = data.getCompassHeading();
                flightDirection = data.getDirectionOfFlight();
               
                repaint();
        }
       
        public void init() {
                GPSPosition upperLeft = new GPSPosition();
                GPSPosition lowerRight = new GPSPosition();
               
                /*
                upperLeft.setLatitude(47.328355);
                upperLeft.setLongitude(8.518231);

                // * l/r:               geotagged geo:lat=47.321749 geo:lon=8.534403
                lowerRight.setLatitude(47.321532);
                lowerRight.setLongitude(8.530822);
               
                // geotagged geo:lat=47.324614 geo:lon=8.528202
                highlight.setLatitude(47.324714);
                highlight.setLongitude(8.528102);
                */

                upperLeft.setLatitude(47.344577);
                upperLeft.setLongitude(8.529304);

                // * l/r:               geotagged geo:lat=47.321749 geo:lon=8.534403
                lowerRight.setLatitude(47.337576);
                lowerRight.setLongitude(8.542220);
               
                setSize(MAPWIDTH, MAPHEIGHT);
                this.upperLeft = upperLeft;
                this.lowerRight = lowerRight;
                mapImage = Toolkit.getDefaultToolkit().getImage("qth.jpg");
        }
}