Ignore:
Timestamp:
2010-01-10T15:46:08+01:00 (14 years ago)
Author:
pieren
Message:

Various minor improvements. More bboxes data in the cache. New cache format v3.

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

Legend:

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

    r18838 r19371  
    4949    private Lock imagesLock = new ReentrantLock();
    5050
     51    public boolean isCachePipeEmpty() {
     52        imagesLock.lock();
     53        boolean ret = imagesToSave.isEmpty();
     54        imagesLock.unlock();
     55        return ret;
     56    }
     57   
    5158    public CacheControl(WMSLayer wmsLayer) {
    5259        cacheEnabled = Main.pref.getBoolean("cadastrewms.enableCaching", true);
     
    171178        for (;;) {
    172179            imagesLock.lock();
    173             // copy locally the images to save for better performance
    174             ArrayList<GeorefImage> images = new ArrayList<GeorefImage>(imagesToSave);
    175             imagesToSave.clear();
     180            //ArrayList<GeorefImage> images = new ArrayList<GeorefImage>(imagesToSave);
     181            int size = imagesToSave.size();
    176182            imagesLock.unlock();
    177             if (images != null && !images.isEmpty()) {
     183            if (size > 0) {
    178184                String extension = String.valueOf((wmsLayer.getLambertZone() + 1));
    179185                if (Main.proj instanceof LambertCC9Zones)
     
    186192                        ObjectOutputStreamAppend oos = new ObjectOutputStreamAppend(
    187193                                new BufferedOutputStream(new FileOutputStream(file, true)));
    188                         for (GeorefImage img : images) {
    189                             oos.writeObject(img);
     194                        for (int i=0; i < size; i++) {
     195                            oos.writeObject(imagesToSave.get(i));
    190196                        }
    191197                        oos.close();
     
    194200                                new BufferedOutputStream(new FileOutputStream(file)));
    195201                        wmsLayer.write(oos);
    196                         for (GeorefImage img : images) {
    197                             oos.writeObject(img);
     202                        for (int i=0; i < size; i++) {
     203                            oos.writeObject(imagesToSave.get(i));
    198204                        }
    199205                        oos.close();
     
    202208                    e.printStackTrace(System.out);
    203209                }
     210                imagesLock.lock();
     211                for (int i=0; i < size; i++) {
     212                    imagesToSave.remove(0);
     213                }
     214                imagesLock.unlock();
    204215            }
    205216            try {wait();} catch (InterruptedException e) {
  • applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/CadastrePlugin.java

    r19267 r19371  
    9393 *                 - cookie expiration automatically detected and renewed (after 30 minutes)
    9494 *                 - proper WMS layer cleanup at destruction (workaround for memory leak)
     95 *                 - new cache format (v3) storing original image and cropped image bbox + angle
     96 *                 - cache management compatible with previous v2 format
     97 *                 - raster image rotation using shift+ctrl key instead of ctrl
     98 *                 - raster image adjustment using default system menu modifier (ctrl for windows) for Mac support 
    9599 */
    96100public class CadastrePlugin extends Plugin {
  • applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/GeorefImage.java

    r18544 r19371  
    2525    private static final long serialVersionUID = 1L;
    2626
     27    // bbox of the georeferenced image (the nice horizontal and vertical box)
    2728    public EastNorth min;
    2829    public EastNorth max;
     30    // bbox of the georeferenced original image (raster only) (inclined if rotated and before cropping)
     31    // P[0] is bottom,left then next are clockwise.
     32    private EastNorth[] orgRaster = new EastNorth[4];
     33    // bbox of the georeferenced original image (raster only) after cropping
     34    private EastNorth[] orgCroppedRaster = new EastNorth[4];
     35    // angle with georeferenced original image after rotation (raster images only)(in radian)
     36    private double angle = 0;
     37
    2938    public BufferedImage image;
    3039
     
    3645        this.min = min;
    3746        this.max = max;
     47        this.orgRaster[0] = min;
     48        this.orgRaster[1] = new EastNorth(min.east(), max.north());
     49        this.orgRaster[2] = max;
     50        this.orgRaster[3] = new EastNorth(max.east(), min.north());
     51        this.orgCroppedRaster[0] = min;
     52        this.orgCroppedRaster[1] = new EastNorth(min.east(), max.north());
     53        this.orgCroppedRaster[2] = max;
     54        this.orgCroppedRaster[3] = new EastNorth(max.east(), min.north());
    3855        updatePixelPer();
    3956    }
     
    4562    }
    4663
    47     private void getNewBounding(EastNorth min, EastNorth max, EastNorth c, EastNorth d) {
     64    /**
     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].
     67     * 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) {
    4874        EastNorth pt[] = new EastNorth[4];
    49         pt[0] = min;
    50         pt[1] = max;
     75        pt[0] = oldMin;
     76        pt[1] = oldMax;
    5177        pt[2] = c;
    5278        pt[3] = d;
     
    6187            highestNorth = Math.max(pt[i].north(), highestNorth);
    6288        }
    63         min.setLocation(smallestEast, smallestNorth);
    64         max.setLocation(highestEast, highestNorth);
     89        return new EastNorthBound(new EastNorth(smallestEast, smallestNorth),
     90                new EastNorth(highestEast, highestNorth));
    6591    }
    6692
     
    84110        if (drawBoundaries) {
    85111            g.setColor(Color.green);
    86             g.drawRect(minPt.x, maxPt.y, maxPt.x - minPt.x, minPt.y - maxPt.y);
     112            if (orgCroppedRaster == null) {
     113                // this is the old cache format where only [min,max] bbox is stored
     114                g.drawRect(minPt.x, maxPt.y, maxPt.x - minPt.x, minPt.y - maxPt.y);
     115            } else {
     116                Point[] croppedPoint = new Point[5];
     117                for (int i=0; i<4; i++)
     118                    croppedPoint[i] = nc.getPoint(orgCroppedRaster[i]);
     119                croppedPoint[4] = croppedPoint[0];
     120                for (int i=0; i<4; i++)
     121                    g.drawLine(croppedPoint[i].x, croppedPoint[i].y, croppedPoint[i+1].x, croppedPoint[i+1].y);
     122            }
    87123        }
    88124        g.drawImage(image, minPt.x, maxPt.y, maxPt.x, minPt.y, // dest
     
    135171     */
    136172    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    137         max = new EastNorth(in.readDouble(), in.readDouble());
    138         min = new EastNorth(in.readDouble(), in.readDouble());
     173        if (WMSLayer.currentFormat == 2 || WMSLayer.currentFormat == 3) {
     174            max = new EastNorth(in.readDouble(), in.readDouble());
     175            min = new EastNorth(in.readDouble(), in.readDouble());
     176        }
     177        if (WMSLayer.currentFormat == 3) {
     178            orgRaster = new EastNorth[4];
     179            orgCroppedRaster = new EastNorth[4];
     180            angle = in.readDouble();
     181            orgRaster[0] = new EastNorth(in.readDouble(), in.readDouble());
     182            orgRaster[1] = new EastNorth(in.readDouble(), in.readDouble());
     183            orgRaster[2] = new EastNorth(in.readDouble(), in.readDouble());
     184            orgRaster[3] = new EastNorth(in.readDouble(), in.readDouble());
     185            orgCroppedRaster[0] = new EastNorth(in.readDouble(), in.readDouble());
     186            orgCroppedRaster[1] = new EastNorth(in.readDouble(), in.readDouble());
     187            orgCroppedRaster[2] = new EastNorth(in.readDouble(), in.readDouble());
     188            orgCroppedRaster[3] = new EastNorth(in.readDouble(), in.readDouble());
     189        } else {
     190            orgRaster = null;
     191            orgCroppedRaster = null;
     192            angle = 0;
     193        }
    139194        image = (BufferedImage) ImageIO.read(ImageIO.createImageInputStream(in));
    140195        updatePixelPer();
     
    143198    /**
    144199     * Method required by BufferedImage serialization.
    145      * Cache uses only primitives to stay independent of software changes.
     200     * Use only primitives for stability in time (not influenced by josm-core changes).
    146201     */
    147202    private void writeObject(ObjectOutputStream out) throws IOException {
    148         out.writeDouble(max.getX());
    149         out.writeDouble(max.getY());
    150         out.writeDouble(min.getX());
    151         out.writeDouble(min.getY());
     203        out.writeDouble(max.getX()); out.writeDouble(max.getY());
     204        out.writeDouble(min.getX()); out.writeDouble(min.getY());
     205        if (orgRaster == null) { // just in case we save an old format layer already cached
     206            orgRaster = new EastNorth[4];
     207            orgCroppedRaster = new EastNorth[4];
     208        }
     209        out.writeDouble(angle);
     210        out.writeDouble(orgRaster[0].getX()); out.writeDouble(orgRaster[0].getY());
     211        out.writeDouble(orgRaster[1].getX()); out.writeDouble(orgRaster[1].getY());
     212        out.writeDouble(orgRaster[2].getX()); out.writeDouble(orgRaster[2].getY());
     213        out.writeDouble(orgRaster[3].getX()); out.writeDouble(orgRaster[3].getY());
     214        out.writeDouble(orgCroppedRaster[0].getX()); out.writeDouble(orgCroppedRaster[0].getY());
     215        out.writeDouble(orgCroppedRaster[1].getX()); out.writeDouble(orgCroppedRaster[1].getY());
     216        out.writeDouble(orgCroppedRaster[2].getX()); out.writeDouble(orgCroppedRaster[2].getY());
     217        out.writeDouble(orgCroppedRaster[3].getX()); out.writeDouble(orgCroppedRaster[3].getY());
    152218        ImageIO.write(image, "png", ImageIO.createImageOutputStream(out));
    153219    }
     
    182248        min = new EastNorth(min.east() + dx, min.north() + dy);
    183249        max = new EastNorth(max.east() + dx, max.north() + dy);
     250        for (int i=0; i<4; i++) {
     251            orgRaster[i] = new EastNorth(orgRaster[i].east() + dx, orgRaster[i].north() + dy);
     252            orgCroppedRaster[i] = new EastNorth(orgCroppedRaster[i].east() + dx, orgCroppedRaster[i].north() + dy);
     253        }
    184254    }
    185255   
     
    192262        min = anchor.interpolate(min, proportion);
    193263        max = anchor.interpolate(max, proportion);
     264        for (int i=0; i<4; i++) {
     265            orgRaster[i] = anchor.interpolate(orgRaster[i], proportion);
     266            orgCroppedRaster[i] = anchor.interpolate(orgCroppedRaster[i], proportion);
     267        }
    194268        updatePixelPer();
    195269    }
     
    198272     * Rotate this image and its min/max coordinates around anchor point
    199273     * @param anchor anchor of rotation
    200      * @param angle angle of rotation (in radians)
    201      */
    202     public void rotate(EastNorth anchor, double angle) {
    203         EastNorth min2 = new EastNorth(min.east(), max.north());
    204         EastNorth max2 = new EastNorth(max.east(), min.north());
    205         min = min.rotate(anchor, angle);
    206         max = max.rotate(anchor, angle);
    207         min2 = min2.rotate(anchor, angle);
    208         max2 = max2.rotate(anchor, angle);
    209         getNewBounding(min, max, min2, max2);
    210         image = tilt(image, angle);
    211     }
    212 
    213     /**
    214      * Rotate by copying original buffered image into a new one with new dimensions
    215      * @param image
    216      * @param angle
    217      * @return
    218      */
    219     public static BufferedImage tilt(BufferedImage image, double angle) {
    220         double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
     274     * @param ang angle of rotation (in radian)
     275     */
     276    public void rotate(EastNorth anchor, double ang) {
     277        // 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());
     280        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       
     291        // rotate the image now
     292        double sin = Math.abs(Math.sin(ang)), cos = Math.abs(Math.cos(ang));
    221293        int w = image.getWidth(), h = image.getHeight();
    222294        int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
     
    225297        Graphics2D g = result.createGraphics();
    226298        g.translate((neww-w)/2, (newh-h)/2);
    227         g.rotate(angle, w/2, h/2);
     299        g.rotate(ang, w/2, h/2);
    228300        g.drawRenderedImage(image, null);
    229301        g.dispose();
    230         return result;
     302        image = result;
    231303    }
    232304
  • applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSAdjustAction.java

    r18544 r19371  
    55
    66import java.awt.Cursor;
     7import java.awt.Toolkit;
    78import java.awt.event.ActionEvent;
    89import java.awt.event.MouseEvent;
     
    8788        if (e.getButton() != MouseEvent.BUTTON1)
    8889            return;
    89         boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
     90        boolean ctrl = (e.getModifiers() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0;
    9091        // boolean alt = (e.getModifiers() & ActionEvent.ALT_MASK) != 0;
    9192        boolean shift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
    92         if (shift)
     93        if (shift && !ctrl)
    9394            mode = Mode.moveZ;
    94         else if (ctrl)
     95        else if (shift && ctrl)
    9596            mode = Mode.rotate;
    9697        else
  • applications/editors/josm/plugins/cadastre-fr/src/cadastre_fr/WMSLayer.java

    r19267 r19371  
    5151    protected Vector<GeorefImage> images = new Vector<GeorefImage>();
    5252
    53     protected final int serializeFormatVersion = 2;
     53    /**
     54     * v1 to v2 = not supported
     55     * v2 to v3 = add 4 more EastNorth coordinates in GeorefImages
     56     */
     57    protected final int serializeFormatVersion = 3;
     58   
     59    public static int currentFormat;
    5460
    5561    private ArrayList<EastNorthBound> dividedBbox = new ArrayList<EastNorthBound>();
     
    6975    public double X0, Y0, angle, fX, fY;
    7076
     77    // bbox of the georeferenced raster image (the nice horizontal and vertical box)
    7178    private EastNorth rasterMin;
    7279    private EastNorth rasterMax;
     
    8996
    9097    public void destroy() {
     98        // if the layer is currently saving the images in the cache, wait until it's finished
     99        while (!cacheControl.isCachePipeEmpty()) {
     100            System.out.println("Try to close a WMSLayer which is currently saving in cache : wait 1 sec.");
     101            CadastrePlugin.safeSleep(1000);
     102        }
    91103        super.destroy();
    92104        images = null;
     
    364376        double ratio = rasterSizeY/rasterSizeX;
    365377        // keep same ratio on screen as WMS bbox (stored in communeBBox)
    366         rasterMin = new EastNorth(eaMin.getX(), rasterCenter.getY()-(eaMax.getX()-eaMin.getX())*ratio/2);
    367         rasterMax = new EastNorth(eaMax.getX(), rasterCenter.getY()+(eaMax.getX()-eaMin.getX())*ratio/2);
     378        rasterMin = new EastNorth(eaMin.getX(), rasterCenter.getY()-(eaMax.getX()-eaMin.getX())*ratio/2); 
     379        rasterMax = new EastNorth(eaMax.getX(), rasterCenter.getY()+(eaMax.getX()-eaMin.getX())*ratio/2); 
    368380        rasterRatio = (rasterMax.getX()-rasterMin.getX())/rasterSizeX;
    369381    }
     
    402414     */
    403415    public boolean read(ObjectInputStream ois, int currentLambertZone) throws IOException, ClassNotFoundException {
    404         int sfv = ois.readInt();
    405         if (sfv != this.serializeFormatVersion) {
     416        currentFormat = ois.readInt();;
     417        if (currentFormat < 2) {
    406418            JOptionPane.showMessageDialog(Main.parent, tr("Unsupported cache file version; found {0}, expected {1}\nCreate a new one.",
    407                     sfv, this.serializeFormatVersion), tr("Cache Format Error"), JOptionPane.ERROR_MESSAGE);
     419                    currentFormat, this.serializeFormatVersion), tr("Cache Format Error"), JOptionPane.ERROR_MESSAGE);
    408420            return false;
    409421        }
     
    531543    public void setCommuneBBox(EastNorthBound entireCommune) {
    532544        this.communeBBox = entireCommune;
    533 //        if (Main.proj instanceof LambertCC9Zones)
    534 //            setLambertCC9Zone(communeBBox.min.north());
    535545    }
    536546
     
    545555        return lambertZone;
    546556    }
    547 
    548 //    public void setLambertCC9Zone(double north) {
    549 //        int lambertZone = LambertCC9Zones.north2ZoneNumber(north);
    550 //        this.lambertZone = lambertZone;
    551 //        if (((LambertCC9Zones)Main.proj).getLayoutZone() != lambertZone) {
    552 //            String currentZone = MenuActionLambertZone.lambert9zones[((LambertCC9Zones)Main.proj).getLayoutZone()+1];
    553 //            String destZone = MenuActionLambertZone.lambert9zones[lambertZone+1];
    554 //            if (Main.map.mapView.getAllLayers().size() == 1) {
    555 //                /* Enable this code below when JOSM will have a proper support of dynamic projection change
    556 //                 *
    557 //                System.out.println("close all layers and change current Lambert zone from "+LambertCC9Zones.layoutZone+" to "+lambertZone);
    558 //                Bounds b = null;
    559 //                if (Main.map != null && Main.map.mapView != null)
    560 //                    b = Main.map.mapView.getRealBounds();
    561 //                LambertCC9Zones.layoutZone = lambertZone;
    562 //                Main.map.mapView.zoomTo(b);
    563 //                */
    564 //            } else {
    565 //                JOptionPane.showMessageDialog(Main.parent, tr("Current layer is in Lambert CC9 Zone \"{0}\"\n"+
    566 //                        "where the commune is in Lambert CC9 Zone \"{1}\".\n"+
    567 //                        "Upload your changes, close all layers and change\n"+
    568 //                        "manually the Lambert zone from the Cadastre menu"
    569 //                        , currentZone, destZone));
    570 //            }
    571 //        }
    572 //    }
    573557
    574558    public EastNorth getRasterCenter() {
Note: See TracChangeset for help on using the changeset viewer.