// EPS: Elgaard Positioning System: GPS navigation software. // Copyright (C) 1997, 1999, 2000 Niels Elgaard Larsen // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Niels Elgaard Larsen, // import java.awt.*; import java.io.*; import java.net.*; import java.lang.Math; import java.util.Date; import java.text.DecimalFormat; import java.awt.event.*; class ImageGMap extends EPSCanvas implements Runnable, MouseListener, MouseMotionListener, KeyListener { static DecimalFormat speedFormat = new DecimalFormat("#.00"); static DecimalFormat distFormat = new DecimalFormat("#.00"); Date simTime = new Date(0) ; ICF theCF; Point mouseScreenPos = new Point(0,0); int ttx; int tx; int tty; int ty=500; boolean mouseUp = true; static boolean CursorPaint= false; Graphics cg; boolean alive = true; boolean NMEA=false; static int sDelta = 50; int tx0=0,ty0=0; int cx0=0, cy0=0; int cx1=0, cy1=0; Pos bottomLeftPos; String oldpos = ""; int XCharts; int YCharts; int ScreenWidth; int ScreenHeight; Font waypointFont = new Font("Helvetica", Font.PLAIN, 12); Font routeFont = new Font("Helvetica", Font.PLAIN, 20); int nLoadMaps0=5; int nLoadMaps = nLoadMaps0; int nLoadMapsMax = 5*nLoadMaps0; String imgNames="?"; double xres=0d, yres=0d; // pixels per degree Dimension ChartDim; Dimension minDim; Dimension prefDim; double fLong, fLat; ChartInfo loadedMaps[][]; Pos cCursor=null; Pos oldcCursor=null; GMenv menv; Usync musync= new Usync(this); ImageGMap(GMenv e, ICF cf){ Pos startPos; menv =e; setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); //System.out.println(" I UGM env= " +menv); loadedMaps = new ChartInfo[nLoadMapsMax*2+1][nLoadMapsMax*2+1]; theCF = cf; CAux.perr("NOW CHARTS",8); CAux.readCharts( menv.epsBase, menv.chartdir, menv); // readCharts sets menv.cw and menv.ch. // FIXME. What happens if charts are added while running. bottomLeftPos = new Pos(0d,0d, theCF.mMapDatum.theDatum); fLong = ((double) menv.cw)/60d; //width of charts in degrees fLat = ((double) menv.ch)/60d; //width of charts in degrees prefDim = new Dimension(600,500); minDim = new Dimension(300,200); startPos = new Pos(menv.initLong, menv.initLat, theCF.mMapDatum.theDatum); System.out.println("Starting at " + startPos.toString(GMenv.posFormat)); ScreenWidth = prefDim.width; ScreenHeight = prefDim.height; yres = (float) menv.initZoom; xres = yres*Math.sqrt(Math.cos(startPos.y.r())); ChartDim = new Dimension((int) (xres*fLong), (int) (yres*fLat)); // FIXME ScreenWidth and ScreenHeight should be correct here. // But is be unknown at this time // System.out.println(" ssz= " +getSize()); jumpTo(startPos, true); setBackground(new Color(240,230,140)); addMouseListener(this); addMouseMotionListener(this); addKeyListener(this); // Math.rint() dos not work on the HP's at least with Netscape CAux.perr("Now reading inital data files ",1); if (GMenv.wpfile.wval != null) { CAux.perr("wpfile "+GMenv.wpfile,1); aWP.theWP.readWayPoints(theCF.outArea,theCF.waypointList,menv.epsBase, GMenv.wpfile.wval , theCF.fileFormat,menv); } if (GMenv.rtfile.wval != null){ CAux.perr("RTfile "+GMenv.rtfile,1); RouteC.readRoutes(theCF.outArea,theCF.routeList,theCF.routeWPList, theCF.waypointList, menv.epsBase, GMenv.rtfile.wval,theCF.fileFormat,menv); } if (GMenv.trfile.wval != null){ CAux.perr("TRfile "+GMenv.trfile,1); TrackC.readTracks(menv.epsBase,GMenv.trfile.wval, theCF.fileFormat,menv); } } public Dimension getMinimumSize(){ return (minDim); } //public Dimension getPreferredSize(){ //return (prefDim); //} public void run() { // System.out.println("Running "); Thread thisThread = Thread.currentThread(); while (ChartFrame1.hThread==thisThread){ if (musync.shouldWork()) { paintupd(); FullPaint = true; repaint(500); } } } int lrnd(double dd) { if (dd>=0d){ return((int)dd); } else { return((int)(dd+Double.MIN_VALUE-1)); } } public void mouseDragged(MouseEvent me) { } public void mouseMoved(MouseEvent me) { mouseScreenPos = me.getPoint(); // CAux.perr("mmv="+mouseScreenPos ,2); } public void mousePressed (MouseEvent evt) { int x,y; x = evt.getX() - tx; y = ty - evt.getY(); String pos; pos= pix2pos(x,y).toString(Pone.MD); if (0!=(evt.getModifiers() & MouseEvent.BUTTON3_MASK)) { trackLog(evt.getX(),evt.getY()); } else if (0!=(evt.getModifiers() & MouseEvent.BUTTON2_MASK)) { newTrackLog(); } else if (0!=(evt.getModifiers() & MouseEvent.META_MASK)) { newTrackLog(); } else { showPos(evt.getX(),evt.getY()); } } public void mouseEntered (MouseEvent evt) { //System.out.println("IG event "+ event); requestFocus(); } public void mouseExited (MouseEvent evt) {} public void mouseReleased (MouseEvent evt) {} void horzScroll(int px) { tx0 += px; ttx += px; FullPaint = true; musync.upd(300); } public void mouseClicked (MouseEvent me) { if (me.getClickCount() == 2) { Pos pos; int x,y; x = me.getX() - tx; y = ty - me.getY(); pos= pix2pos(x,y); CAux.perr("doubleclick at" + pos.toString(Pone.MD), 2); ggoto(pos); FullPaint = true; musync.upd(50); } } public void keyReleased(KeyEvent kevt) { } void vertScroll(int py) { ty0 += py; tty +=py; FullPaint = true; musync.upd(300); } public void keyTyped(KeyEvent kevt) { } public void keyPressed(KeyEvent kevt) { char tk = Character.toLowerCase(kevt.getKeyChar()); int kc = kevt.getKeyCode(); CAux.perr("KEY pressed" + kc,2); if (tk=='t'){ // trackLog(kevt.getX(),kevt.getY()); } else if (tk=='p'){ Pos mpos = screenPix2Pos(mouseScreenPos.x, mouseScreenPos.y); theCF.setLLPos(mpos); } else if (tk=='n'){ newTrackLog(); } else if (tk=='z'){ theCF.pLabel.setText(" test " + "tx("+tx+","+ty+","+tty+")"+ " res("+xres+","+yres+")"); } else if (kc == KeyEvent.VK_LEFT /*|| kc == KeyEvent.VK_KP_LEFT*/) { ttx -= sDelta; FullPaint = true; musync.upd(300); } else if (kc == KeyEvent.VK_RIGHT /*|| kc == KeyEvent.VK_KP_RIGHT */ ) { ttx += sDelta; FullPaint = true; musync.upd(300); } else if (kc == KeyEvent.VK_UP /* || kc == KeyEvent.VK_KP_UP*/ ) { tty += sDelta; FullPaint = true; musync.upd(300); } else if (kc == KeyEvent.VK_DOWN /* || kc == KeyEvent.VK_KP_DOWN*/ ) { tty -= sDelta; FullPaint = true; musync.upd(300); } else if (/* kc == KeyEvent.VK_PLUS || */ kc == KeyEvent.VK_ADD ) { CAux.perr("KEY PLUS",2); theCF.newZoom(1.25f); } else if (/* kc == KeyEvent.VK_MINUS ||*/ kc == KeyEvent.VK_SUBTRACT) { CAux.perr("KEY MINUS",2); theCF.newZoom(0.8f); } else { CAux.perr("?? KEY " + kc,2); } } void newTrackLog() { TrackC.insertTrack(null); theCF.pLabel.setText(" Starting New track"); } void showPos(int sx, int sy) { int x,y; cCursor = screenPix2Pos(sx,sy); CursorPaint = true; repaint(); // System.out.println("Mouse cx ("+cx+","+cy+")"+"sxy("+sx+","+sy+")"+ // "xy=("+x+","+y+")" ); if (cCursor != null){ if (cCursor.theDatum == theCF.mPositionDatum.theDatum) { theCF.pLabel.setText(" pos: " + cCursor.toString(GMenv.posFormat)); } else { theCF.pLabel.setText(" pos: " + cCursor.toString(GMenv.posFormat) + " ("+cCursor.theDatum.name + ") "+ cCursor.toDatum(theCF.mPositionDatum.theDatum).toString(GMenv.posFormat) + "("+theCF.mPositionDatum.theDatum.name + ")" ); } } } void trackLog(int sx, int sy) { Pos mc = screenPix2Pos(sx, sy); TrackC.insertTrack(new TRPos(mc, simTime)); theCF.pLabel.setText( //"x(" + x +","+ y + ")"+ //" tx("+tx+","+ty+"/"+tty+")" + //" sx("+sx+","+sy+") pos:" + "Setting track log at " + mc.toString(GMenv.posFormat) //+" blp=" + bottomLeftPos.toString(theCF.posFm) ); AnnoPaint = true; repaint(20); } int pos2xpix(Pos p){ return((int)Math.round ((p.toDatum(theCF.mapDatum()).x.p - bottomLeftPos.x.p)*xres)); } int pos2ypix(Pos p){ return((int) ((p.toDatum(theCF.mapDatum()).y.p - bottomLeftPos.y.p)*yres+0.5)); } int pos2sxpix(Pos p){ return((int) ((p.toDatum(theCF.mapDatum()).x.p - bottomLeftPos.x.p)*xres +(double)tx)); } int pos2tsypix(Pos ppos){ /* pixels from bottom of canvas */ return((int) ((ppos.toDatum(theCF.mapDatum()).y.p - bottomLeftPos.y.p)*yres -(double)tty)); } int pos2sypix(Pos p){ /* pixels from top of canvas */ return((int) (ty-(p.toDatum(theCF.mapDatum()).y.p - bottomLeftPos.y.p)*yres)); } boolean onScreen(Pos p) { int sx,sy; sx = pos2sxpix(p); sy = pos2sypix(p); return(onScreen(sx,sy)); } boolean onScreen(int sx, int sy) { return (sx>=0 && sy >=0 && sx < ScreenWidth && sy < ScreenHeight); } boolean onScreen(int sx0, int sy0, int sx1, int sy1) { //FIXME does this line show on the screen ? if ((sx0 <0 && sx1 < 0) || (sx0 > ScreenWidth && sx1 > ScreenWidth) || (sy0 <0 && sy1 < 0)|| (sy0 > ScreenHeight && sy1 > ScreenHeight) ) { return (false); } else { return(true); } } public void plotWP(Graphics g){ int nw; WayPoint theWP; g.setColor(GMenv.getColor(GMenv.WAYPOINTCOLOR)); g.setFont(waypointFont); g.setPaintMode(); for (nw=0; nw mindistq*1852) && (td<0 ||td > tdmin)) { if (onScreen(sx,sy)) { g.fillRect(sx-4,sy-4,8,8); CAux.perr("IGM speed dist="+TrackC.adist + " td="+ td + " ialt"+(TrackC.adist*1000d/td),2); CAux.drawString(g, speedFormat.format((TrackC.adist*1000d/td)*GMenv.speedMul+0.005) + GMenv.speedUnitName, TrackC.mx,TrackC.my,1,Color.black); } g.setColor(GMenv.getColor(GMenv.TRACKCOLOR)); TrackC.adist = 0d; TrackC.mfound = true; TrackC.lastTimed = theTP; } } if (onScreen(sx,sy,oldsx,oldsy)) { g.fillArc(sx,sy,4,4,0,360); if (TrackC.lastPlotted.tpos!=null){ g.drawLine(sx,sy,oldsx,oldsy); } } } TrackC.lastPlotted = theTP; if (TrackC.lastPlotted == null || TrackC.lastTimed ==null) { TrackC.lastTimed = theTP; } } public void plotRT(Graphics g){ int rt; Pos p0, p1; int th; FontMetrics fm; Pos nrpos; WayPoint theWP; g.setFont(routeFont); for (rt=0; rt0){ int sy2; nrpos = theRT.wpts.wayPoints[0].wpos.toDatum(theCF.mapDatum()); sx0 = tx + pos2xpix(nrpos); sy0 = ty - pos2ypix(nrpos); theRT.wpts.wayPoints[0].routeHere++; sy2 = sy0-theRT.wpts.wayPoints[0].routeHere*th-4; CAux.drawString(g,"Start: " + theRT.name + " 0 "+GMenv.lengthUnitName, sx0,sy2,2, GMenv.getColor(GMenv.ROUTECOLOR)); } for (nw=1; nw 100d && yunit > 100d ) { xunit = xres/60d/mfac[nPerMin]; yunit = yres/60d/mfac[nPerMin]; xCunit = 1d/60d/mfac[nPerMin]; yCunit = 1d/60d/mfac[nPerMin]; nPerMin++; } while (xunit > 100d && yunit > 100d ) { xunit = xres/60d/10d; yunit = yres/60d/10d; xCunit = 1d/60d/10d; yCunit = 1d/60d/10d; } } Pos dmd = bottomLeftPos.eCopy(); Pos dmdP; dmd.theDatum = theCF.mPositionDatum.theDatum; //System.out.println(" dD = " + bottomLeftPos.toDatum(theCF.mPositionDatum.theDatum) // .toDatum(theCF.mMapDatum.theDatum)); dmdP = dmd.toDatum(theCF.mMapDatum.theDatum); dx0 = ((pos2sxpix(dmdP))); dy0 = ((pos2tsypix(dmdP))); dx = (double)(dx0 % xunit); dy = (double)(dy0 % yunit); CAux.perr("anno: dx0="+dx0+" dy0="+dy0 +" xunit="+xunit+" yunit="+yunit,8); //CAux.perr("anno: dx="+dx+" dy="+dy,5);ww //System.out.println(" (dx,dy) = (" + dx + ","+ dy+ ") (xres,yres)=("+xres+","+yres+")"); for (sx = dx ; sx < ScreenWidth; sx = sx+xunit){ g.drawLine( (int)sx,1,(int)sx,10); } for (sy = ScreenHeight - dy; sy >0; sy -= yunit){ g.drawLine( 1,(int)sy,10,(int)sy); } // Print Long. positions on border fm = g.getFontMetrics(); minWidth = fm.stringWidth("55g88.88 "); if (minWidth> xres/60d && xunit10d || (double)ScreenHeight/(yunit) >10d || (xunit < minWidth))) { xunit = xres/60*dfac[nDegree]; yunit = yres/60*dfac[nDegree]; xCunit = dfac[nDegree]/60d; yCunit = dfac[nDegree]/60d; nDegree++; } } while ((double)ScreenWidth/xunit >10d || (double)ScreenHeight/(yunit) >10d || (xunit < minWidth)){ if ((double)ScreenWidth/xunit >30d){ xunit *=10d; yunit *=10d; xCunit *=10d; yCunit *=10d; } else { xunit *=2d; yunit *=2d; xCunit *=2d; yCunit *=2d; } } int xunitoff = (int) ((tx+pos2xpix(dmdP)) / xunit); int yunitoff = (int) ((-tty+pos2ypix(dmdP) ) / yunit); blc.x.p -= ( xunitoff * xCunit); blc.y.p -= ( yunitoff * yCunit); CAux.perr("yCunit="+yCunit+" ty="+ty+" p2p="+ pos2ypix(dmdP)+ " blc="+blc.toString(Pone.MDD) + " mul="+ yunitoff,9); //blc.y.p += (dy0 / yunit) * yCunit; //CAux.perr("anno: blp=" +dmd+" dmdP="+dmdP + " inv="+dmdP.toDatum(theCF.mPositionDatum.theDatum),5); if (xunit*yunit>100f) { String spos; int pformat=Pone.DMM; dx = pos2sxpix(blc); dy = pos2tsypix(blc); // Print Long. positions on border // System.out.println("Lat ba1r= yunit" + yunit + " dy=" + dy); if ((xunit * 60 >= xres) && (yunit * 60 >= yres)) { pformat = Pone.DM; } for (sx = dx ; sx 2*(cx1-cx0+1) && nLoadMaps > 2*(cy1-cy0+1) && nLoadMaps>2*nLoadMaps0+2) { // scrink cache int mx,my; for (mx=nLoadMaps/2+1; mx < nLoadMapsMax; mx++) { for (my=nLoadMaps/2+1; my < nLoadMapsMax; my++) { loadedMaps[ mx+nLoadMapsMax][ my+nLoadMapsMax] = null; loadedMaps[-mx+nLoadMapsMax][-my+nLoadMapsMax] = null; } } nLoadMaps = nLoadMaps/2; } // System.out.println(" PUU tx = "+tx +" ty="+ty+" fLat="+fLat+" cy0="+ cy0); if ((Math.abs(cy0)+XCharts> nLoadMaps) || (Math.abs(cx0)+XCharts> nLoadMaps)) { newPos = screenPix2Pos(ScreenWidth/2,ScreenHeight/2); jumpTo(newPos, false); tx = -ttx; ty = tty + ScreenHeight; FullPaint =true; repaint(500); } CAux.perr("cx0="+cx0+" cx1="+cx1+" cy0="+cy0+" cy1="+cy1,7); for (cx=cx0; cx<=cx1 && Math.abs(cx)<=nLoadMaps ;cx++){ for (cy=cy0; cy<=cy1 && Math.abs(cy)<=nLoadMaps;cy++){ ChartInfo thisCI=loadedMaps[cx+nLoadMapsMax][cy+nLoadMapsMax]; Pos thePos; String imgName="??"; int imgSuffix; ChartRect theRect=null; thePos = pix2pos(cx*ChartDim.width,cy*ChartDim.height); // System.out.println(" p " + cx+","+cy+" = "+thePos.toString(1)+" to be loaded"); CAux.perr("ImageGMap find pos="+thePos+ " ch="+menv.ch+ " cw="+menv.cw,2); theRect = Rects.find(thePos, menv.ch, menv.cw,(int)yres); CAux.perr("ImageGMap found "+theRect,2); if (theRect!=null && (thisCI==null || thisCI.tried ==0 || thisCI.loadedFrom==null || (thisCI.loadedFrom.zoom < theCF.zoom && thisCI.loadedFrom.zoom < 101)|| theRect.dpd != thisCI.loadedFrom.dpd)) { loadedMaps[cx+nLoadMapsMax][cy+nLoadMapsMax] = thisCI = new ChartInfo(); thisCI.tried=1; imgName= theRect.toString(); chartName = menv.chartdir+ "/" + imgName; CAux.perr("ImageGM loading "+ chartName + "XXXX",2); thisCI.loadedFrom = theRect; if (theRect.chart==null || (theRect.zoom < theCF.zoom && theRect.zoom < 101)) { try { theCF.outArea.append("Loading chart: "+ " "+ imgName+"\n"); } catch (NoSuchMethodError ex) { System.out.println("Loading chart: "+ " "+ imgName+"\n"); } try { chartURL = new URL(menv.epsBase, chartName); CAux.perr("CHARTSURL:" + chartURL+ " cn="+chartName, 2); }catch (MalformedURLException me) { System.out.println("MalformedURLException: " + me); } //System.out.println("Map load imgs="+ imgSuffix + " cn="+chartName + // " URL:"+cx +","+cy+ " URL:"+ chartURL); if (chartURL!=null){ if (menv.epsBase.getProtocol().equals("file")) { theRect.chart = ChartFrame1.fShield.getImage(getToolkit(),ChartFrame1.urlDecode(chartURL.getFile())); //theRect.chart = getToolkit().getImage(ChartFrame1.urlDecode(chartURL.getFile())); } else { theRect.chart = getToolkit().getImage(chartURL); } theRect.cw0 = theRect.chart.getWidth(null); theRect.ch0 = theRect.chart.getHeight(null); // jdk10 getToolkit().prepareImage(theRect.chart, ChartDim.width, ChartDim.height,this); } // thisCI.loadedFrom = theRect; } } if ((thisCI!=null) && thisCI.loadedFrom!=null && ((thisCI.loadedFrom.chart!=null) // ||(loadedMaps[cx+nLoadMaps][cy+nLoadMaps].tried==0) ) ) { CAux.perr("ImageGM try "+ imgName,2); thisCI.tried++; if (thisCI.loadedFrom.zoom != theCF.zoom) { // For low zoom get scaled image to save memeory if ((theCF.zoom < 101) && thisCI.loadedFrom.getdLong()*xres<2000) { thisCI.loadedFrom.zoom = theCF.zoom; CAux.perr("Scaling to :"+ ((int) (thisCI.loadedFrom.getdLong()*xres+0.5)) + "," + ((int) (thisCI.loadedFrom.getdLat() *yres+0.5)), 3); CAux.perr("scale Image orig=("+ thisCI.loadedFrom.chart.getWidth(null)+ "," + thisCI.loadedFrom.chart.getHeight(null)+")" ,2); thisCI.loadedFrom.chart = thisCI.loadedFrom.chart.getScaledInstance( (int) (thisCI.loadedFrom.getdLong()*xres+0.5), (int) (thisCI.loadedFrom.getdLat() *yres+0.5), Image.SCALE_DEFAULT); CAux.perr("scale Image cwh=("+ thisCI.loadedFrom.chart.getWidth(null)+ "," + thisCI.loadedFrom.chart.getHeight(null)+") should("+ (int) (thisCI.loadedFrom.getdLong()*xres+0.5) + "," + (int) (thisCI.loadedFrom.getdLat() *yres+0.5)+ ")" ,5); } else { //getToolkit().checkImage(thisCI.chart, ChartDim.width, ChartDim.height,this); //getToolkit().prepareImage(thisCI.chart, ChartDim.width, ChartDim.height,this); } } } } } } public void paint1(Graphics g, boolean isUp) { int cx,cy; CAux.perr("paint1 cx: "+cx0+ "_" + cx1 + " ,cy: "+cy0+"_"+ cy1 + " isUp="+ isUp, 2 ); g.setPaintMode(); for (cx=cx0; cx<=cx1 && Math.abs(cx)<=nLoadMaps ;cx++) { for (cy=cy0; cy<=cy1 && Math.abs(cy)<=nLoadMaps;cy++) { ChartInfo thisCI=loadedMaps[cx+nLoadMapsMax][cy+nLoadMapsMax]; //CAux.perr("paint1 if cx="+cx+" cy=" + cy + " lms="+loadedMaps[cx+nLoadMapsMax][cy+nLoadMapsMax],2); if ((thisCI!=null) && (thisCI.loadedFrom!=null) && ((thisCI.loadedFrom.chart!=null) // ||(thisCI.tried==0) )) { if (!thisCI.fin || (! isUp)) { CAux.perr("thisCI="+ thisCI.fin,2); loadedMaps[cx+nLoadMapsMax][cy+nLoadMapsMax].tried++; // System.out.println("Chart file cx("+cx+","+cy + ")" + // "cx0("+cx0+","+cy0 + " draw at " + // (tx+cx*ChartDim.width) +"," + // + (ty-(cy+1)*ChartDim.height)); // FIXME: This could be optimized by drawing multible screen rectangles at a time. try { int ch,cw; Image theChart = thisCI.loadedFrom.chart; ChartRect lf = thisCI.loadedFrom; cw = theChart.getWidth(null); ch = theChart.getHeight(null); // Begin Use this with JDK 1.1 int dx1,dy1,dx2,dy2,sx1,sx2,sy1,sy2; dx1=Math.max(tx + cx*ChartDim.width,0); dx2=Math.min(tx + (cx+1)*ChartDim.width, ScreenWidth); dy1=Math.max(ty - (cy+1)*ChartDim.height,0); dy2=Math.min(ty - (cy)*ChartDim.height,ScreenHeight); double x1a = Math.max(bottomLeftPos.x.p + cx*fLong, (ttx/xres+bottomLeftPos.x.p)); double x1s = (ScreenWidth-tx)/xres + bottomLeftPos.x.p; double x1r = bottomLeftPos.x.p + (cx+1)*fLong; double y1a = Math.max(bottomLeftPos.y.p + cy*fLat,tty/yres+bottomLeftPos.y.p); double y1s = (ty)/yres + bottomLeftPos.y.p; double y1u = bottomLeftPos.y.p + (cy+1)*fLat; sx1 = Math.max((int) ((double)cw*(x1a - lf.getLong())/lf.getdLong() + 0.5),0); sx2= (int)((Math.min(x1s,x1r) - lf.getLong())*(double)cw/lf.getdLong() +0.5); sy2=ch-Math.max((int)(ch*(y1a - lf.getLat())/lf.getdLat()+0.5),0); sy1=ch-(int) ((Math.min(y1s,y1u) - lf.getLat())*(double)ch/lf.getdLat()+0.5); CAux.perr("theChart="+theChart+" DLF=("+lf.getLong()+","+lf.getLat()+ ")" + "DLF=("+lf.getdLong()+","+lf.getdLat()+ ")",2); CAux.perr("drawImage cxy=("+cx+ ","+cy+") cwh=("+ cw + "," + ch + ") xyres=("+xres + ","+yres+") x1a="+x1a+" x1s="+x1s+" x1r="+x1r, 2); CAux.perr("drawImage "+ thisCI + ": "+ "d1=("+dx1+","+dy1 + ") d2=("+dx2+","+dy2+ ") s1=("+sx1+","+sy1+") s2=("+sx2+","+sy2+")", 2); if (CAux.tLevel > 0) { g.drawLine(dx1,dy1,dx2,dy2); } thisCI.fin=g.drawImage(theChart, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, this /* Image observer */); // System.out.println(" src=("+sx1 +","+sy1+"),("+sx2 +","+sy2+"),"+ // "dst=("+dx1 +","+dy1+"),("+dx2 +","+dy2+")"); // img - the specified image to be drawn // dx1 - the x coordinate of the first corner of the destination rectangle // dy1 - the y coordinate of the first corner of the destination rectangle // dx2 - the x coordinate of the second corner of the destination rectangle // dy2 - the y coordinate of the second corner of the destination rectangle // sx1 - the x coordinate of the first corner of the source rectangle // sy1 - the y coordinate of the first corner of the source rectangle // sx2 - the x coordinate of the second corner of the source rectangle // sy2 - the y coordinate of the second corner of the source rectangle } catch (NullPointerException me) { CAux.perr("NP IN IG: ",-1); } catch (NoSuchMethodError e) { CAux.perr(" Not JDK11 graphic",-2); g.drawImage(loadedMaps[cx+nLoadMapsMax][cy+nLoadMapsMax].loadedFrom.chart, tx + cx*ChartDim.width, ty - (cy+1)*ChartDim.height, ChartDim.width, ChartDim.height,this); } } } } } plotcCur(g,cCursor); } } class ChartInfo { // One of these for each chart grid ChartRect loadedFrom=null; int tried = 0; boolean fin = false; public String toString() { return ("CI: LF="+ loadedFrom); } } class ChartDisp { // One of these for each grid ChartInfo theChart; int tried = 0; boolean fin = false; } class Usync { private boolean again=true; private boolean working=false; private ImageGMap GMhandle; private int toWait=400; Usync(ImageGMap h) { GMhandle =h; } public synchronized void upd(int wt) { toWait = wt; if (working) { again = true; notify(); } else { again = true; notify(); } } public synchronized boolean shouldWork() { boolean ta = again; again=false; working = ta; if (!ta) { try { wait(); } catch (InterruptedException e) { } while (again){ again=false; try { wait(toWait); } catch (InterruptedException e) { } } } return (true); } }