Ignore:
Timestamp:
2010-02-28T16:29:31+01:00 (14 years ago)
Author:
pieren
Message:

Fixed image rotation and a null pointer exception in adjust mode (raster maps only).

Location:
applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/GeorefImage.java

    r19387 r20211  
    99import java.awt.GraphicsDevice;
    1010import java.awt.GraphicsEnvironment;
     11import java.awt.Image;
    1112import java.awt.Point;
    12 import java.awt.Transparency;
    1313import java.awt.image.BufferedImage;
     14import java.awt.image.ImageObserver;
    1415import java.io.IOException;
    1516import java.io.ObjectInputStream;
     
    2223import org.openstreetmap.josm.gui.NavigatableComponent;
    2324
    24 public class GeorefImage implements Serializable {
     25public class GeorefImage implements Serializable, ImageObserver {
    2526    private static final long serialVersionUID = 1L;
    2627
     
    3536    // angle with georeferenced original image after rotation (raster images only)(in radian)
    3637    public double angle = 0;
     38    public int imageOriginalHeight = 0;
     39    public int imageOriginalWidth = 0;
    3740
    3841    public BufferedImage image;
     
    4346    public GeorefImage(BufferedImage img, EastNorth min, EastNorth max) {
    4447        image = img;
     48       
    4549        this.min = min;
    4650        this.max = max;
     
    5357        this.orgCroppedRaster[2] = max;
    5458        this.orgCroppedRaster[3] = new EastNorth(max.east(), min.north());
     59        this.imageOriginalHeight = img.getHeight();
     60        this.imageOriginalWidth = img.getWidth();
    5561        updatePixelPer();
    5662    }
     
    6369
    6470    /**
    65      * Recalculate the new bounding box of the image based on the previous [min,max] bbox
    66      * and the new box after rotation [c,d].
     71     * Recalculate the new bounding box of the image based on the four points provided as parameters.
    6772     * The new bbox defined in [min.max] will retain the extreme values of both boxes.
    68      * @param oldMin the original box min point, before rotation
    69      * @param oldMax the original box max point, before rotation
    70      * @param c the new box min point, after rotation
    71      * @param d the new box max point, after rotation
    72      */
    73     private EastNorthBound getNewBounding(EastNorth oldMin, EastNorth oldMax, EastNorth c, EastNorth d) {
     73     * @param p1 one of the bounding box corner
     74     * @param p2 one of the bounding box corner
     75     * @param p3 one of the bounding box corner
     76     * @param p4 one of the bounding box corner
     77     */
     78    private EastNorthBound computeNewBounding(EastNorth p1, EastNorth p2, EastNorth p3, EastNorth p4) {
    7479        EastNorth pt[] = new EastNorth[4];
    75         pt[0] = oldMin;
    76         pt[1] = oldMax;
    77         pt[2] = c;
    78         pt[3] = d;
     80        pt[0] = p1;
     81        pt[1] = p2;
     82        pt[2] = p3;
     83        pt[3] = p4;
    7984        double smallestEast = Double.MAX_VALUE;
    8085        double smallestNorth = Double.MAX_VALUE;
     
    109114            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, transparency));
    110115        if (drawBoundaries) {
    111             g.setColor(Color.green);
    112116            if (orgCroppedRaster == null) {
    113117                // this is the old cache format where only [min,max] bbox is stored
     118                g.setColor(Color.green);
    114119                g.drawRect(minPt.x, maxPt.y, maxPt.x - minPt.x, minPt.y - maxPt.y);
    115120            } else {
     
    117122                for (int i=0; i<4; i++)
    118123                    croppedPoint[i] = nc.getPoint(orgCroppedRaster[i]);
    119                 croppedPoint[4] = croppedPoint[0];
     124                croppedPoint[4] = croppedPoint[0];
     125                for (int i=0; i<4; i++) {
     126                    g.setColor(Color.green);
     127                    g.drawLine(croppedPoint[i].x, croppedPoint[i].y, croppedPoint[i+1].x, croppedPoint[i+1].y);
     128                }
     129                /*
     130                //Uncomment this section to display the original image size (before cropping)
     131                Point[] orgPoint = new Point[5];
    120132                for (int i=0; i<4; i++)
    121                     g.drawLine(croppedPoint[i].x, croppedPoint[i].y, croppedPoint[i+1].x, croppedPoint[i+1].y);
     133                    orgPoint[i] = nc.getPoint(orgRaster[i]);
     134                orgPoint[4] = orgPoint[0];
     135                for (int i=0; i<4; i++) {
     136                  g.setColor(Color.red);
     137                  g.drawLine(orgPoint[i].x, orgPoint[i].y, orgPoint[i+1].x, orgPoint[i+1].y);
     138                }
     139                */
    122140            }
    123141        }
     
    171189     */
    172190    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    173         if (WMSLayer.currentFormat == 2 || WMSLayer.currentFormat == 3) {
     191        if (WMSLayer.currentFormat >= 2) {
    174192            max = new EastNorth(in.readDouble(), in.readDouble());
    175193            min = new EastNorth(in.readDouble(), in.readDouble());
    176194        }
    177         if (WMSLayer.currentFormat == 3) {
     195        orgRaster = null;
     196        orgCroppedRaster = null;
     197        if (WMSLayer.currentFormat >= 3) {
    178198            orgRaster = new EastNorth[4];
    179199            orgCroppedRaster = new EastNorth[4];
     
    187207            orgCroppedRaster[2] = new EastNorth(in.readDouble(), in.readDouble());
    188208            orgCroppedRaster[3] = new EastNorth(in.readDouble(), in.readDouble());
    189         } else {
    190             orgRaster = null;
    191             orgCroppedRaster = null;
    192             angle = 0;
    193         }
     209        }
     210        if (WMSLayer.currentFormat >= 4) {
     211            imageOriginalHeight = in.readInt();
     212            imageOriginalWidth =  in.readInt();
     213        }       
    194214        image = (BufferedImage) ImageIO.read(ImageIO.createImageInputStream(in));
    195215        updatePixelPer();
     
    216236        out.writeDouble(orgCroppedRaster[2].getX()); out.writeDouble(orgCroppedRaster[2].getY());
    217237        out.writeDouble(orgCroppedRaster[3].getX()); out.writeDouble(orgCroppedRaster[3].getY());
     238        out.writeInt(imageOriginalHeight);
     239        out.writeInt(imageOriginalWidth);
    218240        ImageIO.write(image, "png", ImageIO.createImageOutputStream(out));
    219241    }
     
    272294     * Rotate this image and its min/max coordinates around anchor point
    273295     * @param anchor anchor of rotation
    274      * @param ang angle of rotation (in radian)
    275      */
    276     public void rotate(EastNorth anchor, double ang) {
     296     * @param old_ang previous angle of image before rotation (0 the first time)(in radian)
     297     * @param delta_ang angle of rotation (in radian)
     298     */
     299    public void rotate(EastNorth anchor, double delta_ang) {
     300        if (orgRaster == null || orgCroppedRaster == null)
     301            return;
    277302        // rotate the bounding boxes coordinates first
    278         EastNorth min2 = new EastNorth(orgRaster[0].east(), orgRaster[2].north());
    279         EastNorth max2 = new EastNorth(orgRaster[2].east(), orgRaster[0].north());
    280303        for (int i=0; i<4; i++) {
    281             orgRaster[i] = orgRaster[i].rotate(anchor, ang);
    282             orgCroppedRaster[i] = orgCroppedRaster[i].rotate(anchor, ang);
    283         }
    284         min2 = min2.rotate(anchor, ang);
    285         max2 = max2.rotate(anchor, ang);
    286         EastNorthBound enb = getNewBounding(orgCroppedRaster[0], orgCroppedRaster[2], min2, max2);
    287         min = enb.min;
    288         max = enb.max;
    289         angle=+ang;
    290        
     304            orgRaster[i] = orgRaster[i].rotate(anchor, delta_ang);
     305            orgCroppedRaster[i] = orgCroppedRaster[i].rotate(anchor, delta_ang);
     306        }
    291307        // rotate the image now
    292         double sin = Math.abs(Math.sin(ang)), cos = Math.abs(Math.cos(ang));
    293         int w = image.getWidth(), h = image.getHeight();
    294         int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
     308        double sin = Math.abs(Math.sin(angle+delta_ang)), cos = Math.abs(Math.cos(angle+delta_ang));
     309        int w = imageOriginalWidth, h = imageOriginalHeight;
     310        int neww = (int)Math.floor(w*cos+h*sin);
     311        int newh = (int)Math.floor(h*cos+w*sin);
    295312        GraphicsConfiguration gc = getDefaultConfiguration();
    296         BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
     313        BufferedImage result = gc.createCompatibleImage(neww, newh, image.getTransparency());
    297314        Graphics2D g = result.createGraphics();
    298         g.translate((neww-w)/2, (newh-h)/2);
    299         g.rotate(ang, w/2, h/2);
     315        g.translate((neww-image.getWidth())/2, (newh-image.getHeight())/2);
     316        g.rotate(delta_ang, image.getWidth()/2, image.getHeight()/2);
    300317        g.drawRenderedImage(image, null);
    301318        g.dispose();
    302319        image = result;
     320        EastNorthBound enb = computeNewBounding(orgCroppedRaster[0], orgCroppedRaster[1], orgCroppedRaster[2], orgCroppedRaster[3]);
     321        min = enb.min;
     322        max = enb.max;
     323        angle+=delta_ang;
     324    }
     325   
     326    /**
     327     * Crop the image based on new bbox coordinates adj1 and adj2 (for raster images only).
     328     * @param adj1 is the new corner bottom, left
     329     * @param adj2 is the new corner top, right
     330     */
     331    public void crop(EastNorth adj1, EastNorth adj2) {
     332        // s1 and s2 have 0,0 at top, left where all EastNorth coord. have 0,0 at bottom, left
     333        int sx1 = (int)((adj1.getX() - min.getX())*getPixelPerEast());
     334        int sy1 = (int)((max.getY() - adj2.getY())*getPixelPerNorth());
     335        int sx2 = (int)((adj2.getX() - min.getX())*getPixelPerEast());
     336        int sy2 = (int)((max.getY() - adj1.getY())*getPixelPerNorth());
     337        int newWidth = Math.abs(sx2 - sx1);
     338        int newHeight = Math.abs(sy2 - sy1);
     339        BufferedImage new_img = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
     340        Graphics g = new_img.getGraphics();
     341        g.drawImage(image, 0, 0, newWidth-1, newHeight-1,
     342                sx1, sy1, sx2, sy2,
     343                this);
     344        image = new_img;
     345        this.min = adj1;
     346        this.max = adj2;
     347        this.orgCroppedRaster[0] = min;
     348        this.orgCroppedRaster[1] = new EastNorth(min.east(), max.north());
     349        this.orgCroppedRaster[2] = max;
     350        this.orgCroppedRaster[3] = new EastNorth(max.east(), min.north());
     351        this.imageOriginalWidth = newWidth;
     352        this.imageOriginalHeight = newHeight;
     353        updatePixelPer();
     354    }
     355
     356    @Override
     357    public boolean imageUpdate(Image img, int infoflags, int x, int y,
     358            int width, int height) {
     359        return false;
    303360    }
    304361
  • applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSAdjustAction.java

    r19387 r20211  
    8686        }
    8787        modifiedLayers.clear();
    88         selectedLayer.adjustModeEnabled = false;
    89         selectedLayer = null;
     88        if (selectedLayer != null) {
     89            selectedLayer.adjustModeEnabled = false;
     90            selectedLayer = null;
     91        }
    9092    }
    9193
  • applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSLayer.java

    r19949 r20211  
    5454    /**
    5555     * v1 to v2 = not supported
    56      * v2 to v3 = add 4 more EastNorth coordinates in GeorefImages
    57      */
    58     protected final int serializeFormatVersion = 3;
     56     * v2 to v3 = add 4 more EastNorth coordinates in GeorefImages
     57     * v3 to v4 = add original raster image width and height
     58     */
     59    protected final int serializeFormatVersion = 4;
    5960   
    6061    public static int currentFormat;
     
    535536        EastNorth adj2 = new EastNorth(en1.east() > en2.east() ? en1.east() : en2.east(),
    536537                en1.north() > en2.north() ? en1.north() : en2.north());
    537         // s1 and s2 have 0,0 at top, left where all EastNorth coord. have 0,0 at bottom, left
    538         int sx1 = (int)((adj1.getX() - images.get(0).min.getX())*images.get(0).getPixelPerEast());
    539         int sy1 = (int)((images.get(0).max.getY() - adj2.getY())*images.get(0).getPixelPerNorth());
    540         int sx2 = (int)((adj2.getX() - images.get(0).min.getX())*images.get(0).getPixelPerEast());
    541         int sy2 = (int)((images.get(0).max.getY() - adj1.getY())*images.get(0).getPixelPerNorth());
    542         int newWidth = Math.abs(sx2 - sx1);
    543         int newHeight = Math.abs(sy2 - sy1);
    544         BufferedImage new_img = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
    545         Graphics g = new_img.getGraphics();
    546         g.drawImage(images.get(0).image, 0, 0, newWidth-1, newHeight-1,
    547                 sx1, sy1, sx2, sy2,
    548                 this);
    549         images.set(0, new GeorefImage(new_img, adj1, adj2));
    550         // important: update the layer georefs !
     538        images.get(0).crop(adj1, adj2);
     539        // update the layer georefs
    551540        rasterMin = adj1;
    552541        rasterMax = adj2;
     542        setCommuneBBox(new EastNorthBound(new EastNorth(0,0), new EastNorth(images.get(0).image.getWidth()-1,images.get(0).image.getHeight()-1)));
    553543        rasterRatio = (rasterMax.getX()-rasterMin.getX())/(communeBBox.max.getX() - communeBBox.min.getX());
    554         setCommuneBBox(new EastNorthBound(new EastNorth(0,0), new EastNorth(newWidth-1,newHeight-1)));
    555544    }
    556545
     
    581570    public void displace(double dx, double dy) {
    582571        this.rasterMin = new EastNorth(rasterMin.east() + dx, rasterMin.north() + dy);
     572        this.rasterMax = new EastNorth(rasterMax.east() + dx, rasterMax.north() + dy);
    583573        images.get(0).shear(dx, dy);
    584574    }
     
    586576    public void resize(EastNorth rasterCenter, double proportion) {
    587577        this.rasterMin = rasterMin.interpolate(rasterCenter, proportion);
     578        this.rasterMax = rasterMax.interpolate(rasterCenter, proportion);
    588579        images.get(0).scale(rasterCenter, proportion);
    589580    }
     
    591582    public void rotate(EastNorth rasterCenter, double angle) {
    592583        this.rasterMin = rasterMin.rotate(rasterCenter, angle);
     584        this.rasterMax = rasterMax.rotate(rasterCenter, angle);
     585//        double proportion = dst1.distance(dst2)/org1.distance(org2);
    593586        images.get(0).rotate(rasterCenter, angle);
     587        this.angle += angle;
    594588    }
    595589
Note: See TracChangeset for help on using the changeset viewer.