public ImageCollector(Tile[] t, int x, int y, Trace tr, Images i) { super(); this.t = t; this.tr = tr; Node n = new Node(2f, 0f); Projection p1 = ProjFactory.getInstance(n, 0, 1500, xSize, ySize); if (p1.isOrthogonal()) { // without overscan // FIXME add overscan support for windows if (Configuration.getCfgBitState(Configuration.CFGBIT_TMS_SPLITSCREEN) || Configuration.getCfgBitState(Configuration.CFGBIT_TMS_BACKGROUND)) { yScreenOverscan = 0; xScreenOverscan = 0; } else { // with overscan yScreenOverscan = y * 12 / 100; xScreenOverscan = x * 12 / 100; } if (tr.isShowingSplitIconMenu()) { yScreenOverscan = 0; } xSize = x + 2 * xScreenOverscan; ySize = y + 2 * yScreenOverscan; } else { // without overscan xSize = x; ySize = y; xScreenOverscan = 0; yScreenOverscan = 0; } img[0] = Image.createImage(xSize, ySize); img[1] = Image.createImage(xSize, ySize); try { pc[0] = new PaintContext(tr, i); pc[0].setP(p1); pc[0].state = PaintContext.STATE_READY; pc[1] = new PaintContext(tr, i); pc[1].setP(ProjFactory.getInstance(n, 0, 1500, xSize, ySize)); pc[1].state = PaintContext.STATE_READY; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } nextSc.setP(ProjFactory.getInstance(mapCenter, nextSc.course, nextSc.scale, xSize, ySize)); processorThread = new Thread(this, "ImageCollector"); // #if polish.android processorThread.setPriority(Thread.MAX_PRIORITY); // #else processorThread.setPriority(Thread.MIN_PRIORITY); // #endif // #if not polish.api.paintdirect processorThread.start(); // #endif }
/** * copy the last created image to the real screen * * <p>public void restart() { processorThread = new Thread(this, "ImageCollector"); //#if * polish.android processorThread.setPriority(Thread.MAX_PRIORITY); //#else * processorThread.setPriority(Thread.MIN_PRIORITY); //#endif //#if not polish.api.paintdirect * processorThread.start(); //#endif } * * <p>/** copy the last created image to the real screen but with the last collected position and * direction in the center */ public Node paint(PaintContext screenPc) { PaintContext paintPC; // System.out.println("paint this: " + screenPc); // System.out.println("paint image: " + pc[nextPaint]); if (suspended || !collectorReady) { return new Node(0, 0); } // Define the parameters for the next image that will be created nextSc.center = screenPc.center.copy(); nextSc.course = screenPc.course; nextSc.scale = screenPc.scale; nextSc.dest = screenPc.dest; nextSc.xSize = screenPc.xSize; nextSc.ySize = screenPc.ySize; Projection p = ProjFactory.getInstance(nextSc.center, nextSc.course, nextSc.scale, xSize, ySize); // System.out.println("p =" + p); Projection p1 = ProjFactory.getInstance( nextSc.center, pc[nextPaint].course, pc[nextPaint].scale, xSize, ySize); // System.out.println("p =" + p1); nextSc.setP(p); screenPc.setP(p); synchronized (this) { if (pc[nextPaint].state != PaintContext.STATE_READY) { logger.error( Locale.get( "imagecollector.ImageCollectorNonReadyPaintContext") /*ImageCollector was trying to draw a non ready PaintContext */ + pc[nextPaint].state); return new Node(0, 0); } paintPC = pc[nextPaint]; paintPC.state = PaintContext.STATE_IN_PAINT; } int screenXCenter = xSize / 2 - xScreenOverscan; int screenYCenter = ySize / 2 - yScreenOverscan; int newXCenter = screenXCenter; int newYCenter = screenYCenter; // return center of the map image drawn to the caller Node getDrawnCenter = paintPC.center.copy(); if (p.isOrthogonal()) { // maps can painted so that the hotspot is at the predefined point on the screen // therfore the offset is useful in that case its not necessary to create a new image // if the position has changed less then half of the offset if (lastCreatedSc != null) { p1.forward(lastCreatedSc.center, oldCenter); newXCenter = oldCenter.x - p.getImageCenter().x + screenXCenter; newYCenter = oldCenter.y - p.getImageCenter().y + screenYCenter; // System.out.println("Paint pos = " + newXCenter + "/" + // newYCenter); // System.out.println("Paint ysize=" + ySize + " nextSc.xSize=" // + nextSc.ySize + " hotspot=" + p.getImageCenter()); } screenPc.g.drawImage( img[nextPaint], newXCenter, newYCenter, Graphics.VCENTER | Graphics.HCENTER); // Test if the new center is around the middle of the screen, in which // case we don't need to redraw (recreate a new image), as nothing has changed. if (Math.abs(newXCenter - screenXCenter) > 4 || Math.abs(newYCenter - screenYCenter) > 4 || paintPC.course != nextSc.course) { // The center of the screen has moved or rotated, so need // to redraw the map image needRedraw = true; // System.out.println("wakeup thread because course or position changed"); // System.out.println("Changed " + newXCenter + "->" + // screenXCenter + " and " + newYCenter + "->" + screenYCenter); } } else { screenPc.g.drawImage( img[nextPaint], screenXCenter, screenYCenter, Graphics.VCENTER | Graphics.HCENTER); p.forward(lastCreatedSc.center, oldCenter); newXCenter = oldCenter.x - p.getImageCenter().x + screenXCenter; newYCenter = oldCenter.y - p.getImageCenter().y + screenYCenter; if (Math.abs(newXCenter - screenXCenter) > 1 || Math.abs(newYCenter - screenYCenter) > 1 || paintPC.course != nextSc.course) { needRedraw = true; } } // screenPc.g.drawArc(newXCenter-14, newYCenter-14, 28, 28, 0, 360); // if (p instanceof Proj3D){ // screenPc.g.setColor(255,50,50); // IntPoint pt0 = new IntPoint(); // IntPoint pt1 = new IntPoint(); // Proj3D p3=(Proj3D)p; // p.forward(p3.borderLD,pt0); // p.forward(p3.borderLU,pt1); // screenPc.g.drawLine(pt0.x, pt0.y, pt1.x, pt1.y); // p.forward(p3.borderRU,pt0); // screenPc.g.drawLine(pt0.x, pt0.y, pt1.x, pt1.y); // p.forward(p3.borderRD,pt1); // screenPc.g.drawLine(pt0.x, pt0.y, pt1.x, pt1.y); // p.forward(p3.borderLD,pt0); // screenPc.g.drawLine(pt0.x, pt0.y, pt1.x, pt1.y); // // } String name = null; Way wayForName = null; /** * used to check for pixel distances because checking for meters from converted pixels requires * to be exactly on the pixel when zoomed out far */ final int SQUARE_MAXPIXELS = 5 * 5; // Tolerance of 15 pixels converted to meters float pixDest = 15 / paintPC.ppm; if (pixDest < 15) { pixDest = 15; } if (paintPC.trace.gpsRecenter) { // Show closest routable way name if map is gpscentered and we are // closer // than SQUARE_MAXPIXELS or 30 m (including penalty) to it. // If the routable way is too far away, we try the closest way. if (paintPC.bUsedGpsCenter == false) { if (paintPC.squareDstWithPenToActualRoutableWay < SQUARE_MAXPIXELS || paintPC.getDstFromSquareDst(paintPC.squareDstWithPenToActualRoutableWay) < 30) { wayForName = paintPC.actualRoutableWay; } else if (paintPC.squareDstWithPenToWay < SQUARE_MAXPIXELS || paintPC.getDstFromSquareDst(paintPC.squareDstWithPenToWay) < 30) { wayForName = paintPC.actualWay; } } else { if (paintPC.getDstFromRouteableWay() < 100) { wayForName = paintPC.actualRoutableWay; } else if (paintPC.getDstFromWay() < 100) { wayForName = paintPC.actualWay; } } } else if (paintPC.getDstFromSquareDst(paintPC.squareDstWithPenToWay) <= pixDest) { // If not gpscentered show closest way name if it's no more than 15 // pixels away. wayForName = paintPC.actualWay; } /* * As we are double buffering pc, nothing should be writing to paintPC * therefore it should be safe to access the volatile variable actualWay */ if (paintPC.actualWay != null) { screenPc.actualWay = paintPC.actualWay; screenPc.actualSingleTile = paintPC.actualSingleTile; tr.actualWay = paintPC.actualWay; tr.actualSingleTile = paintPC.actualSingleTile; } if (wayForName != null) { int nummaxspeed; String maxspeed = ""; String winter = ""; // store for OSM editing if (wayForName.getMaxSpeed() != 0) { nummaxspeed = wayForName.getMaxSpeed(); if (Configuration.getCfgBitState(Configuration.CFGBIT_MAXSPEED_WINTER) && (wayForName.getMaxSpeedWinter() > 0)) { nummaxspeed = wayForName.getMaxSpeedWinter(); winter = Locale.get("imagecollector.Winter") /*W */; } if (nummaxspeed == Legend.MAXSPEED_MARKER_NONE) { maxspeed = Locale.get("imagecollector.SL") /* SL:*/ + winter + Locale.get("imagecollector.MaxSpeedNone") /*none*/; } else if (nummaxspeed == Legend.MAXSPEED_MARKER_VARIABLE) { maxspeed = Locale.get("imagecollector.SL") /* SL:*/ + winter + Locale.get("imagecollector.MaxSpeedVariable") /*var*/; } else if (Configuration.getCfgBitState(Configuration.CFGBIT_METRIC)) { maxspeed = Locale.get("imagecollector.SL") /* SL:*/ + winter + nummaxspeed; } else { // Round up at this point, as the the previouse two // conversions // were rounded down already. (Seems to work better for // speed limits of // 20mph and 30mph) maxspeed = Locale.get("imagecollector.SL") /* SL:*/ + winter + ((int) (nummaxspeed / 1.609344f + 0.5f)); } } if (wayForName.nameIdx != -1) { name = screenPc.trace.getName(wayForName.nameIdx); } else { // #if polish.api.bigstyles WayDescription wayDesc = Legend.getWayDescription(wayForName.type); // #else WayDescription wayDesc = Legend.getWayDescription((short) (wayForName.type & 0xff)); // #endif name = Locale.get("imagecollector.unnamed") /*(unnamed */ + wayDesc.description + ")"; } if (name == null) { name = maxspeed; } else { name = name + maxspeed; } // If there's an URL associated with way, show a letter next to name if (wayForName.urlIdx != -1) { name = name + Locale.get("imagecollector.W") /* W*/; } // Show 'P' for phone number if (wayForName.phoneIdx != -1) { name = name + Locale.get("imagecollector.P") /* P*/; } } // use the nearest routable way for the the speed limit detection if // it's // closer than 30 m or SQUARE_MAXPIXELS including penalty if (paintPC.squareDstWithPenToActualRoutableWay < SQUARE_MAXPIXELS || paintPC.getDstFromSquareDst(paintPC.squareDstWithPenToActualRoutableWay) < 30) { tr.actualSpeedLimitWay = paintPC.actualRoutableWay; } else { tr.actualSpeedLimitWay = null; } boolean showLatLon = Configuration.getCfgBitState(Configuration.CFGBIT_SHOWLATLON); LayoutElement e = Trace.tl.ele[TraceLayout.WAYNAME]; if (showLatLon) { // #if polish.api.finland // show Finnish ETRS-TM35FIN coordinates // FIXME: add a config option for selection of coordinates if (false) { PositionMark pmETRS = ETRSTM35FINconvert.latlonToEtrs(paintPC.center.radlat, paintPC.center.radlon); e.setText( Locale.get("imagecollector.lat") /* lat: */ + Float.toString(pmETRS.lat) + " " + Locale.get("imagecollector.lon") /* lon: */ + Float.toString(pmETRS.lon)); } else { // #endif e.setText( Locale.get("imagecollector.lat") /* lat: */ + Float.toString(paintPC.center.radlat * MoreMath.FAC_RADTODEC) + " " + Locale.get("imagecollector.lon") /* lon: */ + Float.toString(paintPC.center.radlon * MoreMath.FAC_RADTODEC)); // #if polish.api.finland } // #endif } else { if (name != null && name.length() > 0) { e.setText(name); } else { e.setText(" "); } } if (paintPC.scale != screenPc.scale) { // System.out.println("wakeup thread because scale changed"); needRedraw = true; } // when the projection has changed we must redraw if (!paintPC.getP().getProjectionID().equals(screenPc.getP().getProjectionID())) { // System.out.println("wakeup thread because projection changed"); needRedraw = true; } synchronized (this) { paintPC.state = PaintContext.STATE_READY; if (needRedraw) { notify(); } else { // System.out.println("No need to redraw after painting"); } } // currentVisibleSc=lastCreatedSc.cloneToScreenContext(); return getDrawnCenter; }