Revision 8281 trunk/libraries/libCq CMS for java.old/src/org/cresques/px/PxRaster.java

View differences:

PxRaster.java
27 27
import java.awt.Component;
28 28
import java.awt.Graphics2D;
29 29
import java.awt.Image;
30
import java.awt.geom.AffineTransform;
30 31
import java.awt.geom.GeneralPath;
32
import java.awt.geom.NoninvertibleTransformException;
31 33
import java.awt.geom.Point2D;
32 34
import java.awt.image.BufferedImage;
33 35
import java.awt.image.DataBuffer;
......
88 90
    private RasterFilterStackManager stackManager = null;
89 91
    private Image geoImage = null;
90 92
    private ViewPortData lastViewPort = null;
93
    
94
    /**
95
     * Variable usada por el draw para calcular el n?mero de pixeles a leer de un
96
     * raster rotado. 
97
     */
98
    private double[] adjustedRotedExtent = null;
91 99

  
92 100
    /**
93 101
     * Constructor.
......
110 118
        this.proj = proj;
111 119
        this.component = component;
112 120
        setExtent(geoFile[0].getExtent());
121
        setExtentForRequest(geoFile[0].getExtentForRequest());
113 122
        geoFile[0].setView(geoFile[0].getExtent());
114 123
        extentOrig = extent;
115 124
        bandSwitch.addFile(geoFile[0]);
......
142 151
            geoFile[i] = GeoRasterFile.openFile(proj, fnames[i]); //loadECW(fname);
143 152
            geoFile[i].setUpdatable((Component) component);
144 153
            setExtent(geoFile[i].getExtent());
154
            setExtentForRequest(geoFile[i].getExtentForRequest());
145 155
            geoFile[i].setView(geoFile[i].getExtent());
146 156
            bandSwitch.addFile(geoFile[i]);
147 157
        }
......
167 177
        this.component = component;
168 178

  
169 179
        setExtent(geoFile[0].getExtent());
180
        setExtentForRequest(geoFile[0].getExtentForRequest());
170 181
        if(view != null){
171 182
	        geoFile[0].setView(view); //geoFile.getExtent());
172 183
	        extentOrig = extent;
......
203 214
            listFiles[geoFile.length] = GeoRasterFile.openFile(proj, fileName);
204 215
            listFiles[geoFile.length].setUpdatable((Component) component);
205 216
            setExtent(listFiles[geoFile.length].getExtent());
217
            setExtentForRequest(listFiles[geoFile.length].getExtentForRequest());
206 218
            listFiles[geoFile.length].setView(listFiles[geoFile.length].getExtent());
207 219
            bandSwitch.addFile(listFiles[geoFile.length]);
208 220
            geoFile = listFiles;
......
626 638
    }
627 639

  
628 640
    /**
641
     * Asigna el extent sobre el que se ajusta una petici?n para que esta no exceda el 
642
     * extent m?ximo del raster. Para un raster sin rotar ser? igual al extent
643
     * pero para un raster rotado ser? igual al extent del raster como si no 
644
     * tuviera rotaci?n. Esto ha de ser as? ya que la rotaci?n solo se hace sobre la
645
     * vista y las peticiones han de hacerse en coordenadas de la imagen sin shearing
646
     * aplicado.
647
     * @param Extent
648
     */
649
    public void setExtentForRequest(Extent e) {
650
        super.requestExtent = e;
651
        if(e != null){
652
	        pts = new Vector();
653
	        pts.add(proj.createPoint(e.minX(), e.minY()));
654
	        pts.add(proj.createPoint(e.maxX(), e.minY()));
655
	        pts.add(proj.createPoint(e.maxX(), e.maxY()));
656
	        pts.add(proj.createPoint(e.minX(), e.maxY()));
657
        }
658
    }
659
    
660
    /**
629 661
     * Cambia la vista (viewport) sobre el raster.
630 662
     *
631 663
     * @param v extent
......
668 700
    }
669 701

  
670 702
    /**
703
     * Transforma la petici?n que est? en coordenadas de la imagen sin rotar a coordenadas de la imagen rotada
704
     * para que sea posible el calculo de la caja m?nima de inclusi?n. La coordenada superior izquierda de esta
705
     * ser? la que se use para posicionar la imagen sobre el graphics aplicandole la transformaci?n de la la vista.
706
     * @param v
707
     * @return
708
     */
