import java.applet.* ; import java.awt.* ; import java.awt.image.* ; import java.net.*; import java.io.*; import java.io.Reader.*; import java.io.InputStreamReader.*; import java.awt.Component.*; //import java.io.InputStream; //import java.lang.Runtime; //import javax.swing.*; // I took a very simple drawing program and extended it to making // rubberband selections of map regions. // Now I need to choose a non-blank background to draw over. public class Rubberband extends Applet { private int startx, starty ; // start of line private int lastx, lasty ; // last points of line (so far) //private int usePoly; private String polygonfile = "0"; private String selectedStations; private boolean newflag; private int XMAX,YMAX,XMIN,YMIN; private double RX1,RX2,RY1,RY2,TOPY; private int YADJ; private double center, oldcenter; private boolean zoomedIn; private boolean polygonMode; private int numverts; private int MAXVERTS = 25; private int xlist[] = new int[MAXVERTS]; private int ylist[] = new int[MAXVERTS]; private String gif = "test.gif"; Graphics g ; // graphics for drawing Image offscreen; Graphics offscreen_g; Image ourmap, drawme, worldmap; ImageObserver pic; MediaTracker tracker = new MediaTracker(this); Label clabel; TextField ctext; Font bigfont = new Font("TimesRoman",Font.BOLD,20); Font debugfont = new Font("TimesRoman",Font.ITALIC,10); Font oldfont; Choice stations,centerOn; String oldstations; String selectedData; String worldstations; BorderLayout bl; GridBagLayout gbl; GridBagConstraints gbc; Button clearbutton; Button pvpbutton; Panel rightpanel; public void init() { this .setBackground(Color.white); polygonMode = false; bl = new BorderLayout(1,1); setLayout(bl); Panel p = new Panel(); add("North",p); Panel p2 = new Panel(); p2.setLayout(new BorderLayout(1,1)); add("East",p2); Panel p3 = new Panel(); p3.setLayout(new GridLayout(5,1,5,5)); p3.add(new Label("Current Mode:")); Button b = new Button("Box Mode"); p3.add(b); p3.add(clearbutton = new Button("Clear Selection")); b = new Button("Use Stations"); p3.add(b); p2.add("North",p3); p2.add("South",pvpbutton = new Button("PvP Plots")); p2.validate(); pvpbutton.show(false); rightpanel = p2; startx = -1; g = this .getGraphics() ; p.add(new Button("Reset Map")); p.add(new Button("Zoom In")); p.add(clabel = new Label(" Center On:")); center = 0.0; oldcenter = 0.0; zoomedIn = false; centerOn = new Choice(); p.add(centerOn); centerOn.addItem("180'"); centerOn.addItem("135' W"); centerOn.addItem("90' W"); centerOn.addItem("45' W"); centerOn.addItem("0'"); centerOn.select("0'"); centerOn.addItem("45' E"); centerOn.addItem("90' E"); centerOn.addItem("135' E"); centerOn.addItem("180'"); p.add(new Label(" Show:")); p.add(stations = new Choice()); stations.addItem("WOCE CTD"); stations.addItem("WOCE BOT"); stations.addItem("WOCE BOTH"); stations.addItem("None"); oldstations = stations.getSelectedItem(); worldstations = oldstations; newflag = false; worldmap = myGetImage("world0.gif"); drawme = worldmap; offscreen = createImage(size().width,size().height); offscreen_g = offscreen.getGraphics(); offscreen_g.drawImage(drawme,0,0,this); TOPY = 0.0; // What the 'top' of the map should be. // could be 90.0, 0.0, or even -30.0. XMAX = -1; YMAX = -1; YADJ = 38; RX1 = -180.0; RX2 = 180.0; RY1 = -90.0; RY2 = TOPY; } public boolean action(Event e, Object arg) { if (e.target instanceof Choice) { if (e.target == stations) { String ns = stations.getSelectedItem(); if (ns.equals(oldstations)) return true; oldstations = ns; String R = RX1+"/"+RX2+"/"+RY1+"/"+RY2; String A = anotinterval(RX1,RX2,RY1,RY2); ns = ns.replace(' ','_'); //working(); //String location; if (zoomedIn) { //String location = "http://deacon.tamu.edu/cgi-bin/zoomtest.csh?"+R+"/"+A+"/"+ns+"/"+usePoly; String location = "http://deacon.tamu.edu/cgi-bin/zoomtest.csh?"+R+"/"+A+"/"+ns+"/"+polygonfile; URL url = null; URLConnection conn = null; String ref = null; try { url = new URL(location); conn = url.openConnection(); InputStream cx = conn.getInputStream(); InputStreamReader inx = new InputStreamReader(cx); BufferedReader in = new BufferedReader(inx); while (ref == null || ref.compareTo("Done!") != 0) { ref = in.readLine(); if (ref.equals("GIFNAME:")) { gif = in.readLine(); } if (ref.equals("TMPNAME:")) { selectedStations = in.readLine(); } } in.close(); if (ourmap != null) ourmap.flush(); ourmap = myGetImage(gif); drawme = ourmap; clabel.show(false); //ctext.show(false); centerOn.show(false); repaint(); } catch (Exception err) { System.err.println(err); } } else { worldstations = oldstations; String location = "http://deacon.tamu.edu/cgi-bin/zoom1.csh?"+R+"/"+ns; URL url = null; URLConnection conn = null; String ref = null; try { url = new URL(location); conn = url.openConnection(); InputStream cx = conn.getInputStream(); InputStreamReader inx = new InputStreamReader(cx); BufferedReader in = new BufferedReader(inx); while (ref == null || ref.compareTo("Done!") != 0) { ref = in.readLine(); } in.close(); if (worldmap != null) worldmap.flush(); worldmap = myGetImage("world.gif"); //startx = -1; drawme = worldmap; repaint(); } catch (Exception err) { debuging(err.toString()); System.err.println(err); } return true; } } else { //Okay, they're changing the center degree. String centerstr = centerOn.getSelectedItem(); String f = null; oldcenter = center; if (centerstr.equals("0'")) { f = "world0.gif"; center =0.0; } if (centerstr.equals("45' E")) { f = "world45.gif";center =45.0; } if (centerstr.equals("90' E")) { f = "world90.gif";center =90.0; } if (centerstr.equals("135' E")) {f = "world135.gif";center =135.0; } if (centerstr.equals("180'")) {f = "world180.gif";center =180.0; } if (centerstr.equals("45' W")) {f = "world-45.gif";center =-45.0; } if (centerstr.equals("90' W")) {f = "world-90.gif";center =-90.0; } if (centerstr.equals("135' W")) {f = "world-135.gif";center =-135.0; } if (center == oldcenter) return true; working(); RX1 = center-180.0; RX2 = center+180.0; startx = -1; numverts = 0; if (f != null) { if (worldmap!=null) worldmap.flush(); worldmap = myGetImage(f); //worldmap = myGetImage("world0.gif"); drawme = worldmap; repaint(); } return true; } } if (e.target instanceof TextField) { TextField ee = (TextField)e.target; try { double c = center; c = (Double.valueOf(ee.getText())).doubleValue(); //Grr they hid that command //sscanf(c,"%D",ee.getText()); //c = ee.getText().doubleValue(); if (c < -180.0 || c > 180.0) { ee.setText(""+center); return true; } if (c == center) return true; working(); ee.setText(""+c); oldcenter = center; center = c; RX1 = RX1 + center-oldcenter; RX2 = RX2 + center-oldcenter; String R = RX1+"/"+RX2+"/"+RY1+"/"+RY2; String sta = stations.getSelectedItem(); sta = sta.replace(' ','_'); String location = "http://deacon.tamu.edu/cgi-bin/zoom1.csh?"+R+"/"+sta; URL url = null; URLConnection conn = null; String ref = null; try { url = new URL(location); conn = url.openConnection(); /// Okay, it looks like at this point it's actually opened /// and run the CGI script. Since there isn't actually any /// output, we should be done. //ourmap = getImage(getDocumentBase(),"test.gif"); //InputStreamReader inx = new InputStreamReader(System.in); InputStream cx = conn.getInputStream(); InputStreamReader inx = new InputStreamReader(cx); BufferedReader in = new BufferedReader(inx); while (ref == null || ref.compareTo("Done!") != 0) { ref = in.readLine(); } in.close(); if (worldmap != null) worldmap.flush(); worldmap = myGetImage("world.gif"); startx = -1; drawme = worldmap; repaint(); } catch (Exception err) { System.err.println(err); } } catch (Exception err) { System.err.println(err); System.out.println("Bad input value "+ee.getText()+"."); ee.setText(""+center); } } if (e.target instanceof Button) { if (((String)arg).equals("Use Stations")) { int i; if (startx == -1) { numverts = 4; xlist[0] = XMIN; xlist[1] = XMAX; xlist[2] = XMAX; xlist[3] = XMIN; ylist[0] = YMIN; ylist[1] = YMIN; ylist[2] = YMAX; ylist[3] = YMAX; } else { if (!polygonMode && startx != lastx && starty != lasty) { numverts = 4; xlist[0] = startx; xlist[1] = lastx; xlist[2] = lastx; xlist[3] = startx; ylist[0] = starty; ylist[1] = starty; ylist[2] = lasty; ylist[3] = lasty; } } // At this point we need to write the polygon out. // If there is no polygon, we've created a temporary one. String s = "# Polygon file\nX\n"; for (i=0; i < numverts; i++) { s = s + (xtor(xlist[i]))+" "+(ytor(ylist[i]))+"\n"; } s = s + (xtor(xlist[0]))+" "+(ytor(ylist[0]))+"\n"; sendData(s); // Call the 'zoom' button. zoomIn(xtor(XMIN),xtor(XMAX),ytor(YMIN),ytor(YMAX)); pvpbutton.show(true); rightpanel.validate(); return true; } if (((String)arg).equals("PvP Plots")) { // First, we must call make_tempdata.py. // Actually, I've replaced it with make_tempdata.pl because Perl is much // faster than Python for text manipulation. message("Creating PvP Table - Please Wait"); String location = "http://deacon.tamu.edu/cgi-bin/make_tempdata.pl?infile="+selectedStations; URL url = null; URLConnection conn = null; String ref = null; String tmpfile = null; try { url = new URL(location); conn = url.openConnection(); InputStream cx = conn.getInputStream(); InputStreamReader inx = new InputStreamReader(cx); BufferedReader in = new BufferedReader(inx); while (ref == null || ref.compareTo("Done!") != 0) { ref = in.readLine(); if (ref.equals("TMPFILE:")) { tmpfile = in.readLine(); System.out.println("Tmpfile="+tmpfile); } if (ref.equals("INFILE:")) { ref = in.readLine(); } } in.close(); //if (ourmap != null) ourmap.flush(); //ourmap = myGetImage(gif); //drawme = ourmap; clabel.show(false); //ctext.show(false); centerOn.show(false); repaint(); } catch (Exception err) { System.err.println(err); } location = "http://deacon.tamu.edu/cgi-bin/my_pvp.py?DATA="+tmpfile+"&BASEMAP="+gif; try { url = new URL(location); getAppletContext().showDocument(url,"MyPvP"); } catch (Exception err) { System.err.println(err); } return true; } if (((String)arg).equals("Polygon Mode")) { polygonMode = false; startx = -1; ((Button)e.target).setLabel("Box Mode"); //clearbutton.setLabel("Clear Selection"); repaint(); } if (((String)arg).equals("Box Mode")) { polygonMode = true; startx = -1; ((Button)e.target).setLabel("Polygon Mode"); //clearbutton.setLabel("Clear Selection"); repaint(); } //if (((String)arg).equals("Clear Selection")) { // startx = -1; // repaint(); //} if (((String)arg).equals("Zoom In")) { double x1,x2,y1,y2,z; int rc,i; Process p; Runtime r; // Must calculate -R, then call cgi-script to zoom in. if (polygonMode) { if (numverts < 3) return false; startx = 10000; lastx = -10000; starty = 10000; lasty = -10000; for (i=0;i lastx) lastx = xlist[i]; if (ylist[i] < starty) starty = ylist[i]; if (ylist[i] > lasty) lasty = ylist[i]; } } else { if (startx == -1) return false; } if (startx == lastx || starty == lasty) return false; //ourmap.flush(); x1 = (double)(startx - XMIN) / (double)(XMAX-XMIN); x1 = (double)x1 * (RX2-RX1) + (double)RX1; x2 = (double)(lastx - XMIN) /(double)(XMAX-XMIN); x2 = (double)x2 * (RX2-RX1) + (double)RX1; y1 = (double)(starty - YMIN) / (double)(YMAX-YMIN); y1 = (double)(1.0-y1) * (RY2-RY1) + RY1; y2 = (double)(lasty - YMIN) / (double)(YMAX-YMIN); y2 = (double)(1.0-y2) * (RY2-RY1) + RY1; //y1 = -y1; //y2 = -y2; if (x1 > x2) { z=x1; x1=x2; x2=z; } if (y1 > y2) { z=y1; y1=y2; y2=z; } // Now call "test.csh x1/x2/y1/y2" //String location = "http://deacon.tamu.edu/cgi-bin/zoomtest.csh"; // Okay, the basics are working... now I need to calculate an appropriate // Anotation Interval such that we ALWAYS get 5-10 annotations. String R = x1+"/"+x2+"/"+y1+"/"+y2; String A = anotinterval(x1,x2,y1,y2); String ns = oldstations; ns = ns.replace(' ','_'); //String location = "http://deacon.tamu.edu/cgi-bin/zoomtest.csh?"+R+"/"+A+"/"+ns+"/"+usePoly; String location = "http://deacon.tamu.edu/cgi-bin/zoomtest.csh?"+R+"/"+A+"/"+ns+"/"+polygonfile; URL url = null; URLConnection conn = null; String ref = null; working(); try { zoomedIn = true; url = new URL(location); conn = url.openConnection(); /// Okay, it looks like at this point it's actually opened /// and run the CGI script. Since there isn't actually any /// output, we should be done. //ourmap = getImage(getDocumentBase(),"test.gif"); //InputStreamReader inx = new InputStreamReader(System.in); InputStream cx = conn.getInputStream(); InputStreamReader inx = new InputStreamReader(cx); BufferedReader in = new BufferedReader(inx); while (ref == null || ref.compareTo("Done!") != 0) { ref = in.readLine(); if (ref.equals("GIFNAME:")) { gif = in.readLine(); } if (ref.equals("TMPNAME:")) { selectedStations = in.readLine(); } } in.close(); //offscreen.invalidate(); //ourmap.invalidate(); //for (rc=1;rc<100000;rc++) { } if (ourmap != null) ourmap.flush(); ourmap = myGetImage(gif); //imageUpdate(ourmap,ALLBITS,0,0,0,0); RX1 = x1; RX2 = x2; RY1 = y1; RY2 = y2; if (polygonMode) { for (i=0;i XMAX) x = XMAX; if (x < XMIN) x = XMIN; if (y > YMAX) y = YMAX; if (y < YMIN) y = YMIN; //if (x > XMAX || x < XMIN) return false; //if (y > YMAX || y < YMIN) return false; if (polygonMode) { if (startx == -1) { startx = x; starty = y; numverts = 1; xlist[0] = startx; ylist[0] = starty; } else if (numverts < MAXVERTS-1) { numverts = numverts + 1; xlist[numverts-1] = x; ylist[numverts-1] = y; } } else { startx = x ; starty = y; lastx = startx ; lasty = starty ; newflag = false; } repaint(); return true ; } /* This subroutine writes data out to a special CGI file. */ private void sendData(String s) { try { URL url = new URL("http","deacon.tamu.edu","/cgi-bin/write_polygon.pl"); URLConnection con = url.openConnection(); con.setDoOutput(true); con.setDoInput(true); con.setUseCaches(false); con.setRequestProperty("Content-type", "text/plain"); con.setRequestProperty("Content-length", s.length()+""); PrintStream out = new PrintStream(con.getOutputStream()); out.print(s); out.flush(); out.close(); DataInputStream in = new DataInputStream(con.getInputStream()); String ss; polygonfile = ""; while ((ss = in.readLine()) != null) { polygonfile = ss; } System.out.println("Polygonfile = "+polygonfile); in.close(); } catch (Exception err) { System.err.println(err); } } public void paint(Graphics g) { while (XMAX < 0 || YMAX < 0) set_minmax(); offscreen_g.setColor(Color.white); //offscreen_g.fillRect(0,0,size().width-1,size().height-1); offscreen_g.fillRect(0,0,XMAX,YMAX); offscreen_g.setColor(Color.black); offscreen_g.drawImage(drawme,0,0,this); if (startx > -1 && !polygonMode) { int x1,y1,x2,y2,z; //offscreen_g.setColor(Color.black); x1 = startx; x2 = lastx; y1 = starty; y2 = lasty; if (x1 > x2) { z = x1; x1 = x2; x2 = z; } if (y1 > y2) { z = y1; y1 = y2; y2 = z; } offscreen_g.drawRect(x1,y1,x2-x1,y2-y1); //offscreen_g.drawString("WORKING...",(XMAX-XMIN)/2+XMAX,(YMAX-YMIN)/2+YMIN); } if (polygonMode && startx > -1) { offscreen_g.drawPolygon(xlist,ylist,numverts); int i; for (i = 0; i < numverts; i++) { offscreen_g.drawOval(xlist[i]-2,ylist[i]-2,4,4); } //if (numverts == 1) offscreen_g.drawOval(startx,starty,3,3); } g.drawImage(offscreen,0,YADJ,this); } public void update(Graphics g) { paint(g); } public void set_minmax() { int xedge = 39; int yedge = 21; XMIN = xedge; YMIN = yedge; XMAX = worldmap.getWidth(pic)-xedge; YMAX = worldmap.getHeight(pic)-yedge; } public String anotinterval(double X1,double X2,double Y1,double Y2) { // Return the annotation interval to be used. // Also append the size of the dots to draw. String anot; double z; double dx = X2 - X1; double dy = Y2 - Y1; double ddx = dx / 9.0; double ddy = dy / 9.0; double sz; if (ddx > 1.0) { ddx = Math.round(ddx); z = ddx / 5.0; z = Math.round(z) * 5.0; if (z >= 5.0) ddx = z; } else { //ddx = ddx * 2.0; ddx = 1.0; } if (ddy > 1.0) { ddy = Math.round(ddy); z = ddy / 5.0; z = Math.round(z) * 5.0; if (z >= 5.0) ddy = z; } else { //ddy = ddy * 2.0; ddy = 1.0; } sz = 0.01; z = 360.0/dx; if (180.0/dy < z) z = 180.0/dy; sz = sz * z; sz = Math.round(sz * 100)/100.0; return ddx+"/"+ddy+"/"+sz; } public void working() { int x=0,y=0; String text = "WORKING..."; oldfont = g.getFont(); g.setFont(bigfont); FontMetrics xx = g.getFontMetrics(); //x = FontMetrics.stringWidth(text); x = xx.stringWidth(text); y = xx.getHeight(); while (XMAX < 0 || YMAX < 0) set_minmax(); x = (XMAX-XMIN)/2 + XMIN - x/2; y = (YMAX-YMIN)/2 + YMIN + y; g.drawString(text,x,y); g.setFont(oldfont); return; } public void debuging(String text) {//throws IOException { //File debugfile = new File("ddd"); //FileOutputStream debugstream1 = new FileOutputStream(debugfile); //DataOutputStream debugstream = new DataOutputStream(debugstream1); int x=0,y=0; oldfont = g.getFont(); g.setFont(debugfont); FontMetrics xx = g.getFontMetrics(); //x = xx.stringWidth(text); y = xx.getHeight(); while (XMAX < 0 || YMAX < 0) set_minmax(); //x = (XMAX-XMIN)/2 + XMIN - x/2; y = (YMAX-YMIN)/2 + YMIN + y; g.drawString(text,x,y); g.setFont(oldfont); //if(!debugstream.canWrite()) throw FileCopyException("file can not write"); //debugstream.writeChars(text); //debugstream.close(); //debugstream1.close(); return; } public void message(String str) { int x=0,y=0; //String text = "WORKING..."; oldfont = g.getFont(); g.setFont(bigfont); //x = FontMetrics.stringWidth(text); FontMetrics xx = g.getFontMetrics(); x = xx.stringWidth(str); y = xx.getHeight(); while (XMAX < 0 || YMAX < 0) set_minmax(); x = (XMAX+XMIN)/2 - x/2; y = (YMAX+YMIN)/2 + y; g.drawString(str,x,y); //g.drawOval(x,y,4,4); g.setFont(oldfont); return; } /* public boolean mouseMove(Event e, int x, int y) { if (!polygonMode) return false; if (numverts == 0) return false; if (x != xlist[numverts-1] || y != ylist[numverts-1]) { xlist[numverts] = x; ylist[numverts] = y; } repaint(); return true; } */ private void zoomIn(double x1,double x2,double y1, double y2) { int rc; double z; if (x1 > x2) { z=x1; x1=x2; x2=z; } if (y1 > y2) { z=y1; y1=y2; y2=z; } String R = x1+"/"+x2+"/"+y1+"/"+y2; String A = anotinterval(x1,x2,y1,y2); String ns = oldstations; ns = ns.replace(' ','_'); //String location = "http://deacon.tamu.edu/cgi-bin/zoomtest.csh?"+R+"/"+A+"/"+ns+"/"+usePoly; String location = "http://deacon.tamu.edu/cgi-bin/zoomtest.csh?"+R+"/"+A+"/"+ns+"/"+polygonfile; URL url = null; URLConnection conn = null; String ref = null; working(); try { zoomedIn = true; url = new URL(location); conn = url.openConnection(); InputStream cx = conn.getInputStream(); InputStreamReader inx = new InputStreamReader(cx); BufferedReader in = new BufferedReader(inx); while (ref == null || ref.compareTo("Done!") != 0) { ref = in.readLine(); if (ref.equals("GIFNAME:")) { gif = in.readLine(); } if (ref.equals("TMPNAME:")) { selectedStations = in.readLine(); } } in.close(); if (ourmap != null) ourmap.flush(); ourmap = myGetImage(gif); RX1 = x1; RX2 = x2; RY1 = y1; RY2 = y2; //startx = -1; drawme = ourmap; clabel.show(false); //ctext.show(false); centerOn.show(false); repaint(); } catch (Exception err) { System.err.println(err); } } // rubberband the line public boolean mouseDrag(Event e, int x, int y) { int x1,y1,x2,y2; while (XMAX < 0 || YMAX < 0) set_minmax(); y = y - YADJ; if (x > XMAX && XMAX > 0) x = XMAX; if (y > YMAX && YMAX > 0) y = YMAX; if (x < XMIN) x = XMIN; if (y < YMIN) y = YMIN; //if (newflag) { //offscreen_g.drawImage(ourmap,0,0,this); //x1 = startx; x2 = lastx; //y1 = starty; y2 = lasty; //if (startx > lastx) { x1 = lastx; x2 = startx; } //if (starty > lasty) { y1 = lasty; y2 = starty; } //g.setXORMode(this.getBackground()) ; //g.drawLine(startx, starty, lastx, lasty); //g.drawRect(x1,y1,x2-x1,y2-y1); //g.setPaintMode() ; //} //g.drawLine(startx, starty, x, y) ; //if (startx > x) { z = x; x = startx; startx = z; } //if (starty > y) { z = y; y = starty; starty = z; } x1 = startx; x2 = x; y1 = starty; y2 = y; if (startx > x) { x1 = x; x2 = startx; } if (starty > y) { y1 = y; y2 = starty; } lastx = x ; lasty = y ; newflag = true; repaint(); return true ; } }