180 lines
4.6 KiB
Java
180 lines
4.6 KiB
Java
package org.insa.drawing;
|
|
|
|
import java.awt.BasicStroke;
|
|
import java.awt.Color;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.Image;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.geom.NoninvertibleTransformException;
|
|
import java.awt.geom.Point2D;
|
|
import java.awt.image.*;
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
import org.insa.graph.Point;
|
|
|
|
/**
|
|
* Cette implementation de la classe Dessin produit vraiment un affichage
|
|
* (au contraire de la classe DessinInvisible).
|
|
*/
|
|
|
|
public class Drawing extends JPanel {
|
|
|
|
/**
|
|
*
|
|
*/
|
|
private static final long serialVersionUID = 96779785877771827L;
|
|
|
|
private final Graphics2D gr;
|
|
|
|
private double long1, long2, lat1, lat2;
|
|
|
|
// Width and height of the image
|
|
private final int width, height;
|
|
|
|
private Image image;
|
|
private ZoomAndPanListener zoomAndPanListener;
|
|
|
|
public boolean autoRepaint = true;
|
|
|
|
/**
|
|
* Cree et affiche une nouvelle fenetre de dessin.
|
|
*/
|
|
public Drawing() {
|
|
|
|
this.zoomAndPanListener = new ZoomAndPanListener(this, ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2);
|
|
this.addMouseListener(zoomAndPanListener);
|
|
this.addMouseMotionListener(zoomAndPanListener);
|
|
this.addMouseWheelListener(zoomAndPanListener);
|
|
|
|
this.width = 2000;
|
|
this.height = 1600;
|
|
|
|
BufferedImage img = new BufferedImage(this.width, this.height, BufferedImage.TYPE_3BYTE_BGR);
|
|
|
|
this.image = img;
|
|
this.gr = img.createGraphics();
|
|
|
|
this.zoomAndPanListener.setCoordTransform(this.gr.getTransform());
|
|
|
|
this.long1 = -180;
|
|
this.long2 = 180;
|
|
this.lat1 = -90;
|
|
this.lat2 = 90;
|
|
|
|
this.clear();
|
|
this.repaint();
|
|
|
|
}
|
|
|
|
@Override
|
|
public void paintComponent(Graphics g1) {
|
|
Graphics2D g = (Graphics2D)g1;
|
|
g.clearRect(0, 0, getWidth(), getHeight());
|
|
g.setTransform(zoomAndPanListener.getCoordTransform());
|
|
g.drawImage(image, 0, 0, this);
|
|
}
|
|
|
|
public void setAutoRepaint(boolean autoRepaint) {
|
|
this.autoRepaint = autoRepaint;
|
|
}
|
|
|
|
protected void doAutoPaint() {
|
|
if (autoRepaint) {
|
|
this.repaint();
|
|
}
|
|
}
|
|
|
|
public void setWidth(int width) {
|
|
this.gr.setStroke(new BasicStroke(width));
|
|
}
|
|
|
|
public void setColor(Color col) {
|
|
this.gr.setColor(col);
|
|
}
|
|
|
|
public void clear() {
|
|
this.gr.setColor(Color.WHITE);
|
|
this.gr.fillRect(0, 0, this.width, this.height);
|
|
}
|
|
|
|
public void setBB(double long1, double long2, double lat1, double lat2) {
|
|
|
|
if (long1 > long2 || lat1 > lat2) {
|
|
throw new Error("DessinVisible.setBB : mauvaises coordonnees.");
|
|
}
|
|
|
|
this.long1 = long1;
|
|
this.long2 = long2;
|
|
this.lat1= lat1;
|
|
this.lat2 = lat2;
|
|
|
|
double scale = 1 / Math.max(this.width / (double)this.getWidth(), this.height / (double)this.getHeight());
|
|
|
|
this.zoomAndPanListener.getCoordTransform().setToIdentity();
|
|
this.zoomAndPanListener.getCoordTransform().translate((this.getWidth() - this.width * scale) / 2,
|
|
(this.getHeight() - this.height * scale) / 2);
|
|
this.zoomAndPanListener.getCoordTransform().scale(scale, scale);
|
|
this.zoomAndPanListener.setZoomLevel(0);
|
|
this.repaint();
|
|
|
|
}
|
|
|
|
private int projx(double lon) {
|
|
return (int)(width * (lon - this.long1) / (this.long2 - this.long1)) ;
|
|
}
|
|
|
|
private int projy(double lat) {
|
|
return (int)(height * (1 - (lat - this.lat1) / (this.lat2 - this.lat1))) ;
|
|
}
|
|
|
|
/**
|
|
* Return the longitude and latitude corresponding to the given
|
|
* position of the MouseEvent.
|
|
*
|
|
* @param event
|
|
*
|
|
* @return
|
|
*/
|
|
public Point getLongitudeLatitude(MouseEvent event) throws NoninvertibleTransformException {
|
|
// Get the point using the inverse transform of the Zoom/Pan object, this gives us
|
|
// a point within the drawing box (between [0, 0] and [width, height]).
|
|
Point2D ptDst = this.zoomAndPanListener.getCoordTransform().inverseTransform(event.getPoint(), null);
|
|
|
|
// Inverse the "projection" on x/y to get longitude and latitude.
|
|
double lon = ptDst.getX();
|
|
double lat = ptDst.getY();
|
|
lon = (lon / this.width) * (this.long2 - this.long1) + this.long1;
|
|
lat = (1 - lat / this.height) * (this.lat2 - this.lat1) + this.lat1;
|
|
|
|
// Return a new point.
|
|
return new Point(lon, lat);
|
|
}
|
|
|
|
public void drawLine(Point from, Point to) {
|
|
int x1 = this.projx(from.getLongitude()) ;
|
|
int x2 = this.projx(to.getLongitude()) ;
|
|
int y1 = this.projy(from.getLatitude()) ;
|
|
int y2 = this.projy(to.getLatitude()) ;
|
|
|
|
gr.drawLine(x1, y1, x2, y2) ;
|
|
this.doAutoPaint();
|
|
}
|
|
|
|
public void drawPoint(Point point, int width) {
|
|
int x = this.projx(point.getLongitude()) - width / 2;
|
|
int y = this.projy(point.getLatitude()) - width / 2;
|
|
gr.fillOval(x, y, width, width);
|
|
this.doAutoPaint();
|
|
}
|
|
|
|
public void putText(Point point, String txt) {
|
|
int x = this.projx(point.getLongitude());
|
|
int y = this.projy(point.getLatitude());
|
|
gr.drawString(txt, x, y);
|
|
this.doAutoPaint();
|
|
}
|
|
|
|
}
|