709
    private Point2D coordULRotateRaster(double[] v){
710
        double vx = v[0];
711
        double vy = v[1];
712
        double vx2 = v[2];
713
        double vy2 = v[3];
714
    	if (geoFile != null) {
715
        	double[] transf = geoFile[0].getTransform();
716
        	        	
717
           	if(transf != null && (transf[2] != 0 || transf[4] != 0)){
718
           		//La transformaci?n se hace en base a una esquina que varia con el signo del 
719
           		//pixel size. 
720
           		double ptoDesplX = (transf[1] > 0)?requestExtent.minX():requestExtent.maxX();
721
            	double ptoDesplY = (transf[5] < 0)?requestExtent.maxY():requestExtent.minY();
722
            
723
            	Point2D ul = new Point2D.Double(vx - ptoDesplX, vy2 - ptoDesplY);
724
            	Point2D ur = new Point2D.Double(vx2 - ptoDesplX, vy2 - ptoDesplY);
725
            	Point2D ll = new Point2D.Double(vx - ptoDesplX, vy - ptoDesplY);
726
            	Point2D lr = new Point2D.Double(vx2 - ptoDesplX, vy - ptoDesplY);
727
            	
728
           		double shearX = 0;
729
                double shearY = 0;
730
              
731
                if(transf[5] != 0)
732
                	shearX = transf[2] / transf[5];
733
                else
734
                	shearX = transf[2];
735
                if(transf[1] != 0)
736
                	shearY = transf[4] / transf[1];
737
                else
738
                	shearY = transf[4];
739
                
740
                
741
        		AffineTransform at = new AffineTransform();
742
        		at.setToShear(shearX, shearY);
743

  
744
        		at.transform(ul, ul);
745
        		at.transform(ur, ur);
746
        		at.transform(ll, ll);
747
        		at.transform(lr, lr);
748
        			
749
	        	ul = new Point2D.Double(ul.getX() + ptoDesplX, ul.getY() + ptoDesplY);
750
	        	ur = new Point2D.Double(ur.getX() + ptoDesplX, ur.getY() + ptoDesplY);
751
	        	ll = new Point2D.Double(ll.getX() + ptoDesplX, ll.getY() + ptoDesplY);
752
	        	lr = new Point2D.Double(lr.getX() + ptoDesplX, lr.getY() + ptoDesplY);
753
	        	
754
        		vx2 = Math.max(Math.max(ul.getX(), ur.getX()), Math.max(ll.getX(), lr.getX()));
755
        		vy2 = Math.max(Math.max(ul.getY(), ur.getY()), Math.max(ll.getY(), lr.getY()));
756
        		vx = Math.min(Math.min(ul.getX(), ur.getX()), Math.min(ll.getX(), lr.getX()));
757
        		vy = Math.min(Math.min(ul.getY(), ur.getY()), Math.min(ll.getY(), lr.getY()));
758
        		adjustedRotedExtent = new double[4];
759
        		adjustedRotedExtent[0] = vx;
760
        		adjustedRotedExtent[1] = vy;
761
        		adjustedRotedExtent[2] = vx2;
762
        		adjustedRotedExtent[3] = vy2;
763
        		return ul;
764
        	}
765
           	
766
        }
767
    	return null;
768
        
769
    }
770
    
771
    /**
671 772
     * Ajusta la extensi?n pasada por par?metro y que corresponde al extent de la vista donde
672 773
     * se va a dibujar a los valores m?ximos y m?nimos de la imagen. Esto sirve para que la
673 774
     * petici?n al driver nunca sobrepase los l?mites de la imagen tratada aunque la vista
674 775
     * donde se dibuje sea de mayor tama?o.
675 776
     * 
777
     * Antes de realizar este ajuste hay que transformar la petici?n que puede corresponder a 
778
     * una imagen rotada a las coordenadas de la imagen sin rotar ya que las peticiones al 
779
     * driver hay que hacerlas con estas coordenadas. Para esto trasladamos la petici?n al origen
780
     * de la imagen (esquina superior izquierda), aplicamos la transformaci?n inversa a las cuatro 
781
     * esquinas obtenidas y volvemos a trasladar a su posici?n original. 
782
     * 
783
     * Se usa la transformaci?n inversa para trasladar un punto del raster rotado al mismo sin 
784
     * rotar y la transformaci?n af?n normal para trasladar un punto sin rotar a uno rotado.
785
     * 
676 786
     * @param sz Extent completo de la vista donde se va a dibujar.
677 787
     */
