be-graphes/src/main/org/insa/drawing/Drawing.java
Mikael Capelle 71accfe13b Update code.
2018-02-20 11:27:12 +01:00

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();
}
}