head 1.1; access; symbols; locks http:1.1; strict; comment @# @; expand @b@; 1.1 date 2003.07.08.15.57.32; author PierreFernique; state Exp; branches; next ; desc @none @ 1.1 log @Aladin for AVO source code v0.933 @ text @cds/aladin/Action.java010064400076440000132000001537150770227416100156440ustar00ferniquecds00000400000013 // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.text.ParseException; import java.util.*; import java.awt.*; import cds.tools.parser.*; import cds.astro.Unit; /** * Gestion des actions associees a chaque bloc de contraintes * * @@author Thomas Boch [CDS] * @@version 0.91 : Septembre 2002 - nettoyage du code, ajouts de fonctionalites * @@version 0.9 : Juillet 2002 - Creation */ public class Action { boolean badSyntax=false; // color names static final String[] COLORNAME = { "black", "blue" ,"cyan", "darkGray", "gray", "green", "lightGray", "magenta", "orange", "pink", "red", "white", "yellow" }; // corresponding colors static final Color[] MYCOLORS = { Color.black, Color.blue, Color.cyan, Color.darkGray, Color.gray, Color.green, Color.lightGray, Color.magenta, Color.orange, Color.pink, Color.red, Color.white, Color.yellow}; // different available functions protected static final String DRAWOBJECT = "drawobject"; protected static final String DRAWSTRING = "drawstring"; protected static final String HIDE = "hide"; // shape with parameters protected static final String SIZE = "circle"; protected static final String FILLSIZE = "fillcircle"; protected static final String ELLIPSE = "ellipse"; protected static final String PM = "pm"; // a function to define a color protected static final String RGB = "rgb"; // a function to define a color in the rainbow spectrum protected static final String RAINBOW = "rainbow"; // geometric shapes (no parameters) protected static final String CARRE = "square"; protected static final String CROIX = "cross"; protected static final String PLUS = "plus"; protected static final String LOSANGE = "rhomb"; protected static final String POINT = "dot"; protected static final String DOT = "microdot"; // ensemble des formes sans paramètre protected static final String[] NOPARAMSHAPE = {CARRE,CROIX,PLUS,LOSANGE,POINT,DOT}; // just draw the source as usual protected static final String DRAW = "draw"; protected static final String COLOR = "color="; protected static final String SHAPE = "shape="; // parsers used for the ELLIPSE action Parser majAxisParser, minAxisParser, posAngleParser; // parsers used for the PM (proper motion) ACTION Parser pmDecParser, pmRAParser; Color color = null; // color of selected sources Parser sizeParser; // parser used to calculate the radius of each source // default values for max/min size of radius (actions SIZE and FILLSIZE) private int maxRadius = 30; private int minRadius = 3; /* test si les tailles des cercles sont en taille angulaire // default values (in arcsec) for max/min size of radius (actions SIZE and FILLSIZE) private int maxRadius = 60; private int minRadius = 6; */ // fin test // parsers used for the RGB function Parser redParser, greenParser, blueParser; // parser used for the RAINBOW function Parser rainbowParser; boolean colorIsVariable = false; // true if the RGB color of this action is variable boolean rainbowColorIsVariable = false; // true if the RAINBOW color of this action is variable boolean mustComputeMinMax = true; // true if min/max value is not set yet boolean mustComputeRGBMinMax = true; // true if RGB values of color were not computed yet boolean mustComputeRainbowMinMax = true; // true if RAINBOW values not computed yet boolean userDefinedMinMax = false; // true if min and max values were given by the user (4th and 5th optional parameters of circle) boolean userDefinedRainbowMinMax = false;// true if rainbow min and max values were given by the user (optional parameters) double minValue,maxValue; // max/min value of sizeParser in the set of sources double redMinValue, redMaxValue, blueMinValue, blueMaxValue, greenMinValue, greenMaxValue; // max/min value of R, G, B parsers double rainbowMinValue, rainbowMaxValue; // max/min value of rainbowParser private String shape = DRAW; // name of the shape - default : DRAW private String function = DRAWOBJECT; // function used in this action // chaine representant la chaine à afficher (peut-etre un UCD ou une colonne) String textToDisp; // parser représentant l'expression à afficher à l'écran Parser parserToDisp = null; // largeur et hauteur et du texte int wTexte, hTexte; // fonte du texte Font F = Aladin.SBOLD; // Reference to Aladin Aladin a; // Reference to the PlanFilter PlanFilter pf; // constructor with the name of the action and constraints string Action(String actionStr, Aladin a, PlanFilter pf) { this.a = a; this.pf = pf; decodeAction(actionStr); } /** performs an action * @@param s : the source which the action is performed on * @@param g * @@param p : position(x,y) of the source * @@param numero - numero du filtre * @@param index - index de l'action */ protected void action(Source s, Graphics g, Point p, int numero, int index) { // if the color is not set, set it to the color of the plan of the source if( colorIsVariable ) { color = computeColor(s); } if( rainbowColorIsVariable ) { color = computeRainbowColor(s); } Color theColor = color; if(theColor==null) {theColor = s.plan.c;} if(function.equals(HIDE)) { // do nothing return; } else if( function.equals(DRAWOBJECT) ) { if(shape.equals(DRAW)) { s.doDraw(g,p,theColor); return; } else if(shape.equals(CARRE)) { g.setColor(theColor); s.drawCarre(g,p); return; } else if(shape.equals(CROIX)) { g.setColor(theColor); s.drawCroix(g,p); return; } else if(shape.equals(PLUS)) { g.setColor(theColor); s.drawPlus(g,p); return; } else if(shape.equals(LOSANGE)) { g.setColor(theColor); s.drawLosange(g,p); return; } else if(shape.equals(POINT)) { g.setColor(theColor); s.drawPoint(g,p); return; } else if(shape.equals(DOT)) { g.setColor(theColor); s.drawDot(g,p); return; } else if(shape.equals(ELLIPSE)) { drawEllipse(s,g,p,theColor,numero,index); return; } else if(shape.equals(PM)) { drawPM(s,g,p,theColor, numero, index); return; } else if(shape.equals(SIZE)||shape.equals(FILLSIZE)) { // rien à faire si la valeur est de -1 if( s.values[numero][index][0] == -1 ) return; int intvalue = (int)(s.values[numero][index][0]*a.calque.view.zoomview.zoom); /* TEST pour passer d'un rayon en pixels à un rayon angulaire // test pour passer d'un rayon en pixels à un rayon en arcsec Plan ref = a.calque.getPlanRef(); if(ref==null) ref = s.plan; PointD p0 = new PointD(ref.projd.cx,ref.projd.cy); Coord coo = new Coord(); coo.x = p0.x; coo.y = p0.y; coo = ref.projd.getCoord(coo); coo.al = coo.al+(1.0)/60.0; coo = ref.projd.getXY(coo); PointD p1 = new PointD(coo.x, coo.y); // System.out.println(p0.x); // System.out.println(p1.x); // System.out.println(p0.y); // System.out.println(p1.y); // System.out.println( "result : "+Math.sqrt(Math.pow(p1.x-p0.x,2)+Math.pow(p1.y-p0.y,2))/(1.0) ); // nb pixels pour 1 arcmin double nbPix = Math.sqrt(Math.pow(p1.x-p0.x,2)+Math.pow(p1.y-p0.y,2))/(1.0); //System.out.println("nb pix : "+nbPix); //System.out.println("values : "+s.values[numero][index][0]); intvalue = (int)((s.values[numero][index][0]/60.0)*nbPix*a.calque.view.zoomview.zoom); //System.out.println("intvalue " +intvalue); */ g.setColor(theColor); if( shape.equals(SIZE) ) g.drawOval(p.x-intvalue/2,p.y-intvalue/2,intvalue,intvalue); else g.fillOval(p.x-intvalue/2,p.y-intvalue/2,intvalue,intvalue); return; } // default action for DRAWOBJECT : do nothing special, ie draws the source as usual else { s.doDraw(g,p,null); return; } } else if( function.equals(DRAWSTRING) ) { String texte; // the text is variable if( textToDisp!=null && ( textToDisp.startsWith("[") || textToDisp.startsWith("{") ) ) { int pos; // case of a UCD if( textToDisp.startsWith("[") ) { if( (pos=s.findUCD(UCDFilter.decodeUCD(textToDisp).substring(1,textToDisp.length()-1).toUpperCase())) < 0 ) {return;} texte = s.getValue(pos); } // case of a column else { if( (pos=s.findColumn(UCDFilter.decodeUCD(textToDisp).substring(1,textToDisp.length()-1))) < 0 ) {return;} texte = s.getValue(pos); } } // the text is an arithmetical expression else if( parserToDisp!=null ) { if( !setAllVariables(parserToDisp,s,false) ) return; else texte = new Double(parserToDisp.eval()).toString(); // we keep only 4 significant digits int sepIndex = texte.indexOf("."); if( sepIndex>=0 ) { int expIndex = texte.indexOf("E"); // on cherche le minimum pour savoir ou s'arreter int end = texte.length()>sepIndex+5?sepIndex+5:texte.length(); if( expIndex>=0 ) end = expIndex>end?end:expIndex; String saveText = new String(texte); texte = texte.substring(0, end); if( expIndex>=0 ) texte += saveText.substring(expIndex); } } // the text is constant else { int left,right; if( (left=textToDisp.indexOf("\""))>=0 && (right=textToDisp.lastIndexOf("\""))>=0 && left!=right ) { texte = textToDisp.substring(left+1,right); } else texte = textToDisp; } FontMetrics m = Toolkit.getDefaultToolkit().getFontMetrics(F); wTexte = m.stringWidth(texte)/2; hTexte = Aladin.SSIZE/2; g.setFont(F); g.setColor(theColor); g.drawString(texte,p.x-wTexte,p.y+hTexte); return; } } // decode the action we have to perform on selected/unselected sources private void decodeAction(String s) { // we save the original value of s // we will use it to decode the new syntax String os = new String(s); s = UCDFilter.skipSpaces(s); while(s.charAt(0)=='\n') { s = s.substring(1); } int beginParam = s.indexOf("("); int endParam; String paramStr = ""; if( beginParam < 0 ) {beginParam=s.length();} else { endParam = getClosingParenthesis(s, beginParam+1); if( endParam < 0 ) { badSyntax = true; Aladin.warning("Missing ) in action string",1); return; } paramStr = s.substring(beginParam+1, endParam); } String myFunction = s.substring(0,beginParam); //System.out.println(myFunction); //System.out.println(s.substring(beginParam+1, endParam)); // -- Ancienne syntaxe -- if( myFunction.equals(DRAWOBJECT) ) { function = DRAWOBJECT; decodeDrawObject(paramStr); return; } else if( myFunction.equals(DRAWSTRING) ) { function = DRAWSTRING; decodeDrawString(paramStr); return; } else if( myFunction.equals(HIDE) ) { function = HIDE; return; } // -- Nouvelle syntaxe -- (plus simple) // même plus besoin du draw //if( myFunction.startsWith(DRAW) ) { if(true) { int beginDraw = os.indexOf(DRAW); if( beginDraw>=0 ) os = os.substring(beginDraw+DRAW.length()); os = os.trim(); //System.out.println(os); // On appelle processFunction 2 fois : pour couleur et forme (ou inversement) int suite = processFunction(os); if( suite>=0 && suite=0 && b2>=0 ) before = Math.min( s.indexOf(" "), s.indexOf("(") ); if( b1<0 ) before = b2; else before = b1; if( before<0 ) before = s.length(); String name = s.substring(0,before); int pos; if ( (pos=findColorName(name))>=0 ) { this.color = MYCOLORS[pos]; return name.length(); } else if( s.startsWith(RGB) ) { before = s.indexOf("("); if( before<0 ) { badSyntax = true; Aladin.warning("Error: missing parameters for rgb function !",1); return -1; } int end = getClosingParenthesis(s,before+1); if( end < 0 ) { badSyntax = true; Aladin.warning("Error: closing parenthesis of rgb function was not found !",1); return -1; } decodeRGB(s.substring(Math.max(0,before), end+1)); return end+1; } else if( s.startsWith(RAINBOW) ) { before = s.indexOf("("); if( before<0 ) { badSyntax = true; Aladin.warning("Error: missing parameters for rainbow function !",1); return -1; } int end = getClosingParenthesis(s,before+1); if( end < 0 ) { badSyntax = true; Aladin.warning("Error: closing parenthesis of rainbow function was not found !",1); return -1; } decodeRainbow(s.substring(Math.max(0,before), end+1)); return end+1; } else if( name.startsWith("#") ) { this.color = decodeColorString(s.substring(0,before)); return name.length(); } // les shapes // on fera plus malin plus tard // shapes basiques else if( name.equals(CARRE) || name.equals(CROIX) || name.equals(PLUS) || name.equals(LOSANGE) || name.equals(POINT) || name.equals(DOT) ) { this.shape = name; function = DRAWOBJECT; return name.length(); } // shapes avec parametres // pour les mouvements propres : a voir else if( s.startsWith(SIZE) || s.startsWith(FILLSIZE) || s.startsWith(ELLIPSE) || s.startsWith(PM) ) { function = DRAWOBJECT; before = s.indexOf("("); if( before<0 ) { badSyntax = true; Aladin.warning("Error: missing parameters for shape function !",1); return -1; } int end = getClosingParenthesis(s,before+1); if( end < 0 ) { badSyntax = true; Aladin.warning("Error: closing parenthesis of shape function was not found !",1); return -1; } //System.out.println(s.substring(0, end+1)); decodeShape(SHAPE+s.substring(0, end+1)); return end+1; } // à ce stade, on a épuisé toutes les fonctions disponibles ! // on essaye de parser la chaine comme une expression mathématique dont on afficherait le résultat else { try { parserToDisp = UCDFilter.createParser(s, a); function = DRAWSTRING; return -1; } catch( ParserException e) {} } //if( setAllVariables() ) badSyntax = true; Aladin.warning("Your function "+s+" could not be understood !",1); return -1; } /** decode une couleur pouvant etre une couleur predefinie ou une fonction rgb() * * */ private void processColor(String s) { int pos; if ( (pos=findColorName(s))>=0 ) { this.color = MYCOLORS[pos]; return; } else if( s.startsWith(RGB) ) { decodeRGB(s); return; } else if( s.startsWith(RAINBOW) ) { decodeRainbow(s); return; } else this.color = decodeColorString(s); } /** decode une fonction rainbow(). Set rainbowColorIsVariable a true si besoin est * La fonction peut avoir 1 ou 3 parametres. * Le premier parametre represente l'expression correspondant au rainbowParser * Les 2 parametres optionnelles sont les valeurs min et max (si elles ne sont pas precisees, on scannera l'ensemble des valeurs pour retrouver min et max) * @@param s - chaine a decoder */ private void decodeRainbow(String s) { String paramStr = s.substring(s.indexOf("(")+1, Math.max(s.lastIndexOf(")"),0)); StringTokenizer st = new StringTokenizer(paramStr,","); // there can be 1 or 3 parameters if( st.countTokens()!=1 && st.countTokens()!=3 ) { badSyntax = true; //System.out.println("Incorrect syntax for "+RAINBOW+" function. Syntax is "+RAINBOW+" rainbow(exp[,minValue,maxValue])"); Aladin.warning("Incorrect syntax for "+RAINBOW+" function. Syntax is "+RAINBOW+" rainbow(exp[,minValue,maxValue])",1); return; } try { rainbowParser = UCDFilter.createParser(st.nextToken(),a); } catch(ParserException e) {Aladin.warning("Malformed expression in rainbow parameters, error",1);badSyntax=true;return;} // if value is constant if( rainbowParser.isConstant() ) { color = Color.getHSBColor(getHue((float)rainbowParser.eval()),1f,1f); } else rainbowColorIsVariable = true; // in case min and max values were given if( st.hasMoreTokens() ) { try { rainbowMinValue = Double.valueOf(st.nextToken()).doubleValue(); rainbowMaxValue = Double.valueOf(st.nextToken()).doubleValue(); } catch(NumberFormatException e) { Aladin.warning("Error in min/max values of rainbow function. Only decimal values are permitted,1"); badSyntax=true; return; } // min and max are already fixed, set mustCompute to false mustComputeRainbowMinMax = false; userDefinedRainbowMinMax = true; } } /** decode une fonction rgb(,,). Set colorIsVariable a true si besoin est * @@param s - chaine a decoder */ private void decodeRGB(String s) { //System.out.println(s); //System.out.println(s.indexOf("(")); //System.out.println(s.lastIndexOf(")")); String paramStr = s.substring(s.indexOf("(")+1, Math.max(s.lastIndexOf(")"),0)); //System.out.println(paramStr); StringTokenizer st = new StringTokenizer(paramStr,","); // there must be exactly 3 parameters if( st.countTokens() != 3 ) { badSyntax = true; //System.out.println("rgb function should have exactly 3 parameters"); Aladin.warning("rgb function should have exactly 3 parameters",1); return; } // creation of R, G, B parsers try { redParser = UCDFilter.createParser(st.nextToken(),a); greenParser = UCDFilter.createParser(st.nextToken(),a); blueParser = UCDFilter.createParser(st.nextToken(),a); } catch(ParserException e) {Aladin.warning("Malformed expression in rgb parameters, error",1);badSyntax=true;return;} // if RGB values are constant if( redParser.isConstant() && greenParser.isConstant() && blueParser.isConstant() ) { this.color = new Color( Math.max(Math.min((float)redParser.eval()/255f,1f),0f), Math.max(Math.min((float)greenParser.eval()/255f,1f),0f), Math.max(Math.min((float)blueParser.eval()/255f,1f),0f) ); } else colorIsVariable = true; } /** decode une couleur entree en RGB * @@param s - la chaine reprensentant la couleur en RGB * @@return la couleur correspondante, null si erreur durant le decodage */ private Color decodeColorString(String s) { Color retCol; try { //retCol = Color.decode("#"+s); retCol = Color.decode(s); } catch (NumberFormatException e) {retCol=null;} return retCol; } /** looks for s in COLORNAME, returns the position of s in COLORNAME, -1 if not found */ private int findColorName(String s) { for(int i=0;iupLimit) hue=upLimit; if(hue<0) hue=0; */ return Color.getHSBColor(hue, 1f, 1f); } /** petit traitement sur la valeur de hue */ private float getHue(float hue) { // limite superieure pour hue (sinon, on retombe sur du rouge) final float upLimit = 0.78f; float ret = 1-hue; // parce que hsv(1,x,y)==hsv(0,x,y) ret *= upLimit; // permet d'aller du violet au rouge // ce genre de situations peut se produire lorsque rainbow{Min,Max}value ont ete fixees par l'utilisateur if(ret>upLimit) ret=upLimit; if(ret<0) ret=0; return ret; } /** compute the color when it depends on parameters * @@param s - the source being processed * @@return the computed color, null if the color could not be computed (missing variable in source for example) */ private Color computeColor(Source s) { // RGB components of the color float redComp, greenComp, blueComp; double redVal, greenVal, blueVal; if( mustComputeRGBMinMax ) { computeRGBMinMax(); mustComputeRGBMinMax = false; } if( ! setAllVariables(redParser, s, false) ) return null; if( ! setAllVariables(blueParser, s, false) ) return null; if( ! setAllVariables(greenParser, s, false) ) return null; redVal = redParser.eval(); greenVal = greenParser.eval(); blueVal = blueParser.eval(); // Probleme du 99.9 dans les magnitudes if(redVal==99.9 || greenVal==99.9 || blueVal==99.9) return null; redComp = (redParser.isConstant())? Math.max(Math.min((float)redVal/255f,1f),0f) : (float) ((redVal-redMinValue)/(redMaxValue-redMinValue)); greenComp = (greenParser.isConstant())? Math.max(Math.min((float)greenVal/255f,1f),0f) : (float) ((greenVal-greenMinValue)/(greenMaxValue-greenMinValue)); //System.out.println(blueParser.eval()); blueComp = (blueParser.isConstant())? Math.max(Math.min((float)blueVal/255f,1f),0f) : (float) ((blueVal-blueMinValue)/(blueMaxValue-blueMinValue)); // Probleme du 99.9 dans les magnitudes /*if(redComp>1 || blueComp>1 || greenComp>1 || redComp<0 || blueComp<0 || greenComp<0) return null;*/ //System.out.println(redComp+"\t"+greenComp+"\t"+blueComp); return new Color(redComp, greenComp, blueComp); } /** traite les parametres pour une fonction DRAWSTRING * @@param param - la chaine des parametres */ private void decodeDrawString(String param) { StringTokenizer st = new StringTokenizer(param, ","); String curStr = null; while(st.hasMoreTokens()) { curStr = st.nextToken(); if(curStr.startsWith(COLOR)) { // to retrieve all parameters try { while( countNbOcc('(',curStr) != countNbOcc(')',curStr) ) { curStr += ","+st.nextToken(); } } catch(NoSuchElementException e) {Aladin.warning("Error in color syntax",1);badSyntax=true;return;} processColor(curStr.substring(COLOR.length())); } // sinon on recupere le texte a afficher // on fait ca a l affichage pour le moment // a reporter ici quand on aura un tableau d objets dans Source --> finalement, on laisse ainsi else { textToDisp = curStr; } } } /** traite les parametres pour une fonction DRAWOBJECT * @@param param - la chaine des parametres */ private void decodeDrawObject(String param) { StringTokenizer st = new StringTokenizer(param, ","); String curStr = null; while(st.hasMoreTokens()) { curStr = st.nextToken(); if(curStr.startsWith(COLOR)) { // to retrieve all parameters try { while( countNbOcc('(',curStr) != countNbOcc(')',curStr) ) { curStr += ","+st.nextToken(); } } catch(NoSuchElementException e) {Aladin.warning("Error in color syntax",1);badSyntax=true;return;} processColor(curStr.substring(COLOR.length())); } else if(curStr.startsWith(SHAPE)) { // to retrieve all parameters if( ( curStr.indexOf(SIZE)>=0 || curStr.indexOf(FILLSIZE)>=0 || curStr.indexOf(ELLIPSE)>=0 || curStr.indexOf(PM)>=0 ) && curStr.indexOf("(")>=0 ) { try { while( countNbOcc('(',curStr) != countNbOcc(')',curStr) ) { curStr += ","+st.nextToken(); } } catch(NoSuchElementException e) {Aladin.warning("Error in action syntax",1);badSyntax=true;return;} } decodeShape(curStr); } } } private void decodeShape(String s) { //System.out.println(s); String param = s.substring(s.indexOf("(")+1, Math.max(s.lastIndexOf(")"),0) ); // is there any parameter ? if(param.length() != 0) { shape = s.substring(SHAPE.length(),s.indexOf("(")).trim(); if(shape.equals(SIZE)||shape.equals(FILLSIZE)) { StringTokenizer st = new StringTokenizer(param,","); // there can be 1 or 3 or 5 parameters // Parameters are : // 1 --> expression used to compute the radius of the circle // 2 --> min radius (pixels of image) // 3 --> max radius (pixels of image) // 4 --> minValue (value forced by user) // 5 --> maxValue (value forced by user) if( st.countTokens()!=1 && st.countTokens()!=3 && st.countTokens()!=5 ) { badSyntax = true; //System.out.println("Incorrect syntax for "+SIZE+" function. Syntax is "+SIZE+" (exp[,minRadius,maxRadius])"); Aladin.warning("Incorrect syntax for "+SIZE+" function. Syntax is "+SIZE+" (exp[,minRadius,maxRadius])",1); return; } // creation of the sizeParser try { this.sizeParser = UCDFilter.createParser(st.nextToken(),a); } catch(ParserException e) {Aladin.warning("Malformed expression in action expression, error",1);badSyntax=true;} // in this case, the user has given minRadius and maxRadius values if( st.hasMoreTokens() ) { try { minRadius = Integer.valueOf(st.nextToken()).intValue(); maxRadius = Integer.valueOf(st.nextToken()).intValue(); } catch(NumberFormatException e) { Aladin.warning("Error in min/max values of circle radius. Only integer values are permitted",1); badSyntax=true; return; } } // in this case, the user forces values of minValue and maxValue if( st.hasMoreTokens() ) { try { minValue = Integer.valueOf(st.nextToken()).intValue(); maxValue = Integer.valueOf(st.nextToken()).intValue(); } catch(NumberFormatException e) { Aladin.warning("Error in min/max values of expression. Only integer values are permitted",1); badSyntax=true; return; } // minValue and maxValue are already fixed, set mustCompute to false mustComputeMinMax = false; userDefinedMinMax = true; } } else if(shape.equals(ELLIPSE)) { decodeEllipseParameters(param); } else if(shape.equals(PM)) { decodePMParameters(param); } } else { shape = s.substring(SHAPE.length()); if(shape.equals(ELLIPSE) || shape.equals(SIZE) || shape.equals(FILLSIZE) || shape.equals(PM)) {Aladin.warning("Error, missing parameters for the action "+shape,1);badSyntax=true;} } } /** decodes the parameters of a PM action * @@param param the string of parameters */ private void decodePMParameters(String param) { StringTokenizer st = new StringTokenizer(param,","); String pmdec,pmra; pmdec=pmra=""; try { pmra = st.nextToken(); pmdec = st.nextToken(); } catch(NoSuchElementException e) {Aladin.warning("Missing parameter for the proper motion",1);badSyntax=true;} //System.out.println(pmdec); //System.out.println(pmra); pmRAParser = UCDFilter.createParser(pmra,a); pmDecParser = UCDFilter.createParser(pmdec,a); } /** decodes the parameters of an ELLIPSE action * @@param param the string of parameters */ private void decodeEllipseParameters(String param) { StringTokenizer st = new StringTokenizer(param,","); String majAxis, minAxis, posAngle; majAxis=minAxis=posAngle=""; try { majAxis = st.nextToken(); minAxis = st.nextToken(); posAngle = st.nextToken(); } catch(NoSuchElementException e) {Aladin.warning("Missing parameter for the ellipse",1);badSyntax=true;} //System.out.println(majAxis); //System.out.println(minAxis); //System.out.println(posAngle); majAxisParser = UCDFilter.createParser(majAxis,a); minAxisParser = UCDFilter.createParser(minAxis,a); posAngleParser = UCDFilter.createParser(posAngle,a); } /** set maxValue, minValue */ private void computeMinMax() { // if there is no variable if( sizeParser.isConstant() ) {minValue=0;maxValue=sizeParser.eval();return;} minValue = Double.POSITIVE_INFINITY; maxValue = Double.NEGATIVE_INFINITY; int i,j; Source s; Plan p = null; Objet[] o = null; double value; Plan[] plans = pf.getConcernedPlans(); // loop on all plans and selection of catalogs which are active for( i=plans.length-1; i>=0; i-- ) { p = plans[i]; o = p.pcat.o; // loop on all objects in PlanCatalog for( j=o.length-1; j>=0; j-- ) { // Pour laisser la main aux autres threads if( Aladin.isSlow && j%50==0 ) { try { Thread.currentThread().sleep(10); } catch(Exception e) { } } if( o[j] instanceof Source && o[j]!=null) { s=(Source)o[j]; //setAllVariables(sizeParser, s, true); if( ! setAllVariables(sizeParser, s, false) ) continue; value = sizeParser.eval(); // reserved value in FITS to indicate a problem if(Math.abs(value)!=99.9) { if(value>maxValue) maxValue = value; if(value=0; i-- ) { p = plans[i]; o = p.pcat.o; // loop on all objects in PlanCatalog for( j=o.length-1; j>=0; j-- ) { // Pour laisser la main aux autres threads if( Aladin.isSlow && j%50==0 ) { try { Thread.currentThread().sleep(10); } catch(Exception e) { } } if( o[j] instanceof Source && o[j]!=null) { s=(Source)o[j]; if( !setAllVariables(rainbowParser, s, false) ) { continue; } hue = rainbowParser.eval(); // reserved value in FITS to indicate a problem if( Math.abs(hue)!=99.9) { if(hue>rainbowMaxValue) rainbowMaxValue = hue; if(hue=0; i-- ) { p = plans[i]; o = p.pcat.o; // loop on all objects in PlanCatalog for( j=o.length-1; j>=0; j-- ) { // Pour laisser la main aux autres threads if( Aladin.isSlow && j%50==0 ) { try { Thread.currentThread().sleep(10); } catch(Exception e) { } } if( o[j] instanceof Source && o[j]!=null) { s=(Source)o[j]; if( !setAllVariables(redParser, s, false) || !setAllVariables(greenParser, s, false) || !setAllVariables(blueParser, s, false) ) continue; redValue = redParser.eval(); greenValue = greenParser.eval(); blueValue = blueParser.eval(); // reserved value in FITS to indicate a problem if( Math.abs(redValue)!=99.9) { if(redValue>redMaxValue) redMaxValue = redValue; if(redValuegreenMaxValue) greenMaxValue = greenValue; if(greenValueblueMaxValue) blueMaxValue = blueValue; if(blueValue on garde les valeurs originales else { return; } } // On essaye maintenant de convertir Dec en arcsec/yr succeed = true; try { DEmas = new Unit("1mas/yr"); DEmas.convert(uDec); } catch(java.text.ParseException e) {succeed=false;} catch(ArithmeticException e2) {succeed=false;} // on a réussi convertir RA et Dec if( succeed ) { newValDe = DEmas.value; // si la conversion a donné des choses étranges if( Double.isNaN(newValRA)||Double.isNaN(newValDe) ) { return; } s.values[numero][index][0] = newValRA; s.values[numero][index][1] = newValDe; } else { return; } } /** private method used by computePM and which actually draws the vector on the graphic context g * @@param s - the source * @@param g - the graphic context * @@param p - position of the source in g * @@param c - color of the ellipse * @@param numero - numero du filtre * @@param index - index de l'action */ private void drawPM(Source s, Graphics g, Point p, Color c, int numero, int index) { double factor = 1000.0; // par combien on multiplie pour voir qqch ? // un déplacement de 1 arcsec/yr est représenté par une flèche de 1*factor mas // prendre les valeurs en mas/yr, et multiplier d'office par 1000 int lFleche = 8; // longueur du bout de la fleche double pmRA = s.values[numero][index][0]; double pmDec = s.values[numero][index][1]; //System.out.println(pmRA); //System.out.println(pmDec); // -1 est la valeur d'initialisation if(pmRA==-1 && pmDec==-1) return; Plan base = a.calque.getPlanRef(); if(base==null) base = s.plan; Coord coord = new Coord(); coord.al = s.raj; coord.del = s.dej; coord=base.projd.getXY(coord); double orgX = coord.x; double orgY = coord.y; ZoomView zoomview = a.calque.view.zoomview; lFleche *= zoomview.zoom; // multiplication par le facteur pour y voir qqch pmRA *= factor; pmDec *= factor; // pmRA et pmDec sont en mas/yr coord.al += (pmRA/3600000)/Math.cos(Math.PI*coord.del/180.0); coord.del += (pmDec/3600000); coord = new Coord(coord.al,coord.del); coord = base.projd.getXY(coord); // dessin du mouvement propre Point p1 = zoomview.getViewCoord(orgX,orgY); Point p2 = zoomview.getViewCoord(coord.x,coord.y); // calcul pour les fleches // angle que fait p2 avec l'horizontale dans le repere (p1,x,y) double angle = Math.atan((orgY-coord.y)/(orgX-coord.x)); if( (orgX-coord.x)<0 ) angle = angle+Math.PI; double alpha = angle+45*Math.PI/180.0; Point f1 = new Point( (int)(lFleche*Math.cos(alpha))+p2.x, (int)(lFleche*Math.sin(alpha))+p2.y ); alpha = angle-45*Math.PI/180.0; Point f2 = new Point( (int)(lFleche*Math.cos(alpha))+p2.x, (int)(lFleche*Math.sin(alpha))+p2.y ); g.setColor(c); g.drawLine(p1.x,p1.y,p2.x,p2.y); g.drawLine(p2.x,p2.y,f1.x,f1.y); g.drawLine(p2.x,p2.y,f2.x,f2.y); } /** draws the ellipse associated with a source * @@param s - the source * @@param numero - numero du filtre * @@param index - index de l'action */ private void computeEllipse(Source s, int numero, int index) { // reference unit : arcsec try{Unit refUnit = new Unit("arcsec");} catch(java.text.ParseException e) {} // first, we retrieve the value of the 3 parameters // on considere que par defaut : grand axe et petit axe en arcsec // posangle en degres decimaux // on pourrait faire la conversion aussi // pour le grand axe if( ! setAllVariables(majAxisParser, s, false) ) return; // pour le petit axe if( ! setAllVariables(minAxisParser, s, false) ) return; // A ce stade, on sauvegarde deja les valeurs de petit axe et grand axe dans s.values (comme ca c'est fait meme si on trouve rien pour l'angle de position) s.values[numero][index][0] = majAxisParser.eval(); s.values[numero][index][1] = minAxisParser.eval(); // pour l'angle de position if ( ! setAllVariables(posAngleParser, s, false) ) return; s.values[numero][index][2] = posAngleParser.eval(); } /** private method which actually draws the ellipse on the graphic context g * @@param s - the source * @@param g - the graphic context * @@param p - position of the source in g * @@param c - color of the ellipse * @@param numero - numero du filtre * @@param index - index de l'action */ // Remarque : on pourrait ameliorer le temps de calcul en ne recalculant pas a chaque fois // il faudrait verifier que le plan de ref. n'a pas change private void drawEllipse(Source s, Graphics g, Point p, Color c, int numero, int index) { // majAxis and minAxis in arcsec, posAngle in deg double majAxis = s.values[numero][index][0]; double minAxis = s.values[numero][index][1]; double posAngle = s.values[numero][index][2]; if(posAngle==-1) posAngle=0; //System.out.println(posAngle); if(majAxis==-1) return; //System.out.println(majAxis+" "+minAxis+" "+posAngle); // fin test Plan base = a.calque.getPlanRef(); if(base==null) base = s.plan; Coord coord = new Coord(); coord.al = s.raj; coord.del = s.dej; Coord coord2 = new Coord(); coord2.al = s.raj; coord2.del = s.dej; coord2=base.projd.getXY(coord2); double orgX = coord2.x; double orgY = coord2.y; ZoomView zoomview = a.calque.view.zoomview; coord.al += (majAxis/3600)*Math.sin(posAngle*2*Math.PI/360)/Math.cos(coord.del*2*Math.PI/360); coord.del += (majAxis/3600)*Math.cos(posAngle*2*Math.PI/360); coord2.al += (minAxis/3600)*Math.cos(posAngle*2*Math.PI/360)/Math.cos(coord2.del*2*Math.PI/360); coord2.del += -(minAxis/3600)*Math.sin(posAngle*2*Math.PI/360); coord = new Coord(coord.al,coord.del); coord = base.projd.getXY(coord); coord2 = new Coord(coord2.al,coord2.del); coord2 = base.projd.getXY(coord2); // dessin du grand axe Point p1 = zoomview.getViewCoord(coord.x,coord.y); double x1 = coord.x; double y1 = coord.y; Point p2 = zoomview.getViewCoord(coord.x-2*(coord.x-orgX),coord.y-2*(coord.y-orgY)); double gdAxe = Math.sqrt(Math.pow(p2.x-p1.x,2)+Math.pow(p2.y-p1.y,2)); // dessin du petit axe p1 = zoomview.getViewCoord(coord2.x,coord2.y); p2 = zoomview.getViewCoord(coord2.x-2*(coord2.x-orgX),coord2.y-2*(coord2.y-orgY)); double petitAxe = Math.sqrt(Math.pow(p2.x-p1.x,2)+Math.pow(p2.y-p1.y,2)); Point centre = new Point((int)((p1.x+p2.x)/2),(int)((p1.y+p2.y)/2)); // de combien faut il tourner l ellipse dans le contexte graphique courant //double angle = Math.asin((orgY-y1)/Math.sqrt(Math.pow(x1-orgX,2)+Math.pow(y1-orgY,2)))*180/Math.PI; //System.out.println(angle); double angle = Math.atan((orgY-y1)/(orgX-x1))*180/Math.PI; //System.out.println(angle); doDrawEllipse(g,c,centre,0.5*gdAxe,0.5*petitAxe,angle); } /** draws an ellipse which can be rotated * @@param g - the graphic context we draw on * @@param c - color of the ellipse * @@param center - the "center" of the ellipse * @@param semiMA - value of the semi-major axis * @@param semiMI - value of the semi-minor axis * @@param angle - rotation angle around center */ private void doDrawEllipse(Graphics g, Color c, Point center, double semiMA, double semiMI, double angle) { // convert the angle into radians angle = angle*Math.PI/180.0; // number of iterations int nbIt = 30; Point[] p = new Point[nbIt]; double x,y,tmpX,tmpY; double curAngle; // first, we fill the array for(int i=0; imaxValue ) value = maxValue; else if( value * Elle fonctionne a la fois en Applet ou en Standalone via la fonction main() * * @@author Pierre Fernique [CDS] * @@version 0.932 AVO prototype deuxieme generation * *
 *    1.429 Mar 2003 Quelques corrections de bugs + prise en compte VOPLot/Web
 *    1.426 Mar 2003 Installation officielle
 *    1.425 Mar 2003 Pour faire plaisir a Christian
 *    1.424 Mar 2003 ExtApp interface pour VOPlot/Aladin interactions
 *    1.422 fev 2003 qq bugs fixes (nouvelle version officielle)
 *    1.419 nov 2002 XY reels, VOtable et filtre
 *    1.305 juin 2002 Qq bugs corriges
 *    1.302 mai 2002 VizieR externalise (Andre Schaaff) + Projection
 *    1.212 avril 2002 contours + corrections
 *    1.203 mars 2002 bouton LINKS
 *    1.202 mars 2002 peaufinage du code
 *    1.200 jan 2002 La nouvelle version officielle
 *    1.146 26 octobre 2001 reorganisation des commandes scripts
 *    1.145 23 mars 2001 suppression du -noveto
 *    1.144 9 mars 2001 - methode launch(), parametre -np
 *    1.143 19 fev 2001 - Bridage pour l'utilisation en script (-noveto)
 *    1.142 12 fev 2001 - Command.java et extension des shortcut commmand
 *    1.141 8 fev 2001 - Correction bug Calib.java
 *    1.140 1 fev 2001 - Une nouvelle version distribuable
 *    1.138 12 dec 2000 - MCanvas aligne, saisie rapide
 *    1.137 22 nov 2000 - Definition serveurs utilisateur
 *    1.136 18 sept 2000 - PlanField
 *    1.135 19 juin 2000 - Utilisation de PushbackInputStream()
 *    1.134 5 juin 2000 - Mise en place de Hdecomp
 *    1.133 27 avril 2000 - Corr. bug precession Calib.java
 *    1.132 11 avril 2000 - Corr. bug "out of memory" du backup stack
 *    1.131 7 avril 2000 - Correction bug superposition plans
 *    1.130 23 mars 2000 - Utilisation du package Fox pour les Coord
 *    1.128 20 mars 2000 - Creation des objets java en asynchrone
 *    1.127 10 mars 2000 - Nouvelle Calib + Projection Fox
 *    1.126 25 fev 2000 - Nouvelle Calib + zoom <1
 *    1.125 21 fev 2000 - qq mises au point
 *    1.124 17 fev 2000 - ajout de la colorMap Gray
 *    1.123 14 fev 2000 - qq mise au point + URLStatus
 *    1.122 4 fev 2000 - qq mise au point + gzip pour fits
 *    1.121 6 jan 2000 - qq mise au point + save, print and load
 *    1.120 25 nov 1999 - Modif XML + mrdecomp
 *    1.110 6 sept 1999 - integration XMl pour l'acces aux data et
 *    1.100 3 sept 1999 - premiere version officielle
 *    0.972 24 aout 1999 - mode trace
 *    0.971 27 juil 1999 - Acces HST archive
 *    0.970 15 juin 1999 - Nouvel Aladin server interface
 *    0.969 7 juin 1999 - Je ne sais plus
 *    0.968 3 juin 1999 - Pad
 *    0.967 2 juin 1999 - Browser Windows + suivi de log
 *    0.966 28 mai 1999 - Correction bugs des fonts Netscape 4.5
 *    0.965 28 mai 1999      - Chargement local d'images FITS
 *    0.964 26 mai 1999      - GLU JAVA inside + 2MASS
 *    0.963 25 mai 1999      - Toilettage Daniel Egret + qq bugs corriges
 *    0.962 19 mai 1999      - Message d'accueil special lors d'un load
 *    0.961 10 mai 1999      - Toilettage du code
 *    0.960 4 mai 1999       - Mise en place du package aladin
 *    0.956 26 avril 1999    - status d'attente des images,
 *                             bug n superimposed corrige + FITS
 *    0.955 23 avril 1999    - Gestion du Fits (prelude), clignotement debogue,
 *                            + setPixels() maison
 *    0.954 17 mars 1999     - Fusion automatique simbad
 *    0.953 4 mars 1999      - Repere avec position affichable
 *    0.952 26 fevrier 1999  - Test calibration + getParam Vizir+Aladin
 *    0.951 23 fevrier 1999  - correction TRC + PA
 *    0.95  18 fevrier 1999  - mise en service
 *    0.942 15 fevrier 1999  - Optimisation "final" et getContent()
 *    0.941 4 fevrier 1999   - Nettoyage de code
 *    0.94  4 fevrier 1999   - Fin automatique du message d'accueil
 *    0.93  1 fevrier 1999   - Premiere version officielle (en test)
 *    0.92  28 janvier 1999  - Implantatation de ma propre gestion des images
 *                            + getFAQ et WARNING des calibrations
 *    0.91  14 janvier 1999  - Ajout de la fonction video inverse
 *                             reformatage des formulaires des serveurs
 *    0.9   23 novembre 1998 - Premiere partie du nettoyage a fond du code
 *    0.8   octobre 1998     - premiere version executable
 * 
*/ public class Aladin extends Applet implements ExtApp,AceConsumer { static final boolean LSCREEN= Toolkit.getDefaultToolkit().getScreenSize().width>1000; /** Nom de l'application */ static protected final String TITRE = "A.V.O demonstration prototype"; /** Numero de version */ static protected final String VERSION = "v0.932"; static protected String currentVersion = null; // Version courante dispo /** MRdecomp active */ static protected final boolean MRDECOMP= false; /** Nombre de plans de l'interface */ static protected int MAXPLANS = LSCREEN?14:7; /** Nombre de plans*/ /** Taille moyenne des fonts */ static protected final int SIZE = 12; static final String ICON = "icon.gif"; static final String WELCOME = "Bienvenue sur "+TITRE+ " - "+getReleaseNumber(); static final String COPYRIGHT = "CDS - ESO - AstroGrid - ST-ECF - UMAN/Jodrell Bank - CNRSDR01 - VO-India"; // La couleur du fond static final Color BKGD = Color.lightGray; static Color LGRAY; static Color BLUE; static Color MAXBLUE; // Le repertoire d'installation d'Aladin static String HOME; // Le nom de la machine d'ou provient l'applet (s'il y a lieu) static String APPLETSERVER=null; static String HOSTSERVER=null; // true si Java <1.1.8 static boolean JAVABEFORE118=false; // true si le reseau est accessible static boolean NETWORK=true; // true si on affiche la console static boolean CONSOLE=true; // true si flag a Francois Bonnarel static boolean BOF=false; // True si on garde les links (pour XMM) static boolean FLAGLINKS=true; // Le nom du dico GLU specifique a Aladin static String ALAGLU = "AlaGlu.dic"; // Les fontes associees a Aladin static Font BOLD ; static Font PLAIN ; static Font ITALIC ; static int SSIZE ; static Font SBOLD ; static Font SPLAIN ; static Font SITALIC; static int LSIZE ; static Font LPLAIN ; static Font LBOLD ; static Font LITALIC; static Font LLITALIC; static Font COURIER; static Font BCOURIER; // L'instance d'aladin lui-meme, pour la methode main() et // l'utilisation par une autre application java (voir methode launch() ); static Aladin aladin; // Les objets associees a l'interface View view; // Gere la "View frame" Status status; // Gere la ligne de "Status" Split split; // Gere le logo de creation de fenetres splittees MyLabel urlStatus; // Gere la ligne de l'info sur les URLs Mesure mesure; // Gere la "Frame of measurements" ToolBox toolbox; // Gere la "Tool bar" Calque calque; // Gere a la fois les plans et le zoom Target target; // Gere l'affichage du "target" Localisation localisation; // Gere l'affichage de la "Localisation" Logo logo; // Gere le "logo" Help help; // Gere le "Help" en ligne ServerDialog dialog; // Gere l'interrogation des serveurs TreeView treeView; // Gere l'arbre contenant l'historique des interrogations Properties properties; // Gere la fenetre des proprietes de chaque plan FilterProperties filterProperties; // Gere la fenetre des proprietes pour un PlanFilter FrameCM frameCM; // Gere la fenetre du controle de la table des couleurs FrameRGB frameRGB; // Gere la fenetre pour la creation des plans RGB FrameContour frameContour; // Gere la fenetre pour les choix de niveaux de contour NotePad pad; // Gere la fenetre du bloc note Command command=null; // Gere les commandes asynchrones FrameNewCalib frameNewCalib=null; // Gere la fenetre de recalibration astrometrique // Les objets internes Glu glu; // Gere les interractions avec le GLU CardLayout cardView; // Gere la permutation entre le "Help" et la "View" CreatObj co; // pour gerer la creation parallele des widgets Object save=null; // pour gerer les sauvegardes ExtApp extApp = null; // Application cooperative a Aladin // Les memorisations en vue de mises a jour Panel bigView; // Panel contenant a la fois le view et le help Panel mesurePanel; // Panel contenant les mesures MyButton bext; // Bouton associe au "Detach" Vector vButton; // Vecteur des boutons du menu a (des/)activer Container myParent=null; // Pour pouvoir re-fenestrer Dimension dimOrigSize=null; // Dimension d'origine dans netscape static String error; // La derniere chaine d'erreur (DEVRAIT NE PAS ETRE STATIC) // True si on fonctionne en mode standalone static boolean STANDALONE = false; // Juste pour les essais NED static String CGIPATH = null; // Gestion du niveau de trace static final int MAXLEVELTRACE = 3; static int levelTrace=0; // Variables associees au mode de fonctionnement boolean flagLoad=false; // true si on est en mode de chargement static MyFrame f; // Le "Frame" en mode "Standalone" boolean msgOn=true; // True si le message d'accueil est actif static boolean test=false; // True pour le mode test actif static boolean flagLaunch=false; // true si on a demarre aladin par launch static boolean script=false; // True si le mode script est actif (sans interface) static boolean inHelp=false; // True si le mode "Help" est actif static int iv=0; // Indice de la performance JAVA static long speed=-1; // Indice de performance (lower is better) static final long slownessThreshold = 800; // Seuil a partir duquel on considere la JVM comme lente static boolean isSlow; // true si lance en mode APPLET et speed>seuil // boolean flagInsets=false; // True si on a deja pris en compte le Insets du peer boolean print=false; // true si on est entrain d'imprimer static Applet extApplet=null; // Decrit l'applet qui aurait appele launch() // La liste des auteurs static final String AUTEURS = "!\"Aladin for AVO\"\n \n \n"+ "A prototype to demonstrate\n"+ "the Astronomical Virtual Observatory concept:\n \n"+ "Partners:\n"+ " .CDS: Aladin program core - Image server - Science cases\n"+ " .ESO: SED facilities - GOODS images\n"+ " .AstroGrid: ACE facility - Science cases\n"+ " .ST-ECF: Science cases\n"+ " .UMAN/Jodrell Bank: Radio images - Science cases\n"+ " .Terapix: Sextractor provided for ACE\n"+ "Extension:\n"+ " .VO-India: VOplot facility\n"+ ""; // Les textes associes aux differentes possibilites du menu static final int GETHEIGHT = 15; // Cochonnerie de getHeight() static final String MLOAD = "Load..."; static final String MSAVE = "Save..."; static final String MPLUGIN = "Plugins..."; static final String MLINK = "Links..."; static final String MHELP = "Help..."; static final String MDCH1 = "Detach"; static final String MDCH2 = "Undetach"; static final String MPRINT = "Print..."; static final String MQUIT = "Quit"; static final String SED = "SED (ESO): Spectral Energy Distribution drawer for selected objects..."; static final String ACE = "ACE (AstroGrid): Remote object extraction on the current image..."; static final String VOPLOT = "VOplot (VO-India): 2D plotter for selected objects..."; static final String HELP = "Interactive Help mode (on/off)"; static final String FAQ = "Get the Aladin FAQ"; static final String MAN = "Get the Aladin Manual"; static final String ABOUT = "About \""+TITRE+"\""; // Les sous-menus static final String [] SMPLUGIN = { SED, ACE, VOPLOT }; static final String [] SMHELP = { HELP, FAQ, MAN, ABOUT }; // Liste des menus static final String [] MENU = { MLOAD,MSAVE,MLINK,MPLUGIN,MPRINT,MHELP, MDCH1,MQUIT }; // Menus StandAlone static final String [] MENUS = { MLOAD,MSAVE,MPLUGIN,MPRINT,MHELP,MQUIT }; // Menus Applet static final String [] MENUA = { MLOAD,MLINK,MPLUGIN,MHELP,MDCH1 }; // Menus Applet Christian static final String [] MENUA1 = { MLOAD,MPLUGIN,MHELP,MDCH1 }; static final String [] MENUD = { "Access to the images, catalogs, FoV", "Save images and data on the local disk", "Available plugins", "Print the current view", "Produce an HTML page with original image links", "Help information", "Create windows outside the web browser", "Authors, contributors and copyrights", "Quit Aladin" }; static final String MENUHEXT = " \n- LOCAL : access to your own data. Images has to be FITS with the "+ "WCS field. Tables has to be in ASCII, either in Tab-Separated-Value "+ "with the two first column with RA and DEC in J2000 decimal degrees, or "+ "in XML Astrores. See the FAQ to have more detail"; static final String [] MENUH = { "!Button ``"+MLOAD+"''\n"+ "By clicking on this button, you open a new window allowing you "+ "to choose a specific server, either for images or for data.\n"+ " \n"+ "- ALADIN image server: these images come from several "+ "surveys (POSI, POSII, SERC, ESO) and have been digitized either "+ "by the Space Telescope Science Institute (STScI) and/or by the "+ "Centre d'Analyse des Images (CAI/MAMA).\n"+ " \n"+ "- VIZIER : gives you access to more than 2000 astronomical catalogs "+ "and tables, logs of missions with images and spectra.\n"+ " \n"+ "- SIMBAD : the well--known astronomical database.\n"+ " \n"+ "- NED : the well--known extragalactic database.\n"+ " \n"+ "- FOV : Fields of View of several instruments\n", "!Button ``"+MSAVE+"''\n"+ "By clicking this button you can store data and images on your local "+ "disk.\nYou have three possibilities:\n"+ " \n"+ "- Backup the stack: generate a unique file containing all current "+ "data, graphics and images. The format is Aladin proprietary "+ "(AJ format). This feature is typically used to work without "+ "network, or to continue a previous work.\n"+ " \n"+ "- Export some planes: to allow you to choose individually the planes "+ "of the stack that you want to export in order to reuse them in "+ "other applications. The tables and catalogs are exported in ASCII "+ "Tab-Separated-Value format with a short header. The images are exported "+ "in 8bits FITS with the WCS header fields.\n"+ " \n"+ "- Export the current view: to allow you to export the current view "+ "with the overlays to an image file in BMP 24bits format.\n"+ " \n"+ "- Get image links: to allow you to retrieve the original images "+ "directly from the image servers.\n"+ " \n"+ "You can reload from the files with the Button ``"+MLOAD+"'' - sub-menu "+ "``Local'', or directly at the startup in the command line.\n", "!Button ``"+MPLUGIN+"''\n"+ "Give access to the plug-ins compatible with Aladin"+ "such as SED (ESO), ACE (AstroGrid), VOPlot (VO-India)", "!Button ``"+MLINK+"''\n"+ "Produce a HTML page with the list of image urls in order to "+ "allow you to retrieve the original images directly from "+ "the image servers.", "!Button ``"+MPRINT+"''\n"+ "Allows you to print the current view.\n"+ "The printer has to be PostsScript compatible", "", "!Button ``"+MDCH1+"''\n"+ "Allows you to run Aladin outside the Web browser "+ "window. In this way the size of the Aladin window can be adjusted "+ "to the size of the screen.\n \n"+ "WARNING: for Netscape 3.0 (and previous versions), iconifying "+ "the Web Browser will stop Aladin.", "!Button ``"+MQUIT+"''\n"+ "Allows you to quit Aladin", }; /** Retourne le tableau de strings d'un sous menu, null sinon */ private String[] getPopupMenu(String m) { if( m==MPLUGIN ) return SMPLUGIN; if( m==MHELP ) return SMHELP; return null; } /** Demarrage d'Aladin JAVA. * Dans le cas d'un demarrage par applet et que le parametre * frame=load est positionne, init se contente * de re-appeler Aladin JAVA avec le parametre frame=launching * ce qui permet de changer la page HTML qui contient le message pour * patienter (avec re-transmission des autres parametres) * * @@see aladin.Aladin#suiteInit() */ public void init() { // Pour gerer le chargement en deux fois if( !STANDALONE ) { String [] var = { "-c","-rm","-server","-source","img", "-fov","-aladin.resolution","-aladin.zoom","script" }; // Mode trace (pour aider au debogage) String trace = getParameter("-trace"); if( trace!=null ) levelTrace=3; // Provenance de l'applet (si different de aladin.u-strasbg.fr) String tmp = getCodeBase().toString(); int a = tmp.indexOf("//"); if( a>0 ) { tmp= tmp.substring( a+2 ); a = tmp.indexOf('/'); if( a>0 ) { tmp= tmp.substring( 0,a ); HOSTSERVER=tmp; if( !tmp.equals("aladin.u-strasbg.fr") && !tmp.equals("aladin") ) APPLETSERVER=tmp; } } // Recuperation du CGIPATH s'il est different du getCodeBase(); CGIPATH=getCodeBase()+""; try { String cgi = getParameter("cgi"); if( cgi!=null ) CGIPATH="http://"+HOSTSERVER+cgi; } catch( Exception e3 ) {}; String load=null; try { load = getParameter("-load"); } catch( Exception e4 ) {}; if( load!=null ) { if( !flagLoad ) { URL utest=null; String param=""; String s; trace(1,"init loading"); // Recopie des parametres a transmettre for( int i=0; i=MENUS.length ) continue; } else { if( FLAGLINKS ) { for( j=0;j=MENUA.length ) continue; } else { for( j=0;j=MENUA1.length ) continue; } } boolean enable = !(MENU[i].equals(MSAVE) || MENU[i].equals(MLINK) || MENU[i].equals(MPRINT) ); vb = new MyButton(this,MENU[i],MENUD[i],MENUH[i],enable); if( !MENU[i].equals(MHELP) && islownessThreshold; if( isSlow ) trace(1,"Slow JVM detected"); // Evaluation de la vitesse de la machine JAVA Date d = new Date(); String sGlu = "\nThe HTTP requests will be resolved "; sGlu += !STANDALONE?"remotely by the applet server GLU system.": Glu.GLUFILTER!=null?"by "+Glu.GLUFILTER+".": "by the inside JAVA GLU resolver."; // Log String osName = System.getProperty("os.name"); String osArch = System.getProperty("os.arch"); String osVersion = System.getProperty("os.version"); String javaVersion = System.getProperty("java.version"); String javaVendor = System.getProperty("java.vendor"); glu.log("Start",(STANDALONE?"standalone ":"applet ")+VERSION+ " perf="+speed+ " java="+javaVersion+"/"+javaVendor+ " syst="+osName+"/"+osArch+"/"+osVersion); if( !flagLaunch ) { System.out.println("Your JVM release is java "+javaVersion+" by "+javaVendor); System.out.println("Your java machine performance is "+speed+ " (lower is better)"+sGlu); } // positionne le flag Java 1.0 (et 1.1.2) JAVABEFORE118 = numJVMVersion(javaVersion)<118; // Lecture des commandes scripts sur l'entree standard if( STANDALONE && CONSOLE ) command.readStandardInput(); } /** Memorisation de la derniere version disponible (transmis par Glu.log) */ synchronized protected void setCurrentVersion(String s ) { currentVersion = s; // On en profite pour tester le numero de version ainsi // que l'affichage d'un reseau non trouve //PAS POUR L'AVO // if( STANDALONE ) testVersion(); // On en profite pour afficher le message No network if( !NETWORK ) warning("!Warning\n \nNo network !\nOnly local data will be available !"); } /** Indication de l'etat de l'impression */ synchronized void setFlagPrint(boolean print) { this.print = print; } /** Transformation de la chaine du numero de version vx.xxx en valeur * numerique * @@param s la chaine v1.120 par exemple * @@return 112 par exemple (on ne prend pas en compte le dernier digit) * ou 0 si s==null ou d'un mauvais format; */ protected int numVersion(String s) { if( s==null || s.length()<6 ) return 0; char [] a = s.toCharArray(); if( a[0]!='v' || a[2]!='.' ) return 0; int i= (a[1]-'0')*100 + (a[3]-'0')*10 + (a[4]-'0'); return i; } /** Transformation de la chaine du numero de version n.n.n en valeur * numerique * @@param s la chaine 1.3.1 par exemple * @@return 131 par exemple ou 0 si s==null ou d'un mauvais format; */ protected int numJVMVersion(String s) { if( s==null || s.length()<5 ) return 0; char [] a = s.toCharArray(); int i= (a[0]-'0')*100 + (a[2]-'0')*10 + (a[4]-'0'); return i; } /** calcule la vitesse de la machine virtuelle * @@return un indicateur de performance (lower is better) * */ protected static long getSpeed() { long start = System.currentTimeMillis(); Vector vec = new Vector(); for(int i=0;i<30000;i++) { vec.addElement(new Vector(30)); Vector pipo = (Vector)vec.elementAt(i); } long end = System.currentTimeMillis(); vec=null; return (end-start); } /** Transformation de la chaine du numero de version vx.abc en sa valeur * generale x.a */ static protected String getReleaseNumber() { return VERSION.substring(0,VERSION.indexOf('.')+2); } /** Test du numero de version */ protected void testVersion() { int cv = numVersion(currentVersion); if( cv==0 ) return; int v = numVersion(VERSION); if( v>=cv ) return; String s = "A new major release\n"+ "is available at CDS\n \n!Aladin Java "+currentVersion+"\n \n"+ "Do you want to install it now ?"; if( !confirmation(s) ) return; aladin.glu.showDocument("AladinJava.SA",""); } /** Test du reseau et positionnement du flag en fonction */ private void testReseau() { if( !NETWORK || !STANDALONE ) return; trace(1,"Network test"); NETWORK=false; try { InetAddress.getAllByName("aladin.u-strasbg.fr"); NETWORK=true; } catch(Exception e) { System.err.println("WARNING: No network found !!"); } } /** Fin du message d'accueil */ protected void endMsg() { cardView.show(bigView,"View"); msgOn=false; setHelp(false); } /** Efface le contenu du Status. En fait, si l'evenement * arrive jusqu'ici c'est qu'il n'a pas ete traite par les autres * objets, donc on peut effacer */ public boolean mouseMove(Event e, int x, int y) { if( inHelp ) help.setDefault(); else status.setText(""); return true; } /** Remise en place de l'Applet dans la fenetre du navigateur */ protected void unDetach() { f.remove(this); f.dispose(); makeAdd(myParent,this,"Center"); resize(dimOrigSize); myParent.show(); bext.setLabel(MDCH1); bext.pop(); } // Juste pour eviter que la classe Save.class ne soit chargee // dans la version applet private void save() { try { Class x = Class.forName("cds.aladin.Save"); Class a = this.getClass(); Boolean b = new Boolean(true); Constructor c = x.getDeclaredConstructor(new Class [] { a, boolean.class }); Object save = c.newInstance(new Object[] { this,b }); } catch( Exception e ) { System.out.println(e); } // save = (Object)( new Save(this,true) ); } // Affichage des authors et contributors private void info() { Aladin.info(AUTEURS); } // Juste pour eviter que la classe Printer.class ne soit chargee // dans la version applet // RETIRER POUR DES PROBLEMES AVEC JSHRINK /* private void printer() { try { Class x = Class.forName("cds.aladin.Printer"); Class a = this.getClass(); Constructor c = x.getDeclaredConstructor(new Class [] { a }); c.newInstance(new Object[] { this }); } catch( Exception e ) { System.out.println(e); } } */ private void printer() { new Printer(this); } /** Reactions aux differents boutons du menu */ public boolean action(Event e, Object o) { String s; try { s = (String) o; } catch( Exception eact ) { return true; } /* // Message pour indiquer que le reseau n'a pas ete trouve if( !flagReseau && !aladin.NETWORK && !s.equals(MQUIT) ) { flagReseau=true; Aladin.warning("I cannot find the network !\nLocal features availabled only !"); return true; } */ // Interface d'interrogation des serveurs if( s.equals(MLOAD) ) { if( dialog==null ) { Aladin.warning("Form not yet ready\nPlease try again in few seconds"); return true; } dialog.toFront(); dialog.show(); // Insertion de l'Applet dans sa propre fenetre } else if( s.equals(MDCH1) ) { makeAdd(f,this,"Center"); f.pack(); f.show(); bext.setLabel(MDCH2); bext.pop(); // Passage en mode (ou hors mode) Help } else if( s.equals(HELP) || s.equals(MHELP) ) { inHelp = !inHelp; setHelp(inHelp); cardView.show(bigView,inHelp?"Help":"View"); } else if( s.equals(MSAVE) ) { save(); } else if( s.equals(MDCH2) ) { unDetach(); } else if( s.equals(FAQ) ) { glu.showDocument("Aladin.java.getFAQ",""); } else if( s.equals(MAN) ) { glu.showDocument("Aladin.java.getManual.pdf",""); } else if( s.equals(MPRINT) ){ printer(); } else if( s.equals(ABOUT) ) { info(); } else if( s.equals(MLINK) ) { saveHTML(); } else if( s.equals(SED) ) { startSED(); } else if( s.equals(VOPLOT) ){ startVOPlot(); } else if( s.equals(ACE) ) { startACE(); // Fin du programme } else if( s.equals(MQUIT) ) { // Mise en garde si on est entrain d'imprimer if( print ) { Aladin.warning("You are printing\nwait a few seconds !"); return true; } if(flagLaunch) { // Si Aladin demarre par launch() cacher la fenetre // System.out.println("Aladin.action: flagLaunch true => dispose"); f.dispose(); } else { // Sinon terminer l'application System.exit(0); } } return true; } /** Lancement de VOPlot avec les objets selectionnes */ private void startVOPlot() { if( !calque.view.hasSelectedObjet() ) { Aladin.warning(" No selected objects in the view "); return; } trace(1,"Starting VOPlot..."); try { String s = writeSelectedObjectInVOTable(); extApp = com.jvt.applets.PlotVOApplet.launch(); if( levelTrace==3 ) System.out.println(s); ByteArrayInputStream in = new ByteArrayInputStream( s.getBytes() ); extApp.loadVOTable(this,in); } catch( Exception es ) { System.err.println("Error: "+es); if( levelTrace==3 ) es.printStackTrace(); } } /** Lancement de ACE sur l'image courante */ private void startACE() { trace(1,"Starting ACE..."); try { PlanImage p = (PlanImage)calque.getPlanBase(); if( p==null ) { Aladin.warning(" No image "); } String u = p.u.toString(); if( p.orig==PlanImage.ALADIN && p.fmt==PlanImage.JPEG ) { u=AladinServer.change2FITS(u); } trace(2,"Url for AladinAceClient: "+u); new org.astrogrid.ace.aladin.AceProducer(new URL(u), this); } catch( Exception es ) { System.err.println("Error: "+es); if( levelTrace==3 ) es.printStackTrace(); } } ExtApp sed = null; /** Lancement de SED sur les objets selectionnes */ private void startSED() { if( !calque.view.hasSelectedObjet() ) { Aladin.warning(" No selected objects in the view "); return; } trace(1,"Starting SED..."); // thomas Source[] selectedSources; // we retrieve selected sources Vector vec = new Vector(); Enumeration e = aladin.view.vselobj.elements(); Objet o=null; Source s=null; while( e.hasMoreElements() ) { // o is a Source AND o.isSelected o = (Objet)e.nextElement(); if( o instanceof Source ) { s = (Source)o; } else continue; if( s.noFilterInfluence() || s.isSelected() ) { vec.addElement(o); } } // copy sources into selectedSources selectedSources = new Source[vec.size()]; vec.copyInto(selectedSources); // creating VOTable for selected sources VOTableEISGenerator v = new VOTableEISGenerator(selectedSources); long begin, end; begin = System.currentTimeMillis(); InputStream result = v.getOutput(); end = System.currentTimeMillis(); trace(3,"\nTotal VOTablegeneration time : "+(end-begin)+"\n"); // nouvelle interface : if( sed==null ) sed = new Sed(result,(ExtApp)this); else { // nouvelle interface : sed.loadVOTable((ExtApp)this,result); sed.setVisible(true); } } public void setLocation(int x, int y) { System.out.println("Aladin setLocation(x="+x+" y="+y+")"); super.setLocation(x,y); } public void setLocation(Point p) { System.out.println("Aladin setLocation(p="+p.x+","+p.y+")"); super.setLocation(p); } public Insets insets() { return new Insets(3,8,1,7); } /* // public Insets getInsets() { return new Insets(5,5,1,5); } // Un peu d'espace autour du panel public Insets getInsets() { return insets(); } // Un peu d'espace autour du panel public Insets insets() { Insets i; if( !flagInsets ) { i = super.insets(); i.top+=3; i.left+=6; i.bottom+=1; i.right+=5; flagInsets = true; } else i = new Insets(3,6,1,5); return i; } */ /** Passage en mode Help ou retour a la normale * @@param vrai : true -> passage en mode help * false -> retour a la normal */ protected void setHelp(boolean vrai) { if( vrai ) { localisation.setPanelPos(); help.setDefault(); makeCursor(this,HAND); } else makeCursor(this,DEFAULT); // Desactivation des composantes innaccessibles if( !msgOn ) { Enumeration e = vButton.elements(); while( e.hasMoreElements() ) { MyButton c = (MyButton) e.nextElement(); c.enable(!vrai); // je desactive si je suis en help } } if( calque.isFree() ) setButtonMode(false); msgOn=false; } static final int DEFAULT = 0; static final int WAIT = 1; static final int HAND = 2; static final int CROSSHAIR = 3; static final int MOVE = 4; static final int RESIZE = 5; static final int TEXT = 6; /** Retourne le Frame parent */ protected Frame getFrame(Component c) { while( c!=null && !(c instanceof Frame) ) c=(Component)c.getParent(); return (Frame)c; } /** Positionnement du curseur en fonction du type de machine * java afin d'eviter une erreur de verif de la securite */ protected static void makeCursor(Component c,int type) { if( inHelp ) type=HAND; // if( JAVA10 ) { while( c!=null && !(c instanceof Frame) ) c=(Component)c.getParent(); if( c==null ) return; ((Frame)c).setCursor(type==WAIT?Frame.WAIT_CURSOR: type==HAND?Frame.HAND_CURSOR: type==CROSSHAIR?Frame.CROSSHAIR_CURSOR: type==MOVE?Frame.MOVE_CURSOR: type==RESIZE?Frame.N_RESIZE_CURSOR: type==TEXT?Frame.TEXT_CURSOR: Cursor.DEFAULT_CURSOR ); /* } else { c.setCursor( Cursor.getPredefinedCursor( type==WAIT?Cursor.WAIT_CURSOR: type==HAND?Cursor.HAND_CURSOR: type==CROSSHAIR?Cursor.CROSSHAIR_CURSOR: type==MOVE?Cursor.MOVE_CURSOR: type==RESIZE?Cursor.N_RESIZE_CURSOR: type==TEXT?Cursor.TEXT_CURSOR: Cursor.DEFAULT_CURSOR )); } */ } /** Ajout dans un Layout en fonction du type de machien Java */ protected static void makeAdd(Container ct,Component c,String s) { try { ct.add(c,s); } catch( Error e ) { ct.add(s,c); } } /** Activation/Desactivation des boutons associes a la presence * d'au moins un plan (MSAVE et MPRINT) * @@param mode true: activation, false: desactivation */ protected void setButtonMode(boolean mode) { if( !STANDALONE ) return; Enumeration e = vButton.elements(); while( e.hasMoreElements() ) { MyButton c = (MyButton) e.nextElement(); if( c.text.equals(MSAVE) || c.text.equals(MPRINT) ) c.enable(mode); } } /** Determination du repertoire d'installation d'Aladin. * La methode consiste a balayer les valeurs de la variable * java.class.path en recherchant dans chacun de ces repertoires * la presence du fichier ALAGLU * * Met a jour la variable static HOME */ protected static void setAladinHome() { String PS = System.getProperty("path.separator"); String FS = System.getProperty("file.separator"); HOME="."+FS; // Par defaut, le repertoire courant String path = System.getProperty("java.class.path"); if( path==null ) return; StringTokenizer st = new StringTokenizer(path,PS); // Parcours de la liste des elements de classpath while( st.hasMoreTokens() ) { String s = st.nextToken(); // Cas particulier du .jar if( s.endsWith(FS+"Aladin.jar") ) s=s.substring(0,s.lastIndexOf(FS)); else if( s.endsWith("Aladin.jar") ) s="."; String sep = s.endsWith(FS)?"":FS; File f = new File(s+sep+ALAGLU); if( !f.canRead() ) continue; // C'est bon on a trouve HOME=s+sep; return; } } /** Lancement d'Aladin par une autre application java. * Il s'agit d'appeler la methode main() et de retourner * l'instance de l'objet Aladin */ public static Aladin launch() { return launch("-noconsole"); } public static Aladin launch(String s) { return launch("-noconsole",null); } public static Aladin launch(Applet applet) { return launch(null,applet); } public static Aladin launch(String s,Applet applet) { String args[]; extApplet = applet; if( s!=null ) { StringTokenizer st = new StringTokenizer(s); int n; args = new String[n=st.countTokens()]; for( int i=0; i no graphic interface !"); } // Chargement d'un fichier XML, FITS ou AJ while( lastArg */ public void loadVOTable(ExtApp extApp, InputStream in) { this.extApp = extApp; try {calque.newPlanCatalog(new MyInputStream(in)); } catch( Exception e ) { System.out.println("Ext App error!"); e.printStackTrace(); } } /** * Callback method allowing external application to ask Aladin * to SHOW a list of objects * @@param oid list of oid */ public void showVOTableObject(String oid[]) { Source o[] = calque.getSources(oid); if( o.length==0 ) { ooid=null; calque.view.hideSource(); } else { ooid=o[0].getOID(); trace(3,"showVOTableObject("+o[0].id+","+ooid+")"); calque.view.showSource(o[0]); } } /** * Callback method allowing external application to ask Aladin * to SELECT a list of objects * @@param oid list of oid */ public void selectVOTableObject(String oid[]) { olistOid = oid; // Evite des appels en aller/retour if( levelTrace==3 ) { StringBuffer s=null; for( int i=0; i1 ) return s; if( s.equals("J") ) return "int"; if( s.equals("K") ) return "long"; if( s.equals("A") ) return "char"; if( s.equals("E") ) return "float"; if( s.equals("D") ) return "double"; if( s.equals("L") ) return "boolean"; if( s.equals("I") ) return "short"; if( s.equals("X") ) return "bit"; if( s.equals("B") ) return "unsignedByte"; if( s.equals("C") ) return "floatComplex"; if( s.equals("M") ) return "doubleComplex"; return "float"; } /** * Generation du VOTable pour la legende d'un objet (les champs FIELD) * @@param s le buffer de sortie * @@param o l'objet en question */ private void writeVOTableStartTable(StringBuffer s,Source o) { int indent=4; Legende leg = o.leg; // On recupere le nom de la table sur le premier element "info" de l'objet (le triangle) StringTokenizer st = new StringTokenizer(o.info,"\t"); String tableName=getValue(st.nextToken()); // Le nom de la table est "sur le triangle" writeIndent(s,indent); s.append("\n"); indent+=3; // Le champ pour le OID writeIndent(s,indent); s.append("\n"); for( int i=0; i\n"); } writeIndent(s,indent); s.append("\n"); } /** * Generation du VOTable pour un objet * @@param s le buffer de sortie * @@param o L'objet a traiter */ private void writeVOTableData(StringBuffer s,Source o) { StringTokenizer st = new StringTokenizer(o.info,"\t"); st.nextElement(); // On saute le triangle writeIndent(s,7);s.append(""); // Sauvegarde de l'OID, (si necessaire, generation d'un oid) String oid = o.getOID(); if( oid==null ) oid = o.setOID(); s.append(""); for( int i=0; st.hasMoreTokens(); i++ ) { Words w = new Words(st.nextToken()); if( i==5 ) { i=0; s.append("\n"); writeIndent(s,11); } s.append(""); } s.append("\n"); } /** * Generation du VOTable des objets du plan p. * Dans le cas ou il n'y a aucun objet (selectionne) dans le plan, la ressource * est totalement omise. * @@param s1 le buffer de sortie * @@param p le plan a traiter * @@param onlySelected true si on ne considere que les objets selectionnes par l'utilisateur */ private void writePlanInVOTable(StringBuffer s1, Plan p,boolean onlySelected) { Legende leg=null; StringBuffer s = new StringBuffer(10000); // debut de la ressource (le plan) s.append( " \n"+ " "+XMLParser.XMLEncode(p.label)+" object selection from Aladin\n" ); // Parcours des objets PlanObjet pcat = p.pcat; for( int i=0; i
"+oid+""+getValue(w.getText())+"
\n"); // fin de la table precedente writeVOTableStartTable(s,o); // Nouvelle table leg=o.leg; } // Ecriture des donnees pour l'objet courant writeVOTableData(s,o); } if( leg==null ) return; // Il n'y avait aucun objet dans cette ressource // Fin de la derniere table et fin de la ressource s.append(" \n"); s.append(" \n"); s1.append(s.toString()); } /** * Generation de VOTable de tous les objets en cours de selection * dans Aladin */ protected String writeSelectedObjectInVOTable() { StringBuffer s = new StringBuffer(10000); s.append( "\n"+ "\n"+ "\n"+ " Object selection from Aladin\n"+ " \n"+ " \n"+ " \n" ); // Parcours de tous les plans CATALOG for( int i=calque.plan.length-1; i>=0; i-- ) { Plan p = calque.plan[i]; if( p.type!=Plan.CATALOG || !p.flagOk || !p.active ) continue; writePlanInVOTable(s,p,true); } s.append("\n"); return s.toString(); } // CETTE FONCTION DEVRAIT ETRE PLACEE DANS L'OBJET "Words" ET IL FAUDRAIT // L'UTILISER DANS "Source.getValue()" static String getValue(String s) { if( s.startsWith("<&") ) { int a = s.indexOf('|'); if( a>0 ) { int b = s.indexOf('>',a+1); if( b>=0 ) return s.substring(a+1,b); } } return s; } /** * Cache d'imagettes (logo, images utilisées dans les helps...) * @@param name Nom de l'image a retrouvée. Elle peut se trouver * dans le fichier jar, dans le home directory ou * sur le serveur de l'applet * @@return L'image, ou null si erreur */ private static Hashtable imageCache=null; protected Image getImagette(String name) { if( imageCache==null ) imageCache = new Hashtable(10); // L'image a-t-elle ete deja chargee Object i = (Image)imageCache.get(name); if( i!=null ) { if( i instanceof Image) return (Image)i; else return null; } // Pas encore dans le cache, on la charge try { MyInputStream is = new MyInputStream(getClass().getResourceAsStream("/"+name)); byte buf[] = is.readFully(); if( buf.length==0 ) throw new Exception(name+" unreachable"); Image img = Toolkit.getDefaultToolkit().createImage(buf); PlanImage.waitImage(this,img); imageCache.put(name,img); is.close(); return img; } catch( Exception e ) { e.printStackTrace(); } // Cas d'erreur, on memorise dans le cache une chaine vide // histoire de ne pas essayer a chaque fois imageCache.put(name,""); return null; } /** Appel a la generation par le serveur de l'applet ou "aladin.u-strasbg.fr" * d'une page HTML permettant l'acces aux images originales de la pile * Utilise le format HTTP suivant : * frame=save&An=label&Dn=origine&Rn=format(FITS|HFITS|GFITS|MRCOMP)&Un=url * ou n est un numero distinct pour chaque plan * * Dans le cas ou le plan vient du serveur d'images Aladin en JPEG, * l'url du plan est modifiee pour que ce soit du FITS. * * RQ: IL PEUT Y AVOIR UN RISQUE DE DEBORDEMENT DE LA METHODE GET HTTP * MAIS JE NE VOIS PAS COMMENT FAIRE CELA EN METHODE POST...QUI VIVRA VERRA */ protected void saveHTML() { StringBuffer pf=null; int j=0; for( int i=calque.plan.length-1; i>=0; i-- ) { Plan p = calque.plan[i]; if( p.type!=Plan.IMAGE || !p.flagOk || p.error!=null ) continue; if( p.u==null ) continue; if( pf==null ) pf=new StringBuffer(); else pf.append("&"); String u = p.u.toString(); String format = PlanImage.getFormat(((PlanImage)p).fmt); // Cas particulier d'aladin en JPEG if( ((PlanImage)p).orig==PlanImage.ALADIN && ((PlanImage)p).fmt==PlanImage.JPEG ) { u=AladinServer.change2FITS(u); format="FITS"; } pf.append("A"+j+"="+URLEncoder.encode(p.label)+ "&D"+j+"="+URLEncoder.encode(p.from)+ "&U"+j+"="+URLEncoder.encode(u)+ "&R"+j+"="+URLEncoder.encode(format) ); j++; } if( pf==null ) { Aladin.warning("There is no image\nin the stack"); return; } String s=Aladin.STANDALONE?"http://aladin.u-strasbg.fr/java":CGIPATH; String u = s+"/nph-aladin.pl?frame=save&"+pf; trace(2,u); glu.showDocument("Http",u,true); } /* void debug() { int i; // Affichage des infos des sources selectionnes System.out.println("DEBUG: INFORMATION SUR LES SOURCES SELECTIONNEES:\n"); for( i=0; i= au niveau courant * le message sera affiche sur la sortie standard * @@param n Le niveau de debogage * @@param s Le message a afficher */ static final void trace(int n,String s) { if( levelTrace>=n ) { switch(n) { // Affichage du deroulement au niveau de la creation des objets case 1:System.out.println("."+s+"..."); break; // Affichage au niveau des actions principales case 2:System.out.println("- "+s); break; // Affichage en detail case 3:System.out.println("*** "+s); break; } } } } Parser.XMLEncode(tableName)+"\">\n"); indent+=3; // Le champ pour le OID writeIndent(s,indent); s.append("\n"); for( int i=0; i0 ) s = s+" "+Glu.quote(qual); if( (u=aladin.glu.getURL(Glu.debugTag("Image"),s))==null ) { Aladin.warning(this,WERROR,1); return -1; } // Verification de non-redondance if( !verif(Plan.IMAGE,target,qual, PlanImage.getFmt(format)+"/"+PlanImage.getRes(resol) ) ) return -1; // Generation automatique du label du plan if( label==null) label=getPlanLabel(resol,qual); // Positionnement de l'origine si non mentionne if( origin==null ) { if( qual.indexOf("MAMA")>=0 ) origin="MAMA scan by CAI/Paris - data online provided by CDS"; else if(qual.indexOf("DSS2")>=0 ) origin="DSS2 by STScI - data online provided by CDS"; else if(qual.indexOf("2MASS")>=0 ) origin="2MASS by UMass/IRSA - data online provided by CDS"; else origin="DSS1 by STScI - data online provided by CDS"; } return aladin.calque.newPlanImage(u,PlanImage.ALADIN,label, target,qual,origin, PlanImage.getFmt(format), PlanImage.getRes(resol), false,null); } /** uniquement pour des tests */ private String getTarget(String s) { Coord c; try { if( !View.notCoord(s) ) c = new Coord(s); else c = aladin.view.getSimbad(s); } catch(Exception e) {return null;} return c==null?null:c.getSexa(":"); } /** * Mise a jour de l'arbre de Thomas par Thread independant * pour ne pas bloquer l'affichage */ private void submitThread() { waitCursor(); try { String obj = getTarget(); String r = getRadius(); if( r!="" ) r = getRadius(r)/60.+""; String objc = getTarget(obj); if( objc==null ) throw new Exception("Fox sesame error for \""+obj+"\" !"); URL url = aladin.glu.getURL("Aladin.IDHASIA", Glu.quote(TreeView.getDeciCoord(objc))+" "+ Glu.quote(r)); MyInputStream is = new MyInputStream(url.openStream()); if( (is.getType() & (MyInputStream.IDHA|MyInputStream.SIA))==0 ) { String err = is.gets().trim(); Aladin.warning(this,"!Aladin server error (IDHASIA mode)!\n"+ "\""+err+"\""); defaultCursor(); return; } aladin.treeView.updateTree(is,tree,this,obj); } catch( Exception e ) { if( Aladin.levelTrace==3 ) e.printStackTrace(); Aladin.warning(this,"Aladin server error (IDHASIA mode) !",1); } defaultCursor(); } /** Interrogation d'Aladin */ public void submit() { // Recuperation et memorisation du target String obj = getTarget(); memoTarget(obj); // Test sur les objets du systeme solaire if( PlanImage.isSolar(obj) ) { creatAladinPlane(obj,null,null,null, obj,"CDS joke"); return; } // Traitement des images par lot if( tree!=null && !tree.isEmpty() ) { if( tree.nbSelected()>0 ) { // verif() IL FAUDRAIT AJOUTER LA VERIFICATION DU PLAN. tree.loadSelected(); tree.resetCb(); } else Aladin.warning(this,"You have to check atleast one resource"); return; } // Chargement des descriptions des images disponibles (threade) thread= new Thread(this); flagIDHASIAcall=true; thread.setPriority( Thread.NORM_PRIORITY -1); thread.start(); } /** Construit le label du plan en fonction du qualifier et de la resolution * Exemple: PLATE SERC J STScI => Pl-SERC.J.DSS1 */ static protected String getPlanLabel(String resol, String qual) { return getPlanLabel( PlanImage.getRes(resol),qual); } static protected String getPlanLabel(int resol, String qual) { StringBuffer s = new StringBuffer(); String [] f = new String[3]; // On decoupe les trois champs SURVEY COLOR SCAN StringTokenizer st = new StringTokenizer(qual); for( int i=0; i<3; i++ ) f[i] = st.nextToken(); if( f[0].indexOf("2MASS")>=0 ) { f[2]=f[0]; f[0]=null; } // Et on les assemble dans le sesn inverse eventuellement // precedes par l'indication Pl- pour Plate if( resol==PlanImage.PLATE ) s.append("Pl-"); else if( resol==PlanImage.LOW ) s.append("Lw-"); if( f[2].equals("STScI") || f[2].equals("STSCI") ) s.append("DSS1."); else if( !f[2].startsWith("___") ) s.append(f[2]+"."); s.append(f[1]); if( f[0]!=null ) s.append("."+f[0]); return s.toString(); } static String otarget=null; boolean flagClear=true; // Une horreur pour eviter un clear() // intempestif lors d'un reset /** Memorisation du target de la derniere interrogation aladin */ protected void memoTarget(String s) { otarget=s; } /** Pre-remplissage du champ target * Si il ne s'agit pas de la meme chaine que la derneire interro d'aladin, * le formulaire est resete (pour effacer les images disponibles qui ne * correspondront plus) * @@param s La chaine a mettre dans le champ target */ protected void setTarget(String s) { if( flagClear && otarget!=null && !otarget.equals(s) ) { clear(); } flagClear=true; super.setTarget(s); } /** Remplace les blancs par des soulignes */ protected static String blankToUnderline(String s) { char [] a = s.toCharArray(); for( int i=0; i=0; i-- ) missionlist.deselect(i); creatPlane(objet,sz,cata,null,null); defaultCursor(); } /** Reset du formulaire */ protected void clear() { super.clear(); rad[0].setText("10 arcmin"); mission.setText(""); // A MODIFIER VizieR.resetList(missionlist); } /** Re-affichage avec regeneration du panel du formulaire. * Rq : Eh oui, il faut bien ruser pour supporter Netscape 3.0 */ protected void reaffiche() { // try{ invalidate(); validate(); } catch( Exception e ) {} hide();show(); } /** Gestion des evenements. */ public boolean action(Event evt, Object what) { // Affichage via Netscape du Readme du missionue courant if( CATDESC.equals(what) ) { String cata = mission.getText().trim(); if( cata.equals("") ) { Aladin.warning(this,WNEEDCAT); return true; } cata = Glu.quote(cata); aladin.glu.showDocument("getReadMe",cata); return true; } return false; } } cds/aladin/BasicNode.java010064400076440000132000000153740770227416100162540ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // /**

Title : BasicNode

*

Description : Basic node for a tree

*

Copyright: 2002

*

Company: CDS

* @@author Thomas Boch * @@version 0.5 : 27 Novembre 2002 (Creation) */ package cds.aladin; import java.util.Vector; import java.util.Enumeration; abstract public class BasicNode { Vector children; // fils du noeud String name; BasicNode father = null; int level; // Coordonnees du nom dans le canvas BasicTree int x,y; boolean isOpen=false; boolean isLeaf=false; int nbChildren=0; // true if this node must be hidden boolean hide = false; // true if the node is selected boolean isSelected=false; // true if the node lits up boolean litup=false; // true if the node is framed boolean framed = false; // Constructeur par recopie BasicNode(BasicNode n) { super(); this.name = n.name; //this.isOpen = n.isOpen; this.isLeaf = n.isLeaf; this.hide = n.hide; this.children = new Vector(); } BasicNode() { this(""); } BasicNode(String name) { this.name=name; children = new Vector(); } BasicNode(String name, boolean isOpen, boolean isLeaf) { this(name); this.isOpen = isOpen; this.isLeaf = isLeaf; } abstract public BasicNode createNode(String name); public BasicNode addChild(String childName) { BasicNode newNode = createNode(childName); newNode.father = this; children.addElement(newNode); nbChildren++; return newNode; } public BasicNode addChild(String childName, boolean isOpen, boolean isLeaf) { BasicNode newNode = createNode(childName); newNode.isOpen = isOpen; newNode.isLeaf = isLeaf; newNode.father = this; children.addElement(newNode); nbChildren++; return newNode; } public BasicNode addChild(BasicNode child) { child.father = this; children.addElement(child); nbChildren++; return child; } public Enumeration getChildren() { return children.elements(); } public BasicNode getChildrenAt(int index) { return (BasicNode)children.elementAt(index); } public BasicNode getParent() { return this.father; } /** Supprime le fils child de la liste des enfants @@param child reference du noeud a supprimer @@return true si le noeud a été effectivement supprimé, false sinon */ public boolean removeChild(BasicNode child) { int index = children.indexOf(child); if( index>=0 ) { children.removeElementAt(index); nbChildren--; return true; } else return false; } /** Supprime tous les sous-noeuds */ public void removeAllChild() { children.removeAllElements(); nbChildren = 0; } public void changeState() { isOpen=!isOpen; } // retourne true si this est le dernier fils de son père public boolean isLastChild() { if( father==null ) return false; BasicNode last = father.lastChild(); return (last!=null&&last.equals(this)); } public BasicNode lastChild() { if(nbChildren>0) { return (BasicNode)children.elementAt(children.size()-1); } return null; } /** returns the corresponding node if this node has a (direct) child called s, null otherwise */ public BasicNode getChild(String s) { Enumeration e = children.elements(); BasicNode current; while( e.hasMoreElements() ) { current = (BasicNode)e.nextElement(); if( current.name.equals(s) ) return current; } return null; } /** Opens all children */ public void openChildren() { Enumeration e = children.elements(); BasicNode current; while( e.hasMoreElements() ) { current = (BasicNode)e.nextElement(); current.isOpen = true; } } public boolean isSelected() { if(!isLeaf) return false; return isSelected; } } cds/aladin/BasicTree.java010064400076440000132000000655350770227416100162720ustar00ferniquecds00000400000013package cds.aladin; import java.util.Enumeration; import java.util.Vector; import java.awt.*; /** Un arbre hiérarchique * @@author Thomas Boch [CDS] * @@version 0.5 ?? */ public class BasicTree extends Canvas { // references to ScrollPane for the tree protected ScrollPane scroll = null; // popupmenu pour actions associées à un noeud/feuille de l'arbre protected PopupMenu popup; //popupmenu pour actions générales sur l'arbre (expand/collapse all) protected PopupMenu popupPrefs; protected static final String DELETE = "Delete"; protected static final String COLLAPSE_ALL = "Collapse all"; protected static final String EXPAND_ALL = "Expand all"; protected static final String FLAT_VIEW = "Flat view"; protected static final String HIER_VIEW = "Hierarchical view"; boolean flatView = false; // GridBagConstraints and GridBagLayout for the infoPanel private GridBagLayout g = new GridBagLayout(); private GridBagConstraints c = new GridBagConstraints(); private int prefHeight=600; private int prefWidth=250; static final int XSPACE=22; static final int YSPACE=18; static final int LOGOSIZE = YSPACE-6; static final int LOGOPADDING = 4; static final Color LITBGCOLOR = Color.yellow; static final Color LITFGCOLOR = Color.magenta; static final Color selectedColor = new Color(255,190,255); static final Color mouseOverColor = Color.blue; static final Color underlineColor = Color.green; // couleur des lignes static final Color lineColor = Color.black; static Font nameFont = Aladin.COURIER; static Font boldNameFont = Aladin.BCOURIER; BasicNode rootNode; // racine de l'arborescence // dernier noeud dont on a montre les infos BasicNode lastInfoNode; private BasicNode ancienCurNode; // couleur de fond private Color bkgColor = Aladin.LGRAY; // true si l'initialisation n'a pas encore ete faite private boolean mustInit = true; private int neededHeight=0; // buffer et contexte graphique private Image buffer; Graphics h; private int hilightNode; int oHilightNode = -1; BasicNode selectedNode,oselectedNode; private Vector nodeFullList; // contient une reference sur tous les noeuds BasicNode[] nodeFullTab; // reference sur tous les noeuds private Vector nodeList; // contient l'ensemble des noeuds actuellement affiches BasicNode[] nodeTab; // tableau des noeuds actuellement affiches private int yCurrent=0; // lastChild[i] vrai si le dernier noeud de niveau i est le dernier fils du noeud père private boolean[] lastChild = new boolean[100]; // Constructors private BasicTree(BasicNode rootNode) { this.rootNode=(ResourceNode)rootNode; this.rootNode.hide = true; setBackground(bkgColor); createPopup(); traverseTree(); } BasicTree(BasicNode rootNode, ScrollPane scroll) { this(rootNode); this.scroll = scroll; } BasicTree(ScrollPane scroll) { this(new ResourceNode(),scroll); } // End of constructors void createPopup() { popup = new PopupMenu(); popup.add( DELETE ); super.add(popup); popupPrefs = new PopupMenu(); popupPrefs.add(COLLAPSE_ALL); popupPrefs.add(EXPAND_ALL); // ligne de séparation popupPrefs.add("-"); popupPrefs.add(flatView?HIER_VIEW:FLAT_VIEW); super.add(popupPrefs); } /** fixe la couleur de fond de l'arbre */ public void setBackground(Color color) { super.setBackground(color); this.bkgColor = color; } /** Déselectionne tous les noeuds */ protected void clearSelected() { ancienCurNode=null; if( oHilightNode<0 || oHilightNode>=nodeTab.length ) return; BasicNode node = nodeTab[oHilightNode]; oHilightNode = -1; drawNodeName(node,true); repaint(); } protected void majSize() { // tres important : fixer ces valeurs // prefWidth doit etre calcule pour version finale //prefWidth=350; prefHeight=nodeFullTab.length*YSPACE+20; setSize(prefWidth, prefHeight); } // a appeler une fois que ressource tree est dans un conteneur // PRE : nodeFullTab doit contenir tous les noeuds de l'arbre protected boolean init() { majSize(); buffer = createImage(size().width,size().height); if( buffer==null ) return false; h = buffer.getGraphics(); doDisplay(); return true; } // calcule la hauteur necessaire a l'affichage // set neededHeight // NE SERT PAS ACTUELLEMENT private void computeHeight() { neededHeight=0; computeNodeHeight(rootNode); } // utilisé par computeHeight // NE SERT PAS ACTUELLEMENT private void computeNodeHeight(BasicNode node) { neededHeight+=YSPACE; if(!node.isLeaf && node.isOpen) { Enumeration e = node.getChildren(); while(e.hasMoreElements()) { computeNodeHeight((BasicNode)e.nextElement()); } } } boolean mustScroll=false; /** Réaffiche l'arbre entièrement */ void doDisplay() { // Ces 2 lignes faisaient planter l'arbre sur le TX : le garbage collector ne se mettait pas en route, et toute la memoire etait prise // un gc en ligne de commande reglait le pb /*buffer = createImage(size().width,size().height); h = buffer.getGraphics();*/ yCurrent=0; nodeList = new Vector(); if( h==null ) return; h.setColor(bkgColor); h.fillRect(0,0,size().width,size().height); // reset de last (sert pour flatView) last = false; h.setColor(Color.black); displayTree(rootNode,0); hilightNode=-1; nodeTab = new BasicNode[nodeList.size()]; nodeList.copyInto(nodeTab); nodeList = null; // TEST 04/06/2003 prefHeight = nodeTab.length*YSPACE; // TEST 04/06/2003 (en conjonction avec paint() )a commenter si on ne veut pas du dolayout à chaque click if( size().width!=prefWidth || size().height!=prefHeight ) setSize(prefWidth,prefHeight); // autre test 13/06/2003 --> ligne non nécessaire en 1.4, mais nécessaire en 1.3 if( !mustInit && scroll!=null ) { scroll.doLayout(); // solution originelle // pour empêcher un bug d'affichage de l'arbre en Java 1.4 int tx = scroll.getHAdjustable().getValue(); int ty = scroll.getVAdjustable().getValue(); setLocation(-tx,-ty); } } // dessine une ligne verticale de hauteur YSPACE private void drawVertLine(int x, int y) { h.setColor(lineColor); h.drawLine(x+XSPACE/2-2,y-4,x+XSPACE/2-2,y+YSPACE+2); } // dessine une ligne verticale de hauteur YSPACE/2 private void drawHalfVertLine(int x, int y) { h.setColor(lineColor); h.drawLine(x+XSPACE/2-2,y-4,x+XSPACE/2-2,y+YSPACE/2-1); } boolean last = false; private void displayTree(BasicNode node, int level) { nodeList.addElement(node); lastChild[level] = node.isLastChild(); node.level = level; int x = -XSPACE; for(int i=0;i=0 && oHilightNode0 && !flatView ) drawHorizLine(x,yCurrent,node); // dessin des checkbox pour les feuilles if( node.isLeaf ) { drawCheckBox(x,yCurrent,node,true); } x+=XSPACE; node.x = x; node.y = yCurrent; drawNodeName(node); } /** teste si la position x se trouve au dessus du label de node */ private boolean inNodeName(int x, BasicNode node) { return (x>=node.x && x<=node.x+h.getFontMetrics().stringWidth(getName(node))); } public boolean mouseMove(Event evt,int x,int y) { int ooHilightNode; hilightNode = y/YSPACE; h.setFont(nameFont); BasicNode curNode; try{ curNode = nodeTab[hilightNode]; if( ( curNode.hide ) ) return true; // on ne souligne que si on se trouve au dessus du nom // (être dans la bonne ligne ne suffit pas) if( !inNodeName(x,curNode)) { BasicNode n = nodeTab[oHilightNode]; onMouseMoved(n,false); oHilightNode = -1; ancienCurNode = null; drawNodeName(n,true); repaint(); return true; } if( ancienCurNode==curNode ) return true; ancienCurNode = curNode; ooHilightNode = oHilightNode; oHilightNode = hilightNode; // draw du noeud couramment sous la souris drawNodeName(curNode,true); } catch (ArrayIndexOutOfBoundsException e) {return true;} // appel du callback onMouseMoved(curNode,true); if(ooHilightNode!=hilightNode) { try{ BasicNode oCurNode = nodeTab[ooHilightNode]; // draw de l'ancien noeud mis en valeur drawNodeName(oCurNode,true); } catch (ArrayIndexOutOfBoundsException e) {} } //oHilightNode = hilightNode; repaint(); return true; } private int maxWidth; private int tmpSize; private FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(boldNameFont); // parcourt tout l'arbre et remplit nodeFullList et nodeFullTab void traverseTree() { nodeFullList = new Vector(); maxWidth=0; recTraverseTree(this.rootNode,0); nodeFullTab = new BasicNode[nodeFullList.size()]; nodeFullList.copyInto(nodeFullTab); // màj de la largeur prefWidth = maxWidth+5; //System.out.println(maxWidth); } // fonction recursive appelee par traverseTree private void recTraverseTree(BasicNode node, int width) { nodeFullList.addElement(node); width+=XSPACE; // la taille totale varie selon que l'on soit en vue hiérarchique ou plate tmpSize = /*width+*/fm.stringWidth(getName(node)); if( !flatView ) tmpSize += width; else tmpSize += 2*XSPACE; if( tmpSize>maxWidth ) maxWidth = tmpSize; Enumeration e = node.getChildren(); BasicNode child; while(e.hasMoreElements()) { child = (BasicNode)e.nextElement(); recTraverseTree(child,width); } } /** recherche dans les noeuds par nom * @@param name nom du noeud recherché * @@return le premier BasicNode correspondant, null si non trouvé */ public BasicNode searchNodeByName(String name) { for(int i=0;i1 ) onNodeSelectedDbleClick(selectedNode); else onNodeSelected(selectedNode); } if( !selectedNode.equals(lastInfoNode) && !inLogo && inNodeName ) { BasicNode oInfoNode = lastInfoNode; lastInfoNode = selectedNode; try { // mise en gras du noeud drawNodeName(selectedNode,true); // ancien noeud remis en fonte normale if( oInfoNode != null ) { // on vérifie que oInfoNode est encore affiché if( !oInfoNode.hide && nodeTab[oInfoNode.y/YSPACE].equals(oInfoNode) ) { drawNodeName(oInfoNode,true); } } } catch(ArrayIndexOutOfBoundsException outExc) {} } // on a clique sur une feuille if(selectedNode.isLeaf) { if( inLogo ) { selectedNode.isSelected = !selectedNode.isSelected; drawCheckBox(selectedNode.x-XSPACE,selectedNode.y,selectedNode,true); } repaint(); } // on a clique sur un noeud else { if( inLogo ) { selectedNode.changeState(); if( selectedNode.isOpen ) { onNodeExpanded(selectedNode); } else { onNodeCollapsed(selectedNode); } doDisplay(); } repaint(); } return true; } private boolean inLogo(BasicNode node, int x) { int min = (node.level)*XSPACE; int max = (node.level)*XSPACE+2+LOGOSIZE; return x>=min && x<=max; } /** Retourne une référence sur le noeud racine de l'arbre */ BasicNode getRootNode() { return rootNode; } public Dimension getSize() { //System.out.println("getSize"); // bidouille if(mustInit) { if( init() ) mustInit = false; } return new Dimension(prefWidth,prefHeight); } public Dimension getPreferredSize() { return getSize(); } public Dimension getMinimumSize() { return getSize(); } public void update(Graphics g){ // bidouille if(mustInit) { if( init() ) mustInit = false; } //System.out.println("update"); mustSetLocation = false; paint(g); } boolean mustSetLocation = false; //Point pScroll; public void paint(Graphics g) { // bidouille if(mustInit) { if( init() ) mustInit = false; } //System.out.println("paint\n"); if( buffer==null) { init(); mustInit = false; } // pour empêcher un bug d'affichage de l'arbre en Java 1.4 if( mustSetLocation ) { //System.out.println("mustSET"); int tx = scroll.getHAdjustable().getValue(); int ty = scroll.getVAdjustable().getValue(); setLocation(-tx,-ty); } mustSetLocation=true; g.drawImage(buffer,0,0,null); // solution originelle } // méthodes appelées lors d'une action sur l'arbre protected void onNodeExpanded(BasicNode node) {} protected void onNodeCollapsed(BasicNode node) {} protected void onNodeSelected(BasicNode node) {} protected void onNodeSelectedDbleClick(BasicNode node) {} protected void onNodeRemoved(BasicNode node) {} protected void onMouseMoved(BasicNode node,boolean inNodeName) {} protected void onRightClickInNode(BasicNode node, int x, int y) { popup.show(this, x, y); } protected void onRightClickOutNode(int x, int y) { popupPrefs.show(this, x,y); } } equals(FLAT_VIEW) || o.equals(HIER_VIEW) ) { setFlat(!flatView); } return true; } /** Enlève node de l'arbre * cds/aladin/Calib.java010064400076440000132000002505720770227416100154400ustar00ferniquecds00000400000013// // Recherche Scientifique // // ------ // // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.astro.*; import java.awt.*; import java.io.*; import java.util.*; import java.lang.*; /** * Gestion d'une calibration aladin * * @@author Francois Bonnarel [CDS] * @@version 0.9 : (??) creation */ public final class Calib implements Cloneable { int aladin ; double [] xyapoly = new double[10]; double [] xydpoly = new double[10]; double [] adypoly = new double[10]; double [] adxpoly = new double[10]; double epoch ; int flagepoc =0 ; double equinox ; double alpha ; double delta ; double yz ; double xz ; double focale ; double Xorg ; double Yorg ; double incX ; double incY ; double alphai ; double deltai ; double incA ; double incD ; double Xcen ; double Ycen ; double widtha ; double widthd ; int xnpix ; int ynpix ; double rota ; double cdelz; double sdelz; String type1; String type2; double [][] CD = new double[2][2]; double [][] ID = new double[2][2]; protected int system = 5; protected int proj ; private double deg_to_rad = Math.PI/180. ; private double rad_to_deg = 180./Math.PI ; static String [] projection = {"SINUS", "TANGENTIAL", "ARC", "AITOFF", "ZENITAL_EQUAL_AREA", "STEREOGRAPHIC", "CARTESIAN" , "NCP"}; /** A MODIFIER PAR FRANCOIS */ protected Calib flipBU() { Calib a = new Calib() ; try {a = (Calib)this.clone();} catch (Exception e) {} if(aladin == 1) { a.Yorg = a.Yorg + ynpix*a.incY ; a.incY = -a.incY ; } else { a.CD[1][1] = -a.CD[1][1] ; a.CD[0][1] = -a.CD[0][1] ; a.ID[1][1] = -a.ID[1][1] ; a.ID[1][0] = -a.ID[1][0] ; a.Ycen = a.ynpix -a.Ycen ; } return a;} protected Calib flipRL() { Calib b = new Calib() ; try {b = (Calib)this.clone();} catch (Exception e) {System.out.println("error");} if (aladin == 1) { b.Xorg = b.Xorg + xnpix*b.incX ; b.incX = -b.incX ; } else { b.CD[1][0] = -b.CD[1][0] ; b.CD[0][0] = -b.CD[0][0] ; b.ID[0][1] = -b.ID[0][1] ; b.ID[0][0] = -b.ID[0][0] ; b.Xcen = b.xnpix -b.Xcen ; } return b; } protected Calib resize(int scale) { double cd00,cd01,cd10,cd11 ; double X_cen, Y_cen ; int xpix,ypix ; if(aladin == 1){ try {GetWCS_i() ;} catch (Exception e) {}} X_cen = Xcen /scale ; Y_cen = Ycen /scale ; xpix = xnpix / scale ; ypix = ynpix / scale ; cd00 = CD[0][0]*scale ; cd01 = CD[0][1]*scale ; cd10 = CD[1][0]*scale ; cd11 = CD[1][1]*scale ; Calib newcal = new Calib(alphai,deltai,X_cen,Y_cen, xpix,ypix,cd00,cd01,cd10,cd11,equinox,epoch,proj); return newcal ; } protected Calib resize(int scale,double cx, double cy , int xpix, int ypix) { double cd00,cd01,cd10,cd11 ; double X_cen, Y_cen ; X_cen = (Xcen-cx) *scale ; Y_cen = (Ycen-cy) *scale ; xpix = xpix * scale ; ypix = ypix * scale ; cd00 = CD[0][0]/scale ; cd01 = CD[0][1]/scale ; cd10 = CD[1][0]/scale ; cd11 = CD[1][1]/scale ; Calib newcal = new Calib(alphai,deltai,X_cen,Y_cen, xpix,ypix,cd00,cd01,cd10,cd11,equinox,epoch,proj); return newcal ; } protected Calib recalibrate(Coord coo[]) { double A =0. ; double B =0. ; double xx ; double yy ; double x = 0.; double y = 0. ; double X = 0. ; double Y = 0. ; double z = 0. ; double XxYy = 0.; double XyYx = 0. ; double det ; double c1,c2,c3,c4 ; double b1,b2,b3,b4 ; double x0 = 0,y0 =0; double X_cen, Y_cen ; double CD00,CD10,CD01,CD11 ; double rot, inc_A,inc_D; int i = 0; try { if(aladin == 1) { GetWCS_i() ; det = CD[0][0]* CD[1][1]-CD[0][1]*CD[1][0] ; ID[0][0] = CD[1][1]/det ; ID[0][1] = -CD[0][1]/det ; ID[1][0] = -CD[1][0]/det ; ID[1][1] = CD[0][0]/det ; incA = Math.sqrt(CD[0][0]*CD[0][0]+CD[0][1]*CD[0][1]) ; incD = Math.sqrt(CD[1][0]*CD[1][0]+CD[1][1]*CD[1][1]) ; widtha = xnpix * Math.abs(incA) ; widthd = ynpix * Math.abs(incD) ; cdelz = Math.cos(deltai*deg_to_rad); sdelz = Math.sin(deltai*deg_to_rad); aladin =0; } for (i =0 ; i < coo.length ; i++) {GetXYstand(coo[i]) ; x += coo[i].dx; y -= coo[i].dy; X += coo[i].xstand ; Y += coo[i].ystand ; z += coo[i].dx * coo[i].dx + coo[i].dy * coo[i].dy ; XxYy += coo[i].dx * coo[i].xstand - coo[i].dy * coo[i].ystand ; XyYx += - coo[i].dx * coo[i].ystand - coo[i].dy * coo[i].xstand ; } x /= coo.length; y /= coo.length ; z /= coo.length ; b1 = X/coo.length ; b2 = Y/coo.length ; b3 = XxYy/coo.length ; b4 = XyYx/coo.length ; c1 = x*x*x + x*y*y - x*z ; c2 = x*x*y + y*y*y - y*z ; c3 = -x*x - y*y +z ; c4 = -x*x*z - y*y*z + z*z ; det = x*x*x*x + 2* x*x*y*y +y*y*y*y -2* x*x*z -2* y*y*z +z*z ; A = (b1*c1 +b2*c2 +b3*c3)/det ; B = (-b2*c1 +b1*c2 +b4*c3)/det ; x0 = (b3*c1 +b4*c2 +b1*c4)/det ; y0 = (-b4*c1 +b3*c2 +b2*c4)/det ; X_cen = Xcen - (A*x0-B*y0)/(A*A+B*B) ; Y_cen = Ycen + (B*x0 +A*y0)/(A*A+B*B) ; CD00 = A*rad_to_deg ; CD01 = -B*rad_to_deg ; CD10 = -B*rad_to_deg ; CD11 = -A*rad_to_deg ; inc_A = Math.sqrt(CD00*CD00+CD01*CD01)*(CD00/Math.abs(CD00)) ; inc_D = Math.sqrt(CD10*CD10+CD11*CD11)*(CD11/Math.abs(CD11)) ; // Et la rotation rot = rad_to_deg*Math.acos(CD00/inc_A); // widtha = xnpix * Math.abs(incA) ; // widthd = ynpix * Math.abs(incD) ; // cos delta au centre de l'image // cdelz = Math.cos((deltai/180.)*Math.PI); // sdelz = Math.sin((deltai/180.)*Math.PI); // cdelz = Math.cos(deltai*deg_to_rad); // sdelz = Math.sin(deltai*deg_to_rad); // Calib newcal = new Calib (alphai,deltai,X_cen,Y_cen, // (double)xnpix,xnpix*inc_A*60.,rot,proj-1,true); Calib newcal = new Calib(alphai,deltai,X_cen,Y_cen, xnpix,ynpix,CD00,CD01,CD10,CD11,equinox,epoch,proj); return newcal ; // System.out.println(coo[i].x+" "+coo[i].y+" "+coo[i].xstand +" "+coo[i].ystand);} } catch (Exception e) {} return this; } /** Creation de la calibration. * @@param Methode triviale */ protected Calib (double ra,double de, double cx, double cy, int xpix, int ypix, double cd00, double cd01, double cd10, double cd11, double equin, double epo, int proje) { aladin = 0 ; xnpix = xpix ; ynpix = ypix ; Xcen = cx ; Ycen = cy ; alphai = ra ; deltai = de ; CD[0][0] = cd00 ; CD[0][1] = cd01 ; CD[1][0] = cd10 ; CD[1][1] = cd11 ; equinox = equin ; epoch = epo ; proj = proje ; incA = Math.sqrt(CD[0][0]*CD[0][0]+CD[0][1]*CD[0][1])*(CD[0][0]/Math.abs(CD[0][0])) ; incD = Math.sqrt(CD[1][0]*CD[1][0]+CD[1][1]*CD[1][1])*(CD[1][1]/Math.abs(CD[1][1])) ; rota = Math.acos(CD[0][0]/incA)*(180./Math.PI); widtha = xnpix * Math.abs(incA) ; widthd = ynpix * Math.abs(incD) ; cdelz = Math.cos(deltai*deg_to_rad); sdelz = Math.sin(deltai*deg_to_rad); double det = CD[0][0]* CD[1][1]-CD[0][1]*CD[1][0] ; ID[0][0] = CD[1][1]/det ; ID[0][1] = -CD[0][1]/det ; ID[1][0] = -CD[1][0]/det ; ID[1][1] = CD[0][0]/det ; switch(proj) { case 1: type1 = "'RA---SIN'" ; type2 = "'DEC--SIN'" ; break ; case 2: type1 = "'RA---TAN'" ; type2 = "'DEC--TAN'" ; break ; case 3: type1 = "'RA---ARC'" ; type2 = "'DEC--ARC'" ; break ; case 4: type1 = "'RA---AIT'" ; type2 = "'DEC--AIT'" ; break ; case 5: type1 = "'RA---ZEA'" ; type2 = "'DEC--ZEA'" ; break ; case 6: type1 = "'RA---STG'" ; type2 = "'DEC--STG'" ; break ; case 7: type1 = "'RA---CAR'" ; type2 = "'DEC--CAR'" ; break ; } flagepoc = 1 ; } protected Calib (double ra,double de, double cx, double cy, double width, double radius, double rot, int proje, boolean sym ) { aladin = 0 ; xnpix = (int)width ; ynpix = (int)width ; Xcen = cx ; Ycen = cy ; alphai = ra ; deltai = de ; cdelz = Math.cos(deltai*deg_to_rad); sdelz = Math.sin(deltai*deg_to_rad); double cosdd = Math.cos(rot*deg_to_rad); double sindd = Math.sin(rot*deg_to_rad); radius /= 60. ; if(sym == false) incA = - radius/width ; else incA = radius/width ; incD = radius/width ; widtha = radius ; widthd = radius ; CD[0][0] = incA*cosdd ; CD[0][1] = incA*sindd ; CD[1][0] = -incD*sindd ; CD[1][1] = incD*cosdd ; double det = CD[0][0]* CD[1][1]-CD[0][1]*CD[1][0] ; ID[0][0] = CD[1][1]/det ; ID[0][1] = -CD[0][1]/det ; ID[1][0] = -CD[1][0]/det ; ID[1][1] = CD[0][0]/det ; rota = rot ; equinox = 2000.0 ; epoch = 2000.0; flagepoc = 0 ; // proj = 2 ; // projection tangentielle proj = proje+1 ; switch(proj) { case 1: type1 = "'RA---SIN'" ; type2 = "'DEC--SIN'" ; break ; case 2: type1 = "'RA---TAN'" ; type2 = "'DEC--TAN'" ; break ; case 3: type1 = "'RA---ARC'" ; type2 = "'DEC--ARC'" ; break ; case 4: type1 = "'RA---AIT'" ; type2 = "'DEC--AIT'" ; break ; case 5: type1 = "'RA---ZEA'" ; type2 = "'DEC--ZEA'" ; break ; case 6: type1 = "'RA---STG'" ; type2 = "'DEC--STG'" ; break ; case 7: type1 = "'RA---CAR'" ; type2 = "'DEC--CAR'" ; break ; } } /** Creation de la calibration. * @@param dataflux le flux de donnees contenant la calibration */ protected Calib ( DataInputStream dataflux) throws Exception { String s ; String st ; StringTokenizer tok; int sign = 1; // Calib vient d'aladin ; aladin = 1 ; // L'equinoxe vaut 2000 equinox = 2000.0 ; // L'epoque s=dataflux.readLine(); epoch = (new Double(s)).doubleValue(); flagepoc = 1 ; // focale du telescope s = dataflux.readLine(); // System.out.println(s); focale = (new Double(s)).doubleValue(); // System.out.println("focale "+focale); // alpha centre de plaque s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," "); st = tok.nextToken(); // System.out.println(st); alpha = (new Double(st)).doubleValue(); st = tok.nextToken(); // System.out.println(st); alpha += ((new Double(st)).doubleValue())/60.; st = tok.nextToken(); // System.out.println(st); alpha += ((new Double(st)).doubleValue())/3600.; alpha *= 15.; // System.out.println("alpha = "+alpha); // delta centre de plaque s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," "); st = tok.nextToken(); // System.out.println(st); if (st.startsWith( "-"))sign = -1; delta = (new Double(st)).doubleValue(); if (sign == -1) delta = -delta ; st = tok.nextToken(); // System.out.println(st); delta += ((new Double(st)).doubleValue())/60.; st = tok.nextToken(); // System.out.println(st); delta += ((new Double(st)).doubleValue())/3600.; if (sign == -1) delta = -delta ; // System.out.println("delta = "+delta); // x y centre de plaque (en mm). s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," "); st = tok.nextToken(); // System.out.println(st); yz = (new Double(st)).doubleValue(); st = tok.nextToken(); // System.out.println(st); xz = (new Double(st)).doubleValue(); // System.out.println("xz "+xz+" yz "+yz); // six champs nonj utilsses for ( int i=0; i<6 ; i++) dataflux.readLine(); // coeffs du polynome alpha delta --> x y for ( int i=0; i<10 ; i++) { s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," "); st = tok.nextToken(); // System.out.println(st); adypoly[i] = (new Double(st)).doubleValue(); st = tok.nextToken(); // System.out.println(st); adxpoly[i] = (new Double(st)).doubleValue(); // System.out.println("adxy "+adxpoly[i]+" "+adypoly[i]); } // coeffs du polynome x y --> alpha delta for ( int i=0; i<10 ; i++) { s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," "); st = tok.nextToken(); // System.out.println(st); xyapoly[i] = (new Double(st)).doubleValue(); st = tok.nextToken(); // System.out.println(st); xydpoly[i] = (new Double(st)).doubleValue(); // System.out.println("xyad "+xyapoly[i]+" "+xydpoly[i]); } // dx dy d'un pixel en micron s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," "); st = tok.nextToken(); // System.out.println(st); incY = (new Double(st)).doubleValue(); st = tok.nextToken(); // System.out.println(st); incX = (new Double(st)).doubleValue(); // System.out.println("inc "+incX+" "+incY); // x y coin de l'image ( en microns) s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," "); st = tok.nextToken(); // System.out.println(st); st = tok.nextToken(); // System.out.println(st); Yorg = (new Double(st)).doubleValue(); st = tok.nextToken(); // System.out.println(st); Xorg = (new Double(st)).doubleValue(); // System.out.println("org "+Xorg+" "+Yorg); // alpha delta centre image , largeur hauteur (degres decimaux) s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," ,=/"); st = tok.nextToken(); // System.out.println(st); st = tok.nextToken(); // System.out.println(st); alphai = (new Double(st)).doubleValue(); st = tok.nextToken(); // System.out.println(st); deltai = (new Double(st)).doubleValue(); st = tok.nextToken(); // System.out.println(st); st = tok.nextToken(); // System.out.println(st); widtha = (new Double(st)).doubleValue(); // System.out.println("WIDTHA "+widtha); st = tok.nextToken(); // System.out.println(st); widthd = (new Double(st)).doubleValue(); // System.out.println("center width "+alphai+" "+deltai+" "+widtha+" "+widthd); // nombre de pixels en x et en y de l'image s = dataflux.readLine(); // System.out.println(s); tok = new StringTokenizer (s," ,=/"); st = tok.nextToken(); // System.out.println(st); st = tok.nextToken(); // System.out.println(st); xnpix = (new Integer(st)).intValue(); st = tok.nextToken(); // System.out.println(st); ynpix = (new Integer(st)).intValue(); // System.out.println("npix "+xnpix+" "+ynpix); // cdelz = Math.cos((delta/180.)*Math.PI); // sdelz = Math.sin((delta/180.)*Math.PI); cdelz = Math.cos(delta*deg_to_rad); sdelz = Math.sin(delta*deg_to_rad); incA = (xyapoly[2]*incX/focale/1000)*rad_to_deg ; incD = (xydpoly[1]*incY/focale/1000)*rad_to_deg ; // System.out.println("incAD "+incA+" "+incD ); Coord cc = new Coord() ; cc.al = alphai ; cc.del = deltai ; GetXY(cc) ; Xcen = cc.x ; Ycen = cc.y ; } protected Calib () {} protected Calib ( HeaderFits hf) throws Exception { double det ; // Calib ne vient pas d'aladin ; aladin = 0 ; // Requis nombre de pixels en X et Y xnpix = hf.getIntFromHeader("NAXIS1 "); ynpix = hf.getIntFromHeader("NAXIS2 "); try { alpha = hf.getDoubleFromHeader("PLTRAS "); Dss( hf) ; return ; } catch (Exception e0) { // Requis: pixel central Xcen = hf.getDoubleFromHeader("CRPIX1 "); Ycen = hf.getDoubleFromHeader("CRPIX2 "); // Requis: position (alph delt) du centre alphai = hf.getDoubleFromHeader("CRVAL1 "); deltai = hf.getDoubleFromHeader("CRVAL2 "); // System.out.println("alphai "+alphai+"deltai "+deltai); try { // Version Finale du WCS matrice CDn_j de transformation CD[0][0] = hf.getDoubleFromHeader("CD1_1 "); CD[0][1] = hf.getDoubleFromHeader("CD1_2 "); CD[1][0] = hf.getDoubleFromHeader("CD2_1 "); CD[1][1] = hf.getDoubleFromHeader("CD2_2 "); // Dans ce cas on recalcule les increments par pixel incA = Math.sqrt(CD[0][0]*CD[0][0]+CD[0][1]*CD[0][1]) ; incD = Math.sqrt(CD[1][0]*CD[1][0]+CD[1][1]*CD[1][1]) ; // Et la rotation rota = Math.acos(CD[0][0]/incA)*(180./Math.PI); // System.out.println("CD "+CD[0][0]+" "+CD[0][1]+" "+CD[1][0]+" "+CD[1][1]); } catch (Exception e1) { // Dans les autres versions du WCS on a toujours // les increments incA = hf.getDoubleFromHeader("CDELT1 "); incD = hf.getDoubleFromHeader("CDELT2 "); // System.out.println("incA "+incA+"incD "+incD); // System.out.println("CRPIX1"+Xcen+"CRPIX2 "+Ycen); try { // Et soit l'angle de rotation (1 ou 2) ... double rota1=0,rota2=0 ; try { rota1 = hf.getDoubleFromHeader("CROTA1 "); // System.out.println("CROTA1 "+rota1); rota2 = hf.getDoubleFromHeader("CROTA2 "); // System.out.println("CROTA2 "+rota2); } catch (Exception e6) { try { rota1 = hf.getDoubleFromHeader("CROTA1 "); // System.out.println("CROTA1 "+rota1); } catch (Exception e7) { rota2 = hf.getDoubleFromHeader("CROTA2 "); // System.out.println("CROTA2 "+rota2); } } rota = rota1 ; if (rota1 == 0) rota = rota2 ; else if (rota2 != 0) rota = (rota1+rota2 )/2 ; // Auquel cas on calcule la matrice de transformation CD[0][0] = incA*Math.cos((rota/180.)*Math.PI) ; CD[0][1] = -incD*Math.sin((rota/180.)*Math.PI) ; CD[1][0] = incA*Math.sin((rota/180.)*Math.PI) ; CD[1][1] = incD*Math.cos((rota/180.)*Math.PI) ; //System.out.println("CD "+CD[0][0]+"CD "+CD[0][1]); } catch (Exception e2) { try { // Soit la matrice de rotation, // d'ou l'on deduit la matrice // de transformation ... CD[0][0] = hf.getDoubleFromHeader("PC001001")*incA; CD[0][1] = hf.getDoubleFromHeader("PC001002")*incA; CD[1][0] = hf.getDoubleFromHeader("PC002001")*incD; CD[1][1] = hf.getDoubleFromHeader("PC002002")*incD; // Et l'angle de rotation rota=Math.acos(hf.getDoubleFromHeader("PC001001"))*(180./Math.PI); } catch (Exception e3) { // s'il n'ya ni angle de rotation ni matrice // de rotation la transformation est une homothetie // modifie pour DENIS rota = 0.0 ; CD[0][0] = incA ; CD[0][1] = 0 ; CD[1][0] = 0 ; CD[1][1] = incD ; // ci dessous pour tenir compte des vieilles // images DENIS !!!! String origin ; origin = hf.getStringFromHeader("ORIGIN "); if (origin!=null && origin.startsWith("'DeNIS")) { if (CD[0][0] >0 ) CD[0][0] = - CD[0][0] ; if (CD[1][1] >0 ) CD[1][1] = - CD[1][1] ; } } // Fin de e3 } // Fin de e2 } // Fin de e1 } // Fin de e0 try { epoch = hf.getDoubleFromHeader("EPOCH "); flagepoc = 1 ; } catch(Exception e6) { epoch = 0.0 ; } try { equinox = hf.getDoubleFromHeader("EQUINOX "); } catch(Exception e5) { try { // Epoque d'observation equinox = hf.getDoubleFromHeader("EPOCH ") ; epoch = equinox ; flagepoc = 1 ; } catch (Exception e4) { equinox = 2000.0 ; epoch = 2000.0; flagepoc = 0 ; } } // Requis Type de projection type1 = hf.getStringFromHeader("CTYPE1 "); type2 = hf.getStringFromHeader("CTYPE2 "); // System.out.println(type1+" "+type2); if (type1.startsWith("'DEC")) { double tmp_invert ; tmp_invert = deltai ; deltai = alphai ; alphai = tmp_invert ; tmp_invert = CD[0][0] ; CD[0][0] = CD[1][0] ; CD[1][0] = tmp_invert ; tmp_invert = CD[1][1] ; CD[1][1] = CD[0][1] ; CD[0][1] = tmp_invert ; tmp_invert = incA ; incA = incD ; incD = tmp_invert ; // System.out.println("DEC"); } if (type1.startsWith("'ELON")) { // System.out.println("ELON"); system = 4 ; } if (type1.startsWith("'GLON")) { // System.out.println("GLON"); system = 2 ; } if (type1.startsWith("'SLON")) { // System.out.println("SLON"); system = 3 ; } if (equinox == 1950.0) system = 1 ; try { String Syst = hf.getStringFromHeader("RADECSYS") ; if (Syst.indexOf("ICRS")>=0) system = 6; if (Syst.indexOf("FK5")>=0) system = 5 ; if (Syst.indexOf("FK4")>=0) system = 1 ; } catch(Exception e10) {} // else System.out.println("RA"); proj = 0 ; // System.out.println("type1 "+type1+" type2"+type2); if (type1.indexOf("SIN")>= 0) proj = 1 ; if (type1.indexOf("TAN")>= 0) proj = 2 ; // PIERRE POUR GOODS if (type1.indexOf("COE")>= 0) proj = 2 ; if (type1.indexOf("ARC")>= 0) proj = 3 ; if (type1.indexOf("AIT")>= 0) proj = 4 ; if (type1.indexOf("ZEA")>= 0) proj = 5 ; if (type1.indexOf("STG")>= 0) proj = 6 ; if (type1.indexOf("CAR")>= 0) proj = 7 ; if (type1.indexOf("NCP")>= 0) proj = 8 ; if (proj == 0) { System.err.println( "Calib warning:CTYPE "+type1+" is not yet supported " +"by AladinJava, please contact us") ; throw new Exception("CTYPE "+type1+" is not yet supported " +"by AladinJava, please contact us") ; } // calcul de la largeur et de la hauteur de l'iamge widtha = xnpix * Math.abs(incA) ; widthd = ynpix * Math.abs(incD) ; // cos delta au centre de l'image // cdelz = Math.cos((deltai/180.)*Math.PI); // sdelz = Math.sin((deltai/180.)*Math.PI); cdelz = Math.cos(deltai*deg_to_rad); sdelz = Math.sin(deltai*deg_to_rad); // calcul de la transformation inverse det = CD[0][0]* CD[1][1]-CD[0][1]*CD[1][0] ; ID[0][0] = CD[1][1]/det ; ID[0][1] = -CD[0][1]/det ; ID[1][0] = -CD[1][0]/det ; ID[1][1] = CD[0][0]/det ; // System.out.println("ID "+ID[0][0]+" "+ID[0][1]+" "+ID[1][0]+" "+ID[1][1]); } protected void Dss ( HeaderFits hf) throws Exception { int sign = 1; double det ; proj = 2 ; // projection TAN ; alpha += hf.getIntFromHeader("PLTRAM ")*60. ; alpha += hf.getIntFromHeader("PLTRAH ")*3600. ; alpha /= 240. ; if(hf.getStringFromHeader("PLTDECSN").startsWith( "'-"))sign = -1 ; delta = hf.getDoubleFromHeader("PLTDECS ") ; delta += hf.getIntFromHeader("PLTDECM ")*60. ; delta += hf.getIntFromHeader("PLTDECD ")*3600. ; delta /= 3600. ; delta *= sign ; // System.out.println(" Header Getimage: "+alphai+" "+deltai); focale = hf.getDoubleFromHeader("PLTSCALE"); focale = 180.*3600./Math.PI/focale ; equinox = hf.getDoubleFromHeader("EQUINOX "); try { // Epoque d'observation epoch = hf.getDoubleFromHeader("EPOCH ") ; } catch (Exception e1) { epoch = equinox ; flagepoc = 0 ; } xz = hf.getDoubleFromHeader("PPO3 "); xz /= 1000. ; yz = hf.getDoubleFromHeader("PPO6 "); yz /= 1000.; xyapoly[2] = hf.getDoubleFromHeader("AMDX1 ") ; xydpoly[1] = hf.getDoubleFromHeader("AMDY1 ") ; // System.out.println(focale+" "+xz+" "+yz+" "+xyapoly[2]+" "+xydpoly[2]); xyapoly[1] = hf.getDoubleFromHeader("AMDX2 ") ; xydpoly[2] = hf.getDoubleFromHeader("AMDY2 ") ; xyapoly[0] = hf.getDoubleFromHeader("AMDX3 ") ; xydpoly[0] = hf.getDoubleFromHeader("AMDY3 ") ; xyapoly[4] = hf.getDoubleFromHeader("AMDX4 ") ; xydpoly[3] = hf.getDoubleFromHeader("AMDY4 ") ; xyapoly[5] = hf.getDoubleFromHeader("AMDX5 ") ; xydpoly[5] = hf.getDoubleFromHeader("AMDY5 ") ; xyapoly[3] = hf.getDoubleFromHeader("AMDX6 ") ; xydpoly[4] = hf.getDoubleFromHeader("AMDY6 ") ; xyapoly[4] += hf.getDoubleFromHeader("AMDX7 ") ; xydpoly[4] += hf.getDoubleFromHeader("AMDY7 ") ; xyapoly[3] += hf.getDoubleFromHeader("AMDX7 ") ; xydpoly[3] += hf.getDoubleFromHeader("AMDY7 ") ; xyapoly[7] = hf.getDoubleFromHeader("AMDX8 ") ; xydpoly[6] = hf.getDoubleFromHeader("AMDY8 ") ; xyapoly[9] = hf.getDoubleFromHeader("AMDX9 ") ; xydpoly[8] = hf.getDoubleFromHeader("AMDY9 ") ; xyapoly[8] = hf.getDoubleFromHeader("AMDX10 ") ; xydpoly[9] = hf.getDoubleFromHeader("AMDY10 ") ; xyapoly[6] = hf.getDoubleFromHeader("AMDX11 ") ; xydpoly[7] = hf.getDoubleFromHeader("AMDY11 ") ; xyapoly[7] += hf.getDoubleFromHeader("AMDX12 ") ; xydpoly[6] += hf.getDoubleFromHeader("AMDY12 ") ; xyapoly[8] += hf.getDoubleFromHeader("AMDX12 ") ; xydpoly[9] += hf.getDoubleFromHeader("AMDY12 ") ; xyapoly[0] /= focale ; xydpoly[0] /= focale ; xyapoly[1] *= -1.; xydpoly[1] *= -1.; xyapoly[2] *= -1.; xydpoly[2] *= -1.; xyapoly[3] *= focale ; xydpoly[3] *= focale ; xyapoly[4] *= focale ; xydpoly[4] *= focale ; xyapoly[5] *= focale ; xydpoly[5] *= focale ; xyapoly[6] *= -focale*focale ; xydpoly[6] *= -focale*focale ; xyapoly[7] *= -focale*focale ; xydpoly[7] *= -focale*focale ; xyapoly[8] *= -focale*focale ; xydpoly[8] *= -focale*focale ; xyapoly[9] *= -focale*focale ; xydpoly[9] *= -focale*focale ; int i ; for (i=0; i<=9;i++) { xyapoly[i] /= (180*3600/Math.PI/focale) ; xydpoly[i] /= (180*3600/Math.PI/focale) ; } incX = hf.getDoubleFromHeader("XPIXELSZ") ; incY = hf.getDoubleFromHeader("YPIXELSZ") ; xnpix = hf.getIntFromHeader("NAXIS1 "); ynpix = hf.getIntFromHeader("NAXIS2 "); Xorg = incX * hf.getIntFromHeader("CNPIX1 ") ; Yorg = incY *(13999 - hf.getIntFromHeader("CNPIX2 ") -ynpix ) ; yz = incY * 13999 / 1000. -yz ; cdelz = Math.cos(delta*deg_to_rad); sdelz = Math.sin(delta*deg_to_rad); aladin = 1 ; GetWCS_i() ; det = CD[0][0]* CD[1][1]-CD[0][1]*CD[1][0] ; ID[0][0] = CD[1][1]/det ; ID[0][1] = -CD[0][1]/det ; ID[1][0] = -CD[1][0]/det ; ID[1][1] = CD[0][0]/det ; incA = Math.sqrt(CD[0][0]*CD[0][0]+CD[0][1]*CD[0][1]) ; incD = Math.sqrt(CD[1][0]*CD[1][0]+CD[1][1]*CD[1][1]) ; widtha = xnpix * Math.abs(incA) ; widthd = ynpix * Math.abs(incD) ; cdelz = Math.cos(deltai*deg_to_rad); sdelz = Math.sin(deltai*deg_to_rad); aladin = 0 ; } protected void GetXYstand(Coord c) throws Exception { double x_obj =1.; double y_obj =1.; double x_objr ; double y_objr ; double x_tet_phi; double y_tet_phi; double y_stand =0.03; double x_stand =0.03; double delrad ; double alrad ; double dr; double al,del; // System.out.println("aladin"+aladin); if(aladin == 1) { // cdelz = Math.cos((delta/180.)*Math.PI); // sdelz = Math.sin((delta/180.)*Math.PI); // Methode aladin = methode plaque .... // delrad = (c.del/180.)*Math.PI; delrad = c.del*deg_to_rad; alrad = (c.al - alpha)*deg_to_rad; double sin_delrad = Math.sin (delrad) ; double cos_delrad = Math.cos (delrad) ; double sin_alrad = Math.sin(alrad) ; double cos_alrad = Math.cos(alrad) ; dr = sin_delrad * sdelz + cos_delrad * cdelz * cos_alrad; x_stand = cos_delrad * sin_alrad/dr ; y_stand = (sin_delrad * cdelz - cos_delrad * sdelz * cos_alrad) / dr; // System.out.println("xy_stand "+x_stand+" " +y_stand); } else { al = c.al ; del = c.del ; // PIERRE : LA J'AVOUE QUE J'HESITE A ENLEVER LE +1 c.dx = c.x - Xcen+1; //c.dy = ynpix - Ycen -c.y; c.dy = c.y - Ycen ; //PIERRE c.dx = (int) (Math.round(c.dxf)); //PIERRE c.dy = (int) (Math.round(c.dyf)); //PIERRE System.out.println(c.dxf+" "+c.dyf); if (equinox != 2000.0) { Astroframe j2000 = new Astroframe() ; Astroframe natif = new Astroframe(1,equinox) ; j2000.set(al,del) ; j2000.convert(natif) ; al = natif.getLon() ; del = natif.getLat() ; } if (system == 2) { Astroframe fk5 = new Astroframe() ; Astroframe natif = new Astroframe(2,equinox); fk5.set(al,del) ; fk5.convert(natif); al = natif.getLon() ; del = natif.getLat() ; // System.out.println(al+" "+del); } // System.out.println("c.al c.del "+al+" "+del); // Methode Header FITS WCS double ddel = (del-deltai)*deg_to_rad ; double dalpha = (al- alphai)*deg_to_rad; //System.out.println("dalpha "+ al +" " + alphai + " " + deg_to_rad ); double cos_del = Math.cos(del*deg_to_rad); double sin_del = Math.sin(del*deg_to_rad); double sin_dalpha = Math.sin(dalpha); double cos_dalpha = Math.cos(dalpha); // x_tet_phi = Math.cos(del*Math.PI/180.) // *Math.sin((al - alphai)*Math.PI/180.) ; x_tet_phi = cos_del *sin_dalpha ; // y_tet_phi = Math.sin(del*Math.PI/180.) // *Math.cos(deltai*Math.PI/180.) // - Math.cos(del*Math.PI/180.) // *Math.sin(deltai*Math.PI/180.) // *Math.cos((al - alphai)*Math.PI/180.); y_tet_phi = sin_del * cdelz - cos_del * sdelz * cos_dalpha ; double phi ; double tet ; switch(proj) { case 8 : case 1 : // SIN proj x_stand = x_tet_phi ; y_stand = y_tet_phi ; break ; case 2: // TAN proj double den = sin_del * sdelz + cos_del * cdelz ; x_stand = x_tet_phi / den ; y_stand = y_tet_phi / den ; break ; case 3: // Arc proj phi = Math.atan(cos_del *sin_dalpha / (sin_del*cdelz- cos_del*sdelz *cos_dalpha)); if (sin_del*cdelz - cos_del*sdelz*cos_dalpha > 0) phi = Math.PI + phi ; tet = Math.asin ( sin_del*sdelz+ cos_del*cdelz *cos_dalpha); x_stand = (Math.PI/2 -tet)*Math.sin(phi) ; y_stand = -(Math.PI/2 -tet)*Math.cos(phi) ; break ; case 4: // AIT proj if (al > 180.) dalpha -= 2*Math.PI ; double cos_ddel = Math.cos(ddel) ; double alph = Math.sqrt(2/(1+cos_ddel*Math.cos(dalpha/2.))); x_stand = 2*alph*cos_ddel*Math.sin(dalpha/2.) ; y_stand = alph*Math.sin(ddel) ; if(dalpha/2. > Math.PI) x_stand = -x_stand ; break ; case 5: // ZEA projection phi = Math.atan(-cos_del *sin_dalpha / (sin_del*cdelz- cos_del*sdelz *cos_dalpha)); if (sin_del*cdelz - cos_del*sdelz*cos_dalpha > 0) phi = Math.PI + phi ; tet = Math.asin ( sin_del*sdelz+ cos_del*cdelz *cos_dalpha); double rtet = Math.sqrt(2*(1-Math.sin(tet))); x_stand = rtet*Math.sin(phi) ; y_stand = - rtet*Math.cos(phi) ; break ; case 6: den = 1 + sin_del*sdelz + cos_del*cdelz*cos_dalpha; x_stand = 2*x_tet_phi / den ; y_stand = 2*y_tet_phi / den ; break ; case 7: // CARTESIEN x_stand = (al-alphai)*deg_to_rad ; y_stand = (del-deltai)*deg_to_rad ; break ; default: break ; } } c.xstand = x_stand ; c.ystand = y_stand ; } protected void GetCoord(Coord c) throws Exception { double x_obj =1.; double y_obj =1.; double x_objr ; double y_objr ; double posx ; double posy ; if(aladin == 1) { // cdelz = Math.cos((delta/180.)*Math.PI); // sdelz = Math.sin((delta/180.)*Math.PI); // Methode aladin = methode plaque .... x_obj = (c.x*incX +Xorg)/1000. ; y_obj = (c.y*incY + Yorg)/1000. ; // System.out.println("xyobj "+x_obj+" " +y_obj); x_objr = (x_obj -xz) / focale ; y_objr = (y_obj -yz) / focale ; // System.out.println("xyobjr "+x_objr+" " +y_objr); posx = xyapoly[0] + xyapoly[1]*y_objr + xyapoly[2]*x_objr + xyapoly[3]*y_objr*y_objr + xyapoly[4]*x_objr*x_objr + xyapoly[5]*y_objr*x_objr + xyapoly[6]*y_objr*y_objr*y_objr + xyapoly[7]*x_objr*x_objr*x_objr + xyapoly[8]*y_objr*y_objr*x_objr + xyapoly[9]*y_objr*x_objr*x_objr ; posy = xydpoly[0] + xydpoly[1]*y_objr + xydpoly[2]*x_objr + xydpoly[3]*y_objr*y_objr + xydpoly[4]*x_objr*x_objr + xydpoly[5]*y_objr*x_objr + xydpoly[6]*y_objr*y_objr*y_objr + xydpoly[7]*x_objr*x_objr*x_objr + xydpoly[8]*y_objr*y_objr*x_objr + xydpoly[9]*y_objr*x_objr*x_objr ; // System.out.println("pos "+posx+" " +posy); c.al = alpha + (Math.atan(posx/(cdelz-posy*sdelz)))*rad_to_deg ; c.del = Math.atan(Math.cos((c.al-alpha)*deg_to_rad) *(sdelz +posy *cdelz)/(cdelz-posy*sdelz)) // *(180./Math.PI); *rad_to_deg ; if((c.del * delta< 0)&&(Math.abs(delta) > 87.)) { c.al += 180.; c.del = -c.del; } if(c.al > 360.) c.al -= 360.; if(c.al < 0.) c.al += 360.; // System.out.println("coord "+c.al+" " +c.del); } else { // Methode Header FITS WCS // System.out.println("xy "+c.x+" "+c.y); x_obj = c.x - Xcen+1; y_obj = ynpix - Ycen -c.y; // System.out.println("xyobj "+x_obj+" "+y_obj); // y_obj = Ycen -c.y ; // y_obj = c.y -Ycen ; // x_objr = (CD[0][0]*x_obj +CD[0][1]*y_obj)/cdelz ; // System.out.println("CD "+CD[0][0]+" "+CD[0][1]); // System.out.println("CD "+CD[1][0]+" "+CD[1][1]); x_objr = (CD[0][0]*x_obj +CD[0][1]*y_obj) ; y_objr = (CD[1][0]*x_obj +CD[1][1]*y_obj) ; // System.out.println("xyobjr "+x_objr+" "+y_objr); // x_objr *= Math.PI/180. ; // y_objr *= Math.PI/180. ; x_objr *= deg_to_rad ; y_objr *= deg_to_rad ; // System.out.println("xyobjr "+x_objr+" "+y_objr); double X ; double tet ; switch(proj) { case 1: // projection en SINUS // System.out.println("Deux valeurs " + sdelz +" "+ Math.sin(deltai*Math.PI/180.)) ; // c.del = (180./Math.PI) // *(Math.asin(y_objr*Math.cos(deltai*Math.PI/180.) // +Math.sin(deltai*Math.PI/180.) // *Math.sqrt(1-y_objr*y_objr - x_objr*x_objr))); c.del = rad_to_deg *(Math.asin(y_objr*cdelz +sdelz *Math.sqrt(1-y_objr*y_objr - x_objr*x_objr))); X = x_objr / // (Math.cos(deltai*Math.PI/180.) (cdelz *Math.sqrt(1-y_objr*y_objr - x_objr*x_objr) // - y_objr*Math.sin(deltai*Math.PI/180.)); - y_objr*sdelz); // c.al = alphai + (180./Math.PI)*Math.atan(X) ; c.al = alphai + rad_to_deg*Math.atan(X) ; double sign ; if (deltai == 0) sign = 1; else sign = deltai / Math.abs(deltai) ; // System.out.println("deltai "+" "+c.al); // if( sign*y_objr -Math.cos (deltai*Math.PI/180.) > 0) if( sign*y_objr -cdelz > 0) c.al += 180. ; // System.out.println("deltai "+" "+c.al); break ; case 8: c.del = rad_to_deg *(Math.acos((cdelz- y_objr*sdelz)/Math.cos((c.al-alpha)*deg_to_rad))) ; X = x_objr / (cdelz - y_objr*sdelz); c.al = alphai + rad_to_deg*Math.atan(X) ; break ; case 2: // projection en TAN // double deno = Math.cos(deltai*Math.PI/180.) double deno = cdelz // -y_objr*Math.sin(deltai*Math.PI/180.); -y_objr*sdelz; double d_al = Math.atan(x_objr/deno) ; c.del = (180./Math.PI)*Math.atan(Math.cos(d_al) // *(Math.sin(deltai*Math.PI/180.) *(sdelz // +y_objr*Math.cos(deltai*Math.PI/180.)) +y_objr*cdelz) / deno ) ; // c.al = alphai + d_al*180./Math.PI; c.al = alphai + d_al*rad_to_deg; if((c.del * deltai< 0)&&(Math.abs(deltai) > 87.)) { c.al += 180.; c.del = -c.del; } break ; case 3: //ARC proj tet = Math.sqrt(x_objr*x_objr+y_objr*y_objr); c.del = rad_to_deg*Math.asin(+y_objr*cdelz*Math.sin(tet)/tet +sdelz*Math.cos(tet)); if (tet < Math.PI/2) c.al =alphai + rad_to_deg*Math.asin(Math.sin(tet)*x_objr/(tet*Math.cos(c.del*deg_to_rad))); else c.al =alphai + 180. - rad_to_deg*Math.asin(Math.sin(tet)*x_objr/(tet*Math.cos(c.del*deg_to_rad))) ; // System.out.println("rtet1 "+Math.cos(tet)*x_objr/(tet*Math.cos(c.del*deg_to_rad))); break; case 4: // projection AiTOFF double z = 1 - x_objr*x_objr/16 -y_objr*y_objr/4; if (z < 0.5) // throw new Exception("No coordinates") ; { c.del = -32000 ; c.al = -32000.0;} else { double Z = Math.sqrt(z); // c.del = (180./Math.PI)*Math.asin(y_objr*Z) ; c.del = rad_to_deg*Math.asin(y_objr*Z) ; // c.al = (360./Math.PI)*Math.atan((x_objr*Z/2)/(2*Z*Z-1)); c.al = 2*rad_to_deg*Math.atan((x_objr*Z/2)/(2*Z*Z-1)); } break ; case 5: // projection ZEA double phi ; double rtet = Math.sqrt(x_objr*x_objr +y_objr*y_objr)/2.; // System.out.println("rtet "+rtet); tet = Math.PI/2. - 2*Math.asin(rtet); // System.out.println("tet "+180.*tet/Math.PI); if(y_objr != 0.0) phi = Math.atan(-x_objr/y_objr); else phi = Math.atan(-x_objr) ; if(y_objr < 0.0) phi = phi+Math.PI ; // System.out.println("phi "+180.*phi/Math.PI); // c.del = (180./Math.PI)* c.del = rad_to_deg* // Math.asin(Math.sin(deltai*Math.PI/180.)*Math.sin(tet)+ Math.asin(sdelz*Math.sin(tet)+ // Math.cos(deltai*Math.PI/180.)*Math.cos(tet)*Math.cos(phi)); cdelz*Math.cos(tet)*Math.cos(phi)); // if((y_objr < 0.0)) c.del = 2*deltai - c.del ; // double arg1 = (Math.sin(tet)*Math.cos(deltai*Math.PI/180.) // - Math.cos(tet)*Math.sin(deltai*Math.PI/180.)*Math.cos(phi)); double arg1 = (Math.sin(tet)*cdelz - Math.cos(tet)*sdelz*Math.cos(phi)); double arg ; // if(arg1 != 0) // arg = -(Math.cos(tet)*Math.sin(phi))/ arg1 ; // else arg = 0.0 ; arg = -(Math.cos(tet)*Math.sin(phi)); // if(y_objr < 0.0) arg = -arg ; if (Math.abs(deltai) != 90.) // c.al = alphai + (180./Math.PI)*Math.atan(arg) ; // else if (deltai == 90.)c.al = (180./Math.PI)*(phi+Math.PI) ; // else c.al = (180./Math.PI)*(-phi); // c.al = alphai + rad_to_deg*Math.atan(arg) ; c.al = alphai + rad_to_deg*Math.atan2(arg,arg1) ; else if (deltai == 90.)c.al = rad_to_deg*(phi+Math.PI) ; else c.al = rad_to_deg*(-phi); // System.out.println(" C.aldel"+c.del+" "+c.al+"\n"); if((c.del*c.del > 90.*90.)&&(Math.abs(deltai) > 65.)) { c.al = 180. - c.al ; c.del = 2*deltai - c.del ; } // System.out.println(" C.aldel"+c.del+" "+c.al+"\n"); break ; case 6: double sintet = Math.sin(Math.PI/2 - 2*Math.atan(Math.sqrt(y_objr*y_objr + x_objr*x_objr)/2)); // c.del = (180./Math.PI) // *Math.asin(Math.cos(deltai*Math.PI/180.)*y_objr/2 // + sintet *(Math.sin(deltai*Math.PI/180.) + // Math.cos(deltai*Math.PI/180.)*y_objr/2)); c.del = rad_to_deg *Math.asin(cdelz*y_objr/2 + sintet *(sdelz + cdelz*y_objr/2)); deno = // sintet* (2*cdelz-y_objr*Math.sin(deltai*Math.PI/180.)) -y_objr*Math.sin(deltai*Math.PI/180.); sintet* (2*cdelz-y_objr*sdelz) -y_objr*sdelz; // c.al = alphai + (180./Math.PI) * Math.atan( // c.al = alphai + rad_to_deg * Math.atan( // x_objr*(1+sintet) /deno) ; c.al = alphai + rad_to_deg * Math.atan2(x_objr*(1+sintet),deno) ; break ; case 7: // CARTESIEN c.al = alphai +x_objr*rad_to_deg ; c.del= deltai +y_objr*rad_to_deg ; break ; default: break ; } if (equinox != 2000.0) { Astroframe j2000 = new Astroframe() ; Astroframe natif = new Astroframe(1,equinox) ; natif.set(c.al,c.del) ; natif.convert(j2000) ; c.al = j2000.getLon() ; c.del = j2000.getLat() ; } if (system == 2) { Astroframe fk5 = new Astroframe() ; Astroframe natif = new Astroframe(2,equinox); natif.set(c.al,c.del) ; natif.convert(fk5); c.al = fk5.getLon() ; c.del = fk5.getLat() ; } if(c.al > 360.) c.al -= 360.; if(c.al < 0.) c.al += 360.; // System.out.println("coord "+c.al+" " +c.del); } } protected boolean TheSame(Calib cal) { if (aladin == 1) return false ; if (xnpix != cal.xnpix) return false ; if (ynpix != cal.ynpix) return false ; if (Xcen != cal.Xcen) return false ; if (Ycen != cal.Ycen) return false ; if (alphai != cal.alphai) return false ; if (deltai != cal.deltai) return false ; if (CD[0][0] != cal.CD[0][0]) return false ; if (CD[0][1] != cal.CD[0][1]) return false ; if (CD[1][0] != cal.CD[1][0]) return false ; if (CD[1][1] != cal.CD[1][1]) return false ; if (equinox != cal.equinox) return false ; if (proj != cal.proj) return false ; return true ; } protected void GetXY(Coord c) { double x_obj =1.; double y_obj =1.; double x_objr ; double y_objr ; double x_tet_phi; double y_tet_phi; double y_stand =0.03; double x_stand =0.03; double delrad ; double alrad ; double dr; double al,del ; // System.out.println("aladin"+aladin); if(aladin == 1) { // cdelz = Math.cos((delta/180.)*Math.PI); // sdelz = Math.sin((delta/180.)*Math.PI); // Methode aladin = methode plaque .... // delrad = (c.del/180.)*Math.PI; delrad = c.del*deg_to_rad; alrad = (c.al - alpha)*deg_to_rad; double sin_delrad = Math.sin (delrad) ; double cos_delrad = Math.cos (delrad) ; double sin_alrad = Math.sin(alrad) ; double cos_alrad = Math.cos(alrad) ; dr = sin_delrad * sdelz + cos_delrad * cdelz * cos_alrad; x_stand = cos_delrad * sin_alrad/dr ; y_stand = (sin_delrad * cdelz - cos_delrad * sdelz * cos_alrad) / dr; // System.out.println("xy_stand "+x_stand+" " +y_stand); x_obj = adxpoly[0] + adxpoly[1]*x_stand + adxpoly[2]*y_stand + adxpoly[3]*x_stand*x_stand + adxpoly[4]*y_stand*y_stand + adxpoly[5]*y_stand*x_stand + adxpoly[6]*x_stand*x_stand*x_stand + adxpoly[7]*y_stand*y_stand*y_stand + adxpoly[8]*y_stand*x_stand*x_stand + adxpoly[9]*y_stand*y_stand*x_stand ; y_obj = adypoly[0] + adypoly[1]*x_stand + adypoly[2]*y_stand + adypoly[3]*x_stand*x_stand + adypoly[4]*y_stand*y_stand + adypoly[5]*y_stand*x_stand + adypoly[6]*x_stand*x_stand*x_stand + adypoly[7]*y_stand*y_stand*y_stand + adypoly[8]*y_stand*x_stand*x_stand + adypoly[9]*y_stand*y_stand*x_stand ; // System.out.println("coord "+x_obj+" " +y_obj); x_obj = x_obj *focale +xz; y_obj = y_obj *focale +yz; // System.out.println("coord "+x_obj+" " +y_obj); //PIERRE c.xf = (x_obj *1000.0 - Xorg)/incX; //PIERRE c.yf = (y_obj *1000.0 - Yorg)/incY ; c.x = (x_obj *1000.0 - Xorg)/incX; c.y = (y_obj *1000.0 - Yorg)/incY ; // System.out.println("coord "+c.x+" " +c.y); } else { al = c.al ; del = c.del ; if (equinox != 2000.0) { Astroframe j2000 = new Astroframe() ; Astroframe natif = new Astroframe(1,equinox) ; j2000.set(al,del) ; j2000.convert(natif) ; al = natif.getLon() ; del = natif.getLat() ; } if (system == 2) { Astroframe fk5 = new Astroframe() ; Astroframe natif = new Astroframe(2,equinox); fk5.set(al,del) ; fk5.convert(natif); al = natif.getLon() ; del = natif.getLat() ; // System.out.println(c.al+" "+c.del); } // System.out.println("c.al c.del "+c.al+" "+del); // Methode Header FITS WCS double ddel = (del-deltai)*deg_to_rad ; double cos_ddel = Math.cos(ddel) ; double dalpha = (al- alphai)*deg_to_rad; //System.out.println("dalpha "+ c.al +" " + alphai + " " + deg_to_rad ); double cos_del = Math.cos(del*deg_to_rad); double sin_del = Math.sin(del*deg_to_rad); double sin_dalpha = Math.sin(dalpha); double cos_dalpha = Math.cos(dalpha); // x_tet_phi = Math.cos(del*Math.PI/180.) // *Math.sin((al - alphai)*Math.PI/180.) ; x_tet_phi = cos_del *sin_dalpha ; // y_tet_phi = Math.sin(del*Math.PI/180.) // *Math.cos(deltai*Math.PI/180.) // - Math.cos(del*Math.PI/180.) // *Math.sin(deltai*Math.PI/180.) // *Math.cos((al - alphai)*Math.PI/180.); y_tet_phi = sin_del * cdelz - cos_del * sdelz * cos_dalpha ; switch(proj) { case 1: case 8 : // NCP case 2: // TAN proj if (cos_ddel == 0) return ; if (( cos_del * cos_dalpha / cos_ddel ) < 0) return ; break ; default : break ; } double phi ; double tet ; switch(proj) { case 1 : // SIN proj // x_stand = 180./Math.PI*x_tet_phi ; // y_stand = 180./Math.PI*y_tet_phi ; x_stand = rad_to_deg*x_tet_phi ; y_stand = rad_to_deg*y_tet_phi ; // if((al - alphai)>+180.) x_stand = -x_stand ; // if((al - alphai)<-180.) x_stand = -x_stand ; break ; case 8 : // NCP x_stand = rad_to_deg*x_tet_phi ; if (sdelz == 0) y_stand = rad_to_deg*y_tet_phi ; else y_stand = rad_to_deg*y_tet_phi + (cdelz/sdelz)*rad_to_deg *(1- Math.sqrt(1-cos_del*cos_del*sin_dalpha*sin_dalpha -sin_del*sin_del*cdelz*cdelz-cos_del*cos_del*sdelz*sdelz*cos_dalpha*cos_dalpha +2*sin_del*cos_del*sdelz*cdelz*cos_dalpha)); break ; case 2: // TAN proj // double den = Math.sin(del*Math.PI/180.) // *Math.sin(deltai*Math.PI/180.) + // Math.cos(del*Math.PI/180.) // *Math.cos(deltai*Math.PI/ 180.) ; double den = sin_del * sdelz + cos_del * cdelz *cos_dalpha; x_stand = x_tet_phi / den ; y_stand = y_tet_phi / den ; // x_stand *= 180./Math.PI ; // y_stand *= 180./Math.PI ; x_stand *= rad_to_deg; y_stand *= rad_to_deg; // System.out.println("proj 2\n"); break ; case 3: phi = Math.atan(-cos_del *sin_dalpha / (sin_del*cdelz- cos_del*sdelz *cos_dalpha)); if (sin_del*cdelz - cos_del*sdelz*cos_dalpha > 0) phi = Math.PI + phi ; tet = Math.asin ( sin_del*sdelz+ cos_del*cdelz *cos_dalpha); x_stand = (Math.PI/2 -tet)*Math.sin(phi) ; y_stand = -(Math.PI/2 -tet)*Math.cos(phi) ; x_stand *= rad_to_deg; y_stand *= rad_to_deg; // System.out.println("proj 2\n"); break ; case 4: // AIT proj // double ddel = (del-deltai)*Math.PI/180. ; // if (al > 180.) al -= 360. ; if (al > 180.) dalpha -= 2*Math.PI ; // double dalpha = (al- alphai)*Math.PI/180./2.; // double cos_ddel = Math.cos(ddel) ; double alph = Math.sqrt(2/(1+cos_ddel*Math.cos(dalpha/2.))); // System.out.println("alph "+alph); x_stand = 2*alph*cos_ddel*Math.sin(dalpha/2.) ; y_stand = alph*Math.sin(ddel) ; // System.out.println("xy "+x_stand+" "+y_stand+"\n"); // x_stand *= 180./Math.PI ; // y_stand *= 180./Math.PI ; x_stand *= rad_to_deg; y_stand *= rad_to_deg ; // System.out.println("xy "+x_stand+" "+y_stand+"\n"); if(dalpha/2. > Math.PI) x_stand = -x_stand ; // System.out.println("xy "+x_stand+" "+y_stand+"\n"); break ; case 5: // ZEA projection // phi = Math.atan(-Math.cos(del*Math.PI/180) // *Math.sin((al -alphai)*Math.PI/180) // / (Math.sin(del*Math.PI/180)*Math.cos(deltai*Math.PI/180)- // Math.cos(del*Math.PI/180)*Math.sin(deltai*Math.PI/180) // *Math.cos((al -alphai)*Math.PI/180))); phi = Math.atan(-cos_del *sin_dalpha / (sin_del*cdelz- cos_del*sdelz *cos_dalpha)); // System.out.println(" phi:"+180*phi/Math.PI+"\n") ; // if (Math.sin(del*Math.PI/180)*Math.cos(deltai*Math.PI/180) // - Math.cos(del*Math.PI/180)*Math.sin(deltai*Math.PI/180) // *Math.cos((al -alphai)*Math.PI/180) >0) if (sin_del*cdelz - cos_del*sdelz*cos_dalpha > 0) phi = Math.PI + phi ; // System.out.println(" phi:"+180*phi/Math.PI+"\n") ; tet = Math.asin ( // Math.sin(del*Math.PI/180)*Math.sin(deltai*Math.PI/180)+ // Math.cos(del*Math.PI/180)*Math.cos(deltai*Math.PI/180) // *Math.cos((al -alphai)*Math.PI/180)); sin_del*sdelz+ cos_del*cdelz *cos_dalpha); // double rtet = (180/Math.PI)*Math.sqrt(2*(1-Math.sin(tet))); double rtet = rad_to_deg*Math.sqrt(2*(1-Math.sin(tet))); // System.out.println(" tet:"+180*tet/Math.PI+"\n"); x_stand = rtet*Math.sin(phi) ; y_stand = - rtet*Math.cos(phi) ; // System.out.println(" xy_stand"+x_stand+" "+y_stand+"\n"); break ; case 6: // den = 1 + Math.sin(del*Math.PI/180.) // *Math.sin(deltai*Math.PI/180.) + // Math.cos(del*Math.PI/180.) // *Math.cos(deltai*Math.PI/ 180.) // *Math.cos((al - alphai)*Math.PI/180.) ; den = 1 + sin_del*sdelz + cos_del*cdelz*cos_dalpha; x_stand = 2*x_tet_phi / den ; y_stand = 2*y_tet_phi / den ; // x_stand *= 180./Math.PI ; // y_stand *= 180./Math.PI ; x_stand *= rad_to_deg ; y_stand *= rad_to_deg ; break ; case 7: // CARTESIEN // x_stand = -(al-alphai)*cos_del ; x_stand = al-alphai ; y_stand = del-deltai ; break ; default: // System.out.println("proj 3\n"); break ; } // System.out.println("ID "+x_stand+" "+ID[0][0]+" "+y_stand+" "+ID[0][1]+" "+Xcen); // System.out.println("ID "+x_stand+" "+ID[1][0]+" "+y_stand+" "+ID[1][1]+" "+Ycen); //PIERRE c.xf = (ID[0][0]*x_stand +ID[0][1]*y_stand)+ Xcen -1; //PIERRE c.yf = - (ID[1][0]*x_stand +ID[1][1]* y_stand) + ynpix - Ycen; c.x = (ID[0][0]*x_stand +ID[0][1]*y_stand)+ Xcen -1; c.y = - (ID[1][0]*x_stand +ID[1][1]* y_stand) + ynpix - Ycen; // System.out.println("c.xyf "+c.xf+" "+c.yf); // c.yf = - (ID[1][0]*x_stand +ID[1][1]* y_stand) + Ycen; } //PIERRE c.x = (int) (Math.round(c.xf)) ; //PIERRE c.y = (int) (Math.round(c.yf)) ; } protected double [] GetResol() { double inc[] = new double[2]; inc[0]= incA ; inc[0]= incD ; return inc; } protected void GetWCS_i() throws Exception { Coord a_d = new Coord() ; Coord x_y_1 = new Coord() ; Coord x_y_2 = new Coord() ; Coord x_y_3 = new Coord() ; Coord x_y_4 = new Coord() ; double alpha1,delta1 ; double alpha2,delta2 ; double alpha3,delta3 ; double alpha4,delta4 ; if(aladin == 1) // calcul du header WCS si l'image vient d'aladin { Xcen = xnpix/2. ; Ycen = ynpix/2. ; //PIERRE a_d.xf = Xcen ; //PIERRE a_d.yf = Ycen ; //PIERRE a_d.x = (int)Math.rint(a_d.xf) ; //PIERRE a_d.y = (int)Math.rint(a_d.yf) ; a_d.x = Xcen ; a_d.y = Ycen ; // System.out.println("XYcen "+a_d.xf+" "+a_d.yf); GetCoord(a_d) ; alphai = a_d.al ; deltai = a_d.del ; // System.out.println("XYcen "+Xcen+" "+Ycen); // System.out.println("alp delt"+alphai+" "+deltai); //PIERRE x_y_1.xf = Xcen - xnpix/4. ; //PIERRE x_y_1.yf = Ycen - ynpix/4. ; //PIERRE x_y_1.x = (int)Math.rint(x_y_1.xf) ; // System.out.println("x_y_1 "+x_y_1.xf+" "+x_y_1.yf); //PIERRE x_y_1.y = (int)Math.rint(x_y_1.yf) ; x_y_1.x = Xcen - xnpix/4. ; x_y_1.y = Ycen - ynpix/4. ; GetCoord(x_y_1); // System.out.println("alp delt"+alphai+" "+deltai); // System.out.println("alp delt"+x_y_1.al+" "+x_y_1.del); double cdelz1, sdelz1 ; cdelz1 = Math.cos((deltai/180.)*Math.PI); sdelz1 = Math.sin((deltai/180.)*Math.PI); // CD[0][0] = -(x_y_1.al*cdelz1+x_y_1.del)*2/xnpix; // CD[0][1] = -(x_y_1.al*cdelz1-x_y_1.del)*2/ynpix; double xst, yst,deno; deno = Math.sin(x_y_1.del*Math.PI/180.)*sdelz1 +Math.cos(x_y_1.del*Math.PI/180.)*cdelz1 *Math.cos((x_y_1.al-alphai)*Math.PI/180.) ; xst = Math.cos(x_y_1.del*Math.PI/180.) *Math.sin((x_y_1.al-alphai)*Math.PI/180.) / deno ; yst = Math.sin(x_y_1.del*Math.PI/180.)*cdelz1 -Math.cos(x_y_1.del*Math.PI/180.)*sdelz1 *Math.cos((x_y_1.al-alphai)*Math.PI/180.) / deno; CD[0][0] = -(ynpix*xst+xnpix*yst)*2/ynpix/xnpix; CD[0][1] = +(ynpix*xst-xnpix*yst)*2/xnpix/ynpix; //PIERRE x_y_2.xf = Xcen + xnpix/4. ; //PIERRE x_y_2.yf = Ycen - ynpix/4. ; //PIERRE x_y_2.x = (int) Math.rint(x_y_2.xf) ; //PIERRE x_y_2.y = (int)Math.rint(x_y_2.yf) ; x_y_2.x = Xcen + xnpix/4. ; x_y_2.y = Ycen - ynpix/4. ; // System.out.println("x_y_2 "+x_y_2.xf+" "+x_y_2.yf); GetCoord(x_y_2); // System.out.println("alp delt"+alphai+" "+deltai); // System.out.println("alp delt"+x_y_2.al+" "+x_y_2.del); // CD[0][0] -= (x_y_2.al*cdelz1-x_y_2.del)*2/xnpix; // CD[0][1] += (x_y_2.al*cdelz1+x_y_2.del)*2/ynpix; deno = Math.sin(x_y_2.del*Math.PI/180.)*sdelz1 +Math.cos(x_y_2.del*Math.PI/180.)*cdelz1 *Math.cos((x_y_2.al-alphai)*Math.PI/180.) ; xst = Math.cos(x_y_2.del*Math.PI/180.) *Math.sin((x_y_2.al-alphai)*Math.PI/180.) / deno ; yst = Math.sin(x_y_2.del*Math.PI/180.)*cdelz1 -Math.cos(x_y_2.del*Math.PI/180.)*sdelz1 *Math.cos((x_y_2.al-alphai)*Math.PI/180.) / deno; //System.out.println("stl "+xst+" "+yst+" "); CD[0][0] += (ynpix*xst-xnpix*yst)*2/ynpix/xnpix; CD[0][1] += (ynpix*xst+xnpix*yst)*2/xnpix/ynpix; //System.out.println("CD "+CD[0][0]+" "+CD[0][1]+" "); //PIERRE x_y_3.xf = Xcen - xnpix/4. ; //PIERRE x_y_3.yf = Ycen + ynpix/4. ; //PIERRE x_y_3.x = (int)Math.rint(x_y_3.xf) ; //PIERRE x_y_3.y = (int)Math.rint(x_y_3.yf) ; x_y_3.x = Xcen - xnpix/4. ; x_y_3.y = Ycen + ynpix/4. ; // System.out.println("x_y_3 "+x_y_3.xf+" "+x_y_3.yf); GetCoord(x_y_3); // System.out.println("alp delt"+x_y_3.al+" "+x_y_3.del); deno = Math.sin(x_y_3.del*Math.PI/180.)*sdelz1 +Math.cos(x_y_3.del*Math.PI/180.)*cdelz1 *Math.cos((x_y_3.al-alphai)*Math.PI/180.) ; xst = Math.cos(x_y_3.del*Math.PI/180.) *Math.sin((x_y_3.al-alphai)*Math.PI/180.) / deno ; yst = Math.sin(x_y_3.del*Math.PI/180.)*cdelz1 -Math.cos(x_y_3.del*Math.PI/180.)*sdelz1 *Math.cos((x_y_3.al-alphai)*Math.PI/180.) / deno; // CD[0][0] += (x_y_3.al*cdelz1-x_y_3.del)*2/xnpix; // CD[0][1] -= (x_y_3.al*cdelz1+x_y_3.del)*2/ynpix; CD[0][0] -= (ynpix*xst-xnpix*yst)*2/ynpix/xnpix; CD[0][1] -= (xst*ynpix+yst*xnpix)*2/xnpix/ynpix; //PIERRE x_y_4.xf = Xcen + xnpix/4. ; //PIERRE x_y_4.yf = Ycen + ynpix/4. ; //PIERRE x_y_4.x = (int)Math.rint(x_y_4.xf) ; //PIERRE x_y_4.y = (int) Math.rint(x_y_4.yf) ; x_y_4.x = Xcen + xnpix/4. ; x_y_4.y = Ycen + ynpix/4. ; GetCoord(x_y_4); // System.out.println("x_y_4 "+x_y_4.xf+" "+x_y_4.yf); // System.out.println("alp delt"+x_y_4.al+" "+x_y_4.del); // CD[0][0] += (x_y_4.al*cdelz1+x_y_4.del)*2/xnpix; // CD[0][1] -= (x_y_4.al*cdelz1-x_y_4.del)*2/ynpix; deno = Math.sin(x_y_4.del*Math.PI/180.)*sdelz1 +Math.cos(x_y_4.del*Math.PI/180.)*cdelz1 *Math.cos((x_y_4.al-alphai)*Math.PI/180.) ; xst = Math.cos(x_y_4.del*Math.PI/180.) *Math.sin((x_y_4.al-alphai)*Math.PI/180.) / deno ; yst = Math.sin(x_y_4.del*Math.PI/180.)*cdelz1 -Math.cos(x_y_4.del*Math.PI/180.)*sdelz1 *Math.cos((x_y_4.al-alphai)*Math.PI/180.) / deno; CD[0][0] += (ynpix*xst+xnpix*yst)*2/ynpix/xnpix; CD[0][1] -= (xst*ynpix-yst*xnpix)*2/xnpix/ynpix; CD[0][0] *= 180./Math.PI/4. ; CD[0][1] *= 180./Math.PI/4. ; CD[1][0] = CD[0][1] ; CD[1][1] = -CD[0][0] ; equinox = 2000.0 ; proj = 2 ; //System.out.println("CD "+CD[0][0]+" "+CD[0][1]+" "); } } protected void GetWCS(Vector key, Vector value) throws Exception { GetWCS_i() ; // ce qui suitvest fait dans les deux cas, simple recopie // dans le cas aladin == 0 key.addElement( "NAXIS1 "); value.addElement(new Integer(xnpix).toString()); key.addElement( "NAXIS2 "); value.addElement(new Integer(ynpix).toString()); key.addElement("CRPIX1 "); value.addElement(new Double(Xcen).toString()); key.addElement("CRPIX2 "); value.addElement(new Double(Ycen).toString()); key.addElement("EQUINOX"); value.addElement(new Double(equinox).toString()); key.addElement("CRVAL1 "); value.addElement(new Double(alphai).toString()); key.addElement("CRVAL2 "); value.addElement(new Double(deltai).toString()); key.addElement("CTYPE1 "); if (aladin == 1) value.addElement("'RA---TAN'"); else value.addElement(type1); key.addElement("CTYPE2 "); if (aladin == 1) value.addElement("'DEC--TAN'"); else value.addElement(type2); key.addElement("CD1_1 "); value.addElement(new Double(CD[0][0]).toString()); key.addElement("CD1_2 "); value.addElement(new Double(CD[0][1]).toString()); key.addElement("CD2_1 "); value.addElement(new Double(CD[1][0]).toString()); key.addElement("CD2_2 "); value.addElement(new Double(CD[1][1]).toString()); } protected void SetEquinox(double equin) { equinox = equin ; } protected double GetEquinox() { /* Equinox =0 : absence d'equinoxe */ return equinox ; } protected double GetEpoch() { /* Epoch =0 : absence d'epoque */ if (flagepoc != 0) return epoch ; else return 0.0 ; } /* * Retourne le centre de l'image en coord J2000 et en pixels */ protected Coord getImgCenter() throws Exception { Coord c = new Coord(); c.x = xnpix/2; c.y = ynpix/2; GetCoord(c); return c; } /* * Retourne le centre de la projection en coord J2000 et en pixels */ protected Coord getProjCenter() throws Exception { Coord c = new Coord(); c.x = Xcen; c.y = Ycen; GetCoord(c); return c; } /* * Retourne la rotation de la projection par rapport au NORD dans * le sens ???? (unite : le degre) */ protected double getProjRot() { return rota; } /* * Retourne la largeur du champ en degres */ protected double getImgWidth() { return widtha; } /* * Retourne la largeur du champ en degres */ protected double getImgHeight() { return widthd; } /* * Retourne true si les RA sont inverses */ protected boolean getProjSym() { return incA>0; } /* * Retourne Le type de projection (indice du tableau projection) */ protected int getProjSys() { return proj-1; } /* * Retourne La dimension en pixels de l'image */ protected Dimension getImgSize() { return new Dimension(xnpix,ynpix); } void cropping(int w,int h) { int offx = xnpix -w; int offy = ynpix -h; offx /= 2 ; offy /= 2 ; if( aladin == 0) { Xcen -= offx ; Ycen -= offy ; } else { Xorg += offx *incX ; Yorg += offy *incY ; } xnpix = w ; ynpix = h ; widtha = xnpix * Math.abs(incA) ; widthd = ynpix * Math.abs(incD) ; } static String[] getProj() { return projection ; } } = Ycen - ynpix/4. ; //PIERRE x_y_1.x = (int)Math.rint(x_y_1.xf) ; // System.out.println("x_y_1 "+x_y_1.xf+" "+xcds/aladin/Calque.java010064400076440000132000000771500770227416100156370ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Objet de gestion des plans et de tout ce qui est associe * * @@author Pierre Fernique [CDS] * @@version 1.1 : (15 janvier 2000) Clien d'oeil on/off * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.91 : Revisite le 1 dec 98 * @@version 0.9 : (??) creation */ public final class Calque extends Panel { // les variables generiques // static final String NOPLACE = "No place on the top of the plane stack"; int FIRSTBLOC = 14; int BLOC = 7; // Les references aux objets Aladin aladin; View view; // Les composantes de l'objet Select select; // Le selecteur de manipulation des plans Zoom zoom; // Le zoom Plan plan []; // les plans int maxPlan=0; // Nombre total de plan actuellement alloue // Les valeurs a memoriser int current; // Le plan courant int runme_n= -1; MyScrollbar scroll; // La scrollbar verticale si necessaire protected boolean flagReticle;// True si le reticule doit etre affiche protected boolean flagScale; // True si l'echelle doit etre affichee protected boolean flagGrid; // True si la grille doit etre affichee protected Vector Fovs = new Vector(); // les FOV protected Fov[] curFov; // champ pour l'objet courant protected Fov cutoutFov = null; // champ pour cutout /** Creation de l'objet calque */ protected Calque(Aladin aladin) { this.aladin = aladin; select = new Select(this,aladin); zoom = new Zoom(this,aladin); scroll = new MyScrollbar(Scrollbar.VERTICAL,FIRSTBLOC-1,1,0,FIRSTBLOC); // Creation des composantes de l'objet (plan, select et zoom) reallocPlan(); flagReticle = flagScale = true; flagGrid = false; // Panel principal : contient le selecteur de plans et le zoom setLayout( new BorderLayout(0,0) ); add("Center",select); add("East",scroll); add("South",zoom); resize( preferredSize()); } /** Retourne les plans d'un folder * @@param f le plan (de type FOLDER) * @@return le tableau des plans contenus dans le folder f */ protected Plan[] getFolderPlan(Plan f) { if( f.type!=Plan.FOLDER ) return null; Vector v = new Vector(10); int n = f.folder; // niveau du folder int i; boolean trouve=false; for( i=0; i=aladin.calque.plan.length-1) return false; return aladin.calque.plan[i+1].collapse; } // Allocation ou reallocation des plans synchronized private void reallocPlan() { int n; int bloc=maxPlan>0?BLOC:FIRSTBLOC; // Allocation d'une nouvelle tranche de plans Plan newP[] = new Plan[maxPlan+bloc]; //Recopie avec decalage if( maxPlan>0 ) { System.arraycopy(plan,0,newP,bloc,maxPlan); newP[0] = plan[0]; n=scroll.getValue()-bloc+1; } else { n=bloc; } // Initialisation du nouveau bloc de plans for( int i=0; itrue si le plan decrit n'est pas deja, sinon false */ protected boolean dejaCharge(int type,String objet,String param) { return dejaCharge(type,objet,param,null); } protected boolean dejaCharge(int type,String objet,String param,String other) { for( int i=0; i=0; i-- ) { if( plan[i].selected ) { if( plan[i].type==Plan.FOLDER ) { Plan p[] = getFolderPlan(plan[i]); for( j=0; j1; j-- ) { plan[j]=plan[j-1]; } i++; plan[1]=ptmp; } } } // Je repositionne un plan courant par defaut s'il y en a encore un if( lastcurrent>=0 ) { for( i=lastcurrent; i Reaffichage du target * --> Modification des libelles des reperes */ protected void changeFrame() { // Reaffichage du target dans le bon frame aladin.target.repaint(); // Modification des libelles de reperes boolean flagRepaint = false; // Vrai si la vue doit etre reaffichee for( int i=0; itrue si ca a marche, sinon false */ protected boolean setPlanRef(Plan p) { for( int i=0; itrue si ca a marche, sinon false */ protected boolean setPlanRef(int n) { if( plan[n].ref ) return false; // deja fait, inutile // Seuls les plans images et catalogues peuvent etre de reference if( canBeRef(n) ) { // On memorise les parametres du zoom dans le plan de reference // et on supprime le flag du precedent plan de refence for( int i=0; inull si aucun */ protected Plan getPlanRef() { int n = getIndexPlanRef(); return (n<0)?null:plan[n]; } /** Retourne l'index plan de reference * @@return le numero du plan de ref ou -1 si aucun */ protected int getIndexPlanRef() { for( int i=0; inull si aucun */ protected Plan getPlanBase() { int n = getIndexPlanBase(); return (n<0)?null:plan[n]; } /** Retourne l'index plan de base (plan ref si image et actif) * @@return le numero du plan de base ou -1 si aucun */ protected int getIndexPlanBase() { int i = getIndexPlanRef(); if( i==-1 || plan[i].type!=Plan.IMAGE || !plan[i].active ) return -1; return i; } /** Recalcul les plans FoV en fonction de leur centre en x,y,al,del * Necessaire apres une translation par la souris */ protected void resetPlanField() { for( int i=0; iplan.length || i<=0 || i-1==n ) return; select.permute(plan[n],plan[i-1]); //On permute les plans pour prendre en compte le folder } /** Enregistre une image ARCHIVE dans le prochain plan libre. * @@param u l'URL qu'il va falloir appeler * @@param label le nom du plan (dans la pile des plans) * @@param objet le target (objet) demande * @@param orig L'origine du plan (copyright, provider...) * @@param survey Le survey d'origine * @@param o La source associee a l'image d'archive protected int newPlanImage(URL u,String label,String objet,String orig, String survey,Objet o) { int n=getFirstFree(); if( n<0 ) return -1; plan[n] = new PlanImage(aladin,u,label,objet,survey,o); // Positionnement de l'origine plan[n].setFrom(orig); bestPlace(n); suiteNew(); return n; } */ /** Enregistre une image LOCALE dans le prochain plan libre. * @@param file Le nom du fichier .fits, .fits.h ou .fits.gz * @@param autocut True s'il faut activer l'autocut de l'histogramme des couleurs */ protected int newPlanImage(String file,MyInputStream inImg, boolean autocut) { int n=getFirstFree(); if( n<0 ) return -1; plan[n] = new PlanImage(aladin,file,inImg,autocut); bestPlace(n); suiteNew(); return n; } /** le prochain plan libre devient un plan objet graphique. * @@param label le nom du plan (dans la pile des plans) */ protected int newPlanTool(String label) { int n=getFirstFree(); if( n<0 ) return -1; plan[n] = new PlanTool(aladin,label); suiteNew(); return n; } protected int newPlanFov(String label, Fov[] fov) { int n=getFirstFree(); if( n<0 ) return -1; plan[n] = new PlanFov(aladin,label,fov); suiteNew(); return n; } /** le prochain plan devient un plan contenant les contours * @@param label - nom du plan * @@param levels - tableau des niveaux * @@param cAlgo - algorithme de contour utilise * @@param useSmoothing - utilisation du lissage ? * @@param useOnlyCurrentZoom - calcul sur la vue courante uniquement ? * @@param indiceCouleurs - tableau des indices dans Couleur.DC des couleurs de chaque niveau */ protected int newPlanContour(String label, double[] levels, ContourAlgorithm cAlgo, boolean useSmoothing, int smoothingLevel, boolean useOnlyCurrentZoom, boolean reduceNoise, Color[] couleurs) { int n=getFirstFree(); if( n<0 ) return -1; if (levels == null) plan[n] = new PlanContour(aladin,label); else { Color coul = PlanContour.getNextColor(aladin.calque); plan[n] = new PlanContour(aladin,label, levels, cAlgo, useSmoothing, smoothingLevel, useOnlyCurrentZoom, reduceNoise, couleurs, coul); } bestPlace(n); suiteNew(); return n; } /** le prochain plan libre devient un plan de champ de vue. * @@param target Nm de l'objet ou coordonnees * @@param roll Angle de rotation par rapport au nord * @@param instr le nom du plan et de l'instrument */ protected int newPlanField(String target,double roll,String instr) { int n=getFirstFree(); if( n<0 ) return -1; plan[n] = new PlanField(aladin,target,roll,instr,instr); // Truc tordu pour qu'il y ait une demande de resolution Simbad // Rq: pb du cache Simbad... if( !plan[n].flagOk && plan[n].objet!=null ) aladin.view.setRepere(plan[n]); // view.repaint(); suiteNew(); return n; } /** Positionnement du centre des plans FoV en attente de resolution * Simbad. Ces plans ont leur flagOk a false. */ protected void setCenterForField(double al,double del) { int i; for( i=0; itrue si au moins un plan, sinon false */ protected boolean noSelected() { for( int i=0; i-1 si aucun */ protected int getFirstSelected() { for( int i=0; i-1 si aucun */ protected int getFirstFree() { int i; for( i=0; i calcul (x,y) et (xBord,yBord). * @@param proj la projection a utiliser */ protected void projection(Projection proj) { super.projection(proj); if( methode!=CERCLE ) return; c.al = raBord; c.del = deBord; proj.getXY(c); xBord = (int)Math.round(c.x); yBord = (int)Math.round(c.y); } protected void setCoord() { super.setCoord(); // Mise a jour des coordonnees du point du bord raBord=raj; deBord=dej+rd; } /** Modification de la position (relative) * @@param dx,dy decalages */ protected void deltaPosition(double dx, double dy) { if( methode==SIMPLE ) { super.deltaPosition(dx,dy); return; } x += dx; xBord+=dx; y += dy; yBord+=dy; oiz=-1; setCoord(); } /** Generation d'un clip englobant. * Retourne un rectangle qui englobe l'objet * @@param zoomview reference au zoom courant * @@return le rectangle enblobant */ protected Rectangle getClip(ZoomView zoomview) { int rayon = (methode==SIMPLE)?L/2:vp.y-vpBord.y; if( vp==null ) { vp = zoomview.getViewCoord(x,y); } return new Rectangle(vp.x-rayon,vp.y-rayon,rayon*2,rayon*2); } /** Affiche le repere * @@param g le contexte graphique * @@param zoomview reference au zoom courant */ protected void draw(Graphics g,ZoomView zoomView,int dx, int dy) { // On se fait un getViewCoord a sa sauce if( zoomView.iz!=oiz ) { vp = zoomView.getViewCoord(x,y); if( methode==CERCLE ) { vpBord = zoomView.getViewCoord(xBord,yBord); } oiz = zoomView.iz; } vp.x+=dx; vp.y+=dy; if( plan!=null ) g.setColor( plan.c ); g.drawLine(vp.x-L, vp.y, vp.x+L, vp.y); g.drawLine(vp.x, vp.y-L, vp.x, vp.y+L); int rayon = (methode==SIMPLE)?L/2:vp.y-vpBord.y; g.drawOval( vp.x-rayon,vp.y-rayon,rayon*2,rayon*2); if( withlabel ) g.drawString(id,vp.x-dw/2,vp.y-L-1); if( select ) drawSelect(g,zoomView); } } cds/aladin/ColorMap.java010064400076440000132000000453730770227416100161430ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion du graphique de la dynamique d'une image * * @@author Pierre Fernique [CDS] * @@author Anais Oberto [CDS] * @@version 1.3 : (15 mars 2002) petite modif pour l'histogramme Chandra * @@version 1.2 : (dec 2001) incorporation image RGB * @@version 1.1 : (15 juin 2000) Recuperation memoire libre * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class ColorMap extends Canvas implements Runnable{ // Les constantes representants les 3 triangles de controles static final int MIN = 0; // Seuil minimal static final int MIL = 1; // Seuil moyen static final int MAX = 2; // Seuil maximal static final int NO = 3; // Aucun seuil // Les constantes d'affichage static final int mX = 10; // Marge en abscisse static final int mY = 10; // Marge en ordonnee static final int Hp = 150; // Hauteur du graphique static final int W = 256+2*mX; // Largeur totale du graphique static final int H = Hp+mY+25; // Hauteur totale du graphique // Ordonnees (cas normal ou cas Inverse) de la courbe de // reponse des gris static final int Y[] = {mY+Hp,mY+Hp,mY+Hp/2,mY+1, mY+1 }; static final int Yr[] = {mY+1, mY+1, mY+Hp/2,mY+Hp,mY+Hp}; // les references PlanImage pimg; // le plan image concerne byte [] pixels; // Les pixels de l'image courante /* anais */ int [] pixelsRGB; // Les pixels de l'image colorisee courante int width; // La largeur " int height; // La hauteur " // Les valeurs a memoriser double [] hist; // histogramme courant de la repartition des couleurs int currentTriangle=NO; // Le triangle en cours de selection int [] triangle = new int[3]; // Positions courantes des 3 triangles Image img=null; // Image du double buffer contenant l'histogramme boolean flagDrag = false; // True si on drague boolean flagKey = false; // true si on doit remettre a jour toute la vue suite a deplacement avec fleches Thread thread = null; // thread pour la maj de l'image apres modif de la CM avec les fleches /* anais */ int COLOR = -1; // couleur, utilise pour le PlanImageRGB // 0: rouge, 1: vert, 2: bleu /** Creation du graphique de la table de reponse des gris * @@param pimg le Planimage associe */ protected ColorMap(PlanImage pimg, /*anais*/int color) { double max=0; // Maximum de l'histogramme pour un changt d'echelle int i; this.pimg = pimg; /* anais */ if( pimg instanceof PlanImageRGB ) { if( color==0 ) this.pixels = ((PlanImageRGB)pimg).red; else if( color==1 ) this.pixels = ((PlanImageRGB)pimg).green; else if( color==2 ) this.pixels = ((PlanImageRGB)pimg).blue; // Positionnement des triangles for( i=0; i<3; i++ ) triangle[i]=((PlanImageRGB)pimg).RGBControl[color*3+i]; } else { this.pixels = pimg.pixels; // Positionnement des triangles for( i=0; i<3; i++ ) triangle[i]=pimg.cmControl[i]; } this.width = pimg.width; this.height = pimg.height; /*anais*/ COLOR=color; // Calcul de la repartition des couleurs hist = new double[256]; double maxBidon=0; // Pour Chandra qui traine des stupides bords for( i=0; imaxBidon ) maxBidon=c; else if( c>max ) max=c; } // passage au log max = Math.log(max+1); for( i=0; i0 && hist[i]==0)?hist[i-1]:Math.log( hist[i]+1 ); } // Mise a l'echelle de l'histogramme max+=max/5; for( i=0; i0.0 ) { double alpha = dy/dx; double beta = -alpha*tr0; for( i=tr0, n=tr1; i0.0 ) { double alpha = dy/dx; double beta = 128.0-alpha*tr1; for( i=tr1, n=tr2; i255 ) rd=255; gn = (j-64)<<1; if( gn<0 ) gn=0; else if( gn>255 ) gn=255; bl = (j-128)<<1; if( bl<0 ) bl=0; r[i]=(byte)rd; g[i]=(byte)gn; b[i]=(byte)bl; } // S'il s'agit d'une table des couleurs A } else if( typeCM == PlanImage.CMA ) { for( i=0; i<256; i++ ) { j=(int)r[i] & 0xFF; rd = (j<64)?0:(j<128)?(j-64)<<2:255; gn = (j<64)?j<<2:(j<128)?255-((j-64)<<2):(j<192)?0:(j-192)<<2; bl = (j<32)?0:(j<128)?((j-32)<<3)/3:(j<192)?255-((j-128)<<2):0; r[i]=(byte)rd; g[i]=(byte)gn; b[i]=(byte)bl; } // Table des 3 couleurs } else { for( i=0; i<256; i++ ) g[i] = b[i] = r[i]; } return new IndexColorModel(8,256,r,g,b); } public Dimension preferredSize() { return new Dimension(W,H); } public Dimension getPreferredSize() { return preferredSize(); } /** Dessin d'un triangle. * @@param g le contexte graphique * @@param x l'abcisse du triangle a dessinner */ protected void drawTriangle(Graphics g,int x) { int [] tx = new int[4]; int [] ty = new int[4]; tx[0] = tx[3] = x+mX; tx[1] = tx[0]-7; tx[2] = tx[0]+7; ty[0] = ty[3] = Hp+4+mY; ty[1] = ty[2] = ty[0]+10; g.setColor( Color.black ); g.fillPolygon(tx,ty,tx.length); g.setFont( Aladin.SPLAIN ); g.drawString(""+x,mX+x-7,mY+Hp+24); } /** Ajustement des valeurs des triangles pour concerver un ordre coherent MIN<=MIL<=MAX */ protected void ajustTriangle() { int i; for( i=0; i<2; i++ ) { if( triangle[i]>triangle[i+1] ) triangle[i+1]=triangle[i]; } for( i=2; i>0; i-- ) { if( triangle[i]-1 ) { // On applique le filtre sur toute l'image pimg.aladin.view.setFilter(triangle,COLOR); pimg.aladin.calque.zoom.zoomView.repaint(); } else { IndexColorModel ic = getCM(); pimg.setCM(ic); pimg.aladin.calque.zoom.zoomView.setCM(ic); } repaint(); System.gc(); System.runFinalization(); } return true; } // thomas /** Traitement de l'evt appui sur une touche (pour ajuster la colormap au clavier) */ public boolean keyDown(Event e,int key) { flagKey=false; if(currentTriangle == NO) return true; if (key == Event.RIGHT) { if(triangle[currentTriangle]<255) triangle[currentTriangle]++; } else if (key == Event.LEFT) { if(triangle[currentTriangle]>0) triangle[currentTriangle]--; } ajustTriangle(); flagDrag=true; repaint(); // S'il s'agit d'un des histogrammes couleurs if (COLOR>-1) { // On applique le filtre sur une zone de l'image pimg.aladin.view.setDynamicFilter(triangle,COLOR); } else pimg.newCM(getCM()); repaint(); flagKey=true; if( thread!=null ) thread.stop(); thread = new Thread(this); thread.setPriority( Thread.NORM_PRIORITY -1); thread.start(); return true; } //thomas /** Reperage du triangle le plus proche du clic souris */ public boolean mouseMove(Event e,int x,int y) { if( ymY+Hp+15 ) return true; x-=mX; // on demande a avoir le focus pour les evts clavier requestFocus(); // Reperage du triangle le plus proche for( int i=0; i<3; i++ ) { if( x>triangle[i]-7 && xmY+Hp+15 ) return true; x-=mX; // Reperage du triangle le plus proche for( int i=0; i<3; i++ ) { if( x>triangle[i]-7 && x255 ) x=255; triangle[currentTriangle] = x; ajustTriangle(); flagDrag=true; if( !e.shiftDown() ) { // S'il s'agit d'un des histogrammes couleurs if (COLOR>-1) { // On applique le filtre sur une zone de l'image pimg.aladin.view.setDynamicFilter(triangle,COLOR); } else pimg.newCM(getCM()); } repaint(); return true; } /** Fin de deplacement du triangle precedemment selectionne */ public boolean mouseUp(Event e,int x, int y) { if( currentTriangle==NO ) return true; x-=mX; if( x<0 ) x=0; else if( x>255 ) x=255; triangle[currentTriangle] = x; ajustTriangle(); flagDrag=false; repaint(); /* anais */ // S'il s'agit d'un des histogrammes couleurs if( COLOR>-1 ) { // On applique le filtre sur toute l'image pimg.aladin.view.setFilter(triangle,COLOR); pimg.aladin.calque.zoom.zoomView.repaint(); } else { IndexColorModel ic = getCM(); pimg.setCM(ic); pimg.aladin.calque.zoom.zoomView.setCM(ic); } System.gc(); System.runFinalization(); return true; } public void update(Graphics gr) { Graphics g; int i; if( flagDrag ) { paint(gr); return; } if( img==null ) img = createImage(256,Hp); g=img.getGraphics(); g.setColor( Color.white ); g.fillRect(0,0,256,Hp); /* anais */ // S'il s'agit d'un des histogrammes couleurs // on affecte une couleur correspondante if( COLOR>-1 ) { // Dans le cas de la video inverse, on inverse la couleur des histogrammes if( pimg.video==PlanImage.VIDEO_INVERSE ) { // !((PlanImageRGB)pimg).twoColors) { g.setColor( (COLOR==0)?Color.cyan: ( (COLOR==1)?Color.magenta: Color.yellow ) ); } else { // sauf dans le cas de 2 couleurs g.setColor( (COLOR==0)?Color.red: ( (COLOR==1)?Color.green: Color.blue ) ); } } else { g.setColor( Color.blue ); } for( i=0; i<256; i++ ) g.drawLine( i,Hp, i,(int)(Hp-hist[i]) ); /* anais */ g.setColor( Color.black ); if( pimg instanceof PlanImageRGB ) g.drawString(((PlanImageRGB)pimg).labels[COLOR],100,20); /* ??? else : Met-on le label lors qu'il n'y a qu'1 seul histo ? g.drawString(pimg.label,100,20); */ g.drawRect(0,0,256,Hp); g.dispose(); paint(gr); } public void run() { try {thread.sleep(1000);} catch(Exception e) {} if(flagKey) { //ajustTriangle(); flagDrag=false; flagKey=false; // anais // S'il s'agit d'un des histogrammes couleurs if( COLOR>-1 ) { // On applique le filtre sur toute l'image pimg.aladin.view.setFilter(triangle,COLOR); pimg.aladin.calque.zoom.zoomView.repaint(); } else { IndexColorModel ic = getCM(); pimg.setCM(ic); pimg.aladin.calque.zoom.zoomView.setCM(ic); } System.gc(); System.runFinalization(); } } public void paint(Graphics g) { int i; if( img==null ) { update(g); return; } g.drawImage(img,mX,mY,null); gris(g); g.clearRect(0,mY+Hp,W,mY+Hp+20); for( i=0; i<3; i++ ) drawTriangle(g,triangle[i]); } } r[i] = (byte)(p); } } // Deuxieme segment de droite pour la 2eme moitie de la dynamique dx = (double)(tr2-tr1); if( dx>0.0 ) { double alpha = dy/dx; double beta = 128.0-alpha*tr1; cds/aladin/Command.java010064400076440000132000001152420770227416100157760ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.net.*; import java.io.*; import java.util.*; import java.awt.image.*; /** * Gestion de commandes en ligne d'Aladin java * * @@version 1.5 (16 aout 2002) ajout command draw * @@version 1.4 (24 juin 2002) ajout command flipflop * @@version 1.3 (17 mai 2002) separateur ":" toleres dans commande get * @@version 1.2 (22 fevrier 2002) Ajout de la commande RGB * @@version 1.1 (12 fevrier 2001) Ajout d'un time out sur la synchro * @@version 1.0 (5 fevrier 2001) Creation * @@author P.Fernique [CDS] */ public final class Command extends Thread { static final long TIMEOUT = (long)15; // 15 minutes de chien de garde // pour la commande "sync" static long timeout = TIMEOUT*60000; // Gestion du systeme de coordonnees pour la commande "draw" static int DRAWXY = 0; static int DRAWRADEC = 1; static int drawMode = DRAWXY; // mode de coord courant Aladin a; Calque c; boolean filterMode = false; // vrai si on est en mode "definition de filtre" StringBuffer filterDef = null; // objet contenant la def. du filtre PlanImage planRGBRef; // Particulartie puor traiter la commande RGB static final String execHelp = " get servers [target] [radiusUnit] - call image/data servers\n"+ " (ex: \"get aladin,VizieR(GSC2,USNO2) M99 4'\")\n"+ " load file - load the file (image, data or script)\n"+ " save file - save the current view (fits format, after sync.)\n"+ " export nn file - export the plane number nn (after sync.)\n"+ " backup file - generate a backup of the Aladin plane stack (after sync.)\n"+ " zoom fct - change zoom factor on the current view (1/2x, 4x...)\n"+ " reverse [on/off]- (un)reverse the current view\n"+ " flipflop [V|H] - Vertical (resp. horizontal) pixel image inversion\n"+ " cm {gray|BB|A} - select the current colormap\n"+ " select nn - select the plane nn (the bottom plane has number 1)\n"+ " hide [nn] - hide a plane (the selected plane or the plane number nn)\n"+ " show [nn] - show a plane (the selected plane or the plane number nn)\n"+ " RGB [n1 n2 [n3|diff]] - create a RGB image from plane number n1, n2 [,n3]\n"+ " a \"*\" after a plane number specifies the ref plane\n"+ " filter [name] {on|off} - switch on/off the specified filter\n"+ " free [nn] - free a plane (the selected plane or the plane number nn)\n"+ " ref nn - set the plane nn as the reference plane\n"+ " reset - reset the Aladin plane stack\n"+ " grid [on/off] - (un)activate the coordinate grid\n"+ " reticle [on/off]- (un)activate the reticle\n"+ " scale [on/off] - (un)activate the scale line\n"+ " draw fct(param) - draw graphical overlays (string(x,y,\"msg\")...)\n"+ " status - display stack plane status\n"+ " info msg - print a message in the status window\n"+ " help - display this help\n"+ " pause [nn] - wait nn secondes, 1 by default\n"+ " contour [ nn [nosmooth] [zoom] ] - draw nn isocontours on the\n"+ " selected plane (default: 4 levels)\n"+ " sync - wait until all planes are ready\n"+ " timeout nn|off - set nn minutes as timeout - 15 by default\n"+ " mem - display the java memory used (after a garbage collector)\n"+ " quit - stop Aladin"; /** Creation d'un module de commande. * @@param aladin la reference habituelle */ Command(Aladin aladin) { a=aladin; } /** Lance la lecture asynchrone du standard input */ protected void readStandardInput() { start(); } private InputStream stream=System.in; Stack stackStream = new Stack(); synchronized void setStream(InputStream in ) { System.out.println("setStream("+(in==null?"null":in+"")+")"); if( in==null ) in=(InputStream)(stackStream.empty()?System.in:stackStream.pop()); else stackStream.push(in); stream=in; } /** Lance la lecture asynchrone du standard input */ protected void readFromStream(InputStream in) { setStream(in); } /** Module de controle des commandes asynchrones. * Il s'agit d'un thread qui lit l'entree standard et execute * les commandes qu'il recoit. */ public void run() { a.waitDialog(); System.out.println("The script module is listening...\n"+ " (more info by typing \"help\" at the Aladin prompt)..."); scriptFromInputStream(); } // Procedure un peu tordue pour lire une ligne private String readLine() { StringBuffer s = new StringBuffer(); int b=0; try { do { if( stream==System.in && stream.available()==0 ) { sleep(1000); continue; } b=stream.read(); if( stream!=System.in && b==-1 ) { setStream(null); continue; } s.append((char)b); } while( b!=10 ); } catch( Exception e ) { System.err.println("Pb "+e); return null; // Indispensable sous JVM 1.4 // en cas de lancement par javaw.exe } return s.toString(); } /** Lecture d'un script * @@param in InputStream */ protected void scriptFromInputStream() { String s=null; int i; boolean prompt=(stream==System.in); if( prompt ) System.out.print("Aladin> "); while(true) { s = readLine(); if( s==null ) return; if( s.trim().length()!=0 ) { // thomas : quand on definit un filtre, les lignes de commentaires ne sont pas skippees if( s.charAt(0)=='#' && !filterMode ) continue; try { execScript(s); } catch( Exception e ) { System.out.println("Error: "+e); e.printStackTrace(); } } if( prompt ) { if(filterMode) System.out.print("Aladin - Filter def.> "); else System.out.print("Aladin> "); } } } /** Retourne l'indice du plan en fonction de son numero * dans la pile (1 etant celui tout en bas). * @@param s la chaine qui doit contenir le numero * @@return n l'indice du plan */ private int getNumber(String s ) { int n=0; try{ n = Integer.parseInt(s); } catch(Exception e) {} if( n<1 || n>a.calque.plan.length ) { System.out.println("Plane number error !"); return -1; } n=Aladin.MAXPLANS-n; return n; } // retourne le plan correspondant au parametre (numero du plan eventuellement // suivi d'une etoile pour indiquer qu'il s'agit du plan de reference // pour le sampling // Si le plan ne peut etre utilise ou est a "-", retourne null private PlanImage getRGBPlan(String s) { boolean flagRef=false; // Pas de plan indique pour cette composatne if( s.charAt(0)=='-' ) return null; // Si suivi de * il s'agit du plan de reference pour le sampling if( s.charAt(s.length()-1)=='*' ) { s = s.substring(0,s.length()-1); flagRef=true; } int n=getNumber(s); if( n<0 || a.calque.plan[n].type!=Plan.IMAGE || a.calque.plan[n] instanceof PlanImageRGB ) return null; PlanImage p = (PlanImage)a.calque.plan[n]; if( !p.flagOk || p.error!=null ) return null; if( flagRef ) planRGBRef = p; return p; } /** Retourne vrai si tous les plans sont flagOk et que l'acces * au serveur aladin n'est pas en cours de recherche d'un qualifier */ private boolean isSync() { if( a.dialog==null || a.calque==null || a.calque.plan[0]==null ) return false; if( !((AladinServer)a.dialog.server[ServerDialog.ALADIN]).isSync() ) { return false; } for( int i=0; i0 && System.currentTimeMillis()-d>timeout ) { System.out.println("!!! Time out error ("+(timeout/60000)+" minutes)."); return; } try { sleep(500); } catch(Exception e) {} } } /** Affichage du status de plans */ private void status() { for( int i=0; i0 && a[i]!=' '; i--); if( i==0 ) return false; String s = new String(a,i+1,a.length-i-1); if( s.endsWith("'") ) s = s.substring(0,s.length()-1)+"m"; else if( s.endsWith("\"") ) s = s.substring(0,s.length()-1)+"s"; if( !( s.endsWith("arcmin") || s.endsWith("sec") || s.endsWith("deg") || s.endsWith("m") || s.endsWith("s") || s.endsWith("d")) ) return false; radius.append(""+Server.getRadius(s)); tX.append( new String(a,0,i)); return true; } /** Decoupage des champs d'une commande "get [serveur...] target [radius]" */ private boolean splitGetCmd(StringBuffer servers, StringBuffer target, StringBuffer radius,String cmd) { char b[]=cmd.toCharArray(); int d,i; int inPar; // Niveau de parenthesage // On passe les espaces en debut de chaine for( d=0; d=0 ) { a.dialog.server[j].flagToFront=false; // Pour eviter le toFront d'Aladin a.dialog.server[j].creatPlane(target,radius,criteria,null,null); } else { if( erreur.length()>0 ) { erreur.append(", "); pluriel="s"; } erreur.append(server); } } while( i0 ) { Aladin.warning("Server"+pluriel+" \""+erreur+"\" unknown ! ",1); } return true; } // voir getDrawParam(); private int getOneDrawParam(StringBuffer p,char a[],int i) { boolean flagText,bslash; for( bslash=flagText=false; i0 ) { if( i==0 ) { if( !exec(cmd,verbose) ) return false; } else exec(cmd,verbose); } i++; } return true; } /** Traitement d'une commande aladin * @@param s la commande a traiter * @@param verbose true si ca doit etre bavard * @@return false si la commande n'existe pas */ protected boolean exec(String s) { return exec(s,true); } protected boolean exec(String s,boolean verbose) { StringTokenizer st = new StringTokenizer(s); String cmd = st.nextToken(); String param = s.substring(cmd.length()).trim(); int n; if( !Aladin.flagLaunch && verbose ) System.out.println("["+s+"]..."); //thomas // est-ce le debut d'une nouvelle definition de filtre ? if(s.toLowerCase().startsWith("filter") && s.indexOf("{")>=0 ) { System.out.println("Enter the constraints for the new filter"); filterMode = true; filterDef = new StringBuffer(); //filterDef.append(s); //return true; } if(filterMode) { filterDef.append("\n"+s); // a-t-on atteint la fin de la definition ? if( Action.countNbOcc('{',filterDef.toString()) <= Action.countNbOcc('}',filterDef.toString()) ) { filterMode = false; createFilter(filterDef.toString()); a.calque.select.repaint(); return true; } //System.out.println("Enter other constraints or finish with \"end filter\""); if( Action.countNbOcc('\n', filterDef.toString()) > 1 ) System.out.println("Enter other constraints for the new filter"); return true; } if( cmd.equalsIgnoreCase("reset") ) a.calque.FreeAll(); else if( cmd.equalsIgnoreCase("quit") ) System.exit(0); else if( cmd.equalsIgnoreCase("help") ) System.out.println(execHelp); else if( cmd.equalsIgnoreCase("get") ) execGetCmd(param); else if( cmd.equalsIgnoreCase("draw") ) execDrawCmd(param); else if( cmd.equalsIgnoreCase("status") ) status(); else if( cmd.equalsIgnoreCase("info") ) a.status.setText(param); else if( cmd.equalsIgnoreCase("grid") ) { boolean flag= !param.equals("off"); a.calque.setGrid(flag); a.calque.repaint(); } else if( cmd.equalsIgnoreCase("pause") ) { try { n=Integer.parseInt(param); if( n<=0 ) n=1; } catch( Exception e ) { n=1; } try { sleep(n*1000); } catch( Exception e1 ) {} } else if( cmd.equalsIgnoreCase("timeout") ) { if( param.equals("off") ) n=0; else { n=-1; try { n=Integer.parseInt(param); } catch( Exception e ) { n=-1; } } if( n<0 ) { System.out.println("Timeout error ("+param+") !"); } else timeout=n*6000; } else if( cmd.equalsIgnoreCase("target") || cmd.equalsIgnoreCase("reticle")) { boolean flag= !param.equals("off"); a.calque.setReticle(flag); a.calque.repaint(); } else if( cmd.equalsIgnoreCase("scale") ) { boolean flag= !param.equals("off"); a.calque.setScale(flag); a.calque.repaint(); } else if( cmd.equalsIgnoreCase("flipflop") ) { int methode=0; PlanImage p = (PlanImage)a.calque.getPlanBase(); if( p==null || !p.flagOk ) { System.out.println("No image ready !"); return true; } if( param==null || param.equalsIgnoreCase("V") || param.length()==0 ) methode=0; else if( param.equalsIgnoreCase("H") ) methode=1; else if( param.equalsIgnoreCase("VH") ||param.equalsIgnoreCase("HV") ) methode=2; else { System.out.println("Bad flipflop argument"); return true; } p.flip(methode); } else if( cmd.equalsIgnoreCase("reverse") ) { boolean flag= !param.equals("off"); PlanImage p = (PlanImage)a.calque.getPlanBase(); if( p==null || !p.flagOk ) { System.out.println("No image ready !"); return true; } if( p.video==PlanImage.VIDEO_NORMAL && !flag ) return true; if( p.video==PlanImage.VIDEO_INVERSE && flag ) return true; p.video=flag?PlanImage.VIDEO_INVERSE:PlanImage.VIDEO_NORMAL; IndexColorModel cm = ColorMap.getCM(0,128,255, p.video==PlanImage.VIDEO_INVERSE,p.typeCM); p.setCM(cm); a.calque.zoom.zoomView.setCM(cm); } else if( cmd.equalsIgnoreCase("RGB") ) { st = new StringTokenizer(param); PlanImage pR=null,pG=null,pB=null; boolean diff=false; // Par defaut on prend les 3 premiers plans images if( !st.hasMoreTokens() ) { for( int i=a.calque.plan.length-1,j=0; i>=0; i--) { if( a.calque.plan[i].type==Plan.IMAGE ) { PlanImage pi = (PlanImage)a.calque.plan[i]; if( !pi.flagOk || pi.error!=null || pi instanceof PlanImageRGB) continue; if( j==0 ) pR=pi; else if( j==1 ) pG=pi; else if( j==2 ) { pB=pi; break; } j++; } } // on recherche les plans indiques par la commande } else { try { pR = getRGBPlan(st.nextToken()); pB = getRGBPlan(st.nextToken()); pG = getRGBPlan(st.nextToken()); if( st.hasMoreTokens() && st.nextToken().equals("diff") ) diff=true; }catch( Exception eRGB) {} if( pB==null && pG==null ) { System.out.println("RGB usage error !"); return false; } } a.calque.newPlanImageRGB(pR,pG,pB,planRGBRef,diff); } else if( cmd.equalsIgnoreCase("cm") ) { PlanImage p = (PlanImage)a.calque.getPlanBase(); if( p==null || !p.flagOk ) { System.out.println("No image ready !"); return true; } if( param.equals("gray") ) p.typeCM=PlanImage.CMGRAY; else if( param.equals("BB") ) p.typeCM=PlanImage.CMBB; else if( param.equals("A") ) p.typeCM=PlanImage.CMA; else { System.out.println("Colormap \""+param+"\" unknown"); return true; } IndexColorModel cm = ColorMap.getCM(0,128,255, p.video==PlanImage.VIDEO_INVERSE,p.typeCM); p.setCM(cm); a.calque.zoom.zoomView.setCM(cm); } else if( cmd.equalsIgnoreCase("sync") ) sync(); else if( cmd.equalsIgnoreCase("free") ) { if( param.length()==0 ) n=a.calque.getFirstSelected(); else n=getNumber(st.nextToken()); if( n<0 ) return true; a.calque.select.selectPlan(n); a.calque.FreeSet(); } else if( cmd.equalsIgnoreCase("hide") ) { if( param.length()==0 ) n=a.calque.getFirstSelected(); else n=getNumber(st.nextToken()); if( n<0 ) return true; a.calque.plan[n].active=false; a.calque.repaint(); } else if( cmd.equalsIgnoreCase("show") ) { if( param.length()==0 ) n=a.calque.getFirstSelected(); else n=getNumber(st.nextToken()); if( n<0 ) return true; a.calque.plan[n].active=true; a.calque.repaint(); } else if( cmd.equalsIgnoreCase("zoom") ) { if( !a.calque.zoom.setZoom(param) ) { System.out.println("Zoom factor \""+param+"\" unknown !"); } } else if( cmd.equalsIgnoreCase("ref") ) { if( (n = getNumber(st.nextToken()))<0 ) return true; if( !a.calque.setPlanRef(n) ) { System.out.println("Plane number "+param+" cannot be a reference plane !"); } else a.calque.repaint(); } else if( cmd.equalsIgnoreCase("select") ) { if( (n = getNumber(st.nextToken()))<0 ) return true; a.calque.select.selectPlan(n); a.calque.repaint(); } else if( cmd.equalsIgnoreCase("backup") ) { if( a.save==null ) a.save = new Save(a); sync(); ((Save)a.save).save(param); } else if( cmd.equalsIgnoreCase("save") ) { if( a.save==null ) a.save = new Save(a); sync(); ((Save)a.save).saveView(param); } else if( cmd.equalsIgnoreCase("export") ) { if( a.save==null ) a.save = new Save(a); if( (n = getNumber(st.nextToken()))<0 ) return true; sync(); Plan p = a.calque.plan[n]; if( p.type==Plan.CATALOG ) ((Save)a.save).saveCatalog(st.nextToken(),p); else if( p.type==Plan.IMAGE ) ((Save)a.save).saveImage(st.nextToken(),p); else System.out.println("Plane number "+n+" free !"); } else if( cmd.equalsIgnoreCase("trace") ) { if( param.equals("off") || param.equals("0")) { a.levelTrace=0; System.out.println("Trace off"); return true; } try { n=Integer.parseInt(param); if( n>Aladin.MAXLEVELTRACE || n<0 ) n=1; } catch( Exception e ) { n=1; } a.levelTrace=n; System.out.println("Trace on (level "+n+")"); } else if( cmd.equalsIgnoreCase("mem") || cmd.equalsIgnoreCase("gc") ) { System.gc(); System.out.println("Total memory: "+Runtime.getRuntime().freeMemory()+ "/"+Runtime.getRuntime().totalMemory()); } else if( cmd.equalsIgnoreCase("load") ) a.load(param); // Pour CFHT-QSO: Renaud Savalle // Creation d'un nouveau plan tool // arguments; nom du plan else if( cmd.equalsIgnoreCase("ptool") ) { String nom = st.nextToken(); System.out.println("Creating new PlanTool "+nom); a.calque.newPlanTool(nom); a.calque.repaint(); } // Pour CFHT-QSO: Renaud Savalle // Creation d'un repere (tag) pour une position en pixels // arguments: numero du plan de reference (image), coordonnees du repere en pixels else if( cmd.equalsIgnoreCase("rep") ) { String p = st.nextToken(); if( (n = getNumber(p))<0 ) return true; // Coordonnees en pixels int x = Integer.parseInt(st.nextToken()); int y = Integer.parseInt(st.nextToken()); // Creation du repere System.out.println("Creating repere ("+x+","+y+") on plan "+p); Repere repere = new Repere(a.calque.plan[n],x,y); // Ajoute le repere sur le plan courant, il doit etre du type PlanTool sinon rien ne se passe a.calque.setObjet(repere); a.calque.repaint(); } // thomas else if( cmd.equals("contour") ) { PlanImage p = (PlanImage)a.calque.getPlanBase(); if( p==null || !p.flagOk ) { System.out.println("No image ready !"); return true; } if( p instanceof PlanImageRGB ) { System.out.println("Can't produce contours on a RGB picture"); return true; } // 4 niveaux par defaut int nbContours=4; if( st.hasMoreTokens() ) { String p1 = st.nextToken(); try{ nbContours = Integer.parseInt(p1);} catch (NumberFormatException e) {System.out.println("Incorrect or missing parameter");return true;} } int tmp[] = new int[nbContours]; tmp = FrameContour.generateLevels(nbContours); double levels[] = new double[nbContours]; for(int i=0;i=tab.length) fin=true; p1=tab[i1]; p2=tab[i2]; p3=tab[i3]; retTab[indexRet]=p1; indexRet++; indexOrg=testPoints(i1,tab); retTab[indexRet] = tab[indexOrg]; indexRet++; i1=indexOrg+1; i2=i1+1; i3=i2+1; if (i3>=tab.length) fin=true; } PointD[] tmp = new PointD[indexRet+1]; System.arraycopy(retTab,0,tmp,0,indexRet+1); return tmp; } /** methode privee appelee par cleanContours */ private static int testPoints(int i1, PointD[] tab) { int i2=i1+1; int i3=i2+1; PointD p1,p2,p3; boolean fin=false; int type=-1; while(!fin) { if (i3>=tab.length) { fin=true; continue; } p1=tab[i1]; p2=tab[i2]; p3=tab[i3]; if(p1==null||p2==null||p3==null) { fin=true; continue; } if (p1.x == p2.x && p2.x == p3.x && (type==0||type==-1)) { type=0; i2++; i3++; continue; } if (p1.y == p2.y && p2.y == p3.y && (type==1||type==-1)) { type=1; i2++; i3++; continue; } if( ( (p2.x-p1.x)==(p3.x-p2.x) ) && ( (p2.y-p1.y)==(p3.y-p2.y) ) && (type==2||type==-1)) { type=2; i2++; i3++; continue; } fin=true; } return i2; } } s de contour * Ces algos devront heriter de cette classe * * @@author Thomas Boch [CDS] * Juillet 2002 - Correction d'un bug de cleanContours lorsque le parametre est un tableau de 0 element */ public abstract class ContourAlgorithm { protected PlanContour pc; // reference au PlanContour appelant protected int width,height; // dimensions de l'image protected double level; // valeur du niveaucds/aladin/ContourPlot.java010064400076440000132000000350300770227416100167040ustar00ferniquecds00000400000013package cds.aladin; public final class ContourPlot extends ContourAlgorithm { // Below, data members which store the grid steps, // the z values, the interpolation flag, the dimensions // of the contour plot and the increments in the grid: int xSteps, ySteps; private short z[][]; private int compteur; // pour les thread // flag mis a true lorsque l'on debute un nouveau contour private boolean newContour; // variables de travail private PointD p1,p2,pTemp,firstPoint; // Below, data members, most of which are adapted from // Fortran variables in Snyder's code: int l1[] = new int[4]; int l2[] = new int[4]; int ij[] = new int[2]; int i1[] = new int[2]; int i2[] = new int[2]; int i3[] = new int[6]; int ibkey,icur,jcur,ii,jj,elle,ix,iedge,iflag,ni,ks; int idir,nxidir,k; int z1,z2; double cval; double intersect[] = new double[4]; double xy[] = new double[2]; double prevXY[] = new double[2]; float lev; boolean workSpace[]; boolean jump; private double prevU,prevV,u,v; // variable servant a la construction des contours private PointD[] Contours; int index; int nb=0; //------------------------------------------------------- // A constructor method. //------------------------------------------------------- public ContourPlot() { super(); init(); } //------------------------------------------------------- private int sign(int a, int b) { a = Math.abs(a); if (b < 0) return -a; else return a; } //------------------------------------------------------- // "DrawKernel" is the guts of drawing and is called // directly or indirectly by "ContourPlotKernel" in order // to draw a segment of a contour or to set the pen // position "prevXY". Its action depends on "iflag": // // iflag == 1 means Continue a contour // iflag == 2 means Start a contour at a boundary // iflag == 3 means Start a contour not at a boundary // iflag == 4 means Finish contour at a boundary // iflag == 5 means Finish closed contour not at boundary // iflag == 6 means Set pen position // //------------------------------------------------------- void DrawKernel() { if ((iflag == 1) || (iflag == 4) || (iflag == 5)) { prevU = (prevXY[0] - 1.0); prevV = (prevXY[1] - 1.0); u = (xy[0] - 1.0); v = (xy[1] - 1.0); // Interchange horizontal & vertical //System.out.println(prevU +" " +prevV); //System.out.println(u+" "+v+"\n \n"); p1 = new PointD(prevU,prevV); //PointD p1 = new PointD(Math.round(prevU),Math.round(prevV)); p2 = new PointD(u,v); //PointD p2 = new PointD(Math.round(u),Math.round(v)); if(newContour) { newContour = false; firstPoint = p1; } pTemp = new PointD(-1.0,-1.0); if(index>0) pTemp = Contours[index-1]; //if( index==0 || ! p1.equals(Contours[index-1]) )// a remettre if( index==0 || pTemp==null || ! ( (int)p1.x==(int)pTemp.x && (int)p1.y==(int)pTemp.y ) ) {check();Contours[index]=p1;index++;} pTemp = Contours[index-1]; //if( ! p2.equals(Contours[index-1]) )// a remettre if( ! ( (int)p2.x==(int)pTemp.x && (int)p2.y==(int)pTemp.y ) ) {check();Contours[index]=p2;index++;} nb+=2; // Pour laisser la main aux autres threads(test) if(Aladin.isSlow) { if( nb%300==0 ) { try { Thread.currentThread().sleep(10); } catch(Exception e) { } } } } prevXY[0] = xy[0]; prevXY[1] = xy[1]; } //------------------------------------------------------- // "DetectBoundary" //------------------------------------------------------- void DetectBoundary() { ix = 1; if (ij[1-elle] != 1) { ii = ij[0] - i1[1-elle]; jj = ij[1] - i1[elle]; ii = ij[0] + i2[elle]; jj = ij[1] + i2[1-elle]; ix = 0; if (ij[1-elle] >= l1[1-elle]) { ix = ix + 2; return; } } ii = ij[0] + i1[1-elle]; jj = ij[1] + i1[elle]; } //------------------------------------------------------- // "Routine_label_020" corresponds to a block of code // starting at label 20 in Synder's subroutine "GCONTR". //------------------------------------------------------- boolean Routine_label_020() { l2[0] = ij[0]; l2[1] = ij[1]; l2[2] = -ij[0]; l2[3] = -ij[1]; idir = 0; nxidir = 1; k = 1; ij[0] = Math.abs(ij[0]); ij[1] = Math.abs(ij[1]); elle = 0; return false; } //------------------------------------------------------- // "Routine_label_050" corresponds to a block of code // starting at label 50 in Synder's subroutine "GCONTR". //------------------------------------------------------- boolean Routine_label_050() { while (true) { if (ij[elle] >= l1[elle]) { if (++elle <= 1) continue; elle = idir % 2; ij[elle] = sign(ij[elle],l1[k-1]); if (Routine_label_150()) return true; continue; } ii = ij[0] + i1[elle]; jj = ij[1] + i1[1-elle]; break; } jump = false; return false; } //------------------------------------------------------- // "Routine_label_150" corresponds to a block of code // starting at label 150 in Synder's subroutine "GCONTR". //------------------------------------------------------- boolean Routine_label_150() { compteur++; if(Aladin.isSlow) { // on laisse la main aux autres threads if(compteur%2000==0) { try{Thread.currentThread().sleep(10);} catch(Exception e) {} } } while (true) { //------------------------------------------------ // Lines from z[ij[0]-1][ij[1]-1] // to z[ij[0] ][ij[1]-1] // and z[ij[0]-1][ij[1]] // are not satisfactory. Continue the spiral. //------------------------------------------------ if (ij[elle] < l1[k-1]) { ij[elle]++; if (ij[elle] > l2[k-1]) { l2[k-1] = ij[elle]; idir = nxidir; nxidir = idir + 1; k = nxidir; if (nxidir > 3) nxidir = 0; } ij[0] = Math.abs(ij[0]); ij[1] = Math.abs(ij[1]); elle = 0; return false; } if (idir != nxidir) { nxidir++; ij[elle] = l1[k-1]; k = nxidir; elle = 1 - elle; ij[elle] = l2[k-1]; if (nxidir > 3) nxidir = 0; continue; } if (ibkey != 0) return true; ibkey = 1; ij[0] = icur; ij[1] = jcur; if (Routine_label_020()) continue; return false; } } //------------------------------------------------------- // "Routine_label_200" corresponds to a block of code // starting at label 200 in Synder's subroutine "GCONTR". // It has return values 0, 1 or 2. //------------------------------------------------------- short Routine_label_200() { while (true) { xy[elle] = ij[elle] + intersect[iedge-1]; xy[1-elle] = ij[1-elle]; workSpace[2*(xSteps*(ij[1]-1) +ij[0]-1) + elle] = true; DrawKernel(); if (iflag >= 4) { icur = ij[0]; jcur = ij[1]; return 1; } ContinueContour(); if (!workSpace[2*(xSteps*(ij[1]-1)+ij[0]-1)+elle]) return 2; iflag = 5; // 5. Finish a closed contour iedge = ks + 2; if (iedge > 4) iedge = iedge - 4; intersect[iedge-1] = intersect[ks-1]; } } //------------------------------------------------------- // "CrossedByContour" is true iff the current segment in // the grid is crossed by one of the contour values and // has not already been processed for that value. //------------------------------------------------------- boolean CrossedByContour() { ii = ij[0] + i1[elle]; jj = ij[1] + i1[1-elle]; z1 = z[ij[0]-1][ij[1]-1]; z2 = z[ii-1][jj-1]; int i = 2*(xSteps*(ij[1]-1) + ij[0]-1) + elle; if (!workSpace[i]) { if ((lev>Math.min(z1,z2)) && (lev<=Math.max(z1,z2))) { workSpace[i] = true; return true; } } return false; } //------------------------------------------------------- // "ContinueContour" continues tracing a contour. Edges // are numbered clockwise, the bottom edge being # 1. //------------------------------------------------------- void ContinueContour() { short local_k; ni = 1; if (iedge >= 3) { ij[0] = ij[0] - i3[iedge-1]; ij[1] = ij[1] - i3[iedge+1]; } for (local_k = 1; local_k < 5; local_k++) if (local_k != iedge) { ii = ij[0] + i3[local_k-1]; jj = ij[1] + i3[local_k]; z1 = z[ii-1][jj-1]; ii = ij[0] + i3[local_k]; jj = ij[1] + i3[local_k+1]; z2 = z[ii-1][jj-1]; if ((cval > Math.min(z1,z2) && (cval <= Math.max(z1,z2)))) { if ((local_k == 1) || (local_k == 4)) { int zz = z2; z2 = z1; z1 = zz; } intersect[local_k-1] = (cval - z1)/(z2 - z1); ni++; ks = local_k; } } if (ni != 2) { //------------------------------------------------- // The contour crosses all 4 edges of cell being // examined. Choose lines top-to-left & bottom-to- // right if interpolation point on top edge is // less than interpolation point on bottom edge. // Otherwise, choose the other pair. This method // produces the same results if axes are reversed. // The contour may close at any edge, but must not // cross itself inside any cell. //------------------------------------------------- ks = 5 - iedge; if (intersect[2] >= intersect[0]) { ks = 3 - iedge; if (ks <= 0) ks = ks + 4; } } //---------------------------------------------------- // Determine whether the contour will close or run // into a boundary at edge ks of the current cell. //---------------------------------------------------- elle = ks - 1; iflag = 1; // 1. Continue a contour jump = true; if (ks >= 3) { ij[0] = ij[0] + i3[ks-1]; ij[1] = ij[1] + i3[ks+1]; elle = ks - 3; } } //------------------------------------------------------- // "ContourPlotKernel" is the guts of this class and // corresponds to Synder's subroutine "GCONTR". //------------------------------------------------------- void ContourPlotKernel() { short val_label_200; l1[0] = xSteps; l1[1] = ySteps; l1[2] = -1;l1[3] = -1; i1[0] = 1; i1[1] = 0; i2[0] = 1; i2[1] = -1; i3[0] = 1; i3[1] = 0; i3[2] = 0; i3[3] = 1; i3[4] = 1; i3[5] = 0; prevXY[0] = 0.0; prevXY[1] = 0.0; xy[0] = 1.0; xy[1] = 1.0; iflag = 6; DrawKernel(); icur = Math.max(1, Math.min((int)Math.floor(xy[0]), xSteps)); jcur = Math.max(1, Math.min((int)Math.floor(xy[1]), ySteps)); ibkey = 0; ij[0] = icur; ij[1] = jcur; if (Routine_label_020() && Routine_label_150()) return; if (Routine_label_050()) return; while (true) { DetectBoundary(); if (jump) { if (ix != 0) iflag = 4; // Finish contour at boundary iedge = ks + 2; if (iedge > 4) iedge = iedge - 4; intersect[iedge-1] = intersect[ks-1]; val_label_200 = Routine_label_200(); if (val_label_200 == 1) { if (Routine_label_020() && Routine_label_150()) return; if (Routine_label_050()) return; continue; } if (val_label_200 == 2) continue; return; } if ((ix != 3) && (ix+ibkey != 0) && CrossedByContour()) { newContour = true; // nouveau contour pour ce niveau if(index>0 && p2!=null ) { if( !p2.equals(Contours[index-1]) && distance(p2,firstPoint)<2 ) { check(); Contours[index]=p2; index++; } } check(); Contours[index]=null; index++; // An acceptable line segment has been found. // Follow contour until it hits a // boundary or closes. // //System.out.println("BEGIN CONTOUR"); iedge = elle + 1; cval = lev; if (ix != 1) iedge = iedge + 2; iflag = 2 + ibkey; intersect[iedge-1] = (cval - z1) / (z2 - z1); val_label_200 = Routine_label_200(); if (val_label_200 == 1) { if (Routine_label_020() && Routine_label_150()) return; if (Routine_label_050()) return; continue; } if (val_label_200 == 2) continue; return; } if (++elle > 1) { elle = idir % 2; ij[elle] = sign(ij[elle],l1[k-1]); if (Routine_label_150()) return; } if (Routine_label_050()) return; } } protected PointD[] getContours() { init(); int a; // z a initialiser a partir de data z = new short[width][height]; for(int j=0;j=1.0 ) s="°"; if( x<1.0 ) { s="'"; x=x*60.0; } if( x<1.0 ) { s="\""; x=x*60.0; } x=((int)(x*100.0))/100.0; s=x+s; return s; } /** Affichage dans la bonne unite (H:M:S). * Retourne un angle en degres sous forme de chaine dans la bonne unite * @@param x l'angle * @@return l'angle dans une unite coherente + l'unite utilisee */ protected static String getUnitTime(double x) { String s=null; if( x>=1.0 ) s="h"; if( x<1.0 ) { s="min"; x=x*60.0; } if( x<1.0 ) { s="s"; x=x*60.0; } x=((int)(x*100.0))/100.0; s=x+" "+s; return s; } /** Calcul d'un distance entre deux points reperes par leurs coord * @@param c1 premier point * @@param c2 deuxieme point * @@return La distance angulaire en degres protected static double getDist1(Coord c1, Coord c2) { double dra = c2.al-c1.al; double dde = Math.abs(c1.del-c2.del); dra = Math.abs(dra); if( dra>180 ) dra-=360; double drac = dra*Astropos.cosd(c1.del); return Math.sqrt(drac*drac+dde*dde); } */ protected static double getDist(Coord c1, Coord c2) { return Coo.dist(c1.al,c1.del,c2.al,c2.del); } } cds/aladin/Cote.java010064400076440000132000000167370770227416100153230ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.astro.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Objet graphique pour une Cote * * @@author Pierre Fernique [CDS] * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Cote extends Ligne { /** Constructeurs du premier bout. * @@param plan plan d'appartenance de la cote * @@param x,y position du premier bout */ protected Cote(Plan plan, double x, double y) { super(plan,x,y,(String)null); bout=2; } /** Creation d'une Cote pour les bakcups */ protected Cote(Plan plan) { super(plan); bout=2; } /** Constructeurs du premier bout. * @@param plan plan d'appartenance de la cote * @@param x,y position du premier bout * @@param id identificateur associe a la cote */ protected Cote(Plan plan, double x, double y,String id) { super(plan,x,y,id); bout=2; } /** Constructeurs du deuxieme bout. * @@param plan plan d'appartenance de la cote * @@param x,y position du premier bout * @@param debcote premier bout de la cote */ protected Cote(Plan plan, double x, double y,Cote debcote) { this(plan,x,y,"",debcote); } /** Constructeurs du deuxieme bout. * @@param plan plan d'appartenance de la cote * @@param x,y position du premier bout * @@param id identificateur associe a la cote * @@param debcote premier bout de la cote */ protected Cote(Plan plan, double x, double y, String id,Cote debcote) { super(plan,x,y,id,(Ligne)debcote); bout=2; } /** Modification de id pour prendre en compte la taille */ protected void status(Aladin aladin) { setId(); super.status(aladin); } /** Test d'appartenance a la cote. * Retourne vrai si le point (x,y) de la vue se * trouve sur la cote * Met egalement a jour l'id avec la taille courante de la Cote * afin de pouvoir la visualiser pendant le trace * @@param x,y le point a tester * @@param z le zoom */ protected boolean in(double x, double y, double z) { if( !super.in(x,y,z) ) return false; setId(); return true; } /** Mise en place de l'ID. * En fonction du plan de reference courant, positionne id avec la * longueur courante de la cote */ protected void setId() { Position p1,p2; if( debligne!=null ) { p2 = (Position)this; p1 = (Position)debligne; } else { p2 = (Position)finligne; p1 = (Position)this; } Plan ref = plan.aladin.calque.getPlanRef(); if( ref!=null && ref.projd!=null ) { Coord c1 = new Coord(); c1.x=p1.x; c1.y=p1.y; Coord c2 = new Coord(); c2.x=p2.x; c2.y=p2.y; if( ref.projd.getCoord(c1)!=null && ref.projd.getCoord(c2)!=null ) { double dra = c2.al-c1.al; double dde = Math.abs(c1.del-c2.del); double cosc2 = Coo.cosd(c2.del); double num = cosc2 * Coo.sind(dra); double den = Coo.sind(c2.del) * Coo.cosd(c1.del) - cosc2 * Coo.sind(c1.del) * Coo.cosd(dra); double angle = (dra==0.0 && dde==0.0)?-1000:(den==0.0)?90.0:Math.atan2(num,den)*180/Math.PI; if( angle<0.0 ) angle+=360.0; dra = Math.abs(dra); if( dra>180 ) dra-=360; double drac = dra*Coo.cosd(c1.del); id= "Dist = "+Coord.getUnit( Coord.getDist(c1,c2) ) + " (diff : RA="+Coord.getUnit(drac)+ "/"+Coord.getUnitTime(dra/15)+ ", DE="+Coord.getUnit(dde)+")"+ ((angle==-1000)?"":" PA = "+(Math.round(angle*10)/10.0)+" deg"); return; } } // Si on ne peut pas calculer les coordonnees, on donne juste // le dx et le dy int dx = (int)Math.round(Math.abs(p1.x-p2.x)); int dy = (int)Math.round(Math.abs(p1.y-p2.y)); id= Math.round(Math.abs(Math.sqrt(dx*dx+dy*dy))) + " (delta x="+dx+", delta y="+dy+")"; } /** Test d'appartenance. * Retourne vrai si le point (x,y) de l'image se trouve * - soit a proximite de l'extremite courante du segment * - soit sur le segment mais eloigne des deux extremites * @@param x,y le point a tester * @@param z le zoom */ protected boolean inside(double x, double y,double z) { Ligne bout, autreCote; if( nearArrow(x,y,z) ) return true; if( debligne==null ) { autreCote=bout=finligne; } else { autreCote=debligne; bout=this; } return bout.in(x,y,z) && !autreCote.nearArrow(x,y,z); } } CONTREFACON) // POUVANT RESULTERcds/aladin/Couleur.java010064400076440000132000000253630770227416100160420ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion des couleurs (choix et valeur par defaut) * Affichage d'un selecteur de couleurs (8 petits carres cliquables) * * @@author Pierre Fernique [CDS] * @@version 1.1? : (mars 02) Ajout de constructeur permettant le choix de la taille des carres * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Couleur extends Canvas { static final int W = 25; // Taille d'un carre de selection de couleur (marge comprise) static final int GAP = 4; // Marge entre deux carres de selection de couleur int w = W-GAP; // Taille reelle d'un carre static int iDC = 0; // indice de la prochaine couleur si aucune vide int ww = W; int gap = GAP; // Les couleurs gerees (doivent necessairement etre en nombre pair) static final Color [] DC = { Color.red, Color.blue, Color.yellow, Color.cyan, Color.pink, Color.orange, Color.magenta, Color.green,Color.black,Color.white }; Color[] dc; static final int ROW = DC.length/2; // Nombre d'item dans une rangee int row; int current=-1; // Couleur courante du selecteur boolean first; // true si on affiche pour la premiere fois le selecteur /** Creation d'un selecteur de couleur. * (pas de couleur selectionne par defaut) */ protected Couleur() { this(null); } /** Creation d'un selecteur de couleur. *

Rq : les couleurs possibles sont : Color.red, Color.blue, * Color.yellow, Color.cyan, Color.pink, Color.orange, Color.magenta, * Color.green,Color.black,Color.white * * @@param c la couleur courante (ex: Color.red...) */ protected Couleur(Color c) { dc=DC; if( c!=null ) setCouleur(c); resize( (DC.length/2)*W,2*W); first=true; dc=DC; row=ROW; } //thomas /** Creation d'un selecteur de couleur avec choix de la taille des carres. * @@param c la couleur courante * @@param width taille d'un carre, gap compris * @@param gap l'espace entre deux carres */ protected Couleur(Color c, int width, int gap) { dc=DC; if( c!=null ) setCouleur(c); if (width>gap) { this.ww = width; this.gap = gap; this.w = ww-this.gap; } resize( (DC.length/2)*ww,2*ww); first=true; row=ROW; } //thomas /** Creation d'un selecteur de couleur avec choix de la taille des carres * et choix des couleurs * @@param c la couleur courante * @@param width taille d'un carre, gap compris * @@param gap l'espace entre deux carres * @@param tabcoul tableau des couleurs que l'on veut en plus des couleurs initiales */ protected Couleur(Color c, int width, int gap, Color[] tabcoul) { int i; dc = new Color[DC.length+tabcoul.length]; // initialisation de dc for(i=0;igap) { this.ww = width; this.gap = gap; this.w = ww-this.gap; } resize( (dc.length/2)*ww,2*ww); first=true; } //thomas /** Creation d'un selecteur de couleur avec choix de la taille des carres * et choix des couleurs * @@param tabcoul tableau des couleurs que l'on veut * @@param c la couleur courante * @@param width taille d'un carre, gap compris * @@param gap l'espace entre deux carres */ protected Couleur(Color[] tabcoul,Color c, int width, int gap) { int i; dc = new Color[tabcoul.length]; // initialisation de dc for(i=0;igap) { this.ww = width; this.gap = gap; this.w = ww-this.gap; } resize( (dc.length/2)*ww,2*ww); first=true; } /** Retourne la prochaine couleur par defaut. * Prend en compte les couleurs deja utilisees par les autres plans * @@param calque reference * @@return la prochaine couleur par defaut */ protected static Color getNextDefault(Calque calque) { int i,j; // Y a-t-il une couleur de libre ? for( j=0; jfalse si la couleur n'est pas valide, true sinon * see aladin.Couleur(java.awt.color) */ protected boolean setCouleur( Color c ) { for( int i=0; itrue si des donnees vont etre chargee, sinon false * * @@RQ: Uniquement via l'applet */ protected void processParameter() { processParameter(null); } protected void processParameter(Hashtable t) { URL u; String param; boolean rep=false; StringTokenizer st; a.waitDialog(); a.trace(1,"Analyzing the parameters"); try { // Chargement d'un script // Chargement d'eventuelles images par le parametre // "img=url[ label],..." String load = getParam(t,"img"); if( load!=null ) { st = new StringTokenizer(load,","); while( st.hasMoreTokens() ) { StringTokenizer st1 = new StringTokenizer(st.nextToken()," "); try { String adr=st1.nextToken(); String label=st1.hasMoreTokens()?st1.nextToken():null; String origin=st1.hasMoreTokens()?st1.nextToken():null; a.dialog.server[ServerDialog.LOCAL].creatPlane(null,null,adr,label,origin); } catch( Exception ef ) { System.err.print("Cannot build url: "+ef); }; } } // Compatibilite avec l'ancienne methode des parametres String c = getParam(t,"-c"); if( c!=null ) { // Recuperation des differents parametres String rm = getParam(t,"-rm"); String servers = getParam(t,"-server"); String source = getParam(t,"-source"); String qualifier = getParam(t,"-aladin.qualifier"); String resol = getParam(t,"-aladin.resolution"); String fmt = getParam(t,"-aladin.format"); String fov = getParam(t,"-fov"); // les valeurs par defaut if( servers==null ) servers="Aladin"; if( resol==null ) resol="FULL"; if( fmt==null ) fmt="JPEG"; st = new StringTokenizer(servers,","); while( st.hasMoreTokens() ) { try { String server = st.nextToken(); // Aladin if( server.indexOf("Aladin")>=0 ) { String criteria = fmt+" "+resol; if( qualifier!=null ) criteria = criteria+" "+qualifier; int n=a.dialog.server[ServerDialog.ALADIN].creatPlane(c,rm,criteria,null,null); String sZoom = getParam(t,"-aladin.zoom"); if( sZoom!=null ) a.calque.plan[n].setZoom(sZoom); } // VizieR if( server.indexOf("VizieR")>=0 && source!=null ) { a.dialog.server[ServerDialog.VIZIER].creatPlane(c,rm,source,null,null); } // Simbad if( server.indexOf("Simbad")>=0 ) { a.dialog.server[ServerDialog.SIMBAD].creatPlane(c,rm,null,null,null); } // NED if( server.indexOf("NED")>=0 ) { a.dialog.server[ServerDialog.NED].creatPlane(c,rm,null,null,null); } } catch( Exception e1 ) { System.out.println("Pb: "+e1); e1.printStackTrace(); } } // Pour les FoV st = new StringTokenizer(fov,","); while( st.hasMoreTokens() ) { a.dialog.server[ServerDialog.FIELD].creatPlane(c,null,st.nextToken(),null,null); } } String script = getParam(t,"script"); if( script!=null ) a.command.execScript(script); } catch( Exception e ) {} } } Localisation(a); a.trace(1,"Creating the target window"); a.target = new Target(a); a.trace(1,"Creating the main view window"); a.viecds/aladin/Curseur.java010064400076440000132000000140750770227416100160520ustar00ferniquecds00000400000013package cds.aladin; import java.awt.*; import java.awt.event.*; /** * @@author Thomas Boch */ /* classe destinee a l'affichage des curseurs pour definir les niveaux des contours */ public class Curseur extends Canvas { static final int NO = -1; // constante signifiant qu'aucun triangle // n'est le triangle courant int[] niveaux; // tableau des niveaux int currentTriangle; // indice dans niveaux du triangle en cours de selection boolean flagDrag = false; // true si on drague int nbNiveaux = 0; // nb de niveaux couramment utilises Color[] couleurTriangle; // tableau des couleurs pour les triangles // Les constantes d'affichage final int mX = 10; // Marge en abscisse final int mY = 0; // Marge en ordonnee final int Hp = 0; // Hauteur du graphique final int W = 256+2*mX; // Largeur totale du graphique final int H = Hp+mY+24; // Hauteur totale du graphique /* constructeur */ Curseur() { initNiveaux(); initCouleurs(); setBackground(Aladin.BKGD); resize(W,H); } /** initCouleurs * initialise le tableau des couleurs * chaque element est initialise a Color.black */ private void initCouleurs() { couleurTriangle = new Color[PlanContour.MAXLEVELS]; for (int i=0;iniveaux[i]-5 && xniveaux[i]-5 && x255 ) x=255; niveaux[currentTriangle] = x; flagDrag=true; repaint(); return true; } /** Fin de deplacement du triangle precedemment selectionne */ public boolean mouseUp(Event e,int x, int y) { if( currentTriangle==NO ) return true; x-=mX; if( x<0 ) x=0; else if( x>255 ) x=255; niveaux[currentTriangle] = x; flagDrag=false; repaint(); return true; } public void paint(Graphics g) { int i; g.setColor(Color.black); g.drawLine(mX, Hp+mY+3, mX+255, Hp+mY+3); for( i=0; i=PlanContour.MAXLEVELS) return false; niveaux[nbNiveaux] = 0; // niveau a la creation du nouveau curseur nbNiveaux++; repaint(); return true; } // ajoute un curseur au niveau specifie protected boolean addCurseur(int level) { if (nbNiveaux>=PlanContour.MAXLEVELS) return false; niveaux[nbNiveaux] = level; // niveau a la creation du nouveau curseur nbNiveaux++; repaint(); return true; } // remet le nb de niveaux a zero protected void reset() { nbNiveaux = 0; repaint(); } // pour Francois Ochsenbein // methode permettant le deplacement des niveaux au clavier public boolean keyDown(Event e,int key) { if(currentTriangle == NO) return true; if (key == Event.RIGHT) { if(niveaux[currentTriangle]<255) niveaux[currentTriangle]++; } else if (key == Event.LEFT) { if(niveaux[currentTriangle]>0) niveaux[currentTriangle]--; } repaint(); return true; } } /* constructeur */ Curseur() { initNiveaux(); initCouleurs(); setBackground(Aladin.BKGD); resize(W,H); } /** initCouleurs * initialise le tableau des couleurs * chaque element est initialise a Color.black */ private void initCouleurs() { couleurTriangle = new Color[PlanContour.MAXLEVELS]; for (int i=0;i1 pour une ligne, 0 pour du blanc */ protected Filet(int h,int type) { this.type = type; resize(5,h); // Taille initiale } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { switch( type ) { case 0: return; case 1: int w = size().width-20; int y = size().height/2; if( w<=0 ) return; // Je trace un filet bicolore g.setColor( Color.black ); g.drawLine(5,y,w,y); g.setColor( Color.white ); g.drawLine(5,y+1,w,y+1); break; } } } cds/aladin/FilterHelp.java010064400076440000132000000350460770227416100164610ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; /** * Frame d'aide pour la syntaxe des filtres * * @@author Thomas Boch [CDS] * @@version 0.9 : 8 Novembre 2002 - Creation */ public class FilterHelp extends Frame { private static String ucdSyntaxExpla = "${columnName} is used to point out\nthe column named columnName\n"+ "whereas $[MY_UCD] points out\nthe first column being tagged with\nthe UCD MY_UCD.\n\n"+ "You can use the star \"*\" as a suffix\nsyntax for UCD."+ " For instance, $[PHOT_*]\nwill search for the first column" + " having\na UCD beginning by \"PHOT_\""; private static FilterHelp singleton=null; private static final String TITRE = "Help for filter syntax"; private FilterHelp() { super(TITRE); setBackground(Aladin.BKGD); suite(); move(350,200); } private void suite() { setLayout(new BorderLayout()); Panel panel = new Panel(); GridBagConstraints cc = new GridBagConstraints(); GridBagLayout gg = new GridBagLayout(); //cc.fill = GridBagConstraints.HORIZONTAL; panel.setLayout(gg); Color white = Color.white; // p1 : panel pour affichage de la syntaxe generale Panel p1 = new Panel(); p1.setBackground(white); GridBagConstraints c = new GridBagConstraints(); GridBagLayout g = new GridBagLayout(); c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; p1.setLayout(g); Label lIntro = new Label("The generic syntax of a filter is : "); lIntro.setFont(Aladin.BOLD); makeAdd(lIntro,gg,cc,GridBagConstraints.REMAINDER,panel); // premiere ligne Label lA1 = new Label(""); lA1.setFont(Aladin.COURIER); lA1.setBackground(white); makeAdd(lA1,g,c,GridBagConstraints.RELATIVE,p1); Label lA2 = new Label(" {"); lA2.setFont(Aladin.SBOLD); lA2.setBackground(white); makeAdd(lA2,g,c,GridBagConstraints.REMAINDER,p1); // deuxieme ligne Label lB1 = new Label(" "); lB1.setFont(Aladin.COURIER); lB1.setBackground(white); makeAdd(lB1,g,c,GridBagConstraints.REMAINDER,p1); // troisieme ligne Label lC1 = new Label(" "); lC1.setFont(Aladin.COURIER); lC1.setBackground(white); makeAdd(lC1,g,c,GridBagConstraints.REMAINDER,p1); // quatrieme ligne Label lD1 = new Label(" ......"); lD1.setFont(Aladin.COURIER); lD1.setBackground(white); makeAdd(lD1,g,c,GridBagConstraints.REMAINDER,p1); // cinquieme ligne Label lE1 = new Label(" "); lE1.setFont(Aladin.COURIER); lE1.setBackground(white); makeAdd(lE1,g,c,GridBagConstraints.REMAINDER,p1); // sixieme ligne Label lF1 = new Label("}"); lF1.setFont(Aladin.SBOLD); lF1.setBackground(white); makeAdd(lF1,g,c,GridBagConstraints.REMAINDER,p1); // septieme ligne Label lG1 = new Label(""); lG1.setFont(Aladin.COURIER); lG1.setBackground(white); makeAdd(lG1,g,c,GridBagConstraints.RELATIVE,p1); Label lG2 = new Label(" {"); lG2.setFont(Aladin.SBOLD); lG2.setBackground(white); makeAdd(lG2,g,c,GridBagConstraints.REMAINDER,p1); // huitieme ligne Label lH1 = new Label(" ......"); lH1.setFont(Aladin.COURIER); lH1.setBackground(white); makeAdd(lH1,g,c,GridBagConstraints.REMAINDER,p1); // neuvieme ligne Label lI1 = new Label("}"); lI1.setFont(Aladin.SBOLD); lI1.setBackground(white); makeAdd(lI1,g,c,GridBagConstraints.REMAINDER,p1); // dixieme ligne Label lJ1 = new Label("......"); lJ1.setFont(Aladin.COURIER); lJ1.setBackground(white); makeAdd(lJ1,g,c,GridBagConstraints.REMAINDER,p1); // ----- fin panel p1 ------ // ajout de l'explication sur syntaxe ucd/colonne a panel makeAdd(new MyLabel(ucdSyntaxExpla,Label.LEFT),gg,cc,GridBagConstraints.RELATIVE,panel); // ajout de p1 a panel makeAdd(p1,gg,cc,GridBagConstraints.REMAINDER,panel); // Label pour annoncer l'exemple Label lEg = new Label("E.g :"); lEg.setFont(Aladin.BOLD); makeAdd(lEg,gg,cc,GridBagConstraints.REMAINDER,panel); // Panel de l'exemple Panel p2 = new Panel(); p2.setBackground(white); GridBagConstraints c2 = new GridBagConstraints(); GridBagLayout g2 = new GridBagLayout(); c2.fill = GridBagConstraints.NONE; c2.anchor = GridBagConstraints.WEST; p2.setLayout(g2); Color remColor = Color.blue; Color ucdColor = Color.magenta; Color kwColor = Color.green; Color funcColor = Color.orange; // 1ere ligne Panel pp1 = new Panel(); pp1.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llA1 = new Label("$[phot_phg_b]"); llA1.setFont(Aladin.COURIER); llA1.setBackground(white); llA1.setForeground(ucdColor); pp1.add(llA1); Label llA2 = new Label(">19 {"); llA2.setFont(Aladin.COURIER); llA2.setBackground(white); pp1.add(llA2); makeAdd(pp1,g2,c2,GridBagConstraints.REMAINDER,p2); // 2e ligne Panel pp2 = new Panel(); pp2.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llB1 = new Label(" draw"); llB1.setFont(Aladin.COURIER); llB1.setBackground(white); llB1.setForeground(funcColor); pp2.add(llB1); Label llB4 = new Label("cyan"); llB4.setFont(Aladin.COURIER); llB4.setBackground(white); pp2.add(llB4); Label llB6 = new Label("plus"); llB6.setFont(Aladin.COURIER); llB6.setBackground(white); pp2.add(llB6); makeAdd(pp2,g2,c2,GridBagConstraints.REMAINDER,p2); // 3e ligne Panel pp3 = new Panel(); pp3.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llC1 = new Label(" draw"); llC1.setFont(Aladin.COURIER); llC1.setBackground(white); llC1.setForeground(funcColor); pp3.add(llC1); Label llC3 = new Label("$[phot_phg_b]"); llC3.setFont(Aladin.COURIER); llC3.setBackground(white); llC3.setForeground(ucdColor); pp3.add(llC3); makeAdd(pp3,g2,c2,GridBagConstraints.REMAINDER,p2); // 4e ligne Panel pp4 = new Panel(); pp4.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llD1 = new Label("}"); llD1.setFont(Aladin.COURIER); llD1.setBackground(white); pp4.add(llD1); makeAdd(pp4,g2,c2,GridBagConstraints.REMAINDER,p2); // 5e ligne Panel pp5 = new Panel(); pp5.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llE1 = new Label("$[phot_phg_b]"); llE1.setFont(Aladin.COURIER); llE1.setBackground(white); llE1.setForeground(ucdColor); pp5.add(llE1); Label llE2 = new Label(">17"); llE2.setFont(Aladin.COURIER); llE2.setBackground(white); pp5.add(llE2); Label llE3 = new Label(" && "); llE3.setFont(Aladin.ITALIC); llE3.setBackground(white); pp5.add(llE3); Label llE4 = new Label("$[class_object]"); llE4.setFont(Aladin.COURIER); llE4.setBackground(white); llE4.setForeground(ucdColor); pp5.add(llE4); Label llE5 = new Label("=\"Star\""); llE5.setFont(Aladin.COURIER); llE5.setBackground(white); pp5.add(llE5); Label llE6 = new Label("{"); llE6.setFont(Aladin.COURIER); llE6.setBackground(white); pp5.add(llE6); makeAdd(pp5,g2,c2,GridBagConstraints.REMAINDER,p2); // 6e ligne Panel pp6 = new Panel(); pp6.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llF1 = new Label(" draw"); llF1.setFont(Aladin.COURIER); llF1.setBackground(white); llF1.setForeground(funcColor); pp6.add(llF1); Label llF4 = new Label("square"); llF4.setFont(Aladin.COURIER); llF4.setBackground(white); pp6.add(llF4); Label llF6 = new Label("yellow"); llF6.setFont(Aladin.COURIER); llF6.setBackground(white); pp6.add(llF6); makeAdd(pp6,g2,c2,GridBagConstraints.REMAINDER,p2); // 7e ligne Panel pp7 = new Panel(); pp7.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llG1 = new Label("}"); llG1.setFont(Aladin.COURIER); llG1.setBackground(white); pp7.add(llG1); makeAdd(pp7,g2,c2,GridBagConstraints.REMAINDER,p2); // 8e ligne Panel pp8 = new Panel(); pp8.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llH1 = new Label("# No condition : this action concerns all remaining sources"); llH1.setFont(Aladin.COURIER); llH1.setBackground(white); llH1.setForeground(remColor); pp8.add(llH1); makeAdd(pp8,g2,c2,GridBagConstraints.REMAINDER,p2); // 9e ligne Panel pp9 = new Panel(); pp9.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llI0 = new Label("{"); llI0.setFont(Aladin.COURIER); llI0.setBackground(white); pp9.add(llI0); Label llI1 = new Label("draw"); llI1.setFont(Aladin.COURIER); llI1.setBackground(white); llI1.setForeground(funcColor); pp9.add(llI1); Label llI4 = new Label("rgb"); llI4.setFont(Aladin.ITALIC); llI4.setBackground(white); pp9.add(llI4); Label llI5 = new Label("(255,0,255)"); llI5.setFont(Aladin.COURIER); llI5.setBackground(white); pp9.add(llI5); makeAdd(pp9,g2,c2,GridBagConstraints.REMAINDER,p2); // 10e et derniere ligne Panel pp10 = new Panel(); pp10.setLayout(new FlowLayout(FlowLayout.LEFT,0,0)); Label llJ1 = new Label("}"); llJ1.setFont(Aladin.COURIER); llJ1.setBackground(white); pp10.add(llJ1); makeAdd(pp10,g2,c2,GridBagConstraints.REMAINDER,p2); // ajoute de p2 a panel makeAdd(p2,gg,cc,GridBagConstraints.REMAINDER,panel); // Label "Regardez les filtres predef. pour d'autres exemples" Label lOther = new Label("See predefined filters for other examples"); lOther.setFont(Aladin.BOLD); cc.weightx = 0.0; // ajout de lOther a panel makeAdd(lOther,gg,cc,GridBagConstraints.REMAINDER,panel); add(panel); pack(); } private void makeAdd(Component comp, GridBagLayout g, GridBagConstraints c, int gridwidth, Panel p) { c.gridwidth = gridwidth; g.setConstraints(comp,c); p.add(comp); } /** Retourne la reference de la Frame */ static protected FilterHelp getInstance() { if( singleton == null) singleton = new FilterHelp(); return singleton; } public void toFront() { move(350,200); super.toFront(); } /** Pour gerer la fermeture de la fenetre */ public boolean handleEvent(Event e) { if( e.id==Event.WINDOW_DESTROY ) { hide(); } return super.handleEvent(e); } } nel); // premiere ligne Label lA1 = new Label(""); lA1.setFont(Aladin.COURIER); lA1.setBackground(white); makeAdd(lA1,g,c,GridBagConstraints.RELATIVE,p1); Label lA2 = new Label(" {"); lA2.setFont(Aladin.SBOLD); lA2.setBackground(white); makeAdd(lA2,g,c,GridBagConstraints.REMAINDER,p1); // deuxieme ligne Label lB1 = new Label(" "); cds/aladin/FilterProperties.java010064400076440000132000000651130770227416100177230ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; /** FilterProperties * Frame de Propriétés des filtres (PlanFilter) * Cette classe est découplée de la fenêtre des propriétés des autres plans * @@author Thomas Boch [CDS] - Pierre Fernique [CDS] * @@version 0.5 : (3 mars 2003) Création */ public final class FilterProperties extends Frame implements MouseListener { private static final String SELECT = "Select"; private static final String EXPORT = "Export"; private static final String UCD = "Open UCD Browser"; private static final String FILTERHELP = "Help on syntax"; private static final String FILTERMANUAL = "Get Manual"; private static final String SAVEFILTER = "Save filter"; private static final String LOADFILTER = "Load filter"; private static final String PICKCOLUMN = "*Pick a column*"; private static final String PICKUCD = "*Pick a UCD*"; private static final String SHAPEFUNC = "*Shape functions*"; private static final String COLORFUNC = "*Color functions*"; // URL d'accès au browser d'UCD private static final String URLUCD = "http://vizier.u-strasbg.fr/UCD/UCD/java/"; private static final String[] UCDBASE = {"CLASS*","PHOT*"}; FileDialog fd = null; // Les references aux objets Aladin aladin; PlanFilter plan; // mémoire du label et du script String oscript, olabel; // Les composantes de l'objet private Panel panel; // Le panel de la frame private int hcmemo=0; // Memorisation du hashcode du plan memorise private boolean flagHide=true; // Vrai si la fenetre est cache private boolean computeCol=true; // flag indiquant si on doit recalculer l'ensemble des colonnes et UCD dispos private boolean pickUCDMode = false; // vrai si on est en mode "pick UCD" private boolean pickColumnMode = false; // vrai si on est en mode "pick column" // Widgets private TextField label; // Le label du plan // partie supprimée //CheckboxGroup state=null; // Etat actif/non-active //Checkbox viewableCb, hiddenCb;// Checkboxs pour le CheckboxGroup state private TextArea filterDef; // Pour entrer/modifier la definition du filtre private String saveDef; // Sauvegarde de la definition du filtre private Choice predefFilters; // Pour choisir un filtre predefini private PopupMenu popup; // PopupMenu d'aide à l'écriture (UCD,colonnes, actions) private Menu columnMenu; // Pour choisir une colonne directement private Menu currentUcdMenu; // contient les UCDs correspondant aux cats chargés private Label titre; private int oldIndex = 0; // index sauvegardant la derniere position dans predefFilters /** Creation du Frame donnant les proprietes d'un PlanFilter * @@param aladin Reference */ protected FilterProperties(Aladin aladin) { super("Filter"); // quel titre ?? setBackground(Aladin.BKGD); this.aladin = aladin; // Pour contourner le bug sous Linux/KDE/ super.show(); if( !Aladin.LSCREEN ) move(400,300); else move(800,400); super.hide(); } // partie supprimée /* // met à jour l'état du plan lorsqu'on n'a pas besoin de reconstruire tout le panel private void majState(PlanFilter p) { // maj de viewable/hidden hiddenCb.setState(!p.active); viewableCb.setState(p.active); } */ // Initialisation d'un Panel en fonction d'un plan void showProp(PlanFilter p) { flagHide=false; if( panel!=null ) { if( !oscript.equals(p.script) ) filterDef.setText(p.script); if( !olabel.equals(p.label) ) label.setText(p.label); } oscript = p.script; olabel = p.label; if( hcmemo==p.hashCode() ) { // partie supprimée //majState(p); if( computeCol ) updateUCDAndColumn(); if( isShowing() ) return; show(); return; } boolean noPack = (hcmemo!=0); hcmemo = p.hashCode(); // On remet a null ce qui est necessaire // partie supprimée //state=null; saveDef = ""; plan = p; if( panel!=null ) remove(panel); panel = new Panel(); panel.setLayout( new BorderLayout(5,5) ); titre = new Label("Properties of the filter ``"+plan.label+"''",Label.CENTER); titre.setFont( Aladin.LBOLD ); Aladin.makeAdd(panel,titre,"North"); Aladin.makeAdd(panel,propertiesPlan(),"Center"); Aladin.makeAdd(panel,valid(),"South"); Aladin.makeAdd(this,panel,"Center"); // partie supprimée //majState(p); if( !noPack ) pack(); show(); } /** Maj de la fenetre des Properties en fonction de l'etat du * bouton PROP de la toolbar et du plan courant */ protected void majProp() { int n=aladin.calque.getFirstSelected(); // FilterProperties ne gère que les PlanFilter if( n>=0 && aladin.calque.plan[n].type!=Plan.FILTER ) return; if( aladin.toolbox.tool[ToolBox.FILTER].mode==Tool.DOWN ) { //int n=aladin.calque.getFirstSelected(); if( n>=0 && aladin.calque.plan[n].type==Plan.FILTER ) { showProp((PlanFilter)aladin.calque.plan[n]); return; } } if( !flagHide ) hide(); } /** Construction du panel des boutons de validation * @@return Le panel contenant les boutons Apply/Close */ protected Panel valid() { Panel p = new Panel(); p.setLayout( new FlowLayout(FlowLayout.CENTER)); p.setFont( Aladin.LBOLD ); p.add( new Button("Apply")); p.add( new Button("Close")); return p; } /** Construction du panel des proprietes du plan courant. * @@return Le panel des proprietes du plan courant */ protected Panel propertiesPlan() { GridBagConstraints c = new GridBagConstraints(); GridBagLayout g = new GridBagLayout(); c.fill = GridBagConstraints.BOTH; // J'agrandirai les composantes Panel p = new Panel(); p.setLayout(g); // le label associe au plan label = new TextField(plan.label,15); Properties.addCouple(p, "Label:", label, g,c); // partie supprimée /* // La visualisation active ou non Panel pstate = new Panel(); pstate.setLayout( new FlowLayout(FlowLayout.LEFT)); state = new CheckboxGroup(); hiddenCb = new Checkbox("hidden",!plan.active,state); viewableCb = new Checkbox("viewable",plan.active,state); pstate.add( hiddenCb ); pstate.add( viewableCb ); Properties.addCouple(p,"State:", pstate, g,c); */ // si le plan est un PlanFilter et que la def est vide, il est actif par defaut if( plan.script.length()==0 ) { plan.active = true; } Properties.addFilet(p,g,c); PlanFilter pFilter = (PlanFilter)plan; // Possibilite de choisir dans la liste deroulante un filtre predefini Label l2 = new Label("Choose a predefined filter"); l2.setFont(Aladin.BOLD); c.gridwidth = GridBagConstraints.REMAINDER; g.setConstraints(l2,c); p.add(l2); // création et ajout d'éléments à predefFilters createPredefFilters(); Properties.addCouple(p, "Predefined filters", predefFilters,g,c); Label l1 = new Label("Or enter your own filter definition"); l1.setFont(Aladin.BOLD); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; g.setConstraints(l1,c); p.add(l1); // Panel avec les 2 boutons d'aide Panel helpPanel = new Panel(); helpPanel.setLayout( new BorderLayout(2,2) ); // Bouton ouvrant la frame d'aide Button helpFilterBtn = new Button(FILTERHELP); helpFilterBtn.setFont(Aladin.LBOLD); // Bouton pour obtenir le manuel d'aide Button manualFilterBtn = new Button(FILTERMANUAL); manualFilterBtn.setFont(Aladin.LBOLD); helpPanel.add(helpFilterBtn,BorderLayout.NORTH); helpPanel.add(manualFilterBtn,BorderLayout.SOUTH); c.gridwidth = GridBagConstraints.RELATIVE; c.weightx = 0.0; c.fill = GridBagConstraints.NONE; g.setConstraints(helpPanel,c); p.add(helpPanel); // TextArea pour entrer sa propre definition de filtre // reduction a la demande de Francois O. (60 a 50) filterDef = new TextArea(9,50); // ajout listener pour permettre le déroulement du PopupMenu sur click droit filterDef.addMouseListener(this); // font plus lisible que celle par defaut filterDef.setFont(Aladin.COURIER); filterDef.setText(plan.script); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; c.fill = GridBagConstraints.BOTH; g.setConstraints(filterDef,c); p.add(filterDef); // boutons permettant de sauvegarder/charger un filtre (mode STANDALONE only) if( Aladin.STANDALONE ) { Button saveFilter = new Button(SAVEFILTER); Button loadFilter = new Button(LOADFILTER); Panel loadSavePanel = new Panel(); loadSavePanel.setLayout(new FlowLayout()); loadSavePanel.add(saveFilter); loadSavePanel.add(loadFilter); c.gridx=1; c.gridwidth = GridBagConstraints.REMAINDER; g.setConstraints(loadSavePanel,c); p.add(loadSavePanel); c.gridx=0; } // PopupMenu pour aide à la syntaxe if( popup==null ) { createPopup(); } filterDef.add(popup); if( computeCol ) updateUCDAndColumn(); Properties.addFilet(p,g,c); // partie (temporairement ?) supprimée // Mark veut le retour du bouton EXPORT // boutons SELECT et EXPORT Panel pBtns = new Panel(); GridBagConstraints cc = new GridBagConstraints(); GridBagLayout gg = new GridBagLayout(); cc.fill = GridBagConstraints.BOTH; cc.insets = new Insets(1,3,1,3); pBtns.setLayout(gg); //Button bSelect = new Button(SELECT); //Label lSelect = new Label("Select all filtered sources"); Button bExport = new Button(EXPORT); Label lExport = new Label("Create a new plane with all filtered sources"); //Button bUCD = new Button(UCD); //Label lUCD = new Label("Open the UCD browser in your navigator window"); //cc.gridwidth = GridBagConstraints.RELATIVE; //cc.weightx = 0.0; //gg.setConstraints(bSelect,cc); //pBtns.add(bSelect); //cc.gridwidth = GridBagConstraints.REMAINDER; //cc.weightx = 1.0; //gg.setConstraints(lSelect,cc); //pBtns.add(lSelect); cc.gridwidth = GridBagConstraints.RELATIVE; cc.weightx = 0.0; gg.setConstraints(bExport,cc); pBtns.add(bExport); cc.gridwidth = GridBagConstraints.REMAINDER; cc.weightx = 1.0; gg.setConstraints(lExport,cc); pBtns.add(lExport); //cc.gridwidth = GridBagConstraints.RELATIVE; //cc.weightx = 0.0; //gg.setConstraints(bUCD,cc); //pBtns.add(bUCD); //cc.gridwidth = GridBagConstraints.REMAINDER; //cc.weightx = 1.0; //gg.setConstraints(lUCD,cc); //pBtns.add(lUCD); g.setConstraints(pBtns, c); p.add(pBtns); Properties.addFilet(p,g,c); //*/ Properties.addFilet(p,g,c); return p; } // Méthodes implémentant l'interface MouseListener public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) {} // en affichant le popup sur l'evt mouseReleased, on évite de mauvaises surprises liées au WM public void mouseReleased(MouseEvent e) { int modifiers = e.getModifiers(); // le popup se déroule sur un right click, ou un click+control par exemple if( ( modifiers & ~(MouseEvent.BUTTON1_MASK) )>0 ) { popup.show(filterDef,e.getX(),e.getY()); } } public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} // crée et initialise le popup private void createPopup() { popup = new PopupMenu(); columnMenu = new Menu("-- Choose a column --"); Menu ucdMenu = new Menu("-- Choose a UCD --"); Menu actionMenu = new Menu("-- Choose an action"); popup.add(columnMenu); popup.add(ucdMenu); popup.add(actionMenu); // le remplissage de columnMenu se fait ailleurs // remplissage partiel de ucdMenu Menu freqUcdMenu = new Menu("Frequenly used UCDs"); MenuItem mi; for( int i=0;i=s.leg.field.length ) return true; if( pickColumnMode ) { String col = s.leg.field[index].name; col = col!=null?col:""; filterDef.insert("${"+col+"}",filterDef.getCaretPosition()); pickColumnMode = false; toFront(); return true; } if( pickUCDMode ) { String ucd = s.leg.field[index].ucd; ucd = ucd!=null?ucd:""; filterDef.insert("$["+ucd+"]",filterDef.getCaretPosition()); pickUCDMode = false; toFront(); return true; } return false; } /** Remplissage du Choice columnChooser * PREconditions : columnChooser != null */ private void updateUCDAndColumn() { Aladin.trace(3,"Recompute all available columns and UCD"); Vector vCol = new Vector(); // pour mémoriser les noms de colonnes Vector vUCD = new Vector(); // pour mémoriser les noms des UCD Plan p; Objet[] o; Source s; String str; // boucle sur les plans : on récupères tous les noms de colonnes existant for( int i=aladin.calque.plan.length-1;i>=0;i-- ) { p = aladin.calque.plan[i]; if( p.type == Plan.CATALOG ) { o = p.pcat.o; if( o==null ) continue; for( int j=o.length-1;j>=0;j-- ) { // pour chaque source, on récupère les noms de colonnes (oui, c'est un peu lourd) if( o[j] instanceof Source) { s=(Source)o[j]; for( int k=s.leg.field.length-1;k>=0;k-- ) { str = s.leg.field[k].name; if( vCol.indexOf(str)<0 ) vCol.addElement(str); str = s.leg.field[k].ucd; if( str!=null && str.length()>0 && vUCD.indexOf(str)<0 ) vUCD.addElement(str); } } } } } String[] columns = new String[vCol.size()]; vCol.copyInto(columns); vCol = null; String[] ucds = new String[vUCD.size()]; vUCD.copyInto(ucds); vUCD = null; // on trie les noms de colonnes dans l'ordre alphabétique sortLexico(columns); sortLexico(ucds); columnMenu.removeAll(); currentUcdMenu.removeAll(); // pour sélectionner une colonne dans la frame des mesures columnMenu.add(PICKCOLUMN); columnMenu.add("-"); MenuItem mi; // ajout de tous les noms de colonnes for( int i=0;i * Rq : on test le precedent etat de l'image courante afin de s'eviter * un travail deja fait * Rq : on cache la fenetre s'il n'y a pas d'image de base adequate */ protected void majCM() { if( aladin.toolbox.tool[ToolBox.COLOR].mode==Tool.DOWN ) { memoControl(); PlanImage p = (PlanImage)aladin.calque.getPlanBase(); if( p!=null && p.flagOk ) { int newEtat = p.getEtat(); // On a change l'image et pas seulement la CM if( etat==-1 || (etat!=newEtat && newEtat%2!=1) ) { etat=newEtat; showCM(p); } } return; } dispose(); } /** Construction du panel en fonction de l'image en parametre. * @@param pimg l'image courante */ protected void showCM(PlanImage pimg) { boolean doPack=false; this.pimg = pimg; // J'enleve toute les precedentes composantes if( p!=null ) remove(p); else doPack=true; p = new Panel(); GridBagLayout g = new GridBagLayout(); p.setLayout(g); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.NONE; c.gridwidth = GridBagConstraints.REMAINDER; // Le titre MyLabel titre = new MyLabel(TITRE+"\nfor "+pimg.objet,Label.CENTER); titre.setFont(Aladin.LBOLD); g.setConstraints(titre,c); p.add(titre); // Indication pour remplir le formulaire Panel p1 = new Panel(); MyLabel methode = new MyLabel(METHODE); g.setConstraints(methode,c); p1.add(methode); p1.add(new Button(HELP)); g.setConstraints(p1,c); p.add(p1); /* anais */ // Le gestionnaire de CM if (pimg instanceof PlanImageRGB) { if( ((PlanImageRGB)pimg).Red!=null ) { cm = new ColorMap(pimg,0); g.setConstraints(cm,c); p.add(cm); } if( ((PlanImageRGB)pimg).Green!=null ) { cm2 = new ColorMap(pimg,1); g.setConstraints(cm2,c); p.add(cm2); } if( ((PlanImageRGB)pimg).Blue!=null ) { cm3 = new ColorMap(pimg,2); g.setConstraints(cm3,c); p.add(cm3); } /* cm = new ColorMap(pimg,0); g.setConstraints(cm,c); p.add(cm); if (!((PlanImageRGB)pimg).twoColors) { cm2 = new ColorMap(pimg,1); g.setConstraints(cm2,c); p.add(cm2); } cm3 = new ColorMap(pimg,2); g.setConstraints(cm3,c); p.add(cm3); */ } else { cm = new ColorMap(pimg,-1); g.setConstraints(cm,c); p.add(cm); } // Les boutons Panel validation = new Panel(); validation.setLayout( new FlowLayout(FlowLayout.RIGHT)); validation.add( new Button(REVERSE)); /* anais */ if( ! (pimg instanceof PlanImageRGB) ) validation.add( new Button(CM)); validation.add( new Button(PREVIOUS)); validation.add( new Button(RESET)); validation.add( new Button(CLOSE)); g.setConstraints(validation,c); p.add(validation); add("Center",p); /*anais*/ //if( doPack ) pack(); show(); toFront(); if( doPack ) setResizable(false); flagHide=false; } /** Gestion des evenements */ public boolean action(Event evt, Object what) { if( CLOSE.equals(what) ) dispose(); else if( PREVIOUS.equals(what) ) { /* anais *//*cm.previous(); setCM(cm.getCM());*/previous(); } else if( RESET.equals(what) ) { /* anais *//*cm.reset(); setCM(cm.getCM());*/reset(); } else if( REVERSE.equals(what) ) reverse(); else if( HELP.equals(what) ) Aladin.info(this,MESSAGE); else if( CM.equals(what) ) changeCM(); System.gc(); return true; } /* anais */ private void reset() { if( pimg instanceof PlanImageRGB ) { if( ((PlanImageRGB)pimg).Red!=null ) cm.reset(); if( ((PlanImageRGB)pimg).Green!=null ) cm2.reset(); if( ((PlanImageRGB)pimg).Blue!=null ) cm3.reset(); /* cm.reset(); if (!((PlanImageRGB)pimg).twoColors) cm2.reset(); cm3.reset(); */ ((PlanImageRGB)pimg).createImgRGB(); aladin.view.repaint(); aladin.calque.zoom.zoomView.repaint(); } else { cm.reset(); setCM(cm.getCM()); } } /* anais */ private void previous() { if( pimg instanceof PlanImageRGB ) { if( ((PlanImageRGB)pimg).Red!=null ) { cm.previous(); ((PlanImageRGB)pimg).filterRGB(cm.triangle, 0); } if( ((PlanImageRGB)pimg).Green!=null ) { cm2.previous(); ((PlanImageRGB)pimg).filterRGB(cm.triangle, 1); } if( ((PlanImageRGB)pimg).Blue!=null ) { cm3.previous(); ((PlanImageRGB)pimg).filterRGB(cm.triangle, 2); } aladin.view.repaint(); repaint(); aladin.calque.zoom.zoomView.repaint(); /* if (!((PlanImageRGB)pimg).twoColors) { cm2.previous(); ((PlanImageRGB)pimg).filterRGB(cm2.triangle, 1); aladin.calque.zoom.zoomView.repaint(); repaint(); aladin.view.repaint(); } cm3.previous(); ((PlanImageRGB)pimg).filterRGB(cm3.triangle, 2); repaint(); aladin.view.repaint(); aladin.calque.zoom.zoomView.repaint(); */ } else { cm.previous(); setCM(cm.getCM()); } } /** Gestion du bouton REVERSE */ private void reverse() { if( pimg.video==PlanImage.VIDEO_NORMAL ) pimg.video=PlanImage.VIDEO_INVERSE; else pimg.video=PlanImage.VIDEO_NORMAL; /* anais */ if( pimg instanceof PlanImageRGB ) { if( ((PlanImageRGB)pimg).Red!=null ) { cm.pimg.video=pimg.video; cm.repaint(); } if( ((PlanImageRGB)pimg).Green!=null ) { cm2.pimg.video=pimg.video; cm2.repaint(); } if( ((PlanImageRGB)pimg).Blue!=null ) { cm3.pimg.video=pimg.video; cm3.repaint(); } /* cm.pimg.video=cm3.pimg.video=pimg.video; cm.repaint(); if (!((PlanImageRGB)pimg).twoColors) { cm2.pimg.video=pimg.video; cm2.repaint(); } cm3.repaint(); */ ((PlanImageRGB)pimg).inverseRGB(); aladin.view.repaint(); aladin.calque.zoom.zoomView.repaint(); } else { cm.repaint(); setCM(cm.getCM()); } } /** Gestion du bouton CMBB */ private void changeCM() { pimg.typeCM++; if( pimg.typeCM>=PlanImage.MAXCM ) pimg.typeCM=0; cm.repaint(); setCM(cm.getCM()); } /** Mise a jour par rapport a la nouvelle table des couleurs * @@param ic la nouvelle CM */ private void setCM(IndexColorModel ic) { pimg.setCM(ic); pimg.aladin.calque.zoom.zoomView.setCM(ic); } /** Memorisation des infos de controle de la tables des couleurs */ private void memoControl() { if( pimg==null ) return; // Memorisation du control de la table des couleurs /*anais*/ if( pimg instanceof PlanImageRGB ) { for( int i=0; i<3; i++ ) { PlanImageRGB pRGB = (PlanImageRGB)pimg; if( pRGB.Red!=null ) pRGB.RGBControl[i]=cm.triangle[i]; if( pRGB.Green!=null ) pRGB.RGBControl[3+i]=cm2.triangle[i]; if( pRGB.Blue!=null ) pRGB.RGBControl[6+i]=cm3.triangle[i]; } } else { for( int i=0; i<3; i++ ) pimg.cmControl[i]=cm.triangle[i]; } } /** Fermeture de la Frame. * Cache la fenetre et remonte le bouton * des properties */ public void dispose() { if( flagHide ) return; memoControl(); if( aladin.calque.getPlanBase()!=null ) aladin.toolbox.tool[ToolBox.COLOR].mode=Tool.UP; else aladin.toolbox.tool[ToolBox.COLOR].mode=Tool.UNAVAIL; aladin.toolbox.repaint(); flagHide=true; etat=-1; super.dispose(); } /** Trap sur l'evenement WINDOW_DESTROY */ public boolean handleEvent(Event e) { if( e.id==Event.WINDOW_DESTROY ) dispose(); return super.handleEvent(e); } } * des boutons. La mise a jour se fera sur l'image de base *

* Rq : on test le precedent etat de l'image courante afin de s'eviter * un travail deja fait * Rq : on cache la fenetre s'il n'y a pas d'image de base adequate */ protected void majCM() { if( aladin.toolbox.tool[ToolBox.COLOR].mode==Tool.DOWN ) { mcds/aladin/FrameContour.java010064400076440000132000000432670770227416100170330ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; /** * Gestion de la fenetre associee a la creation d'un plan Contour * * @@author Thomas Boch [CDS] * @@version 1.0 : (22 fevrier 2002) Creation */ public final class FrameContour extends Frame { static final String CLOSE = "Close"; static final String RESET = "Reset"; static final String SUBMIT = "Get Contour"; static final String NEWLEVEL = "New Level"; static final String SHOWHELP = "Show HELP"; static final String HIDEHELP = "Hide HELP"; static final String SMOOTHINFO = "Smoothing decreases the size of the original picture\n"+ "This allows a faster computation and a reduction \n"+ "of the number of control points"; static final String NOISEINFO = "When active, reduces the noise in the contours by \n"+ "computing a running average\n"+ "(doesn't reduce the number of pixels)"; static final String ZOOMINFO = "Choose whether contours are computed on\n"+ "the whole image or on the current view"; /*static final String ALGOINFO = "2 algorithms are available\n"+ "contourplot draws finer contours and is recommended ";*/ static final Font HELPFONT = new Font("Monospaced",Font.PLAIN,10); boolean showHelp = false; // faut-il montrer les labels d'aide ? boolean flagHide = true; Panel p; // panel principal Label lab1 = new Label(" Smooth level"); MyLabel smoothInfo = new MyLabel(SMOOTHINFO,Label.CENTER,HELPFONT); MyLabel noiseInfo = new MyLabel(NOISEINFO,Label.CENTER,HELPFONT); MyLabel zoomInfo = new MyLabel(ZOOMINFO,Label.CENTER,HELPFONT); //MyLabel algoInfo = new MyLabel(ALGOINFO,Label.CENTER,HELPFONT); Button helpBtn; // bouton pour afficher/masquer l'aide Checkbox cb; // utilise-t-on le smoothing ? Checkbox noisecb; // reduction du bruit ? //Checkbox conrec; //Checkbox contourplot; PlanImage pimg; Choice nbLevelsChoice; Choice smooothLevelChoice; CheckboxGroup cGroup; Checkbox currentZoomOnly; Panel pHist; private Color[] couleurs = null; // tableau des couleurs pour les curseurs private int[] indicesCouleurs = null; // tableau des indices dans Couleur.DC des couleurs static final String TITRE = "Contours plotting"; private double[] levels; // tableaux des valeurs entres par l'utilisateur // Les references aux objets Aladin a; Curseur curs; int etat = -1; // // Memorisation de l'etat de l'image /** Creation du Frame gerant la creation d'un plan Contour. * @@param aladin Reference */ protected FrameContour(Aladin aladin) { super(TITRE); setBackground(Aladin.BKGD); this.a = aladin; pimg = (PlanImage) a.calque.getPlanBase(); move(350,200); curs = new Curseur(); initCouleurs(); fillCouleurTriangle(); } // Creation du panel de la fenetre private void createPanel() { if (p!=null) remove(p); setLayout( new BorderLayout(5,5)); p = new Panel(); GridBagLayout g = new GridBagLayout(); p.setLayout(g); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.NONE; c.gridwidth = GridBagConstraints.REMAINDER; // Le titre Label titre = new Label("Contours plotting",Label.CENTER); titre.setFont(Aladin.LBOLD); g.setConstraints(titre,c); p.add(titre); MyLabel myLab = new MyLabel("Choose the level values"); g.setConstraints(myLab,c); p.add(myLab); // panel de l'histogramme pHist = new Panel(); pHist.setLayout( new FlowLayout(FlowLayout.CENTER)); Histogramme hist = new Histogramme(pimg); pHist.add(hist); g.setConstraints(pHist,c); p.add(pHist); // panel du curseur Panel pCursor = new Panel(); pCursor.setLayout( new FlowLayout(FlowLayout.CENTER)); pCursor.add(curs); g.setConstraints(pCursor,c); p.add(pCursor); // panel de generation automatique des niveaux Panel pGenerate = new Panel(); pGenerate.setLayout( new FlowLayout(FlowLayout.CENTER)); pGenerate.add(new Label("Generate")); nbLevelsChoice = new Choice(); for(int i=2;i<=10;i++) { nbLevelsChoice.add(new Integer(i).toString()); } for(int i=12;i<=PlanContour.MAXLEVELS;i+=2) { nbLevelsChoice.add(new Integer(i).toString()); } nbLevelsChoice.select("4"); pGenerate.add(nbLevelsChoice); pGenerate.add(new Label("levels evenly spaced")); // on envoie l'evt MOUSE_DOWN pour generer les niveaux action(new Event(nbLevelsChoice,Event.MOUSE_DOWN,nbLevelsChoice), nbLevelsChoice); g.setConstraints(pGenerate,c); p.add(pGenerate); Panel pNewLevel = new Panel(); pNewLevel.setLayout( new FlowLayout(FlowLayout.CENTER)); pNewLevel.add(new Label("Manually add a")); pNewLevel.add(new Button(NEWLEVEL)); g.setConstraints(pNewLevel,c); p.add(pNewLevel); // label d'aide sur le lissage //smoothInfo.setFont(HELPFONT); smoothInfo.setVisible(showHelp); g.setConstraints(smoothInfo,c); p.add(smoothInfo); // panel utilisation du lissage Panel pLissage = new Panel(); pLissage.setLayout( new FlowLayout(FlowLayout.CENTER)); cb = new Checkbox("Use smoothing",null,false); cb.setState(true); smooothLevelChoice = new Choice(); smooothLevelChoice.add(new Integer(2).toString()); smooothLevelChoice.add(new Integer(3).toString()); smooothLevelChoice.add(new Integer(4).toString()); smooothLevelChoice.select("2"); smooothLevelChoice.enable(); lab1.enable(); pLissage.add(cb); pLissage.add(lab1); pLissage.add(smooothLevelChoice); g.setConstraints(pLissage,c); p.add(pLissage); // label d'aide sur reduction du bruit //noiseInfo.setFont(HELPFONT); noiseInfo.setVisible(showHelp); g.setConstraints(noiseInfo,c); p.add(noiseInfo); // reduction du bruit Panel pNoise = new Panel(); pNoise.setLayout( new FlowLayout(FlowLayout.CENTER)); noisecb = new Checkbox("Reduce noise",null,true); pNoise.add(noisecb); g.setConstraints(pNoise,c); p.add(pNoise); // label d'aide sur current view //zoomInfo.setFont(HELPFONT); zoomInfo.setVisible(showHelp); g.setConstraints(zoomInfo,c); p.add(zoomInfo); // checkbox "dessine t on les contours sur toute l'image" ? currentZoomOnly = new Checkbox("Consider only current zoom",false); g.setConstraints(currentZoomOnly,c); p.add(currentZoomOnly); // label d'aide sur les algos /*algoInfo.setVisible(showHelp); g.setConstraints(algoInfo,c); p.add(algoInfo);*/ // checkboxs pour savoir quel algo on utilise /*Panel p1 = new Panel(); p1.setLayout( new FlowLayout(FlowLayout.RIGHT)); cGroup = new CheckboxGroup(); conrec = new Checkbox("Use conrec", cGroup, false); contourplot = new Checkbox("Use contourplot", cGroup, true); p1.add(conrec); p1.add(contourplot); g.setConstraints(p1,c); p.add(p1);*/ // panel de l'aide helpBtn = new Button(showHelp?HIDEHELP:SHOWHELP); g.setConstraints(helpBtn,c); p.add(helpBtn); // panel des boutons Panel pButtons = new Panel(); pButtons.setLayout( new FlowLayout(FlowLayout.RIGHT)); pButtons.add( new Button(SUBMIT)); pButtons.add( new Button(RESET)); pButtons.add( new Button(CLOSE)); g.setConstraints(pButtons,c); p.add(pButtons); add("Center",p); pack(); show(); //toFront(); flagHide = false; } // Visualisation de la fenetre public void show() { initCouleurs(); fillCouleurTriangle(); super.show(); flagHide=false; } public void hide() { if( a.calque.getPlanBase()!=null ) a.toolbox.tool[ToolBox.CONTOUR].mode=Tool.UP; else a.toolbox.tool[ToolBox.CONTOUR].mode=Tool.UNAVAIL; a.toolbox.repaint(); flagHide=true; etat=-1; super.hide(); } /** Mise a jour de la fenetre si necessaire*/ protected void majContour() { if( a.toolbox.tool[ToolBox.CONTOUR].mode==Tool.DOWN ) { PlanImage p = (PlanImage)a.calque.getPlanBase(); if( p!=null && p.flagOk && !(p instanceof PlanImageRGB)) { int newEtat = p.getEtat(); if (showHelp) move(350,70); else move(350,200); if( etat!=newEtat) { etat=newEtat; this.pimg = (PlanImage)p; createPanel(); } } return; } hide(); } /** Fermeture de la Frame. */ /*public void dispose() { if( flagHide ) return; if( a.calque.getPlanBase()!=null ) a.toolbox.tool[ToolBox.CONTOUR].mode=Tool.UP; else a.toolbox.tool[ToolBox.CONTOUR].mode=Tool.UNAVAIL; a.toolbox.repaint(); flagHide=true; etat=-1; super.dispose(); }*/ // remplit curs.couleurTriangle en fonction de indicesCouleurs private void fillCouleurTriangle() { int i; for(i=0;iscreenSize.width-50 ) p.x = screenSize.width-50; if( p.y>screenSize.height-50 ) p.y = screenSize.height-50; //System.out.println(p); return p; } private boolean firstUpdate = true; /** MAJ de la frame avec les infos de node */ public void update(ResourceNode node,MetaDataTree tree) { grabMode = false; this.node = node; this.tree = tree; // à la première update, on positionne la frame if( firstUpdate ) { firstUpdate = false; Point pos = computeAbsLoc(); move(pos.x,pos.y); } infoPanel.removeAll(); GridBagLayout g = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); infoPanel.setLayout(g); // maj cutout target if( node.isLeaf && (node.cutout || node.type==ResourceNode.CAT) ) { // si il n'y a pas encore de target pour le cutout, on prend celui du server if( node.getCutoutTarget()==null && node.server!=null ) { node.setCutoutTarget(node.server.getTarget(false),false); } String cTarget = node.getCutoutTarget(); if( cTarget!=null ) target.setText(cTarget); } // maj du nom namePanel.removeAll(); Label name = new Label(node.name); name.setFont(Aladin.BOLD); namePanel.add(name); // maj de btnPanel btnPanel.removeAll(); btnPanel.add(lockBtn); if( node.type==ResourceNode.IMAGE ) btnPanel.add(fovBtn); if( node.isLeaf ) btnPanel.add(btnLoad); btnPanel.add(closeBtn); // affichage ou non de cutoutPanel if( node.isLeaf && node.cutout ) cutoutPanel.setVisible(true); else cutoutPanel.setVisible(false); // affichage ou non de formatPanel // si il n'y a qu'un format, on ne va pas l'afficher ! if( node.isLeaf && node.formats!=null && node.formats.length>1 ) { formatPanel.removeAll(); fmt = new CheckboxGroup(); formatPanel.add( new Label("Get in:")); boolean selected; for( int i=0; i0 ) { part1 = node.catDesc.substring(0,index); part2 = node.catDesc.substring(index); } Label lPart1 = new Label(part1); lPart1.setFont(Aladin.SBOLD); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; g.setConstraints(lPart1,c); infoPanel.add(lPart1); if( part2!=null ) { Label lPart2 = new Label(part2); lPart2.setFont(Aladin.SBOLD); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; g.setConstraints(lPart2,c); infoPanel.add(lPart2); } // affichage des infos dispos // pour toutes les descriptions displayInfo(node, g, c); } } /* EOF if BasicNode.CAT */ Filet f = new Filet(); g.setConstraints(f,c); // pour que le panel d'info se mette a jour infoPanel.invalidate(); infoPanel.validate(); pack(); } // affiche dans infoPanel toutes les infos (tableaux description et explanation) relatives au noeud node private void displayInfo(ResourceNode node, GridBagLayout g, GridBagConstraints c) { if( node.description == null || node.explanation == null ) return; // affichage des infos dispos // pour toutes les descriptions for( int i=0; i60 ) { l2 = new Label(node.explanation[i].substring(0,57)+"..."); } */ l2.setFont(Aladin.SBOLD); c.gridwidth = GridBagConstraints.RELATIVE; c.weightx = 0.0; g.setConstraints(l1,c); infoPanel.add(l1); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; g.setConstraints(l2,c); infoPanel.add(l2); } } // cree les differents components necessaires private void createComponents() { // Les panels //Le choix du format de l'image //fmt = new CheckboxGroup(); formatPanel = new Panel(); formatPanel.setLayout( new FlowLayout(FlowLayout.LEFT)); /*String JPG="JPEG"; String MRC="MRCOMP"; String FITS="FITS"; formatPanel.add( new Label("Get in:")); formatPanel.add( new Checkbox(JPG,true,fmt)); if( Aladin.MRDECOMP ) formatPanel.add( new Checkbox(MRC,false,fmt)); formatPanel.add( new Checkbox(FITS,false,fmt));*/ formatPanel.setFont(Aladin.PLAIN); grabBtn = new Button("Grab"); /*grabBtn.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { grabMode = true; } } );*/ grabBtn.setFont(Aladin.SBOLD); fovBtn = new Button("FoV in stack"); lockBtn = new Button("Lock"); /*lockBtn.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { isLocked = true; lockBtn.setEnabled(false); } } );*/ closeBtn = new Button("Close"); /*closeBtn.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { hide(); } } );*/ /** Les boutons */ // bouton pour demander l'affichage du FOV // n'est plus utilisé /* btnFov = new Button("Display/hide image field"); btnFov.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { tree.fovAction(node); } } ); */ // bouton pour cacher tous les champs // n'est plus utilisé /* btnHide = new Button("Hide all fields"); btnHide.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { tree.hideAllFovs(); tree.unframeAll(); repaint(); } } ); */ // bouton pour charger l'image/le catalogue directement btnLoad = new Button("LOAD"); btnLoad.setFont(Aladin.BOLD); /*btnLoad.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { node.setCutoutTarget(target.getText(),false); tree.load(node); } } );*/ // bouton pour demander l'affichage de tous les FOV du niveau // n'est plus utilisé /*showAllLevBtn = new Button("Show all image fields for this level"); showAllLevBtn.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { tree.showAllLev(node); tree.frameNode(node); tree.repaint(); //aladin.calque.view.repaint(); } } );*/ // bouton pour demander l'affichage de tous les FOV du niveau // n'est plus utilisé /*hideAllLevBtn = new Button("Hide all image fields for this level"); hideAllLevBtn.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { tree.hideAllLev(node); tree.unframeNode(node); tree.repaint(); //aladin.calque.view.repaint(); } } );*/ // bouton Expand/Collapse // n'est plus utilisé /* expandBtn = new Button("Expand/Collapse this node"); expandBtn.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { node.changeState(); tree.doDisplay(); tree.repaint(); } } ); */ } boolean inGrabMode() { return grabMode; } /** renvoie le noeud pour lequel on affiche les infos */ ResourceNode getNode() { return this.node; } /** fixe le target du cutout (ou du catalogue) de la ressource courante * @@param t le target */ void setTarget(String t) { // remarque : la maj du TextField target se fait par effet de bord dans ResourceNode node.setCutoutTarget(t); //target.setText(t); toFront(); grabMode = false; } // met à jour le TextField target void setTargetTF(String t) { target.setText(t); } public boolean action(Event e, Object o) { // grab du cutout target if( e.target.equals(grabBtn) ) { grabMode = true; } // "lock" de la fenêtre else if( e.target.equals(lockBtn) ) { isLocked = true; lockBtn.setEnabled(false); } // fermeture de la fenêtre else if( e.target.equals(closeBtn) ) { hide(); } // export du fov dans le stack --> A FAIRE else if( e.target.equals(fovBtn) ) { Aladin.aladin.calque.newPlanFov("FoV for "+node.name,tree.getFovs(node)); Aladin.aladin.view.repaint(); } // Chargement de la ressource else if( e.target.equals(btnLoad) ) { node.setCutoutTarget(target.getText(),false); tree.load(node); } // les checkboxes else if( e.target instanceof Checkbox ) { Checkbox cb = (Checkbox)e.target; // changement du format if( fmt.getSelectedCheckbox().equals(cb) ) { node.curFormat = cb.getLabel(); } } return true; } /** Retourne l'instance courante */ static public FrameInfo getInstance() { if( curInstance==null || curInstance.isLocked ) { curInstance = new FrameInfo(); } return curInstance; } /* public Insets getInsets() { return new Insets(10,10,10,10); } */ /** Méthodes implémentant WindowListener */ /** Windows closing * * @@param e window event */ public void windowClosing(WindowEvent e){ hide(); } /** Window Closed * * @@param e WindowEvent */ public void windowClosed(WindowEvent e){ hide(); } // Méthodes ne servant pas public void windowOpened(WindowEvent e){} public void windowDeactivated(WindowEvent e){} public void windowActivated(WindowEvent e){} public void windowDeiconified(WindowEvent e){} public void windowIconified(WindowEvent e){} // /!\ Déconne, et je sais pas pourquoi public boolean mouseExit(Event e, int x, int y) { //System.out.println("on EXIT de : " + e.target); tree.hideFov(); tree.deactivateCutoutFov(); return true; } public boolean mouseEnter(Event e, int x, int y) { //System.out.println("on ENTER : " + e.target); if( /*node.isLeaf && */node.type==ResourceNode.IMAGE ) { tree.showFov(node); if(node.cutout) { tree.showCutoutFov(node); } } return true; } public void mousePressed(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} } ndcds/aladin/FrameMesure.java010064400076440000132000000103560770227416100166330ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.astro.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion de la fenetre "externe" associee aux mesures * * @@author Pierre Fernique [CDS] * @@version 1.0 : (22 fevrier 2002) Creation */ public final class FrameMesure extends Frame { // Les references aux objets Aladin a; /** Creation du Frame gerant la creation d'un plan RGB. * @@param aladin Reference */ protected FrameMesure(Aladin aladin) { super("Aladin Java measurements frame"); setBackground(Aladin.BKGD); this.a = aladin; // pour le bug sous KDE super.show(); // test (bug KDE) , le move est effectué entre un show() et un hide() if( !Aladin.LSCREEN ) move(400,300); else move(800,400); super.hide(); a.mesurePanel.remove(a.mesure); a.validate(); a.repaint(); Aladin.makeAdd(this,a.mesure,"Center"); int deltaY=600; a.mesure.split(true); pack(); show(); } protected void close() { remove(a.mesure); dispose(); Aladin.makeAdd(a.mesurePanel,a.mesure,"Center"); a.split.in(); int deltaY=-600; a.mesure.split(false); a.validate(); a.repaint(); } // Gestion des evenement public boolean handleEvent(Event e) { // On supprime le frame if( e.id==Event.WINDOW_DESTROY ) close(); return super.handleEvent(e); } } cds/aladin/FrameNewCalib.java010064400076440000132000000752230770227416100170630ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.astro.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion de la fenetre associee a la creation d'une calib manuelle * * @@author Pierre Fernique [CDS] * @@version 1.1 : (20 aout 2002) Mise en place de la methode WCS * @@version 1.0 : (23 avril 2002) Creation */ public final class FrameNewCalib extends Frame { static final int SIMPLE=0; // Methode par parametres static final int QUADRUPLET=1; // Methode par echantillonage static final int WCS=2; // Methode par header WCS static int num=0; // Numero de la projection perso static final String SUBMIT = "CREATE"; static final String MODIFY = "MODIFY"; static final String HELP = "Help"; static final String RESET = "Reset"; static final String CANCEL = "Close"; static final String ONE = "by parameters"; static final String TWO = "by matching stars"; static final String THREE = "by WCS header"; /* EN ATTENTE DE BOF */ static final String HELPSTRING = "Aladin allows you to recalibrate images following\n"+ "two different methods. You can specify the basic parameters\n"+ "to describe the new projection. You can also select a set\n"+ "of stars and their corresponding coordinates that you will\n"+ "pick from a overlaying catalog." ; /* static final String HELPSTRING = "Aladin allows you to recalibrate images by \n"+ "specifying the basic parameters to describe \n"+ "the new projection." ; */ // Les references aux objets Aladin a; Plan plan; // Le plan pour lequel on cree la nouvelle calibration Projection oldp; // En cas de modif, precedente projection // Les widgets TextField labelT,cooT,xyT,/*xyS,*/rmT,rT,rotT; TextArea wcsT; // Editeur pour le WCS Choice projChoice=null; // Choice des projections Checkbox trueSym, falseSym; // Checkbox pour la symetrie CheckboxGroup symRadio=null; // Boutons radios pour la symetrie Panel pSym; // Panel des boutons trueSym et falseSym Button submitButton; int maxPosT=30; // Le nombre max d'etoiles TextField xyPosT[]; // Textfields des XY TextField cooPosT[]; // textfields des coordonnees associees // Les variables correspondantes aux widgets String label; double raj,dej,cx,cy,rm,r,rot; boolean sym; int t; // Type de la projection TextField focusTextField=null;// Component ayant le focus (parmi xyPosT[] et cooPosT[]) boolean flagXY=false; // true si le focus est sur un element de xyPosT[] Panel panelOne,panelTwo,panelThree; // Panels methode One, Two et Three CardLayout cardMethod; // Gere la permutation entre les deux methodes Panel panelMethod; Choice methodChoice=null; // Pour choisir la methode de calibration int method; // methode SIMPLE, QUADRUPLET ou WCS Plan suivi=null; // Le plan dans lequel on dessine les croix // pour la methode QUADRUPLET double suiviHeight; // La hauteur de l'image sous le plan de suivi /** Creation du Frame gerant la creation/modification d'une projection * @@param aladin Reference * @@param p Le plan pour lequel la projection est faite * @@param oldp une eventuelle precedente projection a modifier (ou null sinon) */ protected FrameNewCalib(Aladin aladin,Plan p,Projection oldp) { super("Astronomical calibration"); setBackground(Aladin.BKGD); this.a = aladin; this.plan=p; this.oldp=oldp; if( !Aladin.LSCREEN ) move(350,380); else move(500,450); createPanel(); // setData(); pack(); majFrameNewCalib(p,oldp); } /** Mise a jour du Frame gerant la creation/modification d'une projection * @@param p Le plan pour lequel la projection est faite * @@param oldp une eventuelle precedente projection a modifier (ou null sinon) */ protected void majFrameNewCalib(Plan p) { majFrameNewCalib(p,null); } protected void majFrameNewCalib(Plan p,Projection oldp) { this.plan=p; this.oldp=oldp; setData(); show(); } /* Retourne un nouveau nom de projection */ private String getNewLabel() { return "My projection "+(++num); } // Initialisation des Widgets en fonction des variables de classes // utilise a l'ouverture de la fenetre ou lors d'un reset private void setData() { //System.out.println("FrameNewCalib on "+plan.label); if( plan.projd!=null ) { label=(oldp!=null)?plan.projd.label:getNewLabel(); try { Coord co = plan.projd.c.getProjCenter(); raj=co.al; dej=co.del; cx=co.x; cy=co.y; rm=plan.projd.c.getImgWidth()*60; r=plan.projd.c.getImgSize().width; rot=plan.projd.c.getProjRot(); sym=plan.projd.c.getProjSym(); t=plan.projd.c.getProjSys(); } catch( Exception e) { System.err.println("Error on projd: "+e); } } else { label=getNewLabel(); raj=dej=cx=cy=rm=r=rot=0.0; if( plan.type==Plan.IMAGE ) { rm=10; r=((PlanImage)plan).width; cx=((PlanImage)plan).width/2; cy=((PlanImage)plan).height/2; } sym=false; t=1; } labelT.setText(label); cooT.setText(Coord.getSexa(raj,dej," ")); xyT.setText(Math.round(cx)+" "+Math.round(cy)); rmT.setText(rm==0?"0":Coord.getUnit(rm/60.)); // xyS.setText(rm==0||r==0?"0":Coord.getUnit((rm/60.)/r)); rT.setText(r+""); rotT.setText(rot+""); setSymRadio(sym); setProjChoice(t>=0?t:0); setCoo(plan.projd); // methodChoice.setEnabled(oldp==null); submitButton.setLabel(oldp==null?SUBMIT:MODIFY); // Determination du mode de creation/modification de la projection method=SIMPLE; if( plan.projd!=null ) { if( plan.projd.type==Projection.QUADRUPLET ) method=QUADRUPLET; else if( plan.projd.type==Projection.WCS ) method=WCS; } cardMethod.show(panelMethod,method==SIMPLE?ONE:method==QUADRUPLET?TWO:THREE); if( method==QUADRUPLET ) { xyPosT[0].requestFocus(); setFocusPos(xyPosT[0]); majSuivi(); a.calque.repaint(); } // Ajustement du menu deroulement en fonction de la methode methodChoice.select(method); // Dans le cas ou l'on veut editer le WCS getWCS(plan.projd!=null?plan.projd: new Projection(label,Projection.SIMPLE,raj,dej,rm,cx,cy,r,rot,sym,1)); } /** Construction de l'entete WCS FITS dans le TextArea wcsT concerne * en fonction de la projection passee en parametre, ou vide sinon */ private void getWCS(Projection p) { StringBuffer s = new StringBuffer(); wcsT.setText(""); if( p==null ) return; Vector key = new Vector(20); Vector value = new Vector(20); try { p.c.GetWCS(key,value); } catch( Exception e ) { System.err.println("GetWCS error"); return; } Enumeration ekey = key.elements(); Enumeration evalue = value.elements(); while( ekey.hasMoreElements() ) { String skey = (String)ekey.nextElement(); String svalue = (String)evalue.nextElement(); s.append(skey+" = "+svalue+"\n"); } wcsT.setText(s.toString()); } /* // Mise a jour du champ rmT en fonction du champ xyS et r private void updatermT() { double x = Server.getRadius(xyS.getText())/60.; r= Double.valueOf( rT.getText()).doubleValue(); rmT.setText(Coord.getUnit(x*r)); } // Mise a jour du champ xyS en fonction du champ rm et r private void updatexyS() { double rm = Server.getRadius(rmT.getText()); r= Double.valueOf( rT.getText()).doubleValue(); xyS.setText(rm==0||r==0?"0":Coord.getUnit((rm/60.)/r)); } */ // Creation ou mise a jour du choix des projections // @@param type l'indice de la projection courante private void setProjChoice() { setProjChoice(1); } private void setProjChoice(int type) { if( projChoice==null ) { projChoice = new Choice(); String p[]=Calib.getProj(); for( int i=0; i=p.coo.length ) xy=co=""; else { Coord c=p.coo[i]; xy=p.coo[i].x+" "+p.coo[i].y; co=p.coo[i].getSexa(); } xyPosT[i].setText(xy); cooPosT[i].setText(co); } } /** Generation d'un tableau de Coord[] en fonction des champs TextField * de la liste des quadruplets (x,y,alpha,delta) */ private Coord[] getCoo() throws Exception { int i=0,n; Component comp=xyPosT[0]; // permet de reperer le champ en cas d'erreur Vector v = new Vector(); Coord coo[] = null; try { // Analyse des champs for( i=0; i"+max); } } } Point p = new Point(W/2-x,W/2-y); System.out.println("Corrections: "+p); return p; } /** Met a jour le plan de suivi des croix dans la methode QUADRUPLET */ private void majSuivi() { // Creation du plan de suivi si necessaire avec petite subtilite // pour que le select ne change pas lors de sa creation if( suivi==null ) { int i = a.calque.getFirstSelected(); int j = a.calque.newPlanTool("Calibration"); if( j<0 ) return; suivi = a.calque.plan[j]; suivi.c = a.calque.plan[0].c; suivi.selected=false; suiviHeight=0; a.calque.plan[i].selected=true; Plan pref= a.calque.getPlanRef(); if( pref.type==Plan.IMAGE ) suiviHeight = ((PlanImage)pref).height; } // Mise en place d'un repere par quadruplet suivi.pcat = new PlanObjet(suivi,suivi.c,a.calque,a.status,a); for( int i=0; i plan[] CheckboxGroup cbg; // Les checkBox pour determiner l'image de base Checkbox cbDiff; // Le checkbox pour indiquer une difference entre 2 plans Checkbox cbX; // Checkbox pour le plan defaut du reechantillonage /** Creation du Frame gerant la creation d'un plan RGB. * @@param aladin Reference */ protected FrameRGB(Aladin aladin) { super("RGB image generator"); setBackground(Aladin.BKGD); this.a = aladin; if( !Aladin.LSCREEN ) move(400,300); else move(800,400); choicePlan = new PlanImage[0]; createPanel(); } // Creation du panel de la fenetre private void createPanel() { GridBagConstraints c = new GridBagConstraints(); GridBagLayout g = new GridBagLayout(); c.fill = GridBagConstraints.BOTH; // J'agrandirai les composantes Panel p = new Panel(); p.setLayout(g); // le titre de la fenetre MyLabel l = new MyLabel("Specify two or three images as color components,\n"+ "choose the reference image for the re-sampling and\n"+ "press the "+SUBMIT+" button to create a RGB image plane.", Label.CENTER,Aladin.ITALIC); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; g.setConstraints(l,c); p.add(l); Label lr = new Label("1) Red:"); lr.setForeground(Color.red); lr.setFont(Aladin.BOLD); Label lg = new Label("2) Green:"); lg.setForeground(Color.green); lg.setFont(Aladin.BOLD); Label lb = new Label("3) Blue:"); lb.setForeground(Color.blue); lb.setFont(Aladin.BOLD); Label lx = new Label(" Sampling ref:"); cR = new Choice(); cR.setFont(Aladin.BOLD); cG = new Choice(); cG.setFont(Aladin.BOLD); cB = new Choice(); cB.setFont(Aladin.BOLD); cbg = new CheckboxGroup(); Checkbox cbR = new Checkbox(R); cbR.setCheckboxGroup(cbg); Checkbox cbG = new Checkbox(G); cbG.setCheckboxGroup(cbg); Checkbox cbB = new Checkbox(B); cbB.setCheckboxGroup(cbg); cbX = new Checkbox(X); cbX.setCheckboxGroup(cbg); cbg.setCurrent(cbX); c.gridwidth = GridBagConstraints.RELATIVE; c.weightx = 0.0; g.setConstraints(lr,c); p.add(lr); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 10.0; g.setConstraints(cR,c); p.add(cR); c.gridwidth = GridBagConstraints.RELATIVE; c.weightx = 0.0; g.setConstraints(lg,c); p.add(lg); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 10.0; g.setConstraints(cG,c); p.add(cG); c.gridwidth = GridBagConstraints.RELATIVE; c.weightx = 0.0; g.setConstraints(lb,c); p.add(lb); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 10.0; g.setConstraints(cB,c); p.add(cB); Panel pp = new Panel(); pp.add(lx);pp.add(cbR);pp.add(cbG);pp.add(cbB);pp.add(cbX); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 10.0; g.setConstraints(pp,c); p.add(pp); // Pour la difference entre 2 plans cbDiff = new Checkbox("images substractions"); cbDiff.disable(); c.fill = GridBagConstraints.NONE; g.setConstraints(cbDiff,c); p.add(cbDiff); c.fill = GridBagConstraints.BOTH; Panel v = valid(); g.setConstraints(v,c); p.add(v); Aladin.makeAdd(this,p,"Center"); pack(); } /** Mise a jour d'un menu deroulant contenant les labels des plans images * @@param default L'item du menu par defaut */ private void adjustImageChoice(Choice c) { adjustImageChoice(c,0); } private void adjustImageChoice(Choice c,int defaut) { int i=c.getSelectedIndex(); String s = (i>=0)?c.getItem(i):null; c.removeAll(); setItems(c); if( i>=0) c.select(s); else c.select(defaut0?1:0)+ (cG.getSelectedIndex()>0?1:0)+ (cB.getSelectedIndex()>0?1:0); boolean enabled = cbDiff.isEnabled(); boolean newEnabled = (i==2); if( enabled==newEnabled ) return; if( newEnabled ) cbDiff.enable(); else cbDiff.disable(); } // Gestion des evenement public boolean action(Event evt, Object what) { // Cancel if( CANCEL.equals(what) ) hide(); // Creation du plan RGB else if( SUBMIT.equals(what) ){ // Determination de chaque plan et du plan de reference PlanImage r=getPlan(cR),b=getPlan(cB),g=getPlan(cG),ref; String s=cbg.getCurrent().getLabel(); ref = s.equals(R)?r:s.equals(B)?b:s.equals(G)?g:null; // Doit-on appliquer une difference entre 2 plans boolean diff = cbDiff.isEnabled() && cbDiff.getState(); a.calque.newPlanImageRGB(r,g,b,ref,diff); } // Help else if( HELP.equals(what) ) Aladin.info(this,HELPSTRING); //Reset else if( RESET.equals(what) ) reset(); // Ajustement du panel en cas de changement de choix else if( evt.target instanceof Choice ) adjustCbDiff(); return true; } // Gestion des evenement public boolean handleEvent(Event e) { // On supprime le frame if( e.id==Event.WINDOW_DESTROY ) hide(); return super.handleEvent(e); } } cds/aladin/Glu.java010064400076440000132000001206200770227416100151430ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.io.InputStream; import java.util.*; //import java.io.File; //import java.io.FileNotFoundException; //import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Objet gerant les interactions avec le Generateur de Liens Uniformes (GLU). * Un objet GLU permet de resoudre des marques GLU, soit en * utilisant le "glufilter" local dans le cas d'une session standalone * soit en accedant a distance a un proxyGLU qui se chargera de faire * la resolution GLU et de retourner le resultat. *

* Chaque resolution GLU (standalone ou non) generera un log distant * via une requete HTTP *

* Rq Dans le cas ``standalone'' il est indispensable que le dico GLU * additionnel pour Aladin JAVA se trouve dans le repertoire d'installation * et se nomme ALAGLU * * @@author Pierre Fernique [CDS] * @@contributor Andre Schaaff [CDS] * @@version 1.6 : 16 dec 02 - Prise en compte de Mozilla * @@version 1.5 : 13 mai 02 - Adaptation pour utilisation hors package Aladin * [A. Schaaff] (avant remplacement complet par Jglu) * @@version 1.4 : 4 mars 02 - Meilleur gestion de l'acces au dico GLU distant * @@version 1.3 : 20 mars 00 - gestion d'un log asynchrone * @@version 1.2 : 2 juin 99 - demarrage du browser sous Windows + bug cutParam * @@version 1.1 : 26 mai 99 - Alternative du Glu en java * @@version 1.0 : (5 mai 99) - Toilettage du code * @@version 0.9 : (??) creation */ public final class Glu implements Runnable { /** Nom du dico GLU additionnel pour Aladin Java en ``standalone'' */ protected static String ALADINDIC = Aladin.HOME+Aladin.ALAGLU; /** URL d'envoi des logs */ protected static String LOGSCRIPT = "nph-alalog.pl"; protected static String ALADINLOG = "http://aladin.u-strasbg.fr/java/"+LOGSCRIPT; /** Commande glufilter locale pour Aladin Java en ``standalone'' */ protected static String GLUFILTER; // null s'il faut utilise GLU java inside private String[] NETSCAPE = { "netscape","mozilla","Netscape" }; Aladin aladin; // Reference Thread thread; // Thread pour mettre a jour le log String param; // Les elements du log static int nWindow=0; // Numero de la fenetre netscape static boolean newWindow=false; // true - showDocument dans une nouvelle fenetre /** Memorisation des serveurs definis par le dictionnaire GLU */ protected static Vector vGluServer; /** Creation de l'objet GLU. *
En mode Standalone, met a jour la variable ``glufilter'' * (cherche dans le repertoire d'installation Aladin.HOME, puis dans * /usr/local/glu) * @@param aladin reference */ protected Glu(Aladin aladin) { this.aladin=aladin; aladinDic = new Hashtable(); vGluServer = new Vector(5); // Methode propre a la version Standalone if( Aladin.STANDALONE ) { // Lecture du dico GLU propre a Aladin try { InputStream is = getClass().getResourceAsStream("/"+Aladin.ALAGLU); DataInputStream dis = new DataInputStream(is); // DataInputStream dis = new DataInputStream( new FileInputStream(ALADINDIC)); Aladin.trace(1,"Loading the inside glu dictionary"); loadGluDic(dis); dis.close(); } catch( Exception e ) { System.err.println("GluResolver error: "+e); } // Determination de la commande glufilter GLUFILTER = Aladin.HOME+"glufilter"; File f = new File(GLUFILTER); if( !f.exists() ) { GLUFILTER = "/usr/local/glu/glufilter"; f = new File(GLUFILTER); if( !f.exists() ) GLUFILTER=null; } //GLUFILTER=null; } // Recuperation des enregistrements GLU des serveurs additionnels if( Aladin.NETWORK ) getRemoteGluDic(); } /** Lancement de la recuparation des enregistrements GLU qui se trouvent * sur la machine aladin.u-strasbg.fr */ private void getRemoteGluDic() { DataInputStream dis; // Lancement du parsing try { URL url; if( Aladin.STANDALONE ) url = getURL("Aladin.java.gludic"); else url = new URL(Aladin.CGIPATH+"/nph-aladin.pl?frame=gludic"); dis = new DataInputStream(url.openStream()); Aladin.trace(1,"Loading the remote glu dictionary"); loadGluDic(dis); } catch( Exception e) { System.err.println("Remote Glu dictionary not reached"); } } /** Pour acceder aux marques GLU de debugging. * Retourne le tag GLU suffixe par -test si Aladin est en mode debug * (c'est-a-dire que Aladin.debug=true) */ static String debugTag(String tag) { if( Aladin.test ) return tag+"-test"; return tag; } // Ajout des quotes simples et prefixe par \ des quotes internes // --> Entree : la chaine a traiter // --> Retour : la chaine traitee // static String quote(String s) { boolean first=true; StringBuffer res = new StringBuffer("'"); StringTokenizer st = new StringTokenizer(s,"'"); while( st.hasMoreTokens() ) { if( first ) first=false; else res.append("\\'"); res.append(st.nextToken()); } res.append("'"); return res.toString(); } /** Appel au GLU local (mode standalone). * L'appel se fera au moyen d'une commande exec * * @@param tag le tag GLU a resoudre * @@return l'URL resolue (mais sous forme de String), ou null si probleme */ final String gluFilter(String tag) { Process p; // Le process StringBuffer url=new StringBuffer(""); // Le resultat int b; // pour lire chaque caractere de la reponse InputStream in; // flux de la reponse String [] cmd = new String[4]; // Tableau des arguments du exec try { // preparation de la commande cmd[0] = GLUFILTER; cmd[1] = "-e"; cmd[2] = "-r"; cmd[3] = tag; Aladin.trace(3,"Querying the local GLU: "+cmd[0]+" -e -r '"+cmd[3]+"' ..."); // Creation du process associe au glufilter p = Runtime.getRuntime().exec(cmd); in = p.getInputStream(); // Lecture du resultat, caractere par caractere while( (b = in.read())!=-1 ) url.append((char)b); } catch( Exception e ) { System.err.println("Glufilter error : "+e); return null; } // Detection des erreurs String u = url.toString(); if( u.startsWith("<*") ) { Aladin.trace(3,"WARNING: "+u); return null; } return u; } /* private static Class mrjFileUtilsClass; private static Class mrjOSTypeClass; private static Class macOSErrorClass; private static Class aeDescClass; private static Constructor aeTargetConstructor; private static Constructor appleEventConstructor; private static Constructor aeDescConstructor; private static Method findFolder; private static Method getFileType; private static Method makeOSType; private static Method putParameter; private static Method sendNoReply; private static Object kSystemFolderType; private static Integer keyDirectObject; private static Integer kAutoGenerateReturnID; private static Integer kAnyTransactionID; private static final String FINDER_TYPE = "FNDR"; private static final String FINDER_CREATOR = "MACS"; private static final String GURL_EVENT = "GURL"; // Pour le chargement Mac private static void loadAppleClasses(int jvm) throws Exception { switch (jvm) { case 0: //MRJ_2_0 Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget"); macOSErrorClass = Class.forName("com.apple.MacOS.MacOSError"); Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils"); Class appleEventClass = Class.forName("com.apple.MacOS.AppleEvent"); Class aeClass = Class.forName("com.apple.MacOS.ae"); aeDescClass = Class.forName("com.apple.MacOS.AEDesc"); aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new Class [] { int.class }); appleEventConstructor = appleEventClass.getDeclaredConstructor(new Class[] { int.class, int.class, aeTargetClass, int.class, int.class }); aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[] { String.class }); makeOSType = osUtilsClass.getDeclaredMethod("makeOSType", new Class [] { String.class }); putParameter = appleEventClass.getDeclaredMethod("putParameter", new Class[] { int.class, aeDescClass }); sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply", new Class[] { }); Field keyDirectObjectField = aeClass.getDeclaredField("keyDirectObject"); keyDirectObject = (Integer) keyDirectObjectField.get(null); Field autoGenerateReturnIDField = appleEventClass.getDeclaredField("kAutoGenerateReturnID"); kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null); Field anyTransactionIDField = appleEventClass.getDeclaredField("kAnyTransactionID"); kAnyTransactionID = (Integer) anyTransactionIDField.get(null); break; case 1: //MRJ_2_1 mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils"); mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType"); Field systemFolderField = mrjFileUtilsClass.getDeclaredField("kSystemFolderType"); kSystemFolderType = systemFolderField.get(null); findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder", new Class[] { mrjOSTypeClass }); getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType", new Class[] { File.class }); break; } } static boolean firstShowDoc=true; */ static final String [] BROWSERS = {"netscape","mozilla","Netscape" }; static String BROWSER=null; /* * Test de l'existence d'un browser compatible Netscape par essais successifs * de lancement avec l'option "-v" * Positionne la variable de classe BROWSER en fonction du resultat * Si non trouve, BROWSER est initialise a "" */ private void setBrowser() { String [] cmd = new String[2]; Process p; for( int i=0; i "+res); if( res==0 ) { BROWSER = BROWSERS[i]; return; } } catch( Exception e ) { } } Aladin.warning("Browser launching problem: no netscape compatible browser found"); BROWSER=""; } /** Gestion de la prochaine fenetre Browser. * Positionne le flag pour determiner si la prochaine fenetre browser * a creer dot etre une nouvelle fenetre ou s'il faut reutiliser * la precedente * * @@param newWindow true : il faudra une nouvelle fenetre, * false : il n'en faut pas */ protected void newWindow(boolean newWindow) { this.newWindow = newWindow; } /** Affichage d'un document HTML via une marque GLU. * @@see aladin.Glu#showDocument(java.lang.String, java.lang.String, boolean) */ protected void showDocument(String id,String params) { showDocument(id,params,false); } /** Affichage d'un document HTML via une marque GLU. * Dans le cas ``standalone'' on va se baser uniquement sur Netscape * et demander soit dans demarrer un, soit de faire afficher la page souhaitee * par le Netscape courant. Pour cela, on utilise la commande -remote * de Netscape qui permet d'acceder au Display X pour interragir avec * le Client X Netscape courant. *

* Pour la version Applet, une simple utilisation de showDocument() resoud * une partie des problemes. En revanche il va etre necessaire d'utiliser * le GLU en ``rebond'' afin de contourner la politique de securite * JAVA. Pour cela le dico GLU additionnel pour Aladin contient une marque * ``http'' qui prend en parametre une URL. Il suffit donc de demander * cette marque-la avec l'option de resolution immediate pour s'en sortir * (un peu sioux mais efficace) */ protected void showDocument(String id,String params,boolean encode) { URL url = getURL(id,params,encode); // Resolution GLU String window = ""; if( url==null ) return; // On se base uniquement sur netscape if( Aladin.STANDALONE ) { Process p; String [] cmd = new String[3]; Aladin.trace(1,"Launching the browser"); // Dans une nouvelle fenetre netscape ? if( newWindow ) { window=",aladin-"+nWindow; nWindow++; } // On determine le type de plate-forme String syst = System.getProperty("os.name"); // Dans le cas Windows (on lance le Browser par defaut) if( syst!=null && syst.startsWith("Windows") ) { try { // preparation de la commande "rundll32 url.dll,FileProtocolHandler url" cmd[0]="rundll32"; cmd[1]="url.dll,FileProtocolHandler"; cmd[2]=url.toString(); Aladin.trace(2,"trying: "+cmd[0]+" "+cmd[1]+" "+cmd[2]); // Creation du process associe au browser p = Runtime.getRuntime().exec(cmd); } catch( Exception e1 ) { Aladin.warning("Browser launching problem : "+e1); } /* TROP DE MACHINE VIRTUEL A SUIVRE // Pour les macs (beurkkk) } else if( syst!=null && syst.equals("Mac OS") ) { try { String majorMRJVersion = System.getProperty("mrj.version").substring(0, 3); double version = Double.valueOf(majorMRJVersion).doubleValue(); int jvm = (version==2)?0:1; if( firstShowDoc ) { loadAppleClasses(jvm); firstShowDoc=false; } switch(jvm) { case 0: //Aladin.warning("Detection MRJ "+majorMRJVersion); Object aeDesc; Integer finderCreatorCode = (Integer) makeOSType.invoke(null, new Object[] { FINDER_CREATOR }); Object aeTarget = aeTargetConstructor.newInstance(new Object[] { finderCreatorCode }); Integer gurlType = (Integer) makeOSType.invoke(null, new Object[] { GURL_EVENT }); Object browser = appleEventConstructor.newInstance(new Object[] { gurlType, gurlType, aeTarget, kAutoGenerateReturnID, kAnyTransactionID }); aeDesc = aeDescConstructor.newInstance(new Object[] { url }); putParameter.invoke(browser, new Object[] { keyDirectObject, aeDesc }); sendNoReply.invoke(browser, new Object[] { }); break; case 1: File systemFolder = (File) findFolder.invoke(null, new Object[] { kSystemFolderType }); String[] systemFolderFiles = systemFolder.list(); for( int i=0; i < systemFolderFiles.length; i++) { File file = new File(systemFolder, systemFolderFiles[i]); if( !file.isFile() ) continue; Object fileType = getFileType.invoke(null, new Object[] { file }); if (FINDER_TYPE.equals(fileType.toString())) { //Aladin.warning("Detection MRJ "+majorMRJVersion+"\n["+file+"]\n["+url+"]"); Runtime.getRuntime().exec(new String[] { file.toString(), url.toString() } ); return; } } throw new Exception(); } } catch( Exception emac ) { Aladin.warning("Browser launching problem : "+emac); } */ // Dans le cas Unix (on prend Netscape ou Mozilla) } else { if( BROWSER==null ) setBrowser(); if( BROWSER.length()==0 ) return; try { // preparation de la commande "netscape -remote openURL(url,nn)" cmd[0] = BROWSER; cmd[1] = "-remote"; cmd[2] = "openURL("+url.toString()+window+")"; Aladin.trace(2,"Trying: "+cmd[0]+" "+cmd[1]+" "+cmd[2]); // Creation du process associe au netscape remote p = Runtime.getRuntime().exec(cmd); // J'attend sa fin p.waitFor(); if( p.exitValue()==0 ) return; // On essaye de demarrer un nouveau netscape Aladin.trace(2,"Trying: "+cmd[0]+" "+url); // Creation du process netscape p = Runtime.getRuntime().exec(BROWSER+" "+url.toString()); } catch( Exception e ) { System.out.println("Browser launching problem : "+e); } } return; } // Pour le mode Applet Aladin.trace(1,"Opening a new browser page"); try { if( newWindow ) aladin.getAppletContext().showDocument(url,window); else aladin.getAppletContext().showDocument(url,"aladin"); } catch( Exception e ) { System.err.println("showDocument() error : "+e); } } /** Tableau associatif contenant le dico GLU additionnel Aladin sous la forme id -> URL avec des $nn */ Hashtable aladinDic=null; /** Cherche la premiere lettre qui soit un espace, un \t, ou un \n. * @@param a Le tableau de caracteres * @@param i l'offset courant dans le tableau * @@return Le nouvel offset ou -1 si fin de chaine */ static int afterWord(char [] a, int i) { while( i * ATTENTION : Ne prend pas en compte les valeurs de champs * qui seraient repliees sur plusieurs lignes sans le signe \ en continuation * * @@param s La ligne a analyser * @@param dis Flux de donnees (en cas de continuation sur plusieurs lignes * @@return La valeur champ GLU ou null si non trouve */ static String getValue(String s1,DataInputStream dis) { int i; StringBuffer res= new StringBuffer(); // Pour construire sur plusieurs lignes String s = new String(s1); // Pour ne pas faire d'effet de bord char [] a = s.toCharArray(); // On passe le nom du champ et les blancs qui suivent if( (i=afterWord(a,0))==-1 ) return null; if( (i=afterSpace(a,i))==-1 ) return null; // S'agit-il d'une ligne avec continuation ? while( a[a.length-1]=='\\' ) { // Memorisation de la ligne courante res.append(a,i,a.length-i-1); // Lecture de la ligne suivante try { do { s=dis.readLine(); } while( s!=null && (s.charAt(0)=='#' || s.trim().length()==0) ); if( s==null ) break; } catch( Exception e ) { s=null; break; } a = s.toCharArray(); // On laisse les blancs en debut de ligne i=afterSpace(a,0); } // On ajoute la derniere ligne qui n'est pas en continuation // si ce n'est pas deja fait if( s!=null ) res.append(a,i,a.length-i); return res.toString(); } /** Recuperation du numero du parametre dans une chaine GLU %Param.XXX * @@param s la chaine au format "$nn=xxx" ou "nn:xxx" * @@return le numero du parametre (nn) ou "" s'il y a un probleme */ static String getNumParam(String s) { char [] a = s.toCharArray(); int i,j; for( i=0; i'9'); i++ ); for( j=i+1; j='0' && a[j]<='9'; j++); return (j nom du serveur * @@param D Description du serveur * @@param MP Label du sous-menu Popup ou null si aucun * @@param LP Label du bouton ou null si aucun * @@param PP Label du plan ou null si aucun * @@param FU URL vers la doc utilisateur associee * @@param PDh Descriptions de chaque parametre (cle 1,2,3...) * @@param PKh Type de chaque parametre (cle 1,2,3...) * @@param PVh Valeurs de chaque parametre (cle 1,2,3..., separateur \t) * s'il n'y a qu'une valeur, il s'agit d'une valeur par defaut, * s'il y en a plusieurs, c'est la liste des valeurs possibles, * sinon ce sera un champ texte libre. */ private void memoServer(String A,String D, String MP,String LP,String PP,String FU, Hashtable PDh,Hashtable PKh,Hashtable PVh,String R) { int i; if( PDh==null ) return; int n=PDh.size(); String [] PD = new String[n]; for( i=1; i<=n; i++) PD[i-1] = (String)PDh.get(i+""); String [] PK = new String[n]; for( i=1; i<=n; i++) PK[i-1] = (String)PKh.get(i+""); String [] PV = new String[n]; for( i=1; i<=n; i++) PV[i-1] = (String)PVh.get(i+""); vGluServer.addElement( new GluServer(aladin,null,A,D,MP,LP,PP,FU,PD,PK,PV,R) ); } static private String subCR(String s) { char [] a = s.toCharArray(); int i,j; for( i=j=0; itrue Ok, false sinon. */ protected boolean loadGluDic(DataInputStream dis) { String name; // Le nom du champ courant String value; // La valeur du champ courant String A=null; // L'identificateur de l'enr courant String MP=null; // Label du sous-menu Popup ou null sinon String LP=null; // Label du bouton ou null sinon String PP=null; // Masque du Label du plan ou null sinon String FU=null; // URL d'une doc associee ou null sinon String U=null; // Le masque de l'URL de l'enr courant String s=null; // Variable de travail String D=null; // La description courante String R=null; // Le type de donnees retournees Hashtable PD=null;// Les descriptions des parametres (cle=numero du param) Hashtable PK=null;// Les types des parametres (cle=numero du param) Hashtable PV=null;// Les valeurs possibles des parametres (cle=numero du param) boolean distribAladin=false; // true si distribue dans le domaine ALADIN boolean flagLabel=false; // true si on a un champ %Aladin.Label PD = new Hashtable(); PK = new Hashtable(); PV = new Hashtable(10); try { while( (s=dis.readLine())!=null ) { if( s.equals("") || s.charAt(0)=='#' ) continue; if( (name=getName(s))==null ) continue; if( (value=getValue(s,dis))==null ) continue; if(name.equals("Aladin.Menu") ) MP = subCR(value); else if(name.equals("Aladin.LabelPlane") ) PP = subCR(value); else if( name.equals("F.U") || name.equals("Doc.User") ) FU = value; else if( name.equals("D") || name.equals("Description") ) D = value; else if( name.equals("R") || name.equals("ResultDataType") ) R=value; else if( name.equals("A") || name.equals("ActionName") ) { if( flagLabel && distribAladin ) memoServer(A,D,MP,LP,PP,FU,PD,PK,PV,R); distribAladin=false; flagLabel=false; A=D=R=MP=LP=PP=FU=null; PD = new Hashtable(); PK = new Hashtable(); PV = new Hashtable(10); A = subCR(getValue(s,dis)); } else if( name.equals("U") || name.equals("Url") ) { U = value; StringTokenizer aST = new StringTokenizer(A); while( aST.hasMoreTokens() ) aladinDic.put(aST.nextToken(),U); } else if(name.equals("Aladin.Label") ) { LP = subCR(value); flagLabel=true; } else if( name.equals("Z") || name.equals("DistribDomain") ) { if( getValue(s,dis).equals("ALADIN") ) distribAladin=true; } else if( name.equals("P.D") || name.equals("Param.Description") ) { PD.put(getNumParam(value),getValParam(value)); } else if( name.equals("P.K") || name.equals("Param.DataType") ) { PK.put(getNumParam(value),getValParam(value)); } else if( name.equals("P.V") || name.equals("Param.Value") ) { String num = getNumParam(value); String v = getValParam(value); String v1 = (String)PV.get(num); if( v1!=null ) v1 = v1+"\t"+v; else v1=v; PV.put(num,v1); } } if( flagLabel && distribAladin ) memoServer(A,D,MP,LP,PP,FU,PD,PK,PV,R); } catch( Exception e ) { aladinDic=null; System.err.println("loadGluDic error: "+e); e.printStackTrace(); return false; } return true; } /** Enleve les \ qui precede un caractere particulier * @@param s La chaine a traiter * @@param x Le caractere qui doit suivre \ * @@return La chaine traitee */ static String removeBackslash(String s,char x) { if( s.length()==0 ) return s; char [] a = s.toCharArray(); StringBuffer res = new StringBuffer(); int i; for( i=0; i'0' && a[i]<='9'; i++); try { num = Integer.parseInt( new String(a,offsetNum,i-offsetNum)); } catch( NumberFormatException e ) { num=0; } num--; // Les indices $nnn commence en 1 } while( num<0 ); // Recherche de la fin du prefixe fin=offsetNum-1; // Par defaut if( num>=param.length ) { while( fin>0 && a[fin]!='&' && a[fin]!='?' ) fin--; // on supprime le "&name=" if( a[fin]=='?' ) fin++; // On laisse le '?' } // Memorisation du prefixe res.append( new String(a,deb,fin-deb) ); // Memorisation de la valeur si necessaire if( num..."); // Decoupage des parametres param = cutParam(params); // Encodage des parametres si necessaire if( !encode ) { for( i=0; i Appel inside, puis local en cas d'echec if( Aladin.STANDALONE ) { // Appel au GLU inside u = gluResolver(id,params,encode); // Appel au GLU local s'il existe if( u==null && GLUFILTER!=null ) { option=option+"u"; // On veut juste l'URL tag = "<&"+id+option+" "+params+">"; u=gluFilter(tag); } if( u==null ) { System.err.println("getURL error: glu record \""+id+"\" not found !\n"); return null; } url = new URL(u); // Netscape => Appel au GLU distant, on va retourner l'URL d'appel // a ce GLU distant avec l'option R dans le tag GLU } else { option=option+"R"; tag = "<&"+id+option+" "+params+">"; url = new URL(aladin.CGIPATH+"/nph-glu.pl?" + URLEncoder.encode(tag)); // url = new URL(aladin.getCodeBase()+"/nph-glu.pl?" + URLEncoder.encode(tag)); } } catch( Exception e ) { System.err.println("getURL error: "+e); e.printStackTrace(); return null; } Aladin.trace(2,"Get: "+((url==null)?"null":url.toString())); return url; } private boolean flagVers; // Vrai s'il faut lire le resultat du log // pour connaitre le numero de la dern version boolean lock=false; /** Demande le lock */ void lock() { try { while( lock ) { thread.sleep(100); } } catch( Exception e) {} setlock(true); } /** Libere le lock */ void unlock() { setlock(false); } synchronized void setlock(boolean lock) { this.lock=lock; }; /** Envoi d'un log. * Generation d'un log sur le serveur de l'applet ou * sur aladin.u-strasbg.fr par defaut. * Utilise un simple appel a l'URL alalog.pl avec les parametres * de la derniere marque GLU. * * Rq: Utilise un verrou afin de pouvoir tranquillement passer les * variables param et flagVers au thread qui va etre charge * du log sans se les faire ecraser par le log suivant * * @@param id l'identificateur GLU
* @@param params les parametres de la marque GLU * @@return null ou eventuellement le retour du log si Id=="Start" */ protected void log(String id, String params) { if( !Aladin.NETWORK ) return; lock(); // verrouillage param = ALADINLOG+"?id=" + URLEncoder.encode(id)+ "¶ms=" + URLEncoder.encode(params); flagVers=(Aladin.STANDALONE && id.equals("Start")); thread = new Thread(this); thread.start(); } /** Envoi d'un log. */ public void run() { URL url; String tmp = param; // Copie des variables critiques boolean flagTmp = flagVers; // Copie des variables critiques unlock(); // liberation du verrou try{ // Construction de l'URL par defaut if( Aladin.APPLETSERVER==null ) { url = new URL(tmp); // Construction de l'URL par rebond + ajout du param &host= pour // que le nph-glu.pl ajoute la provenance } else { tmp += "&host="; url = getURL("Http",tmp,true,false); } InputStream is=url.openStream(); // Lecture du numero de la derniere version disponible if( flagTmp ) { DataInputStream dis = new DataInputStream(is); aladin.setCurrentVersion(dis.readLine()); dis.close(); } is.close(); } catch( Exception elog ) { System.err.println("error log: "+elog); } } } * Decoupage des parametres d'une marque GLU. * Les parametres peuvent etre ``enquotes''. * * @@param cds/aladin/GluServer.java010064400076440000132000000512430770227416100163360ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Le formulaire d'interrogation d'un serveur defini par enregistrement GLU * * @@author Pierre Fernique [CDS] * @@version 2.0 : jan 03 - Suppression du Layout Manager et toilettage * @@version 1.0 : (23 oct 2000) Creation */ public class GluServer extends Server { static final String HELP = "INFO on this server"; private boolean flagSIAIDHA=false; int fmt; // Format de retour (PlanImage.fmt) String tagGlu; Vector vc; // Liste des componenents associes aux parametres du tagGlu d'interrogation String planeLabel; // Format pour le label du plan ou null sinon String docUser=null; // Tag GLU ou URL de la doc associee au serveur String [] vD=null; // Contient eventuellement la liste des valeurs // par defaut pour les champs a saisir. L'index // correspond a l'indice du champ. le tableau est null // si aucune valeur sinon seulement les elements sans // valeur par defaut sont null. /** Creation du formulaire d'interrogation du serveur decrit * par les champs GLU * @@param aladin reference * @@param status le label qui affichera l'etat courant * @@param A,D,MP,LP,PP,FU,PD,PV,R Les champs GLU */ protected GluServer(Aladin aladin,Label status, String A, String D, String MP, String LP, String PP, String FU, String [] PD, String [] PK, String [] PV, String R) { //System.out.println("["+A+"] -> R="+R+" MP="+MP); tagGlu=A; nom=(LP!=null)?LP:A; info=D; myPopup=MP; planeLabel=PP; docUser=FU; type=(R!=null && R.indexOf("text")>=0)?DATA:IMAGE; flagSIAIDHA = R!=null && (R.indexOf("sia")>=0 || R.indexOf("idha")>=0); fmt = getFmt(R); this.aladin = aladin; this.status = status; setLayout(null); setFont(Aladin.PLAIN); int y=390/2-(PD.length*30+50+60+(FU!=null?30:0)+(flagSIAIDHA?180:0))/2; // Le titre Label t1 = new Label(D); t1.setFont( Aladin.LLITALIC ); int l = stringSize(t1); int x = 470/2-l/2; if( x<0 ) x=5; t1.setBounds(x,y,l+10,20); y+=40; add(t1); // Indication Label info1 = new Label("Fill in all these fields"); info1.setBounds(165,y,300, 20); y+=15; add(info1); Label info2 = new Label("and press the SUBMIT button"); info2.setBounds(128,y,300, 20); y+=20; add(info2); // Creation du Panel du target if( targetRequired(PK) ) { Panel tPanel = targetPanel(35,TARGET_EX,true,0); tPanel.setBounds(10,y,450,50); y+=60; add(tPanel); } // Creation des champs de saisie int X=150; vc = new Vector(5); for( int i=0; i1 ) { Choice ch = new Choice(); while( pv.hasMoreTokens() ) ch.addItem(pv.nextToken()); co = (Component)ch; // Construction d'un champ de texte libre } else { TextField t; if( pv!=null ) { // memorisation de la valeur par defaut if( vD==null ) vD = new String[PD.length]; vD[i]=PV[i]; t = new TextField(vD[i],40); // Une seule valeur possible => valeur par defaut } else t = new TextField(40); // Type de donnees ? (pour target et radius) if( PK!=null && PK[i]!=null ) flagShow=setModeCooRad(PK[i],t); // if( PK!=null && PK[i]!=null ) setModeCooRad(PK[i],t); co = (Component)t; } if( flagShow ) { String s = PD[i]==null?("Parameter "+(i+1)):(PD[i]+": "); Label pTitre = new Label(s); pTitre.setFont(Aladin.LBOLD); pTitre.setBounds(5,y,X-10,30); add(pTitre); co.setBounds(X,y,455-X,30); y+=30; add(co); } vc.addElement(co); } // Pour IDHA ou SIA if( flagSIAIDHA ) { ScrollPane sc = new ScrollPane(); tree = new MetaDataTree(aladin, sc); sc.add(tree); sc.setBounds(10,y,455,180); y+=180; add(sc); } // Vers de la doc associee if( docUser!=null ) { Button b = new Button(HELP); b.setFont(Aladin.BOLD); b.setBounds(250,y+40,130,25); y+=30; add(b); } } /** Retourne vrai si le champ Target est necessaire dans le formulaire. * Recherche dans la liste PK[] s'il y a un type de donnee correspondant * au Target. */ private boolean targetRequired(String PK[]) { for( int i=0; i0?PlanImage.GFITS: R.indexOf("/hfits")>0?PlanImage.HFITS: R.indexOf("/mrcomp")>0?PlanImage.MRCOMP:PlanImage.FITS; } /** Extrait le prochain mode d'un type de donnees "a la GLU" qui precise * pour un Target ou un Field ce qui est accepte par le serveur * @@param mode Contiendra le prochain mode (ou chaine vide si termine) * @@param a tableau de caracteres * @@param i offset dans a[] * @@return prochain offset a traiter */ private int getMode(StringBuffer mode,char a[],int i) { while( i "+PK+": prefixe=["+prefixe+"]:"); // Pour le target if( prefixe.equalsIgnoreCase("Target") ) { //System.out.println(" Target..."); while(true) { mode = new StringBuffer(); i=getMode(mode,a,i+1); if( mode.length()==0 ) break; s=mode.toString(); //System.out.println(" mode="+s); if( s.equalsIgnoreCase("RA") ) { nbField=2; modeCoo |= RADEC; } else if( s.equalsIgnoreCase("DE") ) { nbField=2; ind=1; modeCoo |= RADEC; } else if( s.equalsIgnoreCase("RAb") ) { nbField=2; modeCoo |= RADEb; } else if( s.equalsIgnoreCase("DEb") ) { nbField=2; ind=1; modeCoo |= RADEb; } else if( s.equalsIgnoreCase("SIMBAD") ) { modeCoo |= SIMBAD; } else if( s.equalsIgnoreCase("NED") ) { modeCoo |= NED; } else if( s.equalsIgnoreCase("COO") ) { modeCoo |= COO; } else if( s.equalsIgnoreCase("COOd") ) { modeCoo |= COOd; } else if( s.equalsIgnoreCase("COOb") ) { modeCoo |= COOb; } else if( s.equalsIgnoreCase("RAd") ) { nbField=2; modeCoo |= RADEd; } else if( s.equalsIgnoreCase("DEd") ) { nbField=2; ind=1; modeCoo |= RADEd; } } if( coo==null ) coo = new TextField[nbField]; coo[ind] = f; //System.out.println(" modeCoo="+modeCoo); return false; } // Pour le Field if( prefixe.equalsIgnoreCase("Field") ) { //System.out.println(" Field..."); while(true) { mode = new StringBuffer(); i=getMode(mode,a,i+1); if( mode.length()==0 ) break; s=mode.toString(); //System.out.println(" mode="+s); if( s.equalsIgnoreCase("RA") ) { nbField=2; modeRad |= RADBOX; } else if( s.equalsIgnoreCase("DE") ) { nbField=2; ind=1; modeRad |= RADBOX; } else if( s.equalsIgnoreCase("SQR") ) { modeRad |= RADSQR; } else if( s.equalsIgnoreCase("RADIUS") ) { modeRad |= RADIUS; } else if( s.equalsIgnoreCase("RADIUSd") ){ modeRad |= RADIUSd; } } if( rad==null ) rad = new TextField[nbField]; rad[ind] = f; //System.out.println(" modeRad="+modeRad); } return true; } /** Creation d'un plan de maniere generique * La syntaxe du critere est "Instrument[,roll]" */ protected int creatPlane(String target,String radius,String criteria, String label, String origin) { String s,objet=""; Enumeration e; int i,j; // Resolution par Simbad necessaire ?, // et remplissage des champs adequats if( (objet=resolveTarget(target))==null ) { Aladin.warning(this,"Coordinate error\n"+ "or astronomical identifier unknown ",1); return -1; } // Pre-remplissage des champs concernant le radius // Attention, setRad considere le diametre, et pas le rayon if( radius!=null && radius.length()>0 ) setRad(getRadius(radius)*2); // Recherche dans tous les champs qui ont des valeurs predefinies // ceux dont les criteres pourraient correspondre Vector v = new Vector(10); Vector vbis = new Vector(10); // Juste pour etablir le label du plan e = vc.elements(); while( e.hasMoreElements() ) { Component c = (Component)e.nextElement(); //System.out.print("Analyse de c="+c.getName()+" :"); if( (c instanceof TextField) ){ s = ((TextField)c).getText(); //System.out.println(" Default_Textfield("+s+")"); v.addElement(s); vbis.addElement(s); continue; } StringTokenizer st = new StringTokenizer(criteria," ,"); boolean trouve=false; while( !trouve && st.hasMoreTokens() ) { String cr = st.nextToken().toUpperCase(); //System.out.print(" "+cr); if( c instanceof Choice ) { Choice c1 = (Choice)c; int n=c1.countItems(); for( i=0; i=0 ) { //System.out.print(" Bingo("+s+")"); s = c1.getItem(i); if( (j=s.indexOf(" - "))>0 ) s=s.substring(0,j); trouve=true; v.addElement(s); vbis.addElement(s); } } } } if( !trouve ) { // IL FAUDRAIT ENCORE VERIFIER QUE TOUS LES CRITERES SONT PRIS EN COMPTE if( c instanceof Choice ) { s = ((Choice)c).getSelectedItem(); if( (j=s.indexOf(" - "))>0 ) vbis.addElement(s.substring(j+3)); else vbis.addElement(s); if( (j=s.indexOf(" - "))>0 ) s=s.substring(0,j); else if( s.equals("?") || s.startsWith("-") && s.endsWith("-")) s=""; //System.out.print(" Default_Choice("+s+")"); v.addElement(s); } } //System.out.println("."); } e = v.elements(); StringBuffer p=null; StringBuffer p1=null; while( e.hasMoreElements() ) { s = (String)e.nextElement(); //System.out.println("Param ["+s+"]"); if( p==null ) { p=new StringBuffer(Glu.quote(s)); p1=new StringBuffer(s); } else { p.append(" "+Glu.quote(s)); p1.append("/"+s); } } // Generation de l'URL par appel au GLU URL u = aladin.glu.getURL(tagGlu,p.toString()); // S'agit-il d'un serveur SIA || IDHA if( flagSIAIDHA ) { System.err.println("SIA or IDHA servers no yet supported by script command"); return 0; } // Generation du label du plan if( label==null ) { if( planeLabel==null ) label=nom; else { String [] param = new String[vbis.size()]; for( i=0; i0 ) vbis.addElement(s.substring(j+3)); else vbis.addElement(s); if( (j=s.indexOf(" - "))>0 ) s=s.substring(0,j); else if( s.equals("?") || s.startsWith("-") && s.endsWith("-")) s=""; v.addElement(s); } } e = v.elements(); StringBuffer p=null; StringBuffer p1=null; while( e.hasMoreElements() ) { s = (String)e.nextElement(); if( p==null ) { p=new StringBuffer(Glu.quote(s)); p1=new StringBuffer(s); } else { p.append(" "+Glu.quote(s)); p1.append("/"+s); } } // Generation de l'URL par appel au GLU URL u = aladin.glu.getURL(tagGlu,p.toString()); // S'agit-il d'un serveur SIA || IDHA if( flagSIAIDHA ) { try{ // Traitement des images par lot if( tree!=null && !tree.isEmpty() ) { if( tree.nbSelected()>0 ) { tree.loadSelected(); tree.resetCb(); } else Aladin.warning(this,"You have to check atleast one resource"); // Chargement des descriptions des images disponibles } else { MyInputStream in = new MyInputStream(u.openStream()); aladin.treeView.updateTree(in,tree,this,""); } } catch( Exception e1) { Aladin.warning(this,"Server or HTTP error!"); if( Aladin.levelTrace==3 ) e1.printStackTrace(); } defaultCursor(); return; } // Generation du label du plan String label=null; if( planeLabel==null ) label=nom; else { String [] param = new String[vbis.size()]; for( int i=0; itrue Ok pour l'image, sinon false */ protected boolean waitImage() { while( !ok ) { try{ Thread.currentThread().sleep(400); } catch( Exception e ) {} } return (status & ImageConsumer.IMAGEABORTED)==0; } /* // Juste pour deboguer cette cochonnerie de NETSCAPE JAVA static void printStatus(String label,int status) { String s = ""; if( (status & ImageConsumer.IMAGEABORTED)!=0 ) s = s+" IMAGEABORTED"; if( (status & ImageConsumer.IMAGEERROR)!=0 ) s = s+" IMAGEERROR"; if( (status & ImageConsumer.SINGLEFRAME)!=0 ) s = s+" SINGLEFRAME"; if( (status & ImageConsumer.SINGLEFRAMEDONE)!=0 ) s = s+" SINGLEFRAMEDONE"; if( (status & ImageConsumer.STATICIMAGEDONE)!=0 ) s = s+" STATICIMAGEDONE"; print(label+s); } // Juste pour deboguer cette cochonnerie de NETSCAPE JAVA static void printHints(String label,int status) { String s = ""; if( (status & ImageConsumer.SINGLEPASS)!=0 ) s = s+" SINGLEPASS"; if( (status & ImageConsumer.SINGLEFRAME)!=0 ) s = s+" SINGLEFRAME"; if( (status & ImageConsumer.COMPLETESCANLINES)!=0 ) s = s+" COMPLETESCANLINES"; if( (status & ImageConsumer.RANDOMPIXELORDER)!=0 ) s = s+" RANDOMPIXELORDER"; if( (status & ImageConsumer.TOPDOWNLEFTRIGHT)!=0 ) s = s+" TOPDOWNLEFTRIGHT"; print(label+s); } */ public void imageComplete(int status) { this.status=status; if( !flagPixels ) return; // Je n'ai recu encore aucun pixel if( (status & ImageConsumer.STATICIMAGEDONE)!=0 || (status & ImageConsumer.IMAGEABORTED)!=0) { source.removeConsumer(this); setOk(true); } } public void setColorModel(ColorModel model) {} public void setProperties(Hashtable props) {} public void setDimensions(int width,int height) {} public void setHints(int status) { status=0;} public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) { flagPixels=true; // Ca y est j'ai eu des pixels //System.out.println("setPixels("+x+","+y+","+w+","+h+") off="+off+" scansize="+scansize); if( BYTEMODE ) { for( int yc=y; ycRq : Les images en couleurs ne sont pas prises en compte par * cette classe => genere imageComplete(ImageConsumer.IMAGEABORTED) */ public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) { System.err.println("setPixels error in GreyMemory: \"int\" not supported"); imageComplete(ImageConsumer.IMAGEABORTED); } } ellectual // cds/aladin/HeaderFits.java010064400076440000132000000300500770227416100164270ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.net.*; import java.io.*; import java.util.*; import java.util.zip.*; /** * Classe dediee a la gestion d'un header FITS. *

* Rq: issue des exemples du livre * "java Network Programming" - O'Reilly - Elliotte Rusty Harold * * @@author Pierre Fernique [CDS] * @@version 1.5 : 20 aout 2002 methode readFreeHeader * @@version 1.4 : 19 juin 00 Utilisation du PushbackInputStream et * implantation de isHCOMP() * @@version 1.3 : (6 juin 2000) format HCOMPRESS * @@version 1.2 : (20 mars 2000) prise en compte du champ EQUINOX enquote * @@version 1.1 : (14 jan 99) affichage du header fits dans un frame * @@version 0.9 : (18 mai 99) Creation */ public final class HeaderFits extends Frame { StringBuffer memoHeaderFits = null; // Memorisation de l'entete FITS telle quelle TextArea ta; boolean flagHCOMP; /** Les elements de l'entete */ protected Hashtable header; /** La taille de l'entete FITS (en octets) */ int sizeHeader=0; /** Creation du header. * Rq: si gzis est !=null, ce sera ce flux qui sera prix, sinon dis * @@param dis le flux en entree * @@param gzis le flux en entree (gzip) * @@param flagHCOMP true s'il s'agit de FITS HCOMP */ protected HeaderFits(MyInputStream dis) throws Exception { makeTA(); readHeader(dis); } /** Creation du header a partir d'un chaine de caracteres. Celle-ci * peut etre une entete FITS "valide" (bloc de 2880, 80 colonnes...) * ou un simple paragraphe KEY = VALUE /COMMENT\n... */ protected HeaderFits(String s) { if( s.length()%2880==0 && s.indexOf('\n')<0) { makeTA(); readHeader(s); } else readFreeHeader(s); } /** Construction du Frame de visualisation du Header FITS */ private void makeTA() { setBackground(Aladin.BKGD); ta = new TextArea(50,70); ta.setFont( Aladin.COURIER ); Aladin.makeAdd(this,ta,"Center"); move(50,50); pack(); } /** Retourne Vrai s'il s'agit d'un FITS Hcompresse */ protected boolean isHCOMP() { return flagHCOMP; } /** Visualise le header FITS */ protected void seeHeaderFits() { ta.setText(""); ta.appendText(getHeader()); show(); } /** Retourne le header FITS original */ protected String getHeader() { return memoHeaderFits.toString(); } /** Ajoute la ligne courante a la memorisation du header FITS * en supprimant les blancs en fin de ligne * @@param s la chaine a ajouter */ private void appendMHF(String s) { if( memoHeaderFits==null ) memoHeaderFits=new StringBuffer(); memoHeaderFits.append(s.trim()+"\n"); } /** Taille en octets de l'entete FITS. * Uniquemenent mis a jour apres readHeader() * @@return La taille de l'entete */ protected int getSizeHeader() { return sizeHeader; } /** Extraction de la valeur d'un champ FITS * @@param buffer La ligne * @@return La valeur * Rq : detecte un eventuel commentaire */ private String getValue(byte [] buffer) { int i; for( i=9; i<80; i++ ) { if( buffer[i]==(byte)'/' ) break; } return (new String(buffer, 0, 9, i-9)).trim(); } /** Lecture de l'entete FITS. * Mise a jour de tableau associatif header. * @@param dis Flux de donnees * @@return true si OK, false sinon */ protected boolean readHeader(MyInputStream dis) throws Exception { int blocksize = 2880; int fieldsize = 80; String key, value; int linesRead = 0; sizeHeader=0; boolean firstLine=true; Aladin.trace(3,"Reading FITS header"); byte[] buffer = new byte[fieldsize]; header = new Hashtable(); try { while (true) { dis.readFully(buffer); //System.out.println(linesRead+":["+new String(buffer,0)+"]"); key = new String(buffer, 0, 0, 8); if( linesRead==0 && !key.equals("SIMPLE ") ) throw new Exception(); appendMHF(new String(buffer,0)); sizeHeader+=fieldsize; linesRead++; if( key.equals("END " ) ) break; if( buffer[8] != '=' /* || buffer[9] != ' ' */ ) continue; value=getValue(buffer); //Aladin.trace(3,(key.trim())+" ["+value+"]"); header.put(key.trim(), value); } // Test s'il s'agit de FITS Hcompresse (on ne teste que le premier // code magic car JAVA 1.0 ne permet pas le unread de plus d'1 octet if( (dis.getType() & MyInputStream.HCOMP)!=0 ) { flagHCOMP=true; return true; } else flagHCOMP=false; /* int a=0; if( (a=dis.read())!=0xDD ) dis.unread(a); else { flagHCOMP=true; dis.unread(a); return true; } flagHCOMP=false; */ // On passe le bourrage eventuel int bourrage = blocksize - sizeHeader%blocksize; if( bourrage!=blocksize ) { byte [] tmp = new byte[bourrage]; dis.readFully(tmp); sizeHeader+=bourrage; } } catch( Exception e ) { // CETTE VARIABLE error AURAIT DU ETRE NON STATIC ET PASSE VIA LA REFERENCE A ALADIN // SI ON VEUT POUVOIR UTILISER CORRECTEMENT PLUSIEURS INSTANCES D'ALADIN if( linesRead==0 ) Aladin.error="Remote server message:\n"+new String(buffer,0); else { Aladin.error="Fits header error (line "+(linesRead+1)+")"; if( Aladin.levelTrace>=3 ) e.printStackTrace(); } throw new Exception(); } return true; } String key,value; /** Lecture de l'entete FITS a partir d'une chaine de caracteres * Mise a jour de tableau associatif header * @@param s La chaine contenant le header Fits * @@return true si OK, false sinon */ protected boolean readHeader(String s) { int fieldsize = 80; String key, value; byte[] buffer = new byte[fieldsize]; int offset; char [] a = s.toCharArray(); Aladin.trace(3,"Reading FITS header"); header = new Hashtable(); for( offset=0; a.length-offset>=fieldsize; offset+=fieldsize ) { for( int j=0; j='0' && ch<='9' ) ) break; } // on cherche le dernier chiffre ou un '.' for( j=a.length-1; j>=i; j-- ) { ch=a[j]; if( (ch>='0' && ch<='9' ) || ch=='.' ) { j++; break; } } return new String(a,i,j-i); } /** Recherche d'un element double par son mot cle * @@param key le mot cle * @@return la valeur recherchee */ protected double getDoubleFromHeader(String key) throws NumberFormatException,NullPointerException { String s; double result; s = (String) header.get(key.trim()); result = Double.valueOf(trimDouble(s)).doubleValue(); return result; } /** Recherche d'une chaine par son mot cle * @@param key le mot cle * @@return la valeur recherchee */ protected String getStringFromHeader(String key) throws NullPointerException { String s; return (String) header.get(key.trim()); } // Gestion des evenement public boolean handleEvent(Event e) { if( e.id==Event.WINDOW_DESTROY ) hide(); return super.handleEvent(e); } } ique [CDS] * @@version 1.5 : 20 aout 2002 methode readFreeHeader * @@version 1.4 : 19 juin 00 Utilisation du PushbackInputStream et * implantation de isHCOMP() * @@version 1.3 : (6 juin 2000) format HCOMPRESS * @@version 1.2 : (20 mars 2000) prise en compte du champ EQUINOX enquote * @@version 1.1 : (14 jan 99) affichage du header fits dans un frame * @@version 0.9 : (18 mai 99) Creation */ public final class HeaderFits extends Frame { Stcds/aladin/Help.java010064400076440000132000000273270770227416100153160ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion du HELP * * @@author Pierre Fernique [CDS] * @@version 1.1 : (6 juin 2003) Prise en compte des imagettes * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Help extends Canvas { static final String WCLIC = "To quit the help mode,\nclick on the HELP button"; // Les composantes de l'objet String text; // Le texte courant FontMetrics fm=null; // La font courante Image img; // Image contenant le help Graphics g; // Contexte graphique int ws=500,hs=500; // Taille du Help par defaut boolean flagBlack; // true si fond noir // Les references Aladin aladin; // Les variables de travail static final Font FI = Aladin.LPLAIN;// Font par defaut static final Font FG = Aladin.LBOLD; // Font grasse static int dy=-1; // Espace entre deux lignes /** Creation de l'objet de manipulation du Help * @@param aladin reference */ protected Help(Aladin aladin) { this(aladin,true); } protected Help(Aladin aladin,boolean flagBlack) { this.aladin = aladin; this.flagBlack=flagBlack; setBackground(flagBlack?Color.black:Color.white); } /** Le texte du Help pour expliquer le HELP. * @@return le help du help */ protected String H() { return("!View window\n"+ "Displays the current projection according to the status of the "+ "``Plane stack'' and the ``Zoom window''.\n"+ " \n"+ "The mouse position in astronomical coordinates is given "+ "at the top of the window. If the mouse position is "+ "on a source, its name is given in the ``status window''.\n"+ " \n"+ "If the ``Select'' button is pressed, you can select an individual "+ "source by clicking on it, or several sources by delimiting a "+ "rectangular area with a clik-and-drag mouse operation. All "+ "measurements and links associated to these sources will be displayed "+ "in the ``Measurement window''.\n"+ " \n"+ "In the same way, you can select one or several additional graphic "+ "symbols that you can subsequently move or delete.\n"+ " \n"+ "Tips: To Cut-and-Paste a mouse position, click on it and "+ "pick it up in the \"Localization\" rectangle."); } /** Modifie le texte du Help. * Demande egalement le repaint() * @@param text le nouveau texte */ protected void setText(String text) { this.text = text; repaint(); } /** Positionne le texte par defaut du help */ protected void setDefault() { text = "!Help on line\n"+ "*Just move the mouse on the Aladin logo\n"+ "*at the upper left corner of the Aladin window to see how to start\n"+ "*or on any other interface components for which\n"+ "*you want some explanations.\n \n \n"+ "*To quit the help mode, click on the\n"+ "*HELP OFF button.\n \n"+ "!Interface vocabulary\n"+ "- View window: the main window in the center of the Aladin window,\n"+ "- Plane stack: window on the right side of the Aladin window with the eye logo,\n"+ "- Tool bar: the set of the logos between the View window and the Plane stack,\n"+ "- Zoom window: the square window at the right-bottom corner,\n"+ "- Measurement window: the rectangular window at the bottom of the Aladin window with the scrollbar,\n"+ "- Status window: the rectangular area between the View window and the measurement window.\n"; repaint(); } // Juste pour manger l'evenement public boolean mouseMove(Event e, int x, int y) { return true; } public boolean mouseEnter(Event e, int x, int y) { aladin.localisation.setPanelPos(); if( aladin.inHelp ) { setText(H()); repaint(); } return true; } public boolean mouseDown(Event e, int x, int y) { if( aladin.msgOn ) aladin.endMsg(); else Aladin.warning(WCLIC); return true; } /** Affichage d'une ligne de texte dans la fenetre du help. * La fonction se charge des retours a la ligne en verifiant qu'elle * coupe correctement entre deux mots.
* Si la chaine commence par '*', la ligne va etre affichee en gras * et centree. Si elle commence par '!' il s'agit d'un titre. Si * elle commence par '%', il s'agit d'un image (nom de l'image doit suivre), * si elle commence par '*%' il s'agit d'une image qui doit etre centree. * * @@param g le contexte graphique * @@param s la ligne a afficher * @@param x,y la position du debut * @@return l'ordonnee de la prochaine ligne */ int drawString(Graphics g,String s,int x, int y) { StringTokenizer st; String sc=null; String nsc=null; boolean flag_center=false; // Pas encore de contexte if( fm==null ) return y; // else dy = fm.getHeight(); else dy = Aladin.GETHEIGHT+1; // Cochonnerie de JAVA if( s.charAt(0)=='%' || (flag_center=(s.indexOf("*%")==0)) ) { String imgFile = s.substring(flag_center?2:1); Image i = aladin.getImagette(imgFile); if( i==null ) return y; if( flag_center ) x=ws/2-i.getWidth(this)/2; g.drawImage(i,x,y,this); return y+=i.getHeight(this)+dy; } if( s.charAt(0)=='!' ) { g.setFont(FG); x=ws/2-fm.stringWidth(s)/2; y+=dy; g.drawString(s.substring(1),x,y); y+=2*dy; return y; } else g.setFont(FI); if( s.charAt(0)=='*' ) { flag_center=true; s=s.substring(1); } st = new StringTokenizer(s," \t"); // Recherche du dernier blanc avant le retour a la ligne while( st.hasMoreTokens() ) { String mot = (String)st.nextToken(); // Concatenation mot par mot if( sc==null ) nsc = mot; else nsc = sc+" "+mot; // Test de taille if( fm.stringWidth( nsc.toString() )>=(ws-10) ) { // affichage du stringbuffer precedent if( sc!=null ) { x=(flag_center)?ws/2-fm.stringWidth(sc)/2:10; g.drawString(sc,x,y); y+=dy; } // Dans le cas ou le mot qui reste tout seul depasse la taille // ou qu'il n'y a plus de mot apres if( fm.stringWidth(mot)>=(ws-10) ) { x=(flag_center)?ws/2-fm.stringWidth(mot)/2:10; g.drawString(mot,x,y); y+=dy; sc=null; } else sc = mot; } else sc = nsc; } // J'affiche ce qui reste if( sc!=null ) { x=(flag_center)?ws/2-fm.stringWidth(sc)/2:10; g.drawString(sc,x,y); } return y+dy; } static final int NRANDOM = 300; Random r = new Random(); boolean flagR = false; byte [] xR = new byte[NRANDOM]; byte [] yR = new byte[NRANDOM]; byte [] zR = new byte[NRANDOM]; Color BLUE = new Color(225,225,255); public void update(Graphics gr) { if( img==null || img.getWidth(this)!=ws || img.getHeight(this)!=hs ) { if( g!=null ) g.dispose(); img = createImage(ws,hs); g=img.getGraphics(); g.setFont(FI); fm = g.getFontMetrics(); g.setColor(flagBlack?Color.black:Color.white); g.drawRect(0,0,ws-1,hs-1); } // On efface tout g.setColor(flagBlack?Color.black:Color.white); g.fillRect(0,0,ws,hs); // Quelques etoiles if( flagBlack ) { if( !flagR ) { r.nextBytes(xR); r.nextBytes(yR); r.nextBytes(zR); flagR=true; } for( int i=0; i470)?3:z>400?2:1; g.setColor(z<30?Color.red:z<100?Color.blue:z<250?Color.yellow:Color.white); if( r==1 ) g.drawLine(x,y,x,y); else g.fillOval(x,y,r,r); } } // On ecrit les lignes du texte courant StringTokenizer st = new StringTokenizer(text,"\n"); int x=10; int y=20; g.setColor(flagBlack?Color.white:Color.blue); while( st.hasMoreElements() ) { String s = (String) st.nextElement(); y=drawString(g,s,x-2,y-2); } paint(gr); } public void paint(Graphics gr) { ws = size().width; hs = size().height; if( img==null || img.getWidth(this)!=ws || img.getHeight(this)!=hs ) { update(gr); return; } //Affichage du buffer du paint gr.drawImage(img,0,0,null); } } components for which\n"+ "*you want some explanations.\n \n \n"+ "*To quit the help mode, click on the\n"+ "*HELP OFF button.\n \n"+ "!Interface vocabulary\n"+ "- View window: the main window in the center of the Aladin window,\n"+ cds/aladin/Histogramme.java010064400076440000132000000053530770227416100167000ustar00ferniquecds00000400000013package cds.aladin; import java.awt.*; import java.awt.image.*; public class Histogramme extends Canvas { // Les constantes d'affichage static final int mX = 10; // Marge en abscisse static final int mY = 0; // Marge en ordonnee static final int Hp = 150; // Hauteur du graphique static final int W = 256+2*mX; // Largeur totale du graphique static final int H = Hp+mY; // Hauteur totale du graphique // titre de l'histogramme static final String TITLE = "Pixel values histogram"; // valeurs a memoriser double [] hist; // histogramme courant de la repartition des niveaux de gris Image img=null; // Image du double buffer contenant l'histogramme // les references PlanImage pimg; // le plan image concerne byte [] pixels; // Les pixels de l'image courante protected Histogramme(PlanImage pimg) { if ( (pimg != null) && !(pimg instanceof PlanImageRGB) ) { double max=0; int i; this.pimg = pimg; this.pixels = pimg.pixels; // Calcul de la repartition des couleurs hist = new double[256]; for( i=0; imax ) max=c; } for( i=0; i0 ) { g.setColor(Color.black); int y = HM/2+Aladin.SIZE/2-2; g.drawString(text,5,y); } paint(gr); } /* public void paint(Graphics gr) { if( img==null ) { update(gr); return; } gr.drawImage(img,0,0,null); } */ // Gestion du Help public boolean handleEvent(Event e) { if( Aladin.inHelp ) return true; return super.handleEvent(e); } } cds/aladin/Legende.java010064400076440000132000000155370770227416100157710ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.xml.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion des legendes des plans catalogues * Une legende peut avoir plusieurs lignes. *

* Utilise un tableau qui associe des noms (ex: unite) aux legendes * (ex: mm minarc Spect). Chaque element de la ligne-legende est separe * par un tab comme dans le format TSV. * * @@author Pierre Fernique [CDS] * @@version 1.2 : (25 juillet 2002) VOTable s'ajoute a Astrores * @@version 1.1 : (12 dec 00) developpement de getWidth() * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Legende { Field [] field; protected Legende(Vector vField) { field = new Field[ vField.size() ]; Enumeration e = vField.elements(); for( int i=0; e.hasMoreElements(); i++ ) field[i]=(Field)e.nextElement(); } /** Retourne la description pour l'infobulle * @@param i numero du champ * @@return la description, null si pas de texte */ protected String getToolTipText(int i) { if( i>=field.length || i<0) return null; Field f = field[i]; String s= f.name; s+=" / "; s+= (f.ucd!=null)?f.ucd:""; s+=" / "; s+= (f.unit!=null)?f.unit:""; return s; } /** Retourne la description associee au champ. * @@param i numero du champ * @@return la description, null si erreur ou non decrit */ protected String getDescription(int i) { if( i>=field.length ) return null; Field f = field[i]; String s = f.name+" : "; s += (f.description!=null)?f.description:(f.name!=null)?f.name:null; if( f.ucd!=null ) { s = s+ " (UCD: "+f.ucd; if( f.unit!=null ) s = s+ " / unit: "+f.unit; s = s+")"; } else if( f.unit!=null ) s = s + " (unit: "+f.unit+")"; //System.out.println("UCD:"+f.ucd+" unit: "+f.unit+" datatype:"+f.datatype); return s; } /** Retourne le nombre de caracteres associes au champ. * @@param i numero du champ * @@return le nombre de caracteres, 0 si non specifie, -1 si erreur * * DETAIL PAS DROLE: Pour le cas des boutons (associes a l'acces aux archives) * la taille est en fait le nombre de caractere du label du bouton +1 * Malheureusement ce label peut se confondre avec le texte pour un lien. * J'ai pris comme element discriminant la presence d'une variable ${..} * en supposant que le nom des boutons est constant sur toute la colonne * ... je sens que ca me jouera des tours tot ou tard. */ protected int getWidth(int i) { int j = 0; if( i>=field.length ) return -1; Field f = field[i]; // VOTable compatibility if( f.width !=null ) { if( f.refText!=null && f.refText.indexOf("${")<0 ) return f.refText.length()+1; try { j=Integer.parseInt(f.width); } catch( Exception e ) { return -1; } } else if (f.arraysize != null) { if (f.arraysize.endsWith("*") == false) j = Integer.parseInt(f.arraysize); else j = Integer.parseInt((f.arraysize).substring(0, (f.arraysize).length()-1)); // System.out.println("and now the arraysize " + j); } return j; } /** Retourne le nombre de caractere (+1) de la chaine refText * @@param i numero du champ * @@return 0 si non defini, -1 si erreur */ protected int getRefTextLength(int i) { if( i>=field.length ) return -1; if( field[i].refText==null ) return 0; return field[i].refText.length()+1; } protected String getHref(int i) { return i>=field.length?null:field[i].href; } protected String getGref(int i) { return i>=field.length?null:field[i].gref; } protected String getRefText(int i) { return i>=field.length?null:field[i].refText; } protected String getRefValue(int i) { return i>=field.length?null:field[i].refValue; } protected String getDataType(int i) { return i>=field.length?null:field[i].datatype; } protected boolean hasInfo(int i) { return i>=field.length?false:itrue si la ligne doit etre affichee avec son id */ // protected boolean withlabel; // couleur de la ligne ou null si on prend la couleur du plan d'appartenance protected Color couleur = null; // la ligne ne doit pas etre affichee si hidden == true protected boolean hidden = false; /** Reference au point de debut de la ligne ou null sinon */ protected Ligne debligne=null; /** Reference au point de fin de la ligne ou null sinon */ protected Ligne finligne=null; /** Creation d'une ligne pour les backups */ protected Ligne(Plan plan) { super(plan); } /** Constructeurs du premier bout. * @@param plan plan d'appartenance de la ligne * @@param x,y position du premier bout */ protected Ligne(Plan plan, double x, double y) { super(plan,x,y,0.,0.,XY|RADE_COMPUTE,null); } /** Constructeurs du premier bout. * @@param plan plan d'appartenance de la ligne * @@param x,y position du premier bout * @@param id identificateur associe a la ligne */ protected Ligne(Plan plan, double x, double y,String id) { super(plan,x,y,0.,0.,XY|RADE_COMPUTE,id); } /** Continuation d'une ligne. * @@param plan plan d'appartenance de la ligne * @@param x,y position du premier bout * @@param debligne sommet precedent dans la ligne */ protected Ligne(Plan plan, double x, double y,Ligne debligne) { this(plan,x,y,"",debligne); } /** Continuation d'une ligne. * @@param plan plan d'appartenance de la ligne * @@param x,y position du premier bout * @@param id identificateur associe a la ligne * @@param debligne sommet precedent dans la ligne */ protected Ligne(Plan plan, double x, double y, String id, Ligne debligne) { super(plan,x,y,0.,0.,XY|RADE_COMPUTE,id); this.debligne = debligne; debligne.finligne = this; } // Constructeurs en ra,dec (thomas) /** Constructeur du premier bout * @@param ra ascension droite * @@param dec déclinaison * @@param plan plan d'appartenance */ protected Ligne(double ra, double dec, Plan plan) { super(plan,0,0,ra,dec,RADE|XY_COMPUTE,null); } /** * * @@param ra ascension droite * @@param dec déclinaison * @@param plan plan d'appartenance * @@param debligne sommet précédent */ protected Ligne(double ra, double dec, Plan plan, Ligne debligne) { super(plan,0,0,ra,dec,RADE|XY_COMPUTE,null); this.debligne = debligne; debligne.finligne = this; } ///// Constructeurs permettant de preciser la couleur de la ligne ///// /** Constructeurs du premier bout. * @@param plan plan d'appartenance de la ligne * @@param x,y position du premier bout * @@param c couleur de la ligne */ protected Ligne(Plan plan, double x, double y, Color c) { this(plan,x,y); this.couleur=new Color(c.getRGB()); } /** Constructeurs du premier bout. * @@param plan plan d'appartenance de la ligne * @@param x,y position du premier bout * @@param id identificateur associe a la ligne * @@param c couleur de la ligne */ protected Ligne(Plan plan, double x, double y,String id, Color c) { this(plan,x,y,id); this.couleur=new Color(c.getRGB()); } /** Continuation d'une ligne. * @@param plan plan d'appartenance de la ligne * @@param x,y position du premier bout * @@param debligne sommet precedent dans la ligne * @@param c couleur de la ligne */ protected Ligne(Plan plan, double x, double y,Ligne debligne, Color c) { this(plan,x,y,"",debligne,c); this.couleur=new Color(c.getRGB()); } /** Continuation d'une ligne. * @@param plan plan d'appartenance de la ligne * @@param x,y position du premier bout * @@param id identificateur associe a la ligne * @@param debligne sommet precedent dans la ligne * @@param c couleur de la ligne */ protected Ligne(Plan plan, double x, double y, String id, Ligne debligne, Color c) { this(plan,x,y,id); this.debligne = debligne; debligne.finligne = this; this.couleur=new Color(c.getRGB()); } ///// FIN des constructeurs ///// /** Test d'appartenance a la Ligne (ne marche que pour les sommets). * Retourne vrai si le point (x,y) de la vue se * trouve sur la cote * Met egalement a jour l'id avec la taille courante de la Cote * afin de pouvoir la visualiser pendant le trace * @@param x,y le point a tester * @@param z le fzoom */ protected boolean in(double x, double y, double z) { double l = 9/z; if( debligne==null ) return false; PointD p2 = new PointD(this.x,this.y); PointD p1 = new PointD(debligne.x,debligne.y); // Verifie qu'on est pas en dehors de la boite contenant le segment if( (p2.x-x)*(p1.x-x)>l || (p2.y-y)*(p1.y-y)>l ) return false; // Verifie qu'on est a moins de 3 pixels du segment double dx = p2.x-p1.x; double dy = p2.y-p1.y; double ddx = x-p1.x; double ddy = y-p1.y; double dd = ddx*ddx + ddy*ddy; if( dx!=0 || dy!=0 ) { double ddd = (dx*ddx + dy*ddy); dd -= ddd*ddd / (dx*dx + dy*dy); } return (dd<=l); } /** Retourne vrai si le point (x,y) de l'image se trouve proche * de l'extremite d'un segment * @@param x,y le point a tester * @@param z le zoom */ boolean nearArrow(double x, double y,double z) { double l = 9/z; double ddx = x-this.x; double ddy = y-this.y; return (ddx*ddx + ddy*ddy)<=l; } /** Test d'appartenance. * Retourne vrai si le point (x,y) de l'image se trouve * - soit a proximite de l'extremite courante du segment * - soit sur le segment mais eloigne des deux extremites * @@param x,y le point a tester * @@param fz le zoom */ protected boolean inside(double x, double y,double z) { return nearArrow(x,y,z); } /** Coordonnees dans la vue courante. * Retourne la position dans les coord. de la vue courante * Memorise l'etat du zoom pour s'eviter du travail ulterieur * @@param zoomview reference au zoom courant * @@return les coordonnees */ protected Point getViewCoord(ZoomView zoomview) { vp = zoomview.getViewCoord(x,y); oiz=zoomview.iz; return vp; } /** Generation d'un clip englobant. * Retourne un rectangle qui englobe la ligne dans les coord de la vue * En fait on traite le cas general avec 3 points (debligne,this,finligne) * @@param zoomview reference au zoom courant * @@return le rectangle enblobant */ protected Rectangle getClip(ZoomView zoomview) { Point [] p = new Point[4]; int x1=2048,y1=2048,x2=0,y2=0; p[0] = (debligne!=null)?debligne.getViewCoord(zoomview):null; p[1] = getViewCoord(zoomview); p[2] = (finligne!=null)?finligne.getViewCoord(zoomview):null; // Recherche des min et max for( int i=0; i<4; i++ ) { if( p[i]==null ) continue; if( p[i].xx2 ) x2=p[i].x; if( p[i].y>y2 ) y2=p[i].y; } if( bout>0 || select ) { x1-=DL; y1-=DL; x2+=DL; y2+=DL; } return new Rectangle(x1,y1,x2-x1+1,y2-y1+1); } /** Trace de la portion de la ligne. * @@param g le contexte graphique * @@param zoomview reference au zoom courant */ protected void draw(Graphics g,ZoomView zoomview,int dx,int dy) { if( !this.hidden ) { Point p2; if( couleur!=null ) g.setColor( couleur ); else g.setColor( plan.c ); if( debligne!=null ) { // Le segment p2 = getViewCoord(zoomview); Point p1 = debligne.getViewCoord(zoomview); p1.x+=dx; p1.y+=dy; p2.x+=dx; p2.y+=dy; g.drawLine(p1.x,p1.y, p2.x,p2.y); // Trace des fleches if( bout>0 ) { double theta,delta; if( p1.x!=p2.x) { theta = Math.atan( (double)(p2.y-p1.y)/(p2.x-p1.x) ); if( p1.x>p2.x ) theta += Math.PI; } else { if( p1.y * Rq : Utilise uniquement par la version Standalone * * @@author Pierre Fernique [CDS] * @@version 2.0 : jan 03 - Suppression du Layout Manager et toilettage * @@version 1.5 : 12 mars 02 readFully deplace dans la classe PlanImage * @@version 1.4 : 14 jan 02 Local(http:) pour les catalogues * @@version 1.3 : 19 juin 00 Utilisation du PushbackInputStream * pour readFully() * @@version 1.2 : 8 juin 2001 - correction readFully() * @@version 1.1 : 11 avril 2000 - contournement "out of memory" * @@version 1.0 : 9 dec 1999 - Creation */ public class LocalServer extends Server implements XMLConsumer { // static final String NOM = "Local\n"+MyButton.LOGOBOTH; static final String NOM = "Local"; static final String TITRE = "Image/data/script loading by file or URL"; static final String INFO = "Access to images/data/scripts by filename/URL"; static final String DEFAULT_METHODE = "\n- The image has to be in FITS format (eventually gzipped).\n"+ " Its header has to contain WCS fields\n \n"+ "- The data has to be in XML/Astrores or XML/VOTable format\n"+ " see documentation for details\n"+ " or simplier, in Tab-Separated-Value\n"+ " with the first two columns as RA and DE in J2000 decimal degrees\n \n"+ "- The Aladin backups have to be produced by the Aladin save method\n"+ " (XML/AJ format)\n \n"+ "- The Aladin script must have the extension \".ajs\""; static final String HELP = "\nSpecify a filename and press\n"+ "the SUBMIT button below.\n"; static final String BROWSE = "Browse..."; TextField file; // Le champ de saisie du nom de fichier static String loadError; // Le message d'erreur courant String explication,titre; /** Initialisation des variables propres */ protected void init() { type = IMAGE; nom = NOM; info = INFO; titre = TITRE; explication = DEFAULT_METHODE; } /** Creation du formulaire d'interrogation des images sur le disque * @@param aladin reference * @@param status le label qui affichera l'etat courant */ protected LocalServer(Aladin aladin,Label status) { init(); this.aladin = aladin; this.status = status; setLayout(null); setFont(Aladin.PLAIN); int y=45; // Le titre Label t = new Label(titre); t.setFont( Aladin.LLITALIC ); t.setBounds(65,y,400,20); y+=40; add(t); // Premiere indication Label info1 = new Label("Specify a filename or an URL and press the SUBMIT button"); info1.setBounds(20,y,400, 20); y+=20; add(info1); // Label info2 = new Label("and press the SUBMIT button"); // info2.setBounds(118,y,300, 20); y+=20; // add(info2); // Le nom du fichier a charger file = new TextField(50); file.setBounds(10,y,380,30); add(file); // Pour s'aider d'une boite de recherche Button browse = new Button(BROWSE); browse.setBounds(395,y+5,60,20); y+=40; add(browse); ScrollPane sc = new ScrollPane(); tree = new MetaDataTree(aladin, sc); sc.add(tree); sc.setBounds(10,y,455,230); y+=230; add(sc); /* // Un peu de baratin StringTokenizer st = new StringTokenizer(explication,"\n"); while( st.hasMoreTokens() ) { Label m = new Label(st.nextToken()); m.setBounds(30,y,400,20); y+=15; add(m); } */ } /** Creation d'un plan de maniere generique * Le target et radius sont ignores, criteria contient * le nom du fichier ou l'URL */ protected int creatPlane(String target,String radius,String criteria, String label, String origin) { // String mime=null; String f=criteria; // S'il n'y a pas de label ni d'origine mentionnee il est possible // que le critere soit en fait forme de la chaine suivante // url,label,origin (methode script) if( label==null && origin==null && criteria.indexOf(',')>0 ) { StringTokenizer st = new StringTokenizer(criteria,","); f = st.nextToken(); if( st.hasMoreTokens() ) { label = st.nextToken(); if( st.hasMoreTokens() ) origin = st.nextToken(); } } // le fichier (ou url) peut etre suivi d'un mime type // avec un blanc comme separateur int i=f.indexOf(' '); if( i>0 ) { // mime=f.substring(i+1,f.length()); f=f.substring(0,i); } return creatLocalPlane(f,label,origin); // return creatLocalPlane(f,mime,label,origin); } /** Determination automatique du Mime type d'une ressource * en fonction de son extension protected String autoDetectMimeType(String f) { f = f.toUpperCase(); if( f.endsWith(".IDHA") ) return "idha/xml"; if( f.endsWith(".FITS") || f.endsWith(".FIT") ) return "image/fits"; if( f.endsWith(".GZ") ) return "image/gfits"; if( f.endsWith(".H") ) return "image/hfits"; if( f.endsWith(".MRC") || f.endsWith(".MRCOMP") ) return "image/mrfits"; if( f.endsWith(".AJ") ) return "application/aladin"; if( f.endsWith(".AJS") ) return "text/script"; if( f.endsWith(".XML") ) return "text/xml"; return "text/tsv"; } */ /** Creation d'un plan issu d'un chargement d'un fichier AJ, fits ou autre * Le choix se fait en fonction de l'extension du nom de fichier * .aj -> AJ * .fits -> FITS * autre -> XML + TSV * @@param f path du fichier */ /* protected int creatLocalPlane(String f,String mime,String label,String origin) { int n=-1; // Valeurs par defaut if( mime==null ) mime = autoDetectMimeType(f); if( label==null ) label=(f.length()>10)?f.substring(0,10):f; if( origin==null ) origin=f; // Pas de verification de la redoncance pour les fichiers locaux // mais tout de meme affichage des messages divers flagVerif=false; verif(0,null,null,null); try { // Acces par http if( f.startsWith("http://") ) { URL u = aladin.glu.getURL("Http",f,true,true); if( mime.equals("text/script") ) { InputStream is = u.openStream(); aladin.command.readFromStream(is); } else if( mime.charAt(0)=='t' ) { n=aladin.calque.newPlanCatalog(u,label,"",f); } else { n=aladin.calque.newPlanImage(u,PlanImage.OTHER, label,null,f, origin, PlanImage.UNKNOWN,PlanImage.UNDEF, true,null); } // Acces fichier } else { if( mime.equals("text/script") ) { InputStream is = new FileInputStream(f); aladin.command.readFromStream(is); } else if( mime.charAt(0)=='i' ) loadIDHA(f); else if( mime.charAt(0)=='t' ) n=aladin.calque.newPlanCatalog(f); else if( mime.charAt(0)=='a' ) { loadAJ(f); n=0; } else n=aladin.calque.newPlanImage(f,true); } } catch(Exception e) { Aladin.warning(this,""+e,1); return -1; } return n; } */ /** Creation d'un plan issu d'un chargement d'un fichier AJ, fits ou autre * Le choix se fait en fonction de l'extension du nom de fichier * .aj -> AJ * .fits -> FITS * autre -> XML + TSV * @@param f path du fichier */ protected int creatLocalPlane(String f,String label,String origin) { int n=0; MyInputStream in; int type; URL u=null; waitCursor(); try { File x = new File(f); if( x.isDirectory() ) { Aladin.trace(3,f+" => detect: DIR"); aladin.treeView.updateTree((new IDHAGenerator()).getStream(x,this),tree,this,""); defaultCursor(); return n; } if( label==null ) label=(f.length()>10)?f.substring(0,10):f; if( origin==null ) origin=f; // Pas de verification de la redoncance pour les fichiers locaux // mais tout de meme affichage des messages divers flagVerif=false; verif(0,null,null,null); //Obtention du stream (donnee locale ou distante) if( f.startsWith("http://") ) { u = aladin.glu.getURL("Http",f,true,true); in = new MyInputStream(u.openStream()); } else { in = new MyInputStream(new FileInputStream(f)); } in = in.startRead(); type = in.getType(); Aladin.trace(3,f+" => detect: "+in.decodeType(type)); if( (type & MyInputStream.AJS|MyInputStream.UNKNOWN)!=0) aladin.command.readFromStream(in); else if( (type & MyInputStream.AJ)!=0) loadAJ(in); else if( (type & MyInputStream.IDHA)!=0) aladin.treeView.updateTree(in,tree,this,""); else if( (type & MyInputStream.SIA)!=0) aladin.treeView.updateTree(in,tree,this,""); else if( (type & MyInputStream.FITS)!=0) { if( u!=null ) { n=aladin.calque.newPlanImage(u,in,PlanImage.OTHER, label,null,f, origin, PlanImage.UNKNOWN,PlanImage.UNDEF, true,null); } else n=aladin.calque.newPlanImage(f,in,true); } else { if( u!=null ) n=aladin.calque.newPlanCatalog(u,in,label,"",f); else n=aladin.calque.newPlanCatalog(f,in); } } catch(Exception e) { Aladin.warning(this,""+e,1); defaultCursor(); return -1; } defaultCursor(); return n; } /** Chargement de l'image ou des donnees */ public void submit() { waitCursor(); if( tree!=null && !tree.isEmpty() ) { if( tree.nbSelected()>0 ) { tree.loadSelected(); tree.resetCb(); } else Aladin.warning(this,"You have to check atleast one resource"); } else creatLocalPlane(file.getText(),null,null); defaultCursor(); } /** Nettoyage du formulaire */ protected void clear() { file.setText(""); tree.clear(); super.clear(); } /** Reset du formulaire */ protected void reset() { if( tree!=null ) tree.resetCb(); } FileDialog fd=null; /** Gestion des evenements. * Le bouton BROWSE permet d'afficher la fenetre de recherche des * fichiers */ public boolean action(Event evt, Object what) { // Affichage de la fenetre des filtres VizieR if( BROWSE.equals(what) ) { if( fd==null || Aladin.JAVABEFORE118 ) fd = new FileDialog(aladin.f,INFO); fd.show(); String dir = fd.getDirectory(); String name = fd.getFile(); String s = (dir==null?"":dir)+(name==null?"":name); file.setText(s); if( name!=null && name.length()>0 ) submit(); return true; } return true; } /** Chargement d'un fichier au format AJ * @@param in l'inputStream * @@return true si ok, false sinon */ protected boolean loadAJ(MyInputStream in) { byte [] a; boolean rep; XMLParser xmlParser = new XMLParser(this); loadError=null; try { rep=xmlParser.parse(in); } catch( Exception e ) { loadError=""+e; return false; } if( !rep ) loadError=xmlParser.getError(); return (rep && loadError==null ); } /* Variables temporaires associees au parsing du XML */ boolean inPlane,inName,inTable,inValue; // Etat Vector vField; // Vecteur contenant les FIELDS de la table courante Legende leg=null; // Legende de la table courante Plan plan=null; // Plan courant double ra=0; // RA du centre du plan courant double de=0; // DE du centre du plan courant double rm=0; // SIZE du plan courant int proj=0; // Type de la projection courante (cf Projection.NAME[]) int typePlan=-1; // Type du plan courant (cf Plan.Type) String rec; // Enregistrement courant dans l'analyse des lignes d'une table Objet prevO=null; // Dernier objet tool inserer dans la table courante boolean prevFlagSuite=false; // Dernier flag de suivi de ligne /** Creation d'un plan courant (tag ) * @@param atts les attributs XML du tag PLANE * @@return le plan cree */ private Plan creatPlaneByAJ(Hashtable atts) { int i; String s; String type = (String)atts.get("type"); for( i=0; i getXMLHeadPlan() */ private void parseCalib(Calib c, String s) { StringTokenizer st = new StringTokenizer(s,","); c.aladin =Integer.parseInt(st.nextToken()); c.epoch = Double.valueOf(st.nextToken()).doubleValue(); c.alpha = Double.valueOf(st.nextToken()).doubleValue(); c.delta = Double.valueOf(st.nextToken()).doubleValue(); c.yz = Double.valueOf(st.nextToken()).doubleValue(); c.xz = Double.valueOf(st.nextToken()).doubleValue(); c.focale = Double.valueOf(st.nextToken()).doubleValue(); c.Xorg = Double.valueOf(st.nextToken()).doubleValue(); c.Yorg = Double.valueOf(st.nextToken()).doubleValue(); c.incX = Double.valueOf(st.nextToken()).doubleValue(); c.incY = Double.valueOf(st.nextToken()).doubleValue(); c.alphai = Double.valueOf(st.nextToken()).doubleValue(); c.deltai = Double.valueOf(st.nextToken()).doubleValue(); c.incA = Double.valueOf(st.nextToken()).doubleValue(); c.incD = Double.valueOf(st.nextToken()).doubleValue(); c.Xcen = Double.valueOf(st.nextToken()).doubleValue(); c.Ycen = Double.valueOf(st.nextToken()).doubleValue(); c.widtha = Double.valueOf(st.nextToken()).doubleValue(); c.widthd = Double.valueOf(st.nextToken()).doubleValue(); c.xnpix = Integer.parseInt(st.nextToken()); c.ynpix = Integer.parseInt(st.nextToken()); c.rota = Double.valueOf(st.nextToken()).doubleValue(); c.cdelz = Double.valueOf(st.nextToken()).doubleValue(); c.sdelz = Double.valueOf(st.nextToken()).doubleValue(); c.type1 = st.nextToken(); c.type2 = st.nextToken(); try { c.equinox = Double.valueOf(st.nextToken()).doubleValue(); } catch( Exception e1 ) { c.equinox=2000.0; } try { c.proj = Integer.parseInt(st.nextToken()); } catch( Exception e1 ) { c.proj=1; } } /** Parse un Polynome dans un attribut xml et retourne les coefficients * sous la forme d'un tableau de double. * Chaque valeur est separee par une simple "," * Voir Save.java -> getXMLHeadPlan() */ private double[] parsePoly(String s) { StringTokenizer st = new StringTokenizer(s,","); double [] x = new double[st.countTokens()]; for( int i=0; i getXMLHeadPlan() */ private double[][] parseMat(String s) { StringTokenizer st = new StringTokenizer(s,","); double [][] x = new double[2][2]; x[0][0] = Double.valueOf(st.nextToken()).doubleValue(); x[0][1] = Double.valueOf(st.nextToken()).doubleValue(); x[1][0] = Double.valueOf(st.nextToken()).doubleValue(); x[1][1] = Double.valueOf(st.nextToken()).doubleValue(); return x; } /** Interface XMLConsumer */ public void startElement(String name, Hashtable atts) { if( name.equals("ALADINJAVA") ) { // Liberation des plans precedents et positionnement du premier // numero libre aladin.calque.FreeAll(); // for( int i=0; i0 ) leg = new Legende(vField); // Description de colonnes } else if( name.equals("COLUMN") ) { Field f = new Field(atts); Enumeration e = atts.keys(); while( e.hasMoreElements() ) { String key = (String)e.nextElement(); f.addInfo(key,(String)atts.get(key)); } vField.addElement(f); } } /** Interface XMLConsumer */ public void endElement(String name){ if( name.equals("PLANE") ) { inPlane=false; if( plan!=null ) { // Post-traitement sur le plan CATALOG if( typePlan==Plan.CATALOG ) plan.pcat.postJob(ra,de,rm); // Post-traitement sur le plan IMAGE if( typePlan==Plan.IMAGE ) { // Creation de la table des couleurs PlanImage pi = (PlanImage)plan; pi.cm=ColorMap.getCM(pi.cmControl[0],pi.cmControl[1],pi.cmControl[2], pi.inverseCM(),0); pi.changeEtat(); } // validation et memorisation plan.flagOk = true; aladin.calque.plan[aladin.calque.getFirstFree()]=plan; plan=null; } } else if( name.equals("NAME") ) { inName =false; } else if( name.equals("TABLE") ) { inTable=false; leg=null; vField=null; } else if( name.equals("VALUE") ) { inValue=false; } else if( name.equals("ALADINJAVA") ) { aladin.calque.setDefaultPlanRef(); aladin.calque.activeAllPlan(); aladin.calque.repaint(); } } /** Remplit le champ courant de la source courante * Met a jour la variable de classe rec * @@param ch le tableau de caracteres a analyser * @@param cur l'indice du caractere courant * @@param end le dernier indice valide * @@return la nouvelle position dans ch[] */ private int getSourceField(char [] ch, int cur, int end) { int start=cur; while( cur initialisations if( p.pixels==null ) { p.pixels = new byte[p.width * p.height]; pOffset=0; } // Traitement du bloc courant pOffset=Save.get64(p.pixels,pOffset,ch,start,length); } /** Interface XMLConsumer */ public void characters(char ch[], int start, int length){ int cur = start; // Current character int end = start+length; // Last character if( inValue ) { switch( typePlan ) { case Plan.CATALOG: while( cur0 ) text.select(0,0); // aladin.dialog.setGrabCoord(s); } // Changement du panel pour passer en mode texte protected void setPanelText() { if( aladin.inHelp || flagText ) return; flagText=true; cl.show(p,"text"); // text.requestFocus(); } // Changement du panel pour passer en mode pos protected void setPanelPos() { if( !flagText ) return; flagText=false; cl.show(p,"pos"); } /** Positionne la valeur indefinie */ protected void setUndef() { pos.setText(""); } /** Retourne la position du menu deroulant */ protected int getFrameSelected() { return c.getSelectedIndex(); } // Retourne la valeur du frame prevue dans Astroframe // en fonction de la valeur courante du menu deroulant private int getFrame(int i) { return (i==J2000 || i==J2000D)?Astroframe.FK5: (i==B1950 || i==B1950D)?Astroframe.FK4: (i==ICRS)?Astroframe.ICRS: (i==GAL)?Astroframe.GAL: (i==SGAL)?Astroframe.SGAL:Astroframe.FK5; } /** Affiche la position, en fonction du frame defini * dans le menu deroulant * @@param x,y Les coordonnees de la souris dans la View */ protected void setPos(int x,int y) { setPos(x,y,0); } protected void setPos(int x,int y,int methode) { int i = getFrameSelected(); Plan plan = aladin.calque.getPlanRef(); PointD p = aladin.calque.zoom.zoomView.getPosition((double)x,(double)y); String s=null; if( plan==null ) return; // Position (X,Y) simplement // if( i==XY ) s=p.x+" "+(int)(plan.projd.r-p.y); if( i==XY ) { if( plan.type!=Plan.IMAGE ) return; s=p.x+" "+(((PlanImage)plan).height-p.y); // s=p.x+" "+p.y; // Calcul de la projection (resultat en J2000) } else { if( plan.projd==null ) return; Coord coo = new Coord(); coo.x = p.x; coo.y = p.y; coo = plan.projd.getCoord(coo); if( coo==null ) return; s=toString(coo.al,coo.del); } //Affichage du resultat if( methode==1 ) { setText(s); setPanelText(); } else { pos.setText(s); setPanelPos(); } } /** Retourne la position d'un objet en fonction du frame * courant * @@param al,del : coordonnees (J2000) * @@return La chaine decrivant la position */ protected String toString(double al,double del) { int i = getFrameSelected(); // Memorisation dans l'objet astroframe J2000 afs.set(al,del); // Conversion dans une autre frame en fonction de la // valeur courante du menu deroulant if( i!=oi ) { oi=i; aft = new Astroframe(getFrame(i)); } afs.convert(aft); // Generation de la chaine try { return (i==J2000D || i==B1950D || i==ICRSD )? aft.toString("d"):aft.toString(":"); } catch( Exception e) { System.err.println(e); } return ""; } /** Indication de la position d'une source. * (en fonction du repere courant) * @@param o La source * @@param methode 0 dans pos, 1 dans text (memorisation) */ protected void seeCoord(Source o) { seeCoord(o,0); } protected void seeCoord(Source o,int methode) { int i; String s; switch( (i=getFrameSelected()) ) { case XY: s = o.x+" "+o.y; break; default : s = toString(o.raj,o.dej); } if( methode==0 ) { pos.setText(s); setPanelPos(); } else { setText(s); setPanelText(); } } /** Gere la validation du champ de saisie rapide. */ public boolean keyDown(Event e,int key) { if( e.target instanceof TextField ) { // Validation par ENTER if( key!=13 && key!=10 ) return false; String saisie = text.getText().trim(); text.selectAll(); // Suppose qu'il s'agit d'une ligne de script, si ce n'est pas // le cas, suppose qu'il s'agit d'une quick commande if( saisie.length()>0 ) { if( !aladin.command.execScript(saisie,false) ) { aladin.command.execGetCmd(saisie); } } return true; } return false; } /** Gestion du Help * @@return retourne la chaine du Help concernant cet objet */ protected String Help() { return("!Localization window\n"+ "Displays the coordinates and the pixel value corresponding to the current position "+ "of the mouse in the `` View window''.\n"+ "You can choose the reference system from the "+ "menu on the left of the coordinates.\n \n"+ "By clicking on the gray rectangle, you can insert in it a"+ "\"quick Aladin command\". It follows this syntax:\n"+ "!ServerName[,ServerName] Target\n"+ "- The \"ServerNames\" can be Simbad, NED, Aladin or VizieR. "+ "For Aladin, you can specified in parenthesis the "+ "survey (POSSI,SERC...) or the scan (DSS1,DSS2,MAMA,2MASS) or the resolution (FULL,LOW,PLATE) "+ "or the color (J,R,...) or the format (JPEG,FITS)"+ "For example: Aladin(DSS1,LOW,FITS).\n"+ "For VizieR, you must specified in parenthesis the "+ "catalog name. For example: VizieR(USNO2).\n"+ "- The \"Target\" can be a Simbad identifier or J2000 coordinates "+ "in sexagesimal syntax.\n \n"+ "If the \"Target\" is omitted, Aladin takes into account "+ "the last specified target.\n"+ "If there is only a \"Target\" and no \"ServerName\", two cases:\n"+ "- Aladin will load a default data set if the plane stack is free\n"+ "- Aladin will move the current target tag to the corresponding position "+ "eventually by resolving the identifier into coordinates." ); } // Gestion du Help public boolean handleEvent(Event e) { if( Aladin.inHelp ) { if( e.id==Event.MOUSE_ENTER ) aladin.help.setText(Help()); return true; } return super.handleEvent(e); } public boolean action(Event e, Object o) { if( e.target instanceof Choice && getFrameSelected()!=oi ) { aladin.calque.changeFrame(); return true; } return false; } } GMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTcds/aladin/Logo.java010064400076440000132000000227750770227416100153300ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion du logo CDS. * Il va s'afficher en haut a gauche de l'interface. Si on clique dessus, * le browser chargera la home page du CDS. * Le deplacement de la souris sur le logo affichera une page * de HELP ``pour demarrer'' * *
Rq: en cas de fonctionnement standalone, le fichier du logo * sera cherche dans le repertoire d'installation d'AladinJava * * @@See Aladin.HOME * @@version 1.1 (19 mai 99) Generation d'un message special au demarrage * si des donnees sont entrain d'etre chargees * @@version 1.0 (4 mai 99) Toilettage du code * @@version 0.9 Creation */ public final class Logo extends Canvas { static final int W=89; // Taille du logo static final int H=56; // Hauteur du logo static final int DF=20; // Taille de la font si le logo n'est pas accessible Image img=null; // L'image du logo Aladin aladin; // Reference boolean first=true; // Pour reperer le premier passage boolean mem_inHelp=false; // Memorisation de l'etat du Help Thread waitCmd=null; // Pour recevoir des commandes asynchrones /** Creation du logo. * Procede par importation via HTTP ou par lecture * de fichier d'une image GIF * Rq : img est mis a jour * @@param aladin reference a la hierarchie objet */ protected Logo(Aladin aladin) { this.aladin=aladin; img = aladin.getImagette("logo.gif"); resize(W,H); setBackground( Aladin.BKGD ); // positionnement de l'icone aladin.f.setIcone(img); } /** Entree de la souris dans le logo. * Lorsque l'on rentre dans le logo, le curseur se change en petite main * afin de signifier que l'icone est cliquable */ public boolean mouseEnter(Event e, int x, int y) { Aladin.makeCursor(this,Aladin.HAND); requestFocus(); return true; } /** Sortie de la souris du logo. * Lorsque l'on sort du le logo, le curseur reprend sa forme initiale */ public boolean mouseExit(Event e, int x, int y) { Aladin.makeCursor(this,Aladin.DEFAULT); return true; } /** Clique sur le logo. * Cliquer dans le logo entraine l'appel a la marque GLU * Aladin.java.home */ public boolean mouseDown(Event e, int x, int y) { aladin.glu.showDocument("Aladin.java.home",""); return true; } /** Deplacement sur le logo. * Necessaire pour ``manger'' l'evenement */ public boolean mouseMove(Event e, int x, int y) { return true; } /** Changement du niveau de trace */ public boolean keyDown(Event e,int key) { if( key=='d' ) { Aladin.levelTrace++; if( Aladin.levelTrace>Aladin.MAXLEVELTRACE ) { Aladin.levelTrace=0; System.out.println("Trace mode off!\n"); } else System.out.println("Trace mode level "+Aladin.levelTrace+" / "+Aladin.MAXLEVELTRACE); } return true; } /** Inhibe */ public void update(Graphics g) { paint(g); } /** Gestion de l'affichage. * Dessine le logo apres avoir mise en place le fond * Si le logo est innacessible, se contente d'ecrire en grand * les lettres CDS */ public void paint(Graphics g) { if( first ) { first=false; g.setColor( Aladin.BKGD ); g.fillRect(0,0,W,H); } if( img!=null ) g.drawImage(img,0,0,this); else { g.setFont(Aladin.LLITALIC); g.setColor( Color.darkGray ); g.drawString("CDS",W/2-30,H/2+DF/2); } } /** Generation du texte du Help. * Genere le Help qui va apparaitre lorsque l'utilisateur * deplace la souris sur le logo * * @@Return : La chaine du Help (String) */ protected String Help() { String six=""; if( !Aladin.STANDALONE ) six="-> Click on ``DETACH'' button to have Aladin Java "+ "into a separate window.\n \n"; return "*%AVO.gif\n \n"+ "AVO demonstration prototype uses Aladin "+ "allowing one to visualize digitized images of any part of the sky, "+ "to superimpose entries from astronomical catalogs, "+ "and to interactively access related data and information,"+ "especially the GOODS CDFS data for this demonstration.\n \n"+ "Note that this page is always accessible just by moving the mouse "+ "to the AVO logo at the top-left corner of the screen.\n"+ "!To start\n"+ "1) Click on the button \""+Aladin.MLOAD+ "\" to load an image;\n"+ "2) From the same form choose a data server to overlay "+ "astronomical sources;\n"+ "3) Look at the ``plane stack'' on the right side of the screen "+ "for a summary of the state of your queries and to modify the current visualization;\n"+ "4) Click on an overplotted object to display its basic parameters in the "+ "``measurement frame'' (bottom frame); detailed parameters can then be accessed "+ "by clicking on the source name (in blue underlined)\n"+ "5) See the Help for the ``Tool bar'' to learn what you can do "+ "with each tool button.\n \n"+ six; } /** Generation du texte du Help. * Genere le Help qui va apparaitre lorsque l'utilisateur * lance Aladin Java avec un chargement immediat d'une image ou de donnees * * @@Return : La chaine du Help (String) */ protected String inProgress() { return "!"+Aladin.TITRE+" - "+Aladin.getReleaseNumber()+"\n"+ "\n"+ "AVO demonstration prototype uses Aladin "+ "allowing one to visualize digitized images of any part of the sky, "+ "to superimpose entries from astronomical catalogs, "+ "and to interactively access related data and information, "+ "especially the GOODS CDFS data for this demonstration."+ " \n"+ "*...YOUR DATA ARE BEING DOWNLOADED..."+ " \n \n"+ "Note that a short help to start is always accessible just by moving "+ "the mouse to the Aladin logo at the top-left corner of the screen.\n"+ " \n \n"; } /** Gestion du Help. * Trappe les evenements MOUSE_ENTER et MOUSE_EXIT * afin de gerer convenablement l'affichage lorsque Aladin JAVA * est en mode Help ou non */ public boolean handleEvent(Event e) { if( e.id==Event.MOUSE_ENTER ) { mem_inHelp = Aladin.inHelp; aladin.help.setText(Help()); if( !Aladin.inHelp ) { Aladin.inHelp=true; aladin.cardView.show(aladin.bigView,"Help"); } } else if( e.id==Event.MOUSE_EXIT ) { if( mem_inHelp==false ) { Aladin.inHelp=false; aladin.cardView.show(aladin.bigView,"View"); } } return super.handleEvent(e); } } cumcds/aladin/MCanvas.java010064400076440000132000000707030770227416100157520ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Canvas d'affichage des mesures des objets selectionnees * * @@author Pierre Fernique [CDS] * @@version 1.2 : 28 mars 00 Toilettage du code * @@version 1.1 : 3 juin 99 Gestion du bloc-note * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class MCanvas extends Canvas /*thomas*/implements Runnable{ static final int NBLIGNE = 5; // Nombre de lignes visibles par defaut static final int HM = 1; // Hauteur des marges (en haut et en bas) static final int HF = Aladin.SIZE; // Hauteur des lettres static final int HL = HF+3; // Hauteur d'une ligne static final Color BG = Aladin.LGRAY; //Color.white ou Aladin.BKGD precedemment // Triangles-reperes de la ligne courante (position sur 1ere ligne) static final int [] tX = { 5, 5, 14, 5 }; // Exterieur static final int [] tY = { HL/2+HM -5, HL/2+HM +5, HL/2+HM, HL/2+HM -5 }; Aladin aladin; // Reference Vector text; // Reference MyScrollbar scrollV; // Reference MyScrollbar scrollH; // Reference int W,H; // Taille courante du MCanvas Image img; // Buffer de l'image Graphics g; // Contexte graphique du buffer boolean quickRepaint; // true si l'affichage n'a pas besoin de faire un update() complet FontMetrics m; // Metrique associee au texte int wblanc; // Taille d'un ``blanc'' dans le texte int firstsee; // Premiere ligne affichee int lastsee; // Derniere ligne affichee int currentsee=-1; // Ligne courante (sous la souris) int nbligne; // Nombre de lignes visibles actuellement Source oo; // Precedente Source montree Words ow; // Dernier mot selectionne Words wButton; // Dernier bouton appuye Objet oButton; // Objet associe au dernier bouton appuye int yrep=-1; // l'ordonnee du dernier repere courant int X=0; // Abscisse d'origine int oy=-1; // L'ordonnee avant un drag int ox=-1; // L'abscisse avant un drag boolean flagDrag=false; boolean firstUpdate=true; // Pour positionner le premier curseur int currentselect=-2; // thomas (test pour infobulle) Thread thread = null; // thread pour l'affichage de l'infobulle boolean showToolTip = false; int indiceCourant=-1; Source sCourante = null; Words wCourant = null; /** Creation. * @@param aladin Reference * @@param text Le vecteur contenant chaque ligne de mesures * @@param scrollV La reference a la barre de defilement verticale * @@param scrollH La reference a la barre de defilement horizontale */ protected MCanvas(Aladin aladin,Vector text,MyScrollbar scrollV,MyScrollbar scrollH) { this.aladin = aladin; this.text = text; this.scrollV = scrollV; this.scrollH = scrollH; // Determination des tailles des lettres m = getToolkit().getFontMetrics(Aladin.COURIER); wblanc = m.stringWidth(" "); // Positionnement des valeurs de defaut resize(2, HL*NBLIGNE + HM*2); W=size().width; H=size().height; } /** Recale l'absisse par defaut */ protected void initX() { X=0; } /** Dessine le bord gauche * @@param x,y l'emplacement du mot dans la case * @@param width la taille de la case */ private void drawBordG(Graphics g,int x,int y,int width) { g.setColor(Color.black); g.drawLine(x+width+2,y,x+width+2,y+HF+2); } /** Dessin d'un repere (petit triangle) a la position (x,y). * @@param g Le contexte graphique * @@param x,y Les coordonnees ou le repere doit etre dessine * @@param p L'objet (au sens aladin) associe au repere ou null si aucun * (l'objet (p) n'est utilise que pour determiner la * couleur du repere) * @@param flagRep true si on remplit le repere */ private void drawRepere(Graphics g,int x,int y,Position p,boolean flagRep) { int dy = y-HF-2; // Decallage en ordonnee a partir de la ligne de base int [] cY = new int[tY.length]; // Pour memoriser les nouvelles ordonnees // Decallage en ordonnee for( int i=0; iwidthw ) width = w.width*wblanc; else width=widthw; if( x+width>=1 ) { l=width-3; g.setColor(Aladin.BKGD); g.fillRect(x,y,l,h); g.setColor(w.pushed?Color.black:Color.white); g.drawLine(x,y,x+l,y); g.drawLine(x,y,x,y+h); g.setColor(w.pushed?Color.white:Color.black); g.drawLine(x+l,y+h,x+l,y); g.drawLine(x+l,y+h,x,y+h); if( w.pushed ) g.setColor( Color.red ); else if( w.haspushed ) g.setColor( Color.white ); else g.setColor( Color.black ); g.drawString(s,x+3,y+h-1); drawBordG(g,x,y-2,width); } return width; } static Color C1 = new Color(199,207,255); static Color C2 = new Color(85,26,139); static Color C3 = new Color(104,230,255); /** Tracer d'un mot dans la fenetre des mesures. *
* Rq : Met a jour la boite englobante du mot w.setPosition(...) * * @@param g Le contexte du graphique * @@param w Le mot * @@param flagClear true s'il faut au prealable effacer * @@return La taille calculee */ private int drawWord(Graphics g, Words w, boolean flagClear) { int y = w.y+HF; // Ligne de base int x = w.x; int xtext; // Ligne du texte int width; // Taille totale (en fonction du nbre de carac. indiques) int widthw; // Taille du mot // Determination de la taille widthw = m.stringWidth(w.text); if( w.width*wblanc>widthw ) width = w.width*wblanc; else width=widthw; if( x+width<1 || x>W ) return width; // trop a gauche ou a droite // Effacement prealable si necessaire if( flagClear || w.selected ) { g.setColor( w.selected ?Color.black:BG ); g.fillRect(x-4,y-HF,width+7,HL-1); } // Une marque GLU (ancre) if( w.glu ) { if( w.pushed ) g.setColor( Color.red ); // L'ancre a ete cliquee else if( w.haspushed ) g.setColor( w.selected ?C1:C2 ); // Ancre inactive (jamais cliquee) else g.setColor( w.selected ?C3:Color.blue ); // Ancre deja cliquee } else g.setColor( w.selected ?Color.white:Color.black ); // Par defaut // Affichage du texte en fonction de l'alignement xtext=x; if( w.align==Words.RIGHT ) xtext=x+width-widthw; else if( w.align==Words.CENTER ) xtext=x+width/2 - widthw/2; g.drawString(w.text,xtext,y); if( w.glu ) g.drawLine(xtext,y+1,xtext+widthw,y+1); // On souligne s'il s'agit d'une ancre drawBordG(g,x,y-HF,width); return width; } /** Mise a jour d'une ligne. * Ecrit dans le contexte graphique les infos d'une ligne de mesures contenues dans * le vecteur word a l'ordonnee y * Rq: Le repere qui commence generalement la ligne sera trace a la fin (memorisation) * afin d'effacer un eventuel mot qui serait trace en dessous suite a un decallage * a gauche des valeurs (par drag souris) * * @@param g Le contexte graphique * @@param y La position de la ligne de base (ordonnee) * @@param word Le vecteur contenant les differents mots de la ligne de mesures * @@param flagClear true si efface la surface au prealable * @@param flagRep true si le repere doit etre plein * @@param flagSelect true si la ligne doit etre encadree * @@return le nombre de pixels necessaires a la ligne */ private int drawWords(Graphics g,int y,Vector word,boolean flagClear, boolean flagRep,boolean flagSelect) { Words w; // liste courante de mots int x=X; // Abscisse courante dans la ligne int width; // Largeur du mot (ou du repere) courant Enumeration e = word.elements(); // Pour faciliter la manip Position p = (Position)e.nextElement(); // L'objet lui-meme est en 1er place du vecteur // Effacement de la ligne si necessaire if( flagClear ) { g.setColor( BG ); g.fillRect(1,y-HF,W,y+3); } // Pour l'extraction du repere de debut de ligne Words rep = null; boolean flagFirst=true; // Affichage du repere et de chaque mot while( e.hasMoreElements() ) { w = (Words) e.nextElement(); // Dans le cas d'un repere if( w.repere ) { if( flagFirst ) rep = w; else drawRepere(g,x,y,p,flagRep); width=tX[2]; // Dans le cas d'un pointeur vers une archive FITS } else if( w.archive ) { width=drawButton(g,x,y,w.text,w); // Dans le cas d'un mot } else { w.setPosition(x,y-HF,0,0); // Memo des coord width = drawWord(g,w,false); } w.setPosition(x,y-HF,width,HF); // Memo de la boite recouvrant le mot, le repere x += width+wblanc; // Calcul de la prochaine abscisse flagFirst=false; } // Affichage du repere de debut de ligne si necessaire if( rep!=null ) drawRepere(g,X,y,p,flagRep); // On trace le trait sous la ligne g.setColor(flagSelect?Color.red:Color.black); g.drawLine(1,y+2,W,y+2); return x-X; } /** Remonte un eventuel bouton et chargement d'une image d'archive */ public boolean mouseUp(Event ev, int x, int y) { if( wButton!=null ) { wButton.pushed=false; wButton.haspushed=true; wButton.callArchive(aladin,oButton); wButton=null; oButton=null; repaint(); } if( flagDrag) flagDrag=false; return true; } int memFirstsee=0; /** Clic sur une marque HTML * Appel au Glu resolver si on se trouve sur une ancre GLU */ public boolean mouseDown(Event ev, int x, int y) { // on avertit filterProperties qu'il y a eu un click dans les mesures if( aladin.filterProperties!=null ) { if( aladin.filterProperties.clickInMesure(sCourante,indiceCourant) ) return true; } // Il n'y a pas de mesure dans la fenetre des mesures if( currentsee<0 || text.size()<=currentsee ) return true; // En cas d'un drag ox=x; oy=y; memFirstsee=firstsee; // Recuperation des mots de la ligne courante Vector word = (Vector)text.elementAt(currentsee); Enumeration e = word.elements(); // Pour faciliter la manip. Source o = (Source)e.nextElement(); // L'objet lui-meme // Recalibration dynamique en cours ? if( aladin.frameNewCalib!=null && aladin.frameNewCalib.isShowing() ) { aladin.frameNewCalib.mouse(0,0,null,o); } // Affichage de la coordonnees de la source aladin.localisation.seeCoord(o,1); while( e.hasMoreElements() ) { Words w = (Words) e.nextElement(); // Analyse mot par mot if( !w.glu ) continue; // Inutile si ce n'est pas une marque GLU if( w.inside(x,y) ) { // C'est gagne // Indication d'appel direct a l'archive if( w.archive ) { wButton=w; // Memo en vue de l'utilisation dans mouseUp oButton=o; // Idem w.pushed=true; repaint(); return true; } // Appel a l'ancre aladin.glu.newWindow(ev.shiftDown());// Pour pouvoir creer une nouvelle fenetre w.callGlu(aladin.glu,this); repaint(); return true; } } currentselect=(currentselect==currentsee)?-2:currentsee; repaint(); return true; } /** Deplacement de la souris sur les mesures. * Reperage du mot courant et de l'objet associe dans la vue */ public boolean mouseMove(Event evt, int x, int y) { String s; // La chaine a afficher dans le status quickRepaint=false; // true s'il faut faire un affichage de certaines mesures Words w=null; // Mot courant (sous la souris) // Determination de la ligne courante currentsee = firstsee+ (y-HM)/HL; // Si on se trouve en dehors de toute ligne, on gere l'evenement // de la meme maniere que si l'on sort de la fenetre // if ( currentsee>=text.size() ) return mouseExit(evt,x,y); if ( currentsee>=text.size() ) { // Si aucun nouveau mot n'est selectionne, il faut quand meme deselectionne le // precedent indiceCourant=-1; if( ow!=null ) { quickRepaint=true; ow.selected=false; drawWord(g,ow,true); ow=null; repaint(); } return true; } // Determination de l'objet courant Vector v = (Vector) text.elementAt(currentsee); Source o = (Source) v.elementAt(0); // Affichage de la coordonnees de la source aladin.localisation.seeCoord(o); // Affichage du texte (legende ou texte) associee a la mesure Enumeration e = v.elements(); e.nextElement(); // Je saute l'objet lui-meme int i=0; boolean trouve=false; // true si on trouve un mot a selectionner while( e.hasMoreElements() ) { w = (Words) e.nextElement(); // Les mots if( w.inside(x,y) ) { trouve=true; // thomas indiceCourant=i-1; wCourant = w; sCourante = o; if( thread!=null ) thread.stop(); thread = new Thread(this); thread.setPriority( Thread.NORM_PRIORITY -1); thread.start(); // Effacement du precedent if( ow!=null ) { if( ow==w ) break; // toujours le meme mot ow.selected=false; drawWord(g,ow,true); ow=null; } // On change le curseur et on affiche eventuellement // l'URL ou la marque GLU try { if( w.glu ) w.urlStatus(aladin.urlStatus); else aladin.urlStatus.setText(""); } catch(Exception ecurs) {} if( w.archive ) { // Baratin explicatif s="Click on it to load the corresponding archive data"; } else if( w.repere ) { // Pour le repere on affiche que le texte s=w.text; } else { ow = w; // Memorisation du mot courant w.selected=true; // Selection du mot courant drawWord(g,w,true); g.setColor(Color.darkGray); g.drawLine(0,H-1,0,0); // Recuperation de la description du champ s=(o.leg!=null)?o.leg.getDescription(i-1):null; } if( s==null ) s=""; aladin.mesure.setStatus(s); // Mise a jour du status quickRepaint=true; break; } i++; } // Visualisation dans la vue de la source associee a la mesure courante // ainsi que du repere if( !trouve ) { if( oo!=null ) { aladin.view.hideSource(); if( yrep!=-1) { quickRepaint=true; drawRepere(g,0,yrep,(Position)oo,false); } oo=null; } currentsee=-1; } else if( o!=oo) { aladin.view.showSource(o); if( oo!=null && yrep!=-1) drawRepere(g,0,yrep,(Position)oo,false); drawRepere(g,0,w.y+HF,(Position)o,true); yrep=w.y+HF; oo=o; // Memorisation de la source courante } // thomas if(!trouve) indiceCourant=-1; // Si aucun nouveau mot n'est selectionne, il faut quand meme deselectionne le // precedent if( !trouve && ow!=null ) { quickRepaint=true; ow.selected=false; drawWord(g,ow,true); ow=null; } if( quickRepaint ) repaint(); return true; } public boolean mouseEnter(Event e, int x, int y) { Aladin.makeCursor(this,Aladin.HAND); return true; } /** Sortie de la souris. * Fin de reperage du mot courant et de l'objet associe dans la vue */ public boolean mouseExit(Event e, int x, int y) { aladin.mesure.setStatus(""); // Clear du status aladin.urlStatus.setText(aladin.COPYRIGHT); // Remet le copyright currentsee=-1; // Plus aucune ligne courante Aladin.makeCursor(this,Aladin.DEFAULT); // thomas if(thread!=null) thread.stop(); if( oo==null && ow==null ) return true; // Rien de repere // Traitement de l'objet dans la vue if( oo!=null ) { oo=null; aladin.view.hideSource(); } // Traitement du mot courant if( ow!=null ) { ow.selected=false; ow=null; } quickRepaint=false; repaint(); return true; } /** Indication d'une ligne de mesure. * Recherche d'une ligne de mesures dans la fenetre des mesures * associees a un objet * @@param o L'objet a trouver dans la liste des mesures * @@return true si la recherche aboutie, sinon false */ protected boolean show(Source o) { int n; // Numero de ligne int ntext; // Nombre de ligne de mesures boolean retour=false; // Le code de retour par defaut if( o==null ) currentsee=-1; // Logique ! else { for( n=0, ntext=text.size(); nlastsee ) { if( nmax ) max=m; } lastsee--; // Ajustement du scrollbar horizontal si necessaire adjustScroll(max); // Nettoyage de la fin de la fenetre si necessaire y-=HF; int ry=H-y-2; // La plage restante if( ry>0 ) { g.setColor( BG ); g.fillRect(1,y,W-1,ry); } // Les bordures du cadre g.setColor(Color.darkGray); g.drawLine(0,H-1,0,0); g.drawLine(0,0,W-1,0); g.setColor(Color.white); g.drawLine(W-1,0,W-1,H-1); g.drawLine(W-1,H-1,0,H-1); // thomas if(showToolTip) { drawToolTip(); } paint(gr); } // Affichage du buffer de l'image sur l'ecran public void paint(Graphics gr) { int w = size().width; int h = size().height; // Detection d'image vide ou de changement de taille if( img==null || img.getWidth(this)!=w || img.getHeight(this)!=h) { img=null; update(gr); return; } gr.drawImage(img,0,0,null); } /** Gestion du Help */ protected String Help() { return("!Measurement window\n"+ "Display associated data on the sources selected"+ "in the ``View window''.\n \n"+ "In the ``View window'', you can select an individual "+ "source by clicking on it, or several sources by delimiting a "+ "rectangular area with a clik-and-drag mouse operation.\n \n"+ "In the ``Measurement window'' :"+ "- Move the mouse to each data component to see "+ " its label and some explanations (in the ``Status window''), and to see "+ " its corresponding source (in the ``View window'').\n \n"+ "- Click on colored triangles at the beginning of each line to launch "+ " a Web browser and to receive explanations on "+ " the origin of the data.\n \n"+ "- Click on blue underlined components to learn more "+ " about the source.\n \n"+ "To free this window, you have to deselect the sources. You can "+ "click on the SELECT tool, or click in the ``View window'' away "+ "from all sources.\n \n"+ "To select all the sources in a source plane, deselect the sources, "+ "if necessary, and then reselect the plane in the ``Plane stack'' and click "+ "on the SELECT tool."); } // Gestion du Help public boolean handleEvent(Event e) { if( Aladin.inHelp ) { if( e.id==Event.MOUSE_ENTER ) aladin.help.setText(Help()); return true; } return super.handleEvent(e); } // thomas public void run() { if(showToolTip) { showToolTip=false; repaint(); } // attente de 0.5 sec. try {thread.sleep(500);} catch(Exception e) {} showToolTip=true; repaint(); // attente de 4 sec. puis on cache de nouveau try {thread.sleep(4000);} catch(Exception e) {} showToolTip=false; repaint(); } // thomas private void drawToolTip() { int xTT,yTT; String toolTipText = sCourante.leg.getToolTipText(indiceCourant); if(toolTipText==null) return; Color bgColor = Color.yellow; Color cadreColor = Color.black; Color textColor = Color.black; Font font = Aladin.SPLAIN; Font oFont = g.getFont(); g.setFont(font); FontMetrics fm = g.getFontMetrics(font); int wOriginal = fm.stringWidth(toolTipText); int hOriginal = fm.getMaxAscent()+fm.getDescent(); int w = (int)(1.2*wOriginal); int h = (int)(1.2*hOriginal); // Determination de la taille int widthw = m.stringWidth(wCourant.text); if( wCourant.width*wblanc>widthw ) widthw = wCourant.width*wblanc; // coordonnes de l'infobulle xTT = wCourant.x+widthw; yTT = wCourant.y-1; // pour eviter que l'infobulle soit tronquee par le haut int decY = yTT-h; if(decY<0) yTT-=decY-HF-2; // pour eviter que l'infobulle ne soit tronquee par la droite int decX = xTT+w-size().width; if(decX>0) xTT-=decX; g.setColor(bgColor); g.fillRect(xTT,yTT-h,w,h); g.setColor(cadreColor); g.drawRect(xTT,yTT-h,w,h); g.setColor(textColor); g.drawString(toolTipText,(int)(xTT+0.5*(w-wOriginal)),(int)(yTT-0.7*(h-hOriginal))); g.setFont(oFont); } } adin.mesure.setStatus(s); // Mise a jour du status cds/aladin/Message.java010064400076440000132000000173260770227416100160100ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.util.*; /** * Gestion des messages *

Description:

*

Copyright: Copyright (c) 2003

*

Company:

* @@author non attribué * @@version 1.0 */ public class Message extends Panel { static final int NON=0; static final int OUI=1; static final int MESSAGE=0; static final int CONFIRME=1; static final int WARNING=2; int type; int value=NON; Button ok,oui,non; static Dialog dialog; public Message(String message,int type) { super(); this.type = type; GridBagLayout g = new GridBagLayout(); setLayout(g); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.NONE; c.gridwidth = GridBagConstraints.REMAINDER; Label a; c.anchor = GridBagConstraints.WEST; StringTokenizer st = new StringTokenizer(message,"\n"); boolean first=true; int MH=-5; int mh=10; int mg; int MG=20; int max; while( st.hasMoreTokens() ) { String s=st.nextToken().trim(); int taille=12; if( s.length()==0 ) { mh+=12; continue; } if( s.charAt(0)=='.' ) { mg=MG+20; max=55;} else if( s.charAt(0)=='!') { s=s.substring(1); taille=14; mg=MG+20; max=30; } else { mg=MG; max=60; } int n=0; StringBuffer b = new StringBuffer(); StringTokenizer sta = new StringTokenizer(s," "); while( sta.hasMoreTokens() ) { if( n>0 ) b.append(" "); String mot = sta.nextToken(); n+=mot.length()+1; b.append(mot); if( !sta.hasMoreTokens() || n>max ) { String ligne=b.toString(); a = new Label(ligne); a.setFont( new Font("Helvetica",Font.BOLD,taille)); if( type==WARNING) a.setForeground(Color.red); c.insets = new Insets(mh,mg,0,20); mh=MH; g.setConstraints(a,c); add(a); b = new StringBuffer(); n=0; } } } c.anchor = GridBagConstraints.CENTER; c.insets = new Insets(10,20,10,20); Panel p = new Panel(); if( type!=CONFIRME ) { ok = new Button("OK"); ok.setFont( new Font("Helvetica",Font.PLAIN,12)); p.add(ok); } else { oui = new Button("Yes"); oui.setFont( new Font("Helvetica",Font.PLAIN,12)); p.add(oui); non = new Button("No"); non.setFont( new Font("Helvetica",Font.PLAIN,12)); p.add(non); } g.setConstraints(p,c); add(p); } private void addAction() { if( type!=CONFIRME ) { ok.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { dialog.dispose(); } }); } else { oui.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { value=OUI; dialog.dispose(); } }); non.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { value=NON; dialog.dispose(); } }); } } public static int showWarning(Component c, String message) { Message pane = new Message(message,WARNING); dialog = pane.createDialog(c, "Warning"); pane.addAction(); dialog.show(); return pane.value; } public static int showMessage(Component c, String message) { Message pane = new Message(message,MESSAGE); dialog = pane.createDialog(c, "Information"); pane.addAction(); dialog.show(); return pane.value; } public static int showConfirme(Component c, String message) { Message pane = new Message(message,CONFIRME); dialog = pane.createDialog(c, "Confirmation"); pane.addAction(); dialog.show(); return pane.value; } public Dialog createDialog(Component c, String title) { final Dialog dialog; while( c!=null && !(c instanceof Frame) ) c=c.getParent(); dialog = new Dialog((Frame)c, title, true); dialog.setLayout(new BorderLayout()); dialog.add(this, BorderLayout.CENTER); dialog.pack(); Point p; try { p = c.getLocationOnScreen(); } catch( Exception e ) { p = new Point(400,300); } Dimension d = c.getSize(); Dimension dc = getSize(); dialog.setLocation(p.x+Math.abs(d.width/2-dc.width/2), p.y+Math.abs(d.height/2-dc.height/2)); dialog.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent we) { dialog.dispose(); } }); return dialog; } } cds/aladin/Mesure.java010064400076440000132000000232300770227416100156530ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Element de l'interface d'affichage des mesures * * @@author Pierre Fernique [CDS] * @@version 1.2 : (25 juillet 2002) VOTable s'ajoute a Astrores * @@version 1.1 : (28 mars 00) ReToilettage du code * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Mesure extends Panel { Aladin aladin; // Reference MCanvas mcanvas; // Canvas des infos et mesures MyScrollbar scrollV; // Scrollbar verticale MyScrollbar scrollH; // Scrollbar horizontale Vector text = new Vector(100); // Listes des infos courantes Panel haut; // Le panel haut Status status; // status propre a une fenetre independante boolean flagSplit; // true si la fenetre est independante int previousHeight=0; // Hauteur en fenetree /** Creation du Panel des mesures. * Il s'agit de creer MCanvas et la scrollV associee * @@param aladin Reference */ protected Mesure(Aladin aladin) { this.aladin = aladin; scrollV = new MyScrollbar(Scrollbar.VERTICAL,0,0,0,0); scrollH = new MyScrollbar(Scrollbar.HORIZONTAL,0,0,0,0); mcanvas = new MCanvas(aladin,text,scrollV,scrollH); status = new Status(aladin,""); flagSplit=false; haut = new Panel(); haut.setLayout( new BorderLayout(2,2) ); Aladin.makeAdd(haut,new Filet(4,0),"North"); Aladin.makeAdd(haut,status,"Center"); Aladin.makeAdd(haut,new Filet(4,0),"South"); setLayout( new BorderLayout(0,0) ); Aladin.makeAdd(this,haut,"North" ); Aladin.makeAdd(this,mcanvas,"Center"); Aladin.makeAdd(this,scrollV,"East"); Aladin.makeAdd(this,scrollH,"South"); resize( preferredSize()); haut.hide(); } /** Ajustement du panel pour une visualisation dans une fenetre independante */ protected void split(boolean flagSplit) { if( flagSplit==this.flagSplit ) return; this.flagSplit=flagSplit; if( flagSplit ) { previousHeight = mcanvas.size().height; haut.show(); status.resize(status.size().width,status.H); mcanvas.resize(mcanvas.size().width, 600); scrollV.resize(scrollV.size().width, 600); } else { haut.hide(); mcanvas.resize(mcanvas.size().width, previousHeight); scrollV.resize(scrollV.size().width, previousHeight); } resize( preferredSize()); } /** * Update the status string * @@param text */ protected void setStatus(String text) { if( flagSplit ) status.setText(text); else aladin.status.setText(text); } /** Ajout des mesures d'une source. * Analyse et ajout des infos/mesures associees a la source SANS reaffichage * @@param o La source pour laquelle il faut afficher les mesures */ protected void insertInfo(Source o) { boolean first=true; String prefix=""; String tag; Vector word = new Vector(20); Words w,w1; String s; word.addElement(o); // L'objet lui-meme est tjrs en premiere place s=(o.info!=null)?o.info:o.id; // Faute de grive... StringTokenizer st = new StringTokenizer(s,"\t"); int i=0; while( st.hasMoreTokens() ) { tag = st.nextToken(); if( i==0 ) w = new Words(tag); // Le triangle n'a pas de taille else { // Determination de l'alignement en fonction du type de donnees String datatype = o.leg.getDataType(i-1); int align=Words.LEFT; if( datatype!=null ) { char c = datatype.charAt(0); if( c=='D' || c=='F' || c=='I') align=Words.RIGHT; if( datatype.equals("double") == true || datatype.equals("float") == true || datatype.equals("int") == true) align=Words.RIGHT; } // Creation du nouveau mot w = new Words(tag,o.leg.getWidth(i-1),align); } i++; word.addElement(w); if( w.glu && w.size=0 && fin>deb ) res.append( w.text.substring(deb+1,fin)+":\t"); } else res.append(w.text+"\t"); } res.append("\n"); } return res.toString(); } /** Vidange. * Enleve toutes les mesures. */ protected void removeAllElements() { mcanvas.currentselect=-2; text.removeAllElements(); scrollV.setValues(0,1,0,1); } /** Purge. * Purge des Sources dont les plans d'appartenance ont ete * vides ou ne sont pas selectionnes */ protected void removeOldElements() { boolean dopaint = false; // Le lock sur text est necessaire en raison du thread qui calcule les filtres --> risque de pb sans ce lock synchronized(text) { for( int i=0; inl?n-nl:n,n>nl?nl:n,1,m); } // Gestion du scrollV public boolean handleEvent(Event e) { switch(e.id) { case Event.SCROLL_LINE_UP: case Event.SCROLL_LINE_DOWN: case Event.SCROLL_PAGE_UP: case Event.SCROLL_PAGE_DOWN: case Event.SCROLL_ABSOLUTE: mcanvas.repaint(); } return super.handleEvent(e); } } cds/aladin/MetaDataTree.java010064400076440000132000000557670770227416100167370ustar00ferniquecds00000400000013package cds.aladin; import java.awt.*; import java.net.URLEncoder; import java.util.*; /** Classe MetaDataTree * @@author Thomas Boch [CDS] * @@version 0.6 5 Juin 2003 - Découplement de cette classe avec TreeView * 0.5 Février 2003 - Création */ // arbre qui sera utilisé pour afficher les ressources sous forme hiérarchiques public class MetaDataTree extends BasicTree { // message quand aucun cutout n'est dispo private static final String NOIMAGE_WARNING = "can not be loaded : \nno cutout available at this position !\nClick on the region you are interested in\nAvailable images will be marked with a red tick"; private static final String SORTBY = "Sort by ..."; private GridBagLayout g = new GridBagLayout(); private GridBagConstraints c = new GridBagConstraints(); // référence à l'objet aladin Aladin aladin; // Constructeurs MetaDataTree(BasicNode rootNode, Aladin aladin, ScrollPane scroll) { super(rootNode, scroll); this.aladin = aladin; } MetaDataTree(Aladin aladin, ScrollPane scroll) { this(new ResourceNode(), aladin, scroll); } // Fin constructeurs /** Ajoute newNode comme sous-noeud de parent * Met l'arbre à jour pour que newNode apparaisse */ void addNode(ResourceNode parent, ResourceNode newNode) { parent.addChild(newNode); traverseTree(); getStartPosition(newNode); init(); // nécessaire ? //if( scroll!=null ) scroll.doLayout(); repaint(); } /** Change la racine de l'arbre et reconstruit le tout */ void setRoot(ResourceNode newRoot) { this.rootNode = newRoot; traverseTree(); getStartPosition(rootNode); init(); repaint(); } // eteint tous les noeuds couramment affiches protected void turnOffAllNodes() { ResourceNode curNode; if( nodeTab==null ) return; for( int i=0; i0 && ( node.getChildrenAt(0).isLeaf || ((ResourceNode)node).valueCriteria!=null ) ) node.isOpen = false; else node.isOpen = true; // le noeud racine est toujours ouvert if( node.equals(rootNode) ) node.isOpen = true; } } protected void getStartPosition() { getStartPosition(nodeFullTab); } protected void getStartPosition(BasicNode myNode) { Vector v = new Vector(); getAllSubnodes(myNode,v); v.addElement(myNode); BasicNode[] tab = new BasicNode[v.size()]; v.copyInto(tab); v=null; getStartPosition(tab); } // Override de certaines méthodes protected void drawFrame(BasicNode node) { ResourceNode n = (ResourceNode)node; if( n.col == null ) h.setColor(Color.black); else h.setColor(n.col); h.drawRect( n.x,(node.y/YSPACE)*YSPACE+2, h.getFontMetrics().stringWidth(n.name),YSPACE-6); } protected void onNodeExpanded(BasicNode node) {} protected void onNodeCollapsed(BasicNode node) {} protected void onNodeSelected(BasicNode node) { showInfo((ResourceNode)node); } protected void onNodeSelectedDbleClick(BasicNode node) { load((ResourceNode)node); } protected void onNodeRemoved(BasicNode node) { // si le noeud supprimé ou un de ses sous-noeuds est le noeud lastInfoNode Vector vec = new Vector(); getAllSubnodes(node,vec); if( node.equals(lastInfoNode) || vec.contains(lastInfoNode) ) { lastInfoNode = null; } } protected void onMouseMoved(BasicNode node, boolean inNodeName) { ResourceNode curNode = (ResourceNode)node; if( /*curNode.isLeaf &&*/ curNode.type == ResourceNode.IMAGE && inNodeName ) { showFov(curNode); if( curNode.cutout ) showCutoutFov(curNode); else deactivateCutoutFov(); } else deactivateCutoutFov(); if( !inNodeName || curNode.type!=ResourceNode.IMAGE ) { hideFov(); } } /** ajoute à pop les combinaisons possibles d'éléments de sort */ private void createMenuItem(Menu pop, String[] sort) { // cas terminal : il ne reste plus que 2 éléments if( sort.length==1 ) { MenuItem item = new MenuItem(sort[0]); item.setActionCommand(pop.getActionCommand()+";"+sort[0]); pop.add(item); return; } // récursion for( int i=0; i0 ) { System.arraycopy(sort,0,newSort,0,i); start = i; } // on copie ce qui se trouve après i if( i1 ) { // ligne de séparation popup.add("-"); popup.add(SORTBY); createMenuItem(popup,resNode.sortCriteria); } popup.show(this,x,y); } public boolean action(Event e, Object o) { super.action(e,o); // action trappée dans onNodeRemoved if( o.equals(DELETE) ) return true; else if( e.target instanceof MenuItem ) { // quelle horreur, je me demande si je ne ferai pas mieux de coller des ActionListener if( o.equals(SORTBY) || o.equals(COLLAPSE_ALL) || o.equals(EXPAND_ALL) || o.equals(FLAT_VIEW) || o.equals(HIER_VIEW) ) { return true; } sortNode((ResourceNode)selectedNode, ((MenuItem)e.target).getActionCommand()); //System.out.println(((MenuItem)e.target).getActionCommand()); } return true; } /** trie les sous-noeuds de node en appliquant l'ordre des critères définis dans critStr */ private void sortNode(ResourceNode node, String critStr) { // récupération de l'ordre de tri StringTokenizer st = new StringTokenizer(critStr,";"); String[] crit = new String[st.countTokens()]; for( int i=0;i noeud */ private void sortAndCreate(ResourceNode[] tab, ResourceNode parent, String[] criteria, Hashtable nonLeaves) { if( tab.length==0 ) return; ResourceNode curLeaf; for( int i=0; i=0 ) aladin.calque.Fovs.removeElementAt(index); else aladin.calque.Fovs.addElement(selectedNode.fov); aladin.calque.view.repaint(); } /** Shows the information of a given node in the info frame @@param node The resource node */ private void showInfo(ResourceNode node) { FrameInfo curInst = FrameInfo.getInstance(); curInst.update(node,this); curInst.toFront(); curInst.show(); } // toutes ces méthodes là, ainsi que load() devraient se trouver dans ResourceNode /** Montre les fovs de node */ void showFov(ResourceNode node) { aladin.calque.curFov = getFovs(node); aladin.calque.view.repaint(); } /** Retournes les fovs d'un noeud * * @@param node le noeud à partir duquel on va chercher tous les fovs * @@return Fov[] tableau des fovs trouvés */ protected Fov[] getFovs(ResourceNode node) { Vector leavesV = new Vector(); getAllLeaves(node, leavesV); if( node.isLeaf ) leavesV.addElement(node); Enumeration e = leavesV.elements(); Fov[] fovs = new Fov[leavesV.size()]; int i=0; while( e.hasMoreElements() ) { fovs[i] = ((ResourceNode)e.nextElement()).fov; i++; } return fovs; } void showCutoutFov(ResourceNode node) { if( node.fov == null) return; try { // la résolution ne devrait pas prendre trop de temps car mini-cache de Pierre //aladin.calque.cutoutFov = new Fov(resolveTarget(aladin.treeView.centerCutOut.getText()), node.fov.cutout_x, node.fov.cutout_y, node.fov.angle); aladin.calque.cutoutFov = new Fov(resolveTarget(node.getCutoutTarget()), node.fov.cutout_x, node.fov.cutout_y, node.fov.angle); } catch(Exception e) {} aladin.calque.view.repaint(); } String resolveTarget(String s) { Coord c; try { if( !View.notCoord(s) ) c = new Coord(s); else c = aladin.view.getSimbad(s); } catch(Exception e) {return null;} return c.getSexa(":"); } void deactivateCutoutFov() { aladin.calque.cutoutFov = null; aladin.calque.view.repaint(); } void hideFov() { aladin.calque.curFov = null; aladin.calque.view.repaint(); } protected void hideAllFovs() { aladin.calque.Fovs.removeAllElements(); aladin.calque.view.repaint(); } /** Retourne le nom du noeud tel qu'on le veut dans l'arbre */ // à améliorer pour remonter aux niveaux n et n+1 pour noeuds autre que AladinServer // faire p-e un cas spécial pour AladinServer ou on prend color survey etc protected String getName(BasicNode node, boolean flat) { if( !node.isLeaf ) return node.name; ResourceNode n = (ResourceNode)node; if( !flat ) { // bidouille pour virer le -EPOCHx int indexEp; if( ( indexEp=n.name.indexOf("-EPOCH") ) > 0 ) { return n.name.substring(0,indexEp); } return n.name; } if( !n.isLeaf || n.color==null || n.survey==null || n.machine==null || n.plateNumber==null ) { String newName = getName(n,false); ResourceNode parent= (ResourceNode)n.getParent(); while( parent!=null && parent.type==ResourceNode.IMAGE ) { newName += " "+parent.name; parent = (ResourceNode)parent.getParent(); } return newName; } else return n.machine + " " + n.color + " " + n.survey + " "+ n.plateNumber + " " + (n.resol!=null?n.resol:""); } protected String getName(BasicNode node) { return getName(node,flatView); } // verifie qu on trouve bien un cutout a cet endroit donne protected boolean checkCutoutAvailability(BasicNode node, double alpha, double delta, Aladin al) { Coord coo = new Coord(alpha, delta); Plan p = al.calque.getPlanRef(); // ce cas m'emmerde un peu, je sais pas quoi faire // je renvoie true, normalement, et le serveur doit dire "No answer available" if( p==null || p.projd==null ) return true; coo = p.projd.getXY(coo); Point point = al.calque.view.zoomview.getViewCoord(coo.x,coo.y); //System.out.println(point.x); //System.out.println(point.y); return ((ResourceNode)node).fov.contains(point.x,point.y,p,al.calque.view.zoomview); } // charge l'image decrite par le noeud private void loadImage(ResourceNode node) { // true si l'image doit être chargé à partir d'Aladin // ceci permet de charger les images du nouveau serveur même à partir d'un fichier local (sauvegarde du fichier renvoyé par le serveur Aladin) // pour l'ancien serveur, je n'ai pas de solution pour le moment boolean fromAladin = node.location!=null && node.location.startsWith("glu:/ALADIN_SERVER"); /* --- Chargement d'une image quelconque --- */ if( node.location!=null && !fromAladin ) { String location = node.location; // les URL du type file:/... ne sont pas supportés par creatPlane, je bidouille if( location.startsWith("file:") ) location = location.substring(5); // vérifier type mime (tous ne sont pas supportés) aladin.dialog.server[ServerDialog.LOCAL].creatPlane("","",location+" image/fits",node.name,""); return; } // cas spécial pour bidouille section SIAP (images de l'ancien serveur) if( node.machine!=null ) { // je dois retransformer 'DSS1' en 'STScI' pour que le qualifier soit reconnu String qual = node.survey+" "+node.color+" "+(node.machine.equals("DSS1")?"STScI":node.machine)+" "; ((AladinServer)aladin.dialog.server[ServerDialog.ALADIN]).creatAladinPlane(Coord.getSexa(node.fov.alpha,node.fov.delta," "),node.curFormat,node.resol,qual,null,null); return; } /* --- Chargement d'une image provenant de Aladin nouveau serveur --- */ if( node.fov == null) return; String label = node.survey +" "+node.color; // bidouille pour avoir un nom correct dans le stack String myName = null; if( node.getParent()!=null && node.getParent().nbChildren>1 ) myName = node.name; if( node.cutout ) { double alpha, delta; alpha = delta = -1; Coord coo; try { coo = new Coord(node.getCutoutTarget()); alpha = coo.al; delta = coo.del; } catch( Exception e ) { // si erreur lors de l'interprétation en coordonnées, tentative de résolution via Sesame coo = aladin.view.getSimbad(node.getCutoutTarget()); if( coo!=null ) { alpha = coo.al; delta = coo.del; } } // pour un cutout, on doit verifier qu il existe a l endroit voulu String myCoord = Coord.getSexa(alpha,delta," "); if( alpha==-1 && delta==-1 ) { Aladin.warning("You have to give the center of the cutout",1); } else if( checkCutoutAvailability(node,alpha,delta,aladin) ) { aladin.treeView.creatAladinPlane(myCoord, node.curFormat, "STAND", label, null, null, node.name, node.epoch, myName); } else Aladin.warning("Image "+node.name+" "+NOIMAGE_WARNING,1); } else aladin.treeView.creatAladinPlane(Coord.getSexa(node.fov.alpha,node.fov.delta," "), node.curFormat, "STAND", label, null, null, node.name, node.epoch, myName); } // montre tous les champs des images contenues dans node protected void showAllLev(ResourceNode node) { recShowAllLev(node); aladin.calque.view.repaint(); } protected void recShowAllLev(ResourceNode node) { Enumeration e = node.getChildren(); ResourceNode n = (ResourceNode)node.getChildrenAt(0); if( !n.isLeaf ) { // appel recursif while( e.hasMoreElements() ) { showAllLev((ResourceNode)e.nextElement()); } } else { // traitement des fils while( e.hasMoreElements() ) { n = (ResourceNode)e.nextElement(); if( n.fov == null) return; if( !aladin.calque.Fovs.contains(n.fov) ) aladin.calque.Fovs.addElement(n.fov); } } } /** Loads all selected nodes */ void loadSelected() { Vector v = getSelectedLeaves(); Enumeration e = v.elements(); while(e.hasMoreElements()) { ResourceNode node = (ResourceNode)e.nextElement(); load(node); } } /** Get the number of resources that are checked and visible */ int nbSelected() { return getSelectedLeaves().size(); } /** Clears the tree */ void clear() { ResourceNode node = new ResourceNode(); node.hide = true; setRoot(node); } /** charge la ressource décrite par node */ // devrait être ramené au niveau du noeud ! protected void load(ResourceNode node) { if( !node.isLeaf ) return; if( node.type == ResourceNode.IMAGE ) { loadImage(node); } else if( node.type == ResourceNode.CAT ) { loadCat(node); } } /* private String getTarget() { return aladin.treeView.centerCutOut.getText().trim(); } */ // charge le catalogue decrit par le noeud private void loadCat(BasicNode node) { String target = ((ResourceNode)node).getCutoutTarget(); if( target.length()==0 ) { // certainement à changer car l'arbre donne une vue pour une région précise Aladin.warning("Please enter a target to load the catalogue",1); return; } aladin.treeView.creatCatPlane(node.name, target, node.name); } // cache tous les champs des images contenues dans node protected void hideAllLev(ResourceNode node) { recHideAllLev(node); aladin.calque.view.repaint(); } private void recHideAllLev(ResourceNode node) { //System.out.println(node.name); Enumeration e = node.getChildren(); if( e.hasMoreElements() ) { // si n n'est pas une feuille, aucun des fils n'est une feuille ResourceNode n = (ResourceNode)node.getChildrenAt(0); if( !n.isLeaf ) { // appel recursif while( e.hasMoreElements() ) { hideAllLev((ResourceNode)e.nextElement()); } } // sinon, tous les fils sont des feuilles else { int index; // traitement des fils while( e.hasMoreElements() ) { n = (ResourceNode)e.nextElement(); index = aladin.calque.Fovs.indexOf(n.fov); if( index>=0 ) aladin.calque.Fovs.removeElementAt(index); } } } } } vs(Resourcds/aladin/MyButton.java010064400076440000132000000271520770227416100162030ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Bouton Aladin java qui gere les entrees et les sorties * de la souris * * @@author Pierre Fernique [CDS] * @@version 2.0 : (janv 03) contourne bug JVM 1.4.0 + suppression double buffer * @@version 1.1 : (16 dec 99) corr bug hauteur des boutons * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class MyButton extends Canvas { // Les constantes static final int UP = 1; static final int DOWN = -1; static final int UNAVAIL = 0; static final int NORMAL = 0; static final int LEFT = 1; static final int RIGHT = 2; static final int TRI = 7; /** La phrase d'explication du bouton */ protected String baratin; /** Le nom du bouton */ protected String text; String help=null; // Le help associe au bouton // Les references Aladin aladin; Label status=null; // Les variables d'etats boolean alwaysUp=true; // Indique s'il s'agit d'un bouton toujours UP int mode=UP; // Etat UP, UNAVAIL, DOWN, du bouton int type = NORMAL; // si !=NORMAL, => fortement lie a Aladin // (baratin sera affiche dans aladin.status(), // type de bord LEFT ou RIGHT...) // Les composants du bouton int W = 70; // Largeur minimale static final int MARGE=10; // Marge int H = Aladin.LSIZE+MARGE; // Hauteur du bouton pour une ligne Font f=null; // Font du bouton /** Creation d'un bouton. * @@param aladin Reference * @@param s Le label du bouton */ protected MyButton(Aladin aladin,String s) { suite(aladin,s,null,null,true); } /** Creation d'un bouton. * @@param aladin Reference * @@param status Label dans lequel il faudra afficher le baratin d'explication * si le type est ``NORMAL'' * @@param type Type de bouton (si != NORMAL, affichage du status dans * aladin.status * @@param s Le label du bouton * @@param baratin L'explication associee au bouton */ protected MyButton(Aladin aladin,Label status,int type, String s, String baratin) { this.status = status; this.type = type; suite(aladin,s,baratin,null,true); } /** Creation d'un bouton. * @@param aladin Reference * @@param s Le label du bouton * @@param baratin L'explication (courte) associee au bouton * @@param help Le help associee au bouton */ protected MyButton(Aladin aladin,String s, String baratin, String help) { suite(aladin,s,baratin,help,true); } protected MyButton(Aladin aladin,String s, String baratin, String help,boolean enable) { suite(aladin,s,baratin,help,enable); } /** Generation d'un bouton (procedure interne) */ void suite(Aladin aladin,String s, String baratin, String help,boolean enable) { this.aladin = aladin; this.baratin = baratin; text=s; mode=enable?UP:UNAVAIL; if( help!=null ) this.help=help; setBackground( Aladin.BKGD ); f=Aladin.LBOLD; H=getH(); resize(W,H); } /** Changement de la font */ public void setFont(Font f) { this.f = f; FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(f); W = fm.stringWidth(text)+10; resize(W,H); } private int getH() { char [] a = text.toCharArray(); int n=1; for( int i=0; itrue, le bouton est toujours UP, flase sinon */ protected void setAlwaysUp(boolean a) { alwaysUp=a; } /** Rend ou non le bouton accessible * @@param a true, le bouton est active, flase sinon */ public void enable(boolean a) { int omode=mode; if( a ) mode=UP; else mode=UNAVAIL; if( omode!=mode ) repaint(); } /** Enfonce le bouton */ protected void push() { if( mode!=UNAVAIL) { mode=DOWN; repaint();} } /** Relache le bouton */ protected void pop() { if( mode!=UNAVAIL) { mode=UP; repaint();} } public boolean mouseDown(Event e, int x, int y) { if( mode==UNAVAIL ) return true; push(); if( pm!=null ) { pm.show(this,W-10,H/2+10); } return true; } public boolean mouseUp(Event e, int x, int y) { if( mode==UNAVAIL ) return true; if( alwaysUp ) pop(); postEvent(new Event(new Button(text),Event.ACTION_EVENT,text) ); return true; } PopupMenu pm=null; public synchronized void add(PopupMenu pm) { this.pm=pm; super.add(pm); } /** Reactions aux differents boutons du menu */ public boolean action(Event e, Object o) { String s; try { s = (String) o; } catch( Exception eact ) { return true; } // System.out.println("action o=["+s+"]"); return false; } public boolean mouseMove(Event e, int x, int y ) { return true; } static boolean flagShift=false; synchronized private void setFlagShift(boolean flag) { flagShift=flag; } /** Retourne true si la touche Key est pressee */ synchronized static boolean shiftDown() { return flagShift; } public boolean handleEvent(Event e) { // Memorisation de la touche Shift if( e.target instanceof MyButton ) setFlagShift( e.shiftDown()); if( e.id==Event.MOUSE_EXIT && alwaysUp && mode!=UNAVAIL ) pop(); if( baratin==null ) return super.handleEvent(e); /* // Pour le Help if( type==NORMAL && Aladin.inHelp ) { if( e.id==Event.MOUSE_ENTER ) { if( text.equals(Aladin.MHLP2) ) aladin.help.setDefault(); else aladin.help.setText(help); } return super.handleEvent(e); } */ if( type!=NORMAL ) { // Baratin sur les boutons dans les selecteur de serveurs if( e.id==Event.MOUSE_ENTER ) status.setText(baratin); else if( e.id==Event.MOUSE_EXIT ) status.setText(""); } else { // Baratin sur les boutons if( e.id==Event.MOUSE_ENTER ) aladin.status.setText(baratin); else if( e.id==Event.MOUSE_EXIT ) aladin.status.setText(""); } return super.handleEvent(e); } // Dessin du bouton void draw(Graphics g) { Color c = (mode!=UNAVAIL)?Color.black:Color.gray; // Dessin du fond g.setColor(Aladin.BKGD); g.fillRect(0,0,W,H); // Couleur du fond du bouton if( mode==DOWN ) { g.setColor(type!=NORMAL?Aladin.LGRAY:Color.gray); g.fillRect(2,2,W-4,H-4); } // Dessin des bords g.setColor( Color.black ); if( type!=NORMAL && mode==DOWN ) { g.drawRect(1,1,W-3,H-2); int x=(type==RIGHT)?0:W-2; int y=H/3 - TRI; g.setColor( Aladin.LGRAY ); g.fillRect(x,y,2,TRI*2); g.setColor( Color.black ); g.drawLine(x,y,x+2,y); g.drawLine(x,y+TRI*2,x+2,y+TRI*2); } else { g.setColor( (mode!=DOWN)?Color.white:Color.darkGray); g.drawLine(1,1,W-2,1); g.drawLine(1,1,1, H-2); g.setColor( mode!=DOWN?Color.darkGray:Color.white ); g.drawLine(W-2,1, W-2,H-2); g.drawLine(W-2,H-2,1, H-2); } } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { W = getSize().width; H = getSize().height; draw(g); // if( w!=W || h!=H ) { W=w; H=h; update(g); return; } // La fonte et la couleur if( mode==UNAVAIL ) { // g.setFont( new Font(f.getName(),Font.ITALIC,f.getSize()) ); g.setFont( f ); g.setColor(Color.gray); } else { g.setFont( f ); g.setColor(Color.black); } // Le texte FontMetrics m = g.getFontMetrics(); if( text!=null && !text.equals("") ) { StringTokenizer st = new StringTokenizer(text,"\n"); int nligne = st.countTokens(); int y = H/2 - (nligne*(Aladin.SIZE+4))/2 + Aladin.SIZE+2; for( int i=0; i0 ) type |= ASTRORES; // Detection de AJ (Aladin Java stack backup) else if( lookForSignature("0 ) type |= AJ; // Detection de VOTABLE else if( lookForSignature("0 ) { type |= VOTABLE; // Detection de IDHA if( lookForSignature("name=\"ObservingProgram\"",true)>0 ) type |= IDHA; // Detection de SIA else if( lookForSignature("0 ) type |= SIA; } } // Detection de TSV else if( isTSV() ) type |= TSV; // Detection de AJS (Aladin Java script) // REM: METHODE TRES PEU SURE else if( lookForSignature("get ",true)>0 ) type |= AJS; } catch ( EOFException e ) { //System.out.println("getType impossible: EOFException !!"); return NOTAVAILABLE; } return type; } /** * Interface InputStream, methode skip() * Attention le skip peut etre fait en plusieurs fois si le tampon * n'est pas vide * @@param n le nombre d'octets a skipper * @@return le nombre d'octets effectivement skippes */ public long skip(long n) throws IOException { //System.out.println("Call skip("+n+")"); if( inCache>0 ) { if( inCache>n ) n=(long)inCache; offsetCache=offsetCache+(int)n; inCache=inCache-(int)n; return n; } return super.skip(n); } /** * Interface InputStream, methode available() * @@return le nombre d'octets disponibles */ public int available() throws IOException { //System.out.println("Call available()"); if( inCache!=0 ) return inCache; return super.available(); } /** * Interface InputStream, methode markSupported() * @@return toujours false car MyInputStream ne supporte pas les marks */ public boolean markSupported() { //System.out.println("Call markSupported()"); return false; } private byte bufRead[] = new byte[1]; /** * Interface InputStream, methode read() * LA METHODE EST UN PEU BOEUF CAR JE PASSE PAR UN TABLEAU DE 1 OCTET. * POUR EVITER LES ALLOCATIONS JE METS CE TABLEAU EN INSTANCE DE CLASSE * @@return retourne le prochain octet disponible dans le flux sous la forme * d'un entier. */ public int read() throws IOException { byte buf[] = new byte[1]; int rep=read(bufRead,0,1); return rep==-1?-1:( ((int)bufRead[0]) &0xFF); } /** * Interface InputStream, methode read(byte buf[]) * Remplit au mieux le tableau passe en parametre. * @@param le buffer a remplir * @@param le nombre d'octets effectivement lus */ public int read(byte buf[]) throws IOException { return read(buf,0,buf.length); } /** * Interface InputStream, methode read(byte bbuf[],int offset,int len) * Remplit au mieux le tableau passe en parametre. * @@param le buffer a remplir * @@param offset position dans le buffer * @@param len nombre d'octets a lire au mieux * @@param le nombre d'octets effectivement lus */ public int read(byte buf[], int offset, int len) throws IOException { //System.out.println("Call read(buf,"+offset+","+len+") inCache="+inCache); // Pour garantir qu'un appel a getType() posterieur ne pourra plus etre // valide alreadyRead=true; // S'il n'y a rien dans le tampon, on lit simplement le flux if( cache==null || inCache==0 ) { //System.out.println("Try to read "+len+" bytes"); return super.read(buf,offset,len); } // Quelque chose dans le tamon, on retourne ce qui s'y // trouve, le client devra eventuellement refaire une lecture // pour avoir la suite if( inCache "+m+" octets"); System.arraycopy(tmp,0,tab,n,m); n+=m; } return tab; } /** * Retourne la prochaine ligne du stream * @@return la ligne lue, */ public String gets() throws IOException { int n; boolean flagEOF=false; try { n = findSignature("\n",false); } catch( EOFException eof ) { if( inCache==0 ) throw new EOFException(); n=offsetCache+inCache; } String s = new String(cache,offsetCache,n-offsetCache); inCache-=(n-offsetCache); offsetCache=n; return s; } /** * Affichage "en clair" du type de fichier en fonction du cahmp de bits * retourne par getType() * @@return une chaine decrivant le type de fichier */ static public String decodeType(int type) { StringBuffer s = new StringBuffer(); if( (type & FITS) == FITS ) s.append(" FITS"); if( (type & JPEG) == JPEG ) s.append(" JPEG"); if( (type & MRCOMP) == MRCOMP ) s.append(" MRCOMP"); if( (type & HCOMP) == HCOMP ) s.append(" HCOMP"); if( (type & GZ) == GZ ) s.append(" GZ"); if( (type & XML) == XML ) s.append(" XML"); if( (type & ASTRORES) == ASTRORES ) s.append(" ASTRORES"); if( (type & VOTABLE) == VOTABLE ) s.append(" VOTABLE"); if( (type & AJ) == AJ ) s.append(" AJ"); if( (type & AJS) == AJS ) s.append(" AJS"); if( (type & IDHA) == IDHA ) s.append(" IDHA"); if( (type & SIA) == SIA ) s.append(" SIA"); if( (type & TSV) == TSV ) s.append(" TSV"); if( (type & NOTAVAILABLE) == NOTAVAILABLE ) s.append(" NOTAVAILABLE"); if( s.length()==0 ) s.append("UNKNOWN"); return s.toString(); } /** * Charge "len" octets dans le tampon. * Le tampon s'agrandit automatiquement si nécessaire. Sort une EOFException * si on rencontre la fin du flux. * @@param len nombre de bytes a charger */ private void loadInCache(int len) throws IOException { // Premiere allocation du buffer du cache if( cache==null ) { //System.out.println("Initialisation du cache "+BLOCCACHE+" bytes"); cache = new byte[BLOCCACHE]; } // Extension eventuelle du cache (avec recopie des bytes // non encore lus). else { int freeCache = cache.length - (offsetCache+inCache); //System.out.println("freeCache="+freeCache+" pour="+len+" bytes"); if( len>freeCache ) { int nByte = (((inCache+len)/BLOCCACHE)+1)*BLOCCACHE; byte newCache[] = new byte[nByte]; System.arraycopy(cache,offsetCache,newCache,0,inCache); offsetCache=0; cache=newCache; //System.out.println("modif cache: size="+nByte+" offsetCache="+offsetCache+" inCache="+inCache); } } // Chargement dans le cache de len bytes int m; int offset=offsetCache+inCache; for( int n=0; n Data fits offset "+dataFits); // On remplit le cache jusqu'au deux premiers bytes // des donnees FITS pour preparer un eventuel test // du MGIC NUMBER de HCOMP if( inCache'A' && x<'Z' ) System.out.print(x); // else System.out.print(" "+(((int)cache[i])&0xFF)); //} //System.out.println(); return dataFits; } else { offset=n; n=-1; } } }while(n<0); return n; } public static void main(String[] args) { try { for( int i=0; i"+decodeType(f.getType())); // byte buf[] = f.readFully(); // out.write(buf); f.close(); // out.close(); } } catch( IOException e ) { e.printStackTrace(); } } } e & XML) == XML ) s.append(" XML"); if( (type & ASTRORES) == ASTRORES ) s.append(" ASTRORES"); if( (type & VOTABLE) == VOTABLE ) s.append(" VOTABLE"); if( (type & AJ) == AJ ) s.append(" AJ"); if( (type & AJS) == AJS ) s.append(" AJS"); if( (type & IDHA) == IDHA ) s.append(" IDHA"); if( (type & SIA) == SIA ) s.appencds/aladin/MyFrame.java010064400076440000132000000107240770227416100157570ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion d'un Frame avec reception de l'evenement * de destruction * * @@author Pierre Fernique [CDS] * @@version 1.1 : 3 juin 99 Gestion du flagNormal pour ``disposer'' * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class MyFrame extends Frame { Aladin aladin=null; static boolean flagNormal=false; /** Creation du Frame. * @@param aladin Reference * @@param title Titre du Frame */ protected MyFrame(Aladin aladin,String title) { this(title,false); this.aladin=aladin; } /** Creation du Frame. * @@param title Titre du Frame */ protected MyFrame(String title) { this(title,false); } /** Creation du Frame. * @@param title Titre du Frame * @@param flagNormal Frame courante (dispose()) */ protected MyFrame(String title,boolean flagNormal) { super(title); this.flagNormal = flagNormal; setBackground(Aladin.BKGD); } /** Positionnement de l'icone */ protected void setIcone(Image img) { setIconImage(img); } public boolean handleEvent(Event e) { if( e.id == Event.WINDOW_DESTROY ) { if( flagNormal ) dispose(); else { if( Aladin.STANDALONE || Aladin.extApplet!=null ) { if(aladin.flagLaunch) { System.out.println("MyFrame.handleEvent: flagLaunch true => dispose"); dispose(); } else System.exit(0); } else aladin.unDetach(); } } return super.handleEvent(e); } } cds/aladin/MyLabel.java010064400076440000132000000155720770227416100157520ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Un Label sur mesure pour Aladin. * * @@author Pierre Fernique [CDS] * @@version 1.1 : (20 mars 01) Rupture des lignes > 60 caracteres * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class MyLabel extends Panel { static final int MARGE=10; Vector line=null; // Le texte a afficher (par ligne) Font font; // Font associee FontMetrics fm; // La metrique de la font courante int mode; // mode d'alignement Label.CENTER,... String text; /** Creation d'un label multi-lignes VIDE. */ protected MyLabel() { super(); } /** Creation d'un label multi-lignes AVEC les options par defaut. * @@param text Le texte du label */ protected MyLabel(String text) { this(text,Label.CENTER,Aladin.PLAIN); } /** Creation d'un label multi-lignes AVEC la fonte par defaut. * @@param text Le texte du label * @@param mode Label.CENTER, Label.RIGHT ou Label.LEFT */ protected MyLabel(String text,int mode) { this(text,mode,Aladin.PLAIN); } /** Creation d'un label multi-lignes. * @@param text Le texte du label * @@param mode Label.CENTER, Label.RIGHT ou Label.LEFT * @@param font la font a utiliser */ protected MyLabel(String text,int mode,Font font) { this.mode = mode; this.font=font; setFont(font); fm = Toolkit.getDefaultToolkit().getFontMetrics(font); setText(text); } /** Recuperation du texte */ public String getText() { return text; } /** Modification du texte du Label. * @@param text Le nouveau texte du label */ public void setText(String text) { String s; StringTokenizer st = new StringTokenizer(text,"\n"); int w,max=0; this.text=text; line = new Vector(10); while( st.hasMoreTokens() ) { s = st.nextToken(); StringTokenizer st1 = new StringTokenizer(s," ",true); StringBuffer s1=new StringBuffer(); while( st1.hasMoreTokens() ) { s1.append(st1.nextToken()); if( s1.length()>80 ) { line.addElement(s1.toString()); w = fm.stringWidth(s1.toString()); if( max0 ) { line.addElement(s1.toString()); w = fm.stringWidth(s1.toString()); if( max=size().height)?size().height-H-1:Y; Enumeration e = menu.elements(); int max=0; while( e.hasMoreElements() ) { String s = (String)e.nextElement(); int l = m.stringWidth(s); if( max=menu.size() ) i=menu.size()-1; return i; } /** Gestion de la souris */ public boolean mouseMove(Event e, int x, int y) { int ochoix=choix; int i = getItem(y); if( ochoix!=i ) { choix=i; repaint(); } return true; } /** Gestion de la souris */ public boolean mouseUp(Event e, int x, int y) { int i = getItem(y); String text = (String)menu.elementAt(i); postEvent(new Event(new Button(text),Event.ACTION_EVENT,text) ); return true; } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { if( !flagOk ) adjust(); Enumeration e = menu.elements(); int yc=y+MARGE; for( int i=0; e.hasMoreElements(); i++ ) { String s = (String)e.nextElement(); g.setColor(Color.black); g.drawString(s,x+MARGE,yc+Aladin.SIZE); g.setColor(i==choix?Color.white:backGround); g.drawLine(x+1,yc+Aladin.SIZE+2,x+1,yc-2); g.drawLine(x+1,yc-2,x+W-1,yc-2); g.setColor(i==choix?Color.black:backGround); g.drawLine(x+W-1,yc-2,x+W-1,yc+Aladin.SIZE+2); g.drawLine(x+W-1,yc+Aladin.SIZE+2,x+1,yc+Aladin.SIZE+2); yc+=Aladin.SIZE+GAP; } g.setColor(Color.white); g.drawLine(x,y+H,x,y); g.drawLine(x,y,x+W,y); g.setColor(Color.black); g.drawLine(x+W,y,x+W,y+H); g.drawLine(x+W,y+H,x,y+H); } } cds/aladin/MyScrollbar.java010064400076440000132000000077110770227416100166520ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Un Scrollbar de largeur raisonnable * * @@author Pierre Fernique [CDS] * @@version 1.0 : (4 mars 2002) Creation */ public final class MyScrollbar extends Scrollbar { final static int LARGEUR=12; private int largeur=LARGEUR; MyScrollbar(int orientation,int value,int visible,int min,int max) { super(orientation,value,visible,min,max); } MyScrollbar(int orientation) { super(orientation); } /** Positionnement de la largeur de la scrollbar * @@param largeur La nouvelle largeur */ protected void setWidth(int largeur) { this.largeur = largeur; } public Dimension preferredSize() { return xsize(); } public Dimension getPreferredSize() { return xsize(); } public Dimension minimumSize() { return xsize(); } public Dimension getMinimumSize() { return xsize(); } private Dimension xsize() { if( getOrientation()==HORIZONTAL ) return new Dimension(size().width,largeur); else return new Dimension(largeur,size().height); } } cds/aladin/NEDServer.java010064400076440000132000000075170770227416100162220ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Le formulaire d'interrogation de NED * * @@author Pierre Fernique [CDS] * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class NEDServer extends SimbadServer { // static final String NOM = "NED\n"+MyButton.LOGOCAT; static final String NOM = "NED"; static final String INFO = "NASA/IPAC Extragalactic Database (Caltech/Pasadena)"; static final String TAGGLU = "NedXML"; static final String TITRE = "NED: NASA/IPAC Extragalactic Database"; /** Initialisation des variables propres a NED */ protected void init() { type = DATA; nom = NOM; info = INFO; titre = TITRE; tagGlu = TAGGLU; } /** Creation du formulaire d'interrogation de NED. * @@param aladin reference * @@param status le label qui affichera l'etat courant */ NEDServer(Aladin aladin,Label status) { super(aladin,status); } } cds/aladin/NotePad.java010064400076440000132000000112700770227416100157460ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.util.*; /** * Gestion de la fenetre du Bloc-note * * @@author Pierre Fernique [CDS] * @@version 1.0 : 4 juin 99 Creation */ public final class NotePad extends Frame { static final String CLOSE = "Close"; static final String RESET = "Reset"; // Les references aux objets Aladin aladin; // Les composantes de l'objet MyFrame bn; // Le bloc-note TextArea ta; // La zone de texte du blocnote /** Creation. * @@param aladin Reference * @@param text Le vecteur contenant chaque ligne de mesures * @@param scrollbar La reference a la barre de defilement */ protected NotePad(Aladin aladin) { super("AladinJava note pad"); setBackground(Aladin.BKGD); this.aladin = aladin; ta = new TextArea(10,80); setLayout( new BorderLayout(5,5)); Aladin.makeAdd(this, new MyLabel("- Pad: just to memorize or cut-and-paste some informations -",Label.CENTER),"North"); Aladin.makeAdd(this,ta,"Center"); // Les boutons de commandes Panel p = new Panel(); p.add( new Button(CLOSE)); p.add( new Button(RESET)); Aladin.makeAdd(this,p,"South"); if( !Aladin.LSCREEN ) move(400,300); else move(400,700); pack(); } /** Ajout d'un texte * @@param s Le texte a ajouter */ protected void setText(String s) { ta.appendText(s); } /** Nettoyage du bloc note */ protected void reset() { ta.setText(""); } // Gestion des evenement public boolean action(Event evt, Object what) { if( CLOSE.equals(what) ) hide(); else if( RESET.equals(what) ) reset(); return true; } // Gestion des evenement public boolean handleEvent(Event e) { if( e.id==Event.WINDOW_DESTROY ) hide(); return super.handleEvent(e); } } cds/aladin/Objet.java010064400076440000132000000103160770227416100154570ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Interface pour la manipulation d'un objet graphique affichable dans la vue * * @@author Pierre Fernique [CDS] * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public abstract class Objet { // Les constantes associees a "methode" lors de la creation protected static final int XY = 1; protected static final int RADE = 2; protected static final int RADE_COMPUTE = 4; protected static final int XY_COMPUTE = 8; protected abstract void setPosition(double x, double y); protected abstract void deltaPosition(double x, double y); protected abstract void setText(String id); protected abstract Point getViewCoord(ZoomView zoomview,int dw, int dh); protected abstract boolean inside(double x, double y, double z); protected abstract boolean in(double x, double y,double z); protected abstract Rectangle getClip(ZoomView zoomview); protected abstract void draw(Graphics g,ZoomView zoomview,int dx,int dy); abstract void drawSelect(Graphics g,ZoomView zoomview); abstract void info(Aladin aladin); protected abstract void status(Aladin aladin); protected abstract void setSelect(boolean flag); protected abstract void switchSelect(); protected abstract boolean isSelect(); protected abstract Plan getPlan(); // abstract void debug(); } cds/aladin/Plan.java010064400076440000132000000355370770227416100153220ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Interface de gestion des plans * * @@author Pierre Fernique [CDS] * @@version 1.1 : (28 mars 00) ReToilettage du code * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.91 : Revisite le 23 nov 98 * @@version 0.9 : (??) creation */ public abstract class Plan implements Runnable { static final String NOREDUCTION="No astronomical reduction"; // Les valeurs decrivant les differents types de plan static final int NO = 0; // Le plan est vide static final int IMAGE = 1; // Le plan contient une image raster static final int CATALOG = 2; // Le plan contient des sources issues d'un serveur de donnees static final int TOOL = 3; // Le plan contient des surcharges graphiques static final int FIELD = 4; // Le plan contient des champs de vue (CCD...) static final int FOLDER = 5; // Le plan est en fait un Folder static final int FILTER = 6; // Le plan contient un filtre static String [] Tp = { "","Image","Catalog","Tool","FoV","Scale","Folder","Filter" }; /** Type de plan: NO, IMAGE, CATALOG, TOOL, FIELD,... */ protected int type; protected int folder; // niveau du folder, 0 si aucun protected boolean collapse; // true si le plan est collapse dans la pile /** Target du plan (celui qui a ete indique a l'interrogation) */ protected String objet; /** Label du plan; (celui qui apparait dans le "plane stack" */ protected String label; /** Les parametres d'interrogation du serveur */ protected String param; /** Les coordonnees J2000 du target de l'interrogation * ou null si non encore calcule */ protected Coord co; protected Thread sr; // Thread pour la resolution Simbad */ /** La couleur associee au plan */ protected Color c; /** La projection PAR DEFAUT associee au plan */ protected Projection projd; protected Hashtable projD = null; /** L'origine du plan */ protected String from; /** pour les filtres */ boolean[] influence = new boolean[PlanFilter.LIMIT]; // tableau d'influence des filtres // Les parametres qui decrivent l'etat du plan boolean flagOk; // Vrai si le plan est disponible boolean active; // vrai si le plan est actif (non transparent) boolean selected; // vrai si le plan est selectionne boolean ref; // vrai si c'est le plan de reference pour la projection courante Projection proj; // La projection COURANTE associee au plan boolean flagProj; // Vrai si le plan est projete (avec positions memorisees) String error; // La chaine d'erreur en cas de probleme boolean flagLocal; // Le plan est issu d'un fichier local protected boolean xyLock; // true si dans le cas d'un plan objet on bloque les xy // La memorisation du dernier zoom associe au plan int xzoom,yzoom; // Dernier centre du zoom (repere zoom) int zoom=-1; // Dernier index du zoom, (-1 si aucune memo) // Les composantes dependantes du type de plan (on les garde a ce niveau // pour eviter les castings intempestifs) PlanObjet pcat; // Les objets du plan si CATALOG ou TOOL ou FIELD // Les variables et objets de travail Thread runme; // Pour charger les images et les plans en asynchrone URL u; // L'URL qui va nous servir pour la prochaine requete // Les references aux autres objets Aladin aladin; // Reference a l'objet Aladin /** Positionnement d'un facteur de zoom particulier. * Utilise par exemple pour le parametre "-aladin.zoom" * @@param sZoom libelle du zoom (a recherche dans le menu deroulant) * @@return true si ok false sinon */ protected boolean setZoom(String sZoom) { //System.out.println("Positionnement d'un facteur de zoom : ["+sZoom+"]"); int i = aladin.calque.zoom.getIndex(sZoom.trim()); if( i==-1 ) return false; zoom = i; xzoom = yzoom = aladin.calque.zoom.zoomView.SIZE/2; return true; } /** Test d'equivalence de plan. * Retourne vrai si les parametres decrivent le meme plan * @@param type Le typ du plan * @@param objet l'objet ou les coordonnees au centre * @@param param les parametres de description du plan (ex: SERC J MAMA) * @@param other dependant du type de plan, sinon null * pour IMAGE: concatenation "code_fmt/code_resol" * @@return true si ok, false sinon. */ protected boolean theSame(int type,String objet,String param) { return theSame(type,objet,param,null); } protected boolean theSame(int type,String objet,String param,String other) { if( type!=this.type ) return false; if( objet!=null && this.objet!=null && !this.objet.equals(objet) ) return false; if( param!=null && this.param!=null && !param.equals(this.param) ) return false; if( other!=null ) { String s="";; switch(type) { case IMAGE: PlanImage p=(PlanImage)this; s=p.fmt+"/"+p.res; break; } if( !other.equals(s) ) return false; } return true; } /** Test d'equivalence de plan. * Retourne vrai si il s'agit du meme plan dans le meme etat * @@param p le plan a comparer avec le plan courant * @@return true si ok, false sinon. */ protected boolean equals(Plan p ) { // Meme plan ? if( !theSame(p.type,p.objet,p.param) ) return false; // Resolution et format identique pour les plans images ? if( this instanceof PlanImage && p instanceof PlanImage ) { if( !PlanImage.sameFmtRes(this,p) ) return false; } // Meme etat ? if( (error==null && p.error!=null) || (error!=null && p.error==null) ) return false; if( error!=null && p.error!=null &&!error.equals(p.error) ) return false; if( flagOk!=p.flagOk ) return false; if( projd!=p.projd ) return false; return true; } double pourcent; // Pourcentage du chargement de l'image /** * Retourne le pourcentage charge de l'image chargee * -1 si non encore en chargement * 0 si en preambule de chargement * 100 si totalement chargee */ protected double getPourcent() { return pourcent; } /** Libere le plan. * cad met toutes ses variables a null ou a false */ protected void Free() { type = NO; objet=error=label=param=null; co=null; proj=projd = null; projD=null; if( sr!=null ) sr.stop(); sr=null; pcat = null; collapse=flagOk=selected=active=ref=flagProj=xyLock = false; folder=zoom=0; System.gc(); } /** Memorisation d'une nouvelle projection possible pour le plan * qui devient la projection par defaut (projd) * Rq: mise a jour de projD * @@param name le nom de la projection (il doit etre unique pour le plan * @@param p la nouvelle projection */ protected void setNewProjD(Projection p) { if( projD==null ) projD = new Hashtable(); projD.put(p.label,p); projd=p; // Suppression du message NOREDUCTION si necessaire if( error!=null && error.equals(NOREDUCTION) ) error=null; } /** Determination de tous les plans de reference possibles pour le plan * @@return le tableau des plans de reference possibles */ protected Plan [] getAvailablePlanRef() { Vector v = new Vector(); if( type==IMAGE ) v.addElement(this); else { for( int i=0;itrue si ok, false sinon. */ protected boolean isViewable() { if( type==NO ) return false; if( type==TOOL || type==FILTER || (xyLock && error!=null) ) return true; // Recherche du plan de reference Plan pref = aladin.calque.getPlanRef(); // Test sur le centre des champs if( pref!=null && pref.projd!=null && !pref.projd.agree(projd,aladin.calque.zoom.getValue()) ) { return false; } // Si aucune reduction if( pref!=null && pref!=this && (projd==null || pref.projd==null) ) return false; return true; } /** Affiche la ligne d'informations concernant le plan dans le statut d'Aladin*/ protected void getInfo() { aladin.status.setText(""); } /** Generation du label du plan. * Retourne le label en fonction de l'etat courant du plan * Il s'agit simplement d'ajouter des "..." quand le plan est en * cours de construction * @@return Le label genere */ protected String getLabel() { if( error==null && !flagOk ) return label+"..."; return label; } /** Enregistrement du label du plan (ce qui apparaitra a cote du logo * du plan). * Change tous les \n en ' ' * @@param label Le label a memoriser */ protected void setLabel(String label) { char [] a = label.toCharArray(); for( int i=0; itrue si ok, false sinon. * @@see aladin.PlanImage#waitForPlan() * @@see aladin.PlanCatalog#waitForPlan() */ protected boolean waitForPlan() { return false; } /** Lance le chargement du plan */ public void run() { Aladin.trace(1,"Creating the "+Tp[type]+" plane "+label); planReady( waitForPlan() ); } /** Positionne le flag ``ready'' du plan. * En fonction de la valeur du flag "ready" positionne les * parametres de l'etat courant du plan et demande les * re-affichages necessaires * @@param ready l'etat a positionner */ protected void planReady(boolean ready) { if( !ready ) { error = aladin.error; aladin.calque.select.repaint(); aladin.toolbox.toolMode(); return; } if( !isViewable() || type==IMAGE ) aladin.calque.setPlanRef(this); active = true; if( aladin.calque.noSelected() ) selected=true; pourcent=-1; flagOk = true; // Ajout thomas : on avertit qu'un nouveau plan a ete cree pour mettre a jour les filtres // et pour mettre a jour filterProperties if( type==CATALOG ) { PlanFilter.newPlan(this); if( aladin.filterProperties!=null ) aladin.filterProperties.notifyNewPlan(); } if( aladin.dialog!=null ) aladin.dialog.setGrab(); // Activation du GrabIt aladin.calque.repaint(); } } tableau d'influence des filtres // Les parametres qui decrivent l'etat du plan boolean flagOk; // Vrai si le plan est disponible booleacds/aladin/PlanCatalog.java010064400076440000132000000176710770227416100166140ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Plan dedie a un catalogue (CATALOG) * * @@author Pierre Fernique [CDS] * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class PlanCatalog extends Plan { // DataInputStream dis; // Le flux de donnees URL url = null; MyInputStream in=null; // Le flux de donnees si on utilise un chargement par InputStream protected boolean flagXY=false; // true s'il s'agit d'un plan catalogue // dont on a que les positions en XY protected PointD xy[]; // Liste des positions XY originales // dans le cas d'un plan XY /** Creation d'un plan de type CATALOG (via une fichier) * @@param file Le nom du fichier */ protected PlanCatalog(Aladin aladin, String file, MyInputStream in) { this.in=in; try { url = new URL("file:"+(new File(file)).getCanonicalPath()); } catch( Exception e ) { String s =file+" not found"; Aladin.warning(s,1); return; } int i = file.lastIndexOf(System.getProperty("file.separator")); String name=(i>=0)?file.substring(i+1):file; // Nom du fichier flagLocal=true; Suite(aladin,name,"",""); } /** Creation d'un plan de type CATALOG (via un InputStream) * @@param in InputStream */ protected PlanCatalog(Aladin aladin, MyInputStream in) { this.in = in; String name="Ext.Appl"; // IL FAUDRAIRE L'EXTRAIRE AUTOMATIQUEMENT DU INPUTSTREAM Suite(aladin,name,"",""); } /** Creation d'un plan de type CATALOG (sans info) */ protected PlanCatalog(Aladin aladin) { this.aladin = aladin; type = CATALOG; c = Couleur.getNextDefault(aladin.calque); pcat = new PlanObjet(this,c,aladin.calque,aladin.status,aladin); flagOk=true; } /** Creation d'un plan de type CATALOG via une URL * @@param aladin reference * @@param u l'URL qu'il va falloir appeler * @@param label le nom du plan (dans la pile des plans) * @@param objet le target central (objet ou coord) * @@param param les parametres du plan (radius...) */ protected PlanCatalog(Aladin aladin, URL u, MyInputStream in, String label,String objet,String param) { this.in = in; this.u = u; flagLocal = false; Suite(aladin,label,objet,param); } /** Creation d'un plan de type CATALOG * @@param aladin reference * @@param label le nom du plan (dans la pile des plans) * @@param objet le target central (objet ou coord) * @@param param les parametres du plan (radius...) */ protected void Suite(Aladin aladin, String label,String objet,String param) { this.aladin= aladin; type = CATALOG; c = Couleur.getNextDefault(aladin.calque); setLabel(label); this.objet = objet; this.param = param; pcat = new PlanObjet(this,c,aladin.calque,aladin.status,aladin); aladin.calque.unSelectAllPlan(); selected = true; runme = new Thread(this); runme.setPriority( Thread.NORM_PRIORITY -1); runme.start(); } /** Libere le plan. * cad met toutes ses variables a null ou a false */ protected void Free() { super.Free(); xy=null; flagXY=false; } /** Attente pendant la construction du plan. * @@return true si ok, false sinon. */ protected boolean waitForPlan() { int n=0; // Chargement du catalogue, soit local, soit distant, soit par inputStream (VOTable seulement) //if( flagLocal ) n=pcat.setPlanCat(this,dis); if( in!=null ) n=pcat.setPlanCat(this,in); else if( flagLocal ) n=pcat.setPlanCat(this,url); else n=pcat.setPlanCat(this,u); if( n==0 ) aladin.error = error = "No object found in the field!"; else if( n<=0 ) { return false; } else { // En cas de chargement par un fichier local if( (objet==null || objet.length()==0) && co!=null) { objet = co.getSexa(); Server.setDefaultTarget(objet); } } if( aladin.msgOn ) aladin.endMsg(); // aladin.message.hideWait(); return true; } /** Affiche la ligne d'informations concernant le plan dans le statut d'Aladin*/ protected void getInfo() { String s; if( type==NO ) { super.getInfo(); return; } s = "``"+label+"'' - around "+objet; if( error!=null ) s = s+" Pb:"+error; else s = s + " - " + pcat.nb_o + " element(s)"; if( !flagOk && error==null ) s = s+" - in progress..."; aladin.status.setText(s); } /** Specification de la forme des objet. * Permet le changement du type de representation de toutes les sources * du plan * @@param sourceType type de representation (Source.CARRE...) * @@see aladin.Source */ protected void setSourceType(int sourceType) { int i=0; try { for( i=0; itrue si ok, false sinon. */ protected boolean waitForPlan() { try { pourcent = -1; // il s'agit juste d'un ajustement de niveau if (mustAdjustContour) { for (int i=0;i0?zoomv.x:0; zoomv.y = zoomv.y>0?zoomv.y:0; zoomv.width = zoomv.width>orgWidth?orgWidth:zoomv.width; zoomv.height = zoomv.height>orgHeight?orgHeight:zoomv.height; if( (zoomv.x+zoomv.width)>orgWidth) zoomv.width = orgWidth - zoomv.x; if( (zoomv.y+zoomv.height)>orgHeight) zoomv.height = orgHeight - zoomv.y; try { // data : tableau des pixels short[] data = new short[((PlanImage)p).pixels.length]; for (int i=data.length-1;i>=0;i--) { data[i] = (short)(((PlanImage)p).pixels[i]<0 ? 256 + ((PlanImage)p).pixels[i] : ((PlanImage)p).pixels[i]); } // remplissage du tableau pixels if (useOnlyCurrentZoom) { width = zoomv.width; height = zoomv.height; // useOnlyCurrentZoom et lissage activé if (useSmoothing) { // chaque dimension est divisee par smoothingLevel this.width = width/smoothingLevel; this.height = height/smoothingLevel; this.pixels = new short[width*height]; makeSmoothing(data,pixels,width,height,orgWidth,orgHeight,zoomv.x,zoomv.y,smoothingLevel); } // useOnlyCurrentZoom sans lissage else { pixels = new short[width*height]; for (int y=height-1;y>=0;y--) { for (int x=width-1;x>=0;x--) { pixels[y*width+x] = data[y*orgWidth+x+zoomv.x+orgWidth*zoomv.y]; } } } } // traitement a effectuer sur toute l'image else { width = orgWidth; height = orgHeight; // lissage sur toute l'image if(useSmoothing) { // chaque dimension est divisee par smoothingLevel this.width = width/smoothingLevel; this.height = height/smoothingLevel; this.pixels = new short[width*height]; makeSmoothing(data,pixels,width,height,orgWidth,orgHeight,0,0,smoothingLevel); } // pas de lissage a faire, on recupere l'image en entier else { pixels = new short[width*height]; pixels = data; } } if(reduceNoise) { pixels = moyenne(pixels,width,height); width=width-1; height=height-1; } } // fin du try catch( OutOfMemoryError e ) {aladin.error = e.toString();System.gc();System.runFinalization();return false;} catch( Exception exc ) {aladin.error = exc.toString(); return false;} return true; } /** fixe les niveaux a calculer */ protected void setlevels(double[] value) { this.levels = value; this.orgLevels = (double[])levels.clone(); } /* calcule tous les contours pour les valeurs de levels */ protected boolean getAllContours() { // initialisation du tableau contours contours = new PointD[levels.length][]; //System.out.println("02"); //System.out.println("03"); if (!getPixels()) { //System.out.println("Pas assez de memoire pour les contours"); return false; } //System.out.println("04"); // setmax et setmin ne servent a rien pour l'instant //setmax(); //setmin(); adjustLevels(); //System.out.println("05"); // on transmet a l'algorithme le tableau de pixels et la taille de l'image cAlgo.setData(pixels); cAlgo.setDimension(width,height); //System.out.println("06"); try { // boucle sur l'ensemble des niveaux for (int indiceLevel = 0; indiceLevel0 ) return label.substring(0,6)+".. "+p+"%"; return super.getLabel(); } /** getNextColor * @@param calque - calque reference * @@return la prochaine couleur libre */ protected static Color getNextColor(Calque calque) { int i,j; for( j=0;jmax) max=pixels[i]; } this.max = max; }*/ /** fixe la valeur de min */ /*private void setmin() { int min = 256; for (int i=0;i=0;y--) { a=y*width; for(x=width-1;x>=0;x--) { if((a+x)%4000==0) { if(aladin.isSlow) { try { Thread.currentThread().sleep(10); } catch(Exception e) { } } } b=smoothLevel*y*orgWidth + smoothLevel*x + decalX + decalY*orgWidth; // calcul des elts de pos et de p for(i=smoothLevel-1;i>=0;i--) { pos[i] = b+i; p[i] = data[pos[i]]; for(j=smoothLevel-1;j>=1;j--) { int factor = j*smoothLevel; pos[i+factor] = pos[i]+j*orgWidth; p[i+factor] = data[pos[i+factor]]; } } // calcul de la somme somme=0; for(i=nbPixels-1;i>=0;i--) somme+=p[i]; pix[a+x] = (short)somme; } }//System.out.println("fin smoothing"); } /** effectue la moyenne glissee */ private short[] moyenne(short pix[],int width, int height) { //System.out.println("debut reduce noise"); int i,j,a; short[] result = new short[(width-1)*(height-1)]; short p1,p2,p3,p4; for(j=height-2;j>=0;j--) { a=j*width; for(i=width-2;i>=0;i--) { if(aladin.isSlow) { if((a+i)%4000 == 0) { try { Thread.currentThread().sleep(10); } catch(Exception e) { } } } p1 = pix[a+i]; p2 = pix[a+i+1]; p3 = pix[a+i+width]; p4 = pix[a+i+width+1]; result[j*(width-1)+i] = (short) ((p1+p2+p3+p4)/4); } } //System.out.println("fin reduce noise"); return result; } } lignej.withlabel = true; lignej.setText(lab); pcat.setObjet(lignej); LignesNiveauCourant[nbPoints] = lignej; nbPoints++; ligne0 = lignej; pointSave = pointj; } i=i+j; } Ligne[] tmp = new Ligne[nbPoints]; System.arraycopy(LignesNiveauCourant,0,tmp,0,nbPoints); Ligne[indLevel] = tmp; xShift = 0; yShift = 0; } /** drawAllContours * dessine tous lescds/aladin/PlanField.java010064400076440000132000000642370770227416100162650ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.astro.*; /** * Plan dedie a des champs de vue (FOV) * * @@author Pierre Fernique [CDS] * @@version 1.2 : (24 mai 2002) methode reset() pour la reprojection apres translation * @@version 1.1 : (7 dec 00) toilettage du code + ajout d'un gap pour CFH12K * @@version 1.0 : (14 sept 00) creation */ public final class PlanField extends Plan { // les differents types d'instruments supportes private static final int CFH12K = 0; private static final int EPICMOS = 1; private static final int EPICPN = 2; private static final int WFPC2 = 3; private static final int MEGACAM = 4; private static final int MEGAPRIME = 5; private static final int ACS = 6; private static String [] INSTR= { "CFH12K", "EPICMOS", "EPICpn","WFPC2", "MEGACAM", "MEGAPRIME","ACS" }; // Les informations a memoriser private int instr; // Type d'instrument (CFH12K, EPICMOS... private boolean flagRoll; // True si l'instrument peut etre pivotable (roll actif) private double roll; // Valeur du roll courant // Les informations propres a chaque instrument lorsqu'ils sont simplement // constitues d'un tableau de rectangles // XXX_RA : largeur d'un rectangle (en degres) // XXX_DE : hauteur d'un rectangle (en degres) // XXX_DRA : facteur multiplicatif a operer en RA pour chaque rectangle // XXX_DDE : facteur multiplicatif a operer en DE pour chaque rectangle // XXX_GAPRA : gap en RA pour chaque rectangle (en secondes) // XXX_GAPDE : gap en DE pour chaque rectangle (en secondes) // XXX_RD : si different de 0, rayon d'un cercle centre indiquant le champ de vue (en degres) // XXX_ORA : offset en RA centre instrument - centre du champ // XXX_ODE : offset en DE centre instrument - centre du champ private static final double ACS_RA = 202.*(202./333.)/3600.; private static final double ACS_DE = ACS_RA/2.; private static final double ACS_DRA[] = { -0.5-258./202., -0.5-258./202. }; private static final double ACS_DDE[] = { -1.-272./202., -2.-272./202. }; private static final double ACS_RD = 0.; private static final double EPICMOS_RA = 10.9/60.0; private static final double EPICMOS_DE = 10.9/60.0; private static final double EPICMOS_DRA[] = { -1.5,-1.5,-0.5,-0.5,-0.5, 0.5,0.5 }; private static final double EPICMOS_DDE[] = { -1.0, 0.0,-1.5,-0.5, 0.5,-1.0,0.0 }; private static final double EPICMOS_RD = 15./60.; private static final double EPICPN_RA = 4.4/60.0; private static final double EPICPN_DE = 13.6/60.0; private static final double EPICPN_DRA[] = {-3.,-2.,-1., 0., 1., 2., -3.,-2.,-1.,0.,1.,2.}; private static final double EPICPN_DDE[] = {-1.,-1.,-1.,-1.,-1.,-1., 0., 0., 0.,0.,0.,0.}; private static final double EPICPN_RD = 15./60.; // Taille des CCDs de la mosaique CFH12K private static final double CFH12K_RA = 2048*0.206/3600.; private static final double CFH12K_DE = 4096*0.206/3600.; private static final double CFH12K_DRA[] = { -3.,-2.,-1., 0., 1., 2., -3.,-2.,-1.,0.,1., 2.}; private static final double CFH12K_DDE[] = { -1.,-1.,-1.,-1.,-1.,-1., 0., 0., 0.,0.,0., 0.}; private static final double CFH12K_GAPRA[] = { -15.,-9.,-3., 3., 9.,15.,-15.,-9.,-3.,3, 9.,15.}; private static final double CFH12K_GAPDE[] = { -3.,-3.,-3.,-3.,-3.,-3., 3., 3., 3.,3.,3., 3.}; // rayon du cercle representant la frontiere des etoiles polluantes private static final double CFH12K_RD = 0.0; // 7.50/60.0; // 15 arcmins diameter // Offset du centre optique par rapport au centre de la mosaique CFH12K private static final double CFH12K_ORA = (-15.0/3600.0); // 15 arcsecs private static final double CFH12K_ODE = (30.0/3600.0); // 30 arcsecs // Nom des CCDs a afficher sur la mosaique CFH12K private static final String CFH12K_CCD[] = { "06","07","08","09","10","11", "00","01","02","03","04","05"}; // Taille des CCDs de la mosaique MEGACAM: 2048 x 4612 private static final double MEGACAM_RA = 2048*0.187/3600.; private static final double MEGACAM_DE = 4612*0.187/3600.; // Position des CCDs de la mosaique MEGACAM /* Mosaique avec les "oreilles" - non utilise private static final double MEGACAM_DRA[] = { -4.5,-3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5, -5.5,-4.5,-3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5,4.5, -5.5,-4.5,-3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5,4.5, -4.5,-3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5, }; */ // Mosaique sans les "oreilles" private static final double MEGACAM_DRA[] = { -4.5,-3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5, -4.5,-3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5, -4.5,-3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5, -4.5,-3.5,-2.5,-1.5,-0.5,0.5,1.5,2.5,3.5, }; /* Mosaique avec les "oreilles" - non utilise private static final double MEGACAM_DDE[] = { -2,-2,-2,-2,-2,-2,-2,-2,-2, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; }; */ // Mosaique sans les "oreilles" private static final double MEGACAM_DDE[] = { -2,-2,-2,-2,-2,-2,-2,-2,-2, -1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; // Gaps (additifs) entre les CCDs de la mosaique MEGACAM /* Mosaique avec les "oreilles" - non utilise private static final double MEGACAM_GAPRA[] = { -56,-42,-28,-14,0,14,28,42,56, -70,-56,-42,-28,-14,0,14,28,42,56,70, -70,-56,-42,-28,-14,0,14,28,42,56,70, -56,-42,-28,-14,0,14,28,42,56, }; */ // Mosaique sans les "oreilles" private static final double MEGACAM_GAPRA[] = { -56,-42,-28,-14,0,14,28,42,56, -56,-42,-28,-14,0,14,28,42,56, -56,-42,-28,-14,0,14,28,42,56, -56,-42,-28,-14,0,14,28,42,56, }; /* Mosaique avec les "oreilles" - non utilise private static final double MEGACAM_GAPDE[] = { -88.5,-88.5,-88.5,-88.5,-88.5,-88.5,-88.5,-88.5,-88.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 88.5, 88.5, 88.5, 88.5, 88.5, 88.5, 88.5, 88.5, 88.5, }; */ // Mosaique sans les "oreilles" private static final double MEGACAM_GAPDE[] = { -88.5,-88.5,-88.5,-88.5,-88.5,-88.5,-88.5,-88.5,-88.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 88.5, 88.5, 88.5, 88.5, 88.5, 88.5, 88.5, 88.5, 88.5, }; // rayon du cercle representant la frontiere des etoiles polluantes private static final double MEGACAM_RD = 0.5; // 30/60; // 1 degre diameter // Offset du centre optique par rapport au centre de la mosaique MEGACAM // Per CV,2003.01 (15as,15as) of NW corner of Amp 44, chip 22 private static final double MEGACAM_ORA = (15.0/3600.0); // 15 arcsecs private static final double MEGACAM_ODE = (-20.5/3600.0); // 15 arcsecs + 1/2gap=5.5 = 20.5 arcsecs // Nom des CCDs a afficher sur la mosaique MEGACAM: NB: Les 2 CCDs exterieurs W et E ne sont pas couvertes // par les filtres et sont donc en dernier /* Mosaique avec les "oreilles" - non utilise private static final String MEGACAM_CCD[] = { "35","34","33","32","31","30","29","28","27", "39","26","25","24","23","22","21","20","19","18","38", "37","17","16","15","14","13","12","11","10","09","36", "08","07","06","05","04","03","02","01","00", }; */ private static final String MEGACAM_CCD[] = { "35","34","33","32","31","30","29","28","27", "26","25","24","23","22","21","20","19","18", "17","16","15","14","13","12","11","10","09", "08","07","06","05","04","03","02","01","00", }; // MEGAPRIME = MEGACAM + MEGAGUI (zones de guidage). On definit la les zones de guidage... // Taille des zones de guidage private static final double MEGAGUI_RA = 1233.0/3600.0; // per BC,2002.01.08 90mm*13.7as/mm old:6144*0.187/3600.; private static final double MEGAGUI_DE = 890.5/3600.0; // per BC,2002.01.08 65mm*13.7as/mm old:2048*0.187/3600.; // Geometrie des zones de guidage private static final double MEGAGUI_DRA[] = {-0.5,-0.5 }; private static final double MEGAGUI_DDE[] = {-1,0}; // Gaps pour positionner les zones de guidage private static final double MEGAGUI_GAPRA[] = {0,0}; // per BC,2002.01.08, 127mm*13.7as private static final double MEGAGUI_GAPDE[] = {-1739.9,+1739.9}; // in arcsec // Nom des zones de guidage: S=South, N=North private static final String MEGAGUI_BOX[] = {"S","N"}; /** Tan() en degres */ public static final double tand(double x) { return Math.tan( x*(Math.PI/180.0) ); } /** Cos() en degres */ public static final double cosd(double x) { return Math.cos( x*(Math.PI/180.0) ); } /** Creation d'un plan de type FIELD"EPICMOS * @@param target Nom d'objet ou coord. * @@param roll Angle de rotation par rapport au nord * @@param label le nom du plan (dans la pile des plans) * @@param instrument Type de FoV (voir INST[]) */ protected PlanField(Aladin aladin, String target ,double roll, String label,String instrument) { this.aladin= aladin; type = FIELD; c = Couleur.getNextDefault(aladin.calque); setLabel(label); pcat = new PlanObjet(this,c,aladin.calque,aladin.status,aladin); aladin.calque.unSelectAllPlan(); selected = true; objet = null; // Positionnement du type d'instrument setInstr(instrument); // Determination du target. // S'il s'agit d'un nom d'objet, il va y avoir une demande // de resolution Simbad pour le plan lui-meme, (objet renseigne) // si le target n'est pas mentionne, on n'attendra la resolutoin // Simbad du prochain plan. if( target.length()==0 || View.notCoord(target) ) { active = false; flagOk=false; this.roll=roll; if( target.length()>0 ) objet=target; } else { Coord co; try { co = new Coord(target); } catch( Exception e ) { error = aladin.error="Unknown object"; return; } active = true; flagOk = true; setCenter(co.al,co.del,roll); } } /** Selection/deselection de tous les objets avec mise a jour * de la liste dans View * @@param mode true => selection, false => deselection */ private void selectAll(boolean mode) { for( int i=0; i1 ) p.debligne=(Ligne)pcat.o[i-1]; if( i<9 ) p.finligne=(Ligne)pcat.o[i+1]; } } void setCCD(double ra,double de, double roll, double RA,double DE, double DRA[],double DDE[],double GAPRA[],double GAPDE[],double rd) { int j=0; // indice d'insertion dans le tableau pcat.o[] int nb_o_more; // cochonnerie au staff CFH double pra,pde; // coordonnees utilisees pour dessiner le centre du champ switch(instr) { // offset a appliquer pour dessiner la mosaique ? case MEGAPRIME : case MEGACAM : case CFH12K : // The center of CFH12K/MEGACAM is offset from the pointing center, to get the CFH12K/MEGACAM center, apply offset double ora = instr==CFH12K?CFH12K_ORA:MEGACAM_ORA; double ode = instr==CFH12K?CFH12K_ODE:MEGACAM_ODE; //System.out.println(" setCCD - CFH12K: applying offset ora="+ora+" ode="+ode+"/COS(DEC)"); pra = ra; // Garde coordonnees de pointing pour dessiner le centre du champ pde = de; ra -= ora/cosd(de); // Applique l'offset pour dessiner le reste de la mosaique - ra en degres ici de -= ode; //System.out.println(" setCCD - CFH12K: ra="+ra+" dec="+de); // Reserve de la place pour plus d'objets sur le plan nb_o_more = DRA.length; break; default: // Pour les autres instruments le centre du FOV est confondue avec la direction du pointing pra = ra; pde = de; nb_o_more = 0; break; } // Allocation ou re-allocation suivant que pcat.o soit alloue ou non if( pcat.o!=null ) { Objet o[] = pcat.o; pcat.o = new Objet[ pcat.nb_o=(o.length + DRA.length*5+nb_o_more) ]; System.arraycopy(o,0,pcat.o,0,o.length); j=o.length; } else { pcat.o = new Objet[pcat.nb_o=(DRA.length*5+1+nb_o_more)]; j=1; // Positionnement ra,de du centre dans l'objet 0 if( rd>0. ) pcat.o[0] = new Champ(this,new Coord(pra,pde),rd); else pcat.o[0] = new Champ(this,new Coord(pra,pde)); } // calcul des x,y correspondants dans le plan tangent Proj3 a = new Proj3(Proj3.TAN,ra,de); double xc=a.getX(); double yc=a.getY(); double x,y; int tj= pcat.nb_o - nb_o_more; // counter for text objects = number of first new object double cosr=0.,sinr=0.; if( roll!=0. ) { cosr=Coo.cosd(roll); sinr=Coo.sind(roll); } for( int i=0; i0 ) p.debligne=(Ligne)pcat.o[j-1]; if( k<4 ) p.finligne=(Ligne)pcat.o[j+1]; } } } } bien ete positionne */ synchronized protected boolean setCenter(double ra,double de) { if( flagOk ) return false; // Inutile setCenter(ra,de,roll); active=true; aladin.calque.repaint(); return true; } // Positionnement de l'instrument adequat private void setInstr(String instrument) { cds/aladin/PlanFilter.java010064400076440000132000000662210770227416100164620ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.util.*; /** * Plan dedie a un filter (FILTER) * * @@author Pierre Fernique [CDS] - Thomas Boch [CDS] * @@version 1.0 : 29 octobre 2002 creation */ public final class PlanFilter extends Plan { private static final int INCREMENT = 20; protected static int LIMIT = INCREMENT; // Definition des filtres predefinies static final String[] PREDEFFILTERS = { // magnitude circles "# This filter draws for each source a circle \n# whose radius is proportional to the magnitude\n" + "{draw circle(-$[PHOT*])}", // ellipses "# This example shows how to draw \n# an ellipse associated with a source\n" + "{\n# draws the source itself\ndraw\n" + "# draws the ellipse ; \n# parameters are semi-major axis, semi-minor axis, and position angle\n" + "draw ellipse(0.5*$[EXTENSION_DIAM],0.5*$[EXTENSION_MIN],${DimPA})\n}", // magnitude cut "# Only sources with a magnitude \n# brighter than 16 are displayed\n" + "$[PHOT*]<16 {draw}\n", // display text "# This filter draws for each source the content\n" + "# of the column tagged by the UCD \"CLASS_OBJECT\"\n" + "{\ndraw $[CLASS_OBJECT]\n}", // parameterized colors "# In this filter, the green and blue components\n" + "# of the color of each source are defined\n" + "# according to the value of the magnitude\n" + "{\ndraw rgb(255,-$[PHOT*],$[PHOT*]) square\n}", // object type "# We draw a different symbol according to\n" + "# the object type (value of the column \"otyp\")\n" + "${otyp}=\"Star\" {draw red square}\n"+ "${otyp}=\"Radio\" {draw blue rhomb}\n"+ "${otyp}=\"Galaxy\" || ${otyp}=\"Seyfert\" {draw green plus}\n"+ "# etc ...\n", // mouvements propres "# Draws an arrow representing\n" + "# the proper motion of the source\n" + "{draw pm(5*$[POS_EQ_PMRA],5*$[POS_EQ_PMDEC])}\n"+ "# Remark : You are suggested to modify the factor \n# if the arrows are too small or too long\n", // fonction rainbow (color index) "# This filters aims to visualize the color of stars\n" + "# according to their color index B-V.\n" + "# The optional parameters -0.3 and 1 mean that :\n" + "# - any source with a color index lesser than -0.3\n# is displayed in blue\n" + "# - any source with a color index greater than 1\n# is displayed in red\n" + "{draw rainbow($[PHOT_*_B-V],-0.3,1)}", // filtres sur les types spectraux "# This filter assigns colors related\n# to the spectral type of sources.\n" + "# The association spectral type --> color\n# is the following:\n" + "# O : violet\n" + "# B : blue/violet\n" + "# A : blue\n" + "# F : green/yellow\n" + "# G : yellow\n" + "# K : orange\n" + "# M R N S C : red\n" + "# T L : brown\n" + "# W : violet\n" + "# D : gray\n\n" + "$[SPECT_TYPE*] = \"*B*\" {draw #8a2be2}\n" + "$[SPECT_TYPE*] = \"*A*\" {draw blue}\n" + "$[SPECT_TYPE*] = \"*F*\" {draw #adff2f}\n" + "$[SPECT_TYPE*] = \"*G*\" {draw yellow}\n" + "$[SPECT_TYPE*] = \"*K*\" {draw orange}\n" + "$[SPECT_TYPE*] = \"*M*\" || $[SPECT_TYPE*] = \"*R*\" || $[SPECT_TYPE*] = \"*N*\" || \n" + "$[SPECT_TYPE*] = \"*S*\" || $[SPECT_TYPE*] = \"*S*\" {draw red}\n" + "$[SPECT_TYPE*] = \"*T*\" || $[SPECT_TYPE*] = \"*L*\" {draw #a52a2a}\n" + "$[SPECT_TYPE*] = \"*O*\" {draw #ee82ee}\n" + "$[SPECT_TYPE*] = \"*W*\" {draw #ee82ee}\n" + "$[SPECT_TYPE*] = \"*D*\" {draw gray}\n" }; // Labels des filtres predefinies static final String[] PREDEFLABELS = {"Magnitude circle", "Ellipses", "Magnitude cut", "Display text", "Parameterized colors", "Select object type", "Proper motions", "Color index", "Spectral types"}; // Mémoire des def. des filtres static String[] saveFilters = new String[LIMIT]; // Mémoire des labels des filtres static String[] saveLabels = new String[LIMIT]; String script; // Code courant du script (A MODIFIER/UTILISER PAR THOMAS) // numero du filtre (ie nombre de filtres deja crees - 1) static int num=-1; static PlanFilter[] allFilters = new PlanFilter[0]; // identifiant pour le filtre int numero; // objet qui effectue reellement le filtrage private UCDFilter filter; // objets mémorisant les plans influencés par le filtre private Vector memPlan, omemPlan; // true si il faut reappliquer le filtre (changement au niveau // des sources sur lesquellles le filtre s'applique) boolean mustUpdate = true; boolean mustRepaint = true; boolean initPlanMem = true; /////// Constructeurs /////// /** Creation d'un plan de type FILTER * @@param a Reference interne * @@param label le nom du plan (ou null si aucun) * @@param script le code initial (ou null si aucun) */ protected PlanFilter(Aladin aladin,String label,String script) { this.aladin = aladin; flagOk=true; type=FILTER; c = Color.black; active=false; selected=true; // si num>=LIMIT, on doit agrandir les tableaux de source (methode de source) numero = ++num; memPlan = new Vector(); omemPlan = new Vector(); // Si on doit reallouer allFilters et les tableaux de Source if(num>=LIMIT) { realloc(); } if( script!=null) { createFilter(script, label); } else { createFilter("", "Filter"+num); } this.script = filter.definition; this.label = filter.name; String orgName = filter.name; // chaque nom doit etre unique uniqueName(orgName); // sauvegarde du nom et de la definition saveDef(); if( script!=null ) doLog(); } /////// EOF Constructeurs /////// // Crée un label unique à partir de orgName private void uniqueName(String orgName) { int compteur=1; String name = orgName; while( getFilterByName(name,aladin) != null ) { name = orgName+compteur++; } this.label = name; } private void saveDef() { saveFilters[numero] = script; saveLabels[numero] = label; } /** Methode permettant de modifier la definition du filtre * @@param script - la definition du filtre * @@param name - nom du filtre */ protected void updateDefinition(String script, String name) { String oldDef = this.script; if( name!=null ) name = UCDFilter.skipSpaces(name); this.script = script; createFilter(script,name); this.script = filter.definition; this.label = filter.name.length()==0?this.label:filter.name; String save = this.label; // on met un label bidon pour que uniqueName ne trouve pas celui de this this.label=""; uniqueName(save); saveDef(); doLog(); // surement à modifier, pb des espaces dans les chaines ${sp}="t" != ${sp}=" t " // doit on updater à chaque fois ? // TESTER avec 1 2 3 4 ... plans éteints if( !UCDFilter.skipSpaces(this.script).equals(UCDFilter.skipSpaces(oldDef)) ) { setPlanMemory(); //System.out.println("on doit updater : "+morePlans(omemPlan,memPlan)); updateInfluence(); mustUpdate = true; /* // remplacer ligne ci dessous par la même action mais sans le resetActions qui me semble inutile setMustUpdate(); if( !mustUpdate ) { mustUpdate = true; // Je pense que la ligne ci dessous est inutile filter.resetActions(); } */ } if( !isValid() ) { if( !aladin.filterProperties.isShowing() ) { Aladin.warning("This filter can not be applied : please check the syntax",1); } this.active = false; aladin.calque.select.repaint(); aladin.view.setMesure(); return; } // a faire, maj de l affichage si necessaire if( isOn() ) applyFilter(); } /** Logue le nom et la définition du filtre */ private void doLog() { // les '\n' sont remplacés par un backslash pour que la définition ne prenne qu'une ligne dans le fichier de log aladin.glu.log("Filter","Label: "+this.label+"\tDef: "+this.script.replace('\n','\\')); } /** Methode privee permettant d'initialiser l'objet filter * a partir de la definition d'un filtre * @@param def - la definition du filtre * @@param name - nom du filtre (ou null si il est contenu dans def) * Si name==null, on suppose que le nom est inclus dans la definition du filtre */ private void createFilter(String def, String name) { // dans le cas ou le nom est inclus dans la definition if(name==null) { filter = new UCDFilter(def,aladin,this); } else { // nom et contraintes separees filter = new UCDFilter(name, def, aladin,this); } filter.setNumero(this.numero); if( !isValid() ) { error = "ERROR"; } else { error = null; } } /** Methode appelee a chaque activation/desactivation du plan */ protected void updateState () { //System.out.println("update state"); if( isOn() ) { if( !isValid() ) { Aladin.warning("This filter can not be applied : please check the syntax",1); this.active = false; aladin.calque.select.repaint(); aladin.view.setMesure(); return; } mustRepaint = true; applyFilter(); } else { aladin.view.setMesure(); //aladin.view.repaint(); } } protected void applyFilter() { if( initPlanMem ) { setPlanMemory(); updateInfluence(); initPlanMem = false; } // On tue d'abord le précédent thread (si on réappuie sur apply avant la fin) if( runme!=null ) runme.stop(); runme = new Thread(this); runme.setPriority( Thread.NORM_PRIORITY -1); runme.start(); } /** Methode appliquant le filtre sur tous les PlanCatalog situes sous le PlanFilter */ protected void doApplyFilter() { if( mustUpdate) { aladin.trace(1,"Updating filter results"); if( !isValid() ) { active=false; return; } else { flagOk = false; aladin.calque.repaint(); Source[] sources = getSources(aladin); resetFlags(); filter.getFilteredSources(sources); flagOk = true; pourcent = -1; } } if( mustRepaint ) { synchronized(aladin.mesure.text) { aladin.view.setMesure(); } } mustUpdate = false; } /** returns all sources of active plans and which are influenced by the filter * @@param aladin - reference to the Aladin object * @@return the array of sources of all active plans */ protected Source[] getSources(Aladin a) { int i,j; Plan p = null; Objet[] o = null; Vector vec = new Vector(); Plan[] plans = getConcernedPlans(); // loop on all plans and selection of catalogs which are active // we retrieve all sources in active plans for( i=plans.length-1; i>=0; i-- ) { p = plans[i]; //if( p.type == Plan.CATALOG && p.flagOk && p.active ) { o = p.pcat.o; if( o==null ) continue; // loop on all objects in PlanCatalog for( j=o.length-1; j>=0; j-- ) { if( o[j] instanceof Source && o[j]!=null) { vec.addElement(o[j]); } } //} } Source[] sources = new Source[vec.size()]; vec.copyInto(sources); vec = null; return sources; } /** Retourne le folder dans lequel se trouve this, null si dans aucun */ private Plan getFolder() { Plan p; Plan[] plansOfFolder; for( int i=aladin.calque.plan.length-1;i>=0;i-- ) { p = aladin.calque.plan[i]; if( p.type!=Plan.FOLDER ) continue; plansOfFolder = aladin.calque.getFolderPlan(p); for( int j=0;j oldMem.size() ) return true; Enumeration e = newMem.elements(); while( e.hasMoreElements() ) { if( !oldMem.contains(e.nextElement() ) ) return true; } return false; } /** Met à jour la mémoire des plans influencées par le filtre PREconditions : omemPlan et memPlan ne sont pas null */ private void setPlanMemory() { Plan[] plans = getConcernedPlans(); omemPlan = memPlan; memPlan = new Vector(); for( int i=0; i=0;i-- ) { p = aladin.calque.plan[i]; if( p.type != Plan.CATALOG ) continue; p.influence[this.numero] = memPlan.contains(p); } } /** Retourne les plans concernes par le filtre, ie les plans catalogue dans le meme folder et sous le PlanFilter * @@return le tableau des plans concernes */ protected Plan[] getConcernedPlans() { int pos = getPositionOfPlan(this); // position du plan this //System.out.println("Position : "+pos); Plan p; // plan courant Vector plans = new Vector(); Plan folder = getFolder(); Vector plansOfThis = null; if(folder!=null) { plansOfThis = getAllPlansOfFolder(getFolder()); } for( int i=aladin.calque.plan.length-1;i>=pos;i-- ) { p = aladin.calque.plan[i]; if( p.type != Plan.CATALOG || !p.flagOk || !p.active ) {continue;} // si le plan est dans un folder if( folder==null || plansOfThis.contains(p) ) { plans.addElement(p); } } // Copie dans un tableau avant de le retourner Plan[] ret = new Plan[plans.size()]; plans.copyInto(ret); return ret; } /** Retourne la position dans aladin.calque.plan du plan * @@param plan - le plan dont on cherche la position * @@return la position du plan, -1 si non trouve */ private int getPositionOfPlan(Plan plan) { Plan curPlan; for( int i=aladin.calque.plan.length-1;i>=0;i-- ) { curPlan = aladin.calque.plan[i]; if( curPlan==plan ) { return i; } } return -1; } /** reset isSelected flags of all sources, reset influence flags of all PlanCatalog and set them to false * */ private void resetFlags() { int i,j; Plan p = null; Objet[] o = null; // loop on all plans and selection of catalogs // note : faut-il le faire seulement sur les cats actifs ou sur tous ? for( i=aladin.calque.plan.length-1; i>=0; i-- ) { p = aladin.calque.plan[i]; if( p.type == Plan.CATALOG && p.flagOk /*&& p.active*/ ) { //p.influence[numero] = false; o = p.pcat.o; if( o==null ) continue; // loop on all objects in PlanCatalog for( j=o.length-1; j>=0; j-- ) { if( o[j] instanceof Source && o[j]!=null) { ((Source)o[j]).isSelected[numero] = false; //((Source)o[j]).influence[numero] = false; } } } } } /** Selection de toutes les sources filtrees par le plan */ protected void select() { filter.select(getSources(aladin)); aladin.view.setMesure(); //aladin.view.repaint(); } /** Exportation des sources filtrees vers un nouveau PlanCatalog */ protected void export() { int indice = aladin.calque.newPlanCatalog(); PlanCatalog plan = (PlanCatalog)aladin.calque.plan[indice]; plan.setLabel("Selected sources from filter "+this.label); Source[] selectedSources = filter.getFilteredSources(getSources(aladin)); Source s, newSource; // fill the new PlanCatalog with selected sources for( int i=selectedSources.length-1;i>=0;i-- ) { s = selectedSources[i]; plan.pcat.setObjetFast(newSource = new Source(plan, s.raj, s.dej, s.id, s.info)); newSource.isSelected = s.isSelected; newSource.values = s.values; newSource.actions = s.actions; newSource.leg = s.leg; } if(aladin.calque.getPlanRef()!=null) { plan.objet = aladin.calque.getPlanRef().objet; } plan.active = true; // set the type plan.setSourceType(Source.getDefaultType(selectedSources.length)); aladin.view.repaint(); } /** Methode appelee lorsque la position du PlanFilter sur le stack a ete modifiee */ protected void positionChange() { //System.out.println("position change"); //System.out.println("\nPosition change pour "+this.label); updateAllFilters(aladin); // permet de prendre en compte l'ordre des filtres setMustUpdate(); if( isOn() ) applyFilter(); } /** Le plan filtre est-il actif */ protected boolean isOn() { return active; } /** Teste la validite syntaxique du filtre * @@return true si la syntaxe est correcte, false sinon */ protected boolean isValid() { return !filter.badSyntax; } /** Methode appelee par le thread de calcul */ protected boolean waitForPlan() { //System.out.println("debut thread"); doApplyFilter(); //System.out.println("finthread"); return true; } /** Realloue de la memoire pour les differents tableaux */ private void realloc() { LIMIT += INCREMENT; Plan p; Objet[] o; Source s; for( int i=aladin.calque.plan.length-1;i>=0;i-- ) { p = aladin.calque.plan[i]; if( p.type == Plan.CATALOG ) { // realloc du tableau influence boolean[] tmp2 = new boolean[LIMIT]; System.arraycopy(p.influence,0,tmp2,0,p.influence.length); p.influence = tmp2; o = p.pcat.o; if( o==null ) continue; for( int j=o.length-1;j>=0;j-- ) { // pour chaque source, reallocation if( o[j] instanceof Source) { s=(Source)o[j]; // realloc de isSelected boolean[] tmp = new boolean[LIMIT]; System.arraycopy(s.isSelected,0,tmp,0,s.isSelected.length); s.isSelected = tmp; // realloc de actions Action[][] ac = new Action[LIMIT][]; for( int k=0;k=0;i-- ) { p = a.calque.plan[i]; if( p.type == Plan.FILTER ) { v.addElement((PlanFilter)p); } } PlanFilter[] ret = new PlanFilter[v.size()]; v.copyInto(ret); return ret; } /** Liberation de la memoire */ protected void Free() { if( runme!= null ) runme.stop(); memPlan = null; omemPlan = null; filter.Free(); super.Free(); // maj des filtres existant PlanFilter.updateAllFilters(aladin); } static protected PlanFilter getFilterByName(String s, Aladin a) { Plan p; for( int i=a.calque.plan.length-1;i>=0;i-- ) { p = a.calque.plan[i]; if( p.type == Plan.FILTER && p.label.equals(s)) { return (PlanFilter)p; } } return null; } /** Methode appelee lorsqu'un PlanCatalog a bouge * @@param p - le plan qui a bouge * @@param oldPos - ancienne position du plan * @@param newPos - nouvelle position du plan */ static void updatePlan(Plan p, int oldPos, int newPos) { //System.out.println("update plan pos"); PlanFilter pf = null; if(allFilters==null) return; for( int i=0;i0 ) { return label.substring(0,5>label.length()?label.length():5)+".. "+p+"%"; } return super.getLabel(); } } nOfPlan(this); // position du plan this //System.out.println("Position : "+pos); Plan p; // plan courant Vector plans = new Vector(); Plan folder = getFolder(); Vector plansOfThis = null; if(folder!=null) { plansOfThis = getAllPlansOfFolder(getFolder()); } for( int i=aladin.calque.plan.length-1;i>=pos;i-- )cds/aladin/PlanFree.java010064400076440000132000000062140770227416100161120ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; /** * Plan libre (NO) * * @@author Pierre Fernique [CDS] * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class PlanFree extends Plan { /** Creation d'un plan vide * @@param aladin reference */ protected PlanFree(Aladin aladin) { this.aladin= aladin; super.Free(); } } cds/aladin/PlanFov.java010064400076440000132000000077730770227416100157760ustar00ferniquecds00000400000013// // Copyright 1999-2003 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIELg, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. package cds.aladin; /** Plan graphique dédié à l'affichage d'un ou plusieurs FoV * */ public class PlanFov extends PlanTool { private Fov[] fov; // Constructeurs /** * @@param aladin référence à l'objet Aladin * @@param label Le label du plan * @@param fov tableau des Fov à afficher */ PlanFov(Aladin aladin, String label, Fov[] fov) { super(aladin, label); this.fov = fov; suite(); } /** * Construit les objets Ligne correspondant aux différents FoV */ private void suite() { PointD[] bords; PointD curPoint; Fov curFov; Ligne curLine; Plan ref = aladin.calque.getPlanRef(); if( ref==null || ref.projd==null ) return; // boucle sur tous les FoV for( int i=0; i=0)?file.substring(i+1):file; try { if( inImg!=null ) { int type = inImg.getType(); if( (type & MyInputStream.MRCOMP)!=0 ) fmt=MRCOMP; dis = inImg; } else { FileInputStream f=new FileInputStream(file); if( file.endsWith(".MRC") ) { dis = new MyInputStream(f); setFmt(); } else { f.close(); u = new URL("file:"+(new File(file)).getCanonicalPath()); Aladin.trace(3,"Opening file: ["+file+"]"); Aladin.trace(3,"Corresponding URL: ["+u+"]"); } } } catch( Exception e ) { String s=file+" error !\n"+e; Aladin.warning(s,1); return; } Suite(aladin,LOCAL,label, null, // objet "", // param "Local file ["+file+"]", // from fmt, UNDEF, // res autocut, null); // o } /** Creation d'un plan de type IMAGE (via une URL) * @@param u l'URL qu'il va falloir appeler * @@param label le nom du plan (dans la pile des plans) * @@param objet le target central (objet ou coord) * @@param param les parametres de l'image (SERC J MAMA...) * @@param fmt le format de l'image (JPEG, FITS, MRC, ...) * @@param res la res (FULL, PLATE...) * * Pour les images 2MASS et DENIS et EROSI, rajout temporaire d'un test * pour les charger obligatoirement en FITS, autocut et interpretation * du WCS. */ protected PlanImage(Aladin aladin, MyInputStream inImg, int orig, URL u, String label,String objet, String param, String from, int fmt,int res, boolean autocut,Objet o) { this.u =u; this.dis=inImg; Suite(aladin,orig,label,objet,param,from, fmt,res, autocut,o); } /** Creation d'un plan de type IMAGE (pour un backup) */ protected PlanImage(Aladin aladin) { this.aladin= aladin; type = IMAGE; c = Color.black; flagOk = true; active = true; } /** Suite de la creation d'un plan de type IMAGE * @@param label le nom du plan (dans la pile des plans) * @@param objet le target central (objet ou coord) * @@param param les parametres de l'interrogation (SERC J MAMA...) * @@param from La description de la provenance * @@param fmt le format de l'image * @@param res la res * @@param compress Le mode de compression * @@param autocut True s'il faut activer l'autocut de l'histogramme des couleurs */ void Suite(Aladin aladin, int orig, String label,String objet, String param, String from, int fmt,int res, boolean autocut,Objet o) { this.aladin = aladin; this.orig = orig; this.objet = objet; this.param = param; this.fmt = fmt; this.res = res; this.from = from; this.autocut = true; // On effectue toujours l'autocut type = IMAGE; setLabel(label); c = Color.black; aladin.calque.unSelectAllPlan(); selected = true; video = VIDEO_NORMAL; if( dis!=null ) setFmt(); else if( res==STAND ) { this.fmt=FITS; } // DESOSRMAIS, L'AUTOCUT EST TOUJOURS APPLIQUEE this.autocut = true; runme = new Thread(this); runme.setPriority( Thread.NORM_PRIORITY -1); runme.start(); } /** Retourne vrai si les deux plans passes en parametre * ont meme resolution et meme format */ protected static boolean sameFmtRes(Plan pa,Plan pb) { PlanImage p1,p2; try { p1=(PlanImage)pa; p2=(PlanImage)pb; } catch( Exception e ) { return false; } if( p1==null && p2==null ) return true; if( p1==null || p2==null ) return false; return p1.fmt==p2.fmt && p1.res==p2.res; } /** Donne le Survey decrit par le parametre. * Retourne l'explication du survey en fonction de la ligne d'interrogation * * @@param param description d'une image (ex: SERC J MAMA) */ protected String survey() { if( orig==ALADIN && (param==null || param.trim().length()==0) ) return("default image (DSS-I/STScI)"); if( orig==ALADIN ) return AladinServer.whichQualifier(param).trim(); return param; } /** Retourne un baratin explicatif pour le fmt et la resolution */ protected static String describeFmtRes(int fmt,int res) { /*anais*/ String f = fmt==RGB?"none (composed image)":fmt==JPEG?"Jpeg":fmt==FITS||fmt==HFITS||fmt==GFITS||fmt==MRCOMP?"Fits":null; String c = fmt==HFITS?"Hcompressed":fmt==GFITS?"gzipped":fmt==MRCOMP?"MR compressed":null; String r = res==FULL?"Full resolution":res==LOW?"Low resolution": res==PLATE?"Plate view":res==STAND?"(Aladin standalone image)":null; StringBuffer s = new StringBuffer(); if( f!=null ) s.append(f+" "); if( c!=null ) s.append(c+" "); if( s.length()>0 /*anais*/ && fmt!=RGB) s.append("format "); if( r!=null ) s.append("- "+r); return s.toString(); } /** Retourne le format sous forme d'une chaine */ protected static String getFormat(int fmt) { return fmt==JPEG?"JPEG":fmt==FITS?"FITS":fmt==GFITS?"GFITS": fmt==HFITS?"HFITS":fmt==MRCOMP?"MRCOMP":"UNKNOWN"; } /** Retourne la resolution sous forme d'une chaine*/ protected static String getResolution(int r) { return r==FULL?"FULL":r==LOW?"LOW":r==PLATE?"PLATE":r==STAND?"STAND":"UNDEF"; } /** Retourne le code du format */ protected static int getFmt(String fmt) { return fmt.equalsIgnoreCase("FITS")?FITS:fmt.equalsIgnoreCase("GFITS")?GFITS: fmt.equalsIgnoreCase("HFITS")?HFITS:fmt.equalsIgnoreCase("MRCOMP")?MRCOMP: fmt.equalsIgnoreCase("JPEG")?JPEG:UNKNOWN; } /** Retourne le code de la resolution */ protected static int getRes(String res) { return res.equalsIgnoreCase("FULL")?FULL:res.equalsIgnoreCase("LOW")?LOW: res.equalsIgnoreCase("PLATE")?PLATE:res.equalsIgnoreCase("STAND")?STAND:UNDEF; } /** Libere le plan. * cad met toutes ses variables a null ou a false */ protected void Free() { close(); headerFits=null; pixels=null; width = height = -1; pourcent=-1; tailleLoad=-1; cm=null; fmt=res=0; video=typeCM=0; changeEtat(); super.Free(); } // Indique que l'image a change en incrementant le numero de version // de l'image. // Un numero de version paire signifie que l'image a ete changee // un numero impair signifie que seule la table des couleurs a ete modifiee // --> mode==0 => changement image // mode==1 => changement CM static synchronized void changeEtat() { changeEtat(0); } static synchronized void changeEtat(int mode) { if( mode==0 ) { if( number%2==0 ) number+=2; else number++; } else { if( number%2==0 ) number++; else number+=2; } } /** Etat de l'image. * En cas de modif de la table des couleurs ou de l'image elle-meme, * la valeur retournee par cette fonction est incrementee * @@return la nouvelle valeur de l'etat de l'image *

* Rq : A l'origine, un numero de version paire signifie que l'image a ete changee, * un numero impair signifie que seule la table des couleurs a ete modifiee. Mais cette * fonctionnalite pose des problemes et n'est pas actuellement utilisable */ protected int getEtat() { return number; } /** Extraction d'une portion de l'image. * Retourne une portion de l'image sur la forme d'un tableau de pixels * @@param newpixels Le tableau a remplir (il doit etre assez grand) * @@param x,y,w,h Le rectangle de la zone a extraire */ protected void getPixels(byte [] newpixels,int x,int y,int w,int h) { int i,j,n,m; int k=0; int aw,ah; // Difference en abs et ord lorsqu'on depasse l'image // Ajustement de la taille en cas de depassement aw=ah=0; if( x+w>width ) { aw = x+w-width; w-=aw; } if( y+h>height ) { ah = y+h-height; h-=ah; } for( i=y, n=y+h; i0 ) { return (label.length()>l?label.substring(0,l):label)+".. "+p+"%"; } return super.getLabel(); } /** Retourne le statut (en langage naturel) de progression de chargement de l'image */ protected String getStatus() { return status+": "+progress; } // Juste pour se distraire static final String[] SOLAR = { "moon","lune","sun","soleil","mercury","mercure", "venus","mars","jupiter","saturn","saturne","uranus", "neptune","pluto","pluton","aladin","milky way", "J2000","sky","io" }; /** Retourne true s'il s'agit d'un objet du systeme solaire */ protected static boolean isSolar(String s) { if( s==null ) return false; s = s.trim(); for( int i=0; i0 ) query = query+" "+Glu.quote(param); URL ux = aladin.glu.getURL(Glu.debugTag("Calibration"),query,false,false); DataInputStream flux = new DataInputStream(ux.openStream()); c = new Calib(flux); flux.close(); status=status+": ok\n"; progress=""; } catch( Exception e2 ) { status=status+": fail\n"; progress=""; aladin.error = " Image server error\n \n"+getStatus()+"\n"+e2; close(); return false; } // Mini-test sur la calibration double taille = (int)(c.widtha*600)/10.0; if( taille<=0.0 ) { status=status+": error\n"; progress=""; aladin.error = "calibration error\n \n"+getStatus(); close(); return false; } // Recuperation de la taille de l'image Dimension d = c.getImgSize(); width = d.width; height = d.height; // On installe l'image en memoire status=status+"- Download the image"; progress="in progress..."; if( fmt==FITS ) r = cacheImageFits(u); // CETTE LIGNE DOIT ETRE COMMENTEE SI ON NE VEUT PLUS SUPPORTER MRCOMP // else if( fmt==MRCOMP ) r = cacheImageMrc(u); else r = cacheImageJpeg(u); if( flagAutoCropping ) c.cropping(width,height); if( !r ) { status=status+": fail\n"; progress=""; aladin.error = "image format unknown or server error\n \n"+getStatus(); close(); return false; } else status=status+": ok\n"; progress=""; // On associe la projection setNewProjD(new Projection(Projection.ALADIN,c)); return r; } /** Chargement d'une image associee a un objet du systeme solaire */ private void loadSolarObject() { width = height = 500; cacheImageJpeg(u); status = "The CDS is dedicated to\nthe extra solar system objects\nonly\n"; Aladin.warning(status); progress=""; error = Plan.NOREDUCTION; System.out.println("!!! "+error); } /** Ouverture du stream depuis une image d'archive */ private boolean openUrlImage() { status="Load the archive image"; progress="in progress..."; Aladin.trace(3,"Load archive image at: "+u); try { dis = new MyInputStream(u.openStream()); dis = dis.startRead(); } catch(Exception e) { if( orig==LOCAL ) { } Aladin.trace(3,"Second try for opening the stream due to: "+e+"..."); try{ dis = new MyInputStream(u.openStream()); dis = dis.startRead(); } catch(Exception e1) { if( u!=null ) System.err.println("Pb with: "+u); error=aladin.error="Server not reached or HTTP error"; Aladin.warning(error,1); close(); return false; } } setFmt(); return true; } private void setFmt() { try { int type=dis.getType(); fmt = (type & MyInputStream.GZ)!=0?GFITS: (type & MyInputStream.HCOMP)!=0?HFITS: (type & MyInputStream.MRCOMP)!=0?MRCOMP: FITS; } catch( Exception e) {} } /** Attente pendant la construction du plan. * @@return true si ok, false sinon. */ protected boolean waitForPlan() { try { // Cas particulier des objets du systeme solaire, juste pour rire if( isSolar(objet) ) loadSolarObject(); // Recherche de la calibration Aladin // IL NE FAUDRA PLUS CHARGER LA CALIBRATION S'IL S'AGIT DU FITS else if( orig==ALADIN && res!=STAND ) { if( !getCalibration() ) return false; // Image locale (necessairement FITS eventuellement gzippee) // ou acces serveur (FITS eventuellement gzippee ou MRC) } else { Calib c=null; /* if( orig!=LOCAL ) { if( !openUrlImage() ) return false; } else { status="Load the local image"; progress="in progress..."; } */ if( orig==LOCAL ) { status="Load the local image"; progress="in progress..."; } if( fmt!=MRCOMP ) { if( dis==null ) { if( !openUrlImage() ) return false; } } // Differentes methodes de lecture suivant le format boolean r; if( fmt==FITS || fmt==HFITS || fmt==GFITS ) r = cacheImageFits(dis); // CETTE LIGNE DOIT ETRE COMMENTEE SI ON NE VEUT PLUS SUPPORTER MRCOMP // else if( fmt==MRCOMP ) r = cacheImageMrc(dis); else { close(); return false; } if( !r ) { status=status+": fail\n"; progress=""; close(); return false; } else status=status+": ok\n"; progress=""; try { c = new Calib(headerFits); if( flagAutoCropping ) c.cropping(width,height); } catch( Exception e3 ) { error=NOREDUCTION; progress=""; Aladin.warning(error,1); } // On determine le x,y et le alpha,delta du centre de l'image if( c!=null ) { co = c.getImgCenter(); setNewProjD(new Projection(Projection.WCS,c)); // En cas de chargement par un fichier local if( objet==null ) { objet = co.getSexa(); Server.setDefaultTarget(objet); } else { // Pour que le repere soit positionne non au centre de l'image // mais en fonction des coordonnees de la requete co=null; } } } close(); // On change l'etat changeEtat(); if( aladin.msgOn ) aladin.endMsg(); // aladin.message.hideWait(); } catch( Exception ex ) { ex.printStackTrace(); error=aladin.error!=null?aladin.error:ex.toString(); Aladin.warning(error,1); close(); return false; } catch( Error eall ) { eall.printStackTrace(); error=aladin.error = eall.toString(); Aladin.warning(error+" ",1); close(); return false; } return true; } /** Determination pour un tableau de bean[] de l'indice du bean min * et du bean max en fonction d'un pourcentage d'information desire * @@param bean les valeurs des beans provenant de l'analyse d'une image * @@return mmBean[2] qui contient les indices du bean min et du bean max */ private int[] getMinMaxBean(int [] bean) { double minLimit=0.003; // On laisse 3 pour mille du fond double maxLimit=0.999; // On laisse 1 pour mille des etoiles int totInfo; // Volume de l'information int curInfo; // Volume courant en cours d'analyse int [] mmBean = new int[2]; // indice du bean min et du bean max int i; // Determination du volume de l'information for( totInfo=i=0; i no autocut applied"); mmBean[0]=0; mmBean[1]=bean.length-1; } return mmBean; } // Conversion byte[] en entier 32 // Recupere sous la forme d'un entier 32bits un nombre entier se trouvant // a l'emplacement i du tableau t[] final private int getInt(byte[] t,int i) { return (((int)t[i])<<24) | ((((int)t[i+1])&0xFF)<<16) | ((((int)t[i+2])&0xFF)<<8) | ((int)t[i+3])&0xFF; } // Conversion byte[] en double 64 // Recupere sous la forme d'un double 64bits un nombre se trouvant // a l'emplacement i*NbByte(bitpix) du tableau t[] // 0 si erreur sur bitpix final private double getPixVal(byte[] t,int bitpix,int i) { switch(bitpix) { case 8: return (double)(((int)t[i])&0xFF); case 16: i*=2; return (double)( (((int)t[i])<<8) | ((int)t[i+1])&0xFF ); case 32: return (double)getInt(t,i*4); case -32: return (double)Float.intBitsToFloat(getInt(t,i*4)); case -64: i*=8; long a = (((long)getInt(t,i))<<32) | (((long)getInt(t,i+1))&0xFFFFFFFF); return (double)Double.longBitsToDouble(a); } return 0.; } /** Mise sur 8 bits de l'image * @@param pIn le tableau des pixels en entree * @@param bitpix la profondeur des pixels (format FITS) * @@param width,height Largeur et hauteur de l'image * @@param minCut,maxCut valeurs limites (si 0 0, non prises en compte) * @@return pOut Le tableau des pixels sur 8 bits * * Le cas echeant, il y a aura egalisation de l'histogramme * des pixels pour tenir dans les 8 bits */ private byte[] getPix8Bits(byte[] pOut, byte[] pIn, int bitpix, int width, int height) { return getPix8Bits(pOut,pIn,bitpix,width,height,0,0,0); } private byte[] getPix8Bits(byte[] pOut, byte[] pIn, int bitpix, int width, int height, double minCut,double maxCut,int ntest) { int i,j,k; int cran=0; boolean flagCut=(ntest>0); Aladin.trace(3,"getPix8Bits ("+ntest+"): bitpix="+bitpix+" size=("+width+","+height+") ["+minCut+".."+maxCut+"]"); if( !autocut && bitpix==8 ) return pIn; if( pOut==null ) pOut = new byte[width*height]; // Recherche du min et du max en evitant les deux valeurs // extremes generalement buguees. pourcent=66; double max = 0, max1 = 0; double min = 0, min1 = 0; boolean first=true; double c; long nmin=0,nmax=0; int MARGE=(int)(width*0.05); for( i=MARGE; imaxCut ) continue; } if( first ) { max=max1=min=min1=c; first=false; } if( min>c ) { min=c; nmin=1; } else if( maxmin || min1==min ) min1=c; else if( c>max1 && cc ) min=c; else if( maxtaille/10 || nmintaille/10 || nmaxmax1-min1 && min1!=Double.MAX_VALUE && min1!=max ) min=min1; if( max-max1>max1-min1 && max1!=Double.MIN_VALUE && max1!=min ) max=max1; if( autocut ) { pourcent=80; // Histogramme int nbean = 10000; double l = (max-min)/(double)nbean; Aladin.trace(3,"image autocut for: min="+min+" max="+max+" nbean="+nbean+" beansize="+l); int[] bean = new int[nbean]; for( i=MARGE; i=bean.length || j<0 ) continue; bean[j]++; } } // Selection du min et du max en fonction du volume de l'information // que l'on souhaite garder int [] mmBean = getMinMaxBean(bean); max1=max; min1=min; max1 = mmBean[1]*l+min1; min1 += mmBean[0]*l; Aladin.trace(3,"image autocut("+ntest+"): beanMin="+ mmBean[0]+" beanMax="+mmBean[1]+" => min="+min+" max="+max); if( mmBean[0]>mmBean[1]-5 && ntest<10 ) { if( min1>min ) min=min1; if( max1=max?0xff:(int)( ((c-min)*r) ) & 0xff); } return pOut; } /** Retournement de l'image * @@param methode 0-N/S, 1-D/G, 2-N/S+D/G */ protected void flip(int methode) { if( methode==0 || methode==2 ) invImageLine(width,height,pixels); if( methode==1 || methode==2 ) invImageRow(width,height,pixels); projd.flip(methode); changeEtat(); for( int i=0; i=0; h-- ) { int offset1=h*width; int offset2=(height-h-1)*width; System.arraycopy(pixels,offset1, tmp,0, width); System.arraycopy(pixels,offset2, pixels,offset1, width); System.arraycopy(tmp,0, pixels,offset2, width); } } /** Retournement de l'image (Inversion des colonnes) * @@param width largeur de l'image * @@param height hauteur de l'image * @@param pixels Tableau des pixels (en entree et en sortie) */ protected static void invImageRow(int width, int height,byte [] pixels) { byte tmp; for( int h=0; h=0; w-- ) { int offset2=offset1+width-w-1; tmp = pixels[offset1+w]; pixels[offset1+w]=pixels[offset2]; pixels[offset2]=tmp; } } } // Met dans un cache memoire l'image au format JPEG // afin d'eviter d'avoir systematiquement recours a l'URL // pour toutes les manipulations de cette image // On lui associe une table de couleurs (256 niveaux de gris) synchronized boolean cacheImageJpeg(URL u) { ImageProducer source; // Pour des stats Date d = new Date(); Date d1; int temps; Aladin.trace(2,"Loading JPEG image"); // La recuperation de la source de production du JPEG est un peu // delicate car les classes ne sont pas les memes suivant // les machines java. En cas ou le getContent() sur l'URL ne // retourne pas un ImageProducer, on va contourner le probleme // en demander l'image (getImage()), et sur cette image, on demandera // la source (cochonnerie de JAVA !) try { URLConnection uc = u.openConnection(); source=(ImageProducer)(uc.getContent()); } catch( Exception ex ) { source=null; } // Netscape 3 et 4 n'implante pas l'interface ImageProducer // pour l'objet retourne par getContent(), va falloir faire // deux appels successifs if( source==null ) { Aladin.trace(3,"Cannot get JPEG image source by getSource()... use getImage()"); Image itmp = aladin.getToolkit().getImage(u); MediaTracker t = new MediaTracker(aladin); t.addImage(itmp,0); try{ t.waitForID(0); } catch( InterruptedException e) { System.err.println("cacheImageJpeg error: "+e); return false; } source=itmp.getSource(); } d1=new Date(); temps = (int)(d1.getTime()-d.getTime()); d=d1; Aladin.trace(3," => Waiting server during "+temps+" ms"); // Recuperation de l'image 8 bits pourcent=10; pixels = new byte[width*height]; GreyMemory gm = new GreyMemory((ImageProducer)source,pixels); if( !gm.waitImage() ) return false; pourcent=66; d1=new Date(); temps = (int)(d1.getTime()-d.getTime()); d=d1; Aladin.trace(3," => Loading in "+temps+" ms"); pixels=getPix8Bits(null,pixels,8,width,height); d1=new Date(); temps = (int)(d1.getTime()-d.getTime()); d=d1; Aladin.trace(3," => Autocutting in "+temps+" ms"); cm = creatDefaultCM(); pourcent=99; return true; } // Recuperation d'une image FITS (via une URL) boolean cacheImageFits(URL u) throws Exception { // Pour des stats Date d = new Date(); Date d1; int temps; try{ dis = new MyInputStream(u.openStream()); dis = dis.startRead(); } catch( Exception e ) { return false; } d1=new Date(); temps = (int)(d1.getTime()-d.getTime()); d=d1; Aladin.trace(3," => Waiting server during "+temps+" ms"); setFmt(); return cacheImageFits(dis); } int offsetLoad=-1; // Nombre d'octets deja charges int tailleLoad=-1; // Nombre d'octets a charger /** Retourne le nombre de KB deja charge */ private String getOffsetLoad() { if( tailleLoad==-1 ) return " - in progress..."; return " - "+((int)pourcent)+"% of "+(tailleLoad/1024)+"KB ..."; } /** Lecture d'un flux stream de n octets exactement * @@param dix le flux de donnees * @@param buf le tableau a remplir * @@param pos la position dans le tableau * @@param len le nombre d'octets a lire * @@return le nombre d'octets lus ou genere une erreur en cas de probleme */ /* protected static int streamReadFully(PushbackInputStream dis,byte [] buf) throws Exception { return streamReadFully(dis,buf,0,buf.length); } protected static int streamReadFully(PushbackInputStream dis1,byte [] buf, int pos,int len) throws Exception { int off=pos; int l=len; int n; DataInputStream dis = new DataInputStream(dis1); */ /* while( (n=dis.read(buf,off,l))!=l && n!=-1 ) { off+=n; l-=n; System.out.print("["+n+"]"); }; if( n==-1 ) throw new Exception(); */ /* dis.readFully(buf,off,l); return len; } */ /** Lecture de la totalite d'un flux dans un tableau de bytes * sans savoir a priori la taille du flux * La lecture se fait dans un vecteur de blocs que l'on concatene * a la fin de la lecture * @@param dis le flux * @@return le tableau de byte */ /* protected static byte [] streamReadFully(InputStream dis) { int size=8192; Vector v = new Vector(10); Vector vSize = new Vector(10); int n=0,m=0,i=0,j=0,last=0; byte [] tmp; try { tmp = new byte[size]; while( (n=dis.read(tmp))!=-1 ) { i++; //System.out.println("Je lis "+n+" octets (tranche "+i+")"); v.addElement(tmp); vSize.addElement( new Integer(n) ); m+=n; if( n "+m+" octets"); System.arraycopy(tmp,0,tab,n,m); n+=m; } return tab; } */ /** Calcul la marge necessaire pour une config memoire donnee * @@param maxmem limite de la memoire en octets * @@param width,height taille de l'image originale * @@param n nombre d'octets par pixel * @@return la marge a enlever en pixels pour que ca tienne en memoire, -1 si pb */ private int getMarge(int maxmem,int width, int height, int n) { double a = 4, b=-2*(width+height), c=width*height-maxmem/n; double marge = (-b-Math.sqrt(b*b-4*a*c))/(2*a); marge += marge%n; if( marge<0 || marge>width/2 ) { marge=-1; // Probleme !! } return (int)marge; } // Recuperation d'une image FITS (via un PushbackInputStream) // Rq: si gzis est !=null, ce sera ce flux qui sera prix, sinon dis boolean cacheImageFits(MyInputStream dis) throws Exception { width = -1; height = -1; int bitpix; int[] theData = null; int naxis = 2; int i,j; byte[] t=null; // tableau de lecture du flux int[] tdec=null; // tableau de decalage des octets int taille; // nombre d'octets a lire int n; // nombre d'octets pour un pixel Aladin.trace(2,"Loading FITS image"); // Lecture de l'entete Fits si ce n'est deja fait if( headerFits==null ) headerFits = new HeaderFits(dis); bitpix = headerFits.getIntFromHeader("BITPIX "); naxis = headerFits.getIntFromHeader("NAXIS "); if (naxis <= 1) { error=aladin.error="Only one dimension => Not an image !"; Aladin.warning(error,1); return false; } width = headerFits.getIntFromHeader("NAXIS1 "); if (width <= 0) return false; height = headerFits.getIntFromHeader("NAXIS2 "); if (height <= 0) return false; n = Math.abs(bitpix)/8; // Nombre d'octets par valeur taille=width*height*n; // Nombre d'octets pourcent=0; //Aladin.trace(3," => NAXIS1="+width+" NAXIS2="+height+" BITPIX="+bitpix+" => taille="+taille); // Pour des stats Date d = new Date(); Date d1; int temps; // Lecture HCompress if( headerFits.isHCOMP() ) { Aladin.trace(2,"Hdecompressing"); fmt=HFITS; // On force le format t=Hdecomp.decomp((InputStream)dis); if( n>1 ) tdec = new int[width*height]; d1=new Date(); temps = (int)(d1.getTime()-d.getTime()); d=d1; Aladin.trace(3," => Hdecompressing in "+temps+" ms"); } // Lecture normale ou Gzip else { offsetLoad=0; // octets effectivement lus tailleLoad=taille; // nombres d'octets a lire int len = taille/1000; // taille des blocs par defaut int marge=0; // marge d'autocropping eventuel int maxmem = taille; // nombres d'octets lisibles boolean encore=true; int essai=0; if( len1 ) tdec = new int[(width-2*marge)*(height-2*marge) + ( n==8?1:0)]; t = new byte[maxmem]; pixels = new byte[(width-2*marge)*(height-2*marge)]; encore=false; } catch( OutOfMemoryError etaille ) { // if( n>1 ) tdec=null; t=null; System.gc(); switch(essai) { case 1: //System.out.println("Garbage collection... and try again"); t=null; System.gc(); break; case 2: //System.out.println("Premiere marge !"); marge=width/100; break; default: marge = (int)(marge*1.4); System.gc(); } maxmem=(width-2*marge)*(height-2*marge)*n; if( marge>width/2 ) { throw new OutOfMemoryError(); } } } if( len>t.length ) len=t.length; if( essai>2 ) System.gc(); d1=new Date(); temps = (int)(d1.getTime()-d.getTime()); d=d1; Aladin.trace(3," => Allocating ("+maxmem+"b) in "+temps+" ms"); // Lecture normale if( marge==0 ) { // Lecture par tranches pour avoir une idee du volume deja charge while( offsetLoad Reading in "+temps+" ms"); // Passage en 8 bits pixels=getPix8Bits(pixels,t,bitpix,width,height); d1=new Date(); temps = (int)(d1.getTime()-d.getTime()); d=d1; Aladin.trace(3," => Setting in 8bits/autocut in "+temps+" ms"); t=null; // pour aider gc // Retournement de l'image (les lignes ne sont pas rangees dans le meme ordre // en FITS et en JAVA invImageLine(width,height,pixels); cm = creatDefaultCM(); pourcent=99; return true; } /* // CETTE METHODE DOIT ETRE COMMENTEE SI ON NE VEUT PLUS SUPPORTER MRCOMP // Recuperation d'une image MRC (via une URL) boolean cacheImageMrc(URL u) { try{ dis = new MyInputStream(u.openStream()); } catch( Exception e ) { return false; } setFmt(); return cacheImageMrc(dis); } // Recuperation d'une image MRC (via un PushbackInputStream) boolean cacheImageMrc(MyInputStream dis) { Aladin.trace(2,"Loading MRC image"); if( Aladin.MRDECOMP ) { // Objet de manipulation de la methode de decompression MRCOMP cea.mrcomp.MrDecomp mrc; try { byte [] mrcBuf = dis.readFully(); Aladin.trace(2,"Lecture complete du fichier ("+mrcBuf.length+")"); mrc= new cea.mrcomp.MrDecomp(mrcBuf); Aladin.trace(2,"Creation de l'objet mrc"); width = mrc.getWidth(); height = mrc.getHeight(); Aladin.trace(2,"Determination de la taille ("+width+","+height+")"); String s = mrc.getHeaderFits(); if( s==null ) { status=status+": fail (no FITS header embedded)\n"; progress=""; aladin.error = " Image MRCOMP error\n \n"+getStatus(); return false; } headerFits=new HeaderFits(s); Aladin.trace(2,"Analyse du header fits"); pixels = new byte[width*height]; if( mrc.getPixel(pixels)<0 ) { System.err.println("MRC getPixels error"); return false; } Aladin.trace(2,"Recuperation des pixels"); } catch (Exception e) { System.err.println("MRC error: "+e);e.printStackTrace(); return false; } cm = creatDefaultCM(); Aladin.trace(2,"C'est termine"); return true; } else return false; } */ /** Retourne vrai si par defaut la table des couleurs doit etre inversee */ // protected boolean inverseCM() { return res==PLATE || res==LOW; } protected boolean inverseCM() { return true; } /** Creation d'une table de couleurs par defaut (grise). * NECESSAIRE A CAUSE D'UN BUG MAC QUI NE COMPREND LA COMMANDE * new DirectColorModel(8,255,255,255); * @@param reverse true s'il faut inverser * @@return la table des couleurs */ protected ColorModel creatDefaultCM() { return creatDefaultCM(inverseCM()); } protected ColorModel creatDefaultCM(boolean reverse) { byte [] g = new byte[256]; // On fait du gris - en reverse s'il s'agit d'une vue globale if( reverse ) { for( int i=0; i<256; i++ ) g[i]=(byte)(~i); video=VIDEO_INVERSE; } else { for( int i=0; i<256; i++ ) g[i]=(byte)i; video=VIDEO_NORMAL; } return (ColorModel) new IndexColorModel(8,256,g,g,g); } /** Affectation d'une nouvelle table des couleurs * a l'image du plan * @@param cm la nouvelle table des couleurs */ protected void setCM(Object cm) { this.cm = (ColorModel)cm; changeEtat(1); aladin.view.endDynamicCM(); } /** Manipulation dynamique de la table des couleurs. * Permet de modifier dans une portion de l'image la table des couleurs * afin de se rendre compte du rendu * @@param cm la table des couleurs courante */ protected void newCM(Object cm) { aladin.view.dynamicCM(cm); } /** Retourne l'identification du plan en fonction de la valeur * objet et du label */ private String getFullLabel() { if( objet!=null && objet.indexOf(label)>=0 ) return objet; if( objet!=null && label.indexOf(objet)>=0 ) return label; return ((objet==null)?"":objet+" - ")+label; } /** Affiche la ligne d'informations concernant le plan dans le statut d'Aladin*/ protected void getInfo() { String s; if( type==NO ) { super.getInfo(); return; } if( !flagOk && error==null ) s = getFullLabel()+getOffsetLoad(); else { s = getFullLabel(); String survey = survey(); if( survey.length()>0 ) survey = " - "+survey; if( error!=null ) s = s+" *** Error *** "+error; else s = s + survey+" - "+describeFmtRes(fmt,res); } aladin.status.setText(s); } /** Dessin des bordures de l'image * @@param g Le contexte graphique * @@param dx,dy Offset en cas d'impression */ protected void drawBord(Graphics g,int dx,int dy) { ZoomView zv = aladin.calque.zoom.zoomView; // int dx = (int)projd.c.xnpix/2; // int dy = (int)projd.c.ynpix/2; Plan pr = aladin.calque.getPlanRef(); if( pr==null || pr.projd==null ) return; Projection proj = pr.projd; g.setColor(aladin.view.getInfoColor()); Coord c; try { c = projd.c.getImgCenter(); } catch( Exception e ) { return; } double x = c.x; double y = c.y; /* Coord c = new Coord(); c.x=dx; c.y=dy; */ Point p[] = new Point[4]; for( int i=0; i<4; i++ ) { Coord ct = new Coord(); int sgnX=(i<2)?-1:1; int sgnY=(i==1 || i==2 )?1:-1; ct.x = c.x+sgnX*x; // X d'un coin dans la calib courante ct.y = c.y+sgnY*y; // Y du coin dans la calib courante projd.getCoord(ct); // Calcul alpha,delta dans la calib courante proj.getXY(ct); // Calcul X,Y dans la calib de ref p[i] = zv.getViewCoord(ct.x,ct.y); // Calcul X,Y dans la View if( i>0 ) g.drawLine(p[i-1].x+dx,p[i-1].y+dy,p[i].x+dx,p[i].y+dy); if( i==3) { g.drawLine(p[i].x+dx,p[i].y+dy,p[0].x+dx,p[0].y+dy); g.drawString(label,p[0].x+dx,p[0].y-4+dy); } } } } /* // CETTE CLASSE DOIT ETRE COMMENTEE SI ON NE VEUT PLUS SUPPORTER MRCOMP class MrDecomp { MrDecomp(byte []a) { System.out.println("Creation de l'objet MrDecomp avec buffer de "+a.length+" octets"); } int getWidth() { return(500); } int getHeight() { return(500); } int getPixels(byte [] pixels) { return 1; } } */ byte[(width-2*marge)*(height-2*marge)]; encore=false; } catch( OutOfMemoryError etacds/aladin/PlanImageRGB.java010064400076440000132000000461170770227416100166140ustar00ferniquecds00000400000013// // Recherche Scientifique // // ------ // // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.image.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; import java.util.zip.*; /** * Gestion d'un plan image RGB * * @@author Anais Oberto [CDS] * @@version 1.2 : fevrier 2002 deduction automatique du plan de reference * @@version 1.1 : janvier 2002 ajustements pour la version officielle (P.Fernique) * @@version 1.0 : decembre 2001 creation */ public final class PlanImageRGB extends PlanImage { protected int [] pixelsRGB; // Tableau des pixels de l'image (sur 4x8 bits) protected byte [] red; // Tableau des pixels de l'image Rouge protected byte [] green; // Tableau des pixels de l'image Verte protected byte [] blue; // Tableau des pixels de l'image Bleue protected boolean twoColors; protected int RGBCONTROL[] = { 0,128, 255 , 0,128, 255 , 0,128, 255 }; protected int RGBControl[]; protected PlanImage [] pi = new PlanImage[3]; protected String [] labels = new String[3]; PlanImage Red,Green,Blue,Ref; protected boolean diff; // true s'il s'agit d'une difference sur 2 plans /** Creation d'un plan de type IMAGE (via 2 ou 3 autres plans) * @@param r Le plan correspondant a la bande rouge * @@param g Le plan correspondant a la bande verte * @@param b Le plan correspondant a la bande bleue * @@param ref Le plan de reference pour le reechantillonage * @@param d true s'il s'git d'une différence */ protected PlanImageRGB(Aladin aladin, PlanImage r, PlanImage g, PlanImage b, PlanImage ref,boolean d) { super(aladin); Red=r; Green=g; Blue=b; // Determination du plan de reference si ce n'est pas indique double x=Double.MAX_VALUE; if( ref==null ) { if( r!=null && Math.abs(r.projd.c.incA)true si ok, false sinon. */ protected boolean waitForPlan() { PlanImage p1=null,p2=null,p3=null; // Determination du plan de reference du reechantillonage // et des deux autres if( Ref==Red ) { p1=Red; p2=Green; p3=Blue; } else if( Ref==Green ) { p1=Green; p2=Red; p3=Blue; } else if( Ref==Blue ) { p1=Blue; p2=Red; p3=Green; } // Acces vers les tableaux de pixels // red = p1.pixels; //Reechantillonage Aladin.trace(3,"Resampling (R:"+labels[0]+",G:"+labels[1]+",B:"+labels[2]+" astro from "+Ref.label+")..."); Coord coo = new Coord(); int x=0,y=0; int w = p1.width; int i; byte [] c1 = diff?(new byte[p1.pixels.length]):p1.pixels; byte [] c2 = new byte[p1.pixels.length]; byte [] c3 = new byte[p1.pixels.length]; for( i=0; i=0 && x=0 && y=0 && x=0 && y0 ) { a[y] = (byte) (a1-b1); b[y]=x[y] = 0; } else { b[y] = (byte) (b1-a1); a[y]=x[y] = 0; } } else x[y] = (byte)((int) Math.min ( ((int) a[y]) & 0xFF, ((int) b[y]) & 0xFF ) & 0xFF ); } } /** Modifie le tableau des pixels couleurs lors d'un changement dans * l'inverse video */ protected void inverseRGB () { int size = width * height; byte r,g,b; for (int y = 0 ; y < size ; y++) { pixelsRGB[y] = pixelsRGB[y] ^ 0x00FFFFFF; /* // Recuperation des couleurs courantes r = (byte) ( (pixelsRGB[y] & 0x00FF0000) >> 16 ) ; g = (byte) ( (pixelsRGB[y] & 0x0000FF00) >> 8 ) ; b = (byte) ( (pixelsRGB[y] & 0x000000FF) ) ; // Dans le cas de 2 couleurs, on inverse le deux couleurs existantes // et on recalcule la derniere if( twoColors ) { if( Blue==null ) { pixelsRGB[y] = ( ( 0xFF ) << 24) | ( ( (255-(int) g) & 0xFF ) << 16) | ( ( (255-(int) r) & 0xFF ) << 8) | ( min( (255-(int)r) & 0xFF, (255-(int)g) & 0xFF ) & 0xFF ); } else if( Green==null ) { pixelsRGB[y] = ( ( 0xFF ) << 24) | ( ( (255-(int) b) & 0xFF ) << 16) | ( ( min( (255-(int)r) & 0xFF, (255-(int)b) & 0xFF ) & 0xFF ) << 8) | ( (255-(int) r) & 0xFF ); } else { pixelsRGB[y] = ( ( 0xFF ) << 24) | ( ( min( (255-(int)g) & 0xFF, (255-(int)b) & 0xFF ) & 0xFF ) << 16) | ( ( (255-(int) b) & 0xFF ) << 8) | ( (255-(int) g) & 0xFF ); } } else pixelsRGB[y] = ( ( 0xFF ) << 24) | ( ( (255-(int) r) & 0xFF ) << 16) | ( ( (255-(int) g) & 0xFF ) << 8) | ( (255-(int) b) & 0xFF ); */ } changeEtat(1); aladin.calque.select.repaint(); } /** Filtre le tableau de pixels couleurs en fonction de l'histogramme * @@param triangle [] Tableau des positions des triangles * @@param size Taille totale de la zone de l'image a parcourir * @@param x,y Position initiale sur l'image * @@param color Couleur de l'histogramme modifie : 0 -> rouge 1 -> vert 2 -> bleu */ public void filterRGB(int [] triangle, int size, int x, int y, int color) { int w = x+size; int h = y+size; int [] out = aladin.view.pixelsCMRGB; changeEtat(1); int tr0 = triangle[0]; int tr1 = triangle[1]; int tr2 = triangle[2]; int r,g,b; for ( int i=y; i> 16 ) ; g = (int) ( (pixel & 0x0000FF00) >> 8 ) ; b = (int) ( (pixel & 0x000000FF) ) ; // modification uniquement de celle concernee if (color==0) r = filter(tr0,tr1,tr2,(int)red[pos]&0xFF); else if (color==1) g = filter(tr0,tr1,tr2,(int)green[pos]&0xFF); else b = filter(tr0,tr1,tr2,(int)blue[pos]&0xFF); // inversion si necessaire if( video==VIDEO_INVERSE ) { if( color==0 ) r=~r; else if( color==1 ) g=~g; else b=~b; if (twoColors) { if( Red==null ) r = Math.max(g & 0xFF, b & 0xFF); else if( Green==null ) g = Math.max(r & 0xFF, b & 0xFF); else b = Math.max(r & 0xFF, g & 0xFF); } } else { if (twoColors) { if( Red==null ) r = Math.min(g & 0xFF, b & 0xFF); else if( Green==null ) g = Math.min(r & 0xFF, b & 0xFF); else b = Math.min(r & 0xFF, g & 0xFF); } } // ecriture en sortie out[(i-y)*(w-x)+j-x]= 0xFF000000 | ((r&0xFF)<<16) | ((g&0xFF)<<8) | (b&0xFF); } } } /** Filtre tout le tableau de pixels couleurs en fonction de l'histogramme * @@param triangle [] Tableau des positions des triangles * @@param color Couleur de l'histogramme modifie : 0 -> rouge 1 -> vert 2 -> bleu */ public void filterRGB(int [] triangle, int color) { changeEtat(1); int tr0 = triangle[0]; int tr1 = triangle[1]; int tr2 = triangle[2]; int size = width*height; int r,g,b ; for ( int pos=0; pos> 16 ) ; g = (int) ( (pixelsRGB[pos] & 0x0000FF00) >> 8 ) ; b = (int) ( (pixelsRGB[pos] & 0x000000FF) ) ; // Modification uniquement de celle concernee if (color == 0) r = filter(tr0,tr1,tr2,(int)red[pos]&0xFF); else if (color == 1) g = filter(tr0,tr1,tr2,(int)green[pos]&0xFF); else b = filter(tr0,tr1,tr2,(int)blue[pos]&0xFF); // inversion si necessaire if( video==VIDEO_INVERSE ) { if( color==0 ) r=~r; else if( color==1 ) g=~g; else b=~b; if (twoColors) { if( Red==null ) r = Math.max(g & 0xFF, b & 0xFF); else if( Green==null ) g = Math.max(r & 0xFF, b & 0xFF); else b = Math.max(r & 0xFF, g & 0xFF); } } else { if (twoColors) { if( Red==null ) r = Math.min(g & 0xFF, b & 0xFF); else if( Green==null ) g = Math.min(r & 0xFF, b & 0xFF); else b = Math.min(r & 0xFF, g & 0xFF); } } // ecriture en sortie pixelsRGB[pos]= 0xFF000000 | ((r&0xFF)<<16) | ((g&0xFF)<<8) | (b&0xFF); } } /** Calcul des nouvelles valeurs ds pixels suivant l'histogramme * Retourne la valeur calculee * @@param tr0, tr1, tr2 Les positions des triangles * @@param var La valeur initiale */ protected int filter(int tr0, int tr1, int tr2, int var){ double dy = 128.0; double dx, alpha, beta; // Seuil bas et haut if (var<=tr0) return 0; else if (var>=tr2) return 255; else if (var>tr0 && var<=tr1) { // Premier segment de droite pour la 1ere moitie de la dynamique dx = (double)(tr1-tr0); if( dx>0.0 ) { alpha = dy/dx; beta = -alpha*tr0; return (byte)(var*alpha+beta); } } else { // Deuxieme segment de droite pour la 2eme moitie de la dynamique dx = (double)(tr2-tr1); if( dx>0.0 ) { alpha = dy/dx; beta = 128.0-alpha*tr1; return (byte)(var*alpha+beta); } } return var; } /** Extraction d'une portion de l'image. * Retourne une portion de l'image sur la forme d'un tableau de pixels * @@param newpixels Le tableau a remplir (il doit etre assez grand) * @@param x,y,w,h Le rectangle de la zone a extraire */ protected void getPixels(int [] newpixels,int x,int y,int w,int h) { int i,j,n,m; int k=0; int aw,ah; // Difference en abs et ord lorsqu'on depasse l'image // Ajustement de la taille en cas de depassement aw=ah=0; if( x+w>width ) { aw = x+w-width; w-=aw; } if( y+h>height ) { ah = y+h-height; h-=ah; } for( i=y, n=y+h; iXY of \""+plan.label+"\" on \"" +p.label+"/"+proj.label+"\""); } /** Positionne les coordonnees RA/DE de tous les objets du plan (TOOL) * en fonction des coordonnees x,y courantes */ protected void setCoord() { if( plan.type!=Plan.TOOL ) return; // Ne se fait que sur les plans TOOL for( int i=0; ira/dec on \""+plan.label+"\""); for( int i=0; i0 ) computeTarget(); // Appel au post traitement postJob(rajc,dejc,rm); } /** Post treatement du chargement d'objet (source) pour mettre a jour * le type de forme par defaut et la projection par defaut */ protected void postJob(double rajc,double dejc,double rm) { // Mise en place de la forme des sources en fontions de nombre de sources ((PlanCatalog)plan).setSourceType(Source.getDefaultType(nb_o)); // Pas de projection associee if( flagXY ) { plan.xyLock=true; plan.error=Plan.NOREDUCTION; // IL FAUDRAIT ICI CALCULER LES PREMIERS xy DE PROJECTION EN FONCTION DE // minRa... // Meorisation des XY originales dans le tableau plan.xy[] ((PlanCatalog)plan).xy = new PointD[nb_o]; for( int i=0; i='a' && c<='z' || c>='A' && c<='Z' || c>='0' && c<='9' || c=='_' ) ) mode=3; break; // Je tente de remplacer le nom de variable par sa valeur case 3: boolean httpEncode=false; if( acco ) startVar++; int length=i-startVar-1; httpEncode=(methode==1); // L'encodage HTTP est demande par parametre // Cas particulier du signe + ou * en debut de nom de variable if( a[startVar]=='+' ) { httpEncode=true; startVar++; length--; } if( a[startVar]=='*' ) { startVar++; length--; } String var = new String(a,startVar,length); int n=getFieldIndex(var); //System.out.println("*** var=["+var+"] n="+n+" value="+(n>=0?value[n]:"null")+" httpEncode="+httpEncode); if( n<0 ) { mode=0; break; } // ici ca plante res.append(httpEncode?URLEncoder.encode(value[n]):value[n]); // prev=acco?i:i-1; mode=0; i--; break; } } res.append(a,prev,a.length-prev); return res.toString(); } boolean [] hiddenField; // Tableau des champs caches (1 pour cache 0 pour ok); boolean firstTrace=true; // Pour afficher la premiere source en cas de trace private int indexOID=-1; // Position de la colonne OID eventuelle /** L'interface AstroRes */ public void setRecord(double ra, double dec, String [] value) { int n; String oid=null; // OID trouve s'il y a lieu try { // Construction de la legende associe a ces sources // uniquement fait a la premiere source (test sur flagFirstRecord) if( flagFirstRecord ) { firstTrace=true; // Pour afficher la premiere source en cas de trace n = vField.size(); Vector v = new Vector(n); // Ne contiendra que les champs conserves // Memorisation des champs caches // et regeneration de la liste des champs conserves hiddenField = new boolean[n]; Enumeration e = vField.elements(); indexOID=-1; for( int i=0; e.hasMoreElements(); i++ ) { Field f = (Field)e.nextElement(); if( f==null ) continue; // Memorisation de l'index du champ OID s'il existe if( indexOID==-1 && f.name!=null && f.name.equals("_OID") ) indexOID=i; if( f.type!=null && (f.type.indexOf("hidden")>=0 || f.type.indexOf("trigger")>=0) || f.name!=null && (f.name.equals("_RAJ2000") || f.name.equals("_DEJ2000")) ) { hiddenField[i]=true; continue; } v.addElement(f); } leg=new Legende(v); flagFirstRecord=false; } // Limite de chargement ? // On agrandi le tableau avec un petit gag sur l'indice de nb_o if( nb_o==o.length ) { nextIndex(); nb_o--; } // Generation de la ligne d'info StringBuffer s; if( catalog.equals("Simbad") ) s = new StringBuffer("<&_SIMBAD |Simbad>"); else if( catalog.equals("NED") || catalog.equals("Ned") ) s = new StringBuffer("<&_NED |NED>"); else s = new StringBuffer("<&_getReadMe "+catalog+" |"+table+">"); // Construction de la ligne des mesures n = value.length; int j=-1; // Veritable index de la mesure (en fonction des champs caches) for( int i=0; i=0 && i==indexOID ) oid=value[i]; if( hiddenField!=null && i"); } else s.append(text); } // Calcul en vue de definir la target if( flagXY || !flagTarget ) { if( ramaxRa ) maxRa=ra; if( decmaxDec ) maxDec=dec; } // Determination de label de la source String lab = ( numId>=0 )?value[numId]:"Source "+nb_o; // Pour le debogage (ATTENTION, n'indique que la premiere source) if( firstTrace ) { Aladin.trace(3,"setRecord "+(oid!=null?"(oid="+oid+")":"")+ " \""+lab+"\" "+(flagXY?"XY":"pos")+ "=("+ra+","+dec+") ["+s+"]"); firstTrace=false; } // Creation de la source, soit en XY, soit en alph,delta Source source; if( flagXY ) source = new Source(plan,ra,dec,0,0,Objet.XY,lab,s.toString(),leg); else source = new Source(plan,ra,dec,lab,s.toString(),leg); if( oid!=null ) source.setOID(oid); o[nb_o++]=(Objet)source; } catch(Exception e) { System.out.println("setRecord (3p) " + e); } } // PEUT ETRE FUSIONNER setTarget() et parseTarget() public void setTarget(String target) { flagTarget = true; // Il sera inutile de calculer le target en fct des donnees double []tmp = parseTarget(target); rajc=tmp[0]; dejc=tmp[1]; rm=tmp[2]; } /** Data access via XML/VOTable * * @@param dis * @@return * @@throws Exception */ private int votableParsing(MyInputStream dis) throws Exception { try { o= new Objet[MAX]; nb_o = 0; catalog=plan.label; table=plan.label; leg=null; flagTarget=false; minRa=minDec = Double.MAX_VALUE; maxRa=maxDec = -Double.MAX_VALUE; hiddenField=null; flagEndResource = false; VOTable res = new VOTable(this); boolean ok = res.parse(dis); if( ok ) { if( !flagEndResource ) endResource(); if( rm == 0.0 ) { plan.error = "no RA or DE rows"; aladin.error = plan.error; } } else { plan.error = "Error: "+res.getError(); aladin.error = plan.error; } if( plan.error!=null ) System.out.println("!!! "+plan.label+": "+plan.error); return ok?nb_o:-1; } catch( Exception e) { System.out.println("votableParsing : " + e); } return -1; } /** * * @@param dis * @@return * @@throws Exception */ private int astroresParsing(MyInputStream dis) throws Exception { o= new Objet[MAX]; nb_o = 0; catalog=plan.label; table=plan.label; leg=null; flagTarget=false; minRa=minDec = Double.MAX_VALUE; maxRa=maxDec = -Double.MAX_VALUE; hiddenField=null; flagEndResource = false; Astrores res = new Astrores(this); boolean ok = res.parse(dis); if( ok ) { if( !flagEndResource ) endResource(); if( !flagXY && rm==0.0 ) { plan.error = "no RA or DE rows"; aladin.error = plan.error; } } else { plan.error = "Error: "+res.getError(); aladin.error = plan.error; } if( plan.error!=null ) System.out.println("!!! "+plan.label+": "+plan.error); return ok?nb_o:-1; } /** Determine le target des donnees en fonction. * en fonction de minRa, maxRa, minDec, maxDec et * met a jour rajc, dejc et rm en fonction */ private void computeTarget() { if( maxRa-minRa>180. ) { double alpha = 360-maxRa; rajc = (minRa+alpha)/2 - alpha; } else rajc = (minRa+maxRa)/2; dejc = (minDec+maxDec)/2; rm = (nb_o==1)?7:Math.abs(minDec-dejc)*60.0*1.4142; Aladin.trace(3,"computeTarget ra=["+minRa+".."+maxRa+"]=>"+rajc+" de=["+minDec+".."+maxDec+"]=>"+dejc+" rm=["+rm+"]"); } // Analyse de la chaine indiquant le target // REMARQUE : Cette procedure a ete ecrite en deux temps trois mouvements, il faudra // ABSOLUMENT la betonner double [] parseTarget(String target) { double [] tmp = new double[3]; StringTokenizer st; boolean neg; st = new StringTokenizer(target,"+-,=/"); try { tmp[0] = Double.valueOf(st.nextToken().trim()).doubleValue(); } catch( Exception e1 ) { } // Determination du signe de la declinaison neg = ( target.lastIndexOf('-')>0 ); try { tmp[1] = Double.valueOf(st.nextToken().trim()).doubleValue(); if( neg ) tmp[1]=-tmp[1]; } catch( Exception e2 ) { } try { st.nextToken(); // On passe sur rm/bm sans s'inquieter tmp[2]=11; tmp[2] = Double.valueOf(st.nextToken().trim()).doubleValue(); if( target.indexOf("bm")>0 ) tmp[2] /= 2; // Une boite } catch( Exception e3 ) { } return tmp; } /** Remplissage d'un Plan de catalogue TSV * @@param plan Le plan d'appartenance * @@param u L'URL d'acces au TSV a analyser * @@return le nombre d'objets ou -1 si probleme */ protected int setPlanCat(Plan plan, URL u) { return setPlanCat(plan,u,null); } /** Remplissage d'un Plan de catalogue TSV * @@param plan Le plan d'appartenance * @@param dis le flux d'acces au TSV a analyser (ou null) * @@return le nombre d'objets ou -1 si probleme */ protected int setPlanCat(Plan plan, MyInputStream dis) { return setPlanCat(plan,null,dis); } /** Remplissage d'un Plan de catalogue TSV * @@param plan Le plan d'appartenance * @@param u L'URL d'acces au TSV a analyser (ou null) * @@param dis le flux d'acces au TSV a analyser (ou null) * @@param flagVOTable true si on est sur a priori que cela va etre du VOTable * @@return le nombre d'objets ou -1 si probleme */ protected int setPlanCat(Plan plan, URL u, MyInputStream dis) { int nb=-1; // Construction et appel de l'URL try { // Deux tentatives... cochonnerie de JAVA if( dis==null ) { try { dis = new MyInputStream(u.openStream()); } catch( Exception efirst ) { dis = new MyInputStream(u.openStream()); } } flagVOTable=(dis.getType() & MyInputStream.VOTABLE)!=0; if( flagVOTable ) nb = votableParsing(dis); else nb = astroresParsing(dis); } catch( Exception e ) { if( aladin.levelTrace==3 ) e.printStackTrace(); aladin.error = "Catalog loading aborted\n --> "+e; System.out.println("!!! "+plan.label+": "+aladin.error); Aladin.warning(aladin.error); nb=-1; } return nb; } // Retourne le prochain index libre dans le tableau des objets int nextIndex() { if( o==null ) { o = new Objet[MAX]; nb_o=0; } if( nb_otrue si trouve, sinon false */ protected boolean delObjet(Objet obj) { int i; // Les sources ne peuvent etre supprimer individuellement if( obj instanceof Source ) return false; // Parcours de tous les objets du plan for( i=0; itrue pour que l'affichage soit effectif, * sinon il n'y aura qu'un simple calcul de position * @@param dx,dy Offset pour le tracage */ protected void Draw(Graphics g, Rectangle r,boolean draw,int dx,int dy) { g.setColor(c); // Projection suivant le plan de base if( plan.type==Plan.CATALOG || plan.type==Plan.TOOL || plan.type==Plan.FIELD ) projection(); // Il s'agit d'un plan qui est cache par une image if( !draw ) return; for( int i=0; i= 2) { StringBuffer t= new StringBuffer(value[nRA]+" "); char ss = value[nDE].charAt(0); if( ss!='-' && ss!='+' ) t.append('+'); t.append(value[nDE]); // sexa or decimal decimal ? boolean flagSexa=isSexa(t.toString()); Coo c = new Coo(); c.set(t.toString(),flagSexa); setRecord(c.lon, c.lat, value); } else if (value.length >= 1) setRecord((new Double(value[nRA])).doubleValue(), 0.0, value); else setRecord(0.0, 0.0, value); } catch(Exception e) { System.out.println("setRecord " + e ); } } /** Return true if the coord is in Sexagesimal format */ private boolean isSexa(String s) { char a[] = s.toCharArray(); int nbb; // Nombre de separateurs int i; for( i=nbb=0; i1 ) return true; } return false; } /** * Set Table data * @@param s1 * @@param s2 */ public void setTableData(String s1, String s2) { } /** * Start Table * @@param table */ public void startTable(SavotTable table) { startTable(table.getName()); } } if( !flagXY && rm==0.0 ) { plan.error = "no RA or DE rows"; aladin.error = plan.error; } } else { plan.error = "Error: "+res.getError(); aladin.error = plan.error; cds/aladin/PlanTool.java010064400076440000132000000120000770227416100161340ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; /** * Plan dedie a des objets graphiques (TOOL) * * @@author Pierre Fernique [CDS] * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public class PlanTool extends Plan { /** Creation d'un plan de type TOOL * @@param label le nom du plan (dans la pile des plans) */ protected PlanTool(Aladin aladin, String label) { this.aladin= aladin; type = TOOL; c = Couleur.getNextDefault(aladin.calque); setLabel(label); pcat = new PlanObjet(this,c,aladin.calque,aladin.status,aladin); flagOk = true; active = true; aladin.calque.unSelectAllPlan(); selected = true; // S'il n'y a pas de plan de reference, on bloque les xy dans l'ecran Plan pref = aladin.calque.getPlanRef(); if( pref==null || pref.projd==null ) xyLock=true; else xyLock=false; } /** Creation d'un plan de type TOOL (pour un backup) */ protected PlanTool(Aladin aladin) { this.aladin= aladin; type = TOOL; c = Couleur.getNextDefault(aladin.calque); pcat = new PlanObjet(this,c,aladin.calque,aladin.status,aladin); flagOk = true; active = true; } /** Bloque ou nom le mode de calcul des x,y des objets. * @@param lock true les objets gardent leurs x,y, sinon false */ protected void setLock(boolean lock) { if( lock ) xyLock=true; else { xyLock=false; pcat.setCoord(); } } /** Retourne l'etat du plan tool (locke ou non). * @@return true les objets gardent leurs x,y, sinon false */ protected boolean lock() { return xyLock; } /** Affiche la ligne d'informations concernant le plan dans le statut d'Aladin*/ protected void getInfo() { String s; if( type==NO ) { super.getInfo(); return; } s = "``"+label+"''"; aladin.status.setText(s); } // Regeneration des libelles des reperes protected void setIdAgain() { for( int i=0; itrue si l'objet est selectionne */ protected boolean select; /** true si la source doit etre affiche avec son label */ protected boolean withlabel; Point vp; // Derniere position calculee de l'objet dans le view int oiz=-1; // numero d'ordre du dernier calcul du zoom /** Creation d'un objet graphique * @@param plan plan d'appartenance de la ligne * @@param x,y position protected Position(Plan plan, double x, double y) { this(plan,x,y,""); } /** Creation d'un objet graphique * @@param plan plan d'appartenance de la ligne * @@param x,y position * @@param id identificateur associe a l'objet graphique protected Position(Plan plan, double x, double y ,String id) { this.id = id; this.plan = plan; this.x = x; this.y = y; setCoord(); } */ /** Creation d'un objet graphique vide (pour les backups) */ protected Position(Plan plan) { this.plan=plan; } /** Creation d'un objet graphique (methode generalisee) * @@param plan plan d'appartenance de la ligne * @@param x,y position XY * @@param raj,dej position RA,DEC * @@param methode masque de bits pour indiquer quels sont les champs qu'on * doit mettre a jour : * XY : la position (x,y) dans les coordonnees de l'image * RADE : la position RA,DEC * RADE_COMPUTE : la position RA,DEC est deduite de XY * en fonction de l'astrometrie courante * XY_COMPUTE : la position XY est deduite de RA,DEC * en fonction de l'astrometrie courante * @@param id identificateur associe a l'objet graphique */ protected Position(Plan plan, double x, double y, double raj, double dej,int methode, String id) { this.id=id; this.plan=plan; if( (methode & XY)!=0 ) { this.x=x; this.y=y; if( (methode & RADE_COMPUTE)!=0 ) setCoord(); } if( (methode & RADE)!=0 ) { this.raj=raj; this.dej=dej; if( (methode & XY_COMPUTE)!=0 ) setXY(); } } // Utilise par les Sources et par les reperes captures Position(Plan plan, String id) { this.id=id; this.x=0; this.y=0; this.plan=plan; } /** Calcul de XY en fonction de radec par la projection par defaut * du plan de reference */ protected void setXY() { if( plan==null) return; Plan ref = plan.aladin.calque.getPlanRef(); if( ref!=null && ref.projd!=null ) projection(ref.projd); } protected void setCoord() { boolean ok=true; if( plan.type==Plan.TOOL && ((PlanTool)plan).lock() ) return; // J'affecte les coordonnees associees a (x,y) par rapport au plan de reference // => A MODIFIER raj=dej=0.0; Plan ref = plan.aladin.calque.getPlanRef(); if( ref!=null && ref.projd!=null ) { Coord c = new Coord(); c.x=x; c.y=y; if( ref.projd.getCoord(c)!=null ) { raj = c.al; dej = c.del; ok=true; } } if( !ok && plan.type==Plan.TOOL ) { ((PlanTool)plan).setLock(true); } } protected void setCoord(Projection proj) { // J'affecte les coordonnees associees a (x,y) Coord c = new Coord(); c.x=x; c.y=y; if( proj.getCoord(c)!=null ) { raj = c.al; dej = c.del; } } static Coord c = new Coord(); // Pour eviter les new inutiles /** Projection de la source => calcul (x,y). * @@param proj la projection a utiliser */ protected void projection(Projection proj) { if( plan!=null && plan.type==Plan.TOOL && ((PlanTool)plan).lock() ) return; c.al = raj; c.del = dej; proj.getXY(c); x = c.x; y = c.y; } /* // Affichage sur sortie standard des infos concernant l'objet void debug() { String s,s1; s=(plan==null)?"null":plan.label; s1=(select)?"[selectionne] ":""; System.out.println("objet \""+id+"\" (appartenant au plan "+s+") "+s1+":"); System.out.println(" .position dans la proj: "+x+","+y); s=(vp==null)?"null":vp.x+","+vp.y; System.out.println(" .position dans la vue : "+s); System.out.println(" .numero d'affichage : "+oiz); } */ /** Retourne le plan d'appartenance de l'objet */ protected Plan getPlan() { return plan; } /** Modification de la position (absolue) * @@param x,y nouvelle position */ protected void setPosition(double x, double y) { this.x = x; this.y = y; oiz=-1; setCoord(); } /** Modification de la position (relative) * @@param dx,dy decalages */ protected void deltaPosition(double dx, double dy) { this.x += dx; this.y += dy; oiz=-1; setCoord(); } /** Modification de l'identificateur * @@param id nouvel identificateur */ protected void setText(String id) { this.id = id; } /** Positionnement du flag de selection * @@param flag true si selectionne, false sinon */ protected void setSelect(boolean flag) { select = flag; } /** premutation du flag de selection */ protected void switchSelect() { select = !select; } /** Retourne Vrai si l'objet est selectionne */ protected boolean isSelect() { return select; } /** Coordonnees dans la vue courante. * Retourne la position dans les coord. de la vue courante. * Memorise l'etat du zoom pour s'eviter du travail ulterieur. * Tolere une marge (dw,dh) de bordure, sinon (-1,-1). * @@param zoomview reference au zoom courant * @@return les coordonnees */ protected Point getViewCoord(ZoomView zoomView,int dw, int dh) { if( zoomView.iz!=oiz ) { vp = zoomView.getViewCoordWithMarge(x,y,dw,dh); oiz = zoomView.iz; } return vp; } /** Test d'appartenance. * Retourne vrai si le point (x,y) de l'image se trouve dans l'objet * @@param x,y le point a tester * @@param z le zoom */ protected boolean inside(double x, double y, double fz) { return false; } /** Test d'appartenance a l'objet * Retourne vrai si le point (x,y) de la vue se trouve sur l'objet * @@param x,y le point a tester * @@param z zoom */ protected boolean in(double x, double y, double z) { return inside(x,y,z); } /** Generation d'un clip englobant. * Retourne un rectangle qui englobe l'objet * @@param zoomview reference au zoom courant * @@return le rectangle enblobant */ protected Rectangle getClip(ZoomView zoomview) { Point p = getViewCoord(zoomview,0,0); if( select ) return new Rectangle(p.x-DS,p.y-DS,1+DDS,1+DDS); else return new Rectangle(p.x,p.y,1,1); } void info(Aladin aladin) {} /** Affichage l'info lie a l'objet * Affiche l'identifacteur dans le statut de l'objet aladin * @@param aladin reference */ protected void status(Aladin aladin) { aladin.status.setText(id); } /** Dessine l'objet * @@param g le contexte graphique * @@param zoomview reference au zoom courant */ protected void draw(Graphics g,ZoomView zoomview,int dx, int dy) { Point p = getViewCoord(zoomview,0,0); if( p.x<0 ) return; g.setColor( plan.c ); p.x+=dx; p.y+=dy; g.drawLine(p.x,p.y,1+dx,1+dy); if( select ) drawSelect(g,zoomview); } // Dessine les poignees de selection de l'objet void drawSelect(Graphics g,ZoomView zoomview) { Rectangle r = getClip(zoomview); int xc=0; int yc=0; // Trace des poignees de selection for( int i=0; i<4; i++ ) { switch(i ) { case 0: xc=r.x; yc=r.y+r.height-DS; break; // coin IG case 1: xc=r.x; yc=r.y; break; // coin SG case 2: xc=r.x+r.width-DS; yc=r.y; break; // coin SD case 3: xc=r.x+r.width-DS; yc=r.y+r.height-DS; break; // coin ID } g.setColor( Color.green ); g.fillRect( xc+1,yc+1 , DS,DS ); g.setColor( Color.black ); g.drawRect( xc,yc , DS,DS ); } } } cds/aladin/Projection.java010064400076440000132000000335540770227416100165410ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.astro.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Classe gerant les projections associees au plan * * @@author Pierre Fernique [CDS] * @@version 1.1 : 20 aout 2002 - Gros bidouillage en lien avec FrameNewCalib * et Calib * @@version 1.1 : 28 mai 99 - Integration de la projection WCS * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Projection { // Les constantes static final int NO =0; static final int ALADIN =1; static final int WCS =2; static final int SIMPLE =3; static final int QUADRUPLET=4; static final String [] NAME = { "-", "Aladin reduction", "WCS reduction", "Simple reduction","Matching star red." }; // Les parametres de la projection protected double raj,dej; /* Centre de l'image (J2000)*/ protected double alphai,deltai; /* Centre de la projection (J2000)*/ protected double cx,cy; /* Pixels correspondants */ /** diametre/largeur du champ (arcmin) */ protected double rm; /** Centre de la projection (pixels) */ protected double r; protected double rot; // rotation en degres (sens horaire / nord ) protected boolean sym; // symetrie ? protected int t; // type de la projection (SIN|TAN...) /** Facteur d'echelle */ protected double fct; /** mode de projection (NO,ALADIN,WCS); */ protected int type; String label=null; Coord coo[]; // Liste de quadruplets pour methode QUADRUPLET // Caracterisation de la projection Calib c; // Calibration Aladin s'il y a lieu, null sinon /** Creation d'une projection. * * @@param label label de la projection * @@param type type de la projection (mode ALADIN|WCS...) * @@param alphai,deltai centre de la projection (J2000 en degres) * @@param rm diametre/largeur du champ (arcmin) * @@param cx,cy Centre de la projection (pixels) * @@param r Facteur d'echelle * @@param rot Rotation (degre / nord) * @@param sym Symetrie RA * @@param t Type de la projection mathematique (TAN|SIN...) */ protected Projection(Projection p) { c=p.c; adjustParamByCalib(c); // modify(p.label,p.type,p.alphai,p.deltai,p.rm,p.cx,p.cy,p.r,p.rot,p.sym,p.t); } /* * Creation d'une projection en fonction des parametres standards * @@param label label de la projection * @@param type type de la projection (mode ALADIN|WCS...) * @@param alphai,deltai centre de la projection (J2000 en degres) * @@param rm diametre/largeur du champ (arcmin) * @@param cx,cy Centre de la projection (pixels) * @@param r Facteur d'echelle * @@param rot Rotation (degre / nord) * @@param sym Symetrie RA * @@param t Type de la projection mathematique (TAN|SIN...) */ protected Projection(String label,int type, double alphai, double deltai, double rm, double cx, double cy,double r, double rot,boolean sym,int t) { c=new Calib(alphai,deltai,cx,cy,r,rm,rot,t,sym); adjustParamByCalib(c); this.type=type; this.label=label; if( this.label==null ) this.label = getName(type,t); // modify(label,type,alphai,deltai,rm,cx,cy,r,rot,sym,t); } /* * Creation d'une projection en fonction d'une Calibration * @@param type type de la projection (mode ALADIN|WCS...) * @@param c Calibration */ protected Projection(int type,Calib c) { /* label = getName(type,0); this.type=type; this.c=c; this.rot=0; this.sym=false; this.t=1; */ this.c=c; adjustParamByCalib(c); this.type=type; label = getName(type,0); //System.out.println("Proj calib: "+this.toString()); } protected void modify(String label,int type, double alphai, double deltai, double rm, double cx, double cy,double r, double rot,boolean sym,int t) { c=new Calib(alphai,deltai,cx,cy,r,rm,rot,t,sym); adjustParamByCalib(c); this.type=type; if( label==null ) label = getName(type,t); this.coo = null; /* if( label==null ) label = getName(type,t); this.label=label; this.type=type; raj=this.alphai=alphai; dej=this.deltai=deltai; this.rm=rm; this.cx=cx; this.cy=cy; this.r=r; this.rot=rot; this.sym=sym; this.t=t; this.coo = null; */ //System.out.println("Proj: "+this.toString()); } /** Retourne le type de projection (géré par Calib) * en fonction du rayon * @@param radius rayon en degres * @@return le type de projection */ static protected int getDefaultType(double radius) { return radius<2.?1: // TANGENTIAL radius<60.?4: // ZENITAL_EQUAL_AREA 3; // AITOFF } /** Modification de la projection par recalibration au moyen * d'une liste de quadruplets (x,y,alpha,delta) */ protected void modify(String label,Coord coo[]) { if( label==null ) label = getName(type,t); this.label=label; this.type=QUADRUPLET; this.coo=coo; for( int i=0; iw)?h*60:w*60; rm = (int)(rm*10)/10.; r=c.getImgSize().width; rot=c.getProjRot(); sym=c.getProjSym(); t=c.getProjSys(); } /** Modification de la projection pour MRCOMP * @@param scale facteur d'echelle * @@param cx,cy nouveau centre en pixel * @@param xpix,ypix largeur en pixel */ protected void resize(int scale) { try { c = c.resize(scale); } catch( Exception e) { return; } adjustParamByCalib(c); } protected void resize(int scale,double cx, double cy , int xpix, int ypix) { c = c.resize(scale,cx,cy,xpix,ypix); adjustParamByCalib(c); } /** Modification de la projection par flip horizontal ou vertical * @@param methode 0 Haut/Bas, 1 Gauche/Droite, 2 les deux */ protected void flip(int methode) { if( methode==0 || methode==2 ) c = c.flipBU(); if( methode==1 || methode==2 ) c = c.flipRL(); adjustParamByCalib(c); } public String toString() { return label+"("+type+":"+t+")"+ round(alphai)+","+round(deltai)+"=>"+((int)cx)+","+((int)cy)+" "+ rm+"/"+r+" "+ (rot!=0.?"rot="+rot+"deg ":"")+ (sym?"RA_symetry ":""); } /** Retourne true si la projection peut etre modifiable */ protected boolean isModifiable() { return type==SIMPLE || type==QUADRUPLET || type==WCS; } /** Retourne le nom de la projection * @@param type mode de la projection * @@param t methode de la projection * @@return nom de la projection */ static protected String getName(int type,int t) { return type==SIMPLE?Calib.getProj()[t]:NAME[type]; } /** Arrondi. * Applique au centre de la projection pour permettre les superpositions * legerement decalees (lors de l'interrogation) * @@param x la valeur a arrondir * @@return la valeur arrondie */ static protected double round(double x) { return Math.ceil(x*10)/10; } /** Positionnement d'une calibration Aladin * @@param c La calibration aladin qu'il faut associe a la projection protected void setCalib(Calib c) { this.c = c; } */ /** Test de ``superposabilite'' de deux projections. * Retourne vrai si la projection passee en parametre est compatible * avec l'objet projection * @@param p la projection a comparer avec la projection courante * @@param z zoom courant * @@return true c'est ok - false c'est mauvais */ protected boolean agree(Projection p,double z) { if( p==null ) return false; // La meme projection if( this==p ) return true; // La distance entre les deux centres d'images // doit etre inferieure a la somme de deux demi tailles*sqrt(2) Coord c1 = new Coord(); c1.al=p.raj; c1.del=p.dej; //System.out.println("Centre 1 : "+Coord.getSexa(c1.al,c1.del)); Coord c2 = new Coord(); c2.al=raj; c2.del=dej; //System.out.println("Centre 2 : "+Coord.getSexa(c2.al,c2.del)); double dist = Coord.getDist(c1,c2); //System.out.println("p.rm="+Coord.getUnit(p.rm/120)+" rm="+ Coord.getUnit(rm/120)); double somme = (rm+p.rm)*Math.sqrt(2)/120; if( z<1 ) somme/=z; //System.out.println("La distance entre les deux centres est de : "+Coord.getUnit(dist)); //System.out.println("La somme des deux demi-tailles est de : "+Coord.getUnit(somme)); //System.out.println("Projection "+(dist<=somme?"possible":"refusee")); return dist<=somme; } /** Retourne les coordonnees J2000 du x,y en fonction de la projection. * @@param coo position dans la projection (x,y doivent y etre renseignes) * @@return les coordonnees (class Coord) ou null si pb */ protected Coord getCoord(Coord coo) { try{ c.GetCoord(coo); } catch( Exception e ) { coo.al=coo.del=0.0; } return coo; } /** Retourne les x,y en fonction des coord et de la projection. * @@param coo position dans la projection (alphai,deltai doivent y etre renseignes) * @@return les coordonnees (class Coord) ou null si pb */ protected Coord getXY(Coord coo) { c.GetXY(coo); return coo; } } J2000)*/ protected double cx,cy; /* Pixels correspondants */ /** diametre/largeur du champ (arcmin) */ protected double rm; cds/aladin/Properties.java010064400076440000132000000716140770227416100165600ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import cds.astro.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion des fenetres des proprietes associees aux plans. * * @@author Pierre Fernique [CDS] * @@version 1.2 : (20 aout 2002) Edition de l'astrometrie * @@version 1.1 : (11 mai 99) Correction bug xylock!=null * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Properties extends Frame { static String SEEFITS = "Get header"; static String NEWCALIB = "New..."; static String MODCALIB = "Edit..."; static String TOPBOTTOM = "Top/Bottom"; static String RIGHTLEFT = "Right/Left"; // Les references aux objets Aladin aladin; Plan plan; // Les composantes de l'objet Panel panel; // Le panel de la frame PlanFree pmemo=null; // un plan (bidon) pour memoriser les caracteristiques courantes int hcmemo=0; // Memorisation du hashcode du plan memorise boolean flagHide=true; // Vrai si la fenetre est cache // Memorisation temporaire TextField label; // Le label du plan Couleur couleur=null; // La couleur Choice sourceType=null; // Le type de representation graphique CheckboxGroup state=null; // Etat actif/non-active Checkbox viewableCb, hiddenCb;// Checkboxs pour le CheckboxGroup state CheckboxGroup xyLock=null; // Pour le plan TOOl, mode de calcul des x,y Choice planRefChoice=null; // Projections possibles pour le plan de reference Plan planRef[]=null; // Tableau associe a projsChoice Choice projsChoice=null; // Plan de projections possibles Projection projs[]=null; // Tableau associe a planRefChoice Button modCalib=null; // Button de modification de la Calib TextField centerField=null; // Pour le plan FIELD, centre du champ String sField=null; // Pour savoir si centerField a ete modifie TextField rollField=null; // Pour le plan FIELD, rotation du FOV TextField eqField=null; // Pour pouvoir modifier l'equinox par defaut String sEquinox=null; // Pour savoir si l'equinox par defaut a ete modifie String sRoll=null; // Pour savoir si rollField a ete modifie Checkbox cbT=null; // Pour plan ADD, controle Target Checkbox cbS=null; // Pour plan ADD, controle Scale Checkbox cbG=null; // Pour plan ADD, controle Grid Checkbox[] contoursCB; // Pour PlanContour, pour pouvoir visualiser ou cacher les contours Couleur[] contoursCouleurs; // Pour PlanContour, pour choisir la couleur de chaque contour Curseur curs = null; // Pour PlanContour, permet de changer la valeur des niveaux Panel panelCont; Panel panelScroll; ScrollPane scroll; /** Creation du Frame donnant les proprietes du plan. * @@param aladin Reference */ protected Properties(Aladin aladin) { super("Properties"); setBackground(Aladin.BKGD); this.aladin = aladin; // Pour contourner le bug sous Linux/KDE/ super.show(); if( !Aladin.LSCREEN ) move(400,300); else move(800,400); super.hide(); } // met à jour l'état du plan lorsqu'on n'a pas besoin de reconstruire tout le panel private void majState(Plan p) { // maj de viewable/hidden if( p==null ||hiddenCb==null || viewableCb==null ) return; hiddenCb.setState(!p.active); viewableCb.setState(p.active); } // Initialisation d'un Panel en fonction d'un plan void showProp(Plan p) { flagHide=false; if( pmemo!=null && hcmemo==p.hashCode() && pmemo.equals(p) ) { if( isShowing() ) return; majState(p); show(); return; } // On compare le type du precedent plan pour eviter un pack() boolean noPack = (pmemo!=null && pmemo.type==p.type && pmemo.flagOk==p.flagOk && pmemo.projd==p.projd); // On memorise les caracteristiques du plan afin de pouvoir // effectuer des comparaisons ulterieurement pmemo=new PlanFree(aladin); pmemo.objet= (p.objet==null)?null:new String(p.objet); pmemo.type = p.type; pmemo.param = (p.param==null)?null:new String(p.param); pmemo.error = (p.error==null)?null:new String(p.error); pmemo.flagOk = p.flagOk; pmemo.projd = p.projd; hcmemo = p.hashCode(); // On memorise au niveau abstrait plan = p; // On remet a null ce qui est necessaire sourceType=null; state=null; couleur=null; sField=sEquinox=null; eqField=rollField=null; if( panel!=null ) remove(panel); panel = new Panel(); panel.setLayout( new BorderLayout(5,5) ); Label titre = new Label("Properties of the plane ``"+plan.label+"''",Label.CENTER); titre.setFont( Aladin.LBOLD ); Aladin.makeAdd(panel,titre,"North"); Aladin.makeAdd(panel,propertiesPlan(),"Center"); Aladin.makeAdd(panel,valid(),"South"); Aladin.makeAdd(this,panel,"Center"); if( !noPack ) pack(); show(); } /** Maj de la fenetre des Properties en fonction de l'etat du * bouton PROP de la toolbar et du plan courant */ protected void majProp() { int n=aladin.calque.getFirstSelected(); // les PlanFilter ne sont pas gérés par Properties if( n>=0 && aladin.calque.plan[n].type==Plan.FILTER ) return; if( aladin.toolbox.tool[ToolBox.PROP].mode==Tool.DOWN ) { ///int n=aladin.calque.getFirstSelected(); if( n>=0 && aladin.calque.plan[n].type!=Plan.FILTER ) { showProp(aladin.calque.plan[n]); return; } } if( !flagHide ) hide(); } /* // Un peu d'espace autour du panel public Insets insets() { Insets i = super.insets(); i.bottom+=5; i.left+=5; i.right+=5; i.top+=5; return i; } */ /** Ajoute un filet et passe a la ligne * @@param p Le panel sur lequel on travaille * @@param g Le gestionnaire d'affichage * @@param c les contraintes courantes sur le gestionnaire d'affichage */ protected static void addFilet(Panel p, GridBagLayout g, GridBagConstraints c) { Filet f = new Filet(); c.gridwidth = GridBagConstraints.REMAINDER; g.setConstraints(f,c); p.add(f); } /** Construction du panel des boutons de validation * @@return Le panel contenant les boutons Apply/Close */ protected Panel valid() { Panel p = new Panel(); p.setLayout( new FlowLayout(FlowLayout.CENTER)); p.setFont( Aladin.LBOLD ); p.add( new Button("Apply")); p.add( new Button("Close")); return p; } /** Ajoute dans le Panel un couple d'elements titre: valeur * @@param p Le panel sur lequel on travaille * @@param titre Le titre de l'element que l'on va ajouter * @@param valeur L'element (Component) a ajouter * @@param g Le gestionnaire d'affichage * @@param c Les contraintes courantes sur le gestionnaire d'affichage */ protected static void addCouple(Panel p, String titre, Component valeur, GridBagLayout g, GridBagConstraints c) { Label l = new Label(titre); l.setFont(Aladin.ITALIC); c.gridwidth = GridBagConstraints.RELATIVE; c.weightx = 0.0; g.setConstraints(l,c); p.add(l); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; g.setConstraints(valeur,c); p.add(valeur); } /** Construction du panel des proprietes du plan courant. * @@return Le panel des proprietes du plan courant */ protected Panel propertiesPlan() { GridBagConstraints c = new GridBagConstraints(); GridBagLayout g = new GridBagLayout(); c.fill = GridBagConstraints.BOTH; // J'agrandirai les composantes Panel p = new Panel(); p.setLayout(g); // le label associe au plan label = new TextField(plan.label,15); addCouple(p, "Label:", label, g,c); //La couleur if( plan.type!=Plan.IMAGE && plan.type!=Plan.FOLDER && !(plan instanceof PlanContour)) { couleur = new Couleur(plan.c); addCouple(p,"Color:", couleur, g,c); } // couleur du plan contour if( plan instanceof PlanContour) { couleur = new Couleur(((PlanContour)plan).couleursBase,plan.c,25,4); addCouple(p,"Color:", couleur, g,c); } // Affichage de l'etat if( !plan.flagOk ) { Label l = new Label(); String titre; l.setForeground( Color.red ); l.setFont(Aladin.BOLD); if( plan.error!=null ) { titre = "Error:"; l.setText(plan.error); } else { titre = "State:"; l.setText("Plane under construction..."); } addCouple(p,titre, l, g,c ); } if( plan.flagOk ) { // Les sourceType du Plan et le nombre d'elements if( plan.type==Plan.CATALOG ) { sourceType = new Choice(); for( int i=0; i0 ) addCouple(p,"Info:", new Label(pimg.survey()), g,c); // Format d'image Label fmtl = new Label(PlanImage.describeFmtRes(pimg.fmt,pimg.res)); // Bouton de recuperation de visualisation du header FITS if( pimg.headerFits!=null ) { Panel fmtp = new Panel(); fmtp.add(fmtl); fmtp.add( new Button(SEEFITS) ); addCouple(p,"Format:", fmtp, g,c); } else addCouple(p,"Format:", fmtl, g,c); // Info d'image if( plan.flagOk && plan.projd!=null ) { double ep = plan.projd.c.GetEpoch(); if( ep!=0.0 ) { ep= (int)(ep*1000)/1000.0; addCouple(p,"Epoch:", new Label(""+ep), g,c); } double eq = plan.projd.c.GetEquinox(); if( eq!=0.0 ) { eq= (int)(eq*1000)/1000.0; addCouple(p,"WCS equinox:", new Label(""+eq), g,c); // On autorise la modification de l'equinoxe par defaut } else { sEquinox="2000.0"; // IL FAUDRA FAIRE PLUS MALIN eqField = new TextField(sEquinox); addCouple(p,"WCS equinox:", eqField, g,c); } Dimension d = plan.projd.c.getImgSize(); addCouple(p,"Size:", new Label(d.width+"x"+d.height+" pixels"), g,c); } } // Origine if( plan.from!=null ) { addCouple(p,"Origin:", new Label(plan.from), g,c); } // Gestion du plan de reference et de la projection associee if( plan.flagOk && (plan.type==Plan.IMAGE || plan.type==Plan.CATALOG) ) { addFilet(p,g,c); Label l = new Label(plan.type==Plan.IMAGE?"Astrometrical reduction": plan.xyLock?"XY to coordinates reduction":"Projection"); l.setFont(Aladin.BOLD); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; g.setConstraints(l,c); p.add(l); // Les plans de reference possibles pour le plan planRefChoice=null; majPlanRef(); if( plan.type!=Plan.IMAGE && !plan.xyLock) { addCouple(p," .on plane ", planRefChoice, g,c); } // Les projections possibles pour le plan de reference courant projsChoice=null; Button n = new Button(NEWCALIB); modCalib = new Button(MODCALIB); majProjs(); if( projsChoice.countItems()==0 ) { projsChoice.addItem("-- none --"); } Panel projsP = new Panel(); projsP.add(projsChoice); projsP.add(n); projsP.add(modCalib); addCouple(p," .method ", projsP, g,c); // Gestion des flips if( plan.type==Plan.IMAGE && !(plan instanceof PlanImageRGB)) { addFilet(p,g,c); l = new Label("Flipflop methods"); l.setFont(Aladin.BOLD); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; g.setConstraints(l,c); p.add(l); Panel pFlip = new Panel(); pFlip.setLayout( new FlowLayout(FlowLayout.LEFT) ); pFlip.add( new Button(TOPBOTTOM) ); pFlip.add( new Button(RIGHTLEFT) ); addCouple(p,"", pFlip, g,c); } } addFilet(p,g,c); return p; } // Mise-a-jour des plans de reference possibles pour le plan // maj de planRef[] et planRefChoice private void majPlanRef() { int j=0; planRef = plan.getAvailablePlanRef(); if( planRefChoice==null ) planRefChoice = new Choice(); planRefChoice.removeAll(); if( planRef.length>0 ) { for( int i=0; i=0 ) { pref = planRef[planRefChoice.getSelectedIndex()]; projs = pref.getAvailableProj(); } else { //System.out.println("bug catched"); } } if( projsChoice==null ) projsChoice = new Choice(); projsChoice.removeAll(); // modif Thomas if( projs!=null && pref!=null && projs.length>0 ) { for( int i=0; i=0 && projs[j].isModifiable() ); } else modCalib.setEnabled(false); } // Changement de plan de ref et/ou de projection en fonction // des choix dans planRefChoice et projsChoice private void actionPlanRefProjs() { // thomas : correction d'un bug : // ArrayIndexOutOfBounds -1 dans actionPlanRefProjs // quand on apply un filtre au bout d'un moment // je ne suis pas sur que ce soit la bonne solution, à voir avec pierre if( planRefChoice.getSelectedIndex() < 0 || projsChoice.getSelectedIndex() < 0) { //System.out.println("The bug was catched"); return; } Plan pref = planRef[planRefChoice.getSelectedIndex()]; boolean flagAction=false; if( !pref.ref ) { Aladin.trace(2,"New reference plane => "+pref.label); aladin.calque.setPlanRef(pref); majProjs(); flagAction=true; } // pour éviter un ArrayIndexOutofBoundsException // je ne suis pas sur que ce soit la bonne solution if( projsChoice.getSelectedIndex() < 0) return; Projection p = projs[projsChoice.getSelectedIndex()]; if( pref.projd!=p ) { Aladin.trace(2,"New proj. method for plane "+pref.label+" => "+p.label); pref.projd=p; flagAction=true; } if( !flagAction ) return; plan.flagProj=false; aladin.calque.view.newView(); aladin.calque.repaint(); majPlanRef(); majProjs(); } private void apply() { plan.label = label.getText(); if( planRefChoice!=null ) actionPlanRefProjs(); if( couleur!=null ) { if (! (plan instanceof PlanContour)) plan.c = couleur.getCouleur(); } // Affichage ou non du plan if( state!=null ) { boolean etat = state.getCurrent().getLabel().equals("viewable"); if( etat && !plan.isViewable() ) { aladin.calque.setPlanRef(plan); } plan.active=etat; } if( plan instanceof PlanContour) { int i; PlanContour pCont = (PlanContour)plan; // a remplacer par un appel ou on passe le tableau des niveaux et basta // vérifier la cohérence des couleurs for (i=0;i1) { int i = projsChoice.getSelectedIndex(); modCalib.setEnabled(projs[i].isModifiable()); if( plan.xyLock ) { plan.pcat.setCoord(projs[i]); aladin.view.repaint(); } else apply(); return true; } //Changement de plan de reference if( evt.target==planRefChoice ) { apply(); // Cancel } else if( "Close".equals(what) ) hide(); // Flip Top/Bottom else if( TOPBOTTOM.equals(what) ) ((PlanImage)plan).flip(0); // Flip Right/Left else if( RIGHTLEFT.equals(what) ) ((PlanImage)plan).flip(1); // Creation d'une nouvelle calib else if( NEWCALIB.equals(what) ) { Plan p = plan.xyLock?plan:aladin.calque.getPlanRef(); if( aladin.frameNewCalib==null ) { aladin.frameNewCalib = new FrameNewCalib(aladin,p,null); } else aladin.frameNewCalib.majFrameNewCalib(p); // Modification d'une calib }else if( MODCALIB.equals(what) ) { Plan p = plan.xyLock?plan:aladin.calque.getPlanRef(); if( aladin.frameNewCalib==null ) { aladin.frameNewCalib = new FrameNewCalib(aladin, p,projs[projsChoice.getSelectedIndex()]); } else aladin.frameNewCalib.majFrameNewCalib(p, projs[projsChoice.getSelectedIndex()]); // Submit PLAN } else if( "Apply".equals(what) ) apply(); // Visualisation du header fits else if( SEEFITS.equals(what) ) ((PlanImage)plan).headerFits.seeHeaderFits(); return true; } /** Cache la fenetre des Properties et remonte le bouton * des properties */ public void hide() { flagHide=true; aladin.toolbox.tool[ToolBox.PROP].mode=Tool.UP; aladin.toolbox.toolMode(); aladin.toolbox.repaint(); super.hide(); } // Gestion des evenement public boolean handleEvent(Event e) { // On supprime le frame if( e.id==Event.WINDOW_DESTROY ) hide(); return super.handleEvent(e); } } OLD); c.gridwidth = GridBagConstraints.REMAINDER; c.weightx = 1.0; g.setConstraints(cds/aladin/RectangleD.java010064400076440000132000000063770770227416100164400ustar00ferniquecds00000400000013// // Copyright 1992-2003 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; /** * Manipulation d'un Rectangle en coordonnees reelles * * @@author Pierre Fernique [CDS] * @@version 1.0 : (30 juillet 2002) creation */ public class RectangleD { protected double X,Y,W,H; protected RectangleD(double x, double y, double w, double h) { X=x; Y=y; W=w; H=h; } /** Return true if (x,y) is in the rectangle */ protected boolean inside(double x, double y) { return x>=X && x<=X+W && y>=Y && y<=Y+H; } } cds/aladin/Repere.java010064400076440000132000000164010770227416100156370ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Objet graphique representant un repere * * @@author Pierre Fernique [CDS] * @@version 1.2 : (1 dec 00) Gestion des differents graphismes * @@version 1.1 : (27 avril 00) Suppression des ':' pour le notePad * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public class Repere extends Position { static final int DEFAULT=0; // Graphisme par defaut (croix simple) static final int TARGET=1; // Graphisme pour un target (croix evidee) int L = 5; // demi-taille du repere int dw,dh; // mesure du label int type=DEFAULT; // Type de graphisme /** Creation d'un repere graphique sans connaitre RA/DE. * @@param plan plan d'appartenance de la ligne * @@param x,y position */ protected Repere(Plan plan, double x, double y) { super(plan,x,y,0,0,XY|RADE_COMPUTE,null); // withlabel=true; // Enregistrement dans le blocnote des mesures // en remplacant les ':' par des ' ' char [] a = id.toCharArray(); for( int i=0; itrue c'est bon, false sinon */ protected boolean inside(double x, double y, double z) { double l=L/z; return(this.x<=x+l && this.x>=x-l && this.y<=y+l && this.y>=y-l); } /** Generation d'un clip englobant. * Retourne un rectangle qui englobe l'objet * @@param zoomview reference au zoom courant * @@return le rectangle enblobant */ protected Rectangle getClip(ZoomView zoomview) { Rectangle r; Point p = getViewCoord(zoomview,L,L); if( select ) r = new Rectangle(p.x-L-DS,p.y-L-DS,L*2+DDS,L*2+DDS); else r = new Rectangle(p.x-L,p.y-L,L*2,L*2); if( withlabel ) r = r.union(new Rectangle(p.x-dw/2,p.y-L-1-dh-1,dw,dh)); return r; } /** Affiche le repere * @@param g le contexte graphique * @@param zoomview reference au zoom courant */ protected void draw(Graphics g,ZoomView zoomview,int dx, int dy) { Point p = getViewCoord(zoomview,L,L); if( p.x<0 ) return; p.x+=dx; p.y+=dy; if( plan!=null ) g.setColor( type==TARGET?plan.aladin.calque.plan[0].c:plan.c ); switch(type) { case DEFAULT: g.drawLine(p.x-L, p.y, p.x+L, p.y); g.drawLine(p.x, p.y-L, p.x, p.y+L); break; case TARGET: g.drawLine(p.x-L, p.y, p.x-3, p.y); g.drawLine(p.x+3, p.y, p.x+L, p.y); g.drawLine(p.x, p.y-L, p.x, p.y-3); g.drawLine(p.x, p.y+3, p.x, p.y+L); break; } if( withlabel ) g.drawString(id,p.x-dw/2,p.y-L-1); if( select ) drawSelect(g,zoomview); } } cds/aladin/ResourceNode.java010064400076440000132000000156520770227416100170210ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // /**

Title : ResourceNode

*

Description : Node of a MetaDataTree

*

Copyright: 2002

*

Company: CDS

* @@author Thomas Boch * @@version 0.5 : 27 Novembre 2002 (Creation) */ package cds.aladin; import java.util.Hashtable; import java.awt.Color; public class ResourceNode extends BasicNode implements Cloneable { // VOID : rien // IMAGE : ressource image (noeud ou feuille) // CAT : ressource catalogue (noeud ou feuille) static final int VOID = 0; static final int IMAGE = 1; static final int CAT = 2; // IMAGE, CAT ou VOID, VOID par defaut int type = VOID; // description du catalogue String catDesc; // formats disponibles (JPEG, FITS, ...) String[] formats; String curFormat; // si != null, couleur des fov des fils Color col; Fov fov = null; boolean cutout=false; // target du centre du cutout // ATTENTION : sert également pour les catalogues !! private String cutoutTarget; // serveur d'où proviennent les ressources Server server; // location to access the resource String location; String resol; // résolution de l'image String survey; String color; String epoch; // si epoch!=null, on est dans la config. nouveau serveur String machine; // champ spécifique pour bidouille section SIAP dans XML String plateNumber; // numéro de plaque pour images DSS String[] description; // e.g: survey, color, position, ... String[] explanation; // e.g: GOODS, ISAAC-J, 53 -27, ... String[] filterDesc=null; String[] filterExpla=null; String criteria; String valueCriteria; // critères de tri applicables sur les sous-noeuds String[] sortCriteria=null; // map des valeurs des critères Hashtable criteriaVal=null; ResourceNode() { super(); } // constructeur par recopie // /!\ ATTENTION : ce constructeur ne recopiera pas les enfants ResourceNode(ResourceNode n) { super(n); this.type = n.type; this.catDesc = n.catDesc; this.col = null; this.fov = n.fov; this.cutout = n.cutout; this.survey = n.survey; this.color = n.color; this.epoch = n.epoch; this.resol = n.resol; this.machine = n.machine; this.plateNumber = n.plateNumber; this.description = n.description; this.explanation = n.explanation; this.filterDesc = n.filterDesc; this.filterExpla = n.filterExpla; this.sortCriteria = n.sortCriteria; this.criteriaVal = n.criteriaVal; this.criteria = n.criteria; this.valueCriteria = n.valueCriteria; this.location = n.location; this.server = n.server; this.cutoutTarget = n.cutoutTarget; this.formats = n.formats; this.curFormat = n.curFormat; } ResourceNode(String name) { super(name); } ResourceNode(String name, boolean isOpen, boolean isLeaf) { super(name, isOpen, isLeaf); } // clone the object public Object clone() { ResourceNode o = null; try { o = (ResourceNode)super.clone(); } catch(Exception e) { System.err.println("Can't clone !!"); e.printStackTrace(); } // clone des children o.children = new java.util.Vector(); o.nbChildren = 0; for( int i=0; i0 ) { cutoutTarget = t; // on teste si la FrameInfo courante affiche les infos de this if( updateInfo && FrameInfo.getInstance().getNode()!=null && FrameInfo.getInstance().getNode().equals(this) ) { FrameInfo.getInstance().setTargetTF(t); } } } public String getCutoutTarget() { return cutoutTarget; } } older. // // ----------- // // Conformement aux conventions icds/aladin/Select.java010064400076440000132000001060630770227416100156400ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion de la pile des plans * * @@author Pierre Fernique [CDS] * @@version 1.2: (11 fev 2003) autre methode de blink (JVM 1.4) * @@version 1.1: (29 octobre 2002) scrollbar + folder + filter * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.91 : revisite le 25 nov 1998 * @@version 0.9 : (??) creation */ public final class Select extends Canvas implements Runnable { // Les definitions statiques static final String HELP_STACK = "Plane stack - click to see/mask it, or drag it to change its position"; static final String HELP_EYE = "Eye view - click to activate all available planes"; static final String HELP_REFIN = "Reference selector - indicate the current reference projection"; static final String HELP_REFOUT= "Reference selector - click on it to select; this image as the new reference projection"; static final String WAITMIN = "Please be patient...\nThis plane is under construction !"; static final String NOPROJ = "These planes cannot be superimposed.\n"+ "Regions do not overlap !"; // Les references aux autres objets Aladin a; Target target; // Pour des problemes de references croisees // Le menu Popup PopupMenu popMenu; // Les parametres a memoriser Vector slides=null; // la liste des slides courants static boolean firstEye=true; // Vrai si l'oeil a deja ete calcule boolean flagDrag = false; // Vrai si on drag Plan currentPlan=null; // Plan en cours de manipulation int x,y; // Derniere position de la souris int oldy; // Pour pouvoir tester la distance minimal de 4 pixels Polygon logo; // Logo en cours de deplacement Rectangle r; // Clip en cas de repaint (eye, blink) boolean flagRClip; // Vrai si le clip "r" doit etre utilise int oldxDrag,oldyDrag; // Derniere position du polygone boolean clinDoeil=false; // Vrai si je dois faire un clin d'oeil Thread clin=null; // Thread d'attente pour le clin d'oeil boolean flagShift; // Vrai si le mouseDown etait avec le Shift Plan newRef=null; // !=null si on est entrain de changer de ref. Plan planIn=null; // si !=null, dernier plan sous la souris private int popX=0, popY=0; // si !=0 demande affichage du popup a l'emplacement Thread thread = null; // thread pour pour le clignotement // Les valeurs accociees aux differents elements graphiques static final int sizeLabel = 106-MyScrollbar.LARGEUR; // Nbre de pixels pour les labels static final int gapL = 11; // Marge de gauche (reserve pour le triangle) static final int gapB = 5; // Marge du bas static final int DX = 35; // Largeur du logo // L'icone du calque static final int [] frX = { 6+gapL, 0+gapL, DX+gapL, DX-6+gapL, 6+gapL }; static final int [] frY = { 1, 14, 14, 1, 1 }; static final int frMin = frX[1]; // Limite inf. de l'icone (en abs) static final int frMax = frX[2]; // Limite sup. de l'icone (en abs) static final int m = (frX[2]+frX[1])/2; // Le centre de la pile des calques // L'oeil (sourcil - ext - int - pupille) static int [] o1x = { 0,10,22,36,36,22,10, 0,0 }; // Sourcil static int [] o1y = { 6, 2, 0, 8,11, 3, 5,10,6 }; static int [] o2x = { 2, 3,12,18,24,32,36,36,32,18, 6, 2, 2 }; // Exterieur de l'oeil static int [] o2y = { 18,18,12,10,12,18,20,24,22,24,20,22,18 }; static int [] o3x = { 6,16,22,28,30,18, 6 }; // Interieur de l'oeil static int [] o3y = { 18,12,14,19,19,21,18 }; static int o4d = o3y[5]-o2y[3]; // Taille (hors tout) de la pupille static int o4xc = o2x[3]-o4d/2; // Abscisse du centre de la pupille static int o4yc = (o2y[3]+o3y[5])/2-o4d/2; // Ordonnee du centre de la pupille static int eyeWidth=o1x[3]; // Largeur static int eyeHeight=o2y[7]; // Hauteur // Les variables de gestion du graphisme int ws=frMax+sizeLabel; // Largeur du canvas (doit etre divisible par ViewZoom.WENZOOM) int hs; // Hauteur du canvas int hsp; // Hauteur de la portion pour les plans Image img; // Image du buffer du paint Graphics g; // GC du buffer du paint /** Creation de l'interface de la pile des plans. * @@param calque,aladin References */ protected Select(Calque calque,Aladin aladin) { this.a = aladin; // Calcule des tailles hs=Aladin.LSCREEN?291:200; // Hauteur du canvas hsp= hs-eyeHeight-gapB; // Hauteur de la portion pour les plans resize(ws,hs); createPopupMenu(); } MenuItem menuShow,menuSelect,menuRef,menuDel,menuDelAll, menuColl,menuCreatFold,menuInsertFold,menuProp,menuFilter; // Cree le popup menu associe au select private void createPopupMenu() { popMenu = new PopupMenu(); popMenu.add( menuShow=new MenuItem("Show")); popMenu.add( menuSelect=new MenuItem("Select all objects of the selected planes")); popMenu.add( menuRef=new MenuItem("Take as the projection reference")); popMenu.add( menuDel=new MenuItem("Delete")); popMenu.add( menuDelAll=new MenuItem("Delete all planes...")); popMenu.addSeparator(); popMenu.add( menuFilter=new MenuItem("Create a new filter")); popMenu.addSeparator(); popMenu.add( menuCreatFold=new MenuItem("Create a new folder")); popMenu.add( menuInsertFold=new MenuItem("Insert in a new folder")); popMenu.add( menuColl=new MenuItem("Collapse")); popMenu.addSeparator(); popMenu.add( menuProp=new MenuItem("Properties of the selected plane")); super.add(popMenu); } /** Reactions aux differents boutons du menu */ public boolean action(Event e, Object o) { if( e.target==menuCreatFold ) { a.calque.newFolder(getDefaultFolderLabel()); } else if( e.target==menuInsertFold ) { insertFolder(); } else if( e.target==menuDel ) { a.calque.FreeSet(); } else if( e.target==menuDelAll ) { a.calque.FreeAll(); } else if( e.target==menuRef ) { a.calque.setPlanRef((Plan)menuPlan.elementAt(0)); } else if( e.target==menuShow ) { boolean flag = menuShow.getLabel().startsWith("Show"); for( int i=menuPlan.size()-1; i>=0; i-- ) { ((Plan)menuPlan.elementAt(i)).active=flag; } } else if( e.target==menuSelect ) { a.view.calque.selectAllObjectInPlans(); } else if( e.target==menuFilter ) { a.view.calque.newPlanFilter(); } else if( e.target==menuColl ) { boolean flag = menuShow.getLabel().startsWith("Coll"); for( int i=menuPlan.size()-1; i>=0; i-- ) { switchCollapseFolder((Plan)menuPlan.elementAt(i)); } } else if( e.target==menuProp ) { if( a.properties==null ) { a.trace(1,"Creating the Propertie window"); a.properties = new Properties(a); } // c'est barbare, mais on n'a pas de connaissance a priori sur le type de plan if( a.filterProperties==null ) { a.trace(1,"Creating the FilterProperties window"); a.filterProperties = new FilterProperties(a); } a.toolbox.tool[ToolBox.PROP].mode=Tool.DOWN; a.toolbox.repaint(); a.properties.majProp(); // idem, c'est barbare a.filterProperties.majProp(); } else return false; a.calque.repaint(); return true; } Vector menuPlan=null; // Affiche le popup private void showPopMenu() { int x=popX, y=popY; popX=popY=0; boolean allShow = true; boolean allCollapse = true; boolean canBeRef = true; boolean canBeColl = true; boolean canBeSelect = false; menuPlan = new Vector(10); for( int i=0; i0); menuInsertFold.setEnabled(menuPlan.size()>0); menuSelect.setEnabled(canBeSelect); menuRef.setEnabled(canBeRef); menuProp.setEnabled(menuPlan.size()==1); menuShow.setEnabled(menuPlan.size()>0); menuDel.setEnabled(menuPlan.size()>0); menuDelAll.setEnabled(menuPlan.size()>0); popMenu.show(this,x,y); } /** Memorise le canvas du target. * Necessaire pour des problemes de references croisees * @@param target Le target a memoriser */ protected void setTarget(Target target) { this.target=target; } /** Retourne vrai si on est dans l'oeil. * @@param x,y Position de la souris * @@return true si on est dans l'oeil false sinon */ protected boolean inEye(int x, int y) { return(x-gapLtrue si c'est pret false sinon */ protected boolean planOk(Plan p) { String s; if( p.type!=Plan.NO && p.type!=Plan.FILTER && !p.flagOk ) { if( p.error==null ) { if( p.type==Plan.IMAGE ) s=WAITMIN+"\n \n"+((PlanImage)p).getStatus(); else s=WAITMIN; Aladin.warning(s); // } else Aladin.warning(a.calque.plan[i].error); } /* else { if( Aladin.confirmation(p.error+"\nDo you want to remove this plan ?") ) { a.calque.unSelectAllPlan(); p.selected=true; a.calque.FreeSet(); } } */ return false; } return true; } /** Gestion de la souris */ public boolean mouseDown(Event e, int x, int y) { // Pas de popupmenu intempestif popX=popY=0; // Fin du message d'accueil if( a.msgOn ) a.endMsg(); // Memorise l'etat du Shift ou du Control flagShift = e.shiftDown() || e.controlDown(); //Menu Popup // if( e.modifiers!=0 && !flagShift ) { showPopMenu(x,y); return true; } // Gestion de l'oeil (selection de tous les plans simultanement, ou avec if( inEye(x,y) ) { // if( e.shiftDown() ) a.calque.activeRSPlan(); // else a.calque.activeAllPlan(); a.calque.activeRSPlan(); a.calque.view.repaint(); clinDoeil=true; repaint(); return true; } // Recherche du plan clique if( (currentPlan = getPlan(y))==null ) return true; // Par defaut, memorisation de la position this.x=x; this.y=y; oldy=y; // Pour faire tout de suite bouger le petit triangle de reference // Voir mouseUp() pour la seconde partie du boulot if( x=4) { flagDrag=true; this.x=x; this.y=y; repaint(); } return true; } static int folderN=0; // Indice pour le nom d'un folder private String getDefaultFolderLabel() { return "Fold. "+(++folderN); } // Creation d'un folder qui va contenir tous les plans qui sont dans // menuPlan private void insertFolder() { Enumeration e = menuPlan.elements(); Plan op = (Plan)e.nextElement(); Plan p = createFolder(op); while( true ) { permute(op,p); p=op; if( !e.hasMoreElements() ) return; op=(Plan)e.nextElement(); } } /** Creation d'un plan Folder juste au-dessus du plan p dans la pile */ protected Plan createFolder(Plan p) { int i; for( i=0; i=a.calque.plan.length-1 ) return; p2=a.calque.plan[i+1]; permute(p1,p2); } /** Permutation des plans avec ajustement des niveaux de folder * @@param source Le plan a deplacer * @@param target Le nouvel emplacement */ public void permute(Plan source, Plan target) { int i,k=0,m=0; int n=1; // nombre de plans a permuter int targetFolder=0; //System.out.println("Permutation "+source.label+" vers "+target.label); // Determination du niveau du folder (plan target) targetFolder=target.folder; if( target.type==Plan.FOLDER ) targetFolder++; // Y a-t-il plusieurs plans consecutifs a permuter (folder) if( source.type==Plan.FOLDER ) { Plan p[] = a.calque.getFolderPlan(source); int deltaFolder = targetFolder-source.folder; //System.out.println("deltaFolder="+deltaFolder); source.folder+=deltaFolder; for( i=0; i=4 */ ) { //System.out.println("currentPlan : "+(currentPlan!=null?currentPlan.label:"null")); //System.out.println("newPlan : "+(newPlan!=null?newPlan.label:"null")); permute(currentPlan,newPlan); a.calque.view.repaint(); a.calque.zoom.zoomView.repaint(); } repaint(); return true; } // Determination du plan et du slide clique Slide s = getSlide(y); if( s==null ) return true; Plan p = s.getPlan(); // Gestion de la selection du plan de reference (voir mouseDown // pour la 1ere partie du boulot if( newRef!=null ) { if( a.calque.setPlanRef(p) ) { p.active = true; // On le selectionne d'office; if( p.projd!=null ) a.calque.activeAllPlan(); a.calque.view.newView(); doAllRepaint=true; } newRef=null; // activation / desactivation du plan clique } else if( s.inLogo(x) && p.type!=Plan.NO) { // Dans l'icone du calque if( p.type==Plan.FOLDER ) { if( e.clickCount>1 ) switchCollapseFolder(p); else switchActiveFolder(p); } else if( p.type==Plan.FILTER ) { p.active = !p.active; ((PlanFilter)p).updateState(); } else { if( !planOk(p) ) return true; if( !(p.projd==null && p.ref ) && !p.isViewable() ) { Aladin.warning(NOPROJ); return true; } p.active = !p.active; // thomas if( p.type==Plan.CATALOG && p.active) { PlanFilter.updatePlan(p); } } doAllRepaint=true; } // Selection / deselection du plan clique int nbc = 0; if( p.type==Plan.NO ) { if( (e.modifiers & java.awt.event.InputEvent.BUTTON3_MASK) !=0 ) { popX=x; popY=y; repaint(); } return true; } planOk(p); // Cas particulier d'un plan d'une image d'archive // on va automatiquement selectionner la source associee if( p.type==Plan.IMAGE && ((PlanImage)p).o!=null ) { a.calque.view.selectOne(((PlanImage)p).o); } // On deselectionne le precedent plan courant // et les groupes de plans si necessaire for( int j=0; j1 && p.selected ) p.selected=false; else p.selected=true; } else p.selected = true; if( !flagShift && p.type==Plan.NO ) p.active = true; //Menu Popup if( p.selected && (e.modifiers & java.awt.event.InputEvent.BUTTON3_MASK) !=0 ) { popX=x; popY=y; } if( doAllRepaint ) a.calque.repaint(); else { repaint(); a.toolbox.toolMode(); } return false; } // Collapse ou uncollapse de tous les plans d'un folder private void switchCollapseFolder(Plan f) { int i,n,m; boolean flag; Plan p[] = a.calque.getFolderPlan(f); if( p==null || p.length==0 ) return; // Determine le nombre de plans collapses de meme niveau for( m=n=i=0; ilargeur ) { g.setFont( Aladin.ITALIC ); m = g.getFontMetrics(Aladin.BOLD); stext = m.stringWidth(p.objet); } if( stext>sizeLabel) return; int xo = (gapL+eyeWidth+ws)/2-stext/2; g.drawString( p.objet, xo , eyeHeight-5); } public void update(Graphics gr) { ws = size().width; hs = size().height; hsp= hs-eyeHeight-gapB; // Hauteur de la portion pour les plans // Creation ou adaptation du plan stack if( img==null || img.getWidth(this)!=ws || img.getHeight(this)!=hs ) { if( g!=null ) g.dispose(); img = createImage(ws,hs); g=img.getGraphics(); // On prepare le fond g.setColor( Aladin.LGRAY ); g.fillRect(0,0,ws,hs); // Le pourtour g.setColor( Color.black ); g.drawLine(0,0,0,hs-1); g.setColor( Color.white ); g.drawLine(0,hs-1,ws-1,hs-1); g.drawLine(ws-1,hs-1,ws-1,0); } // Dans le cas d'un deplacement de plan if( flagDrag ) { moveLogo(gr); return; } // On efface tout, on recommence g.setColor( Aladin.LGRAY ); g.fillRect(1,1,ws-2,hs-2); // Le clip Rect pour ne pas depasser g.clipRect(1,1,ws-2,hs-2); // Dessin de l'oeil de l'observateur et de l'objet central regarde drawEye(g,true); writeTitle(g); // Determination du premier plan image (opaque) int nOpaque = a.calque.getIndexPlanBase(); /*anais*/ int planRGB =(nOpaque>=0 && a.calque.plan[nOpaque] instanceof PlanImageRGB)?nOpaque:-1; if( nOpaque<0 ) nOpaque=a.calque.plan.length; Slide.setBlink(false); // TEMPORAIREMENT JE CREE LES SLIDES A CHAQUE COUP slides = new Vector(20); int y=hs-22; int barreY=hs-2; for( int j=a.calque.getLastVisiblePlan()-1; j>=0 && y>eyeHeight; j-- ) { Slide s = new Slide(a.calque.plan[j]); slides.addElement(s); if( nOpaque==j ) barreY=y; y=s.draw(g,y,planRGB, newRef==a.calque.plan[j] || (newRef==null && a.calque.plan[j].ref)); } /* // Dessin de la barre de vue if( nOpaque Simbad resolver )"; static final String WNEEDOBJ = "You must specify a target"; static final String WNEEDRAD = "You must specify the radius of your query"; static final String WNEEDCAT = "You must specify a catalog name (or number)"; static final String WERROR = "Unknown server error"; static final String WDEJA = "This query has already been submitted !"; // Les elements communs aux formulaires MetaDataTree tree=null; // Le session tree si necessaire pour le formulaire static String defaultTarget="";// Le target par defaut static boolean message=true; // Indique qu'il faut afficher une fenetre pour OK TextField target=null; // Le target (methode unifiee) // TextField radius; // la taille (si necessaire) // Reperage des TextFields indiquants le centre et la taille du champ TextField coo[]; // Pointe les champs du target TextField rad[]; // Pointe les champs du field (radius...) static final int COO = 1; // Coordonnees en J2000 sexa un champ static final int COOb = 2; // Coordonnees en J2000 sexa un champ (separateur ' ') static final int SIMBAD = 4; // Id. Simbad (un champ) static final int NED = 8; // Id. NED (un champ) static final int RADEC = 16; // Coor en J2000 sexa sur deux champs static final int RADEd = 32; // Coor en J2000 deci sur deux champs static final int RADEb = 64; // Coor en J2000 deci sur deux champs, separateur ' ' static final int COOd =128 ; // Coor en J2000 deci sur un champ int modeCoo=0; static final int RADIUS = 1; // Field en radius (arcmin) static final int RADSQR = 2; // Field en carre (arcmin), 1 champ static final int RADBOX = 4; // Field en box (arcmin), 2 champs static final int RADIUSd= 8; // Field en radius (degres) int modeRad=0 ; // Les parametres propres int type; // Le type de serveur (IMAGE ou DATA) String nom; // le nom du serveur String info; // les infos (une ligne) decrivant le serveur MyButton grab=null; // Bouton grab s'il y en a un dans l'interface String myPopup=null; // Label du popup ou null sinon boolean flagVerif=true; // false si on ne verifie pas les redondances des plans boolean flagToFront=true; // false si on ne passe pas la fenetre Aladin devant // Les references aux objets Aladin aladin; Label status; public Dimension getMinimumSize() { return getSize(); } public Dimension getPreferredSize() { return getSize(); } public Dimension getSize() { return new Dimension(WIDTH,HEIGHT); } /** Memorisation des champs qui contiennent le target. * @@param modeCoo mode de memorisation du target (COO|SIMBAD|NED|RADEC...) * @@param f1,f2 references aux champs TextField */ protected void setModeCoo(int modeCoo,TextField f1) { setModeCoo(modeCoo,f1,null); } protected void setModeCoo(int modeCoo,TextField f1,TextField f2) { this.modeCoo = modeCoo; if( (modeCoo & (RADEC|RADEd|RADEb) ) !=0 ) { coo = new TextField[2]; coo[0]=f1; coo[1]=f2; } else { coo = new TextField[1]; coo[0]=f1; } } /** Memorisation des champs qui contiennent le radius (ou champ). * @@param modeRad mode de memorisation du radius (RADIUS|RAQSQR|RADBOX|RADIUSd...) * @@param f1,f2 references aux champs TextField */ protected void setModeRad(int modeRad,TextField f1) { setModeRad(modeRad,f1,null); } protected void setModeRad(int modeRad,TextField f1,TextField f2) { this.modeRad = modeRad; if( (modeRad & RADBOX) !=0 ) { rad = new TextField[2]; rad[0]=f1; rad[1]=f2; } else { rad = new TextField[1]; rad[0]=f1; } } /** transformation du target en champs propres au serveur * avec eventuellement resolution Simbad si necessaire * @@return le target (resolu ou non) sinon null */ protected String resolveTarget() { if( target==null ) return null; return resolveTarget( target.getText().trim() ); } /** transformation du target en champs propres au serveur * avec eventuellement resolution Simbad si necessaire * @@return le target (resolu ou non) sinon null */ protected String resolveTarget(String t) { if( (modeCoo & SIMBAD)!=0 ) { coo[0].setText(t); return t; } Coord c=null; try { if( !View.notCoord(t) ) c = new Coord(t); else c = aladin.view.getSimbad(t); if( (modeCoo & COO)!=0 ) coo[0].setText(c.getSexa(":")); else if( (modeCoo & COOb)!=0 ) coo[0].setText(c.getSexa(" ")); else if( (modeCoo & COOd)!=0 ) coo[0].setText(c.al+" "+c.del); else if( (modeCoo & RADEC)!=0 ) { coo[0].setText(c.getRA()); coo[1].setText(c.getDE()); } else if( (modeCoo & RADEb)!=0 ) { coo[0].setText(c.getRA(' ')); coo[1].setText(c.getDE(' ')); } else if( (modeCoo & RADEd)!=0 ) { coo[0].setText(c.al+""); coo[1].setText(c.del+""); } } catch( Exception e ) { c=null; } return c==null?null:c.getSexa(":"); } /** Mise en place des differents de curseurs */ protected void waitCursor() { makeCursor(Aladin.WAIT); } protected void defaultCursor() { makeCursor(Aladin.DEFAULT); } protected void makeCursor(int c) { Aladin.makeCursor(aladin.dialog,c); Aladin.makeCursor(aladin,c); if( coo!=null ) { Aladin.makeCursor(coo[0],c); if( coo.length>1 ) Aladin.makeCursor(coo[1],c); } if( rad!=null ) Aladin.makeCursor(rad[0],c); if( tree!=null ) Aladin.makeCursor(tree,c); } // Retourne le nombre de pixel du label protected int stringSize(Label l) { FontMetrics m = l.getFontMetrics(l.getFont()); int i=m.stringWidth(l.getText()); return i; } static int HL=30; // Genere le panel pour le target protected Panel targetPanel(int taille, String ex, boolean pickView,int mode) { int x=0,y=0,l; Panel p = new Panel(); p.setLayout(null); Label label= new Label("Target"); label.setFont(Aladin.LBOLD); l = 55; label.setBounds(x,y,l,HL); x+=l+5; p.add(label); int xEx=x; target = new TextField(taille); if( mode!=0) setModeCoo(mode,target); l=taille*8; target.setBounds(x,y,l,HL); x+=l+5; p.add(target); if( pickView ) { grab = new MyButton(aladin,GRABIT); grab.setAlwaysUp(false); grab.setFont(Aladin.SBOLD); grab.enable(false); l=75; grab.setBounds(x,y+2,l,HL-4); x+=l; p.add(grab); } // On ajoute l'exemple if( ex!=null ) { Label exemple = new Label(ex); exemple.setFont(Aladin.SITALIC); y+=HL-7; l=stringSize(exemple)+5; exemple.setBounds(xEx,y,l,HL); p.add(exemple); } return p; } /** Ajout des composantes permettant la saisie du Target (sans exemple). *
Voir la fonction generale protected void targetPanel(Panel p,int taille, GridBagLayout g, GridBagConstraints c) { targetPanel(p,taille,null,g,c); } /** Ajout des composantes permettant la saisie du Target (avec exemple). * * @@param p Le panel auquel est associe le nouveau composant * @@param taille Le nombre de caractere de la fenetre de saisie * @@param ex La chaine de caracteres donnant un exemple * @@param pickView La chaine de caracteres donnant un exemple * @@param g Le gestionnaire de mise en page courant * @@param c Les contraintes courantes sur le gestionnaire g protected void targetPanel(Panel p,int taille, String ex, GridBagLayout g, GridBagConstraints c) { targetPanel(p,taille,ex,false,g,c); } protected void targetPanel(Panel p,int taille, String ex, boolean pickView, GridBagLayout g, GridBagConstraints c) { // Pour gerer le pb de Netscape 3.0 target = new TextField(taille); setModeCoo(COO|SIMBAD,target); if( pickView ) { grab = new Button(GRABIT); grab.enable(false); } addCouple(p,"Target",target,grab,g,c); // On ajoute l'exemple if( ex!=null ) addCouple(p,null,new MyLabel(ex,Label.LEFT,Aladin.SITALIC),g,c); c.anchor=GridBagConstraints.CENTER; } /** Ajout des composantes permettant la saisie du Target (avec exemple). * * @@param p Le panel auquel est associe le nouveau composant * @@param taille Le nombre de caractere de la fenetre de saisie * @@param ex La chaine de caracteres donnant un exemple * @@param pickView La chaine de caracteres donnant un exemple * @@param g Le gestionnaire de mise en page courant * @@param c Les contraintes courantes sur le gestionnaire g protected void targetP(Panel p,int taille, String ex, boolean pickView, GridBagLayout g, GridBagConstraints c) { // Pour gerer le pb de Netscape 3.0 target = new TextField(taille); if( pickView ) { grab = new Button(GRABIT); grab.enable(false); } addCouple(p,"Target",target,grab,g,c); // On ajoute l'exemple if( ex!=null ) addCouple(p,null,new MyLabel(ex,Label.LEFT,Aladin.SITALIC),g,c); c.anchor=GridBagConstraints.CENTER; } */ /** Mise en forme des coordonnees. * En cas de coordonnees (absence de lettre), substitue les ':' * eventuels par ' ' * * @@param coo La chaine contenant les coordonnees * @@return La chaine traitees */ protected static String mefCoord(String coo) { int i; for( i=0; i='A' && ch<='Z') || (ch>='a' && ch<='z') ) return coo; } return coo.replace(':',' ').replace(',',' '); } /** Ajout d'un composant ``binaire''. * Ajoute un composant dans le panel prefixe par du texte * * @@param p Le panel auquel est associe le nouveau composant * @@param s Le texte qui va preceder le composant a inserer * (null s'il n'y en a pas) * @@param cp Le composant a inserer * @@param cp Le composant a inserer (en extra) en null si rien * @@param g Le gestionnaire de mise en page courant * @@param c Les contraintes courantes sur le gestionnaire g protected static void addCouple(Panel p,String s,Component cp, GridBagLayout g, GridBagConstraints c) { addCouple(p,s,cp,null,g,c); } protected static void addCouple(Panel p,String s,Component cp,Component extrac, GridBagLayout g, GridBagConstraints c) { // Determination du texte qui precede MyLabel l; if( s!=null ) l = new MyLabel(s,Label.RIGHT,Aladin.LBOLD); else l = new MyLabel(); c.gridwidth = 1; c.anchor = GridBagConstraints.EAST; g.setConstraints(l,c); p.add(l); // Insertion du nouveau composant if( extrac==null ) c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.HORIZONTAL; g.setConstraints(cp,c); p.add(cp); c.fill = GridBagConstraints.NONE; // Insertion du composant en extra if( extrac!=null ) { c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.CENTER; c.insets = new Insets(0,10,0,10); g.setConstraints(extrac,c); c.insets = new Insets(0,0,0,0); c.anchor = GridBagConstraints.WEST; p.add(extrac); } } */ /** Ajout d'un titre general. * Ajoute le titre du formulaire (ex: Simbad database...) * * @@param p Le panel auquel est associe le nouveau composant * @@param s Le texte du titre * @@param g Le gestionnaire de mise en page courant * @@param c Les contraintes courantes sur le gestionnaire g protected void titrePanel(Panel p,String s, GridBagLayout g, GridBagConstraints c) { Label name = new Label(s,Label.CENTER); name.setFont( Aladin.LLITALIC ); c.gridwidth = GridBagConstraints.REMAINDER; g.setConstraints(name,c); p.add(name); } */ /** Retourne le target courant et le memorise. * * @@return la chaine ayant ete saisie dans le champ ``target'' * @@see aladin.Server#memTarget() * @@see aladin.Server#mefCoord(java.lang.String) */ protected String getTarget() { return getTarget(true); } protected String getTarget(boolean confirm) { String s=""; if( coo==null ) return null; // pas de target dans ce formulaire s = coo[0].getText().trim(); if( coo.length>1 ) { String tmp = coo[1].getText().trim(); if( tmp.length()>0 ) s += " "+tmp; } if( confirm && s.length()==0 ) { Aladin.warning(this,WNEEDOBJ); return null; } return mefCoord(s); } /** Retourne le Radius en arcmin en tenant compte d'une eventuelle * indication d'unite (d ou ° pour degre, s ou " pour secondes) * @@return le radius de l'interrogation, ou "" si erreur */ protected String getRadius() { if( rad==null ) return ""; // Pas de radius sur ce formulaire String r = rad[0].getText().trim(); if( r.length()==0 ) return ""; return ""+getRadius(r); } static protected double getRadius(String r) { double fct=1.0; // Fct multiplicatif en fct de l'unite // Determination de l'unite int offsetD1 = r.indexOf('°'); int offsetD = r.indexOf('d'); int offsetS = r.indexOf('s'); int offsetQ = r.indexOf('\"'); if( offsetD1>0 || offsetD>0 && offsetD>offsetS ) fct=60.0; // Degres else if( offsetS>0 || offsetQ>0) fct=1/60.0; // Secondes r = (new StringTokenizer(r)).nextToken(); // Recup du premier mo char [] a = r.toCharArray(); int i; for( i=0; i='0' && a[i]<='9') || a[i]=='.'); i++); r = new String(a,0,i); return Double.valueOf(r).doubleValue()*fct; } /** Clear du formulaire (et reaffichage) */ protected void clear() { if( coo!=null ) { coo[0].setText(""); if( coo.length>1 ) coo[1].setText(""); } if( rad!=null ) rad[0].setText(""); if( target!=null ) target.setText(""); defaultTarget=""; } /** Reset du formulaire (et reaffichage) */ protected void reset() { aladin.dialog.setTarget(aladin.dialog.getCurrent()); } /* static boolean firstGrab=true; /** Passe en mode GrabIt * @@return le point x,y, dans le repere de la vue void grabIt() { if( firstGrab ) { Aladin.info(this,"Grab the coordinates in the ``view window''.\n"+ " Click down the mouse for the target (and eventually\n"+ "drag it for the radius) "); firstGrab=false; } aladin.view.setModeGrabIt(true); } */ /** Pre-remplissage du(des) champ target + activation eventuelle * du bouton GrabIt * @@param s La chaine a mettre dans le champ target */ protected void setTarget(String s) { if( target==null ) return; target.setText(s); // Activation ou non du bouton GrabIt if( aladin.dialog!=null && !aladin.dialog.isGrabIt() && grab!=null ) { Plan pref = aladin.calque.getPlanRef(); grab.enable(pref!=null && pref.projd!=null ); } } /** Pre-remplissage du champ radius * @@param s La chaine a mettre dans le champ radius */ protected void setRadius(String s) { setRad(getRadius(s)); } /** Pre-remplissage du champ radius * @@param rm le diametre de l'interrogation ou la taille de la boite */ protected void setRad(double rm) { if( (modeRad & (RADIUS|RADIUSd) )!=0 ) { double r = Math.floor((rm/2)*Math.sqrt(2)*10)/10; if( (modeRad & RADIUS)!=0 ) rad[0].setText(r+""); else rad[0].setText((r/60.)+""); } else if( (modeRad & RADSQR)!=0 ) rad[0].setText(rm+""); else if( (modeRad & RADBOX)!=0 ) { rad[0].setText(rm+""); rad[1].setText(rm+""); } } /** Retourne true si le serveur correspond a la chaine * passee en parametre (presence de l'identificateur dans nom sans * tenir compte des majuscules ni des pluriels en "s") * @@param s : identificateur du serveur recherche * @@return true: Ok c'est ce serveur. */ protected boolean is(String s) { if( s.endsWith("s") ) s=s.substring(0,s.length()-1); StringTokenizer st = new StringTokenizer(nom); while( st.hasMoreTokens() ) { String m = st.nextToken(" ()"); if( m.endsWith("s") ) m=m.substring(0,m.length()-1); if( s.equalsIgnoreCase(m) ) return true; } return false; } /** Creation d'un plan de maniere generique * @@param target l'objet ou la coordonnees * @@param radius le rayon de l'interrogation * @@param criteria les criteres d'interrogation (syntaxe a definir) * @@param label Le label du plan qui va etre cree * @@param origin La mention de l'origine de l'image ou des donnees * @@return le numero du plan dans la pile, -1 si erreur */ protected int creatPlane(String target,String radius,String criteria, String label, String origin) { return -1; } /** Verifications et messages divers associes a la creation d'un nouveau * plan */ protected boolean verif(int type,String obj,String qual) { return verif(type,obj,qual,null); } protected boolean verif(int type,String obj,String qual,String other) { flagVerif=flagVerif && !MyButton.shiftDown(); //System.out.println("["+flagVerif+"] verif("+type+","+obj+","+qual+","+other+")"); if( flagVerif && aladin.calque.dejaCharge(type,obj,qual,other) ) { Aladin.warning(this,WDEJA,1); return false; } if( !Aladin.script ) { if( status!=null ) status.setText(OK); if( flagToFront && flagVerif ) aladin.getFrame(aladin).toFront(); } flagVerif=true; flagToFront=true; return true; } /** Voir classes derivees */ public void submit() {} /** Memorisation du dernier target saisie sous forme d'un identificateur */ protected void memTarget() { if( target==null ) return; // if( (modeCoo&(SIMBAD|NED))==0 ) return; // if( coo!=null ) defaultTarget=coo[0].getText().trim(); defaultTarget=target.getText().trim(); } /** Memorisation du dernier target saisie par la saisie rapide */ protected static void setDefaultTarget(String s) { defaultTarget=s; } /** Gestion du ENTER. * Pour pouvoir gerer le ENTER comme si on appuyait sur le bouton SUBMIT * * @@see aladin.Server#submit() */ public boolean keyDown(Event e,int key) { if( e.target instanceof TextField ) { // Validation par ENTER if( key==13 || key==10 ) { flagVerif=!e.shiftDown(); // Pour ne pas verifier les redondances submit(); return true; } /* if( aladin.view.isGrabIt() ) aladin.view.setModeGrabIt(false); */ } return false; } /** Retourne le premier mot du nom */ protected String getNom() { StringTokenizer st = new StringTokenizer(nom); return st.nextToken(); } /** Retrouve le frame. * @@param c le composante pour lequel on veut retrouver le Frame */ protected Frame getFrame(Component c) { while( c!=null && !(c instanceof Frame) ) c=c.getParent(); return (Frame) c; } } lettre), substitue les ':' * eventuels par ' ' * * @@param coo La chaine contenant les coordonnees * @@return La chaine traitees */ protected static String mefCoord(String coo) { int i; for( i=0; i='A' && ch<='Z') || (ch>='a' && ch<='z') ) return coo; } return coo.replace(':',' ').replace(',',' '); } /** Ajout d'un composant ``binaicds/aladin/ServerDialog.java010064400076440000132000000453470770227416100170160ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion de l'interface de choix du serveur de donnees ou d'images * * @@author Pierre Fernique [CDS] * @@version 1.2 : (14 sep 00) Ajout du serveur de champs de vue * @@version 1.1 : (23 nov 99) Chargement des archives, des surveys et des mots * cles par VizieR * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class ServerDialog extends Frame { static final int MAXSERVER = 10; // Les indices des serveurs static int ALADIN = 0; static int SIMBAD = 0; static int NED = 0; static int VIZIER = 0; static int FIELD = 0; static int LOCAL = 0; // Les chaines statiques static final String TREE = "Data Tree"; static final String SUBMIT = "SUBMIT"; static final String RESET = "Reset"; static final String CLEAR = "Clear"; static final String CANCEL = "Close"; static final String INFO = "Choose an image server or a data server\n"+ "and fill in the associated form drawn below"; // Les composantes de l'objet Server [] server; Panel mp; // le panel multiple des formulaires CardLayout card; // et son layout associe SelectDialog selectDialog; // L'entourage du panel multiple des formulaires Label status; // Le status MyButton buttons[]; // Liste des boutons // Les infos a memoriser int current=0; // le formulaire courant int bcurrent=0; // le bouton courant // Les references aux autres objets Aladin aladin; Calque calque; /** Ajoute au Vecteur sv les serveurs decrits par le GLU (Glu.vGluServer). * Le serveur peut se trouver dans un sous-menu Popup (myPopup!=null) * ou avoir un bouton a part entiere * @@param type Server.IMAGE ou Server.DATA suivant que l'on traite * les serveurs Images ou Donnees */ private void addGluServer(Vector sv, int type) { Enumeration e = Glu.vGluServer.elements(); Server sTmp; int i; for( int j=Glu.vGluServer.size()-1; j>=0; j-- ) { sTmp = (Server)Glu.vGluServer.elementAt(j); if( sTmp.type!=type ) continue; // Niveau bouton if( sTmp.myPopup==null ) { sv.addElement(sTmp); } // Via un Popup else { // Est-ce que ce Popup existe deja for( i=sv.size()-1; i>=0; i-- ) { Server s = (Server)sv.elementAt(i); if( s.nom.equals(sTmp.myPopup) && s instanceof MyPopup ) break; } // S'il n'existe pas encore, on le cree if( i<0 ) { i=sv.size(); // Indice de son emplacement sv.addElement( new MyPopup(aladin,sTmp.myPopup,i, type==Server.IMAGE?MyPopup.LEFT:MyPopup.RIGHT) ); } ((MyPopup)sv.elementAt(i)).addItem(sTmp.nom); sv.addElement( sTmp ); } } } /** Creation de l'interface et de tous les formulaires * necessaires a l'acces aux bases * @@param aladin Reference */ protected ServerDialog(Aladin aladin) { int i,j; Vector sv = new Vector(); // Temporaire pour la creation de serveur[] Panel actions = new Panel(); setTitle("Server selector"); setBackground(Aladin.BKGD); this.aladin = aladin; calque = aladin.calque; setFont( Aladin.BOLD ); //Status status = new Label(""); status.setFont( Aladin.BOLD ); status.setForeground( Color.blue ); // Les serveurs Images par programme if( Aladin.NETWORK ) sv.addElement( new AladinServer(aladin,status)); // Les serveurs Images via GLU addGluServer(sv,Server.IMAGE); // L'acces local // if( Aladin.STANDALONE ) sv.addElement( new LocalServer(aladin,status) ); sv.addElement( new LocalServer(aladin,status) ); // Les serveurs Data par programme if( Aladin.NETWORK ) { Server svizier; sv.addElement( (svizier=new VizieRServer(aladin,status,this, actions)) ); sv.addElement( new SurveysServer(aladin,status, ((VizieRServer)svizier).vSurveys)); sv.addElement( new ArchivesServer(aladin,status, ((VizieRServer)svizier).vArchives)); sv.addElement( new SimbadServer(aladin,status)); sv.addElement( new NEDServer(aladin,status)); } // Les serveurs Data via GLU addGluServer(sv,Server.DATA); // Les FoV sv.addElement( new FieldServer(aladin,status) ); // Construction du Panel contenant le bandeau d'explication Panel haut = new Panel(); haut.setLayout( new BorderLayout()); Aladin.makeAdd(haut,new MyLabel(INFO,Label.CENTER,Aladin.PLAIN),"Center"); Aladin.makeAdd(haut,new MyLabel(" \n Image servers:",Label.LEFT,Aladin.BOLD),"West"); Aladin.makeAdd(haut,new MyLabel(" \nData servers : ",Label.CENTER,Aladin.BOLD),"East"); // haut.setFont( Aladin.BOLD ); // Construction des panel des boutons Panel buttonImg = new Panel(); Panel buttonData = new Panel(); buttonImg.setLayout( new GridLayout(0,1) ); buttonData.setLayout( new GridLayout(0,1) ); // Construction du tableau des serveurs et des boutons // et remplissage des panels adequats server = new Server[sv.size()]; buttons = new MyButton[sv.size()]; int nbi=0,nbd=0; for( i=0; ix2 ); } // Retourne vrai si on est dans le label protected boolean in(int y) { return( y1<=y && y<=y2 ); } // Retourne vrai si on est sous le logo (on compte qq pixels dans le logo lui-meme) protected boolean sous(int y) { return( y2-10<=y && y<=y2+5 ); } // Dessine le repere du plan de reference en fonction // de l'etat et du type du plan (a.calque.plan[i]) passe en parametre // l'ordonne pour le dessin est passee en parametre (dy). // Si newREf est different de -1, on remplit le nouveau triangle // de reference void drawRepereRef(Graphics g,int dy,boolean newRef) { if( !p.flagOk || (!p.ref && p.type!=Plan.IMAGE) ) return; int [] y2 = new int[trX.length]; for( int k=0; kLIMIT[i]; i++ ); if( i>=LIMIT.length-1 ) i=LIMIT.length-2; return i; } /** Modification de l'identificateur * @@param id nouvel identificateur de la source */ protected void setText(String id) { super.setText(id); dw=0; // Pour forcer un futur setD() } /** Modification de l'information associee a la source * @@param info la nouvelle info supplementaire */ protected void setInfo(String info) { this.info = info; oid=""; } /** Modification de la legende associee a la source * @@param leg la nouvelle legende */ protected void setLegende(Legende leg) { this.leg = leg; oid=""; } /** Modification de la representation de la source. * @@param sourceType la nouvelle representation (ex : Source.CARRE) */ protected void setSourceType(int sourceType) { this.sourceType = sourceType; } // Affichage de l'info lie a la source void info(Aladin aladin) { aladin.mesure.setInfo(this); } /** Affichage l'info lie a l'objet * Affiche l'identifacteur dans le statut de l'objet aladin * @@param aladin reference */ protected void status(Aladin aladin) { aladin.status.setText("\""+id+"\""+HCLIC); } /** Modification de la position (absolue) * @@param x,y nouvelle position */ protected void setPosition(double x, double y) { } /** Modification de l'identificateur * @@param id nouvel identificateur */ protected void deltaPosition(double dx, double dy) { } // Precalcul le decalage du label en fct de la font // et de la taille de la source void setD() { FontMetrics m = Toolkit.getDefaultToolkit().getFontMetrics(DF); dw=dx = m.stringWidth(id)/2; dh=dy = HF/2; if( dx>L ) { dx=L-1; dw+=(dw-dx); } if( dy>L ) { dy=L-1; dh+=(dh-dy); } } /** Test d'appartenance. * Retourne vrai si le point (x,y) de l'image se trouve dans l'objet * @@param x,y le point a tester * @@param z zoom courant * @@return true si on est dedans, false sinon */ protected boolean inside(double x, double y,double z) { double l=L/z; return(this.x<=x+l && this.x>=x-l && this.y<=y+l && this.y>=y-l); } /** Generation d'un clip englobant. * Retourne un rectangle qui englobe l'objet * @@param zoomview reference au zoom courant * @@return le rectangle enblobant */ protected Rectangle getClip(ZoomView zoomview) { Point p = getViewCoord(zoomview,dw,dh); if( !withlabel ) { if( select ) return new Rectangle(p.x-L-MDS,p.y-L-MDS, L*2+DS, L*2+DS); else return new Rectangle(p.x-L,p.y-L, L*2, L*2); } else { if( dx==0 ) setD(); if( select ) return new Rectangle(p.x-L-MDS,p.y-L-dh-MDS, dw+L*2+DS,dh+L*2+DS); else return new Rectangle(p.x-L,p.y-L-dh, dw+L*2,dh+L*2); } } boolean blinkState=false; /** affiche en video inverse la source. * @@param g le contexte graphique * @@param zoomview reference au zoom courant */ protected void show(Graphics g,ZoomView zoomview) { //System.out.println("show "+id); if( show ) return; show=true; if( !blinkState ) blink(g,zoomview); } /** Affiche la source dans son etat normal (fin du reverse) * @@param g le contexte graphique * @@param zoomview reference au zoom courant */ protected void hide(Graphics g,ZoomView zoomview) { //System.out.println("hide "+id); if( !show ) return; show=false; if( blinkState ) blink(g,zoomview); } // Procedure interne protected void blink(Graphics g,ZoomView zoomview) { //System.out.println("blink "+id+" "+(blinkState?"XOR":"NORMAL")); Point p = getViewCoord(zoomview,L,L); if( p.x<0 ) return; blinkState=!blinkState; g.setColor( Color.red ); g.setXORMode( Color.yellow ); g.drawRect(p.x-L-1,p.y-L-1, L*2+2, L*2+2); g.drawRect(p.x-L-2,p.y-L-2, L*2+4, L*2+4); g.setPaintMode(); } // Tracage d'un carre void drawCarre(Graphics g,Point p) { if( !withlabel ) g.drawRect(p.x-L,p.y-L, L*2, L*2); else { if( dx==0 ) setD(); g.drawLine(p.x+L,p.y-L+dy+2, p.x+L,p.y+L); g.drawLine(p.x-L,p.y+L, p.x+L,p.y+L); g.drawLine(p.x-L,p.y+L, p.x-L,p.y-L); g.drawLine(p.x-L,p.y-L, p.x+L-dx-2,p.y-L); g.drawString(id,p.x+L-dx,p.y-L+dy); } } // Tracage d'un losange void drawLosange(Graphics g,Point p) { g.drawLine(p.x,p.y-L, p.x+L,p.y); g.drawLine(p.x+L,p.y, p.x,p.y+L); g.drawLine(p.x,p.y+L, p.x-L,p.y); g.drawLine(p.x-L,p.y, p.x,p.y-L); if( withlabel ) { g.drawString(id,p.x+L-dx,p.y-L+dy); } } // Tracage d'une croix (vertical/horizontal) void drawPlus(Graphics g,Point p) { g.drawLine(p.x-L,p.y, p.x+L,p.y ); g.drawLine(p.x,p.y-L, p.x,p.y+L ); if( withlabel ) { if( dx==0 ) setD(); g.drawString(id,p.x+L-dx/2,p.y-L+dy/2); } } // Tracage d'une croix (45 degres) void drawCroix(Graphics g,Point p) { g.drawLine(p.x-L,p.y-L, p.x+L,p.y+L ); g.drawLine(p.x-L,p.y+L, p.x+L,p.y-L ); if( withlabel ) { if( dx==0 ) setD(); g.drawString(id,p.x+L,p.y+dy/2); } } // Tracage d'un point void drawPoint(Graphics g,Point p) { g.drawLine(p.x-1,p.y, p.x+1,p.y ); g.drawLine(p.x,p.y-1, p.x,p.y+1 ); if( withlabel ) { g.drawString(id,p.x+2-dx/2,p.y-2+dy/2); } } // Tracage d'un dot void drawDot(Graphics g,Point p) { g.drawLine(p.x,p.y, p.x,p.y ); if( withlabel ) { g.drawString(id,p.x+2-dx/2,p.y-2+dy/2); } } /** Dessine la source pour la legende * @@param g le contexte graphique * param x,y position */ protected void print(Graphics g,int x, int y) { Point p = new Point(x,y); // Memorisation des parametres boolean mwithlabel = withlabel; withlabel = false; g.setColor( plan.c ); switch(sourceType) { case CARRE: drawCarre(g,p); break; case CROIX: drawCroix(g,p); break; case PLUS: drawPlus(g,p); break; case LOSANGE: drawLosange(g,p); break; case POINT: drawPoint(g,p); break; case DOT: drawDot(g,p); break; } withlabel = mwithlabel; } /** retourne true si la source est selectionnee par l'un des filtres actif */ protected boolean isSelected() { PlanFilter pf; for(int i=0;i=0 || ucd.indexOf("?")>=0; for(curPos=0; curPos=0 || name.indexOf("?")>=0; for(curPos=0; curPos0 ) { int b = name.indexOf('>',a+1); if( b>=0 ) name=name.substring(a+1,b); } } return name; } else return null; } /** Returns the value of the field at position index * @@param index - the position of the field one wants * @@return the value of the field at position index, null if not found */ protected String getValue(int index) { StringTokenizer st = new StringTokenizer(this.info,"\t"); String ret; //System.out.println("Nb tokens : "+st.countTokens()); try { st.nextElement(); // skip the triangle for(int i=0;i0 ) { int b = ret.indexOf('>',a+1); if( b>=0 ) ret=ret.substring(a+1,b); } } } //catch(NoSuchElementException e) {return "";} catch(NoSuchElementException e) {return null;} return ret.trim(); } /** Returns the unit for the field at position pos */ protected String getUnit(int pos) { if(pos<0) return ""; return leg.field[pos].unit; } } .x,p.y+L, p.x-L,p.y); g.drawLine(p.x-L,p.y, p.x,p.y-L); if( withlabel ) { cds/aladin/Split.java010064400076440000132000000160170770227416100155130ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Bouton Split pour faire deux fenetres * * @@author Pierre Fernique [CDS] * @@version 1.0 : (26 fevreier 2002) Creation */ public final class Split extends Canvas { static final String DESCRIPTION = "Click here to split/unsplit the interface"; static final int H = 22; // Hauteur de la fenetre static final int W = 35; // Gestion du bouton de Warning static boolean oup=false; // Vrai si le warning precedent est up static boolean up=true; // Vrai si le warning est up Aladin aladin; Image img; // Image du double buffer Graphics g; // Contexte graphique du double buffer FrameMesure f=null; // Frame des mesures en fenetre externe static final int fx[] = { 7,8,12,16,14,23,19,16,15,15,16,12,7 }; static final int fy[] = {19,12,7,5,2,4,12,7,11,15,19,15,19}; /** Creation de l'element du Warning. * @@param aladin reference */ protected Split(Aladin aladin) { this.aladin=aladin; resize(W,H); } /** Affichage du bouton du Warning. * Utilise la valeur de up et oup pour determiner * si le bouton doit etre enfonce ou relache et s'il est necessaire * de le reafficher */ private void drawLogo() { Polygon p; if( up==oup ) return; g.setFont(Aladin.SPLAIN); g.setColor( Aladin.BKGD ); g.fillRect(0,0,W,H); g.setColor(Color.black); if( up ) { p = Tool.setPolygon(fx,fy,0,0); g.drawString("out",20,22); } else { int x[] = new int[fx.length]; int y[] = new int[fy.length]; for( int i=0; i0 ) aladin.pad.setText("New target: "+memoBis+"\n"); } // Affichage ou re-affichage du buffer public void paint(Graphics gr) { if( img==null || g==null || img.getWidth(this)!=size().width || img.getHeight(this)!=size().height) { update(gr); return; } //Affichage du buffer du paint gr.drawImage(img,0,0,null); } /** Retourne la chaine de texte associee au help en ligne */ protected String Help() { return aladin.calque.select.Help(); } // Gestion du Help public boolean handleEvent(Event e) { if( Aladin.inHelp ) { if( e.id==Event.MOUSE_ENTER ) aladin.help.setText(Help()); return true; } return super.handleEvent(e); } } cds/aladin/Texte.java010064400076440000132000000147110770227416100155100ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Objet graphique texte affichable dans la vue * * @@author Pierre Fernique [CDS] * @@version 1.1 : (11 mai 99) Correctoin du bug de la font * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Texte extends Position { // Variables d'etat boolean inprogress; // Vrai si le texte est en cours d'edition /** Font du texte */ static Font F=Aladin.PLAIN; // Pour s'economiser du travail int dw,dh; // Demi-Taille du texte (fct de la fonte) /** Creation du texte. * @@param plan plan d'appartenance de la ligne * @@param x,y position du texte */ protected Texte(Plan plan, double x, double y) { super(plan,x,y,0,0,XY|RADE_COMPUTE,""); inprogress = true; } /** Creation du texte. * @@param plan plan d'appartenance de la ligne * @@param x,y position du texte * @@param id texte initial */ protected Texte(Plan plan, double x, double y,String id) { super(plan,x,y,0,0,XY|RADE_COMPUTE,id); setWH(); } /** Creation d'un texte dont la position est donnee en coord RA/DEC */ protected Texte(Plan plan,Coord c,String id) { super(plan,0,0,c.al,c.del,RADE|XY_COMPUTE,id); setWH(); } /** Creation d'un texte pour les bakcups */ protected Texte(Plan plan) { super(plan); } /** Modification de l'identificateur. * Cela revient a modifier le texte * @@param id le nouveau texte */ protected void setText(String id) { super.setText(id); setWH(); } /** Positionne le flag de inprogress. * Cela signifie que le texte est en cours d'edition et qu'il faut * afficher le ``caret'' a la fin * @@param flag true si c'est vrai false sinon */ protected void inProgress(boolean flag) { inprogress = flag; } /** Precalcul la taille du texte */ void setWH() { FontMetrics m = Toolkit.getDefaultToolkit().getFontMetrics(F); dw = m.stringWidth(id)/2; dh = HF/2; } /** Test d'appartenance. * Retourne vrai si le point (x,y) de l'image se trouve sur le texte * @@param x,y le point a tester * @@param z le zoom courant */ protected boolean inside(double x, double y,double z) { double dw=this.dw/z; double dh=this.dh/z; return( x>=this.x-dw && x<=this.x+dw && y>=this.y-dh && y<=this.y+dh ); } /** Generation d'un clip englobant. * Retourne un rectangle qui englobe l'objet * @@param zoomview reference au zoom courant * @@return le rectangle enblobant */ protected Rectangle getClip(ZoomView zoomview){ Point p = getViewCoord(zoomview,dw,dh); if( select ) return new Rectangle(p.x-dw-5-DS,p.y-dh-DS,dw*2 +10+DDS,dh*2 +8+DDS); else return new Rectangle(p.x-dw-5,p.y-dh,dw*2 +10,dh*2 +8); } /** Affiche le texte * @@param g le contexte graphique * @@param zoomview reference au zoom courant */ protected void draw(Graphics g,ZoomView zoomview,int dx,int dy) { Point p = getViewCoord(zoomview,dw,dh); if( p.x<0 ) return; p.x+=dx; p.y+=dy; g.setFont(F); g.setColor( plan.c ); g.drawString(id,p.x-dw,p.y+dh); if( inprogress ) { int [] caretx = new int[3]; int [] carety = new int[3]; caretx[0] = p.x+dw+2; caretx[1]=caretx[0]-3; caretx[2]=caretx[0]+3; carety[0] = p.y+dh-2; carety[1]=carety[2] = carety[0]+7; g.fillPolygon(caretx,carety,3); } if( select ) drawSelect(g,zoomview); } } cds/aladin/Tool.java010064400076440000132000000616110770227416100153350ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion des differents outils de la barre des boutons * * @@author Pierre Fernique [CDS] * @@version 1.3 : (27 fev 02) Ajout du bouton Contour * @@version 1.2 : (31 jan 02) Ajout du bouton RGB * @@version 1.1 : (28 mars 00) Retoilettage du code * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Tool { // Couleurs geres static final Color CS = Color.black; // Couleur si l'outil est selectionnable static final Color CNS = Color.gray; // COuleur si l'outil n'est pas selectionnable static final Color CD = Aladin.MAXBLUE; // Couleur du bouton appuyé static final Color CU = Aladin.BLUE; // Couleur du bouton releve // Differents modes possible d'un bouton static final int UNAVAIL = 0; // 0 - UP/non-selectionnable static final int UP = 1; // 1 - UP/selectionnable static final int DOWN = -1; // -1 - DOWN/selectionnable // Reference aux autres objets Aladin aladin; Calque calque; // Parametres generaux static int H; // Hauteur d'un bouton static int W; // Largeur d'un bouton // Valeurs a memoriser int ntool; // Type de l'outil int omode; // Precedent mode; int mode; // Mode du bouton // Liste des outils n'ayant pas d'une icone static final int [] noIcone = { }; // Les labels de chaque outils static final String [] label = { "selec","draw","text","tag","dist", "del","mglss","prop","zoom", "hist", "pad", "rgb", "cont","filter" }; // L'explication (1 ligne) de chaque outils static final String [] explanation = { /* 0 */ "Object selector - click and drag with or without the Shift key", /* 1 */ "Overplot drawer - click or drag to append lines", /* 2 */ "Overplot text editor - click and type text" , /* 3 */ "Overplot marker - click on a position", /* 4 */ "Overplot measurer - click or drag to set a vector", /* 5 */ "Clear current selected objects or selected planes", /* 6 */ "Activate the magnifying glass around the mouse", /* 7 */ "Show properties of the selected plane", /* 8 */ "Zoom forwards or backwards (with Shift key) on the current field", /* 9 */ "Color map fixer", /*10 */ "Open the pad - to cut-and-paste, memorize", /*11 */ "Create an RGB image", /*12 */ "Create an isocontour plane", /*13 */ "Create a filter plane", }; // L'explication (help) de chaque outils static final String [] help = { /* 0 */ "The ``object selector'' is the default tool of Aladin Java. "+ "It's goal is to allow you to select one or several objects "+ "in the ``View window''. To do so, just click on an object (source "+ "or graphic symbol) or enclose them with a rectangle. "+ "For all selected sources, the associated measurements are displayed "+ "in the ``Measurement window''.\n"+ "You can extend/modify the current selection by holding down "+ "the SHIFT key during a new selection.\n"+ "To unselect all current objects, just click on a blank area "+ "or click again on the SELECT button.\n"+ "If there is no current selection and you click again on the "+ "SELECT button, all sources in the current plane (see the "+ "``plane stack'') will be selected.\n \n"+ "Selected graphic symbols can be moved by clicking again "+ "and dragging the mouse", /* 1 */ "The ``Overplot drawer'' allows you to add lines and curves to"+ "the ``View window''.\n \nHolding down the mouse button"+ "during drawing creates a curve; simply "+ "clicking at the beginning creates a polyline until "+ "you exit the ``View window''.", /* 2 */ "The ``Overplot text editor'' allows you to add text to the ``View window''.\n "+ "\nClick on the desired position in the ``View window'' and "+ "type the text.", /* 3 */ "The ``Overplot marker'' allows you to mark (+) positions on the ``View window''.\n"+ "If you click and drag the mouse englobing catalogue sources, "+ "all sources in the area are marked. Then, they can be moved in order to "+ "find similar shape.", /* 4 */ "The ``Overplot measurer'' allows you to draw vectors in the ``View window''.\n "+ "\nAfter creation, the length of the vector is given in the ``Status window''."+ "(delta RA, delta DE, "+ "and size in arcmin) as you move around.", /* 5 */ "This tool allows you to delete selected objects (see SELECT button) "+ "Only graphic symbols can be deleted ; the sources can't be "+ "cleared individually. If there are no selected objects, "+ "the current plane is deleted (see the ``plane stack'')."+ "\n \nWarning: there is no ``undo'' function.", /* 6 */ "This tool actives the magnifying glass around the mouse. "+ "The ``Zoom window'' window shows the region in the vicinity"+ "of the mouse when it is in the ``View window''.\n"+ "In this mode, you can use the arrow keys to focus the pointer "+ "and the RETURN key to validate the new position.\n \n", /* 7 */ "Opens a window with the properties of the current selected plane.\n"+ "This window allow you to modify the plane label, the color "+ "and the shape for the sources and all other parameters associated "+ "to the plane.", /* 8 */ "This tool allows you to zoom forwards or backwards (with the Shift key) "+ "in the current field. Click where you wish in the ``View window'' and "+ "wait for the new view (a few secondes).\n \nSee the ``Zoom window'' for "+ "another way to employ the zoom function.", /* 9 */ "This tool allows you to enhance the current image by modifying "+ "the dynamic of the color map :\n"+ ".move the left triangle towards the right to suppress the background noise\n"+ ".move the right triangle towards the left to enhance the objects\n"+ ".adjust the last triangle according to the gray histogram to "+ "enhance the intermediate gray levels\n"+ ".reverse the gray levels by pressing the REVERSE button", /*10 */ "This tool opens the ``pad''. "+ "This pad is just dedicated to memorize values of tags, distances, "+ "or source measurements. "+ "By this way you can cut-and-paste these values to other applications.\n"+ "Just click on this button to copy the informations of the selected objects\n"+ "into the pad.\n \n", /*11 */ "This tool allows you to create an RGB image. "+ "An RGB image is a composed image built with three "+ "other images already loaded in the plane stack.\n"+ "The resampling used to do that is based on the nearest "+ "pixel position.\n \n", /*12 */ "This tool allows you to plot contours in the image "+ "according to the grey levels you choose.\n \n", /*13 */ "This tool allows you to constraints the overlayed object "+ "characteristics (shape, color, hidden/shown,...) "+ "by defining a \"filter\" plane. \n \n", }; // Les parametres graphiques... // Decalage (centre) de chaque icone (dans l'ordre) static final int [] dX = { /* 0 */ 7, /* 1 */ 6, /* 2 */ 12, /* 3 */ 9, /* 4 */ 12, /* 5 */ 10, /* 6 */ 10, /* 7 */ 12, /* 8 */ 8, /* 9 */ 12, /*10 */ 13, /*11 */ 5, /*12 */ 0, /*13 */ -6 }; static final int [] dY = { /* 0 */ 11, /* 1 */ 10, /* 2 */ 10, /* 3 */ 10, /* 4 */ 5, /* 5 */ 10, /* 6 */ 10, /* 7 */ 10, /* 8 */ 10, /* 9 */ 11, /*10 */ 9, /*11 */ 8, /*12 */ 0, /*13 */ 9 }; // La fleche de selection static final int [] selectX = { 0,10, 5, 9, 7, 3, 0,0 }; static final int [] selectY = { 0,10,10,17,18,11,14,0 }; // Le manche du crayon static final int [] craymX = { 3,14,15,17,18, 7, 5, 4, 3, 3}; static final int [] craymY = { 11,0, 0, 2, 4,15,14,13,12,11 }; // La pointe du crayon static final int [] craypX = { 0, 3, 3, 4, 5, 7, 0 }; static final int [] craypY = { 18,11,12,13,14,15,18 }; // Les deux traits du crayon (dans le manche static final int [] craytX = { 3,15,17, 5 }; static final int [] craytY = { 12, 0, 2,14 }; // le dessin du A static final int [] exAX = { 0, 1,17,18,18,19,14,15,15, 2, 3, 0 }; static final int [] exAY = { 16,16, 0, 0,16,16,16,16, 3,16,16,16 }; // La barre du A static final int [] bAX = { 8,15, 8}; static final int [] bAY = { 10,10,10}; //Le dessin du repere (rectangle horizontal) static final int [] hRX = { 0,18,18,0, 0 }; static final int [] hRY = { 10,10, 8,8,10 }; //Le dessin du repere (rectangle vertical) static final int [] vRX = { 10,10, 8,8,10 }; static final int [] vRY = { 0,18,18,0, 0 }; //Le dessin de la fleche de mesure de distance static final int [] fmX = { 0,5,5,17,17,22,17,17,5, 5, 0 }; static final int [] fmY = { 5,0,4, 4, 0, 5,10, 6,6,10, 5 }; //Le repere 1 de la fleche de mesure de distance static final int [] t1mX = { fmX[0],fmX[0] }; static final int [] t1mY = { fmY[1],fmY[6] }; //Le repere 2 de la fleche de mesure de distance static final int [] t2mX = { fmX[5],fmX[5] }; static final int [] t2mY = { fmY[1],fmY[6] }; /* //Le carre du label static final int [] clX = { 8, 3, 3,14,14}; static final int [] clY = { 0, 0,11,11, 8}; // La position du texte du label static final int lX = 10; static final int lY = 7; // Le texte du label static final String lS = "AZ"; */ // La croix static final int [] crX = { 2,9,16,17,10,17,16, 9, 2, 1,8,1,2 }; static final int [] crY = { 0,7, 0, 1, 8,15,16, 9,16,15,8,1,0 }; // La mini-fenetre des proprietes static final int [] p1X = { 0,23,23, 0, 0 }; //Bord externe static final int [] p1Y = { 0, 0,18,18, 0 }; static final int [] p2X = { p1X[0]+2,p1X[1]-2,p1X[2]-2,p1X[3]+2, p1X[0]+2}; //Bord interne static final int [] p2Y = { p1Y[0]+5,p1Y[1]+5,p1Y[2]-2,p1Y[3]-2, p1Y[0]+5}; static final int [] p3X = { 1,1,3,3, 1 }; //Petit rectangle static final int [] p3Y = { 1,3,3,1, 1 }; // Le manche de la loupe static final int [] lpX = { 12,19,17,10,12 }; static final int [] lpY = { 9,16,18,11, 9 }; // Le Z du Zoom static final int [] zX = { 0,11,11, 2,11,11, 0, 0,9,0, 0 }; static final int [] zY = { 0, 0, 2,13,13,15,15,13,2,2, 0 }; // Le graphique des couleurs static final int [] cmX = { 0, 0, 0,16}; // L'abscisse static final int [] cmY = { 0,16, 24,16}; // L'ordonnee static final int [][] cmb = {{ 3,9, 4, 7}, // Les barres { 6, 3, 4,13}, { 9, 0, 4,16}, { 12, 2, 4,14}, { 15, 7, 4,9}}; static final int [] cmlX= { 1,15,25}; // Les X de la courbe de reponse static final int [] cmlY= {15, 9, 0}; // Les X de la courbe de reponse /* // Le graphique pour le SED static final int [] sedX= { 4,8,12,16,20,22}; // Les X de la courbe static final int [] sedY= { 14,4,12, 8,12,12}; // Les Y de la courbe // Le graphique pour le ACE static final int [] aceX= { 4, 5,11,12,16,18,19,20}; // Les X des objets static final int [] aceY= { 8,14, 4,10,15,8, 8,13}; // Les Y des objets */ /** Construction d'un outil * @@param n numero de l'outil (cf ToolBox.DRAW...) * @@param aladin Reference */ protected Tool(int ntool,Aladin aladin) { this.aladin = aladin; this.calque = aladin.calque; this.ntool = ntool; mode = UNAVAIL; omode = DOWN; } /** Fixe la taille des boutons * @@param newW,newH Nouvelles tailles */ protected static void resize(int newW,int newH) { W=newW; H=newH; } /** Selection/Deselection de l'outil (mode UP <-> DOWN) */ protected boolean Push() { if( mode==UNAVAIL ) return false; mode=-mode; return true; } /** Affichage de la description associee a l'outil */ protected void getInfo() { if( ntool>=explanation.length ) aladin.status.setText(""); else aladin.status.setText(explanation[ntool]); } // Creation et deplacement d'un polygone static Polygon setPolygon(int [] x, int [] y, int dx, int dy) { Polygon p = new Polygon(x,y,x.length); for( int i=0; i-1 sinon */ protected int getTool() { for( int i=0; inull */ protected Objet newTool(Plan plan, double x, double y) { int tool = getTool(); switch(tool) { case DRAW: return new Ligne(plan,x,y); case TEXT: return new Texte(plan,x,y); case MARK: return new Repere(plan,x,y); case DIST: return new Cote(plan,x,y); default: return null; } } /** Mise en place de l'etat des boutons. * Positionne les tools en fonction des plans courants actifs */ protected void toolMode() { Plan [] plan = calque.plan; // Pour simplifier int [] omode = new int[NBTOOL]; // etats precedents des tools int [] mode = new int[NBTOOL]; // prochains etats des tools int [] ex = {}; // tmp int nbc = 0; // Nombre de plans courants actifs int nb =0; // Nombre de plans non-vides, valides int nbi = 0; // Nombre de plans images presents int n = -1; // index du dernier plan courant int i,j; boolean dorepaint = false; // Memorise les etats des boutons et prepare un tableau // ou tous les etats sont a 1 for( i=0; i0 ) mode[LABEL]=Tool.UP; else mode[LABEL]=Tool.UNAVAIL; */ // Cas particulier du tool WEN if( p==null ) mode[WEN]=Tool.UNAVAIL; else { if( omode[WEN]!=Tool.UNAVAIL ) mode[WEN] = omode[WEN]; else mode[WEN]=Tool.UP; } // Cas particulier du tool PROP (on n'y touche pas) if( nbc>0 ) { if( omode[PROP]==Tool.UNAVAIL) mode[PROP]=Tool.UP; else mode[PROP]=omode[PROP]; // thomas --> on ne touche pas non plus au tool FILTER mode[FILTER]=omode[FILTER]; } // Cas particulier du tool CONTOUR if( p!=null && !(p instanceof PlanImageRGB)) { if( omode[CONTOUR]==Tool.UNAVAIL ) mode[CONTOUR]=Tool.UP; else mode[CONTOUR]=omode[CONTOUR]; } else mode[CONTOUR]=Tool.UNAVAIL; // Cas particulier du tool COLOR et RGB if( p!=null ) { if( omode[COLOR]==Tool.UNAVAIL ) mode[COLOR]=Tool.UP; else mode[COLOR]=omode[COLOR]; } else mode[COLOR]=Tool.UNAVAIL; } // Cas particulier du bouton RGB if( nbi>1 ) { if( omode[RGB]==Tool.UNAVAIL ) mode[RGB]=Tool.UP; else mode[RGB]=omode[RGB]; } else mode[RGB]=Tool.UNAVAIL; // En fonction de l'etat anterieur, releve le bouton for( i=0; itrue le bouton est exclusif, false sinon */ protected boolean isExcTool(int n) { for( int i=0; itrue Ok, false sinon */ protected static boolean isForTool(int n) { for( int i=0; itrue Ok, false sinon */ protected boolean isHide(int n) { for( int i=0; i=0 && aladin.calque.plan[n].type==Plan.FILTER); if( newFilter || aladin.filterProperties.isShowing() ) { int indiceNew = aladin.view.calque.newPlanFilter(); /*if( newFilter&&first&&indiceNew>=0 ) { aladin.calque.plan[indiceNew].selected=true; System.out.println("toto"); }*/ } //tool[PROP].mode=Tool.DOWN; tool[FILTER].mode=Tool.DOWN; //System.out.println(aladin.toolbox.tool[ToolBox.FILTER].mode); aladin.calque.repaint(); //System.out.println(aladin.toolbox.tool[ToolBox.FILTER].mode); aladin.filterProperties.majProp(); handCursor();return true; } // Les boutons qui ne sont pas sur simple clic ne sont // pas pris en compte for( j=0; j=hs-L-1-L && y<=hs-1 && x>=ws/2-L && x<=ws/2+L ) { flagDim=true; deltaY=firstY=y; firstX=x; repaint(); return true; } // Recherche du bouton i = getNTool(x,y); if( i<0 ) return false; waitCursor(); // Cas particulier du SELECT + shift if( i==SELECT && tool[i].mode==Tool.DOWN && !calque.view.hasSelectedObjet() ) { j=calque.getFirstSelected(); if( j>=0 && calque.plan[j].type==Plan.CATALOG ) { calque.view.selectAllInPlan(calque.plan[j]); } return true; } // Creation automatique d'un plan tool si on clique sur un des // boutons suivants if( ToolBox.isForTool(i) && (tool[i].mode==Tool.UNAVAIL || e.shiftDown()) ) { calque.newPlanTool("Drawing "+(++NUMBERTOOL)); tool[i].mode=Tool.UP; tool[PROP].mode=Tool.UP; } // Cas des outils lies au plan tool if( isExcTool(i) ) { // on permute tous les boutons exclusifs if( tool[i].mode==Tool.UP ) { for( j=0; j=hs-2*L ) n=-2; else n=getNTool(x,y); aladin.help.setText(Help(n)); return true; } // Infos sur le changement de proportions if( y>=hs-L-L-1 ) { resizeCursor(); aladin.status.setText(ICONEBAR); return true; } // Info sur les boutons int i = getNTool(x,y); if( i<0 ) return true; if( tool[i].mode!=Tool.UNAVAIL || isForTool(i) ) handCursor(); else defaultCursor(); tool[i].getInfo(); return true; } //Retourne le numero du bouton en fonction de l'ordonnee y protected int getNTool(int x,int y) { int c = x/W; // quelle colonne ? int i = y/H + c*nb; if( i=HMIN ) break; } // On ajuste la hauteur du bouton pour equilibrer les colonnes // en jouant sur la taille du bouton (entre minimal et recommandee) for( H=HREC; H>HMIN ; H--) { if( H*nbtoolParColTitle : TreeBuilder

*

Description : Builds the hierarchical tree of available resources from a VOTable file

*

Copyright: 2003

*

Company: CDS

* @@author Thomas Boch * @@version 0.7: 24 juin 2003 - Prise en compte de la modif StoredImage * 0.65: 10 avril 2003 - Correction de bugs, ajout du tri sur les critères, et suppression de code non générique * 0.6 : 17 mars 2003 - Prise en compte de la modif de François B. (ajout de StorageMapping dans le fichier XML) Suppressions de la possibilité de parser du parfile * 0.5 : 21 Novembre 2002 (Creation) */ package cds.aladin; import java.net.URL; import java.io.InputStream; import java.util.*; import java.awt.Color; // for tests //import java.awt.*; import cds.savot.pull.*; import cds.savot.model.*; import cds.astro.Astroframe; public class TreeBuilder /*implements Runnable*/ { // different available modes static final int PARFILE = 0; static final int VOTABLE = 1; // different available types static final int VOTABLE_IDHA=0; static final int VIZIER=1; static final int SIAP=2; // ces valeurs devront être remplies et non prédéfinies comme actuellement private int indexCriteria=0; // index dans le TRSet du critère private int indexValue=1; // index dans le TRSet de la valeur du critère // pour le timeout //Thread runme; //boolean parserCreated = false; // variables needed for files complying with SIAP private static final String SIAP_IMAGE_TITLE = "VOX:Image_Title"; private static final String SIAP_RA = "POS_EQ_RA_MAIN"; private static final String SIAP_DE = "POS_EQ_DEC_MAIN"; private static final String SIAP_SCALE = "VOX:Image_Scale"; private static final String SIAP_NAXIS = "VOX:Image_Naxis"; private static final String SIAP_IMAGE_FORMAT = "VOX:Image_Format"; private static final String SIAP_URL = "VOX:Image_AccessReference"; // pour le SIAP (modifié pour démo) généré par le serveur Aladin, on va prendre en compte les ID plutot que les UCD private static final String SIAP_ALADIN_FORMAT = "OriginalCoding"; private static final String SIAP_ALADIN_COLOR = "VOX:BandPass_ID"; // different fields of the parfile private static final String SURVEY = "SRV"; private static final String COLOR = "COL"; private static final String ID = "ID"; private static final String POSITION = "POS"; private static final String X = "X"; private static final String Y = "Y"; private static final String RESOLUTION = "RES"; private static final String IDSURVEY = "ObservingProgram"; private static final String IDBAND = "Observation_Group"; private static final String IDIMAGE = "Observation"; private static final String IDMAPPING = "StorageMapping"; private static final String IDSTORED = "StoredImage"; private static final String CUTOUT = "CUTOUTS"; private static final String AVAILABLE_CODINGS = "AvailableCodings"; double xVal, yVal, alphaVal, deltaVal; String[] descFilter; double angleVal = 0.0; // PARFILE ou VOTABLE // mode PARFILE abandonné actuellement private int mode; // type = [VOTABLE_IDHA | VIZIER | SIAP] private int type; // serveur d'ou proviennent les ressources private Server server = null; static private Color[] colTab = {Color.green, Color.orange, Color.magenta, Color.cyan, Color.pink}; static private int colorNb=0; // memorisation du dernieur noeud "band: cree private ResourceNode nodeMemo; // pour determiner la couleur du fov private Color fovColor; // pour recuperer la taille d'un cutout private double maxSize,pixSize; // pour conversion sexa<->decimal private Astroframe frame = new Astroframe(); // strem permettant de constuire l'arbre private InputStream is; // url permettant de construire l'arbre private URL url; // nom du fichier permettant de constuire l'arbre private String file; private SavotPullParser savotParser; // variables de travail private int nameIndex = 0; private String currentSurvey, currentColor; private FieldSet surveyFieldSet, bandFieldSet, imageFieldSet, filterFieldSet, mappingFieldSet, storedFieldSet; // contient la correspondance Resource --> FieldSet private Hashtable fieldSetMapping = new Hashtable(); /** Constructor * @@param file - xml file * @@param mode - PARFILE or VOTABLE * @@param type - type of file being processed : [VOTABLE_IDHA | VIZIER | SIAP] * @@param server - serveur d'où proviennent les ressources (peut être null) */ TreeBuilder(String file, int mode, int type, Server server) { this.file = file; this.mode = mode; this.type = type; this.server = server; createSavotParser(); } /** Constructor * @@param url - url to retrieve the xml document * @@param mode - PARFILE or VOTABLE * @@param type - type of file being processed : [VOTABLE_IDHA | VIZIER | SIAP] * @@param server - serveur d'où proviennent les ressources (peut être null) */ TreeBuilder(URL url, int mode, int type, Server server) { this.url = url; this.mode = mode; this.type = type; this.server = server; createSavotParser(); } /** Constructor * @@param is - the stream holding the xml document * @@param mode - PARFILE or VOTABLE * @@param type - type of file being processed : [VOTABLE_IDHA | VIZIER | SIAP] * @@param server - serveur d'où proviennent les ressources (peut être null) */ TreeBuilder(InputStream is, int mode, int type, Server server) { this.is = is; this.mode = mode; this.type = type; this.server = server; createSavotParser(); } /** détecte s'il s'agit d'un fichier au format VOTABLE_IDHA ou SIAP ou VIZIER */ private void detectFormat() { if( type>=0 ) { Aladin.trace(3,"detect format of "+file!=null?file:url+": format was already specified"); return; } // on récupère la première ressource SavotResource firstRes = (SavotResource)savotParser.getVOTable().getResources().getItemAt(0); if( firstRes==null ) { Aladin.trace(3,"Could not determine type, stream contains no RESOURCE"); return; } String myType = firstRes.getType(); if( myType==null ) myType = ""; if( myType.equals("results") ) { type = SIAP; Aladin.trace(3,"detect format of "+file!=null?file:url+": SIAP"); return; } String name = firstRes.getId(); if( name==null || name.length()==0 ) name = firstRes.getName(); if( name!=null && ( name.equalsIgnoreCase(IDSURVEY) || name.equals(IDBAND) ) ) { type = VOTABLE_IDHA; Aladin.trace(3,"detect format of "+file!=null?file:url+": VOTABLE_IDHA"); return; } // méthode très médiocre en attendant mieux if( myType.equals("meta") ) { type = VIZIER; Aladin.trace(3,"detect format of "+file!=null?file:url+": VIZIER"); return; } Aladin.trace(3,"format of "+file!=null?file:url+" could not be determined"); } // modifie le flux /* private InputStream getBidouilledStream() { DataInputStream dis=null; String CR = System.getProperty("line.separator"); StringBuffer output = new StringBuffer(); try { if( file!=null ) dis = new DataInputStream(new FileInputStream(file)); else dis = new DataInputStream(url.openStream()); } catch(Exception e) {e.printStackTrace();} String line; try { while( (line=dis.readLine())!=null ) { int begin = line.indexOf(""); if( begin>=0 && end>begin ) { line = replaceBidouille(line,begin,end); } output.append(line); output.append(CR); } } catch(IOException ioe) {ioe.printStackTrace();} return new BufferedInputStream(new ByteArrayInputStream(output.toString().getBytes())); } private String replaceBidouille(String str,int begin,int end) { String ret = str.substring(0,begin)+URLEncoder.encode(str.substring(begin+9,end))+str.substring(end+3); return ret; } */ /** builds the tree */ protected ResourceNode build() { // recherche du target searchTarget(); detectFormat(); // bidouille pour remplacer les par url encodé !! // partie à supprimer quand André aura corrigé Savot /* if( type==SIAP ) { InputStream is = getBidouilledStream(); savotParser = new SavotPullParser(is, SavotPullEngine.FULL, null); } */ if( type==VOTABLE_IDHA ) return buildVotable(); else if( type==VIZIER ) return buildCatVotable(); else if( type==SIAP ) return buildSIAPVotable(); return null; } // cette variable est fixée lors du build() // elle correspond au target trouvé dans le VOTable private String targetFound = null; /** search for the target in the VOTABLE file */ private void searchTarget() { if( savotParser==null ) return; // pour recherche IDHA InfoSet infos = savotParser.getVOTable().getInfos(); SavotInfo info; for( int i=0; i0 ) { descStr[i] = name; } else { descStr[i] = desc[i].getId(); } descId[i] = desc[i].getId(); } String unit; // recuperation des valeurs des TD for( int i=0; i0 && unit.length()>0 ) { //expla[i] += " "+unit; expla[i] = getUnit(expla[i],unit); } } } } // fin de la boucle sur tous les expla // on transforme RA et DE de degres decimaux a degres sexagesimaux if( indexRA>=0 && indexDE>=0 ) { try { frame.set(expla[indexRA]+" "+expla[indexDE]); frame.setPrecision(Astroframe.ARCSEC+1); String coord = frame.toString(":"); int beginDE = coord.indexOf("+"); if( beginDE==-1 ) beginDE= coord.indexOf("-"); expla[indexRA] = coord.substring(0,beginDE); expla[indexDE] = coord.substring(beginDE); } catch( Exception e) {} } myIndexRA = indexRA; myIndexDE = indexDE; ResourceNode node = new ResourceNode(); node.type = ResourceNode.IMAGE; node.server = this.server; node.description = descStr; node.explanation = expla; node.color = color; // pour bidouille aladin node.survey = survey; // pour bidouille aladin node.machine = machine; // pour bidouille aladin node.resol = resol; // pour bidouille aladin node.plateNumber = plateNumber; // pour bidouille Aladin node.isLeaf = true; if( index>=0 ) { node.name = expla[index]; } // on ne le fait pas pour le moment //node.cutout = cutout; // BIDOUILLE A CAUSE DES VUES LOW & FULL if( cutout ) { // ce passage par resolveTarget est AFFREUX String target = server.tree.resolveTarget(server.getTarget()); String coord=null; try { frame.set(target); frame.setPrecision(Astroframe.ARCSEC+1); //coord = TreeView.getDeciCoord(frame.toString(":")); coord = TreeView.getDeciCoord(target).trim(); } catch(Exception e) {} //System.out.println(coord); if( coord!=null ) { int beginDE = coord.indexOf("+"); if( beginDE==-1 ) beginDE= coord.indexOf("-"); // forçage des valeurs alphaVal et deltaVal alphaVal = new Double(coord.substring(0,beginDE)).doubleValue(); deltaVal = new Double(coord.substring(beginDE)).doubleValue(); //expla[indexRA] = coord.substring(0,beginDE); //expla[indexDE] = coord.substring(beginDE); } } // si cutout, on set le target cutout à la target de la zone disponible lors de la création d'un noeud if( node.cutout /*&& server!=null*/ ) { //node.setCutoutTarget(server.getTarget(),false); if( myIndexRA>=0 && myIndexDE>=0 ) node.setCutoutTarget(node.explanation[myIndexRA]+" "+node.explanation[myIndexDE],false); } // bidouille pour Aladin, on ne se sert pas de la location pour le moment if( indexLocation>=0 && !(server instanceof AladinServer) ) { node.location = expla[indexLocation]; } xVal=0; yVal=0; // on va calculer la taille de l'image if( indexScale>=0 && indexNaxis>=0 ) { String[] imScale = split(scale,", "); String[] format = split(naxis,", "); if( format.length>=2 && imScale.length>=2 ) { try { xVal = Math.abs(new Double(imScale[0]).doubleValue() * new Double(format[0]).doubleValue()); yVal = Math.abs(new Double(imScale[1]).doubleValue() * new Double(format[1]).doubleValue()); } catch(NumberFormatException e) { } } String unitScale = desc[indexScale].getUnit(); if( unitScale!=null && unitScale.length()>0 ) { expla[indexScale] = getUnit(imScale[0],unitScale)+" "+getUnit(imScale[1],unitScale); } /*System.out.println(xVal); System.out.println(yVal); System.out.println(alphaVal); System.out.println(deltaVal);*/ } // format de l'image (FITS,JPEG) if( indexImgFormat>=0 ) { node.formats = split(imgFormat,","); // par défaut, le format est le premier node.curFormat = node.formats[0]; } createFov(node); return node; } // Retourne le résultat d'un tokenizer sous forme de tableau private String[] split(String str,String sep) { //System.out.println(str); StringTokenizer st = new StringTokenizer(str,sep); String[] ret = new String[st.countTokens()]; int i=0; while( st.hasMoreTokens() ) { ret[i] = st.nextToken(); i++; } return ret; } /** Remove the ![CDATA[...]] part around the URL string */ /* private String skipCDATA(String s) { s = s.trim(); if( s.startsWith("![CDATA[")) s = s.substring(8); if( s.endsWith("]]>")) s = s.substring(0,s.length()-3); return s; } */ /* ---- FIN Méthodes pour constuire l'arbre partant d'un fichier SIAP ---- */ /* ---- Méthodes pour la construction de l'arbre à partir d'un fichier VOTABLE_IDHA ---- */ /** Construit l'arbre des images a partir du votable */ private ResourceNode buildVotable() { // partie abandonnée pour le moment // a voir si c'est nécessaire /* // on cree le parser runme = new Thread(this); runme.setPriority(Thread.NORM_PRIORITY -1); runme.start(); long tOut = 1000*20; long begin = System.currentTimeMillis(); while(!parserCreated) { try { if( System.currentTimeMillis()-begin>tOut ) { if( runme!=null ) runme.stop(); return null; } Thread.currentThread().sleep(100); } catch(Exception e) {} } */ if( savotParser==null ) { return null; } SavotVOTable vot = savotParser.getVOTable(); ResourceSet rootResSet = vot.getResources(); // noeud racine ResourceNode root = new ResourceNode("root"); root.type = ResourceNode.VOID; // on lance le processus : appel de processResource pour tous les RESOURCE racines for( int i=0; i valeur Hashtable critVal = new Hashtable(); // map nom critère --> SavotResource avec infos Hashtable infoVal = new Hashtable(); SavotResource storageMapping = null; SavotResource storedImage = null; SavotResource processedObs = null; TDSet tdSet; String epoch=null; // on récupère les couples "nom critère" <-> "valeur" for( int i=0; i0 && ! (server instanceof AladinServer) ) resTab[i].location = URLDecode(location); //System.out.println(resTab[i].location); } */ if( descStr.equalsIgnoreCase("Cutout") && td.getContent().equals(CUTOUT) ) { //System.out.println("c est un cutout"); resTab[i].cutout = true; // si cutout, on set le target cutout à la target de la zone disponible lors de la création d'un noeud if( myIndexRA>=0 && myIndexDE>=0 ) resTab[i].setCutoutTarget(resTab[i].explanation[myIndexRA]+" "+resTab[i].explanation[myIndexDE],false); /* if( server!=null ) { resTab[i].setCutoutTarget(server.getTarget(),false); //resTab[i].setCutoutTarget(resTab,false); } */ } //if( descStr.equals("Maximum size") ) { if( descStr.equalsIgnoreCase("size") ) { try { maxSize = new Double(td.getContent()).doubleValue(); } catch( NumberFormatException e) {maxSize = -1.0;} } } } // ici traitement du nouvel élément de François // Traitement de StoredImage if( storedImage!=null ) { TDSet tds = ((SavotTR)trStored.getItemAt(i)).getTDs(); SavotTD td; for( int j=0; j0 && ! (server instanceof AladinServer) ) resTab[i].location = URLDecode(location); //System.out.println(resTab[i].location); } } } resTab[i].isLeaf = true; // survey et color sont pour le moment nécessaires pour pouvoir charger les images resTab[i].survey = currentSurvey; resTab[i].color = currentColor; // epoch pour les labels des plans resTab[i].epoch = epoch; createFov(resTab[i]); //System.out.println(resTab[i].name); } // A ce stade, resTab est rempli de toutes les ResourceNode correspondant aux données // qu'on va refiler à une fonction avec l'ordre de tri // ladite fonction sera réutilisée pour trier correctement (popup) sortAndCreate(resTab, parent, parent.sortCriteria, infoVal); } /** fait le boulot de URLDecoder.decode() qui n'existe pas en 1.1 */ public static String URLDecode(String encoded) { StringBuffer decoded = new StringBuffer(); int i=0; String charCode; char currentChar, decodedChar; while(i < encoded.length()) { currentChar = encoded.charAt(i); //'+' becomes 'space' if (currentChar == '+') { decoded.append(" "); i = i + 1; } else if (currentChar == '%') { charCode = encoded.substring(i+1, i+3); decodedChar = (char)Integer.parseInt(charCode, 16); decoded.append(decodedChar); i = i + 3; } //common case 'a' to 'z' ... else { decoded.append(currentChar); i = i + 1; } } return(decoded.toString()); } /** crée les noeuds nécessaires pour placer les feuilles contenus dans tab dans l'ordre défini dans criteria * * @@param tab * @@param parent * @@param criteria */ private void sortAndCreate(ResourceNode[] tab, ResourceNode parent, String[] criteria, Hashtable info) { if( tab.length==0 ) return; // tous les noeuds dans tab sont réputés faire référence au même criteriaVal Hashtable value = tab[0].criteriaVal; //System.out.println(tab[0].name+" thomas"); // parent auquel raccrocher le nouveau noeud créé ResourceNode curParent=parent; ResourceNode node; String name = null; // on crée les noeuds dans l'ordre imposé par criteria for( int i=0; i0*/ ) { processObsGroup(sr, father); return; } // création des noeuds pour chaque TR for( int i=0; i bizarre if( descMapping[j].equals("Organisation") && td.getContent().equals(CUTOUT) ) { newNode.cutout = true; } if( descMapping[j].equals("Maximum size") ) maxSize = new Double(td.getContent()).doubleValue(); } } newNode.isLeaf = true; newNode.survey = currentSurvey; newNode.color = currentColor; createFov(newNode); } // ajout de l'attribut epoch si necessaire if( nameRes.equals(IDIMAGE) && newNode.getParent().name.startsWith("epoch") ) newNode.epoch = newNode.getParent().name; */ } // System.out.println("in the loop"); //} if( id.equalsIgnoreCase(IDSURVEY) && newNode!=null ) currentSurvey = newNode.explanation[0]; // recursion ResourceSet rSet = sr.getResources(); //System.out.println(sr.getName()); for( int i=0; i0 ) { descStr[i] = name; } else { descStr[i] = desc[i].getId(); } descId[i] = desc[i].getId(); } String unit; // recuperation des valeurs des TD for( int i=0; i0 && unit.length()>0 ) { if( i!=indexPosAng ) expla[i] = getUnit(expla[i],unit); else expla[i] += " "+unit; //expla[i] += " "+unit; } } } } // fin de la boucle sur tous les expla // on transforme RA et DE de degres decimaux a degres sexagesimaux if( indexRA>=0 && indexDE>=0 ) { try { frame.set(expla[indexRA]+" "+expla[indexDE]); frame.setPrecision(Astroframe.ARCSEC+1); String coord = frame.toString(":"); int beginDE = coord.indexOf("+"); if( beginDE==-1 ) beginDE= coord.indexOf("-"); expla[indexRA] = coord.substring(0,beginDE); expla[indexDE] = coord.substring(beginDE); } catch( Exception e) {} } ResourceNode node = new ResourceNode(); node.type = ResourceNode.IMAGE; node.server = this.server; node.description = descStr; node.explanation = expla; if( index>=0 ) { node.name = expla[index]; } myIndexRA = indexRA; myIndexDE = indexDE; // format de l'image (FITS,JPEG) if( indexImgFormat>=0 ) { node.formats = split(imgFormat,","); // par défaut, le format est le premier if( node.formats!=null && node.formats.length>0 ) node.curFormat = node.formats[0]; } return node; } /* ---- FIN Méthodes pour la construction de l'arbre à partir d'un fichier VOTABLE_IDHA ---- */ /** Affichage dans la bonne unite. * Retourne un angle dont l'unité est unit sous forme de chaine dans la bonne unite * @@param x l'angle * @@param unit l'unité de x * @@return l'angle dans une unite coherente + l'unite utilisee */ protected static String getUnit(String angleStr, String unit) { double x; try { x = new Double(angleStr).doubleValue(); } catch(NumberFormatException e) { return angleStr+" "+unit; } // on met d'abord x en degrés if( unit.equalsIgnoreCase("deg") ) x = x/1.0; else if( unit.equalsIgnoreCase("arcmin") ) x = x/60.0; else if( unit.equalsIgnoreCase("arcsec") ) x = x/3600.0; else return x+" "+unit; String s=null; if( x>=1.0 ) s="deg"; if( x<1.0 ) { s="arcmin"; x=x*60.0; } if( x<1.0 ) { s="arcsec"; x=x*60.0; } x=((int)(x*100.0))/100.0; s=x+" "+s; return s; } } desc = getDescription(sr)cds/aladin/TreeLoader.java010064400076440000132000000327260770227416100164530ustar00ferniquecds00000400000013// // Copyright 1999-2003 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.net.*; /** Frame permettant de charger des metadata dans le tree view * @@author Thomas Boch [CDS] * @@version 0.1 (15 avril 2003) kickoff */ public class TreeLoader extends Frame { // référence à aladin Aladin a; // les serveurs pouvant renvoyer du XML Server[] server; Button[] button; TextField[] targetTF; TextField[] radiusTF; // pour accès au NOAO (présenté comme exemple d'accès à des services SIA) TextField noaoTarget; TextField noaoSize; Button noaoButton; // pour accès à SkyView (autre exemple de service SIA) TextField skyvTarget; TextField skyvSize; Button skyvButton; // pour accès à un fichier local TextField filePathTF; Button browseFile; Button addFile; // pour accès à une URL TextField urlTF; Button addURL; FileDialog fd; private static final String ADD2TREE = "Add to tree"; private static final String BROWSE = "Browse ..."; /* Constructeurs */ protected TreeLoader(Aladin a) { super("Tree loader"); setBackground(Aladin.BKGD); this.a = a; init(); buildFrame(); pack(); //show(); } /* Fin constructeurs */ private void init() { server = new Server[2]; server[0] = a.dialog.server[ServerDialog.ALADIN]; server[1] = a.dialog.server[ServerDialog.VIZIER]; radiusTF = new TextField[server.length]; targetTF = new TextField[server.length]; button = new Button[server.length]; } /** Construit la frame */ private void buildFrame() { setLayout(new BorderLayout()); GridBagLayout g = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); Panel p = new Panel(); p.setLayout(g); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(2,2,2,2); for( int i=0; i0 ) c.gridwidth = GridBagConstraints.RELATIVE; //titre Label title = new Label(server[i].nom); title.setFont(Aladin.BOLD); c.gridy=i; c.gridx=0; g.setConstraints(title, c); p.add(title); //c.weightx = 0.0; // label "target" Label target = new Label("Target"); target.setFont(Aladin.PLAIN); c.gridy=i; c.gridx=1; g.setConstraints(target, c); p.add(target); // textfield "target" targetTF[i] = new TextField(15); c.gridy=i; c.gridx=2; g.setConstraints(targetTF[i], c); p.add(targetTF[i]); // label "radius" Label radius = new Label("Radius"); radius.setFont(Aladin.PLAIN); c.gridy=i; c.gridx=3; g.setConstraints(radius, c); p.add(radius); // textfield "radius" radiusTF[i] = new TextField("10 arcmin"); c.gridy=i; c.gridx=4; g.setConstraints(radiusTF[i], c); p.add(radiusTF[i]); // bouton button[i] = new Button(ADD2TREE); /*button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { a.treeView.addBranch(tfTarget.getText(),tfRadius.getText(),curServer); } } );*/ //c.gridwidth = GridBagConstraints.REMAINDER; c.gridy=i; c.gridx=5; //c.weightx = 1.0; g.setConstraints(button[i], c); p.add(button[i]); } // ---- ajout d'une ligne pour chargement fichier local ---- // (version STANDALONE uniquement) if( Aladin.STANDALONE ) { //titre Label title = new Label("Local file"); title.setFont(Aladin.BOLD); c.gridy=server.length; c.gridx=0; g.setConstraints(title, c); p.add(title); // textfield pour nom du fichier filePathTF = new TextField(20); c.gridy=server.length; c.gridx=1; c.gridwidth = 3; g.setConstraints(filePathTF, c); p.add(filePathTF); // bouton pour ouvrir le sélecteur de fichiers browseFile = new Button(BROWSE); c.gridy=server.length; c.gridx=4; c.gridwidth = 1; g.setConstraints(browseFile, c); p.add(browseFile); // bouton pour charger dans le tree view addFile = new Button(ADD2TREE); c.gridy=server.length; c.gridx=5; c.gridwidth = 1; g.setConstraints(addFile, c); p.add(addFile); } // ---- ajout d'une ligne pour chargement URL entré par l'utilisateur ---- //titre Label title = new Label("URL"); title.setFont(Aladin.BOLD); c.gridy=server.length+1; c.gridx=0; g.setConstraints(title, c); p.add(title); // textfield pour nom du fichier urlTF = new TextField("http://",30); c.gridy=server.length+1; c.gridx=1; c.gridwidth = 4; g.setConstraints(urlTF, c); p.add(urlTF); // bouton pour charger dans le tree view addURL = new Button(ADD2TREE); c.gridy=server.length+1; c.gridx=5; c.gridwidth = 1; g.setConstraints(addURL, c); p.add(addURL); // Ajout d'une ligne pour NOAO //titre Label noaoTitle = new Label("NOAO SIA Service"); noaoTitle.setFont(Aladin.BOLD); c.gridy=server.length+2; c.gridx=0; g.setConstraints(noaoTitle, c); p.add(noaoTitle); // label "target" Label target = new Label("Target"); target.setFont(Aladin.PLAIN); c.gridy=server.length+2; c.gridx=1; g.setConstraints(target, c); p.add(target); // textfield "target" noaoTarget = new TextField(15); c.gridy=server.length+2; c.gridx=2; g.setConstraints(noaoTarget, c); p.add(noaoTarget); // label "size" Label size = new Label("Size"); size.setFont(Aladin.PLAIN); c.gridy=server.length+2; c.gridx=3; g.setConstraints(size, c); p.add(size); // textfield "size" noaoSize = new TextField("10 arcmin"); c.gridy=server.length+2; c.gridx=4; g.setConstraints(noaoSize, c); p.add(noaoSize); // bouton noaoButton = new Button(ADD2TREE); c.gridy=server.length+2; c.gridx=5; //c.weightx = 1.0; g.setConstraints(noaoButton, c); p.add(noaoButton); // Ajout d'une ligne pour SkyView //titre Label skyvTitle = new Label("SkyView SIA Service"); skyvTitle.setFont(Aladin.BOLD); c.gridy=server.length+3; c.gridx=0; g.setConstraints(skyvTitle, c); p.add(skyvTitle); // label "target" target = new Label("Target"); target.setFont(Aladin.PLAIN); c.gridy=server.length+3; c.gridx=1; g.setConstraints(target, c); p.add(target); // textfield "target" skyvTarget = new TextField(15); c.gridy=server.length+3; c.gridx=2; g.setConstraints(skyvTarget, c); p.add(skyvTarget); // label "size" size = new Label("Size"); size.setFont(Aladin.PLAIN); c.gridy=server.length+3; c.gridx=3; g.setConstraints(size, c); p.add(size); // textfield "size" skyvSize = new TextField("10 arcmin"); c.gridy=server.length+3; c.gridx=4; g.setConstraints(skyvSize, c); p.add(skyvSize); // bouton skyvButton = new Button(ADD2TREE); c.gridy=server.length+3; c.gridx=5; //c.weightx = 1.0; g.setConstraints(skyvButton, c); p.add(skyvButton); add(p,BorderLayout.CENTER); } protected void updateTF(String s) { for( int i=0; i=0 ) { a.treeView.addBranch(targetTF[index].getText(),radiusTF[index].getText(),server[index]); } } return true; } // Gestion des evenements public boolean handleEvent(Event e) { if( (e.id==Event.WINDOW_DESTROY ) ) { dispose(); } return super.handleEvent(e); } } cds/aladin/TreeView.java010064400076440000132000000655200770227416100161550ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.event.*; import java.net.*; import java.util.*; import java.io.InputStream; import cds.astro.Astroframe; /** * Le frame de visualisation hiérarchique (arbre) des données * * @@author Thomas Boch [CDS] * Juin 2003 --> découplement TreeView/MetaDataTree * @@version 0.6 : avril 2003 refonte profonde pour intégration dans Aladin * novembre 2002 (prototype pour avatar GOODS) */ public final class TreeView extends Frame implements Runnable,WindowListener { static final String NOM = "Tree View"; private static final String WERR = "Error"; private static final String SUBMIT = "Submit"; private static final String RESET = "Reset"; private static final String CLOSE = "Close"; MetaDataTree rt; // l'arbre des resources // noeud racine ResourceNode root; ScrollPane scrollTree; // ScrollPane contenant l'arbre // dimensions initiales du ScrollPane pour l'arbre private static final int SCROLL_TREE_WIDTH = 320; private static final int SCROLL_INFO_WIDTH = 360; Thread thread; //TextField radius; // le champ de saisie du radius //TextField centerCutOut; // le centre du cutout private Button buildTree; // pour construire l'arbre static private int nbRunningThread=0; // nombre de threads actifs TreeLoader treeLoader; String targetFound; // variable de travail // référence à aladin Aladin aladin; /** Creation du tree view * @@param aladin reference */ protected TreeView(Aladin aladin) { super("Tree view"); setSize(350,500); setBackground(Aladin.BKGD); setLayout(new BorderLayout(5,5)); GridBagConstraints c = new GridBagConstraints(); GridBagLayout g = new GridBagLayout(); c.fill = GridBagConstraints.NONE; c.gridwidth = GridBagConstraints.REMAINDER; this.aladin = aladin; Panel p = new Panel(); p.setLayout(g); // on ajoute un component pour gérer le click pour fermer la fenêtre addWindowListener(this); // Creation du Titre general // à remplacer par "Metadata browser" ?? titrePanel(p,"Data Tree",g,c); // Le panel de l'arbre hierarchique scrollTree = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED); scrollTree.setBackground(Aladin.LGRAY); scrollTree.setSize(SCROLL_TREE_WIDTH,getSize().height-70); //c.gridwidth = GridBagConstraints.RELATIVE; c.insets = new Insets(0,5,0,5); c.gridwidth = 1; c.gridheight = 1; c.anchor = GridBagConstraints.WEST; //c.weighty = 1.0; //c.weightx = 1.0; c.fill = GridBagConstraints.BOTH; c.weighty = 1.0; c.weightx = 1.0; // ?? g.setConstraints(scrollTree,c); p.add(scrollTree); // reset c.weighty = 0.0; c.weightx = 0.0; c.fill = GridBagConstraints.NONE; // Creation du Panel du target et du radius c.insets = new Insets(0,0,0,0); c.gridwidth = GridBagConstraints.REMAINDER; c.gridheight = 1; //centerCutOut = new TextField(15); //addCouple(p,"Cutout/image center",centerCutOut,new Label(""),g,c); //radius = new TextField("10 arcmin",15); /* buildTree = new Button("Build tree"); buildTree.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { buildTree(); } } ); */ //addCouple(p,"Radius",radius,buildTree,g,c); c.fill = GridBagConstraints.BOTH; c.weighty = 1.0; //reset to the default c.weightx = 1.0; // ?? //c.gridwidth = GridBagConstraints.REMAINDER; c.gridwidth = 3; c.gridheight = GridBagConstraints.REMAINDER; // reset GridBagConstraints c.fill = GridBagConstraints.NONE; // reset weightx c.weightx = 0.0; // Creation noeud racine ResourceNode root = new ResourceNode("root"); root.hide = true; root.isOpen = true; rt = new MetaDataTree(root,aladin,scrollTree); scrollTree.add(rt); add(p,BorderLayout.CENTER); add(buttonPanel(),BorderLayout.SOUTH); } /** Construction du panel des boutons Submit, Reset * @@return Le panel contenant les boutons Submit/Reset */ private Panel buttonPanel() { Panel p = new Panel(); p.setLayout( new FlowLayout(FlowLayout.CENTER)); p.setFont( Aladin.LBOLD ); p.add( new Button(SUBMIT)); p.add( new Button(RESET)); p.add( new Button(CLOSE)); return p; } // Méthodes implémentant l'interface WindowListener public void windowActivated(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowClosing(WindowEvent e) {hide();} public void windowDeactivated(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowOpened(WindowEvent e) {} // FIN méthodes implémentant l'interface WindowListener /** Méthode appelée par les classes spécialisant Server * Ajoute la branche correspondante dans l'arbre rt (historique) * Met à jour l'arbre passé en paramètre */ public void updateTree(InputStream is, MetaDataTree tree, Server server, String target) { if( server!=null && server.target!=null && (target==null || target.length()==0) ) { target = server.target.getText(); } ResourceNode newBranch = createNewBranch(null,is,null,null,server,null,false); // si on n'a pas le target, TreeBuilder l'a p-e trouvé dans le stream if( (target==null || target.length()==0) && targetFound!=null ) { target = targetFound; } if( target!=null && target.length()!=0 ) { rt.addNode(getTargetNode(target), newBranch); } else { rt.addNode((ResourceNode)rt.getRootNode(), newBranch); } // clonage ResourceNode clone = (ResourceNode)newBranch.clone(); // on cache le niveau avec le nom du serveur clone.hide = true; tree.setRoot(clone); // reset de targetFound targetFound = null; } /** Recherche un noeud du nom target. Retourne un nouveau noeud si non trouvé */ private ResourceNode getTargetNode(String target) { ResourceNode targetNode = (ResourceNode)rt.searchNodeByName(target); // if it does not exist yet, we first create this node if( targetNode==null ) { targetNode = new ResourceNode(target); rt.getRootNode().addChild(targetNode); rt.traverseTree(); } targetNode.isOpen = true; return targetNode; } private String resolveTarget(String s) { Coord c; try { if( !View.notCoord(s) ) c = new Coord(s); else c = aladin.view.getSimbad(s); } catch(Exception e) {return null;} return c.getSexa(":"); } /** Fonction appelée pour ajouter une branche à l'arbre * @@param target nom ou position de la target * @@param radius chaine représentant le rayon * @@param server serveur appelant cette méthode */ protected void addBranch(String target, String radius, Server server) { // first step : does a node called target already exists ? target = target.trim(); ResourceNode targetNode = getTargetNode(target); lock(); // set parameters for the thread parentT = targetNode; targetT = target; radiusT = radius; serverT = server; // launch the thread thread = new Thread(this); thread.start(); } protected void addBranch(String target, Server server) { addBranch(target,"0",server); } /** pour serveur SIA */ protected void addSIABranch(String urlStr, String target, String size, String serverName) { double sizeDeg = Server.getRadius(size)/60.0; String targetSexa = resolveTarget(target); if( targetSexa==null ) { Aladin.warning("Unknown object "+target,1); return; } String position = getDeciCoord(targetSexa).replace(' ',','); URL url=null; try { // on ne demande que les images FITS url = new URL(urlStr+"?POS="+position+"&SIZE="+sizeDeg+"&FORMAT=image/fits"); } catch(MalformedURLException e) { e.printStackTrace(); return; } aladin.trace(3,"Building SIA URL : "+url); ResourceNode targetNode = getTargetNode(target); lock(); // set the parameters for the thread parentT = targetNode; urlT = url; serverT = null; serverNameT = serverName; // launch the thread thread = new Thread(this); thread.start(); } protected void addBranch(URL url) { // recherche du target dans le fichier (la méthode me déplait car on va charger 2 fois le fichier) // voir si on conserve ça ou si on rattache simplement à rt.getRootNode() TreeBuilder builder = new TreeBuilder(url,TreeBuilder.VOTABLE, TreeBuilder.VOTABLE_IDHA,null); String target = builder.getTarget(); targetFound = target; ResourceNode targetNode; if( target!=null ) { targetNode = getTargetNode(target); } // target non trouvé, on rattachera la branche à la racine else { targetNode = (ResourceNode)rt.getRootNode(); } lock(); // set the parameters for the thread parentT = targetNode; urlT = url; serverT = null; // launch the thread thread = new Thread(this); thread.start(); } /** phase de test, pour ajouter une branche "AladinServer" avec un rayon différent de 0 */ private void buildTree() { // test IDHAGenerator //getTreeRoot((new IDHAGenerator()).getStream(new java.io.File("/export/home/boch/tmp/test_gen_xml")),null,""); if( treeLoader==null ) treeLoader = new TreeLoader(this.aladin); treeLoader.show(); treeLoader.toFront(); } protected void titrePanel(Panel p,String s, GridBagLayout g, GridBagConstraints c) { Label name = new Label(s,Label.CENTER); name.setFont( Aladin.LLITALIC ); c.gridwidth = GridBagConstraints.REMAINDER; g.setConstraints(name,c); p.add(name); } protected static void addCouple(Panel p,String s,Component cp,Component extrac, GridBagLayout g, GridBagConstraints c) { // Determination du texte qui precede MyLabel l; if( s!=null ) l = new MyLabel(s,Label.RIGHT,Aladin.LBOLD); else l = new MyLabel(); c.gridwidth = 1; c.anchor = GridBagConstraints.WEST; g.setConstraints(l,c); p.add(l); // Insertion du nouveau composant if( extrac==null ) c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; //c.fill = GridBagConstraints.HORIZONTAL; g.setConstraints(cp,c); p.add(cp); c.fill = GridBagConstraints.NONE; // Insertion du composant en extra if( extrac!=null ) { c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0,10,0,10); g.setConstraints(extrac,c); c.insets = new Insets(0,0,0,0); c.anchor = GridBagConstraints.WEST; p.add(extrac); } } private ResourceNode parentT; private URL urlT=null; private String targetT; private String radiusT; private Server serverT; private String serverNameT; private ResourceNode parentNodeT; /** méthode appelée au début du lancement d'un thread de création d'une nouvelle branche */ private void beginThread() { // changement de curseur pendant le calcul Aladin.makeCursor(this,Aladin.WAIT); nbRunningThread++; } /** méthode appelée à la fin d'un thread */ private void endThread() { if( --nbRunningThread == 0 ) { Aladin.makeCursor(this,Aladin.DEFAULT); } } /* ---- Méthodes de verrouillage copiées de la classe Glu ---- */ boolean lock=false; /** Demande le lock */ void lock() { try { while( lock ) { thread.sleep(100); } } catch( Exception e) {} setlock(true); } /** Libere le lock */ void unlock() { setlock(false); } synchronized void setlock(boolean lock) { this.lock=lock; }; /* ---- Fin méthodes de verrouillage ---- */ // création d'une nouvelle branche de l'arbre dans un thread séparé public void run() { beginThread(); // récupération des "paramètres" critiques passés au thread URL url = urlT; urlT = null; ResourceNode parent = parentT; parentT = null; String target = targetT; targetT = null; String radius = radiusT; radiusT = null; Server server = serverT; serverT = null; String serverName = serverNameT; serverNameT = null; // déverrouillage unlock(); ResourceNode newBranch = createNewBranch(url,null,target,radius,server,serverName,true); rt.addNode(parent, newBranch); // test de clone() //rt.addNode(parent, (ResourceNode)newBranch.clone()); endThread(); } /** Construit une nouvelle branche de l'arbre dans un contexte threadé ou non * * @@param url url d'accès au fichier de description des resources (peut être null) * @@param is stream de description des resources (peut être null) * @@param target coordonées ou nom de l'objet (si url!=null, peut être null) * @@param radius rayon de recherche * @@param server serveur d'ou provient * @@param serverName nom du serveur * @@param isThread si oui, méthode appelée par run() de l'objet this * @@return ResourceNode référence vers la "tête" de la branche que l'on a créé */ private ResourceNode createNewBranch(URL url, InputStream is, String target, String radius, Server server, String serverName, boolean isThread) { // résolution du target String targetCoo=null; if( url==null && is==null ) { targetCoo = resolveTarget(target); if( targetCoo==null ) { Aladin.warning("Unknown object "+target,1); // fin du thread if( isThread ) endThread(); return null; } } ResourceNode newBranch; if( url==null && is==null ) newBranch = createNode(targetCoo,radius,server); else newBranch = createNode(url,is,server); // si newBranch null --> pb if( newBranch==null ) { aladin.trace(3,"The new branch of the tree could not be built"); // fin du thread if( isThread ) endThread(); return null; } // ajout de cette nouvelle branche dans l'arbre if( serverName==null ) { if( server instanceof AladinServer ) serverName = "Aladin"; else if( server instanceof VizieRServer ) serverName = "VizieR"; else { if( url==null ) serverName=server.nom; else { serverName = url.toString(); serverName = "..."+serverName.substring(Math.max(0,serverName.length()-20)); } } } newBranch.name = serverName; return newBranch; } /** construit l'URL qui renverra le XML permettant la construction d'une partie de l'arbre */ private URL buildURL(String target, String radius, Server server) { // on utilisera peut-etre une marque GLU URL url; // radius en degrés double radiusDeg = Server.getRadius(radius)/60.0; try { if( server instanceof AladinServer ) { url = new URL("http://aladin.u-strasbg.fr/cgi-bin/nph-HTTP.cgi?out=qualifier&position="+URLEncoder.encode(getDeciCoord(target))+"&radius="+radiusDeg+"&mode=xml_votable"); } else if( server instanceof VizieRServer) { url = new URL("http://vizier.u-strasbg.fr/cgi-bin/votable/-w?-meta&-c="+URLEncoder.encode(target)+"&-c.r="+radiusDeg+"&-c.u=degree&-c.eq=J2000"); } else return null; } catch(MalformedURLException e) { e.printStackTrace(); aladin.trace(1,"URL could not be built"); return null; } aladin.trace(3,"Building url "+url); return url; } /* protected void updateTarget(String s) { centerCutOut.setText(s); if( treeLoader!=null ) treeLoader.updateTF(s); } */ private String getSurvey(String qual) { //return "SURVEY"; return qual.substring(0,qual.indexOf(" ")); } private String getColor(String qual) { //return "C"; return qual.substring(qual.indexOf(" ")+1); } /** Renvoie le nombre situe tout a la fin d'une chaine */ private String getLastNumber(String s) { if( s==null || s.length()==0 ) return ""; String ret = new String(); int index = s.length()-1; while( Character.isDigit(s.charAt(index)) && index>=0 ) { ret = s.charAt(index)+ret; index--; } if( ret.length()>0 ) return "."+ret; return ""; } /** Creation d'un plan Catalogue Code repris de VizieRServer */ protected int creatCatPlane(String cat, String target, String label) { URL u; //String sz = new Double(Server.getRadius(radius.getText())).toString(); // à modifier String sz = "10"; return ((VizieRServer)aladin.dialog.server[ServerDialog.VIZIER]).creatVizieRPlane(target,sz,cat,label,""); } /** Creation d'un plan Aladin, parametres specifiques */ protected int creatAladinPlane(String target, String format,String resol,String qual, String label, String origin) { return creatAladinPlane(target,format,resol,qual,label,origin,"",null); } // methode supplementaire pour generer un label specifique si il y a differentes epochs protected int creatAladinPlane(String target, String format,String resol,String qual, String label, String origin, String field, String epoch, String name) { String lab=null; // bidouille pour ne mettre l'époque que dans le cas de l'ACS if( epoch!=null && qual.indexOf("ACS")>0 ) { lab = getPlanLabel(resol,qual+".ep"+epoch.substring(5)+" ___"); lab += getLastNumber(name); } return creatAladinPlane(target,format,resol,qual,lab,origin,field,name); } /** @@param coo chaine contenant la coordonnée en sexa @@return chaine avec coordonnées en décimal */ static String getDeciCoord(String coo) { Coord c; try {c = new Coord(coo);} catch( Exception e ) {return "";} return c.al+" "+(c.del>=0.0?"+":"")+c.del; } /** Creation d'un plan Aladin, parametres specifiques */ protected int creatAladinPlane(String target, String format,String resol,String qual, String label, String origin, String field, String name) { URL u; // Default if( format==null ) format="JPEG"; if( resol==null ) resol="FULL"; String survey = getSurvey(qual); String color = getColor(qual); // on a besoin de la target en decimal Coord coo = null; try { coo = new Coord(target); } catch(Exception ee){} String targetDec = coo.al+" "+coo.del; // test pour cette saloperie de digits Astroframe frame = new Astroframe(); try { frame.set(target); frame.setPrecision(6); target = frame.toString(" "); } catch(Exception e) {} // Construction et appel de l'URL String s = Glu.quote(targetDec)+" "+Glu.quote(survey)+" "+Glu.quote(color)+" "+Glu.quote(field); if( (u=aladin.glu.getURL("Image.test",s))==null ) { //if( (u=aladin.glu.getURL(Glu.debugTag("Image"),s))==null ) { Aladin.warning(WERR,1); return -1; } //System.out.println(u); // Generation automatique du label du plan if( label==null) { label=getPlanLabel(resol,qual+" ___"); label+= getLastNumber(name); } // Positionnement de l'origine si non mentionne // à voir !! if( origin==null ) { origin="data online provided by CDS"; } /* // on remet le target en sexagesimal Astroframe frame = new Astroframe(); try { frame.set(target); target = frame.toString(" "); } catch(Exception e) {} */ return aladin.calque.newPlanImage(u,PlanImage.ALADIN,label, target,qual,origin, PlanImage.getFmt(format), PlanImage.getRes(resol), false,null); } /** crée un noeud(et tous les subnodes) pour un target, un radius et un serveur donnés * @@param target target demandé (résolu) * @@param radius rayon entré (sous forme de chaine) * @@param server serveur d'ou provient la requete * @@return le noeud créé */ private ResourceNode createNode( String target, String radius, Server server ) { URL url = buildURL(target,radius,server); return createNode(url,null,server); } /** crée un noeud et les sous-noeuds pour une URL ou un InputStream donné * * @@param url pointeur vers le fichier décrivant les resources * @@param is stream contenant la description des resources * @@param server le serveur (Aladin, VizieR, ...) * @@return le noeud créé */ private ResourceNode createNode(URL url, InputStream is, Server server) { // si url nulle --> pb if( url==null && is==null ) { return null; } int type = -1; if( server instanceof AladinServer ) type = TreeBuilder.VOTABLE_IDHA; else if( server instanceof VizieRServer ) type = TreeBuilder.VIZIER; // cas d'un fichier local //else type = TreeBuilder.VOTABLE_IDHA; aladin.trace(1,"Updating the data tree view, using URL "+url); ResourceNode ret = null; try { TreeBuilder tb; if( url!=null ) { tb = new TreeBuilder(url, TreeBuilder.VOTABLE, type, server); ret = tb.build(); targetFound = tb.getTarget(); } else { tb = new TreeBuilder(is, TreeBuilder.VOTABLE, type, server); ret = tb.build(); targetFound = tb.getTarget(); } ret.hide = false; } catch(Exception e) {e.printStackTrace();} return ret; } /** On charge toutes les feuilles sélectionnées ET visibles */ public void submit() { rt.loadSelected(); } /** Construit le label du plan en fonction du qualifier et de la resolution * Exemple: PLATE SERC J STScI => Pl-SERC.J.DSS1 */ static protected String getPlanLabel(String resol, String qual) { return getPlanLabel( PlanImage.getRes(resol),qual); } static protected String getPlanLabel(int resol, String qual) { StringBuffer s = new StringBuffer(); String [] f = new String[3]; // On decoupe les trois champs SURVEY COLOR SCAN StringTokenizer st = new StringTokenizer(qual); for( int i=0; i<3; i++ ) f[i] = st.nextToken(); if( f[0].indexOf("2MASS")>=0 ) { f[2]=f[0]; f[0]=null; } // Et on les assemble dans le sesn inverse eventuellement // precedes par l'indication Pl- pour Plate if( resol==PlanImage.PLATE ) s.append("Pl-"); else if( resol==PlanImage.LOW ) s.append("Lw-"); if( f[2].equals("STScI") || f[2].equals("STSCI") ) s.append("DSS1"); else if( !f[2].startsWith("___") ) s.append(f[2]+"."); s.append(f[1]); if( f[0]!=null ) s.append("."+(f[0].startsWith("GOODS-")?f[0].substring(6):f[0])); return s.toString(); } /** reset : tous les checkboxes sont déselectionnés */ protected void reset() { rt.resetCb(); } public boolean action(Event e, Object o) { if( o.equals(SUBMIT) ) submit(); else if( o.equals(RESET) ) reset(); else if( o.equals(CLOSE) ) hide(); return true; } /* // Gestion des evenements public boolean handleEvent(Event e) { if( (e.id==Event.WINDOW_DESTROY ) ) { dispose(); } return super.handleEvent(e); } */ } && is==null ) newBranch = createNode(targetCoo,radius,server); else newBranch = createNode(url,is,server); // si newBranch null --> pb ifcds/aladin/UCDFilter.java010064400076440000132000001252170770227416100162040ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.util.*; import cds.tools.parser.*; import cds.astro.Unit; /** * Gestion des filtres avec contraintes sur les UCD * * @@author Thomas Boch [CDS] * @@version 0.9 : Juillet 2002 - Creation */ public class UCDFilter { // fonction pour selectionner une source ne possedant pas une certaine colonne ou UCD static final String UNDEFINED = "undefined"; // different strings representing available operators private static final String GT = ">"; // greather than private static final String GE = ">="; // greather or equal private static final String LT = "<"; // less than private static final String LE = "<="; // less or equal private static final String EQ = "="; // equals private static final String NE = "!="; // not equal private boolean convertProblem = false; // true if a problem arose during the conversion private int nbConvertProblem = 0; // nb of sources for which conversion problems happened private int numero; private int position; // useful in containsOperator to store the position of the operator private String curOperator = null; // equals to the current operator // vector of ConstraintsBlock for the filter private Vector constraintsBlocks; // work variable private ConstraintsBlock block; // definition of the filter, as entered by the user protected String definition; // true if the filter is validated boolean isValidated = false; // true if the syntax is false boolean badSyntax = false; // name of the filter String name = null; // Reference to Aladin Aladin a; // Reference to PlanFilter PlanFilter pf; // constructor with name and constraints string UCDFilter(String name, String constraints, Aladin a, PlanFilter pf) { this.a = a; this.name = name; this.pf = pf; //action = new Action(ACTION+Action.SHOW,a); decodeConstraints(constraints); if (!badSyntax) isValidated = true; } /*// constructor with name and constraints array (each element being one constraint) UCDFilter(String name, String[] constraints, Aladin a) { this.a = a; this.name = name; //action = new Action(ACTION+Action.SHOW,a); decodeConstraints(constraints); if(!badSyntax) isValidated=true; }*/ // constructor with a full definition (for scripting) // example : filter f1 { ... } UCDFilter(String definition, Aladin a, PlanFilter pf) { this.a = a; this.pf = pf; //action = new Action(ACTION+Action.SHOW,a); decodeDefinition(definition); if (!badSyntax) isValidated = true; } /** modify the definition of the filter */ protected void changeDefinition(String newDef) { isValidated = false; badSyntax = false; String oldDef = definition; decodeConstraints(newDef); if (!badSyntax) isValidated = true; } void setNumero(int numero) { this.numero = numero; } // reenclenche les actions, ie demande le recalcul de la size par exemple, etc ... protected void resetActions() { Enumeration e = constraintsBlocks.elements(); ConstraintsBlock cb = null; int i; while (e.hasMoreElements()) { cb = (ConstraintsBlock) e.nextElement(); for (i = 0; i < cb.actions.length; i++) { cb.actions[i].reset(); } } } // decode the different constraints and set variables private void decodeConstraints(String def) { //System.out.println("DEF : "+def); constraintsBlocks = new Vector(); // skip '\n' at the beginning of the definition while (def.length() > 0 && def.charAt(0) == '\n') { def = def.substring(1); } // save of the original definition this.definition = new String(def); // replacement of '\t' by a blank character (avoid problems later) def = def.replace('\t', ' '); String tmp = new String(""); String curTok; // skip the remarks StringTokenizer st = new StringTokenizer(def, "\n"); while (st.hasMoreTokens()) { curTok = st.nextToken(); if (!skipSpaces(curTok).startsWith("#")) tmp += curTok + "\n"; } //System.out.println(tmp); //System.out.println(def); def = tmp; // basic check if (Action.countNbOcc('{', def) != Action.countNbOcc('}', def)) { badSyntax = true; Aladin.warning("Unbalanced { }", 1); return; } if (Action.countNbOcc('[', def) != Action.countNbOcc(']', def)) { badSyntax = true; Aladin.warning("Unbalanced [ ]", 1); return; } int longueur = def.length(); int indice = 0; int beginAction, endAction; String actionStr, constraintsStr; while (indice < longueur) { block = new ConstraintsBlock(); // search for a beginning bracket of a block of actions beginAction = getOpeningBracket(def, indice); if (beginAction < 0) { // traitement pour permettre de ne pas avoir d'accolades quand on a juste une action sans contrainte // exemple : "draw blue plus" devient "{draw blue plus}" if( indice==0 && def.trim().startsWith(Action.DRAW) ) { def = "{"+def+"}"; this.definition = "{\n"+this.definition+"\n}"; longueur += 2; beginAction=0; } else break; } endAction = getClosingBracket(def, beginAction + 1); if (endAction < 0) { badSyntax = true; Aladin.warning("Missing }", 1); return; } // maintenant, on peut supprimer les $ (de '${') constraintsStr = def.replace('$', ' ').substring(indice, beginAction); // pas besoin de skipSpaces ici, on conserve les espaces. Ils seront enleves si besoin est dans la classe Action actionStr = def.replace('$', ' ').substring(beginAction + 1, endAction); // getActions qui renvoie un tableau des actions // retrieve different actions for the current block block.actions = getActions(actionStr); // check if syntax is OK for (int i = 0; i < block.actions.length; i++) { if (block.actions[i].badSyntax) { badSyntax = true; return; } } // replacement of \n with spaces constraintsStr = constraintsStr.replace('\n', ' '); // if the constraint string is empty, we put a trivial constraint (to avoid a bug when no constraint is set) if ( skipSpaces(constraintsStr).length() == 0 ) constraintsStr = "1=1"; // On effectue ici un traitement sur constraintsStr pour enlever // les espaces sauf entre les guillmets où ils doivent être conservés // Il n'y a PAS de skipSpaces sur constraintsStr à un autre endroit !! int index=0; String str = new String(); while( index=0 ) { i1 += index; int i2 = constraintsStr.substring(i1+1).indexOf("\""); if( i2>=0 ) { i2 += i1+1; // d'abord, recopie de index jusqu'à i1 en skippant les espaces str += skipSpaces(constraintsStr.substring(index,i1)); // ensuite, recopie sans toucher à rien de i1 jusqu'à i2 str += constraintsStr.substring(i1,i2+1); index = i2+1; } else { str += skipSpaces(constraintsStr.substring(index)); index = constraintsStr.length(); } } else { str += skipSpaces(constraintsStr.substring(index)); index = constraintsStr.length(); } } //System.out.println("avant : "+constraintsStr); constraintsStr = str; //System.out.println("apres : "+constraintsStr); // we get the condition strings(7+3)*y=18 String[] conditions = getConditions(constraintsStr); block.valueConstraints = new Constraint[conditions.length]; // for each condition string, get the corresponding constraint for (int i = 0; i < conditions.length; i++) { // Processing for an "undefined" constraint if (conditions[i].startsWith(UNDEFINED)) { block.valueConstraints[i] = decodeUndefinedConstraint(conditions[i]); } // Processing for a classic constraint else { if (!containsOperator(conditions[i])) { Aladin.warning( "Error, missing comparison operator", 1); badSyntax = true; return; } block.valueConstraints[i] = decodeValueConstraint(conditions[i]); } if (badSyntax) return; } // replacement of each condition by "\[index]", with index reference to the position in block.valueConstraints // for (int l = 0; l < conditions.length; l++) { constraintsStr = replace(constraintsStr, conditions[l], "\\" + l); } // finally, replacement of "&&" with "*" and "||" with "+" constraintsStr = replace(replace(constraintsStr, "||", "+"), "&&", "*"); block.checkExpr = constraintsStr; //System.out.println("**"+constraintsStr+"**"); // when all constraints are "decoded", add the current block to the vector of all blocks constraintsBlocks.addElement(block); // and we initialize block for the next step block = new ConstraintsBlock(); indice = endAction + 1; } } /** Searches all "conditions" in the string s, and return them * as an array of string. * E.g: when applying to the string "(((x)>4)&&(y<8||(7+3)*y=18))||x>9" * it returns the elements "(x)>4","y<8","(7+3)*y=18","x>9" * PRE : spaces were already skipped where appropriate * @@param s - the string holding the expression * @@return a String array holding all constraints */ private String[] getConditions(String s) { String condStr; StringTokenizer st = new StringTokenizer(s, "|&"); String curToken, workStr, tmp, saveToken; workStr = null; String[] conditions = new String[st.countTokens()]; int i = 0; while (st.hasMoreTokens()) { curToken = st.nextToken(); saveToken = new String(curToken); // traitement special pour undefined if (curToken.startsWith(UNDEFINED)) { conditions[i] = curToken; i++; continue; } // Traitement spécial pour les double quote (cas d'une condition sur une chaine), on enlève les parenthèses, et on les remplace par X if (curToken.indexOf("\"") > 0) { int lIndex,rIndex; lIndex = curToken.indexOf("\""); rIndex = curToken.lastIndexOf("\""); if( lIndex!=rIndex ) { String btw = curToken.substring(lIndex,rIndex+1); btw = btw.replace('(','X'); btw = btw.replace(')','X'); btw = btw.replace('{','X'); btw = btw.replace('}','X'); btw = btw.replace('[','X'); btw = btw.replace(']','X'); curToken = saveToken.substring(0,lIndex)+btw+saveToken.substring(rIndex+1); } } //System.out.println("curToken : "+curToken); containsOperator(curToken); tmp = curToken.substring(0, position); int pos; if (tmp.indexOf("(") >= 0) { int length = tmp.length(); pos = length; workStr = ""; while (pos > 0 && Action.countNbOcc(')', workStr) >= Action.countNbOcc('(', workStr)) { //System.out.println(workStr); workStr = tmp.substring(--pos); } if (Action.countNbOcc('(', workStr) > Action.countNbOcc(')', workStr)) { workStr = workStr.substring(1); pos++; } } else pos = 0; // on recherche une eventuelle parenthese fermante apres l'operateur (parenthese qui ne ferait pas partie de la condition) int finCond = curToken.substring(position).indexOf(')'); //System.out.println("la position vaut: "+finCond); if (finCond < 0) finCond = curToken.length(); else finCond += position; // patch dans le cas d'une condition sur une string //if( Action.countNbOcc('\"',curToken)==2 ) finCond = curToken.lastIndexOf("\""); workStr = saveToken.substring(pos, finCond); conditions[i] = workStr; i++; } return conditions; } /** decode an "undefined" constraint */ private Constraint decodeUndefinedConstraint(String constraint) { int begin, end; String undefVar; begin = constraint.indexOf("("); end = constraint.indexOf(")"); if (begin < 0 || end < 0 || begin > end) { Aladin.warning( "Error in syntax of " + UNDEFINED + " condition", 1); badSyntax = true; return null; } undefVar = constraint.substring(begin + 1, end); return new Constraint(undefVar); } // decode a constraint on UCDs values // returns a Constraint object private Constraint decodeValueConstraint(String constraint) { //System.out.println(constraint); int indexOperator = constraint.indexOf(curOperator); String strToParse = constraint.substring(0, indexOperator); boolean isStringConstraint = false; // true if the constaint is a "string value constraint" (in contrast with decimal value constraints) String op = curOperator; double value = 0; String strValue = null; String valueStr = constraint.substring( indexOperator + curOperator.length(), constraint.length()); Unit unit = null; try { unit = new Unit(valueStr); } catch (java.text.ParseException e) { // if we are in string value constraint mode, the only possible // operators are EQ or NE if (curOperator.equals(EQ) || curOperator.equals(NE)) { strValue = valueStr; isStringConstraint = true; } else { //System.out.println(valueStr); Aladin.warning( "Error during parsing of constraints, invalid number or unit format", 1); badSyntax = true; return null; } } catch (ArithmeticException aExc) { badSyntax = true; Aladin.warning("Problem with the unit", 1); return null; } // case of a string value constraint if (isStringConstraint) { int nQuote = Action.countNbOcc('\"', strValue); if (nQuote != 0 && nQuote != 2) { Aladin.warning("A double quote is missing", 1); badSyntax = true; return null; } return new Constraint(strToParse, op, strValue); } // else we have a decimal value constraint // creation of the parser Parser parser; try { parser = createParser(strToParse, a); } catch (ParserException e) { Aladin.warning( "Malformed expression, error\n" + e.getMessage(), 1); badSyntax = true; return null; } value = unit.value; // do we have a unit symbol ? if (unit.symbol.length() > 0) { /*System.out.println("unti not null");*/ return new Constraint(parser, op, value, unit); } else { /*System.out.println("symbol null");*/ return new Constraint(parser, op, value); } } /** replace each occurence of "pattern" within "source" with "replace" * @@param source - the original string * @@param pattern - the pattern to be replaced * @@param replace - the replacement string */ public static String replace( String source, String pattern, String replace) { final int len = pattern.length(); StringBuffer sb = new StringBuffer(); int found = -1; int start = 0; while ((found = source.indexOf(pattern, start)) != -1) { sb.append(source.substring(start, found)); sb.append(replace); start = found + len; } sb.append(source.substring(start)); return sb.toString(); } /** encode a UCD (or a column name), so that there is no problem with the operator characters * @@param s - the string to be encoded * @@return the encoded string */ protected static String encodeUCD(String s) { String ret = new String(s); ret = ret.replace('+', '@@'); ret = ret.replace('-', '!'); ret = ret.replace('*', '~'); ret = ret.replace('/', '&'); return ret; } /** decode an encoded UCD (or a column name), to retrieve its original form * @@param s - the string to be decoded * @@return the decoded string */ protected static String decodeUCD(String s) { String ret = new String(s); ret = ret.replace('@@', '+'); ret = ret.replace('!', '-'); ret = ret.replace('~', '*'); ret = ret.replace('&', '/'); return ret; } /** * @@param s : the string to parse with unencoded variables * @@param vars: array with unencoded variables * @@param encodedVars: array with encoded variables * @@return : the string to parse with encoded variables */ static private String putEncodedVariables( String s, String[] vars, String[] encodedVars) { int begin, end; int i = 0; int oend = 0; StringBuffer strBuf = new StringBuffer(); for (;;) { if (i == vars.length) break; begin = s.indexOf(vars[i], oend); if (begin < 0) break; end = begin + vars[i].length(); //System.out.println(oend+"\t"+begin); strBuf.append(s.substring(oend, begin)); strBuf.append(encodedVars[i]); oend = end; i++; } if (oend < s.length()) strBuf.append(s.substring(oend, s.length())); return strBuf.toString(); } // returns the array of strings corresponding to variables in str // ( i.e correspnding to UCDs, which are enclosed by square brackets [] ) static private String[] getVariables(String str, Aladin aladin) { Vector vec = new Vector(); String variable = null; int beginUCD, beginCol, begin, end; while (str.length() > 0) { beginUCD = str.indexOf("["); beginCol = str.indexOf("{"); // no more variables if (beginUCD < 0 && beginCol < 0) break; // analyze the UCD variable if (beginCol < 0 || (beginUCD >= 0 && beginUCD < beginCol)) { begin = beginUCD; end = str.indexOf("]"); variable = str.substring(begin, end + 1); try { // loop to catch all [ .. [..] ..] in the variable while (Action.countNbOcc('[', variable) != Action.countNbOcc(']', variable)) { end++; variable = str.substring(begin, end + 1); } } catch (StringIndexOutOfBoundsException e) { Aladin.warning("Error : unbalanced []", 1); return null; } } // analyze the col variable else { begin = beginCol; end = str.indexOf("}"); variable = str.substring(begin, end + 1); try { // loop to catch all { .. {..} ..} in the variable while (Action.countNbOcc('{', variable) != Action.countNbOcc('}', variable)) { end++; variable = str.substring(begin, end + 1); } } catch (StringIndexOutOfBoundsException e) { Aladin.warning("Error : unbalanced {}"); return null; } } vec.addElement(variable); str = str.substring(end + 1, str.length()); } // end of while loop String[] ret = new String[vec.size()]; vec.copyInto(ret); return ret; } // returns true if the string str contains one of the operator // note : faire un tableau comme variable statique de classe contenant tous les operateurs private boolean containsOperator(String str) { int pos; // test a placer avant le test de EQ, sinon on aura un pb ! if ((pos = str.indexOf(NE)) >= 0) { curOperator = NE; position = pos; return true; } if ((pos = str.indexOf(GE)) >= 0) { curOperator = GE; position = pos; return true; } if ((pos = str.indexOf(LE)) >= 0) { curOperator = LE; position = pos; return true; } if ((pos = str.indexOf(EQ)) >= 0) { curOperator = EQ; position = pos; return true; } if ((pos = str.indexOf(GT)) >= 0) { curOperator = GT; position = pos; return true; } if ((pos = str.indexOf(LT)) >= 0) { curOperator = LT; position = pos; return true; } return false; } // delete spaces from a string static public String skipSpaces(String str) { StringTokenizer sTok = new StringTokenizer(str, " ", false); StringBuffer result = new StringBuffer(); while (sTok.hasMoreTokens()) result.append(sTok.nextToken()); return result.toString(); } // decode a whole filter definition void decodeDefinition(String def) { int posBeginDef = -1; this.name=""; this.definition=def; // basic check if ( def.indexOf("}")<0 || (posBeginDef = def.indexOf("{")) < 0) { badSyntax = true; Aladin.warning("The format of the whole filter definition\nis invalid",1); return; } // let's retrieve the name of the filter int posBeginName = def.indexOf("filter") + 6; if( posBeginName<0 ) { badSyntax = true; Aladin.warning("The format of the whole filter definition\nis invalid",1); return; } this.name = skipSpaces(def.substring(posBeginName, posBeginDef)); int posEnd = def.lastIndexOf("}"); // we skip the from the definition the "preamble" def = def.substring(posBeginDef + 1, posEnd); decodeConstraints(def); } /** Select sources according to the filter definition * @@param sources - array of sources at the entry of the filter */ protected void select(Source[] sources) { ConstraintsBlock curBlock = null; Vector remainingSources = new Vector(); nbConvertProblem = 0; Enumeration eBlocks = constraintsBlocks.elements(); // first deselect all sources a.calque.view.deSelect(); // loop on all blocks while (eBlocks.hasMoreElements()) { curBlock = (ConstraintsBlock) eBlocks.nextElement(); remainingSources.removeAllElements(); for (int i = sources.length - 1; i >= 0; i--) { // Pour laisser la main aux autres threads if (Aladin.isSlow && i % 50 == 0) { try { Thread.currentThread().sleep(10); } catch (Exception e) { } } if (verifyValueConstraints(sources[i], curBlock)) { sources[i].select = true; a.calque.view.vselobj.addElement(sources[i]); } else if (convertProblem) { //System.out.println("Problem"); nbConvertProblem++; } else { remainingSources.addElement(sources[i]); } } // copy the remaining sources into sources if (remainingSources.size() > 0) { sources = new Source[remainingSources.size()]; remainingSources.copyInto(sources); } else break; } // for the remaining sources, we set select to false if (remainingSources.size() > 0) { for (int i = sources.length - 1; i >= 0; i--) sources[i].select = false; } if (nbConvertProblem > 0) { Aladin.warning( "Warning : there were conversion problems for " + nbConvertProblem + " sources", 1); } } /** Filters sources according to the different constraints and set isSelected to true when a source correpsonds to the constraints * @@param sources array of sources one wants to filter * @@return array of all selected sources */ protected Source[] getFilteredSources(Source[] sources) { long start = System.currentTimeMillis(); Vector filteredSources = new Vector(); int nbSources = sources.length; // nb de sources total nbConvertProblem = 0; Enumeration eBlocks = constraintsBlocks.elements(); ConstraintsBlock curBlock = null; ConstraintsBlock[] blocks = new ConstraintsBlock[constraintsBlocks.size()]; int l=0; while( eBlocks.hasMoreElements() ) { blocks[l]=(ConstraintsBlock)eBlocks.nextElement(); l++; } // we test all sources for (int i = sources.length - 1; i >= 0; i--) { // Pour laisser la main aux autres threads if ( i % 50 == 0 ) { // maj du pourcentage pf.pourcent = 100.0*((double)(nbSources-i)/(double)(nbSources)); //System.out.println(pf.pourcent); if( Aladin.isSlow ) { try { Thread.currentThread().sleep(10); } catch (Exception e) {} } } boolean accomplished=false; // loop on all blocks for( int k=0;!accomplished&&k 0) Aladin.warning( "Warning : there were conversion problems for " + nbConvertProblem + " sources", 1); long end = System.currentTimeMillis(); //System.out.println("TEMPS TOTAL : "+(end-start)); return sourceArray; } // ANCIEN ALGO /* protected Source[] getFilteredSources(Source[] sources) { //protected void getFilteredSources(Source[] sources) { long start = System.currentTimeMillis(); Vector filteredSources = new Vector(); ConstraintsBlock curBlock = null; Vector remainingSources = new Vector(); int nbSources = sources.length; // nb de sources total int processedSources=0; // nb de sources traitées nbConvertProblem = 0; Enumeration eBlocks = constraintsBlocks.elements(); // loop on all blocks while (eBlocks.hasMoreElements()) { curBlock = (ConstraintsBlock) eBlocks.nextElement(); remainingSources.removeAllElements(); for (int i = sources.length - 1; i >= 0; i--) { // Pour laisser la main aux autres threads if ( i % 50 == 0 ) { // màj du pourcentage pf.pourcent = 100.0*((double)processedSources/(double)nbSources); //System.out.println(pf.pourcent); if( Aladin.isSlow ) { try { Thread.currentThread().sleep(10); } catch (Exception e) {} } } if (verifyValueConstraints(sources[i], curBlock)) { filteredSources.addElement(sources[i]); processedSources++; sources[i].isSelected[numero] = true; sources[i].actions[numero] = curBlock.actions; // initialisation of values array for each source sources[i].values[numero] = new double[sources[i].actions[numero].length][3]; for (int j = 0; j < sources[i].actions[numero].length; j++) { sources[i].actions[numero][j].computeValues( sources[i], numero, j); } } else if (convertProblem) { //System.out.println("Problem"); nbConvertProblem++; processedSources++; } else { remainingSources.addElement(sources[i]); } } // fin de la boucle for // copy the remaining sources into sources if (remainingSources.size() > 0) { sources = new Source[remainingSources.size()]; remainingSources.copyInto(sources); } else break; } // fin du while // for the remaining sources, we set action to null if (remainingSources.size() > 0) { for (int i = sources.length - 1; i >= 0; i--) sources[i].actions[numero] = null; } Source[] sourceArray = new Source[filteredSources.size()]; filteredSources.copyInto(sourceArray); //System.out.println("nb selected sources: "+sourceArray.length); if (nbConvertProblem > 0) Aladin.warning( "Warning : there were conversion problems for " + nbConvertProblem + " sources", 1); long end = System.currentTimeMillis(); System.out.println("TEMPS TOTAL : "+(end-start)); return sourceArray; } */ /** check whether s verifies the value constraints * @@param s source * @@param b block of constraints * @@return true if s verifies value constraints */ private boolean verifyValueConstraints(Source s, ConstraintsBlock b) { int i; Constraint curConst = null; if (b.valueConstraints == null) return true; final int length = b.valueConstraints.length; // array storing if b.valueConstraints[i] is verified boolean[] check = new boolean[length]; for (i = 0; i < length; i++) { curConst = b.valueConstraints[i]; check[i] = verifyOneValueConstraint(s, curConst); if (convertProblem) { /*System.out.println("Convert problem");*/ return false; } } final String un = "1"; final String zero = "0"; String foo; String checkStr = new String(b.checkExpr); // we replace the "\[index]" by the value (0==false, 1==true) for (i = 0; i < length; i++) { foo = (check[i]) ? un : zero; checkStr = replace(checkStr, "\\" + i, foo); //if(!check[i]) return false; } Parser parserCheck = new Parser(checkStr); parserCheck.parseString(); //System.out.println("string vaut : "+checkStr); //return true; return (parserCheck.eval() > 0); } /** checks on a source the validity of a constraint (used by verifyValueConstraints) * @@param s - the source * @@param cons - the constraint * @@return true if s verifies the constraint cons, false otherwise */ private boolean verifyOneValueConstraint(Source s, Constraint cons) { double leftValue = 0.0; String strLeftValue = null; convertProblem = false; // case of a string value constraint if (cons.stringConstraint) { // can be a UCD name or a column name String colOrUCD = cons.ucd.substring(1, cons.ucd.length() - 1); int pos; //System.out.println(colOrUCD); // case of a UCD if (cons.ucd.startsWith("[")) pos = s.findUCD(decodeUCD(colOrUCD).toUpperCase()); // case of a column else pos = s.findColumn(decodeUCD(colOrUCD)); // if the position was not found, return false if (pos < 0) return false; strLeftValue = s.getValue(pos); // ce cas peut arriver lorsque il y a un field sans valeur associee if (strLeftValue == null) return false; if (cons.operator.equals(EQ)) { //if (!strLeftValue.equals(cons.strValue)) return ( match(cons.strValue, strLeftValue) ); } else if (cons.operator.equals(NE)) { //if (strLeftValue.equals(cons.strValue)) return ( !match(cons.strValue, strLeftValue) ); } } // case of an undefined constraint else if (cons.undefinedConstraint) { String undefVar = cons.ucd.substring(1, cons.ucd.length() - 1); // true if the UCD/column is NOT found // case of a UCD if (cons.ucd.startsWith("[")) return (s.findUCD(decodeUCD(undefVar).toUpperCase()) < 0); // case of a column else return (s.findColumn(decodeUCD(undefVar)) < 0); } // case of a decimal value constraint else { //if( ! Action.setAllVariables(cons.parser, s, false) ) return false; if (!Action .setAllVariables(cons.parser, s, false, cons.convertUnit)) return false; leftValue = cons.parser.eval(); // conversion dans l'unite de reference if (cons.convertUnit) { Unit refUnit; try { //System.out.println("Avant conversion : "+cons.parser.evalUnit()); refUnit = new Unit(cons.unit); //System.out.println("refUnit : "+refUnit); //System.out.println("evalUnit : "+cons.parser.evalUnit()); refUnit.convert(cons.parser.evalUnit()); } catch (ArithmeticException aExc) { System.err.println(aExc); convertProblem = true; return false; } catch (java.text.ParseException pExc) { System.err.println(pExc); convertProblem = true; return false; } leftValue = refUnit.value; //System.out.println("Apres conversion : "+refUnit); //System.out.println(refUnit); } else leftValue = cons.parser.eval(); return (checkExpr(leftValue, cons.operator, cons.value)); } return true; } private boolean checkExpr(double lVal, String op, double rVal) { if (op.equals(EQ)) return (lVal == rVal); if (op.equals(GT)) return (lVal > rVal); if (op.equals(GE)) return (lVal >= rVal); if (op.equals(LT)) return (lVal < rVal); if (op.equals(LE)) return (lVal <= rVal); if (op.equals(NE)) return (lVal != rVal); return false; } /** Checks whether word matches the mask. If mask does not contain '*' or '?' wildcards, * the equals native method is called (should be faster) * @@param mask mask * @@param word word to check * @@return boolean true if word matches mask */ private boolean match(String mask, String word) { if( mask.indexOf("*")>=0 || mask.indexOf("?")>=0 ) return UCDFilter.matchMask(mask, word); else return word.equals(mask); } /** Adapted from a C-algorithm from P. Fernique * checks whether word matches mask * @@param mask a string which may contain '?' and '*' wildcards * @@param word the string to check * @@return boolean true if word matches mask, false otherwise */ static protected boolean matchMask(String mask, String word) { mask = mask+'\0'; word = word+'\0'; int indiceM,indiceA; indiceM=indiceA=0; String stringB=null; String stringC=null; while( mask.charAt(indiceM)!='\0' || word.charAt(indiceA)!='\0' ) { if( mask.charAt(indiceM)=='*' ) { indiceM++; stringB = mask.substring(indiceM); continue; } if( stringB!=null && !stringB.equals(mask) && word.charAt(indiceA)==word.charAt(0) ) stringC = word.substring(indiceA); if( mask.charAt(indiceM)==word.charAt(indiceA) || mask.charAt(indiceM)=='?' ) { if( mask.charAt(indiceM)=='\0' ) { if( stringB==null ) return false; } else indiceM++; if( word.charAt(indiceA)=='\0' ) return false; else indiceA++; } else { if( stringB!=null ) { mask = stringB; indiceM = 0; if( stringC!=null ) { word = stringC; indiceA = 0; stringC = null; } else { if( stringB.charAt(0)!=word.charAt(indiceA) ) { if( word.charAt(indiceA)=='\0' ) return false; else indiceA++; } } } else return false; } } return true; } /** creates a parser and sets variables * @@param strToParse - the string which has to be parsed * @@return the parser */ static protected Parser createParser(String strToParse, Aladin aladin) throws ParserException { String[] vars = getVariables(strToParse, aladin); if (vars == null) { throw new ParserException(); } String[] encodedVars = new String[vars.length]; // array of encoded variables // fill the encoded variables array for (int i = 0; i < encodedVars.length; i++) encodedVars[i] = encodeUCD(vars[i]); strToParse = putEncodedVariables(strToParse, vars, encodedVars); // creation of a new parser Parser parser = new Parser(strToParse); // we add the variables to the parser for (int i = 0; i < vars.length; i++) { parser.addVar(encodedVars[i]); } try { parser.parseString(); } catch (ParserException e) { throw new ParserException("Maybe a problem with your variables names"); } return parser; } /** parse a string and returns the corresponding action array * @@param s - string with the action * @@return array of Action objects corresponding to the different actions found in s (different actions are separated by a \'n\ */ private Action[] getActions(String s) { // petite bidouille pour permettre a une action d'etre sur plusieurs lignes StringTokenizer st = new StringTokenizer(s, "\n"); String curToken; String cleanedStr = new String(""); while (st.hasMoreTokens()) { curToken = st.nextToken(); while (st.hasMoreTokens() && (Action.countNbOcc('(', curToken) != Action.countNbOcc(')', curToken))) { curToken += st.nextToken(); } curToken.replace('\n', ' '); cleanedStr += curToken + "\n"; } s = cleanedStr; // Les actions sont separees soit par un retour a la ligne soit par un ";" // Cette partie est a revoir : on peut - dans l'absolu - avoir des noms de colonne contenant un ";" st = new StringTokenizer(s, "\n;"); Action[] ret; int size = st.countTokens(); if (size > 0) { ret = new Action[size]; int i = 0; while (st.hasMoreTokens()) { ret[i] = new Action(st.nextToken(), a, pf); i++; } } else { ret = new Action[1]; ret[0] = new Action(Action.DRAWOBJECT, a, pf); } return ret; } /** searches the first index of an opening bracket '{' beginning at index begin in string s * '${', indicating the beginning of a column variable is skipped * @@param s - the string * @@param begin - index where one begins to search * @@returns the position of the first '{' in s, -1 if not found */ private int getOpeningBracket(String s, int begin) { int result; while (true) { result = s.indexOf("{", begin); if (result == -1) return -1; // we skip the '${' if (result > 0 && s.charAt(result - 1) == '$') begin = result + 1; else return result; } } /** searches the closing bracket '}' of an action * * @@param s - the string * @@param begin - index where one begins to search * @@returns the position of '}' in s, skipping the {} variables, -1 if not found */ private int getClosingBracket(String s, int begin) { int result; int oBegin = begin; String subStr; while (true) { result = s.indexOf("}", begin); if (result == -1) return -1; subStr = s.substring(oBegin, result + 1); //System.out.println(subStr); if (Action.countNbOcc('{', subStr) + 1 == Action.countNbOcc('}', subStr)) return result; else begin = result + 1; } } protected void Free() { if (constraintsBlocks != null) { constraintsBlocks.removeAllElements(); constraintsBlocks = null; } block = null; } // inner class to describe constraints class Constraint { Parser parser; // value of the right part of constraint double value; // unit for value Unit unit; // operator of constraint String operator; // true if the constraint is a string constraint : // example : $[CLASS_STAR/GALAXY]="A" boolean stringConstraint; // true if there is a need of converting units boolean convertUnit = false; // true if the constraint is an "undefined" constraint boolean undefinedConstraint = false; // value in term of string String strValue = null; // used for string and undefined constraints String ucd = null; // constructor for a decimal value constraint Constraint(Parser parser, String operator, double value) { this.parser = parser; this.operator = operator; this.value = value; stringConstraint = false; } // constructor for a decimal value constraint with defined unit Constraint(Parser parser, String operator, double value, Unit unit) { this(parser, operator, value); this.unit = unit; convertUnit = true; } // constructor for a string value constraint Constraint(String ucd, String operator, String strValue) { this.ucd = ucd; this.operator = operator; this.strValue = strValue; stringConstraint = true; // petit traitement pour permettre les strValue entre guillemets ( eg : ${otyp}="Cloud" ) if (strValue.length() > 0 && strValue.charAt(0) == '"' && strValue.charAt(strValue.length() - 1) == '"') this.strValue = strValue.substring(1, strValue.length() - 1); } /** constructor for an "undefined" constraint * @@param ucd - ucd or column which must be undefined */ Constraint(String ucd) { this.ucd = ucd; undefinedConstraint = true; } } // inner class to describe a block of constraints class ConstraintsBlock { // array of actions associated with this block (default : DRAW) //Action action = new Action(ACTION+Action.DRAW,a); Action[] actions = null; // array of Constraint objects representing constraints on UCD (or column) values Constraint[] valueConstraints; // expression which will be used to check whether a source is selected by a filter String checkExpr; ConstraintsBlock() { } } } )) return (s.findUCD(decodeUCD(undefVar).toUpperCase()) < 0); // case of a column else return (s.findColumn(decodeUCD(undefVar)) < 0); } // case of a decimal value constraint else { //if( ! Action.setAllVariables(cons.parser, s, false) ) return false; if (!Action .setAllVariables(cons.parser, s, false, cons.convertUnit)) cds/aladin/View.java010064400076440000132000002726170770227416100153440ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestionnaire de la vue. Il s'agit d'afficher les plans acifs (voir * ToolBox) dans l'ordre de visibilite selon l'echelle indiquee par le zoom * (voir ZoomView) *

* La souris a differentes fonctions suivant l'outil (Tool bar) active. * Ce peut etre la simple selection d'une source, le dessin d'objet * graphique, le zoom pointe... * * @@see aladin.ToolBox() * @@see aladin.Zoomview() * @@author P. Fernique CDS * @@version 1.2 : (1 dec 00) Meilleure gestion de la source montree + gestion du plan Add * @@version 1.1 : (28 mars 00) Modif debug -> trace + label pour les plans * @@version 1.0 : (11 mai 99) Toilettage du code * @@version 0.91 - 3 dec 1998 Nettoyage du code * @@version 0.9 - 31 mars 1998 */ public final class View extends Canvas implements Runnable { // Les valeurs generiques static final String WNOZOOM = "You have reached the zoom limit"; static final int CMSIZE = 150; // Taille de la portion d'image pour la CM dynamique Font F = Aladin.SPLAIN; // Les references aux autres objets Aladin aladin; Calque calque; ZoomView zoomview; Status status; // Les composantes de l'objet Vector vselobj = new Vector(500); // Vecteur des objets selections String saisie =""; // La saisie en cours (cf Localisation) boolean nextSaisie=true; // Va remettre a zero saisie a la prochaine frappe Repere repere=null; Thread thread; // Thread pour mettre faire la resolution simbad // Les valeurs a memoriser Rectangle rv; // Taille courante du view Image imgprep; // Image en cours de preparation Image oimg; // Precedente reference a l'image de base Rectangle orz; // Precedent rectangle de zoom double oz; // Precedente valeur du zoom Thread testagain; // Dans le cas ou l'image n'est pas encore prete Image img; // Buffer du paint Graphics g; // Contexte graphique du buffer du paint boolean imgok=true; // Vrai si l'image courante est prete Rectangle clip; // Clip rect courant Rectangle oclip; // Necessaire pour la memorisation du clip Objet newobj; // Objet en cours d'insertion boolean flagLigneClic; // true si on trace une ligne en mode clic, sinon false; boolean first=true; // Pour afficher au demarrage du Help int etat=-1; // Numero de version de la derniere image byte [] pixels; // Pixels de la portion de l'image visible /*anais*/ int [] pixelsRGB; // Pixels de la portion de l'image visible int [] tmpRGB; // Pixels de la portion de l'image visible int w,h; // largeur et hauteur de l'image dans pixels[] int dx,dy; // memo de la marge en blanc boolean flagCM = false; // True si on s'amuse avec la table des couleurs byte [] pixelsCM = new byte[CMSIZE*CMSIZE]; // pixels de la portion test de la table des couleurs /*anais*/ int [] pixelsCMRGB = new int[CMSIZE*CMSIZE]; // pixels de la portion test de la table des couleurs int [] tmpCMRGB ; // pixels de la portion test de la table des couleurs int cmX,cmY; // taille de pixelsCM[] ColorModel cm; // Model de couleur courant int etatDynamicCM; // idem que "etat" mais concernant la zone test de CM boolean modeGrabIt=false; // True si on est en mode GrabIt int grabItX=0,grabItY=0; // Memorisation du debut du GrabIt int pGrabItX=-1,pGrabItY=0; // Memorisation de la fin du GrabIt (position prec) /* int grabItX=0,grabItY=0; // Memorisation du debut du GrabIt int pGrabItX=-1,pGrabItY=0; // Memorisation de la fin du GrabIt (position prec) */ int cGrabItX=-1,cGrabItY=0; // Memorisation de la fin du GrabIt (position cour) int currentCursor=Aladin.DEFAULT; // Le curseur courant // Les valeurs a memoriser pour le rectangle de selection et de zoom Rectangle rselect; // Rectangle de selection multiple (ou zoom) Rectangle orselect; // Precedent rectangle de selection multiple (ou zoom) boolean flagdrag; // Vrai si on drague la souris boolean flagDragField=false; // Vrai si on a deplace un FoV PointD fixe; // Point d'origine d'un deplacement (coord Image) PointD fixev; // Point d'origine d'une select multi (coord View) PointD lastMove=null; // Derniere position d'un mouseMove pour les fleches // en coordonnees de l'image // Le menu Popup PopupMenu popMenu; // Les valeurs a memoriser pour montrer les sources Thread threadB = null; // thread pour pour le clignotement boolean flagBlink=false; // pour l'aiguillage du run() boolean flagSimbadResolve=false; // pour l'aiguillage du run() Source newsource; // Nouvelle Source a montrer Source lastsource; // Precedente Source a cacher boolean sourceshow; // Vrai s'il faut juste montrer/cacher une source boolean repereshow; // Vrai si un repere d'une source est actif boolean sourceblink=false; // Indique qu'une source doit etre clignotante boolean blinkSource=false; // flag d'affichage /*anais*/ boolean RGBDynInit=false; /** Creation de l'objet View * @@param aladin Reference */ protected View(Aladin aladin) { this.aladin = aladin; this.status = aladin.status; this.calque = aladin.calque; this.zoomview = aladin.calque.zoom.zoomView; createPopupMenu(); setBackground(Color.white); setDimension(500,500); // Rq : Image STSCI de 500x500 pixels } MenuItem menuGrid,menuScale,menuReticle,menuZoomIn,menuZoomOut,menuLabel; // Cree le popup menu associe au View private void createPopupMenu() { popMenu = new PopupMenu(); popMenu.add( menuGrid=new MenuItem("Grid")); popMenu.add( menuScale=new MenuItem("Scale")); popMenu.add( menuReticle=new MenuItem("Reticle")); popMenu.addSeparator(); popMenu.add( menuZoomIn=new MenuItem("Zoom in")); popMenu.add( menuZoomOut=new MenuItem("Zoom out")); popMenu.addSeparator(); popMenu.add( menuLabel=new MenuItem("Label/unlabel the selected objects")); super.add(popMenu); } /** Reactions aux differents boutons du menu */ public boolean action(Event e, Object o) { if( e.target==menuReticle ) { calque.flagReticle=!calque.flagReticle; } else if( e.target==menuGrid ) { calque.flagGrid=!calque.flagGrid; } else if( e.target==menuScale ) { calque.flagScale=!calque.flagScale; } else if( e.target==menuZoomIn ) { initZoom((int)fixev.x,(int)fixev.y,false); } else if( e.target==menuZoomOut ) { initZoom((int)fixev.x,(int)fixev.y,true); } else if( e.target==menuLabel ) { calque.view.setSourceLabel(); /* insertFolder(); } else if( e.target==menuDel ) { a.calque.FreeSet(); } else if( e.target==menuDelAll ) { a.calque.FreeAll(); } else if( e.target==menuRef ) { a.calque.setPlanRef((Plan)menuPlan.elementAt(0)); } else if( e.target==menuShow ) { boolean flag = menuShow.getLabel().startsWith("Show"); for( int i=menuPlan.size()-1; i>=0; i-- ) { ((Plan)menuPlan.elementAt(i)).active=flag; } } else if( e.target==menuSelect ) { a.view.calque.selectAllObjectInPlans(); } else if( e.target==menuFilter ) { a.view.calque.newPlanFilter(); } else if( e.target==menuColl ) { boolean flag = menuShow.getLabel().startsWith("Coll"); for( int i=menuPlan.size()-1; i>=0; i-- ) { switchCollapseFolder((Plan)menuPlan.elementAt(i)); } } else if( e.target==menuProp ) { if( a.properties==null ) { a.trace(1,"Creating the Propertie window"); a.properties = new Properties(a); } a.toolbox.tool[ToolBox.PROP].mode=Tool.DOWN; a.toolbox.repaint(); a.properties.majProp(); */ } else return false; calque.repaint(); return true; } // Affiche le popup private void showPopMenu(int x,int y) { if( calque.flagGrid ) menuGrid.setLabel("Grid off"); else menuGrid.setLabel("Grid on"); if( calque.flagScale ) menuScale.setLabel("Scale off"); else menuScale.setLabel("Scale on"); if( calque.flagReticle ) menuReticle.setLabel("Reticle off"); else menuReticle.setLabel("Reticle on"); popMenu.show(this,x,y); } /* Changement de taille */ protected void setDimension(int w,int h) { resize(w,h); rv = new Rectangle(w,h); zoomview.setViewDim(w,h); } /** Recuperation de l'image courante de la vue */ protected Image getImage() { // Si on est en mode script, il faut creer manuellement l'image // de la vue. La taille sera fonction de l'image de base if( Aladin.script ) { Plan p = calque.getPlanBase(); if( p==null ) return null; if( p.type!=Plan.IMAGE ) setDimension(500,500); else setDimension(((PlanImage)p).width,((PlanImage)p).height); zoomview.NewZoom(); } img=null; paint(null); PlanImage.waitImage(aladin,img); return img; } private boolean flagLockRepaint=false; // Positionnement du flag du lockRepaint (pour le mode script) protected synchronized void setLockRepaint(boolean flag) { flagLockRepaint=flag; } // Positionnement du flag du lockRepaint (pour le mode script) private synchronized boolean lockRepaint() { return flagLockRepaint; } /** Force la regeneration de la vue (projections comprises) */ synchronized protected void newView() { calque.zoom.zoomView.iz++; } /** Retourne la couleur du premier plan selectionne */ protected Color getColor() { int n = calque.getFirstSelected(); if( n<0 || calque.plan[n].type==Plan.NO ) return Color.black; return calque.plan[n].c; } // Extension du clip courant void extendClip(Rectangle r) { if( r==null ) clip=null; clip = (clip==null)?r:clip.union(r); } /** Ajoute l'objet en cours de saisie dans le plan selectionne */ protected void setNewObjet() { if( newobj==null ) return; calque.setObjet(newobj); extendClip(newobj.getClip(zoomview)); newobj = null; } /** Indique s'il y a des objets selectionnes. * @@return true s'il y a des objets selectionnes, false sinon */ protected boolean hasSelectedObjet() { return( vselobj!=null && vselobj.size()>0 ); } /** Indique s'il y a au-moins une suppression effective a faire * @@return true s'il y a des objets a supprimer, false sinon */ protected boolean isDelSelObjet() { Enumeration e = vselobj.elements(); while( e.hasMoreElements() ) { Position p = (Position) e.nextElement(); if( p.plan.type==Plan.TOOL ) return true; // Appartient a un plan Tool } return false; } /** Recopie les id des objets selectionnes dans le bloc note */ protected void selObjToPad() { Enumeration e = vselobj.elements(); StringBuffer res = new StringBuffer("\n"); while( e.hasMoreElements() ) { Position o = (Position) e.nextElement(); if( o instanceof Source ) continue; if( o.id!=null && o.id.length()>0 ) res.append(o.id+"\n"); } aladin.pad.setText(res.toString()); } /** Supprime les objets selectionnes. * Effectue un reaffichage si necessaire * @@return true s'il y en a eu au moins une suppression, * false sinon */ protected boolean delSelObjet() { Enumeration e = vselobj.elements(); boolean ok = !vselobj.isEmpty(); while( e.hasMoreElements() ) { Objet o = (Objet) e.nextElement(); extendClip(o.getClip(zoomview)); calque.delObjet(o); } vselobj.removeAllElements(); if( ok ) repaint(); return ok; } /** Affichage de l'identificateur des objets selectionnes. * Positionne ou non le label (identificateur) des objets selectionnes * Il faut que tous les objets aient le label pour qu'ils soient * supprimes, sinon ils sont ajoutes. * Dans le cas ou aucun objet n'est selectionne, tous les labels * des objets des plans courants sont affiches/ou effaces */ protected void setSourceLabel() { int i,j,k; boolean enleve=false; // true s'il faut enlever les labels, false sinon // Label sur les plans courants if( vselobj.size()==0 ) { // deux tours : 1 pour le pre-traitement et l'autre pour le traitement for( k=0; k<2; k++ ) { encore: for( i=0; i=0; i-- ) { Position o = (Position) vselobj.elementAt(i); if( !(o instanceof Source || o instanceof Repere) ) continue; if( !o.withlabel ) enleve=false; o.withlabel=true; // Par defaut on met le label } // Si jamais il fallait au contraire enlever les labels if( enleve ) { for( i=vselobj.size()-1; i>=0; i-- ) { Position o = (Position) vselobj.elementAt(i); if( !(o instanceof Source || o instanceof Repere) ) continue; o.withlabel=false; } } repaint(); } /** Deselection des objets par rapport au vecteur vselobj. * Deselectionne tous les objets, demande la mise a jour * de la fenetre des infos * @@return Retourne true si au-moins un objet a ete deselectionne */ protected boolean deSelect() { if( vselobj.isEmpty() ) return false; Enumeration e = vselobj.elements(); while( e.hasMoreElements() ) { Objet o = (Objet) e.nextElement(); extendClip(o.getClip(zoomview)); o.setSelect(false); } vselobj.removeAllElements(); aladin.mesure.removeAllElements(); return true; } /** Selection d'un unique objet * @@param Objet o */ protected void selectOne(Objet o) { deSelect(); o.setSelect(true); clip=null; vselobj.addElement(o); aladin.mesure.insertInfo((Source)o); repaint(); aladin.toolbox.toolMode(); aladin.mesure.mcanvas.repaint(); } /** Selection d'une liste de Source par leur OID * @@param oid[] */ protected void selectSourcesByOID(String oid[]) { deSelect(); clip=null; Source o[] = aladin.calque.getSources(oid); for( int i=0; itrue si au-moins un objet a ete deselectionne */ protected boolean selectAllInPlan(Plan plan) { // Deselection des precedents Enumeration e = vselobj.elements(); while( e.hasMoreElements() ) { Position p = (Position) e.nextElement(); p.setSelect(false); } aladin.mesure.removeAllElements(); // Reselection selectAllInPlanWithoutFree(plan); // et affichage repaint(); aladin.toolbox.toolMode(); aladin.mesure.mcanvas.repaint(); return true; } /** Selection de tous les objets d'un plan CATALOG */ protected void selectAllInPlanWithoutFree(Plan plan) { PlanObjet pcat = ((PlanCatalog)plan).pcat; vselobj = new Vector(pcat.nb_o); for( int i=0; i0?(Objet)v.elementAt(0):null; if( o==null || o instanceof Position ) { Plan pref = calque.getPlanRef(); double xImg=p.x; double yImg=p.y; byte pix[] = null; if( pref.type==Plan.IMAGE ) { yImg=((PlanImage)pref).height-yImg; // Ordonnée dans l'autre sens pix = new byte[FrameNewCalib.W*FrameNewCalib.W]; ((PlanImage)pref).getPixels(pix,(int)p.x-FrameNewCalib.W/2,(int)p.y-FrameNewCalib.W/2, FrameNewCalib.W,FrameNewCalib.W); } PointD pCorr=aladin.frameNewCalib.mouse(xImg,yImg,pix,(Position)o); if( pCorr!=null ) { if( pref.type==Plan.IMAGE ) pCorr.y=((PlanImage)pref).height-pCorr.y; setRepere(pref,pCorr.x,pCorr.y); } } } // Recuperation du Focus pour pouvoir utiliser le SimbadResolver requestFocus(); /* // Mode GrabIt actif if( isGrabIt() ) { aladin.dialog.setGrabItCoord(x,y); cGrabItX=pGrabItX=-1; grabItX=x; grabItY=y; repaint(); return true; } */ if( tool== -1 ) return true; // Dans le cas de l'outil Zoom if( tool==ToolBox.ZOOM ) { initZoom(x,y,flagshift); repaint(); return true; } // Dans le cas de l'outil de selection if( tool==ToolBox.SELECT ) { // thomas // click en mode SELECT --> on marque les images disponibles dans le treeView markAvailableImages(x,y); Vector v = calque.getObjWith(p.x,p.y); // Dans le cas du shift on merge les deux vecteurs if( e.shiftDown() ) { // On recommence une selection multiple if( v.size()==0 ) { rselect = new Rectangle(x,y,1,1); return true; } en = v.elements(); while( en.hasMoreElements() ) { Position o = (Position) en.nextElement(); // Faut-il l'ajouter ou l'enlever if( !o.select ) { //System.out.println("faut il ajouter ou enlever"); if( !(o instanceof Source) || ((Source)o).noFilterInfluence() || ((Source)o).isSelected() ) { // ajout thomas vselobj.addElement(o); o.select = true; } } else { o.select = false; vselobj.removeElement(o); } } // Sinon on deselectionne les precedents, et on reselectionne // les nouveaux } else { // Si le premier element a deja ete selectionne precedemment // on suppose qu'il s'agit d'un clic-and-drag if( v.size()>0 && ((Position)v.elementAt(0)).select ) return true; en = vselobj.elements(); while( en.hasMoreElements() ) { ((Position)en.nextElement()).select = false; } en = v.elements(); while( en.hasMoreElements() ) { Position pos = ((Position)en.nextElement()); // on interdit la selection de points d'un PlanContour et d'un PlanFov if (pos.plan instanceof PlanContour || pos.plan instanceof PlanFov) continue; // si un filtre est ON, on ne selectionne que les sources correpondant au filtre // supprimer cette partie me permet de me debarasser d'un bug (la condition isSelected() est testee dans Source) [thomas] /*if(aladin.cnstrntPanel.filtersOn() && aladin.cnstrntPanel.getActiveFilter()!=null && ( pos instanceof Source && !((Source)pos).isSelected ) ) { v.removeElement(pos); continue; }*/ pos.select = true; } vselobj = v; } // Mise a jour des mesures setMesure(); if( hasSelectedObjet() ) { // Positionnement du repere et mise a jour de la // fenetre des infos try { Source o = (Source) v.elementAt(0); repereshow=aladin.mesure.mcanvas.show(o); } catch( Exception ec ) {} // J'amorce une selection multiple } else rselect = new Rectangle(x,y,1,1); return true; } // S'il y a deja un objet en cours de creation, on le // termine avant d'en creer un nouveau if( newobj!=null ) { // Fin d'un texte if( newobj instanceof Texte ) { setNewObjet(); // Traitement d'une polyligne en mode clic, un simple clic on cree // un nouveau sommet, un double clic (ou cote) => on a fini } else if( newobj instanceof Ligne && flagLigneClic ) { Objet suivant=null; boolean cote = (newobj instanceof Cote); extendClip(newobj.getClip(zoomview)); newobj.setPosition(p.x,p.y); if( e.clickCount<2 && !cote ) { suivant = new Ligne(newobj.getPlan(),p.x,p.y,(Ligne)newobj); } setNewObjet(); if( e.clickCount<2 && !cote ) { newobj = suivant; extendClip(newobj.getClip(zoomview)); } repaint(); return true; } } // Creation d'un nouvel objet int n; if( (n = calque.getFirstSelected())<0 ) return true; Plan plan = calque.plan[n]; newobj = aladin.toolbox.newTool(plan,p.x,p.y); // Le debut d'une cote est insere immediatement // et on travaille sur le deuxieme bout if( newobj instanceof Cote ) { calque.setObjet(newobj); newobj = new Cote(newobj.getPlan(),p.x,p.y,(Cote)newobj); flagLigneClic=false; // Par defaut une polyligne s'insere un mode drag } // idem pour le debut d'une polyligne else if( newobj instanceof Ligne ) { calque.setObjet(newobj); newobj = new Ligne(newobj.getPlan(),p.x,p.y,(Ligne)newobj); flagLigneClic=false; // Par defaut une polyligne s'insere un mode drag } // Pour le repere, on pourra eventuellement faire un drag de capture else if( newobj instanceof Repere ) rselect= new Rectangle(x,y,0,0); // Extension du clip Rect if( newobj!=null ) extendClip(newobj.getClip(zoomview)); repaint(); return true; } /** Positionne les mesures dans la fenetre des infos. * et reaffiche la fenetre des tools et de la vue * en fonctions des objets selectionnes */ protected void setMesure() { boolean flagExtApp = aladin.hasExtApp(); String listOid[] = null; int nbOid=0; aladin.mesure.removeAllElements(); Enumeration e = vselobj.elements(); //long b = System.currentTimeMillis(); if( flagExtApp ) listOid = new String[vselobj.size()]; while( e.hasMoreElements() ) { Objet o = (Objet) e.nextElement(); if( o instanceof Source ) { // pas de selection pour les objets ne "passant" pas le filtre if( ((Source)o).noFilterInfluence() || ((Source)o).isSelected() ) { o.info(aladin); } // Test si cette source provient d'une application cooperative // type VOPlot, et si oui, fait le callBack adequat if( flagExtApp ) { String oid = ((Source)o).getOID(); if( oid!=null ) listOid[nbOid++]=oid; } } } //long end = System.currentTimeMillis(); //System.out.println(end-b); aladin.toolbox.toolMode(); aladin.mesure.mcanvas.repaint(); // Callback adequat pour la liste des sources que l'application cooperative // doit selectionner if( flagExtApp ) aladin.callbackSelectExtApp(listOid,nbOid); repaint(); } public boolean mouseUp(Event e, int x, int y) { //Menu Popup if( (e.modifiers & java.awt.event.InputEvent.BUTTON3_MASK) !=0 ) { showPopMenu(x,y); return true; } // Mode GrabIt actif if( isGrabIt() ) { modeGrabIt=false; aladin.dialog.setGrabItRadius(grabItX,grabItY,x,y); stopGrabIt(); aladin.dialog.toFront(); } // Recalcul des Field of View si necessaire if( flagDragField ) { flagDragField=false; calque.resetPlanField(); repaint(); return true; } // memorisation de la position if( aladin.toolbox.getTool()==ToolBox.SELECT ) aladin.localisation.setPos(x,y,1); // Cas du zoom => Rien a faire if( aladin.toolbox.getTool()==ToolBox.ZOOM ) return true; // Le repere est insere if( newobj instanceof Repere ) { int n,i,j,k; flagdrag=false; // Simple repere if( rselect!=null && rselect.width==0 && rselect.height==0 ) { rselect=null; extendClip(newobj.getClip(zoomview)); setNewObjet(); return true; } // Capture de toutes les sources contenues dans rselect if( (n = calque.getFirstSelected())<0 || calque.plan[n].type!=Plan.TOOL ) return true; extendSelect(x,y); extendClip(oclip); Plan plan = calque.plan[n]; PointD p1 = zoomview.getPosition((double)rselect.x,(double)rselect.y); PointD p2 = zoomview.getPosition((double)rselect.x+rselect.width-1, (double)rselect.y+rselect.height-1); RectangleD r = new RectangleD(p1.x,p1.y,p2.x-p1.x+1,p2.y-p1.y+1); // Rect englobant for( i=j=0; j0 ) aladin.status.setText(i+" source"+((i>1)?"s":"")+" duplicated in tag"+((i>1)?"s":"")); else aladin.status.setText("No source found in this area"); newobj=null; // Cet objet (coin sup gauche) n'est pas a prendre en compte rselect=null; repaint(); return true; } // Traitement de la fin d'une selection multiple if( rselect!=null ) { flagdrag=false; extendSelect(x,y); extendClip(oclip); PointD p1 = zoomview.getPosition((double)rselect.x,(double)rselect.y); PointD p2 = zoomview.getPosition((double)rselect.x+rselect.width-1, (double)rselect.y+rselect.height-1); Vector v = calque.setMultiSelect(new RectangleD(p1.x,p1.y,p2.x-p1.x+1,p2.y-p1.y+1)); // Dans le cas du shift on merge les deux vecteurs if( e.shiftDown() ) { Enumeration en = v.elements(); while( en.hasMoreElements() ) { Objet o = (Objet) en.nextElement(); if( !vselobj.contains(o) ) { vselobj.addElement(o); o.info(aladin); } } } else vselobj = v; setMesure(); rselect=null; return true; } // Traitement pour la Ligne et Cote if( newobj!=null && newobj instanceof Ligne ) { // Calcul de la nouvelle position PointD p = zoomview.getPosition((double)x,(double)y); // Rien a faire si je suis une ligne en mode Clic, le mouseDown s'est charge // d'inserer le sommet if( !(newobj instanceof Cote) && flagLigneClic ) return true; // Si on n'a pas bouge de la position du mouse Down, on va tracer // la polyligne en mode clique, plutot qu'en mode drag. il faudra // un double-clic pour terminer // Rq : on test si le point precedent est bien le debut de la ligne et que // l'on a pas bouge if( !flagLigneClic ) { Ligne l = (Ligne) newobj; if( l.debligne!=null ) { l=l.debligne; if( p.x==l.x && p.y==l.y && l.debligne==null ) { flagLigneClic=true; return true; } } } extendClip(newobj.getClip(zoomview)); newobj.setPosition(p.x,p.y); extendClip(newobj.getClip(zoomview)); setNewObjet(); repaint(); return true; } return false; } /* REMARQUE SUR LE CLIP RECT * L'extension en 2 temps du clip est indispensable car il est * possible que la methode mouseDrag soit appelee plusieurs fois avant que * le update() ait pu avoir lieu */ public boolean mouseDrag(Event e, int x, int y) { // Mode GrabIt actif if( isGrabIt() ) { aladin.dialog.setGrabItRadius(grabItX,grabItY,x,y); cGrabItX=x; cGrabItY=y; repaint(); return true; } int tool = aladin.toolbox.getTool(); // Cas du zoom => Rien a faire if( tool==ToolBox.ZOOM ) return true; /* // Traitement d'un repere avec pourtour if( newobj!=null && newobj instanceof Repere && e.shiftDown() ) { rselect=null; // Il n'y aura pas de capture // Calcul de la nouvelle position Point p = zoomview.getPosition(x,y); // Positionnement du clip initial extendClip(newobj.getClip(zoomview)); // on positionne l'entourage if( e.shiftDown() ) p.y=p.x; ((Repere)newobj).setOval(p.x,p.y); // Extension du clip et reaffichage extendClip(newobj.getClip(zoomview)); repaint(); } */ // Agrandissement du rectangle de selection multiple if( rselect!=null ) { extendSelect(x,y); flagdrag=true; repaint(); return true; } // Deplacement d'objets if( tool==ToolBox.SELECT && !vselobj.isEmpty() ) { // Calcul du vecteur deplacement PointD p = zoomview.getPosition((double)x,(double)y); double dx = p.x-fixe.x; double dy = p.y-fixe.y; fixe = p; // pour l'etape suivante Enumeration en = vselobj.elements(); while( en.hasMoreElements() ) { Objet o = (Objet)en.nextElement(); if( ((Position)o).plan.type!=Plan.TOOL && ((Position)o).plan.type!=Plan.FIELD || ((Position)o).plan instanceof PlanContour || ((Position)o).plan instanceof PlanFov ) continue; // pas de deplacement pour un objet de PlanContour ou PlanFov // Creation ou extension du clip extendClip(o.getClip(zoomview)); // Deplacement o.deltaPosition(dx,dy); // Attention il y aura un FoV a reprojeter if( ((Position)o).plan.type==Plan.FIELD ) flagDragField=true; //extension du clip et reaffichage extendClip(o.getClip(zoomview)); } repaint(); } // Traitement des lignes (Cotes, polylignes...) if( newobj!=null && newobj instanceof Ligne ) { // Calcul de la nouvelle position PointD p = zoomview.getPosition((double)x,(double)y); // Positionnement du clip initial extendClip(newobj.getClip(zoomview)); // Memorisation de la nouvelle position newobj.setPosition(p.x,p.y); // Dans le cas d'une polyligne, on commence une nouvelle arete if( !(newobj instanceof Cote) && !flagLigneClic ) { Objet suivant = new Ligne(newobj.getPlan(),p.x,p.y,(Ligne)newobj); setNewObjet(); newobj = suivant; } // Extension du clip et reaffichage extendClip(newobj.getClip(zoomview)); repaint(); } /* // Affichage de la position if( cGrabItX!=x && cGrabItY!=y ) aladin.localisation.setPos(x,y); */ aladin.localisation.setPos(x,y); // affichage de la loupe si necessaire calque.zoom.wen(x,y); return true; } int oc=Aladin.DEFAULT; public boolean mouseMove(Event e, int x, int y) { boolean trouve = false; boolean ok=false; int tool=aladin.toolbox.getTool(); // Affichage de la position aladin.localisation.setPos(x,y); // (thomas) affichage dans l'arbre des images disponibles if( tool==ToolBox.SELECT ) showAvailableImages(x,y); // Memorisation de la position en cas de deplacement fin avec les fleches lastMove = zoomview.getPosition((double)x,(double)y); // Affichage du rectangle du zoom if( tool==ToolBox.ZOOM ) { // Affichage d'un rectangle de zoom x2 - on utilise le meme rectangle que le // selecteur - il ne faut pas oublier en sortant de la fenetre // de reafficher l'ensemble, remettre flagdrag a false et rselect=orselect=null if( e.shiftDown() ) rselect = new Rectangle(x,y,1,1); else rselect = new Rectangle(x-rv.width/4,y-rv.height/4,rv.width/2,rv.height/2); flagdrag=true; // Pour un affichage rapide repaint(); // Affichage des labels des sources et des vecteurs } else if( tool==ToolBox.SELECT || ToolBox.isForTool(tool) ) { PointD p = lastMove; // deja calcule // Affichage du baratin de l'objet pointe int numobj=-1,nplan=-1; int n=0; double z = calque.zoom.getValue(); for( int i=0; i0 ) { calque.plan[nplan].pcat.showBaratin(numobj); // Show info de la source dans le canvas des mesures if( calque.plan[nplan].type==Plan.CATALOG ) { Source o = (Source) calque.plan[nplan].pcat.o[numobj]; if( o.select ) ok=aladin.mesure.mcanvas.show(o); //System.out.println("je vais p-e monter la source courante"); //if(o instanceof Source) System.out.println(((Source)o).isSelected); // Je montre la source courante if( (o instanceof Source) && ( ((Source)o).noFilterInfluence() || ((Source)o).isSelected() ) ) { showSource(o); //System.out.println("je montre la source courante"); } } // Plus d'un objet if( n>1 && !(calque.plan[nplan] instanceof PlanContour)) aladin.status.setText(n+" superimposed objects - click on them to get details"); } trouve=(n>0); // Je cache la derniere source montree si necessaire if( !trouve && lastsource!=null ) hideSource(); // Je change le curseur si necessaire if( tool==ToolBox.SELECT ) { if( trouve ) { if( oc!=Aladin.HAND ) Aladin.makeCursor(this,(oc=Aladin.HAND)); } else { if( oc!=currentCursor ) Aladin.makeCursor(this,(oc=currentCursor)); } } // Cache le repere de la source dans le canvas des mesures // si necessaire et memorise le fait qu'un repere est positionne if( repereshow && !ok ) aladin.mesure.mcanvas.show(null); repereshow=ok; } // Affichage de la loupe si necessaire calque.zoom.wen(x,y); return trouve; } public boolean mouseExit(Event e, int x, int y) { int i; // Fin du blinking si necessaire stopBlinking(); // Fin de l'affichage rapide en cas de zoom if( (i=aladin.toolbox.getTool())==ToolBox.ZOOM ) { flagdrag=false; rselect=orselect=null; aladin.toolbox.tool[i].mode=Tool.UP; aladin.toolbox.tool[ToolBox.SELECT].mode=Tool.DOWN; aladin.toolbox.repaint(); } // Fin d'un GrabIt éventuel // if( isGrabit() ) // (thomas) Fin de l'affichage des images disponibles if( aladin.toolbox.getTool()==ToolBox.SELECT) { if( aladin.treeView.rt != null ) { aladin.treeView.rt.turnOffAllNodes(); } if( aladin.dialog.server[aladin.dialog.current].tree!=null ) { aladin.dialog.server[aladin.dialog.current].tree.turnOffAllNodes(); } } // On arrete l'insertion de l'objet en cours, sauf s'il s'agit de // texte, auquel cas on l'insere if( newobj!=null ) { if( newobj instanceof Texte ) { Texte t = (Texte) newobj; if( t.id.length()>0 ) setNewObjet(); } newobj=null; } // Modification du curseur Aladin.makeCursor(aladin,Aladin.DEFAULT); clip = null; // Modification du zoom si necessaire calque.zoom.wenOff(); // Arret de la localisation aladin.localisation.setUndef(); // ca ne peut pas faire de mal repaint(); return true; } public boolean mouseEnter(Event e, int x, int y) { // Modification du zoom si necessaire calque.zoom.wenOn(); // Recuperation du Focus dans le cas d'un WEN actif pour pouvoir // effectuer un ajustement fin if( aladin.toolbox.tool[ToolBox.WEN].mode==Tool.DOWN ) requestFocus(); int tool = aladin.toolbox.getTool(); // Modification du curseur en fonction de l'outil currentCursor = (tool==ToolBox.ZOOM ||isGrabIt())? Aladin.CROSSHAIR:(tool==ToolBox.TEXT)? Aladin.TEXT:Aladin.DEFAULT; Aladin.makeCursor(this,currentCursor); return true; } /** Action sur le ENTER dans la boite de localisation */ protected void simbadResolve(String coord) { saisie=coord; if( coord.trim().length()>0 ) { if( notCoord(coord) ) { flagSimbadResolve=true; thread = new Thread(this); thread.setPriority( Thread.NORM_PRIORITY -1); thread.start(); return; } setRepere(); } else { repere=null; repaint(); } } Plan planWaitSimbad=null; static Coord oco=null; static String oobjet=null; /** resolution Simbad pour le repere d'un plan */ protected boolean simbadResolveForPlan(Plan p) { // Mini-cache du dernier objet resolu if( oobjet!=null && oco!=null && p.objet.equals(oobjet) ) { p.co = oco; return true; } // Lancement du Thread de resolution Simbad pour le plan indique planWaitSimbad = p; p.sr = new Thread(this); p.sr.setPriority( Thread.NORM_PRIORITY -1); p.sr.start(); return false; } /** Positionnement du repere en fonction des coordonnees de la chaine "saisie" */ protected void setRepere() { try { Coord c = new Coord(saisie); repere = new Repere(null,c); repere.setType(Repere.TARGET); repere.setSize(10); } catch( Exception e) { System.err.println(e); } nextSaisie=true; repaint(); } /** Positionnement du repere en fonction d'un x,y dans la vue */ protected void setRepere(Plan p,double x,double y) { repere = new Repere(p,x,y); repere.setType(Repere.TARGET); repere.setSize(10); repaint(); } /** Positionnement du repere en fonction du target du plan de reference */ protected void setRepere(Plan p) { if( p.objet==null || p.objet.length()==0 ) return; if( p.co==null ) { if( notCoord(p.objet) ) { if( !simbadResolveForPlan(p) ) return; } else { try { p.co=new Coord(p.objet); } catch( Exception e) { System.err.println(e); } } } suiteSetRepere(p.co); } /** Suite de la procedure du positionnement du repere d'un plan */ private void suiteSetRepere(Coord c) { repere = new Repere(null,c); repere.setType(Repere.TARGET); repere.setSize(10); // Positionnement eventuel et a posteriori d'un centre // d'un FoV calque.setCenterForField(c.al,c.del); } /** Aiguillage pour les 2 differents types de resolution simbad * et un éventuel blinking */ public void run() { //System.out.println("run: flagBlink="+flagBlink); // synchronized(this) { if( flagSimbadResolve ) { flagSimbadResolve=false; runB(); } else if( flagBlink ) runC(); else if( planWaitSimbad!=null ) runA(); // } } synchronized void setFlagBlink(boolean a) { flagBlink = a; } // Gestion du blinking d'une source par thread (pour supporter JVM 1.4) private void startBlinking() { if( flagBlink ) { //System.out.println("blink thread already running"); return; } setFlagBlink(true); threadB = new Thread(this); //System.out.println("launch blink thread "+threadB); threadB.setPriority( Thread.NORM_PRIORITY -1); setFlagBlink(true); threadB.start(); } private void stopBlinking() { setFlagBlink(false); } // Juste un repaint dans 0.3 secondes private void runC() { while( flagBlink ) { //System.out.println("blink thread j'attends 0.3 sec "+threadB); try {threadB.sleep(300);} catch(Exception e) {} blinkSource=true; if( lastsource!=null ) extendClip(lastsource.getClip(zoomview)); repaint(); } //System.out.println("stop blink thread"+threadB); // threadB.stop(); } /** Resolution simbad a proprement parle * @@param objet le nom d'objet * @@return les coordonnees J2000 sexagesimales ou null si pb */ synchronized protected Coord getSimbad(String objet) { URL url; String s=null; // Mini-cache du dernier objet resolu if( oobjet!=null && oco!=null && objet.equals(oobjet) ) { return oco; } /* Ancienne methode par le resolver Simbad try { url = aladin.glu.getURL("SimbadResolve",URLEncoder.encode(objet),true); java.io.InputStream is = url.openStream(); if( is!=null ) { DataInputStream cat = new DataInputStream(is); s=cat.readLine(); if( s.length()>0 ) { oco = new Coord(s); oobjet=objet; } } } catch( Exception e ) { oco=null; } */ // Par le Sesame try { url = aladin.glu.getURL("Sesame",URLEncoder.encode(objet),true); java.io.InputStream is = url.openStream(); if( is!=null ) { DataInputStream cat = new DataInputStream(is); while(true){ s=cat.readLine(); if( s.startsWith("%J ") ) { StringTokenizer st = new StringTokenizer(s); st.nextToken(); oco = new Coord(st.nextToken()+" "+st.nextToken()); oobjet=objet; Aladin.trace(2,"Sesame: "+objet+" -> "+oco.getSexa()); break; } } } } catch( Exception e ) { oco=null; } return oco; } /** Resolution Simbad par Thread independant pour un plan */ void runA() { Coord c = getSimbad(planWaitSimbad.objet); if( c!=null ) { planWaitSimbad.co=c; suiteSetRepere(planWaitSimbad.co); repaint(); } if( planWaitSimbad!=null && planWaitSimbad.sr!=null ) planWaitSimbad.sr=null; planWaitSimbad=null; } /** Resolution Simbad par Thread independant pour un objet particulier */ public void runB() { URL url; boolean error=false; String s=null; String memo; memo=saisie; saisie=saisie+" -> Simbad ?"; aladin.localisation.setText(saisie); Coord c = getSimbad(memo); if( c==null ) { if( memo.length()>0 ) Aladin.warning("Simbad resolver error\n for \""+memo+"\""); saisie=memo; } else { saisie=aladin.localisation.toString(c.al,c.del); setRepere(); } aladin.localisation.setText(saisie); } /** Retourne vrai si la chaine contient au moins une lettre */ static protected boolean notCoord(String s) { char a[] = s.toCharArray(); for( int i=0; i='a' && a[i]<='z' || a[i]>='A' && a[i]<='Z' ) return true; } return false; } public boolean keyDown(Event e,int key) { String s=null; // Suppression de l'objet selectionne // if( aladin.toolbox.getTool()==ToolBox.SELECT && (key==-1 || key==8 || key==127) ) { // delSelObjet(); // return true; // } // Construction d'un objet graphique de texte if( newobj instanceof Texte ) { // On commence un nouveau texte en dessous if( key==13 || key==10 ) { Position po = (Position) newobj; int deltaY = (int)( 14/calque.zoom.getValue() ); // Decalage du texte if( deltaY==0 ) deltaY=1; Objet o = (Objet) new Texte(po.plan,po.x, po.y+deltaY); Texte t = (Texte) newobj; if( t.id.length()>0 ) setNewObjet(); else extendClip(newobj.getClip(zoomview)); newobj = o; // On efface le dernier caractere } else if( key==8 || key==-1 || key==127) { Texte t = (Texte) newobj; if( t.id.length()==0 ) return true; t.setText( t.id.substring(0,t.id.length()-1) ); // On insere un nouveau caractere } else if( key>=31 && key<=128 ) { Texte t = (Texte) newobj; char [] c = new char[1]; c[0] = (char) key; t.setText( t.id + new String(c) ); } } // Extension du ClipRect if( newobj!=null ) extendClip(newobj.getClip(zoomview)); // Peut etre un ajustement fin par les fleches else { if( aladin.toolbox.tool[ToolBox.WEN].mode==Tool.DOWN && (key==1004 || key==1005 || key==1006 || key==1007 || key==10 || key==13) ) { Point p=null; if( key>=1004 && key<=1007 ) { p = focusByKey(key); return mouseMove(e,p.x,p.y); } else if( key==10 || key==13 ) { p = zoomview.getViewCoord(lastMove.x,lastMove.y); mouseDown(e,p.x,p.y); mouseUp(e,p.x,p.y); return true; } } } repaint(); return true; } private void markAvailableImages(int x, int y) { // on marque les images pour le serveur courant et pour l'history tree markAvailableImages(x,y,aladin.dialog.server[aladin.dialog.current].tree); markAvailableImages(x,y,aladin.treeView.rt); showAvailableImages(x,y); } /** Marque dans le treeView les images disponibles */ private void markAvailableImages(int x, int y, MetaDataTree tree) { Plan ref = calque.getPlanRef(); if( ref== null ) return; if( ref.projd == null) return; Point p = aladin.calque.zoom.zoomView.getPosition(x,y); Coord c = new Coord(); c.x=p.x; c.y=p.y; ref.projd.getCoord(c); String targetSexa = c.getSexa(); // certainement à virer //aladin.treeView.updateTarget(targetSexa); // si on est en grabMode, maj pour un seul noeud, et on ne marque pas les images dispos !! if( FrameInfo.getInstance().inGrabMode() ) { FrameInfo.getInstance().setTarget(targetSexa); return; } if( tree==null || tree.nodeFullTab==null ) return; BasicNode[] tab = tree.nodeFullTab; ResourceNode node; for( int i=0; itrue si l'[iamge est prete, false sinon */ protected boolean getImgView(Graphics gr,int n) { int imgW,imgH; // Taille de l'image de base double z; // Valeur du zoom Rectangle rz; // Portion a zoomer dans l'image de base boolean flagchange; // Vrai s'il faut reextraire une vue PlanImage p; boolean flagBord=false; // true s'il y a une marge autour de l'image // A priori, rien n'a change flagchange=false; // Pas encore de buffer de base if( img==null || img.getWidth(this)!=rv.width || img.getHeight(this)!=rv.height) { img = createImage(rv.width,rv.height); flagchange=true; // Creation du contexte graphique g = img.getGraphics(); } else { // Regeneration du contexte graphique if( g!=null ) g.dispose(); g=img.getGraphics(); } // Mise en place du clip if( clip!=null ) g.clipRect(clip.x-1,clip.y-1,clip.width+2,clip.height+2); // Du blanc en dessous (dans le cas des bords) g.setColor( Color.white ); g.fillRect(0,0,rv.width,rv.height); // Aucune image de base if( n<0 ) return true; p = (PlanImage)(calque.plan[n]); if( !p.flagOk ) return false; // L'image de base n'est pas prete // Recup des infos sur l'image imgW = p.width; imgH = p.height; //System.out.println("p.width="+p.width+" p.height="+p.height); // Recuperation des infos sur le zoom rz = calque.zoom.zoomView.getZoom(); z = calque.zoom.getValue(); if( rz==null ) return false; // zoom pas pret // if( rz.width>imgW*z ) rz.width=(int)( imgW*z ); // if( rz.height>imgH*z ) rz.height=(int)( imgH*z ); // Teste s'il faut recommencer a extraire une image int newEtat = p.getEtat(); flagchange = (flagchange || etat!=newEtat || !rz.equals(orz) || oz!=z); // Test s'il va y avoir des marges autour flagBord=( rz.x<0 || rz.y<0); //System.out.println("flagBord="+flagBord+" flagchange="+flagchange+" rz="+rz); // l'etat doit avoir change et etre paire pour indiquer que l'image a ete modifiee // et pas seulement la table des couleurs // if( flagchange && newEtat%2==0) { if( flagchange ) { if( gr!=null ) waitImg(gr); // message pour patienter // A tout hasard pixels = p.pixels; w = rz.width; h = rz.height; // faut-il extraire une portion de pixels ou prendre l'image // telle quelle (en fonction du zoom) // Extraction de la portion visible avec reajustement de l'image si // necessaire (presence de bords partiels) // if( z>=1 ) { int x1=(rz.x<0)?0:rz.x; int y1=(rz.y<0)?0:rz.y; w=(rz.width>p.width)?p.width:w; h=(rz.height>p.height)?p.height:h; if( !(x1==0 && y1==0 && w==p.width && h==p.height) ) { pixels = new byte[w*h]; //System.out.println("******* J'extrait les pixels ("+x1+","+y1+") sur "+w+"x"+h); p.getPixels(pixels,x1,y1,w,h); } // } // Zoom en agrandissement if( z>1 ) { byte [] scalepixels; int z1 = (int) z; // Casting // Agrandissement int i,j,k,l,d; if( flagBord ) { w=imgW; h=imgH; } d=0; scalepixels = new byte [w*h*z1*z1]; for( i=0; i ("+maxw+","+maxh+")"); //System.out.println("image dst = ("+dw+","+dh+")"); reducepixels = new byte[dw*dh]; // cas 1/x if( dst==1 ) { for( di=i=0; i>src); BIZARRE reducepixels[di+dj]=(byte)(c/srcX); } } // Cas 2/3 } else { for( di=i=0; i>1; } } c=di*dw; reducepixels[c+=dj] =(byte)(pk[0]+pk[1]); reducepixels[c+1] =(byte)(pk[2]+pk[5]); c=(di+1)*dw; reducepixels[c+=dj] =(byte)(pk[3]+pk[6]); reducepixels[c+1] =(byte)(pk[7]+pk[8]); } } } pixels = reducepixels; w=dw; h=dh; } // Memorisation de l'etat pour eviter de refaire le travail oz = z; orz = new Rectangle(rz.x,rz.y,rz.width,rz.height); } // Construction de l'image if( flagchange ) { imgprep = createImage( new MemoryImageSource(w,h,p.cm, pixels, 0,w)); PlanImage.waitImage(aladin.view,imgprep); // Memorisation de l'etat etat = newEtat; } w=imgprep.getWidth(this); h=imgprep.getHeight(this); if( w<0 ) return false; // Centrage de l'image si plus petite que view et zoom==1 if( flagBord || z<1 ) { dx= - (int)( rz.x*z ); dy= - (int)( rz.y*z ); // Du blanc dans la marge if( dx>0 || dy>0 ) { g.setColor( Color.white ); g.fillRect(0,0,rv.width,rv.height); } // Necessaire dans le cas de bords partiels if( dx<0 ) dx=0; if( dy<0 ) dy=0; } else dx=dy=0; //System.out.println("J'affiche imgprep en ("+dx+","+dy+")"); g.drawImage(imgprep,dx,dy,aladin); /* // Pourtour en noir pour y voir qq chose if( flagBord || z<1 ) { g.setColor( Color.black ); g.drawRect(dx-1,dy-1,w+1,h+1); } */ return true; } /* anais */ /** Preparation de l'image RGB. * Prepare l'image de la vue courante en fonction du plan * de base et du zoom. * @@param gr Le contexte graphique servira a afficher * un eventuel message d'attente, ou null sinon * @@param n Le numero du plan concerne * @@return true si l'[image est prete, false sinon */ protected boolean getRGBImgView(Graphics gr,int n) { int imgW,imgH; // Taille de l'image de base double z; // Valeur du zoom Rectangle rz; // Portion a zoomer dans l'image de base boolean flagchange; // Vrai s'il faut reextraire une vue PlanImageRGB p; boolean flagBord=false; // true s'il y a une marge autour de l'image // A priori, rien n'a change flagchange=false; // Pas encore de buffer de base if( img==null || img.getWidth(this)!=rv.width || img.getHeight(this)!=rv.height) { img = createImage(rv.width,rv.height); flagchange=true; // Creation du contexte graphique g = img.getGraphics(); } else { // Regeneration du contexte graphique if( g!=null ) g.dispose(); g=img.getGraphics(); } // Mise en place du clip if( clip!=null ) g.clipRect(clip.x-1,clip.y-1,clip.width+2,clip.height+2); // Du blanc en dessous (dans le cas des bords) g.setColor( Color.white ); g.fillRect(0,0,rv.width,rv.height); // Aucune image de base if( n<0 ) return true; p = (PlanImageRGB)(calque.plan[n]); if( !p.flagOk ) return false; // L'image de base n'est pas prete // Recup des infos sur l'image imgW = p.width; imgH = p.height; // Recuperation des infos sur le zoom rz = calque.zoom.zoomView.getZoom(); z = calque.zoom.getValue(); if( rz==null ) return false; // zoom pas pret if( rz.width>imgW*z ) rz.width=(int)( imgW*z ); if( rz.height>imgH*z ) rz.height=(int)( imgH*z ); // Teste s'il faut recommencer a extraire une image int newEtat = p.getEtat(); flagchange = (flagchange || etat!=newEtat || !rz.equals(orz) || oz!=z); // Test s'il va y avoir des marges autour flagBord=( rz.x<0 || rz.y<0); // l'etat doit avoir change et etre paire pour indiquer que l'image a ete modifiee // et pas seulement la table des couleurs if( flagchange ) { if( gr!=null ) waitImg(gr); // message pour patienter // A tout hasard pixelsRGB = p.pixelsRGB; w = rz.width; h = rz.height; // faut-il extraire une portion de pixels ou prendre l'image // telle quelle (en fonction du zoom) // Extraction de la portion visible if( !flagBord && z>=1 ) { pixelsRGB = new int[w*h]; p.getPixels(pixelsRGB,rz.x,rz.y,rz.width,rz.height); } // Zoom en agrandissement if( z>1 ) { int [] scalepixelsRGB; int z1 = (int) z; // Casting // Agrandissement int i,j,k,l,d; if( flagBord ) { w=imgW; h=imgH; } d=0; scalepixelsRGB = new int [w*h*z1*z1]; for( i=0; i>16); c2+= ((pixelsRGB[m] & 0x0000FF00)>>8); c3+= ((pixelsRGB[m] & 0x000000FF)); } } c1/=srcX; c2/=srcX; c3/=srcX; c = ( ( 255 & 0xFF ) << 24 ) | ( ((int)c1 & 0xFF ) << 16 ) | ( ((int)c2 & 0xFF ) << 8 ) | ((int)c3 & 0xFF ); reducepixelsRGB[di+dj]=c; } } // Cas 2/3 } else { for( di=i=0; i>17); pk2[c]=((pixelsRGB[m] & 0x0000FF00)>>9); pk3[c]=((pixelsRGB[m] & 0x000000FF)>>1); } } c=di*dw; reducepixelsRGB[c+=dj] = ( ( 255 & 0xFF ) << 24 ) | ( ((int)(pk1[0]+pk1[1]) & 0xFF ) << 16 ) | ( ((int)(pk2[0]+pk2[1]) & 0xFF ) << 8 ) | ((int)(pk3[0]+pk3[1]) & 0xFF ) ; reducepixelsRGB[c+1] = ( ( 255 & 0xFF ) << 24 ) | ( ((int)(pk1[2]+pk1[5]) & 0xFF ) << 16 ) | ( ((int)(pk2[2]+pk2[5]) & 0xFF ) << 8 ) | ((int)(pk3[2]+pk3[5]) & 0xFF ) ; c=(di+1)*dw; reducepixelsRGB[c+=dj] = ( ( 255 & 0xFF ) << 24 ) | ( ((int)(pk1[3]+pk1[6]) & 0xFF ) << 16 ) | ( ((int)(pk2[3]+pk2[6]) & 0xFF ) << 8 ) | ((int)(pk3[3]+pk3[6]) & 0xFF ) ; reducepixelsRGB[c+1] = ( ( 255 & 0xFF ) << 24 ) | ( ((int)(pk1[7]+pk1[8]) & 0xFF ) << 16 ) | ( ((int)(pk2[7]+pk2[8]) & 0xFF ) << 8 ) | ((int)(pk3[7]+pk3[8]) & 0xFF ) ; } } } pixelsRGB = reducepixelsRGB; w=dw; h=dh; } // Memorisation de l'etat pour eviter de refaire le travail oz = z; orz = new Rectangle(rz.x,rz.y,rz.width,rz.height); } // Construction de l'image if( flagchange ) { imgprep = createImage(new MemoryImageSource(w, h, pixelsRGB, 0,w)); PlanImage.waitImage(aladin.view,imgprep); // Memorisation de l'etat etat = newEtat; } w=imgprep.getWidth(this); h=imgprep.getHeight(this); if( w<0 ) return false; // Centrage de l'image si plus petite que view et zoom==1 if( flagBord || z<1 ) { dx= - (int)( rz.x*z ); dy= - (int)( rz.y*z ); // Du blanc dans la marge if( dx>0 || dy>0 ) { g.setColor( Color.white ); g.fillRect(0,0,rv.width,rv.height); } } else dx=dy=0; g.drawImage(imgprep,dx,dy,aladin); return true; } /** Initialisation d'un tableau. * @@param array Le tableau a initialiser * @@param offset L'indice du premier element du tableau concerne * @@param len Longueur de l'initialisation * (NECESSAIREMENT UNE PUISSANCE DE 2) * @@param value La valeur a y mettre */ protected static void bytefill(byte[] array, int offset, int len, byte value) { int i; if( len<4 ) { for( i=0; i<4; i++ ) array[offset+i]=value; } else { array[offset]=value; for( i=1; iPASD[i]; i++ ); if( i>1 ) i-=2; double pasd = PASD[i]/60; // En degres double cosd; try { cosd = Math.cos( (proj.dej*Math.PI)/180.0 ); } catch( Exception e ) { return; } r=r/cosd; for( i=0; iPASA[i]; i++ ); if( i>1 ) i-=2; double pasa = PASA[i]/60; // En degres double dej,raj; double rajc,dejc; c=new Coord(); Point p1 = calque.zoom.zoomView.getPosition(rv.width/2,rv.height/2); c.x=p1.x; c.y=p1.y; c = proj.getCoord(c); rajc = c.al; dejc = c.del; r=proj.rm/120/z; // Rayon en degres if( r>15 ) return; // La grille merdouille sur les grands rayons //System.out.println("Je dois mettre une grille avec un pas de ("+ // (pasa*60)+","+(pasd*60)+") arcmin autour de "+ // c.getSexa()+" sur "+(r*60)+" armin"); Aladin.trace(2,"Computing grid: center on "+c.getSexa()+" with "+c.getUnit(r*2)+" by "+ c.getUnit(pasa)+" x "+c.getUnit(pasd)); double rra = r/cosd; double deb=rajc-rra; deb = deb - deb%pasa; double fin=rajc+rra; double raji,deji; // Calcul des iso-ascensions for( raji=deb; raji180.0 ) dej= dej-360; c.del=dej; proj.getXY(c); p = zoomview.getViewCoord(c.x,c.y); vDE.addElement(p); } while( rv.contains(p) && dej!=deji ); st = new StringTokenizer(c.getSexa(":"),"."); vDE.addElement(st.nextToken()); } deb = dejc-r; deb = deb - deb%pasd; fin = dejc+r; // Calcul des iso-declinaisons for( deji=deb; deji360 ) raj = raj-360.0; c.al=raj; proj.getXY(c); p = zoomview.getViewCoord(c.x,c.y); vRA.addElement(p); } while( rv.contains(p) && raj!=raji ); st = new StringTokenizer(c.getSexa(":")); st.nextToken(); st = new StringTokenizer(st.nextToken(),"."); vRA.addElement(st.nextToken()); } } // Affichage des isolignes g.setColor(Color.magenta); Enumeration e; Point op=null; int x,y; for( i=0; i<2; i++ ) { e = i==0?vDE.elements():vRA.elements(); boolean debLigne=true; while( e.hasMoreElements() ) { Object o = e.nextElement(); if( o instanceof String ) { debLigne=true; y=(i==0 && op.y<40 && op.y>-40)?13:(int)op.y; x=(i==1 && op.x<40 && op.x>-40)?2:(int)op.x; g.drawString((String)o,x+2+dx,y-2+dy); continue; } op=p; p = (Point)o; if( debLigne ) { op=p; debLigne=false; continue; } if( clip==null || clip.contains(op.x,op.y) || clip.contains(p.x,p.y) ) { g.drawLine(op.x+dx,op.y+dy,p.x+dx,p.y+dy); } } } } /** Dessin des FOV */ protected void drawFovs(Graphics g, int dx, int dy) { if( calque.Fovs == null ) return; Fov fov; Plan ref = aladin.calque.getPlanRef(); if( ref==null) return; if( ref.projd == null) return; Enumeration e = calque.Fovs.elements(); while( e.hasMoreElements() ) { fov = (Fov)e.nextElement(); fov.draw(ref,zoomview,g,dx,dy,null); } // champ courant if( calque.curFov != null) { Fov f; for( int i=0; iy*3600.0 ) break; if( i>0 ) i--; // On determine la taille exacte du repere y = PASE[i]/3600.0; coo.del-=y; coo = proj.getXY(coo); w = (int)((coo.y - proj.cy)*zoom); if( w<0 ) w=-w; // Conversion dans une unite adequate String s=Coord.getUnit(y); // Affichage int X,Y; if( zoom>1 ) { int z = (int)zoom; for( X=0; X<16; X+=z); // sur une frontiere de pixel image for( Y=rv.height%z; Y<8; Y+=z); // idem en Y } else { X=16; Y=8; } Y = rv.height-Y; X+=dx; Y+=dy; g.setColor(Color.magenta); g.drawLine(X,Y-4,X,Y); g.drawLine(X,Y,X+w,Y); g.drawLine(X+w,Y,X+w,Y-4); g.setFont( Aladin.SPLAIN ); g.drawString(s,X+3,Y-6); } // Message d'attente de l'image dans la vue void waitImg(Graphics gr ) { // Affichage d'un message d'attente si l'image n'est pas prete String s = "New view in progress..."; int DF=20; gr.setFont( Aladin.LLITALIC ); FontMetrics m = gr.getFontMetrics(); gr.setColor( Aladin.BKGD ); gr.drawString(s,55,55); gr.setColor( Color.black ); gr.drawString(s,rv.width-m.stringWidth(s)-55,rv.height-55+DF); } /** Dessin de la surface couverte par le Grabit */ private void drawGrabIt(Graphics g,int x1,int y1, int x2, int y2) { g.drawLine(x1-5,y1,x1+5,y1); g.drawLine(x1,y1-5,x1,y1+5); int dx = x1-x2; int dy = y1-y2; double r = Math.sqrt(dx*dx+dy*dy); g.drawOval((int)(x1-r),(int)(y1-r),(int)(r*2),(int)(r*2)); } /** Retourne la couleur des infos de services en fonction * du plan de reference. S'il est normal, on prend le vert, * s'il est inverse ou blanc ou prend le noir */ protected Color getInfoColor() { Plan p = calque.getPlanBase(); if( p!=null && p.type==Plan.IMAGE && ((PlanImage)p).video==PlanImage.VIDEO_NORMAL ) return Color.green; return Color.black; } // Jamais d'effacement de la vue public void update(Graphics gr ) { if( !lockRepaint() && !Aladin.script ) paint(gr); // Pas de repaint() pendant un saveView() } private boolean oFlagButton=true; // Memorisation du dernier etat de flagButton /** Tracage des oerlays graphiques * @@param g le contexte graphique concerne * @@param clip le cliprect s'il existe, sinon null * @@param dx,dy l'offset d'affichage uniquement utilise pour les impressions * @@return true si au moins un plan a ete affiche */ protected boolean paintOverlays(Graphics g,Rectangle clip,int dx,int dy) { boolean flagDisplay=false; int n = calque.getIndexPlanBase(); int nref = calque.setDefaultPlanRef(); // Traitement des surcharges graphiques if( calque.flagScale ) drawEchelle(g,dx,dy); if( calque.flagGrid ) drawGrid(g,clip,dx,dy); // Positionnement de la fonte pour d'eventuelles label g.setFont( Aladin.SPLAIN ); // Dessin des plans catalogues et objets jusqu'au plan de base // Recalcul simples des autres plans valides for( int i=calque.plan.length-1; i>=0; i--) { Plan p = calque.plan[i]; if( p.type==Plan.NO || !p.flagOk || !p.active ) continue; boolean flagDraw = (n==-1 || i0 || dy>0 ) p.flagProj=false; } // (thomas) dessins des fov des images // on le place ici pour que le cutout fov puisse se voir même lorqu'il correspond parfaitement avec le drawBord drawFovs(g,dx,dy); // Le repere courant if( calque.flagReticle && repere!=null && nref!=-1 && calque.plan[nref].projd!=null) { repere.projection(calque.plan[nref].projd); g.setColor(Color.magenta); repere.draw(g,zoomview,dx,dy); } return flagDisplay; } public void paint(Graphics gr) { boolean flagButton; // true si MPRINT et MSAVE doivent etre actives // Quel est l'indice de l'image de base int n = calque.getIndexPlanBase(); // Traitement pour le Grabit if( modeGrabIt && cGrabItX!=-1) { gr.setColor( Color.green ); gr.setXORMode( Color.red ); if( pGrabItX!=-1 ) drawGrabIt(gr,grabItX,grabItY,pGrabItX,pGrabItY); drawGrabIt(gr,grabItX,grabItY,cGrabItX,cGrabItY); pGrabItX=cGrabItX; pGrabItY=cGrabItY; gr.setPaintMode(); return; } // Traitement pour la modif dynamique de la table des couleurs if( flagCM ) { Image imgtmp=null; try { /*anais*/ if (calque.plan[n] instanceof PlanImageRGB){ imgtmp = createImage( new MemoryImageSource(CMSIZE,CMSIZE,pixelsCMRGB, 0,CMSIZE)); } else { imgtmp = createImage( new MemoryImageSource(CMSIZE,CMSIZE,(ColorModel)cm, pixelsCM, 0,CMSIZE)); } gr.drawImage(imgtmp,dx+cmX,dy+cmX,this); gr.setColor( getInfoColor() ); gr.drawRect(dx+cmX-1,dy+cmX-1,CMSIZE+2,CMSIZE+2); } catch( OutOfMemoryError e ) { System.gc(); System.runFinalization(); } return; } // Traitement pour montrer/cacher une source (phase initiale) if( sourceshow ) { if( lastsource!=null ) { lastsource.hide(gr,zoomview); lastsource=null; if( newsource==null ) stopBlinking(); } if( newsource!=null ) { newsource.show(gr,zoomview); lastsource=newsource; newsource=null; startBlinking(); } sourceshow=false; return; } // Traitement pour faire clignoter la source courante if( blinkSource ) { if( lastsource!=null ) lastsource.blink(gr,zoomview); blinkSource=false; return; } // Quelle est la taille actuelle du view if( !Aladin.script ) rv = new Rectangle(0,0,size().width,size().height); // trace du rectangle de selection multiple if( orselect!=null || rselect!=null ) { gr.setColor( Color.green ); gr.setXORMode( Color.red ); if( orselect!=null ) { gr.drawRect(orselect.x,orselect.y, orselect.width, orselect.height); orselect = null; } if( rselect!=null ) { gr.drawRect(rselect.x,rselect.y, rselect.width, rselect.height); orselect = new Rectangle( rselect.x,rselect.y,rselect.width,rselect.height); } gr.setPaintMode(); if( flagdrag ) return; } // Recherche de l'image a afficher dans la vue if (n<0) { if( !getImgView(gr,n) ) { return; } } else { if (calque.plan[n]!=null){ /*anais*/ if (calque.plan[n] instanceof PlanImageRGB){ if( !getRGBImgView(gr,n) ) { return; } } else { if( !getImgView(gr,n) ) { return; } } } } //System.out.println("*** repaint all"); // Il sera desormais inutile d'effacer l'objet precedemment montre // puisqu'on reaffiche le tout if( lastsource!=null ) { lastsource.show=false; lastsource=null; } //Positionnement des clips rect si necessaire if( clip!=null ) { if( gr!=null ) gr.clipRect(clip.x-1,clip.y-1,clip.width+2,clip.height+2); g.clipRect(clip.x-1,clip.y-1,clip.width+2,clip.height+2); } // Positionnement du plan de reference par defaut s'il y a lieu // et memorisation de son numero int nref = calque.setDefaultPlanRef(); // Dessin des overlays graphiques flagButton=paintOverlays(g,clip,0,0); // J'encadre le tout g.setColor(Color.black); g.drawRect(0,0,rv.width-1,rv.height-1); // Un objet en cours ? if( newobj!=null ) { g.setColor( getColor() ); newobj.draw(g,zoomview,0,0); if( newobj instanceof Cote ) newobj.status(aladin); } // Activation ou desactivation des boutons du menu principal // associes a la presence d'au moins un plan if( flagButton!= oFlagButton ) { aladin.setButtonMode(flagButton); oFlagButton = flagButton; } // Visualisation du clipRect pour debug if( Aladin.levelTrace==3 ) { if( clip!=null ) { g.setColor( getInfoColor() ); g.drawRect(clip.x+1,clip.y+1,clip.width-2,clip.height-2); } } // Suppression du clip clip = null; // Affichage du buffer if( gr!=null ) gr.drawImage(img,0,0,aladin); } } ; // Determination de la taille du repere (au max d'1/4 de la vue) int w = rv.width/4; double cds/aladin/VizieRServer.java010064400076440000132000000267450770227416100170300ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.event.FocusListener; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.FocusEvent; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; import cds.vizier.*; import cds.tools.*; /** * Le formulaire d'interrogation de Vizir * * @@author Pierre Fernique [CDS] * @@version 3.0 : jan 03 - Suppression du Layout Manager et toilettage [PF] * @@version 2.0 : 13 mai 2002 - Utilisation de l'API VizieR [Andre Schaaff] * @@version 1.0 : (5 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class VizieRServer extends Server implements CDSConstants { // static final String NOM = "VizieR\n"+MyButton.LOGOCAT; static final String NOM = "VizieR\nCatalogs"; static final String INFO = "CDS VizieR catalog service (>3000 astronomical catalogs)"; static final String CATDESC = "Get info."; static final String TAGGLU = "VizieRXML.rm"; // les composantes de l'objet VizieRList vizierlist; // La liste des catalogues proposees TextField catalog; // le champ de saisie du catalogue TextField radius; // le champ de saisie du radius MyLabel legende; // legende courante de la liste Button getReadMe; // Le bouton pour demander des infos boolean hasPreviousFocus = false; // this boolean is needed for th submit button management // Les references Vector vSurveys; //La liste des surveys par defaut Vector vArchives; //La liste des archives ServerDialog serverDialog; // Catalogs panel VizieRPanel vp = null; Vector catalogs = new Vector(); VizieRCatalogs vcl = null; Panel panelButtonRight = new Panel(); Panel actions; /** Creation du formulaire d'interrogation de Vizir * @@param aladin reference * @@param status le label qui affichera l'etat courant * @@param vSurveys La liste des surveys par defaut * @@param actions les boutons d'action */ protected VizieRServer(final Aladin aladin,Label status, ServerDialog serverDialog, Panel actions) { this.aladin = aladin; this.status = status; type = DATA; nom = NOM; info = INFO; setLayout(null); setFont(Aladin.PLAIN); int y=0; this.actions = actions; // Creation des objets propres a l'interrogation de VizieR this.serverDialog = serverDialog; // right buttons panelButtonRight.setBackground(BKGD); panelButtonRight.setFont(BOLD); Button submit = new Button("SUBMIT"); submit.setFont(LBOLD); panelButtonRight.add(submit); // Le titre Label t = new Label("VizieR catalog service"); t.setFont( Aladin.LLITALIC ); t.setBounds(151,y,300,20); y+=25; add(t); // Premiere indication Label info1 = new Label("Specify a target, and a catalog name or identification..."); info1.setBounds(86,y,400, 20); y+=20; add(info1); // Panel pour la memorisation du target (+bouton DRAG) Panel tPanel = targetPanel(27,null,true,COO|SIMBAD); tPanel.setBounds(10,y,450,30); y+=30; add(tPanel); // Catalog + Radius Label label1 = new Label("Catalog"); label1.setFont(Aladin.LBOLD); int l= 55; label1.setBounds(10,y,l,30); add(label1); catalog = new TextField(26); catalog.setBounds(l+15,y,150,30); add(catalog); Label label2 = new Label("Radius"); label2.setFont(Aladin.LBOLD); label2.setBounds(289,y,l,30); add(label2); radius = new TextField("10 arcmin"); radius.setBounds(347,y,100,30); y+=35; add(radius); setModeRad(RADIUS,radius); // Bouton getReadMe getReadMe = new Button(CATDESC); getReadMe.setFont( Aladin.BOLD); getReadMe.enable(true); getReadMe.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { String cata = catalog.getText().trim(); if( cata.equals("") ) { //Aladin.warning(this,WNEEDCAT); } else { cata = Glu.quote(cata); aladin.glu.showDocument("getReadMe",cata); } } } ); // vp = new VizieRPanel(null, true, false, null, null); //vp = new VizieRPanel(aladin.glu, true, false, null, null); vp = new VizieRPanel(aladin.glu, FRAME, false, null, null, 10); vp.setBounds(40,y,400,280); add(vp); String[] tab1 = vp.getSelection("SURVEY"); vSurveys = new Vector(); //La liste des surveys par defaut for (int i = 0 ; i < tab1.length; i++) { vSurveys.addElement(tab1[i]); } String[] tab2 = vp.getSelection("MISSION"); vArchives = new Vector(); //La liste des archives for (int i = 0 ; i < tab2.length; i++) { vArchives.addElement(tab2[i]); } // Positionnement des objets pour les resultats // vizier.setRef(vizierlist,legende); } /** Creation d'un plan de maniere generique */ protected int creatPlane(String target,String radius,String criteria, String label, String origin) { String catalogs=criteria; // EN PREMIERE APPOCHE... if( label==null ) label=catalogs; return creatVizieRPlane(target,radius,catalogs,label,null); } /** Creation d'un plan de maniere specifique */ protected int creatVizieRPlane(String target,String radius,String catalogs, String label, String origin) { URL u; String s = Glu.quote(catalogs)+" "+Glu.quote(target)+" "+Glu.quote(radius); if( (u=aladin.glu.getURL(TAGGLU,s))==null ) { Aladin.warning(this,WERROR,1); return -1; } if( !verif(Plan.CATALOG,target,label+" "+radius) ) return -1; return aladin.calque.newPlanCatalog(u,label,target,label+" "+radius); } /** Interrogation de Vizir */ public void submit() { URL u; String objet,sz,cata; Frame f=getFrame(this); // if focus on catalogs panel then apply on this // component the submit action if (catalog.getText().compareTo("") == 0) { vp.submit(target.getText(), radius.getText()); java.awt.List theTestList = vp.getResultList(); // fill the catalog list catalogs.removeAllElements(); for (int i = 0; i < theTestList.getItemCount(); i++) catalogs.addElement(theTestList.getItem(i)); if (vcl == null) { Button controlButton = new Button("SUBMIT"); controlButton.setFont(LBOLD); controlButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { submit(); vcl.resetCatList(); catalog.setText(""); } } ); vcl = new VizieRCatalogs(catalog, getReadMe, catalogs, controlButton); } else vcl.show(catalogs); if (target.getText().compareTo("") == 0) vcl.setTitle(catalogs.size() + " catalog(s) found " + target.getText()); else vcl.setTitle(catalogs.size() + " catalog(s) found around " + target.getText()); // appel au treeview // aladin.treeView.addBranch(target.getText(),radius.getText(),this); return; } if( (objet=getTarget())==null ) return; sz = getRadius(); if( sz.equals("") ) { Aladin.warning(this,WNEEDRAD); return; } cata = catalog.getText().trim(); if( cata.equals("") ) { Aladin.warning(this,WNEEDCAT); return; } String t= new String(objet); waitCursor(); // Je deselectionne les catalogues dans la liste // histoire de ne pas les reprendre sans faire expres //for( int i=vizierlist.countItems()-1; i>=0; i-- ) vizierlist.deselect(i); creatPlane(objet,sz,cata,null,null); catalog.setText(""); defaultCursor(); } /** Reset du formulaire */ protected void clear() { super.clear(); rad[0].setText("10 arcmin"); catalog.setText(""); vp.resetAll(); } /** Re-affichage avec regeneration du panel du formulaire. * Rq : Eh oui, il faut bien ruser pour supporter Netscape 3.0 */ protected void reaffiche() { // try{ invalidate(); validate(); } catch( Exception e ) {} hide();show(); } /** Events management * @@see aladin.VizieR */ public boolean action(Event evt, Object what) { // Affichage via Netscape du Readme du catalogue courant if( CATDESC.equals(what) ) { String cata = catalog.getText().trim(); if( cata.equals("") ) { Aladin.warning(this,WNEEDCAT); return true; } cata = Glu.quote(cata); waitCursor(); aladin.glu.showDocument("getReadMe",cata); defaultCursor(); return true; } return false; } /** Cache la sous-fenetre d'interrogation de VizieR */ protected void hideSFrame() { } } tions = actions; // cds/aladin/VOTableEISGenerator.java010064400076440000132000000527410770227416100201300ustar00ferniquecds00000400000013package cds.aladin; import cds.xml.Field; import java.util.Vector; import java.util.Hashtable; import java.io.*; /** This class aims at producing a VOTable output from a set of Source objects It was developped for the AVO January 2003 demo, and especially the data exchange with the SED tool * @@author Thomas Boch [CDS] * @@version 0.8 : 13 novembre 2002 - Nettoyage du code, suppression de methodes inutiles * @@version 0.71 : 28 octobre 2002 - Adaptation au format necessaire pour le SED --> une TABLE pour chaque source avec lambda, le flux, l'erreur sur le flux * @@version 0.7 : 27 Septembre 2002 - Creation */ final public class VOTableEISGenerator { static final String CR = System.getProperty("line.separator"); static final String PREAMBLE = new StringBuffer("").append(CR).append("").toString(); // level of indentation private int indentLevel = 0; private int shiftWidth = 4; // VOTable output private StringBuffer vot; // sources from which VOTable output is produced private Source[] sources; // index for case1 int indexFreq, indexFlux, indexFluxErr, indexBW; // list of frequencies for different EIS bands (key = "_"+band) static final private Hashtable FREQUENCY = new Hashtable(); // list of DELTA frequency for different EIS bands (key = "_"+band) static final private Hashtable FERROR = new Hashtable(); // list of zero-points for different EIS bands (key = "_"+band) static final private Hashtable ZP = new Hashtable(); // list of zero-points errors for different EIS bands (key = "_"+band) static final private Hashtable ZPERROR = new Hashtable(); // list of magnitude columns for EIS catalogs static final private Vector MAGCOL = new Vector(); // list of magnitude UCDs for VOTable coming from Sextractor static final private Vector SEXUCD = new Vector(); // list of magnitude UCDs for eis-cc catalog static final private Vector EISCCUCD = new Vector(); // list of magnitude UCDs for EIS single band published catalog static final private Vector EISSINGLEUCD = new Vector(); // different fields which will be in VOTable output static final private Field[] FIELDS = new Field[4]; private static final String EIS_CC = "II/234"; private static final String MAG = "mag"; static { // initialisation of FREQUENCY mapping String[] keys = {"U","B","V","R","I","J","H","K"}; // Valeur de la frequence pour chaque bande (Hz) double[] fValues = {8.4735008e+14, 6.5801681e+14, 5.6119891e+14, 4.6827938e+14, 3.5125068e+14, 2.4573152e+14, 1.8392175e+14, 1.3689153e+14}; // Erreur sur la frequence pour chaque bande (Hz) (demi-bande passante) double[] fErrorValues = {6.7059927e+13, 6.5353952e+13, 4.7274337e+13, 5.8333771e+13, 2.8540404e+13, 2.1451153e+13, 1.7320239e+13, 1.2188972e+13}; // Valeur des zero points pour chaque bande (Jy) double[] zpValues = {8.1321326, 9.0221171, 8.9015597, 8.7157219, 8.4577423, 8.0028097, 7.5215004, 7.0154499}; // Erreur sur le zero point (Jy) ATTENTION : On estime pour le moment que sigmaZP est egal a 0. Cela peut encore changer. double[] zpErrorValues = {0.0 , 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; EISCCUCD.addElement("PHOT_JHN_U"); EISCCUCD.addElement("PHOT_JHN_B"); EISCCUCD.addElement("PHOT_JHN_V"); EISCCUCD.addElement("PHOT_COUS_R"); EISCCUCD.addElement("PHOT_COUS_I"); EISCCUCD.addElement("PHOT_JHN_J"); EISCCUCD.addElement("PHOT_JHN_K"); EISSINGLEUCD.addElement("PHOT_INT-MAG_U"); EISSINGLEUCD.addElement("PHOT_INT-MAG_B"); EISSINGLEUCD.addElement("PHOT_INT-MAG_V"); EISSINGLEUCD.addElement("PHOT_INT-MAG_R"); EISSINGLEUCD.addElement("PHOT_INT-MAG_I"); for( int i = 0 ; i"); newLine(); indentLevel++; writeAllSources(); vot.append(""); Aladin.trace(3,"Generated VOTable for Sed input : \n\n"+vot); return new BufferedInputStream(new ByteArrayInputStream(vot.toString().getBytes())); } // append to vot all the stuff related with sources // PRE : sources must have been sorted according to their cat name private void writeAllSources() { int curPos=0; String curCatName=null; String oldCatName=null; if( sources!=null ) { // process each source for( int i=0; i if( oldCatName!=null && !curCatName.equals(oldCatName) ) { indentLevel--; newLine(); doIndent(); vot.append(""); newLine(); } // new if( oldCatName==null || !curCatName.equals(oldCatName) ) { doIndent(); vot.append(new StringBuffer("")); indentLevel++; } writeTable(sources[i]); oldCatName = curCatName; } } // write final indentLevel--; newLine(); doIndent(); vot.append(""); newLine(); } private void writeDescription() { // FIELD OID newLine(); doIndent(); vot.append(""); newLine(); doIndent(); vot.append(""); for( int i=0;i"); newLine(); doIndent(); vot.append(""); } } /** Retourne la longueur d'onde pour une colonne donnee (colonne representant une bande) */ // A modifier si on decide de ne plus faire qqch code en dur private String getFrequency(String ucd) { try { return ((Double)FREQUENCY.get(ucd.substring(ucd.length()-2))).toString(); } catch(NullPointerException e) {return null;} } private String getDeltaFreq(String ucd) { try { return ((Double)FERROR.get(ucd.substring(ucd.length()-2))).toString(); } catch(NullPointerException e) {return null;} } /** Retourne le flux pour une colonne donnee (colonne representant une bande) */ // A modifier si on decide de ne plus faire qqch code en dur private String getFlux(String fieldUcd, String mag) { if( mag==null) return null; Double zp = (Double)ZP.get(fieldUcd.substring(fieldUcd.length()-2)); double m; try { m = new Double(mag).doubleValue(); } catch( NumberFormatException e ) {return null;} return new Float(FluxConverter.getFlux(zp.doubleValue(),m)).toString(); } /** Retourne l'erreur sur le flux pour une colonne donnee (colonne representant une bande) */ // A modifier si on decide de ne plus faire qqch code en dur private String getFluxError(String fieldUcd, String fieldName, String flux, Source s) { if( flux==null) return null; Double zpError = (Double)ZPERROR.get(fieldUcd.substring(fieldUcd.length()-2)); // On recupere l'erreur correspondante (prefixee par "e_" dans VizieR) int posMagError = s.findColumn("e_"+fieldName); if(posMagError<0) return ""; String magErrorStr = s.getValue(posMagError); // si l'erreur sur la magnitude est vide --> upper limit, on a decide de renvoyer -1 pour l'erreur sur le flux if( magErrorStr.length() == 0 ) return "-1"; return new Float(FluxConverter.getFluxError( new Double(flux).doubleValue(), zpError.doubleValue(), new Double(magErrorStr).doubleValue() )).toString(); } private void writeData(Source s) { // on fixe l'OID s.setOID(PREFIX+s.hashCode()); newLine(); doIndent(); vot.append(""); indentLevel++; newLine(); doIndent(); vot.append(""); indentLevel++; if( case1(s) ) writeCase1Values(s); else if( case2(s) ) writeCase2Values(s); else if( case3(s) ) writeCase3Values(s); else if( case4(s) ) writeCase4Values(s); indentLevel--; newLine(); doIndent(); vot.append(""); indentLevel--; newLine(); doIndent(); vot.append(""); } /* ---- Different cases accorrding to Mark Allen's mail ---- */ // case 1 : table with fluxes and frequencies, ready to be plotted private boolean case1(Source s) { return ( indexFlux = s.findUCD("PHOT_FLUX_DENSITY") ) >=0 && ( indexFluxErr = s.findUCD("ERROR") ) >=0 && ( indexFreq = s.findUCD("OBS_FREQUENCY") ) >=0 && ( indexBW = s.findUCD("INST_FILTER_FWHM") ) >=0 ; } // case 2 : EIS draft catalogue eis-cc private boolean case2(Source s) { // if no UCD "ERROR" --> false if( s.findUCD("ERROR")<0 ) return false; Field[] fields = s.leg.field; String curUcd; for( int i=0;i false if( s.findUCD("ERROR")<0 ) return false; Field[] fields = s.leg.field; String curUcd; for( int i=0;i false if( index<=0 || s.findUCD("ERROR")<0 || s.findColumn("Mtot")<0 ) return false; Field[] fields = s.leg.field; String curUcd; for( int i=0;i"); indentLevel++; newLine(); doIndent(); // OID vot.append(""); vot.append( s.getOID()); vot.append(""); // ---- frequency of the band ---- // vot.append(""); vot.append( s.getValue(indexFreq) ); vot.append(""); // ---- delta frequency for this band ---- // vot.append(""); vot.append( s.getValue(indexBW) ); vot.append(""); // ---- corresponding flux ---- // vot.append(""); vot.append( s.getValue(indexFlux) ); vot.append(""); // ---- corresponding flux error ---- // String fieldName = s.leg.field[indexFlux].name; String fieldUcd = s.leg.field[indexFlux]==null?null:s.leg.field[indexFlux].ucd.toUpperCase(); String fluxErr; // On recupere l'erreur correspondante (prefixee par "e_" dans VizieR) int posFluxError = s.findColumn("e_"+fieldName); if(posFluxError<0) fluxErr = ""; else fluxErr = s.getValue(posFluxError); vot.append(""); vot.append( fluxErr ); vot.append(""); indentLevel--; newLine(); doIndent(); vot.append(""); } private void writeCase2Values(Source s) { Field[] fields = s.leg.field; String fieldName, fieldUcd; String freq,eFreq,flux,mag; for( int i=0; i=0 ) { // si on n'a pas la valeur de la longueur d'onde, on passe au champ suivant if( ( freq = getFrequency(fieldUcd) ) == null ) continue; //System.out.println(fields[i].precision); //System.out.println(fields[i].datatype); newLine(); doIndent(); vot.append(""); indentLevel++; newLine(); doIndent(); // OID vot.append(""); vot.append( s.getOID()); vot.append(""); // ---- frequency of the band ---- // vot.append(""); vot.append( freq ); vot.append(""); // ---- delta frequency for this band ---- // eFreq = getDeltaFreq(fieldUcd); vot.append(""); vot.append( eFreq ); vot.append(""); // ---- corresponding flux ---- // mag = s.getValue(i); flux = getFlux(fieldUcd, mag); vot.append(""); vot.append( flux ); vot.append(""); // ---- corresponding flux error ---- // vot.append(""); vot.append( getFluxError(fieldUcd, fieldName, flux, s) ); vot.append(""); indentLevel--; newLine(); doIndent(); vot.append(""); } } } private void writeCase3Values(Source s) { Field[] fields = s.leg.field; String fieldName, fieldUcd; String freq,eFreq,flux,mag; for( int i=0; i=0 ) { // si on n'a pas la valeur de la longueur d'onde, on passe au champ suivant if( ( freq = getFrequency(fieldUcd) ) == null ) continue; newLine(); doIndent(); vot.append(""); indentLevel++; newLine(); doIndent(); // OID vot.append(""); vot.append( s.getOID()); vot.append(""); // ---- frequency of the band ---- // vot.append(""); vot.append( freq ); vot.append(""); // ---- delta frequency for this band ---- // eFreq = getDeltaFreq(fieldUcd); vot.append(""); vot.append( eFreq ); vot.append(""); // ---- corresponding flux ---- // mag = s.getValue(i); flux = getFlux(fieldUcd, mag); vot.append(""); vot.append( flux ); vot.append(""); // ---- corresponding flux error ---- // vot.append(""); vot.append( getFluxError(fieldUcd, fieldName, flux, s) ); vot.append(""); indentLevel--; newLine(); doIndent(); vot.append(""); } } } private String AB2Vega(String strVal, String ucd) { //System.out.println(strVal); double initialMag; try { initialMag = new Double(strVal).doubleValue(); } catch(NumberFormatException e) {return "";} String band = ucd.substring(ucd.length()-1); if( band.equals("U") ) return new Double(initialMag-0.80).toString(); else if( band.equals("B") ) return new Double(initialMag+0.11).toString(); else if( band.equals("V") ) return new Double(initialMag).toString(); else if( band.equals("R") ) return new Double(initialMag-0.19).toString(); else if( band.equals("I") ) return new Double(initialMag-0.50).toString(); else return ""; } private void writeCase4Values(Source s) { Field[] fields = s.leg.field; String fieldName, fieldUcd; String freq,eFreq,flux,mag; for( int i=0; i=0 ) { // si on n'a pas la valeur de la longueur d'onde, on passe au champ suivant if( ( freq = getFrequency(fieldUcd) ) == null ) continue; //System.out.println(fields[i].precision); //System.out.println(fields[i].datatype); newLine(); doIndent(); vot.append(""); indentLevel++; newLine(); doIndent(); // OID vot.append(""); vot.append( s.getOID()); vot.append(""); // ---- frequency of the band ---- // vot.append(""); vot.append( freq ); vot.append(""); // ---- delta frequency for this band ---- // eFreq = getDeltaFreq(fieldUcd); vot.append(""); vot.append( eFreq ); vot.append(""); // ---- corresponding flux ---- // mag = AB2Vega(s.getValue(i), fieldUcd); //System.out.println(mag); flux = getFlux(fieldUcd, mag); vot.append(""); vot.append( flux ); vot.append(""); // ---- corresponding flux error ---- // vot.append(""); vot.append( getFluxError(fieldUcd, fieldName, flux, s) ); vot.append(""); indentLevel--; newLine(); doIndent(); vot.append(""); } } } /** append an attribut to vot */ private void addAttribut(String att, String attName, boolean encode) { if( att!=null ) { if(encode) att = UCDFilter.replace(att, "\"", """); vot.append(" ").append(new StringBuffer(attName)).append("=\"").append(att).append("\"").toString(); } } /** returns value of field f for source s * returns "" if f doesn't exist in s */ private String getFieldValue(Source s, Field f) { int pos = s.findColumn(f.name); if( pos<0 ) return ""; return s.getValue(pos); } /** append a carriage return to vot */ private void newLine() { vot.append(CR); } /** append to vot the number of spaces correponding to the indent level */ private void doIndent() { for(int i=0;i0 ) { vot.append(new StringBuffer(" ID=\"").append(id).append("\"")); } vot.append(new StringBuffer(">")); indentLevel++; writeDescription(); writeData(s); indentLevel--; newLine(); doIndent(); vot.append(""); } /** retrieves the VOTable-datatype from an Astrores one */ private String getDataType(String fitsDT) { if( fitsDT==null || fitsDT.length()==0 ) return fitsDT; switch(fitsDT.charAt(0)) { case 'F' : return "float"; case 'D' : return "double"; case 'I' : return "int"; case 'L' : return "boolean"; case 'A' : return "char"; default: return fitsDT; } } /*// just for test purposes public static void main(String[] args) { VOTableEISGenerator v = new VOTableEISGenerator(); InputStream is = v.getOutput(); int c; try { while((c = is.read())!= -1) { System.out.print((char)c); } } catch(java.io.IOException e){} //System.out.println(v.getOutput()); }*/ } : re-extracted sources coming fcds/aladin/Warning.java010064400076440000132000000171130770227416100160230ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Bouton WARNING d'indication de la precision * * @@author Pierre Fernique [CDS] * @@version 1.1 : (8 dec 00) Decouplage LCoord et Warning * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Warning extends Canvas { static final String DESCRIPTION = "Click here to see the warning about coordinates"; static final int H = Target.H; // Hauteur de la fenetre static final int HM = H-2; // on enleve la marge static final int W = HM; // Gestion du bouton de Warning static boolean oup=false; // Vrai si le warning precedent est up static boolean up=true; // Vrai si le warning est up static final int [] trX = { W-HM/2, W-HM/2-7, W-HM/2+7, W-HM/2}; static final int [] trY = { HM/2-7, HM/2+7, HM/2+7, HM/2-7}; Aladin aladin; Image img; // Image du double buffer Graphics g; // Contexte graphique du double buffer /** Creation de l'element du Warning. * @@param aladin reference */ protected Warning(Aladin aladin) { this.aladin=aladin; resize(W,H); } /** Affichage du bouton du Warning. * Utilise la valeur de up et oup pour determiner * si le bouton doit etre enfonce ou relache et s'il est necessaire * de le reafficher */ private void drawWarning() { if( up==oup ) return; /* g.setColor( up?Aladin.BKGD:Color.darkGray ); g.fillRect(1,1,HM-2,HM-2); g.setColor( !up?Color.black:Color.white ); g.drawLine(1,0,W-1,0); g.drawLine(1,0,1,HM); g.setColor( up?Color.black:Color.white ); g.drawLine(W-1,HM,W-1,0); g.drawLine(W-1,HM,0,HM); g.setColor( Color.white ); */ g.setColor( !up?Color.red:Color.white ); g.fillPolygon(trX,trY,trX.length); g.setColor( Color.red ); g.drawPolygon(trX,trY,trX.length); g.setColor( Color.black ); g.drawLine(trX[0],trY[0]+4,trX[0],trY[1]-4); g.drawLine(trX[0],trY[1]-2,trX[0],trY[1]-2); oup=up; } /** On enfonce le bouton du warning */ public boolean mouseDown(Event e, int x,int y) { if( Aladin.inHelp ) return true; up=false; repaint(); return true; } /** On relache le bouton du warning. * Appelle le browser avec la marque GLU "Aladin.java.warning" */ public boolean mouseUp(Event e, int x,int y) { if( Aladin.inHelp ) return true; Aladin.info( getWarning() ); up=true; repaint(); return true; } /** On se deplace sur le bouton du warning */ public boolean mouseMove(Event e, int x,int y) { if( Aladin.inHelp ) return true; aladin.status.setText(DESCRIPTION); return true; } /** On quitte le bouton du Warning*/ public boolean mouseExit(Event e, int x,int y) { Aladin.makeCursor(this,Aladin.DEFAULT); aladin.status.setText(""); return true; } /** On quitte le bouton du Warning*/ public boolean mouseEnter(Event e, int x,int y) { aladin.status.setText(""); Aladin.makeCursor(this,Aladin.HAND); return true; } public void update(Graphics gr) { if( img==null || img.getWidth(this)!=W || img.getHeight(this)!=H ) { img=createImage(W,H); g=img.getGraphics(); g.setColor(Aladin.BKGD); g.fillRect(0,0,W,H); } // Le warning drawWarning(); paint(gr); } public void paint(Graphics gr) { if( img==null || img.getWidth(this)!=W || img.getHeight(this)!=H ) { update(gr); return; } gr.drawImage(img,0,0,null); } /** Gestion du texte du Warning * @@return retourne le texte concernant le Warning */ protected String getWarning() { return("!W A R N I N G\n \n"+ "A) Most of the Aladin Java positions are given to the best "+ "astrometric accuracy. "+ "However, in some cases errors could be off up to 4\" "+ "and can't be used as astrometric positions. "+ "The main reasons are:\n"+ ". 1.The pixel is 1\"7 wide for the STScI images and 0\"67 "+ "wide for the MAMA images\n"+ ". 2.The error on the position given by the DSS-I calibrations "+ "(STScI images) could be of the order of 4\" on the edges. "+ "The accuracy of the positions can easely be checked with "+ "the superposition of astrometric catalogues such as TRC or USNO2."+ "\n \n"+ "B) Aladin manipulates the images in 8 bits only, with an automatic"+ "pixel cut keeping 99.9% of the image information only." ); } } cds/aladin/Words.java010064400076440000132000000251240770227416100155150ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Gestion des entites (suite de mots) composants une mesure. * Peut etre un triangle de repere, un texte simple, une ancre *

* - Les Triangles sont des mots qui commencent simplement par "_"
* - Les ancres sont des tags GLU (a la syntaxe la plus simple) * * @@author Pierre Fernique [CDS] * @@version 1.0 : (11 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class Words implements Runnable { // Differents types d'alignement possibles static final int LEFT = 0; static final int RIGHT = 1; static final int CENTER = 2; static final int COORD = 3; // Sur le signe + ou - de la declinaison // Les composantes de l'objet String text; // Texte a afficher (sauf repere) int width; // Nbre de caracteres, 0 si non cadre String id; // Identificateur pour une marque GLU String param; // Parametres pour une marque GLU int x,y; // Position (reference au texte) int w,h; // Largeur et hauteur (totales) int align; // LEFT, RIGHT, CENTER ou COORD int size; // Utilise par le tag GLU ?????? // Type de mots boolean glu; // Marque GLU boolean repere; // Triangle (repere) boolean archive; // Bouton (acces a une archive FITS) // Les variables d'etat boolean selected; // Mot en cours de selection boolean pushed=false; // Ancre qui vient d'etre cliquee -> en rouge boolean haspushed=false; // Ancre qui a ete cliquee -> violet // Variable de travail Thread thread; // Utilise lors de l'appel d'une marque GLU // Les References MCanvas m; // Canvas pour l'affichage des mesures Glu g; // Pour faire appel au GLU /** Creation d'une sequence de mots. * Determine s'il s'agit d'un tag GLU, d'un repere (triangle) ou * d'une simple sequence. * @@param tag La sequence * @@param width le nombre de caracteres d'affichage * @@param align le type d'alignement */ protected Words(String tag) { this(tag,0,LEFT); } protected Words(String tag,int width) { this(tag,width,LEFT); } protected Words(String tag,int width,int align) { this.width = width; this.align = align; char [] a = tag.toCharArray(); if( !(glu=tagGlu(a)) ) text=tag; setRepere(); } /** Positionne le flag repere et archive a true si c'est le cas */ void setRepere() { repere=false; // Par defaut if( !glu ) return; // Recuperation du premier caractere de l'identificateur GLU String type = id.substring(0,1); // Les reperes sont des tags GLU dont l'id commence par _ if( type.equals("_") ) repere=true; else if( type.equals("^") ) archive=true; else return; // On enleve le premier caractere id = id.substring(1); } /** Modifie la position. * @@param x,y Nouvelle position */ protected void setPosition(int x,int y) { this.x = x; this.y = y;} /** Retourne le texte associe a Word */ protected String getText() { return text; } /** Affiche dans aladin.urlStatus l'URL ou la marque GLU associee */ protected void urlStatus(MyLabel urlStatus) { String s; if( id.equals("Http") ) s=param; else s=(param.length()>0)?"Glu tag: <&"+id+" "+param+">":"Glu: <&"+id+">"; urlStatus.setText(s); } /** Modifie la position et la taille. * @@param x,y Nouvelle position * @@param w,h Nouvelle taille */ protected void setPosition(int x,int y, int w, int h) { this.x = x; this.y = y; this.w = w; this.h = h; } /** Analyse de chaine GLU. * Met a jour la variable text avec un eventuel texte d'ancre (<&...|texte>) * @@param a La chaine en cours d'analyse * @@param i L'indice de la position courante * @@return Indice du prochain caratere a analyser, ou -1 si fini */ int anchorGlu(char [] a, int i) { int j; StringBuffer anchor = new StringBuffer(); for( j=i+1; j) * @@param a La chaine en cours d'analyse * @@param i L'indice de la position courante * @@return Indice du prochain caratere a analyser, ou -1 si fini */ int paramGlu(char [] a, int i) { int j; StringBuffer param = new StringBuffer(); for( j=i; j) * @@param a La chaine en cours d'analyse * @@param i L'indice de la position courante * @@return Indice du prochain caratere a analyser, ou -1 si fini */ int idGlu(char [] a, int i) { int j; StringBuffer id = new StringBuffer(); for( j=i; j) * @@param a La chaine a analyser * @@return true s'il s'agit effectivement d'un tag GLU, * sinon false */ protected boolean tagGlu(char [] a ) { int i=2; if( a.length>=2 && (a[0]!='<' || a[1]!='&') ) return false; if( (i=idGlu(a,i))<0 ) return false; if( (i=paramGlu(a,i))<0 ) return false; if( a[i]=='|' ) if( (i=anchorGlu(a,i))<0 ) return false; if( a[i]!='>' ) return false; size = i+1; return true; } /** Test d'appartenance. * @@param xc,yc Position de la souris * @@return true si la position est dans la sequence de mots sinon false */ protected boolean inside(int xc,int yc) { return xc>=x && xc<=x+w && yc>=y && yc<=y+h; } /** Appel au GLU. * L'appel au GLU se fait par un Thread independant. * @@param g Reference au GLU * @@param m Rerefence au Canvas des mesures */ protected void callGlu(Glu g,MCanvas m) { this.g = g; this.m = m; haspushed=pushed=true; /* // ATTENTION, CETTE METHODE n'AUTORISE QU'UN SEUL PARAMETRE // POUR LA MARQUE GLU if( !id.equals("Http") ) { param= (Glu.cutParam(param))[0]; param = URLEncoder.encode(param); } */ thread = new Thread(this); thread.setPriority( Thread.NORM_PRIORITY -1); thread.start(); } public void run() { g.showDocument(id,param,id.equals("Http")); // g.showDocument(id,param,true); try{ Thread.currentThread().sleep(3000); } catch( Exception e) { } pushed=false; m.repaint(); } /* static boolean first=true; static String INFOARCHIVE = "The access to the archive servers\n"+ "may take some time.\nPlease be patient..."; */ /** Appel a l'archive FITS */ protected void callArchive(Aladin aladin,Objet o) { /* if( first ) { Aladin.info(INFOARCHIVE); first=false; } */ // String label = "HST "+param; String label = param; boolean flagEncode = id.equals("Http"); URL url = aladin.glu.getURL(id,param,flagEncode); // Resolution GLU String objet=Coord.getSexa(((Position)o).raj,((Position)o).dej,""); aladin.calque.newPlanImage(url,PlanImage.OTHER, label,objet,param, "provided by the original archive server", PlanImage.UNKNOWN,PlanImage.UNDEF, true,o); } } cds/aladin/Zoom.java010064400076440000132000000204270770227416100153440ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Panel de gestion du Zoom et de la loupe * * @@author Pierre Fernique [CDS] * @@author Anais Oberto [CDS] * @@version 1.3 : (fev 2003) Petit peaufinage sur changeValue() * @@version 1.2 : (dec 2001) Incorporation mode RGB * @@version 1.1 : (27 mai 99) Correction du centrage du zoom * @@version 1.0 : (11 mai 99) Toilettage du code * @@version 0.91 : Revisite le 1 dec 98 * @@version 0.9 : (??) creation */ public final class Zoom extends Panel { // Les valeurs generiques static int mzn[] = { 1, 1, 1, 1, 1, 1, 2 }; // Valeur zoom < 1, Numerateur static int mzd[] = { 64, 32, 16, 8, 4, 2, 3 }; // Valeur zoom < 1, Denominateur static final int MINZOOM=mzn.length; // Nombre de valeurs zoom <1 static final int MAXZOOM=7; // en puissance de 2, valeur maximal du zoom // Les conposantes de l'objet ZoomView zoomView; // Le canvas associe au Zoom Choice cZoom; // Le Choice des differentes valeurs de zoom // Les references aux objets Calque calque; Aladin aladin; /** Creation du Panel du zoom. * @@param calque,aladin References */ protected Zoom(Calque calque, Aladin aladin) { int i; this.aladin = aladin; this.calque = calque; zoomView = new ZoomView(aladin,calque); cZoom = new Choice(); for( i=0; i=0; i-- ) { String s=cZoom.getItem(i).substring(5); if( s.equals(sZoom) ) return i; } return -1; } /** Memorisation des infos du zoom courant dans le plan passe en parametre * @@param plan Le plan qui servira a la memorisation */ protected void setMemo(Plan p) { p.xzoom = zoomView.x; p.yzoom = zoomView.y; p.zoom = cZoom.getSelectedIndex(); } /** Recuperation si possible des infos du zoom depuis le plan * passe en parametre. Sinon positionnement au centre, zoom =1 * @@param plan Le plan qui a servi a la memorisation */ protected void getMemo(Plan p) { if( p.zoom==-1 ) { zoomView.y = zoomView.x = zoomView.SIZE/2; cZoom.select(MINZOOM); } else { zoomView.x = p.xzoom; zoomView.y = p.yzoom; cZoom.select(p.zoom); } zoomView.repaint(); } /** Retourne la valeur courante du zoom. * @@return le facteur d'agrandissement du zoom courant * (x1/4,x1/3,x1/2,x1,x2,x4,x8...x32) */ protected double getValue() { int i= cZoom.getSelectedIndex(); if( i>=MINZOOM ) return (0x1<<(i-MINZOOM)); return (double)mzn[i]/mzd[i]; } /** Retourne le nombre de pixels "sources" lors d'un zoom */ protected int getNbPixelSrc() { int i= cZoom.getSelectedIndex(); return (i>=MINZOOM)?1:mzd[i]; } /** Retourne le nombre de pixels "destinations" lors d'un zoom */ protected int getNbPixelDst() { int i= cZoom.getSelectedIndex(); return (i>=MINZOOM)?(0x1<<(i-MINZOOM)):mzn[i]; } /** Retourne l'index courant du zoom. * @@return l'index du zoom */ protected int getIndex() { return cZoom.getSelectedIndex(); } /** Change la valeur du zoom et demande le repaint necessaire. * Soit multiplie, soit divise par 2. * @@param sens Sens de la modif 1 -> x2,-1 -> /2. * @@param x,y Nouveau centre du zoom * @@return true si on a pu changer de valeur */ protected boolean changeValue(int sens,int x, int y) { int i = cZoom.getSelectedIndex(); if( i+sens<0 || i+sens>=MINZOOM+MAXZOOM ) return false; cZoom.select(i+sens); zoomView.NewZoom(x,y,true); // calque.view.repaint(); return true; } protected boolean setZoom(String fct) { int i = getIndex(fct); if( i<0 ) return false; cZoom.select(i); zoomView.NewZoom(); calque.view.repaint(); return true; } public boolean action(Event e, Object o) { if( e.target instanceof Choice ) { zoomView.NewZoom(); calque.view.repaint(); return true; } return false; } /** Activation de la loupe */ protected void wenOn() { if( aladin.toolbox.tool[ToolBox.WEN].mode==Tool.DOWN ) zoomView.wenOn(); } /** Desactivation de la loupe */ protected void wenOff() { if( aladin.toolbox.tool[ToolBox.WEN].mode!=Tool.UP ) zoomView.wenOff(); } /** Mise a jour la loupe si necessaire. * @@param x,y Centre courant */ protected void wen(int x, int y) { if( aladin.toolbox.tool[ToolBox.WEN].mode!=Tool.DOWN ) return; zoomView.wen(x,y); } } cds/aladin/ZoomView.java010064400076440000132000000705720770227416100162050ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.aladin; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Le Zoom montre l'image de base de la ``View frame'' (en vignette) et * surcharge cette image d'un rectangle representant la partie visible * de l'image dans la ``View frame'' suivant l'echelle courante. *

* Une deuxieme fonction permet d'utiliser cet objet pour visualiser * en loupe les pixels proches de la souris lorsqu'elle se deplace dans * la ``View frame'' * * @@see aladin.Zoom() * @@see aladin.View() * @@author Pierre Fernique [CDS] * @@author Anais Oberto [CDS] * @@version 1.2 : (dec 01) Incorporation image RGB * @@version 1.1 : (27 mai 99) Recentrage du zoom corrige * @@version 1.0 : (11 mai 99) Toilettage du code * @@version 0.91 - 30 novembre 1998 (relecture du code) * @@version 0.9 - 30 mars 1998 */ public final class ZoomView extends Canvas implements Runnable { // Les valeurs generiques static final int WENZOOM = 8; // Agrandissement pour la loupe (puissance de 2) int SIZE; // Taille fixe de la fenetre // Les references aux autres objets Calque calque; Aladin aladin; // les composantes de l'objet Image img; // Image du buffer du canvas Image imgwen; // Image courante de la loupe Graphics gwen; // Contexte graphique de la loupe Image imgzoom; // Image reduite a WxW de l'image en cours Graphics gzoom; // Contexte graphique de l'image reduite // Les parametres a memoriser pour le zoom int etat=-1; // Etat courant de l'image courante double zoom=1; // Facteur d'agrandissement courant Rectangle rectzoom; // Rectangle de zoom Rectangle or; // Precedente position du rectangle de zoom boolean flagdrag; // Vrai si je suis en train de draguer boolean imgok; // vrai si j'ai une image dans le buffer Rectangle clip; // Rectangle du clip int x,y; // Position courante du rect. de zoom int owidth,oheight; // Dimension du calque.view int iz=0; // Numero d'ordre du dernier calcul du zoom Rectangle rzoom; // Rectangle du zoom dans l'image courante int W,H; // Taille de l'image reduite dans le zoom // Les parametres a memoriser pour la loupe int xwen,ywen; // Position de la loupe dans la vue courante Point oc; // Precedente position de la loupe dans les coord images boolean zoomok; // Vrai si on a fini de calculer le zoom Thread calculwen; // Thread du calcul de la loupe int xmwen,ymwen; // Position de la loupe sous la souris int nmwen; // Numero du plan de la loupe int memR,memG,memB,memX; // Memorisation de la valeur du pixel RGB ou gris boolean memInv; // Memorisation du cas INVERSE pour un plan RGB boolean flagRGB; // true s'il s'agit d'un plan RGB boolean flagwen; // Vrai si c'est la loupe qu'il faut afficher // a la place du zoom /** creation de la fenetre du zoom. * @@param aladin,calque References */ protected ZoomView(Aladin aladin,Calque calque) { this.aladin = aladin; this.calque = calque; setBackground(Color.white); SIZE=calque.select.ws+MyScrollbar.LARGEUR; y=x= SIZE/2; resize(SIZE,SIZE); } /** Deplacement du rectangle de zoom */ public boolean mouseDown(Event e, int xc, int yc) { or = null; flagdrag = true; NewZoom(xc,yc); return true; } /** Deplacement du rectangle de zoom */ public boolean mouseDrag(Event e, int xc, int yc) { flagdrag = true; NewZoom(xc,yc,false); return true; } /** Deplacement du rectangle de zoom */ public boolean mouseUp(Event e, int xc, int yc) { flagdrag=false; if( e.shiftDown() ) { xc=SIZE/2; yc=SIZE/2; } // On recentre NewZoom(xc,yc,true); calque.view.repaint(); repaint(); return true; } /** Facteur courant du zoom. * Mise a jour par calque.zoom.getValue(); * @@return Valeur courante du zoom * @@see aladin.calque.zoom#getValue() */ protected double zoom() { return zoom; } /** Recalcul le zoom a l'emplacement courant */ protected void NewZoom() { this.NewZoom(x,y); } /** Calcul et affichage du rectangle du zoom. * @@param xc,yc Nouveau centre du zoom */ protected void NewZoom(int xc, int yc) { NewZoom(xc,yc,true); } /** Calcul et affichage du rectangle du zoom. * @@param xc,yc Nouveau centre du zoom * @@param centrage trueavec centrage, false sinon */ protected void NewZoom(int xc, int yc,boolean centrage) { if( calculZoom(xc,yc,centrage) ) { if( !flagdrag && calque.unActiveOldPlan() ) { calque.select.repaint(); repaint(); System.gc(); } else repaint(); } } /** Calcul les dimensions du rectangle du zoom. * 1) Recherche le facteur du zoom (x1,x2,x4...)
* 2) Determine si le plan de ref est une image ou un catalogue
* 3) Calcul la taille du zoom ou fonction du facteur d'agrandissement * et des proportions de la Vue (View Frame)
* 4) Corrige un depassement eventuelle des limites * * @@param xc,yc Nouveau centre du zoom * @@param centrage trueavec centrage, false sinon */ protected synchronized boolean calculZoom(int xc, int yc,boolean centrage) { double imgW,imgH; zoomok = false; calque.view.newView(); // Recherche du facteur d'agrandissement zoom = calque.zoom.getValue(); // Recherche de l'image de reference en cours de vue et calcul du rapport // de cette derniere. Si il n'y a pas d'image de ref, on prendra la // taille de la projection en pixels Plan p = calque.getPlanRef(); if( p==null || p.type!=Plan.IMAGE || !p.flagOk ) { imgW=imgH=(p==null || p.projd==null)?500:p.projd.r; } else { imgW = (double)( ((PlanImage)p).width); imgH = (double)( ((PlanImage)p).height); } // Calcul de la proportion (si l'image n'est pas carree) W = SIZE; H = (int)(Math.round((W/imgW)*imgH)); if( H>W ) { W = (int)((double)W*W / (double)H); H = SIZE; } // Determination de la taille du rectangle de zoom int dW = (int)(Math.round(((W/imgW)*owidth )/zoom)); int dH = (int)(Math.round(((H/imgH)*oheight )/zoom)); // Recentrage automatique if( centrage ) { if( dW>W ) xc = W/2; else if( xc+dW/2>W ) xc = W-dW/2; else if( xc-dW/2<0 ) xc = dW/2; if( dH>H ) yc = H/2; else if( yc+dH/2>H ) yc = H-dH/2; else if( yc-dH/2<0 ) yc = dH/2; } // Memorisation du rectangle du zoom dans les coord. de l'image courante int xzoom = (int)(Math.round((imgW/W)*xc)); int yzoom = (int)(Math.round((imgH/H)*yc)); int wzoom = (int)(owidth/zoom); int hzoom = (int)(oheight/zoom); if( zoom>1 ) { wzoom++; hzoom++; } // On prend 1 de plus pour couvrir la vue entierement // Alignement fin if( wzoomnull si pb. */ protected synchronized Rectangle getZoom() { if( !zoomok || rzoom==null ) return null; return new Rectangle(rzoom.x,rzoom.y,rzoom.width,rzoom.height); } /** Convertion de coordonnees. * @@param xview,yview Point dans la Vue (View Frame) * @@return Retourne la position dans la vue dans les coordonnees * de l'image courante */ protected Point getPosition(int xview, int yview) { if( rzoom==null ) return new Point(xview, yview); int demi=(zoom>1)?(int)(zoom/2):0; return new Point(rzoom.x + (int)(Math.round((xview-demi)/zoom)), rzoom.y + (int)(Math.round((yview-demi)/zoom))); } /** Convertion de coordonnees. * @@param xview,yview Point dans la Vue (View Frame) * @@return Retourne la position dans la vue dans les coordonnees * de l'image courante */ protected PointD getPosition(double xview, double yview) { if( rzoom==null ) return new PointD((double)xview,(double)yview); double x= rzoom.x + xview/zoom; double y= rzoom.y + yview/zoom; return new PointD(x,y); } /** Convertion de coordonnees. * Ne teste pas si le point calcule est affichable. * @@param x,y Point dans l'image courante * @@return Retourne la position dans les coordonnees de la vue (View Frame) */ protected Point getViewCoord(int x, int y) { int newx,newy; if( rzoom==null ) return new Point(x,y); int demi=(zoom>1)?(int)(zoom/2):0; newx = (int)( (x - rzoom.x)*zoom +demi); newy = (int)( (y - rzoom.y)*zoom +demi); return new Point(newx,newy); } /** Convertion de coordonnees. * Ne teste pas si le point calcule est affichable. * @@param x,y Point dans l'image courante EN FLOATTANT * @@return Retourne la position dans les coordonnees de la vue (View Frame) */ protected Point getViewCoord(double x, double y) { int newx,newy; if( rzoom==null ) return new Point((int)Math.round(x),(int)Math.round(y)); newx = (int)Math.round( (x - rzoom.x)*zoom ); newy = (int)Math.round( (y - rzoom.y)*zoom ); return new Point(newx,newy); } /** Convertion de coordonnees. * @@param xview,yview Point dans la Vue (View Frame) * @@return Retourne la position dans les coordonnees du Zoom */ protected Point getZoomCoord(int xview, int yview) { Point c = getPosition(xview,yview); double imgW,imgH; Plan p = calque.getPlanRef(); if( p.type!=Plan.IMAGE ) imgW=imgH=p.projd==null?500:p.projd.r; else { imgW = (double)((PlanImage)p).width; imgH = (double)((PlanImage)p).height; if( imgW<0 || imgH<0 ) return null; } return new Point( (int)((W/imgW)*c.x),(int)((H/imgH)*c.y) ); } /** Convertion de coordonnees. * @@param x,y Point dans l'image courante * @@param dw,dh Marges de tolerance pour les tests sur l'affichage * @@return Retourne la position dans les coordonnees de la vue (View Frame) * ou (-1,-1) si le point calcule est en dehors de l'espace * affichable en tenant compte des marge de tolerance */ protected Point getViewCoordWithMarge(double x, double y, int dw, int dh) { Point newp = getViewCoord(x,y); if( newp.x<-dw || newp.x>owidth+dw || newp.y<-dh || newp.y>oheight+dh ) return new Point(-1,-1); return newp; } private void drawFleche(Graphics g,int x,int y,int x1,int y1,String s) { int L=5; g.drawLine(x,y,x1,y1); double theta,delta; if( x!=x1) { theta = Math.atan( (double)(y1-y)/(x1-x) ); if( x>x1 ) theta += Math.PI; } else { if( yW ) { W = (int)((double)W*W / (double)H); H = SIZE; } // Affichage du zoom suivant l'echelle gzoom.clearRect(0,0,SIZE,SIZE); /*anais*/ Image pimg; if (p instanceof PlanImageRGB) pimg = createImage( new MemoryImageSource(w, h, ((PlanImageRGB)p).pixelsRGB, 0,w)); else pimg = createImage( new MemoryImageSource(w,h,pi.cm,pi.pixels,0,w) ); PlanImage.waitImage(this,pimg); gzoom.drawImage(pimg,0,0,W,H,this); gzoom.setColor(Color.black); gzoom.drawRect(0,0,SIZE-1,SIZE-1); // Positionnement du Nord et de L'Est setNE(gzoom,(PlanImage)p); etat=pi.getEtat(); calculZoom(x,y,true); } } catch( OutOfMemoryError eOut ) { System.gc(); System.runFinalization(); return false; } catch( Exception ezoom ) { System.out.println("Try ezoom error: "+ezoom); return false; } } // Le buffer du paint sera celui du zoom; img = imgzoom; return true; } /** Changement de table des couleurs * POUR L'INSTANT JE FAIS UN SIMPLE REPAINT */ protected void setCM(IndexColorModel ic) { repaint(); } /** Generation de la loupe courante dans son buffer * Utilise comme posiition centrale (xwen,ywen) */ protected void drawImgWen() { Point c; // Position de la loupe ds les coord de l'image courante // Recherche du plan courant int n = calque.getIndexPlanBase(); if( n<0 ) { img=null; return; } // Calcul de la correspondance du point de la vue // dans les coordonnees de l'image courante c = getPosition(xwen,ywen); // Pas bouge if( c.equals(oc) ) return; oc = c; // Calcul de la nouvelle loupe calculWen(n,c.x,c.y); } /** Extraction des pixels et construction de l'image de la loupe. * @@param n facteur d'agrandissement (puissance de 2 obligatoirement) * @@param x,y Position de la loupe dans l'image de reference * @@see aladin.ZoomView#run() */ protected void calculWen(int n, int x,int y) { xmwen = x; ymwen = y; nmwen = n; /* if( calculwen!=null ) calculwen.stop(); calculwen = new Thread(this); calculwen.setPriority( Thread.NORM_PRIORITY -1); calculwen.start(); */ run(); } /** Suite de calculWen() afin de pouvoir facilement le faire * traiter par un Thread independant */ public void run() { int w = (SIZE/WENZOOM); byte [] pixels=null; /*anais*/ int [] pixelsRGB=null; byte [] scalepixels=null; int [] scalepixelsRGB=null; int x1 = xmwen-w/2; int y1 = ymwen-w/2; Image image; PlanImage p = (PlanImage)calque.plan[nmwen]; // Allocations if( pixels==null ) { /*anais*/ if (p instanceof PlanImageRGB) { pixelsRGB = new int[w*w]; scalepixelsRGB = new int [w*w*WENZOOM*WENZOOM]; } else { pixels = new byte [w*w]; scalepixels = new byte [w*w*WENZOOM*WENZOOM]; } } // Extraction de la portion de l'image if( x1>=0 && y1>=0 && x1+w>16; j= (memR*w)/255; for( i=0; i>8; j= (memG*w)/255; for( i=0; i. It is strongly * recommended to add an unambigus prefix to avoid conflicts with the * assignations done by the "external" application and its own assignations. * The unicity has to be maintained during all the session. It means that * successive VOTables must have difference unique identifiers. * @@param app "external" application compliante with ExtApp java interface * @@param in VOTable stream */ public abstract void loadVOTable(ExtApp app, InputStream in); /** * Allow an "external" application to show or hide this application */ public abstract void setVisible(boolean flag); /** * Allow an "external" application to control by script this application * @@param cmd script command depending to this application * @@return error or messages, can be null */ public abstract String execCommand(String cmd); /** * Call or Callback asking the other application to SHOW objects found * in a VOTable previous transmission via loadVOTable() method. * The action "SHOW" is a choice of the other application (for example a blink) * @@param oid list of identifiers found in VOTables (see comment of the * loadVOTable() method. */ public abstract void showVOTableObject(String oid[]); /** * Call or Callback asking the other application to SELECT objects found * in a VOTable previous transmission via loadVOTable() method. * The action "SELECT" is a choice of the other application (for example select * objects by showing the corresponding measurements, it can be the same thing * that the "SHOW" action - see showVOTableObject() method.) * @@param oid list of identifiers found in VOTables (see comment of the * loadVOTable() method. */ public abstract void selectVOTableObject(String oid[]); }cds/tools/CDSConstants.java010064400076440000132000000140620770227416100166340ustar00ferniquecds00000400000013// // Copyright 2002-2003 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // CDS design and static values for Java applications // // Author: Andr‰ Schaaff // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: schaaff@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.tools; import java.awt.Font; import java.awt.Color; import java.awt.Toolkit; /** * CDS design and static values interface * * @@author Andr‰ Schaaff [CDS] * * @@version 1.0 beta : (july 2002), xml format (Astrores or VOTable), glu and url values * (june 2002), STREAM and FRAME values * renamed to CDSConstants * @@version 0.9 : (january 2002), extraction from AladinJava * * */ public interface CDSConstants { static final boolean LSCREEN= Toolkit.getDefaultToolkit().getScreenSize().width > 1000; /** fonts average size */ static final int SIZE = LSCREEN?12:10; static String s = "Helvetica"; static Font BOLD = new Font(s,Font.BOLD, SIZE); static Font PLAIN = new Font(s,Font.PLAIN, SIZE); static Font ITALIC = new Font(s,Font.ITALIC,SIZE); static int SSIZE = SIZE-2; static Font SBOLD = new Font(s,Font.BOLD, SSIZE); static Font SPLAIN = new Font(s,Font.PLAIN, SSIZE); static Font SITALIC= new Font(s,Font.ITALIC,SSIZE); static int LSIZE = SIZE+2; static Font LPLAIN = new Font(s,Font.PLAIN, LSIZE); static Font LBOLD = new Font(s,Font.BOLD, LSIZE); static Font LITALIC= new Font(s,Font.ITALIC,LSIZE); static Font LLITALIC= new Font(s,Font.BOLD,18); static Font COURIER= new Font("Courier",Font.PLAIN,SIZE); static Font BCOURIER= new Font("Courier",Font.PLAIN+Font.BOLD,SIZE); static final int DEFAULT = 0; static final int WAIT = 1; static final int HAND = 2; static final int CROSSHAIR = 3; static final int MOVE = 4; static final int RESIZE = 5; static final int TEXT = 6; // background color static final Color BKGD = Color.lightGray; static final Color BKGDCOPYRIGHT = Color.white; static Color LGRAY = new Color(229,229,229); static final String COPYRIGHT = "(c) ULP/CNRS 1999-2002 - Centre de Donn‰es astronomiques de Strasbourg"; // Les textes associes aux differentes possibilites du menu static final int GETHEIGHT = 17; // Cochonnerie de getHeight() // True if standalone mode static boolean STANDALONE = true; // units static final String DEGREE = "degree"; static final String ARCMIN = "arcmin"; static final String ARCSEC = "arcsec"; // output mode, stream or frame static final int STREAM = 0; static final int FRAME = 1; // modal or non modal dialog static final boolean MODAL = true; static final boolean NONMODAL = false; // XML specific format static final int ASTRORES = 0; static final int VOTABLE = 1; // url or glu tag values static String VIZIERMETAGLU = "VizieR.Meta"; static String VIZIERMETACATGLU = "VizieR.MetaCat"; static String ASTROVIZIERMETA = "http://vizier.u-strasbg.fr/cgi-bin/asu-xml?-meta.aladin=all"; static String ASTROVIZIERMETACAT = "http://vizier.u-strasbg.fr/cgi-bin/asu-xml?-meta&"; static String VOVIZIERMETA = "http://vizier.u-strasbg.fr/cgi-bin/votable?-meta.aladin=all"; static String VOVIZIERMETACAT = "http://vizier.u-strasbg.fr/cgi-bin/votable?-meta&"; // default VizieR query url or glu values static String VIZIERMETACAT = VOVIZIERMETACAT; static String VIZIERMETA = VOVIZIERMETA; }cds/tools/CDSLabel.java010064400076440000132000000154650770227416100157070ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // ALADIN JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.tools; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; import java.util.*; /** * Un Label sur mesure pour Aladin. * * @@author Pierre Fernique [CDS] * @@version ?? : january 2002, part of a new package, cds.tools * @@version 1.1 : (20 mars 01) Rupture des lignes > 60 caracteres * @@version 1.0 : (10 mai 99) Toilettage du code * @@version 0.9 : (??) creation */ public final class CDSLabel extends Panel implements CDSConstants { static final int MARGE=10; Vector line=null; // Le texte a afficher (par ligne) Font font; // Font associee FontMetrics fm; // La metrique de la font courante int mode; // mode d'alignement Label.CENTER,... String text; /** Creation d'un label multi-lignes VIDE. */ public CDSLabel() { super(); } /** Creation d'un label multi-lignes AVEC les options par defaut. * @@param text Le texte du label */ public CDSLabel(String text) { this(text,Label.CENTER,PLAIN); } /** Creation d'un label multi-lignes AVEC la fonte par defaut. * @@param text Le texte du label * @@param mode Label.CENTER, Label.RIGHT ou Label.LEFT */ public CDSLabel(String text,int mode) { this(text,mode,PLAIN); } /** Creation d'un label multi-lignes. * @@param text Le texte du label * @@param mode Label.CENTER, Label.RIGHT ou Label.LEFT * @@param font la font a utiliser */ public CDSLabel(String text,int mode,Font font) { this.mode = mode; this.font=font; setFont(font); fm = Toolkit.getDefaultToolkit().getFontMetrics(font); setText(text); } /** Recuperation du texte */ public String getText() { return text; } /** Modification du texte du Label. * @@param text Le nouveau texte du label */ public void setText(String text) { String s; StringTokenizer st = new StringTokenizer(text,"\n"); int w,max=0; this.text=text; line = new Vector(10); while( st.hasMoreTokens() ) { s = st.nextToken(); StringTokenizer st1 = new StringTokenizer(s," ",true); StringBuffer s1=new StringBuffer(); while( st1.hasMoreTokens() ) { s1.append(st1.nextToken()); if( s1.length()>80 ) { line.addElement(s1.toString()); w = fm.stringWidth(s1.toString()); if( max0 ) { line.addElement(s1.toString()); w = fm.stringWidth(s1.toString()); if( max 0 ) s.append("&"); s.append(nom); s.append("="); s.append(URLEncoder.encode(valeur)); } }cds/tools/parser/Abs.java010064400076440000132000000005070770227416100163260ustar00ferniquecds00000400000013package cds.tools.parser; /** * Fonction valeur absolue */ public class Abs extends Function { /* * @@see cds.tools.parser.Function#eval(double) */ double eval(double x) { return Math.abs(x); } /* * @@see cds.tools.parser.Operator#keyword() */ String keyword() { return "abs"; } } cds/tools/parser/BasicOperator.java010064400076440000132000000010630770227416100203540ustar00ferniquecds00000400000013package cds.tools.parser; /** Classe BasicOperator */ public class BasicOperator extends Operator { int p; int op; /** Constructeur * @@param p - precedence * @@param op - operateur (voir classe Parser) * @@see cds.tools.parser.Parser */ BasicOperator(int p, int op) { this.p = p; this.op = op; type = Operator.BASIC; } public String toString() { return op + " " +precedence(); } public String keyword() { return ""+((char) op); } public int precedence() { return this.p; } } cds/tools/parser/Cos.java010064400076440000132000000005000770227416100163360ustar00ferniquecds00000400000013package cds.tools.parser; /** * Fonction cosinus */ public class Cos extends Function { /* * @@see cds.tools.parser.Function#eval(double) */ double eval(double x) { return Math.cos(x); } /* * @@see cds.tools.parser.Operator#keyword() */ String keyword() { return "cos"; } } cds/tools/parser/Deg2Rad.java010064400076440000132000000005540770227416100170330ustar00ferniquecds00000400000013package cds.tools.parser; /** * Fonction deg2rad (conversion de degrés en radians) */ public class Deg2Rad extends Function { /* * @@see cds.tools.parser.Function#eval(double) */ double eval(double x) { return Math.PI*x/180.0; } /* * @@see cds.tools.parser.Operator#keyword() */ String keyword() { return "deg2rad"; } }cds/tools/parser/Function.java010064400076440000132000000014630770227416100174100ustar00ferniquecds00000400000013package cds.tools.parser; import java.text.ParseException; import cds.astro.Unit; /** * Gabarit à utiliser pour créer des fonctions (unaires) */ public abstract class Function extends Operator { /** le constructeur devra être appelé par tous les constructeurs des classes dérivées */ Function() { type = Operator.FUNC; } // les fonctions ont une précédence supérieure à toutes les opérations de base int precedence() { return 100; } Unit evalUnit(Unit u) { Unit retUnit; try { retUnit = new Unit( eval(u.value) + u.symbol ); } catch( ParseException e ) {retUnit = new Unit();} return retUnit; } /** évaluation de la fonction au point x * * @@param x * @@return double valeur de la fonction en x */ abstract double eval(double x); } cds/tools/parser/Ln.java010064400076440000132000000005120770227416100161660ustar00ferniquecds00000400000013package cds.tools.parser; /** * Fonction logarithme népérien */ public class Ln extends Function { /* * @@see cds.tools.parser.Function#eval(double) */ double eval(double x) { return Math.log(x); } /* * @@see cds.tools.parser.Operator#keyword() */ String keyword() { return "ln"; } } cds/tools/parser/Log.java010064400076440000132000000005320770227416100163400ustar00ferniquecds00000400000013package cds.tools.parser; /** * Fonction logarithme base 10 */ public class Log extends Function { /* * @@see cds.tools.parser.Function#eval(double) */ double eval(double x) { return Math.log(x)/Math.log(10.0); } /* * @@see cds.tools.parser.Operator#keyword() */ String keyword() { return "log"; } } cds/tools/parser/Node.java010064400076440000132000000012770770227416100165130ustar00ferniquecds00000400000013package cds.tools.parser; import cds.astro.Unit; /** Classe Node - Brique de base pour le parser */ public class Node { // les differents types de noeuds (null/operateur/valeur/variable/fonction) public static final int NULL = -1; public static final int OP = 0; public static final int VALUE = 1; public static final int VAR = 2; public static final int FUNCTION = 3; Node left; Node right; double value; int op; int type; String svalue; protected Unit unit; Node() { type = NULL; left = null; right = null; op = NULL; value = 0.0; svalue=""; } } cds/tools/parser/Operator.java010064400076440000132000000010700770227416100174100ustar00ferniquecds00000400000013package cds.tools.parser; /** Classe Operator, classe abstraite commune aux les opérations de base et aux fonctions */ public abstract class Operator { static final int BASIC = 0; static final int FUNC = 1; // s'agit-il d'une opérateur de base (+,-,*,/) ou d'une fonction int type; /** * @@return int entier représentant la précédence de l'opérateur ( nombre élevé --> précedence importante) */ abstract int precedence(); /** * @@return String chaîne permettant de reconnaître la fonction */ abstract String keyword(); } cds/tools/parser/Parser.java010064400076440000132000000507710770227416100170650ustar00ferniquecds00000400000013package cds.tools.parser; import java.text.ParseException; import java.util.*; import java.io.*; import cds.astro.Unit; /** Classe Parser * Cette classe permet le "parsing" d'une chaine representant * une expression mathematique pouvant comporter des variables . * Les operateurs possibles sont +, -, *, /, (, ), ^ */ public class Parser { // contient les differentes variables private Hashtable vars; // différentes fonctions disponibles private Hashtable functions; // etat lors du parsing de la chaine private int state = 0; // les operateurs private static final int ADD = '+'; private static final int SUBTRACT = '-'; private static final int DIVIDE = '/'; private static final int MULTIPLY = '*'; private static final int POWER = '^'; private static final int GRP = '('; private static final int ENDGRP = ')'; private static final int UNDERSCORE = '_'; private static final int OPSQBR = '['; private static final int CLSQBR = ']'; private static final BasicOperator OP_ADD = new BasicOperator(Parser.precedence(ADD),ADD); private static final BasicOperator OP_MUL = new BasicOperator(Parser.precedence(MULTIPLY),MULTIPLY); private static final BasicOperator OP_DIV = new BasicOperator(Parser.precedence(DIVIDE),DIVIDE); private static final BasicOperator OP_SUB = new BasicOperator(Parser.precedence(SUBTRACT),SUBTRACT); private static final BasicOperator OP_GRP = new BasicOperator(0,GRP); private static final BasicOperator OP_ENDGRP = new BasicOperator(0,ENDGRP); private static final BasicOperator OP_POW = new BasicOperator(Parser.precedence(POWER),POWER); // noeud racine de l'arbre private Node root; // l'expression mathematique private String str; /** Constructeur - cree un nouveau parser vide */ public Parser() { root = null; vars = new Hashtable(5); functions= new Hashtable(5); initFunc(); str = "0"; } /** Constructeur - cree un nouveau parser * @@param s - l'expression a parser */ public Parser(String s) { root = null; vars = new Hashtable(5); functions = new Hashtable(5); initFunc(); if (!s.equals("")) str = new String(s); else str ="0"; } /** * Initialise le hastable functions en y plaçant les fonctions reconnues */ private void initFunc() { addFunc(new Sin()); addFunc(new Cos()); addFunc(new Tan()); addFunc(new Log()); addFunc(new Ln()); addFunc(new Abs()); addFunc(new Deg2Rad()); addFunc(new Rad2Deg()); } /** * Parse la chaine passee en parametre * @@param s - la chaine a parser */ public void parseString(String s) { this.str = s; parseString(); } /** * Effectue le parsing */ public void parseString() { // pile des objets Stack st_ob = new Stack(); // pile des operateurs Stack st_op = new Stack(); StringReader sr = new StringReader(str); StreamTokenizer tokenizer = new StreamTokenizer(sr); // ajustement du tokenizer tokenizer.parseNumbers(); tokenizer.lowerCaseMode(false); tokenizer.ordinaryChar(ADD); tokenizer.ordinaryChar(SUBTRACT); tokenizer.ordinaryChar(MULTIPLY); tokenizer.ordinaryChar(DIVIDE); tokenizer.ordinaryChar(POWER); tokenizer.wordChars(UNDERSCORE,UNDERSCORE); tokenizer.wordChars(OPSQBR,CLSQBR); tokenizer.wordChars('{','{'); tokenizer.wordChars('}','}'); // for encoding characters : tokenizer.wordChars('@@','@@'); tokenizer.wordChars('!','!'); tokenizer.wordChars('~','~'); tokenizer.wordChars('&','&'); try { state = 0; int type; while ( (type=tokenizer.nextToken()) != StreamTokenizer.TT_EOF) { switch (state) { case 0: parserState0(tokenizer,st_ob,st_op); break; case 1: parserState1(tokenizer,st_ob,st_op); break; case 2: parserState2(tokenizer,st_ob,st_op); break; case 3: break; default : break; } } parserState2(tokenizer,st_ob,st_op); root = (Node) st_ob.elementAt(0); } catch (IOException e) {System.err.println(e);} catch (EmptyStackException e2) {throw new ParserException();} } public double eval() { return eval(this.root); } /** ajoute une fonction à celles reconnues par le parser * * @@param f fonction à ajouter */ public void addFunc(Function f) { functions.put(f.keyword(), f); } /** * Ajoute une variable * @@param name - nom de la variable a ajouter */ public void addVar(String name) { vars.put(name,new Variable()); } /** * Fixe l'unite d'une variable * @@param name - nom de la variable * @@param unitStr - unite de la variable * @@return true if success, false otherwise */ public boolean setVarUnit(String name, String unitStr) { // a faire Variable x = (Variable)vars.get(name); if (x == null) throw new ParserException("method setVar : Unknown variable "+name+" !!!"); try { Unit u = new Unit(unitStr); u.setValue(x.getValue()); x.setUnit(u); } catch(java.text.ParseException e) {return false;} return true; } /** * Fixe la valeur d'une variable * @@param name - nom de la variable * @@param value - valeur de la variable */ public void setVar(String name, double value) { Variable x = (Variable)vars.get(name); if (x == null) throw new ParserException("method setVar : Unknown variable "+name+" !!!"); x.setValue(value); } /** Pour obtenir l'ensemble des variables * @@return l'ensemble des variables de ce parser */ public Enumeration getVariables() { return vars.keys(); } /** pour savoir si le parser a une valeur constante, cad si il n'y a pas de variable * @@return true si le parser a une valeur constante */ public boolean isConstant() { return (!getVariables().hasMoreElements()); } /** * Retourne la valeur d'une variable * @@param name - nom de la variable, the keyword of a variable. * @@return valeur de la variable name */ public double getVar(String name) { Variable x = (Variable) vars.get(name); if (x == null) throw new ParserException("methode getVar : La variable "+name+" est inconnue!!!"); return x.getValue(); } // Methodes privees /** Retourne l'objet Operator correspondant a l'entier op */ private static BasicOperator getOp(int op) { switch (op) { case ADD: return OP_ADD; case SUBTRACT: return OP_SUB; case MULTIPLY: return OP_MUL; case DIVIDE: return OP_DIV; case POWER: return OP_POW; case GRP: return OP_GRP; case ENDGRP: return OP_ENDGRP; } return null; } /** Evaluation d'un noeud */ private double eval(Node node) { double value = 0.; if (node == null) throw new ParserException("methode eval : noeud null !!!"); switch (node.type) { case Node.OP: value = evalOp(node); break; case Node.VALUE: value = node.value; break; case Node.VAR: value = evalVar(node); break; case Node.FUNCTION: value = evalFunc(node); break; default: throw new ParserException("methode eval : Ce noeud est de type inconnu !!!"); } return value; } private double evalOp(Node node) { double value = 0.0; switch (node.op) { case ADD: if(node.left != null) value = eval(node.left); value += eval(node.right); break; case SUBTRACT: if(node.right != null) value = eval(node.right); value = eval(node.left) - value; break; case DIVIDE: value = eval(node.left); value /= eval(node.right); break; case MULTIPLY: value = eval(node.left); value *= eval(node.right); break; case POWER: value = Math.pow(eval(node.left),eval(node.right)); break; default: throw new ParserException("methode evalOp : Operateur inconnu !!!"); } return value; } /** Evaluation de la valeur d'un noeud par une fonction */ private double evalFunc(Node node) { Function f = (Function)functions.get(node.svalue); if ( f==null ) throw new ParserException("method evalFunc : la fonction "+node.svalue+" est inconnue !!!"); return f.eval(eval(node.left)); } /** Evaluation d'une variable */ private double evalVar(Node node) { Variable v = (Variable)vars.get(node.svalue); if ( v==null ) throw new ParserException("methode evalVar : la variable "+node.svalue+" est inconnue !!!"); return v.getValue(); } //////// Methodes permettant l'evaluation de l'unite //////// /** Retourne l'évaluation de l'unité complète (valeur+symbole) * Attention : l'unité de chaque variable doit avoir été fixée avec setVarUnit * sans quoi le résultat de evalUnit sera inexact */ public Unit evalUnit() throws java.text.ParseException { return this.evalUnit(root); } private Unit evalUnit(Node node) throws java.text.ParseException { Unit unit = null; if (node == null) throw new ParserException("methode eval : noeud null !!!"); switch (node.type) { case Node.OP: unit = evalOpUnit(node); break; case Node.VALUE: try { unit= new Unit(new Double(node.value).toString()); } catch(java.text.ParseException e) {System.out.println("Error for a VALUE node");throw e;} break; case Node.VAR: unit = evalVarUnit(node); break; case Node.FUNCTION: unit = evalFuncUnit(node); break; default: throw new ParserException("methode eval : Ce noeud est de type inconnu !!!"); } return unit; } /** Evaluation de l'unité d'une fonction */ private Unit evalFuncUnit(Node node) throws ParseException{ Function f = (Function)functions.get(node.svalue); if ( f==null ) throw new ParserException("method evalFunc : la fonction "+node.svalue+" est inconnue !!!"); return f.evalUnit(evalUnit(node.left)); } /** Evaluation de l'unite d'une variable */ private Unit evalVarUnit(Node node) throws java.text.ParseException { Unit unit; Variable x = (Variable) vars.get(node.svalue); if (x == null) throw new ParserException("methode evalVar : la variable "+node.svalue+" est inconnue !!!"); unit = new Unit(x.getUnit()); return unit; } private Unit evalOpUnit(Node node) throws java.text.ParseException { // TO BE CONTINUED Unit unit = null; switch (node.op) { case ADD: if(node.left != null) unit = new Unit(evalUnit(node.left)); unit.plus(evalUnit(node.right)); break; case SUBTRACT: if(node.right != null) unit = new Unit(evalUnit(node.right)); Unit temp = evalUnit(node.left); temp.minus(unit); unit = temp; //unit.minus(evalUnit(node.left)); break; case DIVIDE: unit = new Unit(evalUnit(node.left)); unit.div(evalUnit(node.right)); break; case MULTIPLY: unit = new Unit(evalUnit(node.left)); unit.mult(evalUnit(node.right)); break; // pour ce cas, je ne sais pas bien comment faire (pour les unités) case POWER: if(node.right.type==Node.VALUE) { unit = new Unit("("+evalUnit(node.left).symbol+")"+eval(node.right)); unit.setValue(Math.pow(eval(node.left),eval(node.right))); } // ce cas la, je sais pas else if(node.left.type==Node.VALUE) { unit = new Unit(evalUnit(node.left)); } // celui-la encore moins --> a voir else { unit = new Unit(evalUnit(node.left)); } break; default: throw new ParserException("methode evalOp : Operateur inconnu !!!"); } return unit; } /////// Fin des methodes pour evaluation de l'unite //////// /** Retourne la precedence d'un operateur */ private static int precedence(int op) { switch (op) { case ADD: return 1; case SUBTRACT: return 2; case MULTIPLY: return 3; case DIVIDE: return 3; case POWER: return 5; } return -1; } /** Traitement lorsque state==0 */ private void parserState0(StreamTokenizer tokenizer, Stack ob, Stack op) throws IOException { switch (tokenizer.ttype) { // on tombe sur un mot : soit une variable, soit une fonction case StreamTokenizer.TT_WORD : Variable x = (Variable) vars.get(tokenizer.sval); if (x != null) { Node node = new Node(); node.type = Node.VAR; node.svalue = tokenizer.sval; ob.push(node); state = 2; } else { Function f = (Function)functions.get(tokenizer.sval); if( f!=null ) { op.push(f); state = 0; } // le mot n'a pas été reconnu : envoi d'une exception else throw new ParserException("Le mot "+tokenizer.sval+" est inconnu !"); } break; case StreamTokenizer.TT_NUMBER : Node node = new Node(); node.type = Node.VALUE; node.value = tokenizer.nval; ob.push(node); state = 2; break; case ADD : op.push(getOp(ADD)); node = new Node(); node.type = Node.VALUE; node.value = 0.; ob.push(node); state = 1; break; case SUBTRACT : op.push(getOp(SUBTRACT)); node = new Node(); node.type = Node.VALUE; node.value = 0.; ob.push(node); state = 1; break; case GRP : op.push(getOp(GRP)); state = 0; break; default: throw new ParserException("Le parsing a echoue !!"); } } /** Traitement lorsque state==1 */ private void parserState1(StreamTokenizer tokenizer, Stack ob, Stack op) throws IOException { switch (tokenizer.ttype) { // on tombe sur un mot : soit une variable, soit une fonction case StreamTokenizer.TT_WORD : Variable x = (Variable) vars.get(tokenizer.sval); if (x != null) { Node node = new Node(); node.type = Node.VAR; node.svalue = tokenizer.sval; ob.push(node); state = 2; } // VERIFIER LES POPS !! else { Function f = (Function)functions.get(tokenizer.sval); if( f!=null ) { op.push(f); state = 0; } // le mot n'a pas été reconnu : envoi d'une exception else throw new ParserException("Le mot "+tokenizer.sval+" est inconnu !"); } break; case StreamTokenizer.TT_NUMBER : Node node = new Node(); node.type = Node.VALUE; node.value = tokenizer.nval; ob.push(node); state = 2; break; case GRP : op.push(getOp(GRP)); state = 0; break; default: throw new ParserException("Le parsing a echoue !!"); } } /** Traitement lorsque state==2 */ private void parserState2(StreamTokenizer tokenizer, Stack ob, Stack op) throws IOException { BasicOperator op_read; switch (tokenizer.ttype) { case ADD: case SUBTRACT : case MULTIPLY: case DIVIDE: case POWER: op_read = getOp(tokenizer.ttype); if (!op.empty()) { Operator tmpi = (Operator)op.peek(); while ( tmpi.precedence() >= op_read.precedence() ) { if ( tmpi.type==Operator.BASIC ) { BasicOperator tmp = (BasicOperator)op.pop(); Node deux = (Node)ob.pop(); Node un = (Node)ob.pop(); Node node = new Node(); node.type = Node.OP; node.op = tmp.op; node.left = un; node.right = deux; ob.push(node); } else if( tmpi.type==Operator.FUNC ) { Function tmp = (Function)op.pop(); Node un = (Node)ob.pop(); Node node = new Node(); node.type = Node.FUNCTION; node.svalue = tmp.keyword(); node.left = un; node.right = null; ob.push(node); } if (!op.empty()) tmpi = (Operator)op.peek(); else break ; } } op.push(op_read); state = 1; break; case ENDGRP : { op_read = getOp(tokenizer.ttype); if (!op.empty()) { Operator tmp = (Operator)op.pop(); while ( !tmp.keyword().equals("(") ) { if ( tmp.type==Operator.BASIC ) { BasicOperator tmpi = (BasicOperator)tmp; Node deux = (Node)ob.pop(); Node un = (Node)ob.pop(); Node node = new Node(); node.type=Node.OP; node.op = tmpi.op; node.left = un; node.right = deux; ob.push(node); } else if( tmp.type==Operator.FUNC ) { Function tmpi = (Function)tmp; Node un = (Node)ob.pop(); Node node = new Node(); node.type = Node.FUNCTION; node.svalue = tmpi.keyword(); node.left = un; node.right = null; ob.push(node); } if (!op.empty()) tmp = (Operator)op.pop(); else break ; } } state = 2; break; } case StreamTokenizer.TT_EOF : while ( !op.empty() ) { Operator tmp = (Operator)op.pop(); if ( tmp.type==Operator.BASIC ) { BasicOperator tmpi = (BasicOperator)tmp; Node deux = (Node)ob.pop(); Node un = (Node)ob.pop(); Node node = new Node(); node.type = Node.OP; node.op = tmpi.op; node.left = un; node.right = deux; ob.push(node); } else if( tmp.type==Operator.FUNC ) { Function tmpi = (Function)tmp; Node un = (Node)ob.pop(); Node node = new Node(); node.type = Node.FUNCTION; node.svalue = tmpi.keyword(); node.left = un; node.right = null; ob.push(node); } } state = 0; break; default: throw new ParserException("Le parsing a echoue !!"); } } // pour tester /* public static void main(String[] arg) { Parser parser = new Parser("sin(2*x)+y"); parser.addVar("x"); parser.addVar("y"); parser.parseString(); parser.setVar("x",4.125); parser.setVar("y",3); System.out.println(parser.eval()); parser.setVarUnit("x","arcmin"); parser.setVarUnit("y","arcsec"); try{ //System.out.println(parser.evalUnit()); System.out.println("TOTO" +parser.evalUnit().symbol); Unit u = new Unit("2.ms"); System.out.println(u.symbol); } catch(Exception e) {e.printStackTrace();} }*/ } eturn ucds/tools/parser/ParserException.java010064400076440000132000000005110770227416100207270ustar00ferniquecds00000400000013package cds.tools.parser; /** classe ParserException * Cette expression est envoyee lorsque le parsing n'a pu se faire correctement */ public class ParserException extends RuntimeException { public ParserException() { super(); } public ParserException(String msg) { super(msg); } } cds/tools/parser/Rad2Deg.java010064400076440000132000000005540770227416100170330ustar00ferniquecds00000400000013package cds.tools.parser; /** * Fonction rad2deg (conversion de degrés en radians) */ public class Rad2Deg extends Function { /* * @@see cds.tools.parser.Function#eval(double) */ double eval(double x) { return 180.0*x/Math.PI; } /* * @@see cds.tools.parser.Operator#keyword() */ String keyword() { return "rad2deg"; } }cds/tools/parser/Sin.java010064400076440000132000000004760770227416100163570ustar00ferniquecds00000400000013package cds.tools.parser; /** * Fonction sinus */ public class Sin extends Function { /* * @@see cds.tools.parser.Function#eval(double) */ double eval(double x) { return Math.sin(x); } /* * @@see cds.tools.parser.Operator#keyword() */ String keyword() { return "sin"; } } cds/tools/parser/Tan.java010064400076440000132000000005010770227416100163350ustar00ferniquecds00000400000013package cds.tools.parser; /** * Fonction tangente */ public class Tan extends Function { /* * @@see cds.tools.parser.Function#eval(double) */ double eval(double x) { return Math.tan(x); } /* * @@see cds.tools.parser.Operator#keyword() */ String keyword() { return "tan"; } } cds/tools/parser/Variable.java010064400076440000132000000010430770227416100173420ustar00ferniquecds00000400000013package cds.tools.parser; import cds.astro.Unit; /** classe Variable */ public class Variable { private double value; private Unit unit; Variable() { value = 0.0; unit = new Unit(); } /** Retourne la valeur de la variable */ public double getValue() { return value; } /** Fixe la valeur de la variable */ public void setValue(double x) { value = x; } public void setUnit(Unit u) { this.unit = u; } public Unit getUnit() { return unit; } } cds/vizier/VizieRCatalogs.java010064400076440000132000000225110770227416100173620ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // VizieR JAVA // // Author: Andre Schaaff // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: schaaff@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. package cds.vizier; import java.awt.*; import java.util.Vector; import cds.tools.*; import java.awt.event.*; import cds.aladin.*; /** * VizieRCatalogs * * @@author Andre Schaaff [CDS] * @@version 1.1 : (september 2002) VizieRCatalogs * @@version 1.0 beta : (june 2002) renamed as VizieRCatalogs * @@version 0.9 : (february 2002) creation */ public class VizieRCatalogs extends Frame implements CDSConstants, WindowListener { // a reference to a VizieRList object protected VizieRList vizierlist = null; // the frame title protected CDSLabel title = null; // a control button protected Button controlButton = null; /** Constructor VizieRCatalogs * * @@param cat a field in which the catalog selections are set (like the catalog field from Aladin) * @@param getReadMe the Get info. button from Aladin * @@param catalogs a vector of catalogs * @@param controlButton a control button (like SUBMIT) */ public VizieRCatalogs(TextField cat, final Button getReadMe, final Vector catalogs, Button controlButton) { // main panel Panel panelMain = new Panel(); panelMain.setBackground(BKGD); panelMain.setFont(BOLD); BorderLayout mainLayout = new BorderLayout(0, 0); panelMain.setLayout( mainLayout ); title = new CDSLabel("Catalogs", Label.LEFT, PLAIN); panelMain.add(title, "North"); // creates a list of catalogs and add it to the main panel vizierlist = new VizieRList(cat, getReadMe, catalogs); /* System.out.println(" On passe par là "); Vector text = new Vector(); Vector ligne = new Vector(); ligne.addElement("a"); ligne.addElement("b"); ligne.addElement("c"); ligne.addElement("d"); text.addElement(ligne); ligne = new Vector(); ligne.addElement("r"); ligne.addElement("s"); ligne.addElement("t"); ligne.addElement("u"); text.addElement(ligne); Mesure mesure = new Mesure(text); FrameMesure fm = new FrameMesure(mesure); */ panelMain.add(vizierlist, "Center"); // left button(s) panel Panel panelButtonLeft = new Panel(); panelButtonLeft.setBackground(BKGD); panelButtonLeft.setFont(BOLD); if (getReadMe != null) panelButtonLeft.add(getReadMe); // right buttons panel Panel panelButtonRight = new Panel(); panelButtonRight.setBackground(BKGD); panelButtonRight.setFont(BOLD); // if control button exists then it is added to the right panel if (controlButton != null) { this.controlButton = controlButton; panelButtonRight.add(controlButton); } Button reset = new Button("Reset"); Button close = new Button("Close"); panelButtonRight.add(reset); panelButtonRight.add(close); // bottom panel Panel panelBottom = new Panel(); panelBottom.setBackground(BKGD); panelBottom.setFont(BOLD); BorderLayout buttonlayout = new BorderLayout(5, 5); panelBottom.setLayout( buttonlayout ); panelBottom.add(panelButtonLeft, "West"); panelBottom.add(panelButtonRight, "East"); panelMain.add(panelBottom, "South"); // Reset button listener reset.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { if (vizierlist != null) { for (int i = 0; i < vizierlist.getItemCount(); i++) vizierlist.deselect(i); if (vizierlist.getCatalogField() != null) vizierlist.getCatalogField().setText(""); } if (getReadMe != null) getReadMe.setEnabled(false); } } ); // Close button listener close.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { if (getReadMe != null) getReadMe.setEnabled(false); hide(); } } ); // listener addWindowListener(this); // add main panel to frame content panel, pack and show add(panelMain); pack(); move(300,300); this.setSize((vizierlist.getHCaracterCount() * 6), this.getSize().height); show(); } /** Constructor VizieRCatalogs * * @@param catalogs a vector of catalogs * @@param controlButton a control button (like SUBMIT) */ public VizieRCatalogs(final Vector catalogs, Button controlButton) { this(null, null, catalogs, controlButton); } /** Constructor VizieRCatalogs * * @@param catalogs a vector of catalogs */ public VizieRCatalogs(final Vector catalogs) { this(null, null, catalogs, null); } /** Show a preselection in vizier list * * @@param v the contain of the vector is used to preselect elements in the VizieR catalog list */ public void show(Vector v) { if (vizierlist != null) vizierlist.preSelection(v); show(); } /** Reset catalog list * */ public void resetCatList() { if (vizierlist != null) vizierlist.resetList(); } /** Set a title * * @@param title used to set the title of the frame */ public void setLabel(String title) { this.title.setText(title); } /** Get Title * * @@return CDSLabel the title of the frame */ public CDSLabel getLabel() { return title; } /** Get Vizer List * * @@return VizieRList return a reference to the VizieR catalog list */ public VizieRList getVizerList() { return vizierlist; } /** Set Vizier List * * @@param vizierlist used to set the VizieR catalog list */ public void setVizerList(VizieRList vizierlist) { this.vizierlist = vizierlist; } /** Get Control Button * * @@return controlButton used to get a reference to the control button */ public Button getControlButton() { return controlButton; } /** Set Control Button * * @@param controlButton used to set a control button */ public void setControlButton(Button controlButton) { this.controlButton = controlButton; } /** Windows closing * * @@param e window event */ public void windowClosing(WindowEvent e){ hide(); } /** Window Closed * * @@param e WindowEvent */ public void windowClosed(WindowEvent e){ hide(); } // other methods not implemented public void componentShown(ComponentEvent e) {} public void actionPerformed(ActionEvent e) {} public void windowOpened(WindowEvent e){} public void windowDeactivated(WindowEvent e){} public void windowActivated(WindowEvent e){} public void windowDeiconified(WindowEvent e){} public void windowIconified(WindowEvent e){} }(); ligne.addElement("a"); ligne.addElement("b"); ligne.addElement("c"); ligne.addElement("d"); text.addElement(ligne); ligne = new Vector(); cds/vizier/VizieRList.java010064400076440000132000000172710770227416100165470ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // VizieR JAVA // // Author: Pierre Fernique // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: fernique@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.vizier; import java.awt.*; import java.util.Vector; import java.util.StringTokenizer; import java.util.Enumeration; /** * VizieR catalog list *

* Two important things : a text field and a button can be added from outside *

* Example of button use : show additional informations for a selected catalog *

* Text field use is fixed : selected catalog names are added to this field with a comma as separator *

* Multiple selection are allowed. * @@author Pierre Fernique [CDS] * @@version 1.1 : (august 2002) votable ready * @@version 1.0 : (february 2002) transfer to VizieR package [Andre Schaaff] and add of methods * @@version Aladin 1.0 (in Aladin package): (11 mai 99) Toilettage du code * @@version Aladin 0.9 (in Aladin package): (??) creation */ public final class VizieRList extends java.awt.List { protected TextField catalog; // Catalog name field protected Button getReadMe; // Button used to get (for example) informations about a selected catalog protected int hCaracterCount = 0; static final boolean LSCREEN= Toolkit.getDefaultToolkit().getScreenSize().width>1000; /** Taille moyenne des fonts */ static protected final int SIZE = LSCREEN?12:10; protected static Font COURIER= new Font("Monospaced",Font.PLAIN, SIZE); /** Constructor List creation * Set the selected catalogs * @@param catalog text field (can be optional) * @@param getReadMe button (can be optional) * @@param v vector of lines to put into the list */ public VizieRList(TextField catalog, Button getReadMe, Vector v) { this(catalog, getReadMe, v, 20); } /** Constructor List creation * * @@param catalog text field (can be optional) * @@param getReadMe button (can be optional) * @@param v vector of lines to put into the list * @@param rows number of rows to show at one time */ public VizieRList(TextField catalog, Button getReadMe, Vector v, int rows) { super(rows,true); this.catalog = catalog; this.getReadMe = getReadMe; this.setFont( COURIER ); preSelection(v); } /** Constructor List creation * * @@param v vector of lines to put into the list */ public VizieRList(Vector v) { this(null, null, v, 20); } /** Set the default list * Set the selected catalogs * @@param v vector of lines show in the preselection */ public void preSelection(Vector v) { hCaracterCount = 0; if( countItems()>0 ) clear(); Enumeration e = v.elements(); while( e.hasMoreElements() ) { String s = (String)e.nextElement(); addItem(s); int length = s.length(); if (hCaracterCount < length) hCaracterCount = length; } } /** Reset the list * */ public void resetList() { for( int i=0; i * Two important things : a text field and a button can be added from outside *

* Example of button usecds/vizier/VizieRPanel.java010064400076440000132000000441320770227416100166670ustar00ferniquecds00000400000013// // Copyright 1999-2002 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // VizieR JAVA // // Authors: Pierre Fernique - Andr‰ Schaaff // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: schaaff@@astro.u-strasbg.fr, question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.vizier; import java.awt.*; import java.io.DataInputStream; import java.util.Vector; import java.util.Enumeration; import cds.tools.*; import cds.aladin.*; /** * VizieR panel *

* This panel has multiple usage : as an integrated panel in Aladin application but also in * other application as an external api *

* * @@authors Pierre Fernique - Andre Schaaff [CDS] * @@version 0.9 : (fevrier 2002) creation */ public class VizieRPanel extends Panel implements CDSConstants { // Object components protected CDSLabel titre = null; // Title protected TextField tauthor = new TextField(15); // Free text protected TextField ttarget = new TextField(15); // Target field protected TextField tradius = new TextField(15); // Radius field protected Choice unit = new Choice(); // Unit choice protected Choice coordinate = null; // Coordinate choice // Astrores complient stream, result of the query protected DataInputStream vizierStream = null; // Output as stream or in a frame protected int outputMode = FRAME; // List of lists of constraints protected java.awt.List lk[]; // n keywords lists protected java.awt.List resultat = new java.awt.List(); // List filled with the query result // target and radius strings protected String target = null; protected String radius = null; // VizieR meta data protected int nSection; // GLU // protected Jglu glu = null; // GLU interactions, must be replaced with JGlu as soon as possible // Text for buttons, titles, ... static final String SUBMIT = "SUBMIT"; static final String DEFAULT_TITRE = "... don't know which catalog ? Select the \n" + "potentially interesting ones with words/keywords !"; static final String TITRE = "Copyright CDS, a changer"; static final int DEFAULTROWS = 6; VizieRQuery vq = null; protected BorderLayout borderLayout1 = new BorderLayout(); /** Form title modification depending on the presence of a target * * @@param target the string containing the target, ou null if nothing */ protected void setTitre(String target){ String s = null; s=(target==null)?DEFAULT_TITRE: "Click directly on the SUBMIT button to retrieve all VizieR catalogs around " + target + "\n" + " or include constraints below to reduce the number of matching catalogs."; if (s!= null) titre.setText(s); else titre.setText("probleme"); } /** Constructor * * @@param glu * @@param outputMode * @@param withparam * @@param target * @@param radius * @@param rows */ public VizieRPanel(Glu glu, int outputMode, boolean withparam, String target, String radius, int rows) { try { this.outputMode = outputMode; // vq = new VizieRQuery(); vq.setGLU(glu); // VizieR call for meta information if( vq.metaDataQuery() == false || vq.getNameKey().size() == 0 ) { System.err.println("VizieR meta query error "+(vq.getMetaError()==null?"":vq.getMetaError())); } nSection = vq.getNameKey().size(); this.setLayout(borderLayout1); makeForm(withparam, target, radius, rows); } catch(Exception ex) { ex.printStackTrace(); } } /** Cursor corresponding to the java machine * used to resolve security checking * * @@param c component * @@param type */ protected static void makeCursor(Component c, int type) { while( c!=null && !(c instanceof Frame) ) c=(Component)c.getParent(); if( c==null ) return; ((Frame)c).setCursor(type==WAIT?Frame.WAIT_CURSOR: type==HAND?Frame.HAND_CURSOR: type==CROSSHAIR?Frame.CROSSHAIR_CURSOR: type==MOVE?Frame.MOVE_CURSOR: type==RESIZE?Frame.N_RESIZE_CURSOR: type==TEXT?Frame.TEXT_CURSOR: Cursor.DEFAULT_CURSOR ); } /** Cursor management * */ private int oc = DEFAULT; private void waitCursor() { makeCursor(WAIT); } private void defaultCursor() { makeCursor(DEFAULT); } private void makeCursor(int c) { if( oc==c ) return; makeCursor(this,c); if( resultat!=null ) makeCursor(resultat,c); makeCursor(tauthor,c); for( int i=0; i * This class has been created to separate graphic interface and query features *

* * @@authors Andre Schaaff [CDS] * @@version 1.0 beta : (june 2002) creation */ public class VizieRQuery implements XMLConsumer, CDSConstants { static final int KEYWORDS = 0; static final int SURVEYS = 1; static final int ARCHIVES = 2; static final int CATALOGS = 3; static final int TD = 4; static final int SURVEYMAXCOL = 3; static final int ARCHIVEMAXCOL = 3; private int section; // current section, -1 if unknown private String currentCat=null; //Id du catalogue courant pour le parsing des catalogues private String currentWaveLength=null; //Longueur d'onde du catalogue courant pour le parsing des catalogues private String currentDensity=null; //Densite du catalogue courant pour le parsing des catalogues private String metaError; // XML parser meta information error private Vector vKey; // Current keywords section value private boolean inCSV; // true if in ths section .. private boolean inDesc; // true if in a 5) str = str + currentWaveLength.substring(0, 5); else str = str + currentWaveLength; for (int j = k; j < 5; j++) str = str + " "; currentWaveLength = null; } else str = str + " "; if ( currentDensity != null ) { k = currentDensity.length(); for (int j = 3; j >= k; j--) currentDensity = " " + currentDensity; str = str + currentDensity; currentDensity = null; } else str = str + " "; if ( currentCat != null ) { addItem(str + " " + new String(ch, start, length)); inDesc=false; } } return; } // Traitement de la section data dans le cas des surveys // ou des archives if( inCSV ) { //System.out.println("ch=["+new String(ch,start,length)+"]"); // Separators and headlines ? if( recsep!=null ) rs=recsep.charAt(0); if( colsep!=null ) cs=colsep.charAt(0); h = (headlines==null)?0:Integer.parseInt(headlines); // Heading treatement n=0; // current line number for ( n=0; cur 0); } else { return res == true; } } // public void query() { } } ing)atts.get("headlines"); recsep=(String)atts.get("recsep"); colsep=(String)atts.get("colsep"); cds/astro/Proj3.java010064400076440000132000000371500770227416100153160ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.astro ; /** * Class defining the Mathematical Projections of the Celestial Sphere. * This class contains only the mathematical projections --- * WCS and Aladin projections are in a derived class. *

The available projections are defined by the formulae, where *

 *          l,b   = longitude and latitude
 *          theta = angle to center of projection 
 *          x,y   = projections (cartesian) along x (East) and y (North)
 *          r,phi = projections (polar)
 * TAN      / Standard = Gnomonic     
 *            r = tan(theta)          phi
 * TAN2     / Stereographic           
 *            r = 2.tan(theta/2)      phi
 * SIN      / Orthographic  
 *            r = sin(theta)          phi
 * SIN2     / Equal-area    
 *            r = 2.sin(theta/2)      phi
 * ARC      / Schmidt proj. 
 *            r = theta               phi
 * AITOFF   / Aitoff (equal area)     if D = sqrt(0.5*(1+cos(b)cos(l/2)))
 *            x = 2cos(b)sin(l/2)/D   y = sin(b)/D
 * SANSON   / Global Sinusoidal (equal area)
 *            x = l cos(b)            y = b
 * MERCATOR / with poles at infinity
 *            x = l                   y = atanh(b)
 * LAMBERT  / equal area projection
 *            x = l                   y = sin(b)
 * 
*

The typical usage of the Proj3 class consists in:

    *
  1. Define a projection (type and the center of projection) by means of * one of the constructors; the default center is the (0,0) point. *
  2. Compute the projection values X,Y from a position with * the computeXY method; the projections can be retrieved * either via the getX and getY methods, * or in aProj3.X and aProj3.Y elements. *
  3. The reverse computation (from projections to coordinates) * is done with the computeAngles method; the angles are * obtained by means of the getLon and getLat methods. *
* * @@author Pierre Fernique, Francois Ochsenbein [CDS] * @@version 1.0 : 03-Mar-2000 * @@version 1.1 : 24-Mar-2000: better documentation */ public class Proj3 { protected byte type ; // Projection type private double R[][] ; // Rotation Matrix private double clon, clat; // Center of the Projection (degrees) /** The values of the projections */ protected double X,Y ; // One point in the projection (cartesian) /** The corresponding polar angles */ protected Coo point ; // One point in the projection (original angles) // Constants public static final int NONE = 0; public static final int TAN = 1; // Standard Gnomonic (r = tan(theta)) public static final int TAN2 = 2; // Stereographic (r = 2.tan(theta/2)) public static final int SIN = 3; // Orthographic (r = sin(theta)) public static final int SIN2 = 4; // Equal-area (r = 2.sin(theta/2)) public static final int ARC = 5; // Schmidt proj. (r = theta) public static final int AITOFF = 6; // Aitoff Projection public static final int SANSON = 7; // Global Sinusoidal public static final int MERCATOR = 8; // public static final int LAMBERT = 9; // public static final String [] name = { "-", "Gnomonic (TAN)", "Stereographic (TAN2)", "Orthographic (SIN)", "Zenithal Equal-area (SIN2)", "Schmidt (ARC)", "Aitoff", "Sanson", "Mercator", "Lambert" }; // =========================================================== // Constructors // =========================================================== /** Creation of object used for Projections. * At creation, the center and the type of projection is specified * @@param type projection type -- default (standard) = TAN * @@param lon,lat Center of projection (coordinates of the tangent point) * expressed in degrees. */ public Proj3(int type, double lon, double lat) { this.type = (byte)type ; this.clon = lon ; this.clat = lat ; this.point = new Coo (lon, lat) ; if ((lon != 0) || (lat != 0)) // Keep null for unit matrix R = Coo.localMatrix(clon,clat); } /** Creation of object used for Projections from a String. * @@param type projection type * @@param text the center in a string * @@param equatorial boolean "true" when text represents an equatorial position */ public Proj3(int type, String text, boolean equatorial) throws Exception { this.point = new Coo(text, equatorial) ; this.type = (byte)type ; this.clon = this.point.lon ; this.clat = this.point.lat ; if ((clon != 0) || (clat != 0)) // Keep null for unit matrix R = Coo.localMatrix(clon,clat); } /** Projection at the Origin. * Projection at tangent point (lon=0, lat=0) * @@param type projection type */ public Proj3(int type) { this(type, 0., 0.) ; // Default = Standard Projection } /** Standard projection. * At creation, the center and the type of projection is specified * @@param lon,lat Center of projection (coordinates of the tangent point) */ public Proj3(double lon, double lat) { this(TAN, lon, lat) ; // Default = Standard Projection } // =========================================================== // Static Methods // =========================================================== /* Static methods (functions) in Java are very close to C ones; they do not require any object instanciation. Typical example of static methods are in the Math class */ // =========================================================== // Class Methods // =========================================================== /** Get only the X from the object * @@return X the X projection */ public final double getX() { return(X) ; } /** Get only the Y from the object * @@return Y the Y projection */ public final double getY() { return(Y) ; } /** Get only the longitude from the object * @@return lon the longitude in degrees of the point (point.lon) */ public final double getLon() { return(point.lon) ; } /** Get only the Y from the object * @@return lat the latitude in degrees of the point (point.lat) */ public final double getLat() { return(point.lat) ; } public String toString() { return(name[type] + " projection centered at " + clon + " " + clat + ": " + X + " " + Y) ; } // =========================================================== // Projections from Angles // =========================================================== /** Compute a projection from initial coordinates. *
* Rem : the rotation matrix was computed at Constructor * * @@param lon,lat position * @@return status true if the projection is possible * and false when the position can't be projected. * The values of the projections are in object.X and object.Y */ public boolean computeXY (double lon, double lat) { double x,y,z, r, w ; /* Was this position already computed ?? */ if ((lon == point.lon) && (lat == point.lat)) return(!Double.isNaN(X)) ; /* Set angles + unit vector, but X and Y are not yet computed */ point.set(lon, lat) ; X = 0./0.; Y = 0./0.; if (R == null) { x = point.x; y = point.y; z = point.z ; } else { x = R[0][0]*point.x + R[0][1]*point.y + R[0][2]*point.z ; y = R[1][0]*point.x + R[1][1]*point.y + R[1][2]*point.z ; z = R[2][0]*point.x + R[2][1]*point.y + R[2][2]*point.z ; } switch(type) { case TAN : // Only 1 hemisphere valid if (x <= 0) return false ; X = y/x; Y = z/x; break ; case TAN2 : // All positions valid, just opposite pole w = (1.0 + x)/2.0; if (w <= 0) { X = 0./0.; Y = 0./0.; return false; } X = y/w; Y = z/w; break ; case SIN : // Only 1 hemisphere valid, r <= 1 if (x <= 0) return false ; X = y; Y = z ; break ; case SIN2 : // Whole sphere, r <= 2 (equal area) w = Math.sqrt((1.0 + x)/2.0); if (w > 0) { X = y/w; Y = z/w; } else { X = 2; Y = 0; } break ; case ARC : // r <= pi if (x > -1.0) { // Angular distance = acos(x) r = Math.sqrt(y*y + z*z) ; if (x > 0) w = Coo.asinc(r); else w = Math.acos(x)/r ; X = y*w; Y = z*w; } else { X = Math.PI ; Y = 0 ; } break ; case AITOFF : // Ellipse, r = Math.sqrt(x*x + y*y) ; w = Math.sqrt (r*(r+x)/2.0); // cos lat . cos lon/2 w = Math.sqrt ((1.0 + w)/2.0); X = Math.sqrt(2.*r*(r-x)) / w ; Y = z / w ; if (y<0) X = -X ; break ; case SANSON : // Sinusoidal |X| <= pi, Y <= pi/2 r = Math.sqrt(x*x + y*y) ; Y = Math.asin(z); if (r == 0) X = 0 ; else X = Math.atan2(y,x) * r; break ; case MERCATOR : r = Math.sqrt(x*x + y*y) ; if (r == 0) return false ; X = Math.atan2(y,x); Y = Coo.atanh(z); break ; case LAMBERT : // Equal Area (lon,sin(lat)) r = Math.sqrt(x*x + y*y) ; Y = z ; if (r == 0) X = 0 ; else X = Math.atan2(y,x); break ; default: throw new IllegalArgumentException( "****Proj3: Invalid Projection type #" + type) ; } return(true) ; } // =========================================================== // Projected values to Coordinates // =========================================================== /** Reverse projection: compute the polar angle corresponding to (x,y) *
* Rem : the rotation matrix was computed at Constructor * a la creation de l'objet * * @@param type Projection type * @@param x,y projection values * @@return status true if the X / Y values are within the projection area * and false otherwise, * The values of the angles are obtained via getLon() and getLat() */ public boolean computeAngles (double px, double py) { double x,y,z, x0,y0,z0, r, w ; boolean angles_set = false ; /* Was this position already computed ?? */ if ((px == this.X) && (py == this.Y)) return(!Double.isNaN(point.lon)) ; /* Set the projection values, bug angles not yet computed */ X = px; Y = py; point.lon = 0./0.; point.lat = 0./0. ; switch(type) { case TAN : // Only 1 hemisphere valid x = 1.0 / Math.sqrt(1.0 + X*X + Y*Y); y = X * x; z = Y * x; break ; case TAN2 : // All positions valid, just opposite pole r = (X*X + Y*Y)/4.0 ; w = 1.0 + r ; x = (1.0 - r)/w ; y = X/w ; z = Y/w ; break ; case SIN : // Only 1 hemisphere valid, r <= 1 w = 1.0 - X*X - Y*Y; if (w < 0) { // Accept some rounding error if (w > -2.e-16) w = 0 ; else return false ; } x = Math.sqrt(w) ; y = X; z = Y; break; case SIN2 : // Whole sphere, r <= 2 (equal area) r = (X*X + Y*Y)/4.0 ; if (r > 1.) return false ; w = Math.sqrt(1.0 - r) ; x = 1.0 - 2.0 * r; y = w * X; z = w * Y; break ; case ARC : // r <= pi r = Math.sqrt(X*X + Y*Y) ; if (r > Math.PI) return false ; w = Coo.sinc(r); x = Math.cos(r); y = w * X; z = w * Y; break ; case AITOFF : // Ellipse, dimensions sqrt(2) x 2.sqrt(2) r = X*X/8.0 + Y*Y/2.0; // 1 - cos b . cos l/2 if (r > 1.0) return false ; x = 1. - r ; // cos b . cos l/2 w = Math.sqrt(1. - r/2.) ; // sqrt(( 1 + cos b . cos l/2)/2) y = X * w / 2. ; z = Y * w ; // Convert from Cartesian (l/2,b) to Cartesian (l,b) r = Math.sqrt(x*x + y*y) ; // cos(b) if (r > 0) { w = x; x = (w*w - y*y) /r; y = 2.0 * w * y /r; } break ; case SANSON : // Sinusoidal |X| <= pi, Y <= pi/2 z = Math.sin(Y); r = 1 - z*z; // cos^2(b) if (r < 0) return false ; r = Math.sqrt(r); // cosb if (r == 0) w = 0. ; else w = X/r; // Longitude x = r * Math.cos(w); y = r * Math.sin(w); break ; case MERCATOR : r = 1./Coo.cosh(Y); z = Coo.tanh(Y) ; x = r * Math.cos(X); y = r * Math.sin(X); break ; case LAMBERT : // Equal Area (lon,sin(lat)) z = Y; r = 1 - z*z; // cos(b) ** 2 if (r < 0) return false ; r = Math.sqrt(r); // cosb x = r * Math.cos(X); y = r * Math.sin(X); break ; default: throw new IllegalArgumentException( "****Proj3: Invalid Projection type #" + type) ; } /* From Cartesian: just rotate (used transposed matrix) */ if (R != null) point.set( R[0][0]*x + R[1][0]*y + R[2][0]*z , R[0][1]*x + R[1][1]*y + R[2][1]*z , R[0][2]*x + R[1][2]*y + R[2][2]*z ) ; else point.set(x, y, z) ; return true ; } } cds/astro/ParsingText.java010064400076440000132000000147750770227416100166010ustar00ferniquecds00000400000013package cds.astro; /** *========================================================================== * @@author: François Ochsenbein -- francois@@astro.u-strasbg.fr * @@version: 0.7 07-sep-2002 * @@version: 0.9 15-sep-2002: *========================================================================== */ import java.util.*; import java.text.*; // for parseException /*================================================================== ParsingText class *==================================================================*/ /** * This internal class for parsing text. It just saves the text as an array, * keeping the current position in the text. */ class ParsingText { public char[] a ; // The text as an array of chars public int len ; // Length of text public int pos ; // Current position in text /* CHANGE the Current text position */ public final void set(int n) { pos = n ; if (pos > len) pos = len; if (pos < 0) pos = 0 ; } public final void advance(int n) { this.set(pos+n) ; } /* CONSTRUCTOR */ public ParsingText(String s) { len = s.length(); a = s.toCharArray(); pos = 0; } /* EDITOR */ public final String toString() { return(new String(a, 0, len)) ; } /** Try to match the current text to a Symbol from a List * @@param tSymbol: table of Symbols * @@param len: exact length of text to match * @@return the index in table of Symbols (-1 if not found) **/ public final int lookup (String[] tSymbol, int len) { int i, j; for (i=0; i= len) { // Symbol found -- set what's parsed pos += len; return(i) ; } } return(-1) ; // Not Found } /** Try to match the current text to a Symbol from a List of Symbols * @@param tSymbol: a table of Symbols * @@return the index in table of Symbols (-1 if not found) **/ public final int lookup (String[] tSymbol) { int i, j; int maxlen = len - pos; int symlen = 0; for (i=0; i maxlen) continue; for (j=0; j= len) return(val) ; if (a[i] == '+') pos = ++i; else if (a[i] == '-') i++; while ((ipos) val = Integer.parseInt(new String(a, pos, i-pos)); pos = i ; return(val); } /** Interpret a real number as (+/-)numx10+pow * @@return the double which could be interpreted -- 1 by default. * @@remark No change in the `position' when no number could be matched; * @@remark The number can start by a '+' **/ public final double parseFactor() { // Interpret a Floating-Point double val = 1; double radix = 0.; // Radix of Exponent, normally 10 int posini = pos; int i; boolean hasexpo = false; int e = 0; // Exponent char c = Character.MIN_VALUE; // Terminator for Exponent if (pos >= len) return(val) ; c = a[pos]; if ((c == '+') || (c == '-')) pos++; for (i=pos; (i= (len-1)) return(val); // Look for an Exponent part posini = pos; c = Character.MIN_VALUE; // Terminator in 10^8^ hasexpo = true; if ((a[i] == 'e') || (a[i] == 'E')) i++; else { // Can be x10^8 or just ^8 if (((a[i] == 'x') || (a[i] == '×')) && (i<=(len-4))) { ++i ; if ((a[i] == '1') && (a[i+1] == '0')) i += 2; radix = 10; } if (a[i] == '^') { c = '^'; i++; } else if ((a[i] == '+') || (a[i] == '-') || Character.isDigit(a[i])); else hasexpo = false; } // Interpret the Exponent part if (hasexpo) { pos = i; e = parseInt(); hasexpo = pos != i; } if (!hasexpo) pos = posini; else { if (radix == 0) { // Just 10^8 radix = Math.abs(val); // Normally 10 val /= radix; // Gives ±1 } // Accept 10^8^ (2 carrets) -- c contains the ^ if ((pos0) { val *= radix; e--; } while (e<0) { val /= radix; e++; } } } return(val) ; } /** Interpret a sexagesimal number * @@return as a double what can be interpreted -- 1 by default. * @@remark No change in the `position' when no number could be matched; * @@remark The number can start by a '+' **/ public final double parseSexa() { // Interpret in Sexagesimal double val = 0; double f = 1.; boolean minus = false ; int posini; double x; int hms; /* Default (undefined) is 1. */ if (pos >= len) return(1.) ; if (a[pos] == '-') { minus = true; ++pos; } else if (a[pos] == '+') ++pos; while ((pos < len) && Character.isWhitespace(a[pos])) pos++; /* Get Hours or Degrees */ posini = pos; hms = parseInt(); if (posini == pos) return(0./0.) ; // Just a sign ==> NaN val = hms; // hours while (pos < len) { if (a[pos] == ' ') { pos++; continue; } if (a[pos] == ':') { pos++; continue; } if (!Character.isDigit(a[pos])) break; hms = parseInt(); f /= 60.; val += f*hms; } if ((pos < len) && (a[pos] == '.')) { // Get Fraction pos++; // Gobble the decimal point if ((pos < len) && Character.isDigit(a[pos])) { --pos; // Restore the decimal point val += f*parseFactor(); } } if (minus) val = -val; return(val); } } cds/astro/Udef.java010064400076440000132000000022330770227416100151760ustar00ferniquecds00000400000013package cds.astro; /** *========================================================================== * @@author: François Ochsenbein -- francois@@astro.u-strasbg.fr * @@version: 0.7 07-sep-2002 * @@version: 0.9 15-sep-2002: *========================================================================== */ import java.util.*; import java.text.*; // for parseException /*================================================================== Unit Definitions *==================================================================*/ /** * This internal class defines just the basic unit symbols. * Used in Unit class to store the definition of each unit */ class Udef { public String symb; // Symbol, un principle letters only public String expl; // Text used in 'explain' method public long mksa; // The interpretation in terms of units public double fact; // How to convert to SI /* CONSTRUCTOR */ public Udef(String s, String text, long m, double f) { symb = s; expl = text ; mksa = m; fact = f; } /* EDITOR */ public final String toString() { return(symb + ": " + expl); } } cds/astro/Unit.java010064400076440000132000001546530770227416100152500ustar00ferniquecds00000400000013package cds.astro; /** *========================================================================== * @@author: François Ochsenbein -- francois@@astro.u-strasbg.fr * @@version: 0.7 07-sep-2002 * @@version: 0.9 15-sep-2002: *========================================================================== */ import java.util.*; import java.text.*; // for parseException /*================================================================== Unit class *==================================================================*/ /** * Class able to deal with scientific units and make the appropriate * conversions, according to the * "Adopted Standards for Astronomical Catalogues" * (http://vizier.u-strasbg.fr/doc/catstd.htx) *

* The recursive definition is as follows: *

 * Full_Unit = factor Complex_unit
 * Complex_Unit = single_Unit
 * 	        | single_Unit OP single_Unit
 * 	        | "log[" single_Unit OP single_Unit "]"
 * 	        | "mag[" single_Unit OP single_Unit "]"
 * single_Unit  = extended_UnitSymbol
 * 	        | extended_UnitSymbol power
 * extended_UnitSymbol = UnitSymbol
 * 	   	       | Magnitude_Prefix UnitSymbol
 * 		       | "(" Full_Unit ")"
 * power = Number
 * 	 | +Number
 * 	 | -Number
 * OP	 = . | /
 * 
* * Basically, a unit consists in a value associated to a * unit symbol which is itself related to the SI * (Système International). Most of the unit symbols in use in * astronomy are included, but it is possible to add the definition of new units * with their equivalence via the addSymbol method. *

* The class can also deal with units expressed in log scale like * [km/s] equivalent to log(km/s), or in mag scale * which is defined as -2.5log. Values may be transformed between the * linear and log scales with the log, mag and dexp * methods; conversions may also be performed via the convert method. *

* The operations on units include the basic operations plus, * minus, mult, div and power; operations on * physical values * would however better use the sum or prod methods, which take * care of converting the log scales. To illustrate the differences, assuming * that u1 and u2 have the same content of 5mag, * the operation u1.add(u2) gives the result 10mag, * while u1.sum(u2) gives a value around 4.25mag * corresponding to the brightness of a source merging the two brightnesses. *

* For repetitive operations, like working on values from a table, it is * suggested to use the setValue method which assigns the value * but keeps the unit symbol and definition. *

* The numbers with their associated unit are edited as a single word * (without embedded blanks); the SI equivalent may be edited with the * inSI method. * The numbers in their edited form use an exponential notation * mx10+n; the classical form * mE+n is also correctly interpreted. * Values in sexagesimal notation are also interpreted correctly in * setValue provided their associated unit is "h:m:s" (time) * or "d:m:s" (angle) --- the quotes " are required! *

* An example of a program reading data all with the same km/s unit * could be: *

 * Unit aUnit = new Unit("km/s") ; 
 * while (true) {
 *     aUnit.setValue(stdin.readLine()) ;
 *     System.out.println("Complete Value: " + aUnit);
 *     System.out.println(" SI Equivalent: " + aUnit.inSI());
 *     System.out.println("       Meaning: " + aUnit.explain());
 * }
 * 
* * @@author: François Ochsenbein -- francois@@astro.u-strasbg.fr * @@version: 0.7 07-sep-2002 * @@version: 0.9 15-sep-2002: * ---------------------------------------------------------------------------- */ public class Unit { /** The value, expressed in unit symbol */ public double value; // The value expressed in "symbol" unit /** The symbolic unit, like km/s */ public String symbol; // The symbol for this Unit /* protected String explain; */ /* Detailed explanation of the unit */ /** Exponents in 8 units "mag", "kg", "m", "s", "A", "K", "cd", "mol" */ private long mksa; // Exponents in mag kg m s A K cd mol private double factor; // Factor to convert "symbol" into "SI" // =========================================================== // Constants // =========================================================== /** Definitions of the SI basic units */ /* The exponent in each component of SI is stored as a byte, the 'zero' being represented by the _e0 (0x30) byte, except for the Magnitude where it's represented by 02. The sign (leftmost) bit of the MKSA indicates a log scale of the unit; associated to the 'mag' bit (_mag), this indicates a 'mag' scale (-2.5log) */ static final char[] x = "0123456789abcdef".toCharArray(); static boolean initialized = false; static private byte accuracy = 8; // Number of Significant Digits static final boolean debug = false; static final private byte _e0 = 0x30 ; // Unitless MKSA static final private byte _m0 = 0x02 ; // Unitless mag static final private long _ = 0x0230303030303030L; // Unitless static final private long _LOG = 0xfd00000000000000L; // Mag or Log (~02) static final private long _log = 0x8000000000000000L; // Log scale static final private long _mag = 0x0100000000000000L; // Mag scale static private double scaling = 10.e-8; static final double ln10 = Math.log(10.) ; static final double[] powers = { 1., 1.e1, 1.e2, 1.e3, 1.e4, 1.e5, 1.e6, 1.e7, 1.e8, 1.e9 }; static private Hashtable Hsymbols = new Hashtable(149); static private Vector aDef = null; // Additional Units /** The list of basic symbols */ static final private String[] MKSA = { "mag", "kg", "m", "s", "A", "K", "cd", "mol" }; static final private String[] mul_symb = { "mu", "da", "k", "m", "c", "u", "M", "n", "G", "d", "h", "p", "T", "f", "P", "a", "E", "z", "Z", "y", "Y", "µ" } ; static final private String[] mul_text = { "micro", "deca", "kilo", "milli", "centi", "micro", "mega", "nano", "giga", "deci", "hecto", "pico", "tera", "femto(10-15)", "peta(10+15)", "atto(10-18)", "exa(10+18)", "zepto(10-21)", "zetta(10+21)", "yocto(10-24)", "yotta(10+24)", "micro" } ; static final private int[] mul_fact = { -6, 1, 3, -3, -2, -6, 6, -9, 9, -1, 2, -12, 12, -15, 15, -18, 18, -21, 21, -24, 24, -6 } ; static final private String[] op_symb = { "2", "3", "+", "-", "/", ".", "*", " " } ; static final private String[] op_text = { "square ", "cubic ", "power+", "power-", "per ", "times ", "times ", "times " } ; /* WARNING: index of "mag" in the following array must be >= 4 */ static final private String[] log_symb = { "log(", "log[", "[", "dex", "mag(", "mag[" } ; static final private char[] log_end = { ')', ']', ']', Character.MIN_VALUE, ')', ']' }; // =========================================================== // Definitions of all symbols // (generated from "gawk -f unit.awk") // =========================================================== /*** List of ALL Symbols ***/ static final private Udef[] uDef = { new Udef("---" , "", 0x0230303030303030L, 1.0), new Udef("%" , "percent", 0x0230303030303030L, 1.e-2), new Udef("h" , "hour ", 0x0230303130303030L, 3.6e3), new Udef("min" , "minute ", 0x0230303130303030L, 60.), new Udef("s" , "second ", 0x0230303130303030L, 1.0), new Udef("mag" , "magnitude ", 0x0330303030303030L, 1.0), new Udef("Jy" , "Jansky(10-26W/m2/Hz) ", 0x0231302e30303030L, 1.e-26), new Udef("deg" , "degree ", 0x0230303030303030L, (1./360.)), new Udef("rad" , "radian ", 0x0230303030303030L, (0.5/Math.PI)), new Udef("sr" , "steradian ", 0x0230303030303030L, (0.25/Math.PI)), new Udef("arcmin" , "minute of arc ", 0x0230303030303030L, (1./21600.)), new Udef("arcsec" , "second of arc ", 0x0230303030303030L, (1.e-3/1296.)), new Udef("mas" , "milli-second of arc ", 0x0230303030303030L, (1.e-6/1296.)), new Udef("uas" , "micro-second of arc ", 0x0230303030303030L, (1.e-9/1296.)), new Udef("Sun" , "Solar unit ", 0x0230303030303030L, 1.0), new Udef("solMass" , "solar mass ", 0x0231303030303030L, 1.989e+30), new Udef("solRad" , "solar radius ", 0x0230313030303030L, 6.9599e+8), new Udef("solLum" , "solar luminosity ", 0x0231322d30303030L, 3.826e+26), new Udef("m" , "metre ", 0x0230313030303030L, 1.0), new Udef("Hz" , "Herz ", 0x0230302f30303030L, 1.0), new Udef("kg" , "kilogram ", 0x0231303030303030L, 1.0), new Udef("g" , "gram ", 0x0231303030303030L, 1.e-3), new Udef("degC" , "Celsius ", 0x0230303030313030L, 1.0), new Udef("K" , "Kelvin ", 0x0230303030313030L, 1.0), new Udef("Pa" , "Pascal ", 0x02312f2e30303030L, 1.0), new Udef("T" , "Tesla ", 0x0231302e2f303030L, 1.0), new Udef("V" , "Volt ", 0x0231322d2f303030L, 1.0), new Udef("W" , "Watt ", 0x0231322d30303030L, 1.0), new Udef("J" , "Joule ", 0x0231322e30303030L, 1.0), new Udef("eV" , "electron-Volt ", 0x0231322e30303030L, 1.602177e-19), new Udef("Ry" , "Rydberg(13.6eV) ", 0x0231322e30303030L, 21.798948e-19), new Udef("a" , "year ", 0x0230303130303030L, 31.5576e+6), new Udef("yr" , "year ", 0x0230303130303030L, 31.5576e+6), new Udef("d" , "day ", 0x0230303130303030L, 86.4e+3), new Udef("AU" , "astronomical unit ", 0x0230313030303030L, 1.49598e+11), new Udef("au" , "astronomical unit ", 0x0230313030303030L, 1.49598e+11), new Udef("pc" , "parsec ", 0x0230313030303030L, 3.0857e+16), new Udef("al" , "light-year ", 0x0230313030303030L, .946053e+16), new Udef("JD" , "Julian Day ", 0x0230303130303030L, 86.4e+3), new Udef("MJD" , "Mod. Julian Date (JD-2400000.5) ", 0x0230303130303030L, 86.4e+3), new Udef("pix" , "pixel ", 0x0230303030303030L, 1.0), new Udef("ct" , "count ", 0x0230303030303030L, 1.0), new Udef("ph" , "photon ", 0x0230303030303030L, 1.0), new Udef("A" , "Ampere ", 0x0230303031303030L, 1.0), new Udef("barn" , "barn(10-28m2) ", 0x0230323030303030L, 1.e-28), new Udef("bit" , "binary information unit ", 0x0230303030303030L, 1.0), new Udef("byte" , "byte(8bits) ", 0x0230303030303030L, 1.0), new Udef("C" , "Coulomb ", 0x0230303131303030L, 1.0), new Udef("D" , "Debye (dipole)", 0x0230313131303030L, (1.e-29/3.)), new Udef("cd" , "candela(lumen/sr) ", 0x0230303030303130L, 1.0), new Udef("F" , "Farad ", 0x022f2e3432303030L, 1.0), new Udef("H" , "Henry ", 0x0231322e2e303030L, 1.0), new Udef("lm" , "lumen ", 0x0230303030303130L, (0.25/Math.PI)), new Udef("lx" , "lux(lm/m2) ", 0x02302e3030303130L, (0.25/Math.PI)), new Udef("mol" , "mole ", 0x0230303030303031L, 1.0), new Udef("N" , "Newton ", 0x0231312e30303030L, 1.0), new Udef("Ohm" , "Ohm(V/A) ", 0x0231322d2e303030L, 1.0), new Udef("S" , "Siemens(A/V) ", 0x022f2e3332303030L, 1.0), new Udef("Wb" , "Weber(V.s) ", 0x0231322e2f303030L, 1.0), new Udef("µas" , "micro-second of arc ", 0x0230303030303030L, (1.e-9/1296.)), new Udef("\"d:m:s\"" , "degree arcminute arcsecond (sexagesimal angle from degree)", 0x0230303030303030L, (1./360.)), new Udef("\"h:m:s\"" , "hour minutes seconds (sexagesimal time from hours)", 0x0230303130303030L, 3600.0), new Udef("\"m:s\"" , "minutes seconds (sexagesimal time from minutes)", 0x0230303130303030L, 60.0), // new Udef("\"HHMMSS\"", // "hour minutes seconds (sexagesimal time without separator)", // 0x0230303130303030L, 1.0 ), new Udef("\"HH:MM:SS\"", "hour minutes seconds (sexagesimal time)", 0x0230303130303030L, 1.0 ), // new Udef("\"month\"" , "Month name or number", // 0x0230303030303030L, 86400.), // new Udef("\"MM/YY\"" , "Month/Year(from 1900)", // 0x0230303030303030L, 86400.), // new Udef("\"MM/yy\"" , "Month/Year(from 2000)", // 0x0230303030303030L, 86400.), new Udef("\"day\"" , "Day of month number", 0x0230303030303030L, 86400.), new Udef("pi" , "pi(=3.14...)", 0x0230303030303030L, Math.PI), new Udef("c" , "c(speed_of_light)", 0x0230312f30303030L, 2.997925e+8), new Udef("G" , "G(gravitation)", 0x022f332e30303030L, 6.67e-11), new Udef("\\h" , "h(Planck)", 0x0231322f30303030L, 6.6262e-34), new Udef("e" , "e(electron_charge) ", 0x0230303131303030L, 1.602177e-19), new Udef("k" , "k(Boltzmann) ", 0x0231322e302f3030L, 1.38062e-23), new Udef("R" , "R(gas_constant) ", 0x0231322e302f302fL, 8.3143), new Udef("mp" , "proton_mass ", 0x0231303030303030L, 1.672661e-27), new Udef("me" , "electron_mass ", 0x0231303030303030L, 9.10956e-31), new Udef("atm" , "atmosphere ", 0x02312f2e30303030L, 101325.), new Udef("mmHg" , "mercury_mm ", 0x02312f2e30303030L, 133.3224), new Udef("l" , "litre ", 0x0230333030303030L, 1.e-3), new Udef("hr" , "hour(use 'h') ", 0x0230303130303030L, 3.6e3), new Udef("sec" , "second (use 's')", 0x0230303130303030L, 1.0), new Udef("inch" , "inch ", 0x0230313030303030L, 2.54e-2), new Udef("t" , "ton ", 0x0231303030303030L, 1.e+3), new Udef("month" , "month ", 0x0230303030303030L, 1.0), new Udef("erg" , "erg(10-7J) ", 0x0231322e30303030L, 1.e-7), new Udef("dyn" , "dyne(10-5N) ", 0x0231312e30303030L, 1.e-5), new Udef("bar" , "bar(10+5Pa) ", 0x02312f2e30303030L, 1.e+5), new Udef("gauss" , "Gauss(10-4T) ", 0x0231302e2f303030L, 1.e-4), new Udef("cal" , "calorie ", 0x0231322e30303030L, 4.1854), new Udef("Angstroem" , "Angstroem (0.1nm) ", 0x0230313030303030L, 1.e-10), new Udef("Å" , "Angstroem (0.1nm) ", 0x0230313030303030L, 1.e-10), new Udef("u" , "Unit of atomic mass ", 0x0231303030303030L, 1.66053873e-27), new Udef("lyr" , "light-year (c*yr) ", 0x0230313030303030L, .946053e+16), new Udef("geoMass" , "Earth mass ", 0x0231303030303030L, 5.976e+24), new Udef("jovMass" , "Jovian mass ", 0x0231303030303030L, 1.902e+27), }; // =========================================================== // Initialisation // =========================================================== private static void init() { for (int i=0; i < uDef.length; i++) Hsymbols.put(uDef[i].symb, new Integer(i)) ; initialized = true; } /** Change the default number of significant digits for Editions (8) * @@param digits: the number of significant digits * @@return the previously defined number of significant digits **/ public static final int setAccuracy(int digits) { int old_value = accuracy; if (!initialized) init(); if (digits < 2) accuracy = 2; else if (digits > 16) accuracy = 16; else accuracy = (byte)digits; scaling = power10(1-accuracy); return(old_value); } /*================================================================== Management of the List of Units *==================================================================*/ /** Retrieve one definition of the units from the uDef table * @@param key: the symbol to find out * @@return its object **/ private static final Udef uLookup (String symbol) { int i; Udef u; if (!initialized) init(); Object o = Hsymbols.get(symbol) ; if (o instanceof Integer) ; else return(null); i = ((Integer)o).intValue(); if (i < uDef.length) // In basic list return(uDef[i]) ; i -= uDef.length; u = (Udef)aDef.elementAt(i); return(u); } /** Retrieve one definition of the units from the uDef table * @@param key: the symbol to find out in form of ParsingText * @@return its object **/ private static final Udef uLookup (ParsingText t, int len) { String symb = new String(t.a, t.pos, len); Udef u = uLookup(symb); if (u != null) t.pos += len; return(u); } /** List all symbols (without the multiplicity indexes) * @@return an Enumeration of the symbols. * The symbols can be used as argument in the explain * method to get details. **/ public static final Enumeration symbols() { if (!initialized) init(); return(Hsymbols.keys()); } /** Introduce a new Symbol in the list of Symbols * @@param symbol: the text of the symbol -- made of letters only, * or letters preceded by a backslash, or surrounded by quotes * @@param equiv: the definition of the symbol in terms of existing symbols * @@param explain: the text to be used for explanation * (should be terminated by a blank) * @@return The text of the explanation of the unit previously defined * having the same symbol, or "" * @@exception ParseException when equiv can't be interpreted. **/ public static final String addSymbol (String symbol, String equiv, String explain) throws ParseException { Udef old_unit, new_def; Unit new_unit; int i; // if (!initialized) init(); -- executed in uLookup old_unit = uLookup(symbol) ; new_unit = new Unit(equiv); // Create a vector of additional units if not existing if (aDef == null) aDef = new Vector(16); // Transform the unit into a new definition if (!Double.isNaN(new_unit.value)) { if ((new_unit.mksa&_LOG) != 0) { // Convert the log scale Unit u = new Unit(new_unit); u.dexp(); new_unit.factor = u.factor * u.value; } else new_unit.factor *= new_unit.value; } new_def = new Udef(symbol, explain, new_unit.mksa, new_unit.factor); // Add the new unit into the Vector, and into the Hashtable i = aDef.size() + uDef.length; // Index of new unit for Htable aDef.addElement(new_def); Hsymbols.put(symbol, new Integer(i)); // Return the old Explanation if (old_unit == null) return(""); return(old_unit.expl); } /** Introduce a new Symbol in the list of Symbols * @@param symbol: the text of the symbol -- made of letters only, * or letters preceded by a backslash, or surrounded by quotes * @@param equiv: the definition of the symbol in terms of existing symbols * @@return The text of the explanation of the unit previously defined * having the same symbol * @@exception ParseException when equiv can't be interpreted. **/ public static final String addSymbol (String symbol, String equiv) throws ParseException { return(addSymbol(symbol, equiv, equiv + " ")) ; } /*================================================================== Constructors *==================================================================*/ /** Define the default unit: unitless undefined value **/ public Unit() { symbol = null; mksa = _; factor = 1; value = 0./0.; // NaN } /** Define a Unit and Value from an existing one (clone) * @@param u: the Unit to clone **/ public Unit(Unit u) { // Just copy the instance this.set(u); } /** Define a Value+Unit by interpreting a String * @@param symbol: a text to interpret, e.g. 20km/s, or 2(75km/s/Mpc) * @@exception ParseException when the argument contains non-interpretable * text **/ public Unit(String symbol) throws ParseException { this.set(symbol) ; } /*================================================================== Very Basic Utilities *==================================================================*/ /** Add the () to transform an expression into a simple expression * The () are added only is the string contains non-letter. **/ private static final String toExpr(String s) { char[] b = s.toCharArray(); int i; for (i=0; (i m) { x *= powers[m]; i -= m; } x *= powers[i]; if (inv) x = 1./x ; return(x); } /*================================================================== Adding date_units ?? *==================================================================*/ /*================================================================== Operations on a single Unit *==================================================================*/ /** Convert a value to a log scale * @@exception ArithmeticException when the unit contains already logs **/ public final void log() throws ArithmeticException { if ((mksa&_LOG) != 0) throw new ArithmeticException ("****Unit: log(" + symbol + ")") ; value = Math.log(value)/ln10; mksa |= _log; if (symbol != null) symbol = "[" + symbol + "]"; // Enough to indicate log } /** Convert a value to a mag scale * @@exception ArithmeticException when the unit contains already logs **/ public final void mag() throws ArithmeticException { if ((mksa&_LOG) != 0) throw new ArithmeticException ("****Unit: mag(" + symbol + ")") ; value = -2.5*Math.log(value)/ln10; if ((mksa == _) && (factor == 1)) { // Now we've mag mksa |= _mag; if (symbol != null) symbol = "mag"; } else { mksa |= (_log|_mag); if (symbol != null) symbol = "mag[" + symbol + "]"; } } /** Convert a value to its linear scale * @@exception ArithmeticException when the unit is not a log **/ public final void dexp() throws ArithmeticException { double ls; char c; int i, last; if ((mksa&_log) == 0) throw new ArithmeticException ("****Unit: dexp(" + symbol + ")") ; ls = (mksa&_mag) != 0 ? -2.5 : 1.; value = Math.exp(value*ln10/ls); mksa &= (~_LOG) ; if (symbol == null) return; // Change the symbol i = -1; last = symbol.length()-1; c = symbol.charAt(last); // Closing bracket if (c == ']') i = symbol.indexOf('['); else if (c == ')') i = symbol.indexOf('('); if (i >= 0) symbol = symbol.substring(i+1, last); else { // Symbol can't be found, use SI StringBuffer b = new StringBuffer(64); toSI(b, 0); symbol = "" + b; } } /** Compute the Power of a number/unit * @@param expo: Power value * @@exception ArithmeticException when the power is too large **/ public final void power (int expo) throws ArithmeticException { double error = 0; int i = expo; double r = 1; double v = 1; long u = _; if ((mksa&(_log|_mag)) != 0) throw new ArithmeticException ("****Unit: can't power log[unit]: " + symbol ); while (i > 0) { r *= factor; v *= value; u += mksa; u -= _; if ((u&0xfd80808080808080L) != 0) error++; i--; } while (i < 0) { r /= factor; v /= value; u += _; u -= mksa; if ((u&0xfd80808080808080L) != 0) error++; i++; } if (error > 0) throw new ArithmeticException ("****Unit: power too large: (" + ")^" + expo) ; factor = r; value = v; mksa = u; /* Decision for the new symbol */ if ((u != _) && (expo != 1) && (symbol != null)) { if (expo == 0) symbol = ""; else { /* The 'powered' symbol uses parentheses if made of not just Letters */ symbol = toExpr(symbol) + expo ; } } } /*================================================================== Conversion of a Unit into another one *==================================================================*/ /** Checks whether 2 units are compatible (can be summed via the * sum method) * @@param unit: another Unit, to be verified. **/ public final boolean isCompatibleWith (Unit unit) { return((mksa&(~(_log|_mag))) == (unit.mksa&(~(_log|_mag)))) ; } /** Convert a value to the target Unit * @@param unit: a value expressed in another Unit, * to convert to target unit. * @@exception ArithmeticException when the units are not compatible **/ public final void convert (Unit unit) throws ArithmeticException { double f = unit.factor/factor; double ls; /* unit.dump("...convert-from"); dump("...convert-.to."); */ if (mksa == unit.mksa) { if ((mksa&_log) == 0) value = f*unit.value; else { // Convert to log scale: log(km) --> log(m) f = Math.log(f)/ln10; if ((mksa&_mag) != 0) f = -2.5*f; value = unit.value + f; } return ; } /* Convert to / from Log scale */ if ((mksa&(~_LOG)) != (unit.mksa&(~_LOG))) throw new ArithmeticException ("****Unit: can't convert " + symbol + " into " + unit.symbol); if ((mksa&_log) == 0) { // Remove the log ls = (unit.mksa&_mag) != 0 ? -2.5 : 1.; value = f*Math.exp(unit.value*ln10/ls); return; } /* The target is a log. Check whether the source is also in log scale */ if ((unit.mksa&_log) != 0) { // Convert from log to log value = (unit.mksa&_mag) != 0 ? -0.4*unit.value : // From a magnitude unit.value; value += Math.log(f)/ln10; // Target assumed to be log if ((mksa&_mag) != 0) // Target is a magnitude value *= -2.5; return ; } /* The target is a log, the source is in a linear scale. */ ls = (mksa&_mag) != 0 ? -2.5 : 1.; value = ls*Math.log(f*unit.value)/ln10; } /*================================================================== Addition of 2 Units *==================================================================*/ /** Compute the Addition of 2 numbers * @@param unit: 2nd Unit * @@exception ArithmeticException when the units are not compatible **/ public final void plus (Unit unit) throws ArithmeticException { if (mksa != unit.mksa) throw new ArithmeticException ("****Unit: can't combine: " + symbol + " + " + unit.symbol); /* Addition in log scale: a+b=a+f*log(1.+10^((b-a)/f)) */ value += (unit.value*unit.factor)/factor; } /** Compute the Subtraction of 2 numbers * @@param unit: 2nd Unit * @@exception ArithmeticException when the units are not compatible **/ public final void minus (Unit unit) throws ArithmeticException { if (mksa != unit.mksa) throw new ArithmeticException ("****Unit: can't combine: " + symbol + " - " + unit.symbol); value -= (unit.value*unit.factor)/factor; } /** Compute the Sum of 2 values representing physical units * The difference with "plus" exists only for log scales or magnitudes: * the resulting value corresponds to a physical sum (e.g. of fluxes), * whereas the "plus" corresponds to an arithmetic sum. * @@param unit: 2nd Unit * @@exception ArithmeticException when the units are not compatible **/ public final void sum (Unit unit) throws ArithmeticException { double ls, dv; int error = 0; long rlog, ulog; dump("...term1"); unit.dump("...term2"); if ((mksa&(~_LOG)) != (unit.mksa&(~_LOG))) throw new ArithmeticException ("****Unit: can't sum: " + symbol + " + " + unit.symbol); rlog = mksa&(_log|_mag); ulog = unit.mksa&(_log|_mag); if (rlog != ulog) { // Not the Same log scale -- convert Unit tunit = new Unit(this); tunit.convert(unit); // Convert the argument unit to target. this.sum(tunit); // Now, the units are the same! return; } // Here, we have the same log scales if (rlog == 0) { this.plus(unit); return; } ls = (rlog&_mag) != 0 ? -2.5 : 1.0 ; /* Addition in log scale: a+b=a+f*log(1.+10^((b-a)/f)) */ ls /= ln10; // log scale adapted to natural log/exp dv = unit.value - value; value += ls*Math.log(1.+(unit.factor/factor)*Math.exp(dv/ls)) ; } /*================================================================== Multiplication of 2 Units *==================================================================*/ /** Compute the Multiplication by a Scalar * @@param s: Scalar value for the multiplication **/ public final void mult (double s) throws ArithmeticException { value *= s; } /** Compute the Multiplication of 2 units * @@param unit: 2nd Unit * @@exception ArithmeticException when the units can't be combined **/ public final void mult (Unit unit) throws ArithmeticException { long u = mksa ; double r = factor; double v = value; /* dump("mult:this "); unit.dump("mult:unit"); */ if (((mksa|unit.mksa)&_log) != 0) { if ((mksa == _) && (factor == 1.)) ; else if ((unit.mksa == _) && (unit.factor == 1.)) ; else throw new ArithmeticException ("****Unit: can't multiply logs: " + symbol + " x " + unit.symbol); } v *= unit.value; r *= unit.factor; u += unit.mksa; u -= _; if ((u&0x7c80808080808080L) != 0) throw new ArithmeticException ("****too large powers in: " + symbol + " x " + unit.symbol); mksa = u; factor = r; value = v; /* Decision for the new symbol */ if ((symbol != null) && (unit.symbol != null)) { if ((unit.mksa == _) && (unit.factor == 1)) return; // No unit ... if (( mksa == _) && ( factor == 1)) symbol = unit.symbol; else if ((symbol.equals(unit.symbol)) && (factor == unit.factor)) symbol = toExpr(symbol) + "2" ; else symbol = toExpr(symbol) + "." + toExpr(unit.symbol) ; } } /** Compute the Division of 2 units * @@param unit: 2nd Unit * @@exception ArithmeticException when the units can't be combined **/ public final void div (Unit unit) throws ArithmeticException { long u = mksa ; double r = factor; double v = value; if (((mksa|unit.mksa)&_log) != 0) { if ((mksa == _) && (factor == 1.)) ; else if ((unit.mksa == _) && (unit.factor == 1.)) ; else throw new ArithmeticException ("****Unit: can't divide logs: " + symbol + " / " + unit.symbol); } v /= unit.value; r /= unit.factor; u += _; u -= unit.mksa; if ((u&0xfc80808080808080L) != 0) throw new ArithmeticException ("****too large powers in: " + symbol + " / " + unit.symbol); mksa = u; factor = r; value = v; /* Decision for the new symbol */ if ((symbol != null) && (unit.symbol != null)) { if ((unit.mksa == _) && (unit.factor == 1)) return; // No unit ... if (( mksa == _) && ( factor == 1)) symbol = toExpr(unit.symbol) + "-1"; else if (symbol.equals(unit.symbol)) symbol = edf(factor); else symbol = toExpr(symbol) + "/" + toExpr(unit.symbol) ; } } /** Compute the Product of 2 units representing physical units * The difference with "mult" exists only for log scales or magnitudes: * the resulting value corresponds to a physical product * whereas the "mult" corresponds to an arithmetic multiplication. * @@param unit: 2nd Unit * @@exception ArithmeticException when the units are not compatible **/ public final void prod (Unit unit) throws ArithmeticException { Unit runit, tunit; if (((mksa&_log)==0) && ((unit.mksa&_log)==0)) { mult(unit); return; } /* Convert to non-log Unit */ runit = new Unit(this); tunit = new Unit(unit); if ((runit.mksa&_log) != 0) { runit.mksa &= ~(_log|_mag); runit.convert(this); } if ((tunit.mksa&_log) != 0) { tunit.mksa &= ~(_log|_mag); tunit.convert(this); } runit.mult(tunit) ; if ((mksa&_log) != 0) { // Convert to log scale if ((mksa&_mag) != 0) runit.mag() ; else runit.log() ; } // Copy the result set(runit); // System.arraycopy(runit, 0, this, 0, 1) ; // this = runit; } // ================================================================== // Internal Parsing for Unit Interpretation // ================================================================== /** Interpret for a SimpleUnit as [multiplicator-prefix]Unit-Symbol[power] * @@param ext: text to interpret * @@param edited: result of edited unit (may be null) * @@return the number of bytes interpreted * @@remark Only the UNIT part (value not touched) **/ private final int unit1 (ParsingText text, StringBuffer edited) throws ParseException { int posini = text.pos; // Initial position in text Udef theUnit = uDef[0]; // Default Unit = Unitless int mult_index = -1; // Index in mul_fact by e.g. µ int power = 1; char op = Character.MIN_VALUE; // Operator power int error = 0; // Error counter boolean close_bracket = false; // () not edited when buffer empty int i, s; /* Initialize the Unit to unitless */ mksa = _; factor = 1.; if (text.pos >= text.len) return(0); // Unitless switch(text.a[text.pos]) { case '(': /* Match parenthesized expression */ text.pos++; // Accept the '(' if (close_bracket = (edited != null) && (edited.length() > 0)) edited.append('(') ; this.unitec(text, edited) ; if ((text.pos < text.len) && (text.a[text.pos] == ')')) text.pos++; else throw new ParseException ("****Unit: Missing ) in '" + text + "'", text.pos); if (close_bracket) { // Remove the Ending blanks, before closing the bracket i = edited.length(); while ((--i >= 0) && (edited.charAt(i) == ' ')) ; edited.setLength(++i); edited.append(')') ; close_bracket = false; } break ; case '"': /* Units within quotes " must match exactly */ // Accept the Sexagesimal --- match the closing " for (i=text.pos+1; (i= text.len) break; if (Character.isDigit(text.a[text.pos])) { // Number ? text.pos = s; break; } while ((text.pos1) mult_index = text.lookup(mul_symb) ; if (mult_index < 0) break; theUnit = uLookup(text, i-text.pos) ; if (theUnit == null) text.pos = s; } /* Look now for a Power -- meaningful ONLY applied on a unit */ if ((error == 0) && (text.pos < text.len)) op = text.a[text.pos]; if ((op == '+') || (op == '-') || (op == '^') || Character.isDigit(op)){ if (op == '^') text.pos += 1; if (text.pos < text.len) { op = text.a[text.pos]; if (op == '+') text.pos++ ; if (op != '-') op = '+'; power = text.parseInt() ; // A zero-power is illegal !! if (power == 0) error++; // 'square' or 'cubic' is spelled out BEFORE the unit name else if ((power > 0) && (power < 10) && (edited != null)) { text.pos--; // Now text is the digit of power i = text.lookup(op_symb) ; if (i >= 0) { // Square or cubic edited.append(op_text[i]) ; op = ' '; // Power is now edited } else text.pos++; } } else error++; } if (error>0) throw new ParseException ("****Unit: '" + text + "'+" + text.pos, text.pos) ; if (mult_index >= 0) { // Multiplicities like 'k', 'µ', ... factor *= power10(mul_fact[mult_index]); if (edited != null) edited.append(mul_text[mult_index]) ; } if (theUnit != null) { factor *= theUnit.fact ; mksa = theUnit.mksa; if (edited != null) edited.append(theUnit.expl) ; } if (power != 1) { this.power (power) ; if ((op != ' ') && (edited != null)) { edited.append("power") ; edited.append(op); edited.append(power); } } s = text.pos - posini; return(s); } /** Interpret for a CompoundUnit * [factor] SimpleUnit [operator unit] * @@param text: text to interpret * @@param edited: result of edited unit * @@return the number of bytes interpreted * @@remark Only the UNIT part (value not touched) **/ private final int unitec (ParsingText text, StringBuffer edited) throws ParseException { int posini = text.pos; Unit tunit = null; // Temporary Unit int log_index = -1; // Index in log_symb char op = 'x'; // Operator char end = Character.MIN_VALUE; int error = 0; int i, s; if (debug) System.out.println("..unitec(" + text + "), pos=" + text.pos); /* Initialize the Unit to unitless */ mksa = _; /* Ignore the leading blanks */ while ((text.pos < text.len) && Character.isWhitespace(text.a[text.pos])) text.pos++; /* Possibly all as Log */ log_index = text.lookup(log_symb) ; if (log_index >= 0) { // A log(...) or mag(...) end = log_end[log_index] ; if (edited != null) edited.append(log_symb[log_index&(~3)]) ; } /* Interpret the Factor */ s = text.pos; // Save factor = text.parseFactor(); // Default is 1.0 if ((edited != null) && (s != text.pos)) edited.append(text.a, s, text.pos-s) ; /* Find out the Units and Operators */ s = -1; // Index of Operator in op_symb while (text.pos < text.len) { if (text.a[text.pos] == end) break; /* Closing the log() */ if (tunit == null) tunit = new Unit(); i = tunit.unit1(text, edited) ; // Match a Unit if (debug) tunit.dump("..unitec"); // if (i == 0) break; // Accept Nothing matched if (op == '/') this.div(tunit) ; else this.mult(tunit) ; s = text.lookup(op_symb); // Can there be an Operator ? if (s < 0) break; op = op_symb[s].charAt(0); // Is always '/' for division if (edited != null) { // Edit the Operator // Remove the Ending blanks, to install a single blank i = edited.length(); while ((--i >= 0) && (edited.charAt(i) == ' ')) ; edited.setLength(++i); edited.append(' '); edited.append(op_text[s]); } } /* Close the log() */ if (log_index >= 0) { if (edited != null) { // Close the parenthese // Remove the Ending blanks i = edited.length(); while ((--i >= 0) && (edited.charAt(i) == ' ')) ; edited.setLength(++i); edited.append(log_end[log_index&(~3)]) ; } if ((text.pos < text.len) && (end != Character.MIN_VALUE) &&(text.a[text.pos] == end)) { end = Character.MIN_VALUE; text.pos++; } mksa |= _log ; if ((log_index&4) != 0) mksa |= _mag; } /* Final Verifications */ if (s >= 0) throw new ParseException // Missing 2nd argument ("****Unit.text+" + text.pos + " (missing operand): " + text, text.pos) ; if (end != Character.MIN_VALUE) throw new ParseException ("****Unit.text+" + text.pos + " (missing '" + end + "'): " + text, text.pos) ; /* Skip the trailing blanks */ while ((text.pos < text.len) && Character.isWhitespace(text.a[text.pos])) text.pos++; return(text.pos - posini); } /*================================================================== Set components of a Unit *==================================================================*/ /** Define a Unit and Value from an existing one (clone) * @@param u: the Unit to clone **/ public final void set (Unit u) { // Just copy the instance mksa = u.mksa ; symbol = u.symbol ; value = u.value ; factor = u.factor ; } /** Convert a String to a Unit + Value * @@param text: text to interpret; for instance
* 100km/s is interpreted as Unit=km/s; Value=100
* To add a numeric factor in Unit, use parentheses, e.g.
* 123(100km/s) is: Unit: 100km/s; Value=123 * @@exception ParseException when the argument contains non-interpretable * text **/ public void set (String text) throws ParseException { ParsingText t = new ParsingText(text); double val; int posini; boolean value_def; if (!initialized) init(); // Be sure everyting in place /* Ignore the leading blanks */ while ((t.pos < t.len) && Character.isWhitespace(t.a[t.pos])) t.pos++; posini = t.pos; /* Interpret the Value, if any */ val = t.parseFactor(); // Default value is 1 if (value_def = posini == t.pos) // NaN when nothing interpreted val = 0./0.; /* Skip blanks between value and Unit */ while ((t.pos < t.len) && Character.isWhitespace(t.a[t.pos])) t.pos++; /* It may happen than interpreting the Value first generates an error, for instance 1/4. That means that the number (1) is part of the unit, and is not the value in front of the unit. */ if (t.lookup(op_symb) >= 0) { val = 0./0.; t.pos = posini; } /* Interpret the Unit */ posini = t.pos; // To keep the Unit symbol symbol = null; unitec(t, null) ; symbol = text.substring(posini, t.pos); value = val; // Default value in log scale is 0 ! if (value_def && ((mksa&_log) != 0)) value = 0; /* Skip the trailing blanks */ while ((t.pos < t.len) && Character.isWhitespace(t.a[t.pos])) t.pos++; if (t.pos < t.len) throw new ParseException ("****Unit: set '" + text + "'+" + t.pos, t.pos); } /** Just assign the value of the Unit * @@param text: value (set to NaN when not correct), which can use the * exponential notation like 10+8 to express * 108 * @@exception ParseException when the argument text which does not * represent a number **/ public void setValue (String text) throws ParseException { ParsingText t = new ParsingText(text); int posini; /* Ignore the leading blanks */ while ((t.pos < t.len) && Character.isWhitespace(t.a[t.pos])) t.pos++; posini = t.pos; /* Take care of units requiring data in Sexagesimal */ if ((symbol.charAt(0) == '"') && (symbol.indexOf(':')>0)) // " value = t.parseSexa(); else value = t.parseFactor(); if (t.pos == posini) { // Nothing interpreted, check for NaN value = 0./0. ; while ((t.pos < t.len) && (t.a[t.pos] == '-')) t.pos++; } /* Skip the trailing blanks */ while ((t.pos < t.len) && Character.isWhitespace(t.a[t.pos])) t.pos++; if (t.pos < t.len) throw new ParseException ("****Unit: setValue '" + text + "'+" + t.pos, t.pos); } /** Just assign the value of the Unit * @@param value: value to set * @@remark Unit not touched. **/ public void setValue (double value) { this.value = value; } // ================================================================== // Internal methods for Editing Units // ================================================================== /** Edition of a single factor number if differs from 1 * @@param buf: the edition buffer to which the edited number is appended * @@param value: the number to edit * @@return the number of bytes added to buf * @@remark Edition as x.fraction×10±pow **/ private static final int edf (StringBuffer buf, double factor) { Double aDouble; char[] edited; int len0 = buf.length(); double val = factor ; double f = 1.; boolean addx = true; // Must add the exponent boolean addp = true; // Must add the decimal point int e, n, i, pp; long m; if (Double.isNaN(factor)) // NOT NORMAL for a factor!! return(0) ; if (factor < 0) { buf.append('-'); val = -val; } if (val == 0) { // NOT NORMAL for a factor!! buf.append('0') ; return(buf.length() - len0); } if (Double.isInfinite(val)) { // NOT NORMAL for a factor!! buf.append(val) ; return(buf.length() - len0); } /* Don't edit value 1. */ if (Math.abs(val-1.) < 1.e-15) return(buf.length() - len0); /* Find the exponent n from IEEE format such that: 10^n <= val < &10^(n+1) i.e. normalize the number in range 1 .. 10 */ n = (int)(Double.doubleToLongBits(val) >> 52) - 0x3ff; // Expo base 2 n = (n*3)/10; // Approximative exponent in base 10 f = power10(n) ; while (val < f) f = power10(--n); while (val >= 10.*f) f = power10(++n); val /= f; /* Round the number according to accuracy */ val += 0.5*scaling; if (val >= 10.0) { f = power10(++n); val /= 10.; } /* Convert to an Integer number */ aDouble = new Double(val/scaling) ; m = aDouble.longValue(); /* Edit the number */ i = accuracy; edited = new char[i]; while (--i>=0 ) { edited[i] = x[(int)(m%10)]; m /= 10; } /* Append the edited number */ i = 0; e = n; // Exponent to edit if (n == -1) { buf.append("0."); e = 0; addp = false; } buf.append(edited[i++]); if ((n != 1) && (addp)) { buf.append('.'); addp = false; } buf.append(edited[i++]); if ((n == 1) && (addp)) { buf.append('.'); e = 0; } while (i < edited.length) buf.append(edited[i++]); /* Remove the fractional part when just 0's */ for (i = buf.length()-1; buf.charAt(i) == '0'; i--) ; if (buf.charAt(i) != '.') ++i; else if (e != 0) { // Remove also the '1' in '1x10+n if (buf.charAt(--i) == '1') addx = false; else ++i; } buf.setLength(i); /* Add the Exponent */ if (e != 0) { if (addx) buf.append('x') ; buf.append("10"); if (e>0) buf.append('+'); buf.append(e); } /* Finally, return the number of chars appended */ return(buf.length() - len0); } /** Edition of a single factor number if differs from 1 as a String * @@param value: the number to edit * @@return the edited factort **/ private static final String edf (double factor) { StringBuffer buf ; if (factor == 1) return("") ; buf = new StringBuffer(32); edf(buf, factor); return("" + buf); } /** Interpret the MKSA part, choose the most appropriate unit * @@param buf: edition buffer * @@param mksa: the 'dimension' of the unit (the 'log' is ignored) * @@param option: 0 = only basic SI; 1 = try best * @@return the number of bytes used to explain the MKSA **/ private static final int edu (StringBuffer buf, long mksa, int option) { int len0 = buf.length(); int i, e, o; int nu=0; boolean sep = false; long m; /* Remove the 'log' or 'mag[]' part */ if ((mksa&_log) != 0) { mksa &= ~_log; if ((mksa&_mag) != 0) mksa &= ~_mag; } /* Check unitless -- edited as empty string */ if (mksa == _) return(0); /* Find the best symbol for the physical dimension */ if (option > 0) { nu = (mksa&_mag) == 0 ? 0 : 1; for (m=(mksa<<8)>>8; m!=0; m >>>= 8) { if ((m&0xff) != _e0 ) nu++ ; } /* Find whether this number corresponds to a composed unit */ for (i=0; i>>(56-(i<<3)))&0xff) - o; o = _e0 ; // Other units: the mean is _e0 if (e == 0) continue; if (sep) buf.append("."); sep = true; buf.append(MKSA[i]); if (e == 1) continue; if (e>0) buf.append("+") ; buf.append(e) ; } if (nu>0) buf.append("]"); return(buf.length() - len0) ; } /** Interpret a string in terms of SI dimensions * @@param b: Buffer to fill * @@param option: level of Explanation * 0 = only SI, 1 = detail * @@return the explanation with basic SI units * @@remark Useful to check the compatibility of Units **/ private void toSI (StringBuffer b, int option) { if ((mksa&_log) != 0) b.append( (mksa&_log) != 0 ? "mag[" : "log["); if (factor != 1) edf(b, factor); edu(b, mksa, option); if ((mksa&_log) != 0) b.append("]") ; } /*================================================================== Editions of Units *==================================================================*/ /** Dump the details of the object to stdout * @@param title: title of dump **/ public void dump (String title) { char[] xdim = new char[24]; long m = mksa; int i; /* Hexadecimal edition of mksa */ for (m=mksa, i=24; i>0; ) { xdim[--i] = x[(int)(m&15)]; m>>>=4; xdim[--i] = x[(int)(m&15)]; m>>>=4; xdim[--i] = '.'; } xdim[i] = 'x'; System.out.println(title + ": symbol='" + symbol + "', value=" + value); System.out.println(" factor=" + factor + ", Dim0" + xdim); } /** Interpret a String, and give a complete explanation * @@param text: the text containing the units to explain * @@return the full explanation of the Unit -- or a text * ?***bad Unit when text is not interpretable **/ public static final String explain (String text) { ParsingText t = new ParsingText(text); StringBuffer b = new StringBuffer(120) ; Unit u = new Unit(); if (!initialized) init(); try { u.unitec(t, b); } catch (Exception e) { String prefix = "?***bad Unit <"; b.insert(0, prefix); b.insert(prefix.length(), text); b.insert(prefix.length() + text.length(), "> "); } return(""+b); // Buffer converted to String } /** Explain the Meaning of a Unit * @@@@param level: Level of Explanation: * 0 = only SI, 1 = deteil * @@return the explanation with basic SI units * @@remark Useful to check the compatibility of Units **/ public final String explain () { StringBuffer b = new StringBuffer(120) ; ParsingText t = new ParsingText(symbol); Unit u = new Unit(); try { u.unitec(t, b); } catch (Exception e) {} // Should never happen! b.append(" ("); toSI(b, 1); b.append(")") ; return(""+b); // Buffer converted to String } /** Explain the Unit+Value in terms of SI units * @@return the explanation with basic SI units * @@remark Convert to non-log **/ public final String inSI() { StringBuffer b = new StringBuffer(64) ; Unit u = new Unit(this) ; /* Convert the value to linear scale, and then edit */ if ((u.mksa&_log) != 0) u.mksa &= ~(_log|_mag); u.factor = 1; u.convert(this); if (!Double.isNaN(value)) { edf(b, u.value); if (b.length() == 0) b.append('1'); } u.toSI(b, 0); return(""+b); // Buffer converted to String } /** Express the Unit only in its standardized form. * @@return the expression as a combination of powers of SI units. * The log scale is indicated by the brackets []. **/ public final String unitSI() { StringBuffer b = new StringBuffer(16) ; boolean log_scale = (mksa&_log) != 0; if (log_scale) b.append('[') ; edu(b, mksa, 0); if (log_scale) b.append(']') ; return(""+b); // Buffer converted to String } /*================================================================== Standard Edition *==================================================================*/ /** Edition of the Unit (in terms of SI) * @@return the full explanation of the Unit + Value **/ public String toString () { StringBuffer b = new StringBuffer(120) ; if (debug) dump("unit.toString"); if (!Double.isNaN(value)) { edf(b, value) ; // Value '1' not edited if (b.length() == 0) b.append((mksa&_log)!=0 ? '0' : '1'); } if ((mksa == _) && (factor == 1)); else { if (symbol != null) b.append(symbol) ; else { b.append('('); toSI(b, 0); b.append(')'); } } return(""+b); // Buffer converted to String } } / Nothing interpreted, check for NaN value = 0./0. ; while ((t.pos < t.lecds/astro/Coo.java010064400076440000132000000475710770227416100150510ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.astro ; /** * Class defining the coordinates on the celestial sphere, * and includes the missing trigonometrical functions in degrees * and hyperbolic functions. * The class includes conversions between polar angles (lon,lat) * expressed in degrees, and Cartesian 3-vectors. * The typical way of converting between polar and cartesian is: *
 * Coo aCoo = new Coo ; double u[] = new double[3] ;
 * while (true) {
 *     aCoo.set(stdin.readLine()) ;
 *     System.out.println("Coordonnees   : " + aCoo) ;
 *     u[0] = aCoo.x; u[1] = aCoo.y; u[2] = aCoo.z;
 *     System.out.println("Cos. directeurs: " + Coo.toString(u)) ;
 * }
 * 
* This class also deals with 3x3 matrices. * @@author Pierre Fernique, Francois Ochsenbein [CDS] * @@version 1.0 : 03-Mar-2000 * @@version 1.1 : 24-Mar-2000: Bug in dist */ public class Coo { // private byte status ; // 1 for angles, 2 for xyz /** Polar Angles in degrees */ public double lon, lat ; /** Components of unit vector (direction cosines) */ public double x, y, z ; /** Number of decimals on lon and lat */ public byte dlon, dlat ; // =========================================================== // Trigonometry in Degrees // =========================================================== /* Static methods (functions) in Java are very close to C ones; they do not require any object instanciation. Typical example of static methods are in the Math class Note that the functions toDegrees and toRadians can be used in JDK1.2 -- we stick here strictly to JDK1.1 */ /** Cosine when argument in degrees * @@param angle in degrees * @@return the cosine */ public static final double cosd(double x) { return Math.cos( x*(Math.PI/180.0) ); } /** Sin when argument in degrees * @@param angle in degrees * @@return the sine */ public static final double sind(double x) { return Math.sin( x*(Math.PI/180.0) ); } /** sin-1 (inverse function of sine), gives argument in degrees * @@param x argument * @@return y value such that sin(y) = x */ public static final double asind(double x) { return Math.asin(x)*(180.0/Math.PI); } /** tan-1 (inverse function of tangent), gives argument in degrees * @@param argument * @@return angle in degrees */ public static final double atand(double x) { return Math.atan(x)*(180.0/Math.PI); } /** get the polar angle from 2-D cartesian coordinates * @@param y,x = cartesian (in that order) * @@return polar angle in degrees */ public static final double atan2d(double y,double x) { return Math.atan2(y,x)*(180.0/Math.PI); } // =========================================================== // Hyperbolic Functions (not in Math ??) // =========================================================== /** Hyperbolic cosine cosh = (exp(x) + exp(-x))/2 * @@param argument * @@return corresponding hyperbolic cosine (>= 1) */ public static final double cosh (double x) { double ex ; ex = Math.exp(x) ; return 0.5 * (ex + 1./ex) ; } /** Hyperbolic tangent = (exp(x)-exp(-x))/(exp(x)+exp(-x)) * @@param argument * @@return corresponding hyperbolic tangent (in range ]-1, 1[) */ public static final double tanh (double x) { double ex, ex1 ; ex = Math.exp(x) ; ex1 = 1./ex ; return (ex - ex1) / (ex + ex1) ; } /** tanh-1 (inverse function of tanh) * @@param argument, in range ]-1, 1[ (NaN returned otherwise) * @@return corresponding hyperbolic inverse tangent */ public static final double atanh (double x) { return (0.5*Math.log((1.+(x))/(1.-(x)))); } // =========================================================== // sin(x)/x and Inverse // =========================================================== /** Function sinc(x) = sin(x)/x * @@param argument (radians) * @@return corresponding value */ public static final double sinc(double x) { double ax, y; ax = Math.abs(x); if (ax <= 1.e-4) { ax *= ax; y = 1 - ax*(1.0-ax/20.0)/6.0; } else y = Math.sin(ax)/ax; return y; } /** Reciprocal */ /** Function asinc(x), inverse function of sinc * @@param x argument * @@return y such that sinc(y) = x */ public static final double asinc(double x) { double ax,y; ax = Math.abs(x); if( ax <= 1.e-4) { ax *= ax; y = 1.0 + ax*(6.0 + ax*(9.0/20.0))/6.0; } else y = Math.asin(ax)/ax; return (y); } // =========================================================== // Spherical distance // =========================================================== /** * Distance between 2 points on the sphere. * @@param lon1,lat1 = position of first point in degrees * @@param lon2,lat2 = position of second point in degrees * @@return distance in degrees in range [0, 180] */ public static final double dist(double lon1, double lat1, double lon2, double lat2) { double c1 = cosd(lat1); double c2 = cosd(lat2) ; double w, r2 ; w = c1*cosd(lon1) - c2*cosd(lon2) ; r2 = w*w ; w = c1*sind(lon1) - c2*sind(lon2) ; r2 += w*w ; w = sind(lat1) - sind(lat2) ; r2 += w*w ; // 4.sin^2(r/2) return(2.*asind(0.5*Math.sqrt(r2))) ; } // =========================================================== // Matrices and Vectors 3x3 // =========================================================== /** 3-Matrices Products * @@param A,B = 3x3 matrices * @@return R = A * B */ public static final double[][] prod(double A[][], double B[][]) { double[][] R = new double[3][3]; int i, j ; for (i=0; i<3; i++) for (j=0; j<3; j++) R[i][j] = A[i][0]*B[0][j] + A[i][1]*B[1][j] + A[i][2]*B[2][j] ; return(R) ; } /** Transposed of a Matrix * @@param A = input matric * @@return R = t(A) */ public static final double[][] t(double A[][]) { // Transpose a Matrix double R[][] = new double[3][3]; int i, j ; for (i=0; i<3; i++) for (j=0; j<3; j++) R[i][j] = A[j][i] ; return(R) ; } // =========================================================== // Polar angles (lon,lat) <--> Cartesian // =========================================================== /** Convert (lon,lat) into its direction cosines (x,y,z) * @@param lon, lat angles in degrees */ public final void set (double lon, double lat) { double coslat = cosd(lat); this.lon = lon ; this.lat = lat ; x = coslat * cosd(lon); y = coslat * sind(lon); z = sind(lat); } /** Revert conversion of (x,y,z) into (lon,lat) * @@param x,y,z unit vector (direction cosines) * (Note that (x,y,z) doesn't need to have a norm=1) */ public final void set (double x, double y, double z) { double r2 = x*x + y*y ; this.x = x ; this.y = y ; this.z = z ; lon = 0.0; if( r2==0.0) { /* in case of poles */ if( z==0.0 ) { lon = 0./0. ; lat = 0./0.; } else lat = (z>0.0) ? 90.0 : -90.0; } else { lon = atan2d(y, x); lat = atan2d(z, Math.sqrt(r2)); if( lon<0.0) lon += 360.0; } } // =========================================================== // Interpret a string for Position // =========================================================== /** Define a coordinate for its angles * @@param text a text containing 2 angles, in decimal or Sexagesimal * @@param equatorial true when text represents equatorial coordinates * (the RA in units of time) *
Note: dlon and dlat are set to the number of decimals found * in the longitude and latitude parts. * */ public final void set (String text, boolean equatorial) throws Exception { int n = text.length() ; char b[] = text.toCharArray() ; boolean f15 = equatorial ; int state = 0 ; // 0 = Skip blanks, 1=int, 2=frac int index = 0 ; // 0-2 = lon, 4-6 = lat int nd = 0 ; // Number of decimals double value = 0 ; double angle = 0 ; double ff = 1 ; // fraction factor to get the number double fa = 1 ; // fraction factor to get the angle boolean minus = false ; int i ; char c ; lon = 0./0. ; lat = 0./0. ; // Initialize to NaN for (i=0; i= 0)) { buf.append('+') ; lint--; } if (a < 0) { a = -a ; buf.append('-') ; lint--; } int_part = (int)a ; a -= int_part ; //* Edit the integer part, zero-filled for (n=1; lint>1; lint--) n *= 10; while ((int_part/n) >= 10) n *= 10; // In case too short len //* System.err.print("....int_part=" + int_part + ", n=" + n) ; while (n > 0) { buf.append((char)('0' + int_part / n)) ; int_part %= n ; n /= 10 ; } //* Add now the decimals if (nd >= 0) buf.append('.') ; for (n = (len0 + len) - buf.length() ; n > 0; n--) { a *= 10. ; int_part = (int)a ; a -= int_part ; buf.append((char)('0' + int_part)) ; } /* Finally, return the number of chars appended */ return(buf.length() - len0) ; } /** Edition of a single floating-point number * @@param value the number to edit * @@param len the total width * @@param nd the number of decimals * @@param sign true to edit the sign as '+' or '-' * @@return the string */ public static final String toString(double value, int len, int nd, boolean sign) { StringBuffer b = new StringBuffer(len+2); ed1(b, value, len, nd, sign) ; return(""+b) ; // Buffer converted to String } /** Default Edition of the Coordinates, as 2 numbers expressing * the angles in degrees. */ public final String toString() { StringBuffer b = new StringBuffer(40) ; int nd ; nd = dlon > 0 ? dlon : 12 ; ed1(b, lon, nd+4, nd, false) ; b.append(' ') ; nd = dlat > 0 ? dlat : 12 ; ed1(b, lat, nd+4, nd, true) ; return(""+b) ; // Buffer converted to String } /** Edition of the 3 components of a vector * @@param the 3-vector * @@return the equivalent string (edited with 16 decimals) */ protected static final void edit(StringBuffer buf, double u[]) { ed1(buf, u[0], 19, 16, true) ; buf.append(' ') ; ed1(buf, u[1], 19, 16, true) ; buf.append(' ') ; ed1(buf, u[2], 19, 16, true) ; } /** Edition of the 3 components of a vector * @@param the 3-vector * @@return the equivalent string (makes use of TABs) */ protected static final String toString(double u[]) { StringBuffer b = new StringBuffer(60) ; edit(b, u) ; return(""+b) ; // Buffer converted to String } /** Edition of s 3x3 matrix * @@param the 3x3 matrix * @@return the equivalent string (makes use of TABs) */ protected static final String toString(double m[][]) { StringBuffer b = new StringBuffer(200) ; b.append(" "); edit(b, m[0]) ; b.append("\n ") ; edit(b, m[1]) ; b.append("\n ") ; edit(b, m[2]) ; return(""+b) ; // Buffer converted to String } } else lat = (z>0.0) ? 90.0 : -90.0; } else { lon = atan2d(y, x); lat = atan2d(z, Math.sqrt(r2)); cds/astro/Astroframe.java010064400076440000132000001106210770227416100164170ustar00ferniquecds00000400000013// // Copyright 1999-2000 - Universite Louis Pasteur / Centre National de la // Recherche Scientifique // // ------ // // Address: Centre de Donnees astronomiques de Strasbourg // 11 rue de l'Universite // 67000 STRASBOURG // FRANCE // Email: question@@simbad.u-strasbg.fr // // ------- // // In accordance with the international conventions about intellectual // property rights this software and associated documentation files // (the "Software") is protected. The rightholder authorizes : // the reproduction and representation as a private copy or for educational // and research purposes outside any lucrative use, // subject to the following conditions: // // The above copyright notice shall be included. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON INFRINGEMENT, // LOSS OF DATA, LOSS OF PROFIT, LOSS OF BARGAIN OR IMPOSSIBILITY // TO USE SUCH SOFWARE. IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // For any other exploitation contact the rightholder. // // ----------- // // Conformement aux conventions internationales relatives aux droits de // propriete intellectuelle ce logiciel et sa documentation sont proteges. // Le titulaire des droits autorise : // la reproduction et la representation a titre de copie privee ou des fins // d'enseignement et de recherche et en dehors de toute utilisation lucrative. // Cette autorisation est faite sous les conditions suivantes : // // La mention du copyright portee ci-dessus devra etre clairement indiquee. // // LE LOGICIEL EST LIVRE "EN L'ETAT", SANS GARANTIE D'AUCUNE SORTE. // LE TITULAIRE DES DROITS NE SAURAIT, EN AUCUN CAS ETRE TENU CONTRACTUELLEMENT // OU DELICTUELLEMENT POUR RESPONSABLE DES DOMMAGES DIRECTS OU INDIRECTS // (Y COMPRIS ET A TITRE PUREMENT ILLUSTRATIF ET NON LIMITATIF, // LA PRIVATION DE JOUISSANCE DU LOGICIEL, LA PERTE DE DONNEES, // LE MANQUE A GAGNER OU AUGMENTATION DE COUTS ET DEPENSES, LES PERTES // D'EXPLOITATION,LES PERTES DE MARCHES OU TOUTES ACTIONS EN CONTREFACON) // POUVANT RESULTER DE L'UTILISATION, DE LA MAUVAISE UTILISATION // OU DE L'IMPOSSIBILITE D'UTILISER LE LOGICIEL, ALORS MEME // QU'IL AURAIT ETE AVISE DE LA POSSIBILITE DE SURVENANCE DE TELS DOMMAGES. // // Pour toute autre utilisation contactez le titulaire des droits. // package cds.astro ; /** * This class defines the various elements of an Astronomical Frame: * the type of frame, with its equinox when relevant (equatorial frame); * the accuracy of the coordinates for a correct edition; and one point * (an element of the Coo class) in the frame.
* This class also includes basic transformations in the various kinds * of dates used for stellar astrometry: Julian days/years, and Besselian * years. *

The typical usage of the Astroframe class consists in:

    *
  1. Define an astronomical coordinate frame by means of one of * the constructors; *
  2. Assign a position in this frame via one of the set methods *
  3. Convert to another frame via the convert method *
  4. The angles (in degrees) are best extracted via getLon and * getLat methods *
* The edition of the position in an Astroframe can be done in a StringBuffer * (ed2 methods) with options like sexagesimal or decimal edition, * or as a String with one of the available toString methods. * @@author Francois Ochsenbein, Pierre Fernique [CDS] * Constants from slaLIB (P.T. Wallace) * @@version 1.0 : 03-Mar-2000 * @@version 1.1 : 24-Mar-2000 (Bug in ICRS Edition) */ public class Astroframe { /** One point in the frame contains * lon lat x y z + dlon/dlat (decimals) */ private Coo point ; // Contains lon lat x y z + dlon/dlat (decimals) /** Equinox in Julian Years (FK5) or Besselian (FK4). * Unused for Gal, SGal, ICRS */ protected double equinox ; // Equinox in Julian Years (FK5) or Besselian /** Coordinate system is one of FK4 FK5 GAL SGAL ECL ICRS */ protected byte frame ; // Coordinate System as 1 to 6 /** The precision is 0=unknown, 1=DEG, 3=ARCMIN, 5=ARCSEC, 8=MAS, etc */ protected byte precision ; // 0 = unknown, 1=deg, 3=arcmin, 5=arcsec, 8=mas /** The original precision is the precision used at Construction. It is taken as an upper value of the precision. */ protected byte oprecision ; // Original Precision private byte status_coo ; // 0=no position, 1=angles, 2=xyz, 3=both private byte status_frame ; // 1=matrix to FK4, 2=matrix to FK5 private double[][] matrix ; // Matrix to rotate from standard FK4 or FK5 // protected byte sexa ; // Edition in SEXAgesimal or Degrees /** Definitions of Precisions for the angles */ static public final byte NONE = 0, DEG = 1, ARCMIN=3, ARCSEC=5, MAS=8 ; /** Definitions of Coordinate Frames */ static public final byte FK4 = 1, FK5 = 5, GAL = 2, SGAL = 3, SUPERGAL = 3, ECL = 4, ICRS = 6 ; /** Edition options */ static private final int ED_SIGN=0x01, ED_DECIMAL=0x10, ED_FRAME=0x80, ED_FULL=0x02, ED_SEXA = 0x20, ED_RA=0x40, ED_COLON=0x04 ; static private final int ed_opt[] = { /* FK4 Gal SGal Ecl FK5 ICRS */ 0, ED_RA, ED_DECIMAL, ED_DECIMAL, ED_DECIMAL, ED_RA, ED_DECIMAL|ED_RA } ; static final private String[] explain_frame = { /* FK4 Gal SGal Ecl FK5 ICRS */ "NONE", "FK4", "Gal", "SGal", "Ecl", "FK5", "ICRS" } ; static final private String[] explain_precision = { "unknown", "1degree", "0.1degree", "1arcmin", "0.1arcmin", "1arcsec", "0.1arcsec", "10mas", "1mas", "0.1mas", "10{mu}as", "1{mu}as", "0.1{mu}as" } ; static final double[] default_equinox = { // Default Equinoxes /* FK4 Gal SGal Ecl FK5 ICRS */ 2000.0, 1950., 0./0., 0./0., 2000.0, 2000., 0./0. } ; /* Default Equinoxes in Julian Years */ /** Value of Besselian Year in days */ static final public double Byr = 365.242198781e0 ; // Besselian Year /** Value of the Julian Year in days */ static final public double Jyr = 365.25e0 ; // Julian Year /** Julian date of J2000 epoch */ static final public double JD_J2000 = 2451545. ; // Julian Date of J2000 /** Julian date of B1950 epoch */ static final public double JD_B1900 = 2415020.31352;// Julian Date of B1900 // Rounding values for Decimal edition ... static private double gf[] = {1., 10., 100., 1.e3, 1.e4, 1.e5, 1.e6, 1.e7 } ; // ... and for sexagesimal edition static private double qf[] = {1., 10., 60., 600., .36e4, .36e5, .36e6, .36e7} ; // continues*10 /* Conversion from FK4 to FK5 -- Proper motions are in arcsec/century */ static private final double PMF = 100.*3600.*(180./Math.PI) ; /** Matrix 6x1 to compute the e-term */ static protected double[] A = { // For e-term -1.62557e-6, -0.31919e-6, -0.13843e-6, 1.245e-3, -1.580e-3, -0.659e-3 }; /* The interval B1950 and J2000 is dtB = B2J(1950.) - 2000. = -50.0012775136654 (Besselian Years) */ static private double[] A1 = { // A1[i] = A[i] + A[i+3]*dtB/PMF -1.62255e-6, -0.32302e-6, -0.14003e-6 }; /** The 6x6 matrix to move from FK4 to FK5. Only a part of this matrix systems is used here. This matrix is however totally used when proper motions are involved */ static protected double[][] EM = { // Rotation of u + v vector { 0.9999256782e0, -0.0111820611e0, -0.0048579477e0, 2.42395018e-6, -0.02710663e-6, -0.01177656e-6}, { 0.0111820610e0, 0.9999374784e0, -0.0000271765e0, 0.02710663e-6, 2.42397878e-6, -0.00006587e-6}, { 0.0048579479e0, -0.0000271474e0, 0.9999881997e0, 0.01177656e-6, -0.00006582e-6, 2.42410173e-6}, { -0.000551e0, -0.238565e0, 0.435739e0, 0.99994704e0, -0.01118251e0, -0.00485767e0}, { 0.238514e0, -0.002667e0, -0.008541e0, 0.01118251e0, 0.99995883e0, -0.00002718e0}, { -0.435623e0, 0.012254e0, 0.002117e0, 0.00485767e0, -0.00002714e0, 1.00000956e0} }; /** The 6x6 matrix to move from FK5 to FK4 */ static protected double[][] EM1 = { /* FK5 ==> FK4 */ { 0.9999256795e0, 0.0111814828e0, 0.0048590039e0, -2.42389840e-6, -0.02710544e-6, -0.01177742e-6}, { -0.0111814828e0, 0.9999374849e0, -0.0000271771e0, 0.02710544e-6, -2.42392702e-6, 0.00006585e-6}, { -0.0048590040e0, -0.0000271557e0, 0.9999881946e0, 0.01177742e-6, 0.00006585e-6, -2.42404995e-6}, { -0.000551e0, 0.238509e0, -0.435614e0, 0.99990432e0, 0.01118145e0, 0.00485852e0}, { -0.238560e0, -0.002667e0, 0.012254e0, -0.01118145e0, 0.99991613e0, -0.00002717e0}, { 0.435730e0, -0.008541e0, 0.002117e0, -0.00485852e0, -0.00002716e0, 0.99996684e0} }; /* For moving from FK4 to FK5 without proper motion, the EM50 matrix is used EM50[i][j] = EM[i][j] + EM[i+3][j]*dtB/PMF ; */ static private double EM50[][] = { { 0.9999256795356672, -0.0111814827996970, -0.0048590039655699}, { 0.0111814828233251, 0.9999374848650175, -0.0000271557959449}, { 0.0048590038843768, -0.0000271771046587, 0.9999881945682256} } ; // In B1950, the Galactic Frame is defined by // North Pole at (RA, Dec) = 192.25 +27.4 (12h49 +27d24') // longitude of ascending node = 33 deg // Matrix B1950 to Gal = Euler(asc.node-90, 90-lat(Pole), -lon(Pole)) /** Rotation matrix to move from FK4 to Galactic. */ static public final double[][] gal_1950 = { // Euler(-57, 62.6, -192.25) {-0.0669887394151508,-0.8727557658519927,-0.4835389146321842}, { 0.4927284660753235,-0.4503469580199614, 0.7445846332830311}, {-0.8676008111514348,-0.1883746017229204, 0.4601997847838516} } ; /* Constants for Galactic to SuperGalactic */ // Pole of SuperGalactic at (Glon, Glat) = 47.37 +06.32 // longitude of ascending node = 0.0 /** Rotation matrix to move from Galactic to Supergalactic. */ static public final double[][] supergal = { // Euler(-90, 83.68, -47.37) {-0.7357425748043749, 0.6772612964138942, 0.}, {-0.0745537783652337,-0.0809914713069767, 0.9939225903997749}, { 0.6731453021092076, 0.7312711658169645, 0.1100812622247821} } ; /** Rotation matrix to move from FK5 to Galactic (approximative) */ static public final double[][] gal_2000 = { {-0.054875539726e0, -0.873437108010e0, -0.483834985808e0}, { 0.494109453312e0, -0.444829589425e0, 0.746982251810e0}, {-0.867666135858e0, -0.198076386122e0, 0.455983795705e0} } ; // =========================================================== // Static Methods // =========================================================== /* Static methods (functions) in Java are very close to C ones; they do not require any object instanciation. Typical example of static methods are in the Math class */ /* Conversions of Times between B(esselian Year) / J(ulian year) / JD */ /** Conversion of a Julian epoch to a Julian Date */ public static final double J2JD(double y) { return JD_J2000 + (y-2000)*Jyr ; } /** Conversion of a Besselian epoch to a Julian Date */ public static final double B2JD(double y) { return JD_B1900 + (y-1900)*Byr ; } /** Conversion of a Julian Date to a Julian epoch */ public static final double JD2J(double jd) { return 2000 + (jd-JD_J2000)/Jyr ; } /** Conversion of a Julian Date to a Besselian epoch */ public static final double JD2B(double jd) { return 1900 + (jd-JD_B1900)/Byr ; } /** Conversion of a Besselian epoch to a Julian epoch */ public static final double B2J(double y) { return JD2J(B2JD(y)) ; } /** Conversion of a Julian epoch to a Besselian epoch */ public static final double J2B(double y) { return JD2B(J2JD(y)) ; } // =========================================================== // Private Methods // =========================================================== /** Generate the rotation matrix from the Euler angles * @@param z, theta, zeta the 3 Euler angles * @@return R[3][3] the rotation matrix * The rotation matrix is defined by: * $$ R = R_z(-z) \cdot R_y(\theta) \cdot R_z(-\zeta)$$ |cos.z -sin.z 0| |cos.the 0 -sin.the| |cos.zet -sin.zet 0| = |sin.z cos.z 0| x | 0 1 0 | x |sin.zet cos.zet 0| | 0 0 1| |sin.the 0 cos.the| | 0 0 1| */ static private double[][] EulerMatrix(double z, double theta, double zeta) { double R[][] = new double[3][3]; R[0][2] = Coo.cosd(z); R[1][2] = Coo.sind(z); R[2][2] = Coo.cosd(theta); double w = Coo.sind(theta) ; R[2][0] = Coo.cosd(zeta); R[2][1] = Coo.sind(zeta); R[0][0] = R[2][0]*R[2][2]*R[0][2] - R[2][1]*R[1][2]; R[1][0] = R[2][0]*R[2][2]*R[1][2] + R[2][1]*R[0][2]; R[0][1] = -R[2][1]*R[2][2]*R[0][2] - R[2][0]*R[1][2]; R[1][1] = -R[2][1]*R[2][2]*R[1][2] + R[2][0]*R[0][2]; R[2][0] = R[2][0]*w; R[2][1] = -R[2][1]*w; R[0][2] = -w*R[0][2]; R[1][2] = -w*R[1][2]; //* System.err.println("Compute tR . R ") ; //* System.err.println(Coo.toString(Coo.prod(Coo.t(R), R))) ; return(R) ; } /** Fill the object: compute the angles, or cosines * whatever is missing in the object */ private void fill_coo() { if (status_coo == 0) { System.err.println ("++++Astroframe[" + getFrame() + "]: non-set position, North Pole assumed") ; point.x = 0 ; point.y = 0 ; point.z = 1 ; status_coo = 2 ; } if ((status_coo&2) == 0) { // Compute the ux,uy,uz point.set(point.lon, point.lat) ; status_coo |= 2 ; } if ((status_coo&1) == 0) { // Compute lon,lat point.set(point.x, point.y, point.z) ; status_coo |= 1 ; } } /** Fill the object: compute the matrix which transforms the current * coordinate system into standard FK4 or FK5 * @@param choice 1 prefer B1950, 2 to prefer J2000 *
* Note that the absence of a rotation matrix implies a Unit Matrix */ private void fill_frame (int choice) { double w, z, zeta, theta, t0, dt ; switch(frame) { case FK4: status_frame = 1 ; // Indicates change to B1950. if (equinox == 1950.) { if (matrix != null) matrix = null ; return ; } t0 = (1950.0 - 1900.0)/1000.0; dt = (equinox - 1950.0)/1000.0 ; zeta = dt*(23042.53e0+ t0*(139.73e0+0.06e0*t0) + dt*(30.23e0+18.e0*dt-0.27e0*t0) ) /3600.e0; z = zeta + dt*dt*(79.27e0+0.66e0*t0+0.32e0*dt)/3600.e0; theta = dt* (20046.85e0 - t0*(85.33e0+0.37*t0) - dt*(42.67e0+0.37e0*t0+41.8e0*dt) )/3600.e0; matrix = EulerMatrix(z, theta, zeta) ; break ; case ICRS: equinox = 2000. ; // NO BREAK case FK5: status_frame = 2 ; // Indicates change to J2000. if (equinox == 2000.) { if (matrix != null) matrix = null ; return ; } t0 = 0 ; dt = (equinox - 2000.0)/100.e0; w = 2306.2181e0+(1.39656e0-0.000139e0*t0)*t0; // w in arcsec zeta = (w + ( (0.30188e0-0.000344e0*t0) + 0.017998e0*dt) *dt) *dt/3600.e0; // Degrees z = (w + ( (1.09468e0+0.000066e0*t0) + 0.018203e0*dt) *dt) *dt/3600.e0; // Degrees theta = ( (2004.3109e0 + (-0.85330e0-0.000217e0*t0)*t0) +( (-0.42665e0-0.000217e0*t0) - 0.041833e0*dt) *dt) * dt/3600.e0; matrix = EulerMatrix(z, theta, zeta) ; break ; case GAL: if (matrix == null) matrix = new double[3][3] ; if (choice == 1) { System.arraycopy(gal_1950, 0, matrix, 0, gal_1950.length) ; status_frame = 1 ; // Indicates change to B1950 } else { System.arraycopy(gal_2000, 0, matrix, 0, gal_2000.length) ; status_frame = 2 ; // Indicates change to J2000 } break ; case SGAL: if (choice == 1) { status_frame = 1 ; // Indicates change to B1950. matrix = Coo.prod (supergal, gal_1950) ; } else { status_frame = 2 ; // Indicates change to J2000. matrix = Coo.prod (supergal, gal_2000) ; } break ; default: throw new IllegalArgumentException( "****Astroframe: frame not (yet) accepted: " + getFrame()) ; } //* System.err.println("fill_frame(" + choice + ") on " + getFrame()) ; //* System.err.println(Coo.toString(matrix)) ; } /* Compute FK5 position from FK4, assuming no proper motion in FK5 and an observation in B1950 */ private double[] fk4to5z(double u[]) { double w, r, u0, u1, u2 ; double fk5[] = new double[3] ; // System.err.println("....fk4to5z: Cartesian: " + Coo.toString(u)) ; w = 50.; w = u[0]*A[0] + u[1]*A[1] + u[2]*A[2] ; // e-term // System.err.println("....fk4to5z: w=" + w) ; //* Remove e-term **** Warning, using w1 = 1.+w looses precision ! u0 = u[0] - A[0] + w*u[0]; //u[0]*w1 - A[0] ; u1 = u[1] - A[1] + w*u[1]; //u[1]*w1 - A[1] ; u2 = u[2] - A[2] + w*u[2]; //u[2]*w1 - A[2] ; // System.err.println("....fk4to5z: A : " + Coo.toString(A)) ; // fk5[0] = u0; fk5[1] = u1; fk5[2] = u2; // System.err.println("....fk4to5z: Removed e: " + Coo.toString(fk5)) ; //* Modifications ------------- // Renormalize the Unit Vector /**** This NEW Method just uses EM50 *********/ fk5[0] = EM50[0][0]*u0 + EM50[0][1]*u1 + EM50[0][2]*u2 ; fk5[1] = EM50[1][0]*u0 + EM50[1][1]*u1 + EM50[1][2]*u2 ; fk5[2] = EM50[2][0]*u0 + EM50[2][1]*u1 + EM50[2][2]*u2 ; /******************************************/ return(fk5) ; } /* Compute FK4 position from FK5, assuming no proper motion in FK5 and an observation in B1950. */ private double[] fk5to4z(double u[]) { double w, w1, r, v0, v1, v2 ; double fk4[] = new double[3] ; //* System.err.println("....fk5to4z called") ; // 6-vector Rotation. The velocity is zero. v0 = EM1[0][0]*u[0] + EM1[0][1]*u[1] + EM1[0][2]*u[2] ; v1 = EM1[1][0]*u[0] + EM1[1][1]*u[1] + EM1[1][2]*u[2] ; v2 = EM1[2][0]*u[0] + EM1[2][1]*u[1] + EM1[2][2]*u[2] ; // Renormalize the Unit Vector r = Math.sqrt(v0*v0 + v1*v1 + v2*v2) ; v0 /= r ; v1 /= r ; v2 /= r ; // Apply e-term w = v0*A[0] + v1*A[1] + v2*A[2] ; // e-term w1 = 1 - w ; //* Remove e-term (approximative) /* ======== Old Code fk4[0] = v0*w1 + A[0]*r ; fk4[1] = v1*w1 + A[1]*r ; fk4[2] = v2*w1 + A[2]*r ; // recompute norm r = Math.sqrt(fk4[0]*fk4[0] + fk4[1]*fk4[1] + fk4[2]*fk4[2]) ; //* Remove e-term (correct) fk4[0] = v0*w1 + A[0]*r ; fk4[1] = v1*w1 + A[1]*r ; fk4[2] = v2*w1 + A[2]*r ; ===========*/ fk4[0] = v0*w1 + A[0] ; fk4[1] = v1*w1 + A[1] ; fk4[2] = v2*w1 + A[2] ; return(fk4) ; } /** Round the value * @@param angle Angle (degrees) to edit * @@param precision The precision * @@param sexa true if sexagesimal * @@returns Rounded value */ static private double rounded (double angle, int precision, double gf[]) { int nd = precision - 1; double f = angle ; double rf ; int i ; /* Round the Longitude / Latitude */ if (nd < gf.length) rf = gf[nd] ; else { i = nd-gf.length; rf = gf[gf.length-1]; while (i >= 0) { rf *= 10; i-- ; } } if (angle < 0) rf = -rf ; f = angle + 0.5/rf ; if (f < -180.0) f += 360.0 ; if (f >= 360.0) f -= 360.0 ; return(f) ; } /** Edit a Longitude or Latitude with the specified precision. * Rounding is executed. * @@param buf Buffer where the edited value is added * @@param angle Angle (degrees) to edit * @@param precision The precision of the coordinate * @@param opt One of the options ED_xxx * @@returns Number of bytes filled */ static private int ed1(StringBuffer buf, double angle, int precision, int opt) { int nd = precision - 1; int len0 = buf.length() ; int ival, n ; char sep ; double f; // System.err.println("....ed1(" + angle + ", opt=" // + Integer.toHexString(opt) + ")") ; /* Round the Longitude / Latitude */ f = angle ; if ((opt&ED_FULL) == 0) f = rounded(angle, precision, (opt&ED_SEXA)!=0 ? qf : gf) ; else nd = 10 ; // give 10 digits for full precision /* For a decimal number, just edit */ if (((opt&ED_SEXA) == 0) || (precision < ARCMIN)) return Coo.ed1(buf, f, nd+4, nd, (opt&ED_SIGN)!=0) ; /* Separator may be a blank or a colon */ sep = (opt&ED_COLON) != 0 ? ':' : ' ' ; /* RA: must divide by 15 */ if ((opt&ED_RA)!=0) { precision++ ; f = angle/15. ; if ((opt&ED_FULL)==0) f = rounded(f, precision, qf) ; } /* Edit the sign */ if (((opt&ED_SIGN)!=0) && (f>=0)) buf.append('+') ; if (f<0) { buf.append('-'); f = -f ; } /* Insert the degrees/hours: insert leading zeroes... */ ival = (int)f; f -= ival ; n = 1000 ; if ((opt&(ED_SIGN|ED_RA))!=0) n = 100 ; if(ival >= n) { buf.append(ival/n); ival %= n; } while(n>1) { n /= 10; buf.append((char)('0' + ival/n)); ival %= n; } /* Edit the minutes */ f *= 60.; ival = (int)f ; f -= ival ; buf.append(sep) ; buf.append((char)('0' + ival/10)); buf.append((char)('0' + ival%10)); if (precision == ARCMIN+1) { f *= 10; ival = (int)f; buf.append('.'); buf.append((char)('0' + ival)) ; } /* Edit the seconds */ if (precision >= ARCSEC) { buf.append(sep) ; f *= 60.; n = precision-ARCSEC ; // Number of decimals Coo.ed1(buf, f, n==0 ? 2 : n+3, n, false) ; } return(buf.length() - len0) ; } // =========================================================== // Constructors // =========================================================== /** Create an Astroframe objet: specify just frame, equinox, precision. * Actual positions are normally specified by the set method. * @@param frame FK4|FK5|ICRS|GAL|SGAL|ECL * @@param precision NONE|DEG|ARCMIN|ARCSEC|MAS [default ARCSEC+1] * @@param equinox The equinox (applicable for FK4 FK5 ECL frames) */ public Astroframe(int frame, int precision, double equinox) { this (frame, 0., 90., precision, equinox) ; this.status_coo = 0 ; } /** Create a fully qualified position in a new Astroframe objet. * @@param frame FK4|FK5|ICRS|GAL|SGAL|ECL * @@param lon, lat A position expressed in the frame * @@param precision NONE|DEG|ARCMIN|ARCSEC|MAS [default ARCSEC+1] * @@param equinox The equinox (applicable for FK4 FK5 ECL only) */ public Astroframe(int frame, double lon, double lat, int precision, double equinox) { if (Double.isNaN(equinox)) this.equinox = default_equinox[frame] ; else this.equinox = equinox ; this.point = new Coo(lon, lat) ; this.status_coo = 3 ; this.equinox = equinox ; this.frame = (byte)frame ; this.oprecision= (byte)precision ; this.precision = this.oprecision ; } /** Create an Astroframe objet with default precision (0.1arcsec) * @@param frame FK4|FK5|ICRS|GAL|SGAL|ECL * @@param equinox The equinox (applicable for FK4 FK5 ECL only) */ public Astroframe(int frame, double equinox) { this(frame, ARCSEC+1, equinox) ; } /** Create an Astroframe objet with default equinox. * We specify in this creation the frame, * @@param frame FK4|FK5|ICRS|GAL|SGAL|ECL * @@param precision NONE|DEG|ARCMIN|ARCSEC|MAS [default ARCSEC] */ public Astroframe(int frame, int precision) { this(frame, precision, default_equinox[frame]) ; } /** Create an Astroframe objet, for the standard equinox. * We specify in this creation the frame, * @@param frame FK4|FK5|ICRS|GAL|SGAL|ECL */ public Astroframe(int frame) { this(frame, ARCSEC+1, default_equinox[frame]) ; } /** Create the default J2000 Astroframe */ public Astroframe() { this(FK5, ARCSEC+1, 2000.) ; } // =========================================================== // Set a position in Astroframe // =========================================================== /** Set a particuliar set of positions in the Astroframe. * @@param lon,lat Longitude + latitude in degrees (or RA + Dec) */ public void set (double lon, double lat) { point.lon = lon ; point.lat = lat ; status_coo = 1 ; } /** Set a particuliar set of positions in the Astroframe from Cartesian * @@param lon,lat Longitude + latitude in degrees (or RA + Dec) */ public void set (double x, double y, double z) { point.x = x ; point.y = y ; point.z = z ; status_coo = 2 ; } /** Set a particuliar set of positions in the Astroframe. * The precision is adapted to the number of significant digits * existing in the input text string. * @@param text Longitude + latitude in text */ public void set (String text) throws Exception { point.set(text, (ed_opt[frame]&ED_RA)!=0) ; status_coo = 3 ; // Set Precision = number of decimals + 1. precision = (byte)(1 + (point.dlon > point.dlat ? point.dlon : point.dlat)) ; // System.err.println("...set: precision=" + precision // + ", point precisions=(" + point.dlon + "," + point.dlat + ")") ; } /** Change the precision of the data * @@param precision: integer number, typically one of the values NONE (0), * DEG (1), ARCMIN (3), ARCSEC (5), MAS (8); * use ARCSEC+1 for 0.1arcsec, MAS-1 for 10mas, etc... */ public void setPrecision(int precision) { this.precision = (byte)precision ; } // =========================================================== // Get parts of Astroframe // =========================================================== /** Get an explicit designation of the frame * @@return the explanation as a string */ public final String getFrame() { switch(frame) { case FK4: return ("B" + equinox) ; case FK5: return ("J" + equinox) ; case ICRS: return ("ICRS") ; case ECL: return ("Ecl" + equinox) ; default: return explain_frame[frame] ; } } /** Get the precision of the current value * @@return the value. */ public final int getPrecision() { return precision ; } /** Get a 3-item vector with Cartesian components (x, y, z) * @@return the vector with Cartesian coordinates */ public double[] getUvector() { double u[] = new double[3] ; if ((status_coo&2) == 0) fill_coo() ; u[0] = point.x ; u[1] = point.y ; u[2] = point.z ; return(u) ; } /** Get a 2-item vector with (lon, lat) * @@return the vector with angles in degrees */ public double[] getAngles() { double o[] = new double[2] ; if ((status_coo&1) == 0) fill_coo() ; o[0] = point.lon ; o[1] = point.lat ; return(o) ; } /** Get the longitude part * @@return the longitude in degrees *
The longitude is also accessible in the object (lon) */ public double getLon() { if ((status_coo&1) == 0) fill_coo() ; return(point.lon) ; } /** Get the latitude part * @@return the latitude in degrees *
The latitude is also accessible in the object (lat) */ public double getLat() { if ((status_coo&1) == 0) fill_coo() ; return(point.lat) ; } // =========================================================== // Edit the Coordinates // =========================================================== /* Convert the String of options into an integer */ private static int getOptions(String text) throws Exception { char b[] = text.toCharArray(); int i, n; int o = 0 ; for (i=0, n=b.length; i 0) { if (len<8) len = 8 ; // Minimal accuracy llat = len/2 ; llon = len - llat ; } else llon = llat = 0 ; /* Edit in Decimal or Sexagesimal ? If not specified, use default */ if ((option&(ED_DECIMAL|ED_SEXA)) == 0) option |= ed_opt[frame]&(ED_DECIMAL|ED_RA) ; if ((option&ED_DECIMAL)!=0) { option &= ~(ED_SEXA|ED_RA) ; if ((len > 0) && (precision > (llat-3))) precision = llat-3 ; n = ed1 (buf, point.lon, precision, option) ; // Edit Lon if (llon == 0) buf.append(' ') ; else while (n < llon) { buf.append(' ') ; n++ ; } n = ed1 (buf, point.la