678
    protected double[] calculateNewView(Extent sz) { 
788
    protected double[] calculateNewView(ViewPortData vp) {
789
    	Extent sz = vp.getExtent();
679 790
        double vx = sz.minX();
680 791
        double vy = sz.minY();
681 792
        double vx2 = sz.maxX();
682 793
        double vy2 = sz.maxY();
794
        
795
        //Trasladamos la petici?n si est? rotada a su posici?n sin rotar
796
        
797
        if (geoFile != null) {
798
        	double[] transf = geoFile[0].getTransform();
799
        	        	
800
           	if(transf != null && (transf[2] != 0 || transf[4] != 0)){
801
           		
802
           		//La transformaci?n se hace en base a una esquina que varia con el signo del 
803
           		//pixel size. 
804
           		double ptoDesplX = (transf[1] > 0)?requestExtent.minX():requestExtent.maxX();
805
            	double ptoDesplY = (transf[5] < 0)?requestExtent.maxY():requestExtent.minY();
806
            	
807
            	Point2D ul = new Point2D.Double(vx - ptoDesplX, vy2 - ptoDesplY);
808
            	Point2D ur = new Point2D.Double(vx2 - ptoDesplX, vy2 - ptoDesplY);
809
            	Point2D ll = new Point2D.Double(vx - ptoDesplX, vy - ptoDesplY);
810
            	Point2D lr = new Point2D.Double(vx2 - ptoDesplX, vy - ptoDesplY);
811
            	
812
           		double shearX = 0;
813
                double shearY = 0;
814
                if(transf[5] != 0)
815
                	shearX = transf[2] / transf[5];
816
                else
817
                	shearX = transf[2];
818
                if(transf[1] != 0)
819
                	shearY = transf[4] / transf[1];
820
                else
821
                	shearY = transf[4];
822
                
823
        		AffineTransform at = new AffineTransform();
824
        		at.setToShear(shearX, shearY);
825
        		
826
        		try {
827
        			at.inverseTransform(ul, ul);
828
        			at.inverseTransform(ur, ur);
829
        			at.inverseTransform(ll, ll);
830
        			at.inverseTransform(lr, lr);
831
				} catch (NoninvertibleTransformException e) {
832
					e.printStackTrace();
833
				}
834
				
835
	        	ul = new Point2D.Double(ul.getX() + ptoDesplX, ul.getY() + ptoDesplY);
836
	        	ur = new Point2D.Double(ur.getX() + ptoDesplX, ur.getY() + ptoDesplY);
837
	        	ll = new Point2D.Double(ll.getX() + ptoDesplX, ll.getY() + ptoDesplY);
838
	        	lr = new Point2D.Double(lr.getX() + ptoDesplX, lr.getY() + ptoDesplY);
839
	        	
840
        		vx2 = Math.max(Math.max(ul.getX(), ur.getX()), Math.max(ll.getX(), lr.getX()));
841
        		vy2 = Math.max(Math.max(ul.getY(), ur.getY()), Math.max(ll.getY(), lr.getY()));
842
        		vx = Math.min(Math.min(ul.getX(), ur.getX()), Math.min(ll.getX(), lr.getX()));
843
        		vy = Math.min(Math.min(ul.getY(), ur.getY()), Math.min(ll.getY(), lr.getY()));
844
        	}
845
        }
683 846

  
684
        if (sz.minX() < extent.minX())
685
            vx = extent.minX();
847
        if (vx < requestExtent.minX())
848
            vx = requestExtent.minX();
686 849
        
687
        if (sz.minY() < extent.minY()) 
688
            vy = extent.minY();
850
        if (vy < requestExtent.minY()) 
851
            vy = requestExtent.minY();
689 852
        
690
        if (sz.maxX() > extent.maxX()) 
691
            vx2 = extent.maxX();
853
        if (vx2 > requestExtent.maxX()) 
854
            vx2 = requestExtent.maxX();
692 855
        
693
        if (sz.maxY() > extent.maxY())
694
            vy2 = extent.maxY();
695
        
856
        if (vy2 > requestExtent.maxY())
857
            vy2 = requestExtent.maxY();
858
                
696 859
        if (geoFile != null) {
697 860
            for (int i = 0; i < geoFile.length; i++)
698
                geoFile[i].setView(new Extent(vx, vy, vx2, vy2));
861
            	geoFile[i].setView(new Extent(vx, vy, vx2, vy2));
699 862
        } else {
700 863
            System.err.println("PxRaster.calculateNewView(): Imagen no cargada.");
701 864
        }
......
729 892
        }
730 893
    }
731 894
    
732
    /**
733
     * Dibuja el raster sobre el Graphics. Para ello debemos de pasar el viewPort que corresponde a la
734
     * vista. Este viewPort es ajustado a los tama?os m?ximos y m?nimos de la imagen por la funci?n  
735
     * calculateNewView. Esta funci?n tambi?n asignar? la vista a los drivers. Posteriormente se calcula 
736
     * el alto y ancho de la imagen a dibujar (wImg, hImg), as? como el punto donde se va a pintar dentro 
737
     * del graphics (pt). Finalmente se llama a updateImage del driver para que pinte y una vez dibujado
738
     * se pasa a trav?s de la funci?n renderizeRaster que es la encargada de aplicar la pila de filtros
739
     * sobre el Image que ha devuelto el driver.
740
     * 
741
     * @param g Graphics sobre el que se pinta
742
     * @param vp ViewPort de la extensi?n a dibujar
743
     */
895
    /** Dibuja el raster sobre el Graphics. Para ello debemos de pasar el viewPort que corresponde a la
896
    * vista. Este viewPort es ajustado a los tama?os m?ximos y m?nimos de la imagen por la funci?n  
897
    * calculateNewView. Esta funci?n tambi?n asignar? la vista a los drivers. Posteriormente se calcula 
898
    * el alto y ancho de la imagen a dibujar (wImg, hImg), as? como el punto donde se va a pintar dentro 
899
    * del graphics (pt). Finalmente se llama a updateImage del driver para que pinte y una vez dibujado
900
    * se pasa a trav?s de la funci?n renderizeRaster que es la encargada de aplicar la pila de filtros
901
    * sobre el Image que ha devuelto el driver.
902
    * 
903
    * Para calcular en que coordenada pixel (pt) se empezar? a pintar el BufferedImage con el raster le?do
904
    * se aplica sobre la esquina superior izquierda de esta la matriz de transformaci?n del ViewPortData
905
    * pasado vp.mat.transform(pt, pt). Si el raster no est? rotado este punto es el resultante de la
906
    * funci?n calculateNewView que devuelve la petici?n ajustada al extent de la imagen (sin rotar). Si
907
    * el raster est? rotado necesitaremos para la transformaci?n el resultado de la funci?n coordULRotateRaster. 
908
    * Lo que hace esta ?ltima es colocar la petici?n que ha sido puesta en coordenadas de la imagen sin rotar
909
    * (para pedir al driver de forma correcta) otra vez en coordenadas de la imagen rotada (para calcular su 
910
    * posici?n de dibujado).
911
    * 
912
    * Para dibujar sobre el Graphics2D el raster rotado aplicaremos la matriz de transformaci?n con los 
913
    * par?metros de Shear sobre este Graphics de forma inversa. Como hemos movido el fondo tendremos que
914
    * recalcular ahora el punto donde se comienza a dibujar aplicandole la transformaci?n sobre este
915
    * at.inverseTransform(pt, pt);. Finalmente volcamos el BufferedImage sobre el Graphics volviendo a dejar
916
    * el Graphics en su posici?n original al acabar. 
917
    * 
918
    * @param g Graphics sobre el que se pinta
919
    * @param vp ViewPort de la extensi?n a dibujar
920
    */
744 921
    public synchronized void draw(Graphics2D g, ViewPortData vp) {
745 922
        geoImage = null;
746

  
923
    	double shearX = 0;
924
        double shearY = 0;
925
        double factor = 1;
926
        
747 927
        long t2;
748 928
        long t1 = new Date().getTime();
749 929
        lastViewPort = vp;
......
755 935
            return;
756 936
        }
757 937

  
758
        double[] adjustedExtent = calculateNewView(vp.getExtent());
759

  
938
        double[] adjustedExtent = calculateNewView(vp);
939
        Point2D p2d = coordULRotateRaster(adjustedExtent);
940
        
760 941
        Extent v = geoFile[0].getView();
761 942
        double x = v.minX();
762 943
        double y = v.minY();
......
770 951
        int hImg = (int) Math.round(Math.abs(h * scaley));*/
771 952
        int wImg = (int) Math.round(Math.abs((adjustedExtent[2] - adjustedExtent[0]) * scalex));
772 953
        int hImg = (int) Math.round(Math.abs((adjustedExtent[3] - adjustedExtent[1]) * scaley));
773

  
954
                
774 955
        if ((wImg <= 0) || (hImg <= 0))
775 956
            return;
776
        
957
                
777 958
        //Para la transformaci?n usamos el extent que ha ajustado la funci?n calculateNewView y no usamos 
778 959
        //el getView porque el getView puede haber  sufrido una transformaci?n en caso de que exista 
779 960
        //fichero .rmf. En caso de no existir este fichero ser?a lo mismo aplicar la funci?n:
780 961
        //Point2D.Double pt = new Point2D.Double(x, y + h);
781
        Point2D.Double pt = new Point2D.Double(adjustedExtent[0], adjustedExtent[3]);
962
        int wI = wImg, hI = hImg;
963
        double[] transf = bandSwitch.getBandR().getGeoRasterFile().getTransform();
964
        Point2D.Double pt = null;
965
       	if(transf != null && (transf[2] != 0 || transf[4] != 0)){ //Esta rotada
966
       		pt =  new Point2D.Double(p2d.getX(), p2d.getY());
967
       		wImg = (int) Math.round(Math.abs((adjustedRotedExtent[2] - adjustedRotedExtent[0]) * scalex));
968
            hImg = (int) Math.round(Math.abs((adjustedRotedExtent[3] - adjustedRotedExtent[1]) * scaley));
969
       	}else{	//No est? rotada
970
       			pt = new Point2D.Double(adjustedExtent[0], adjustedExtent[3]);
971
       	}
782 972
        
783 973
        try {
784 974
            vp.mat.transform(pt, pt);
......
851 1041

  
852 1042
                geoImage = renderizeRaster(geoImage, vp, v);
853 1043

  
854
                g.drawImage(geoImage, (int) (pt.getX()), (int) (pt.getY()), component);
1044
                AffineTransform at = new AffineTransform();
1045

  
1046
                if(transf != null && (transf[2] != 0 || transf[4] != 0)){
1047
                	                	
1048
                	//Obtenemos los par?metros de shearing
1049
	                if(transf[5] != 0)
1050
	                	shearX = transf[2] / transf[5];
1051
	                else
1052
	                	shearX = transf[2];
1053
	                if(transf[1] != 0)
1054
	                	shearY = transf[4] / transf[1];
1055
	                else
1056
	                	shearY = transf[4];
1057
	                
1058
	                //Aplicamos el shear a la vista
1059
	        		at.setToShear(-shearX, -shearY);
1060
	        		
1061
	        		//Escalamos en pixeles la misma cantidad que hemos le?do de m?s.  
1062
	        		at.scale(((double)wI/(double)wImg), ((double)hI/(double)hImg));
1063
	        			        		      			        		
1064
	        		g.transform(at);
1065
	        		
1066
	        		//Aplicamos el shear inverso al punto donde se comienza a dibujar
1067
	        		at.inverseTransform(pt, pt);
1068
	        		
1069
	        		g.drawImage(geoImage, (int) (pt.getX()), (int) (pt.getY()), component);
1070
	        		g.transform(at.createInverse());
1071
                }else
1072
                	g.drawImage(geoImage, (int) (pt.getX()), (int) (pt.getY()), component);
1073
                                
1074
                
855 1075
            } else { // no cargada
856 1076
                System.err.println("Dibujando PxRaster: Foto no cargada.");
857 1077
            }

Also available in: Unified diff