20 |
* In addition to |
* In addition to |
21 |
*/ |
*/ |
22 |
|
|
|
import java.awt.AlphaComposite; |
|
23 |
import java.awt.Color; |
import java.awt.Color; |
24 |
import java.awt.Cursor; |
import java.awt.Cursor; |
25 |
import java.awt.Font; |
import java.awt.Font; |
40 |
import java.awt.geom.NoninvertibleTransformException; |
import java.awt.geom.NoninvertibleTransformException; |
41 |
import java.awt.geom.Point2D; |
import java.awt.geom.Point2D; |
42 |
import java.awt.image.BufferedImage; |
import java.awt.image.BufferedImage; |
|
import java.beans.PropertyChangeEvent; |
|
|
import java.beans.PropertyChangeListener; |
|
43 |
import java.io.IOException; |
import java.io.IOException; |
44 |
import java.util.HashMap; |
import java.util.HashMap; |
45 |
import java.util.Map; |
import java.util.Map; |
46 |
import java.util.Vector; |
import java.util.Vector; |
47 |
|
|
|
import javax.swing.JFrame; |
|
48 |
import javax.swing.JPanel; |
import javax.swing.JPanel; |
49 |
import javax.swing.Timer; |
import javax.swing.Timer; |
50 |
|
|
63 |
import org.geotools.renderer.GTRenderer; |
import org.geotools.renderer.GTRenderer; |
64 |
import org.geotools.renderer.label.LabelCacheImpl; |
import org.geotools.renderer.label.LabelCacheImpl; |
65 |
import org.geotools.renderer.lite.LabelCache; |
import org.geotools.renderer.lite.LabelCache; |
66 |
|
import org.geotools.renderer.lite.StreamingRenderer; |
67 |
import org.geotools.swing.JMapPane; |
import org.geotools.swing.JMapPane; |
68 |
import org.geotools.swing.event.MapMouseEvent; |
import org.geotools.swing.event.MapMouseEvent; |
69 |
import org.geotools.swing.event.MapPaneEvent; |
import org.geotools.swing.event.MapPaneEvent; |
80 |
import schmitzm.geotools.gui.SelectableXMapPane; |
import schmitzm.geotools.gui.SelectableXMapPane; |
81 |
import schmitzm.geotools.map.event.JMapPaneListener; |
import schmitzm.geotools.map.event.JMapPaneListener; |
82 |
import schmitzm.geotools.map.event.MapLayerAdapter; |
import schmitzm.geotools.map.event.MapLayerAdapter; |
83 |
|
import schmitzm.lang.LangUtil; |
84 |
import schmitzm.swing.SwingUtil; |
import schmitzm.swing.SwingUtil; |
85 |
import skrueger.geotools.RenderingExecutor; |
import skrueger.geotools.RenderingExecutor; |
86 |
|
import skrueger.swing.formatter.MbDecimalFormatter; |
87 |
|
|
88 |
import com.vividsolutions.jts.geom.Coordinate; |
import com.vividsolutions.jts.geom.Coordinate; |
89 |
import com.vividsolutions.jts.geom.Envelope; |
import com.vividsolutions.jts.geom.Envelope; |
90 |
import com.vividsolutions.jts.geom.Geometry; |
import com.vividsolutions.jts.geom.Geometry; |
91 |
|
|
92 |
public class XMapPane extends JPanel implements PropertyChangeListener { |
public class XMapPane extends JPanel { |
93 |
private static Logger LOGGER = Logger.getLogger(XMapPane.class); |
private static Logger LOGGER = Logger.getLogger(XMapPane.class); |
94 |
|
|
95 |
/** |
/** |
187 |
* with previews. |
* with previews. |
188 |
*/ |
*/ |
189 |
public static final long REPEATING_REPAINT_DELAY = 500; |
public static final long REPEATING_REPAINT_DELAY = 500; |
190 |
|
|
191 |
/** |
/** |
192 |
* The initial delay in milliseconds until the {@link #finalImage} is updated the first time. |
* The initial delay in milliseconds until the {@link #finalImage} is |
193 |
|
* updated the first time. |
194 |
*/ |
*/ |
195 |
public static final long INITIAL_REPAINT_DELAY = 1000; |
public static final long INITIAL_REPAINT_DELAY = 1000; |
196 |
|
|
216 |
protected Envelope oldMapArea = null; |
protected Envelope oldMapArea = null; |
217 |
|
|
218 |
/** |
/** |
|
* the size of the pane last time we drew |
|
|
*/ |
|
|
protected Rectangle oldRect = null; |
|
|
|
|
|
/** |
|
|
* The Renderer for the Background uses this Image. When set to null, please |
|
|
* dispose the {@link Graphics2D} |
|
|
*/ |
|
|
protected BufferedImage bgImage; |
|
|
|
|
|
/** |
|
|
* The Renderer for the LocalLayers uses this Image. When set to null, |
|
|
* please dispose this {@link Graphics2D} |
|
|
*/ |
|
|
volatile protected BufferedImage localImage; |
|
|
|
|
|
/** |
|
219 |
* compass and icon are rendered into this image |
* compass and icon are rendered into this image |
220 |
*/ |
*/ |
221 |
// protected BufferedImage gadgetsImage; |
// protected BufferedImage gadgetsImage; |
343 |
* @param localContext |
* @param localContext |
344 |
* - {@link MapContext} of layer to render. |
* - {@link MapContext} of layer to render. |
345 |
*/ |
*/ |
346 |
public XMapPane(final MapContext localContext, |
public XMapPane(final MapContext localContext_, |
347 |
Map<Object, Object> rendererHints) { |
Map<Object, Object> rendererHints) { |
348 |
super(true); |
super(true); |
349 |
|
|
351 |
|
|
352 |
setOpaque(true); |
setOpaque(true); |
353 |
|
|
354 |
setLocalContext(localContext); |
localRenderer = GTUtil.createGTRenderer(); |
355 |
|
localRenderer.setJava2DHints(getJava2dHints()); |
356 |
|
|
357 |
|
if (localContext_ != null) |
358 |
|
setLocalContext(localContext_); |
359 |
|
|
360 |
/** |
/** |
361 |
* Adding the #zoomMapPaneMouseListener |
* Adding the #zoomMapPaneMouseListener |
420 |
public void actionPerformed(ActionEvent e) { |
public void actionPerformed(ActionEvent e) { |
421 |
synchronized (requestStartRendering) { |
synchronized (requestStartRendering) { |
422 |
if (requestStartRendering && isWellDefined()) { |
if (requestStartRendering && isWellDefined()) { |
423 |
|
|
424 |
if (localExecuter.isRunning()){ |
if (localExecuter.isRunning()) { |
425 |
localExecuter.cancelTask(); |
localExecuter.cancelTask(); |
426 |
} else { |
} else { |
427 |
requestStartRendering = false; |
requestStartRendering = false; |
734 |
public void layerAdded(final MapLayerListEvent event) { |
public void layerAdded(final MapLayerListEvent event) { |
735 |
event.getLayer().addMapLayerListener(localMapLayerListener); |
event.getLayer().addMapLayerListener(localMapLayerListener); |
736 |
|
|
737 |
|
// System.out.println("added a layer context, now it'S " |
738 |
|
// + getContext().getLayerCount() + " layers"); |
739 |
|
// ; |
740 |
|
|
741 |
|
localRenderer.setContext(getContext()); |
742 |
|
|
743 |
if (localContext.getLayers().length == 1) { // the first one |
if (localContext.getLayers().length == 1) { // the first one |
744 |
// if the Area of Interest is unset, the LayerBounds are used |
// if the Area of Interest is unset, the LayerBounds are used |
745 |
if (!setMapArea(localContext.getAreaOfInterest())) |
if (!setMapArea(localContext.getAreaOfInterest())) |
761 |
event.getLayer().removeMapLayerListener(localMapLayerListener); |
event.getLayer().removeMapLayerListener(localMapLayerListener); |
762 |
// mapImageInvalid = true; |
// mapImageInvalid = true; |
763 |
// repaint(); |
// repaint(); |
764 |
|
localRenderer.setContext(getContext()); |
765 |
requestStartRendering(); |
requestStartRendering(); |
766 |
} |
} |
767 |
|
|
769 |
public void layerChanged(final MapLayerListEvent event) { |
public void layerChanged(final MapLayerListEvent event) { |
770 |
// mapImageInvalid = true; |
// mapImageInvalid = true; |
771 |
// repaint(); |
// repaint(); |
772 |
|
localRenderer.setContext(getContext()); |
773 |
requestStartRendering(); |
requestStartRendering(); |
774 |
} |
} |
775 |
|
|
777 |
public void layerMoved(final MapLayerListEvent event) { |
public void layerMoved(final MapLayerListEvent event) { |
778 |
// mapImageInvalid = true; |
// mapImageInvalid = true; |
779 |
// repaint(); |
// repaint(); |
780 |
|
localRenderer.setContext(getContext()); |
781 |
requestStartRendering(); |
requestStartRendering(); |
782 |
} |
} |
783 |
}; |
}; |
854 |
|
|
855 |
@Override |
@Override |
856 |
public void layerChanged(MapLayerEvent event) { |
public void layerChanged(MapLayerEvent event) { |
857 |
|
localRenderer.setContext(getContext()); // betters for SLD changes?! |
858 |
// Change of SLD for example |
// Change of SLD for example |
859 |
// mapImageInvalid = true; |
// mapImageInvalid = true; |
860 |
// repaint(); |
// repaint(); |
917 |
|
|
918 |
public MapContext getContext() { |
public MapContext getContext() { |
919 |
if (localContext == null) { |
if (localContext == null) { |
920 |
this.localContext = new DefaultMapContext(); |
setLocalContext(new DefaultMapContext()); |
|
this.localContext.addMapLayerListListener(localContextListener); |
|
921 |
} |
} |
922 |
return localContext; |
return localContext; |
923 |
} |
} |
944 |
this.localContext = context; |
this.localContext = context; |
945 |
|
|
946 |
if (context != null) { |
if (context != null) { |
947 |
|
|
948 |
setMapArea(localContext.getAreaOfInterest()); |
setMapArea(localContext.getAreaOfInterest()); |
949 |
|
|
950 |
|
localRenderer.setContext(localContext); |
951 |
|
|
952 |
this.localContext.addMapLayerListListener(localContextListener); |
this.localContext.addMapLayerListListener(localContextListener); |
953 |
|
|
954 |
// adding listener to all layers |
// adding listener to all layers |
996 |
*/ |
*/ |
997 |
public Envelope getMapArea() { |
public Envelope getMapArea() { |
998 |
if (mapArea == null) { |
if (mapArea == null) { |
999 |
final Rectangle paneBounds = getBounds(); |
ReferencedEnvelope mapArea_ = null; |
|
|
|
1000 |
try { |
try { |
1001 |
mapArea = localContext.getLayerBounds(); |
mapArea_ = localContext.getLayerBounds(); |
1002 |
} catch (final IOException e) { |
} catch (final IOException e) { |
1003 |
LOGGER.warn("context.getLayerBounds()", e); |
LOGGER.warn("context.getLayerBounds()", e); |
1004 |
} |
} |
1005 |
|
|
1006 |
if (mapArea != null) { |
if (mapArea_ != null) { |
|
/* either the viewer size has changed or we've done a reset */ |
|
1007 |
mapImageInvalid = true; /* note we need to redraw */ |
mapImageInvalid = true; /* note we need to redraw */ |
1008 |
oldRect = paneBounds; /* store what the current size is */ |
setMapArea(mapArea_); |
|
mapArea = bestAllowedMapArea(mapArea); |
|
1009 |
} |
} |
1010 |
} |
} |
1011 |
|
|
1078 |
mapAreaChanged = true; |
mapAreaChanged = true; |
1079 |
repaint(); |
repaint(); |
1080 |
|
|
1081 |
// LOGGER.debug("New maparea = " + mapArea); |
// LOGGER.debug("New maparea = " + mapArea); |
1082 |
return true; |
return true; |
1083 |
} |
} |
1084 |
|
|
1111 |
|
|
1112 |
public static final int NONE = -123; |
public static final int NONE = -123; |
1113 |
|
|
1114 |
private RenderingExecutor localExecuter = new RenderingExecutor(this, 150l); |
private RenderingExecutor localExecuter = new RenderingExecutor(this); |
|
|
|
|
private BufferedImage finalImage; |
|
1115 |
|
|
1116 |
/** |
/** |
1117 |
* A flag set it {@link #setMapArea(Envelope)} to indicated the |
* A flag set it {@link #setMapArea(Envelope)} to indicated the |
1122 |
**/ |
**/ |
1123 |
private boolean mapAreaChanged = false; |
private boolean mapAreaChanged = false; |
1124 |
|
|
|
private JFrame finalImageFrame; |
|
|
|
|
1125 |
private volatile Boolean requestStartRendering = false; |
private volatile Boolean requestStartRendering = false; |
|
private BufferedImage preFinalImage; |
|
1126 |
|
|
1127 |
protected void paintComponent(final Graphics g) { |
/** |
1128 |
// Maybe update the cursor |
* The Renderer for the Background uses this Image. When set to null, please |
1129 |
updateCursor(); |
* dispose the {@link Graphics2D} |
1130 |
|
*/ |
1131 |
|
private BufferedImage bgImage;// = new |
1132 |
|
// BufferedImage(600,600,BufferedImage.TYPE_INT_ARGB); |
1133 |
|
|
1134 |
|
private BufferedImage finalImage; |
1135 |
|
|
1136 |
|
/** |
1137 |
|
* The Renderer for the LocalLayers uses this Image. When set to null, |
1138 |
|
* please dispose this {@link Graphics2D} |
1139 |
|
*/ |
1140 |
|
private BufferedImage localImage;// = new |
1141 |
|
// BufferedImage(600,600,BufferedImage.TYPE_INT_ARGB); |
1142 |
|
private BufferedImage preFinalImage;// = new |
1143 |
|
|
1144 |
|
// BufferedImage(600,600,BufferedImage.TYPE_INT_ARGB); |
1145 |
|
|
1146 |
|
protected void paintComponent(final Graphics g) { |
1147 |
if (!acceptsRepaintCalls) |
if (!acceptsRepaintCalls) |
1148 |
return; |
return; |
1149 |
|
|
1150 |
|
// Maybe update the cursor |
1151 |
|
updateCursor(); |
1152 |
|
|
1153 |
|
super.paintComponent(g); |
1154 |
|
|
1155 |
boolean paintedSomething = false; |
boolean paintedSomething = false; |
1156 |
|
|
1179 |
|
|
1180 |
if (paneResized) { |
if (paneResized) { |
1181 |
paneResized = false; |
paneResized = false; |
1182 |
preFinalImage = null; |
|
1183 |
finalImage = null; |
// if (preFinalImage != null) |
1184 |
localImage = null; |
// preFinalImage.flush(); |
1185 |
bgImage = null; |
// preFinalImage = null; |
1186 |
|
// if (finalImage != null) { |
1187 |
|
// finalImage.flush(); |
1188 |
|
// } |
1189 |
|
// finalImage = null; |
1190 |
|
// if (localImage != null) |
1191 |
|
// localImage.flush(); |
1192 |
|
// localImage = null; |
1193 |
|
// if (bgImage != null) |
1194 |
|
// bgImage.flush(); |
1195 |
|
// bgImage = null; |
1196 |
|
|
1197 |
// gadgetsImage = null; |
// gadgetsImage = null; |
1198 |
} |
} |
1199 |
|
|
1207 |
// TODO Should just paint the getFinalImage(). Update should be |
// TODO Should just paint the getFinalImage(). Update should be |
1208 |
// called by timer every 300ms, and the repaint() until all threads |
// called by timer every 300ms, and the repaint() until all threads |
1209 |
// are done. |
// are done. |
1210 |
g.drawImage(getFinalImage(), 0, 0, this); |
g.drawImage(getFinalImage(), 0, 0, null); |
1211 |
|
|
1212 |
|
g.dispose(); |
1213 |
|
|
1214 |
paintedSomething = true; |
paintedSomething = true; |
1215 |
} |
} |
1227 |
if (localExecuter != null) |
if (localExecuter != null) |
1228 |
localExecuter.cancelTask(); |
localExecuter.cancelTask(); |
1229 |
requestStartRendering = true; |
requestStartRendering = true; |
1230 |
|
|
1231 |
} |
} |
1232 |
|
|
1233 |
/** |
/** |
1286 |
* to give the user something to look at while we are rendering. Method |
* to give the user something to look at while we are rendering. Method |
1287 |
* should be called after {@link #setMapArea(Envelope)} has been set to the |
* should be called after {@link #setMapArea(Envelope)} has been set to the |
1288 |
* new mapArea and transform has been reset.<br/> |
* new mapArea and transform has been reset.<br/> |
|
* This method does nothing if the {@link #lastRenderingDuration} is smaller |
|
|
* then a trashhold. |
|
1289 |
* |
* |
1290 |
* @param g |
* @param g |
1291 |
* Graphics2D to paint the preview into |
* Graphics2D to paint the preview into |
1334 |
quickPreviewHint = 0; |
quickPreviewHint = 0; |
1335 |
|
|
1336 |
graphics.dispose(); |
graphics.dispose(); |
1337 |
|
|
1338 |
// Something has been drawn |
// Something has been drawn |
1339 |
return true; |
return true; |
1340 |
} |
} |
1350 |
if (mapImage != null) |
if (mapImage != null) |
1351 |
graphics.drawImage(mapImage, getBounds().width |
graphics.drawImage(mapImage, getBounds().width |
1352 |
- mapImage.getWidth() - 10, getBounds().height |
- mapImage.getWidth() - 10, getBounds().height |
1353 |
- mapImage.getHeight() - 10, this); |
- mapImage.getHeight() - 10, null); |
1354 |
|
|
1355 |
// If still rendering, paint a gray shadow or so... |
// If still rendering, paint a gray shadow or so... |
1356 |
if (bgExecuter != null && bgExecuter.isRunning() |
if (bgExecuter != null && bgExecuter.isRunning() |
1357 |
|| localExecuter != null && localExecuter.isRunning()) { |
|| localExecuter != null && localExecuter.isRunning()) { |
1358 |
|
|
1359 |
|
Color c = graphics.getColor(); |
1360 |
graphics.setColor(Color.BLACK); |
graphics.setColor(Color.BLACK); |
1361 |
|
|
1362 |
graphics.setFont(waitFont); |
graphics.setFont(waitFont); |
1363 |
graphics.drawString("Wait...", 40, 70); //i8n |
graphics.drawString("Wait...", 40, 70); // i8n |
1364 |
|
|
1365 |
graphics.setColor(getMapBackgroundColor()); |
graphics.setColor(c); |
1366 |
} |
} |
1367 |
|
|
1368 |
} |
} |
1372 |
* |
* |
1373 |
* @return |
* @return |
1374 |
*/ |
*/ |
1375 |
synchronized protected BufferedImage updateFinalImage() { |
synchronized protected Image updateFinalImage() { |
|
|
|
|
final Graphics2D finalG = (Graphics2D) getFinalImage().getGraphics(); |
|
|
finalG.setBackground(getMapBackgroundColor()); |
|
1376 |
|
|
1377 |
// Render the two map images first, into the preFinalImage |
// Render the two map images first, into the preFinalImage |
1378 |
if (bgExecuter != null) |
if (bgExecuter != null) { |
|
{ |
|
1379 |
final Graphics2D preFinalG = (Graphics2D) getPreFinalImage() |
final Graphics2D preFinalG = (Graphics2D) getPreFinalImage() |
1380 |
.getGraphics(); |
.getGraphics(); |
1381 |
preFinalG.setBackground(getMapBackgroundColor()); |
preFinalG.setBackground(getMapBackgroundColor()); |
1382 |
|
|
1383 |
preFinalG.drawImage(getBgImage(), 0, 0, getMapBackgroundColor(), |
preFinalG.drawImage(getBgImage(), 0, 0, getMapBackgroundColor(), |
1384 |
null); |
null); |
1385 |
|
|
1386 |
// // Draw the local layers image |
// // Draw the local layers image |
1387 |
preFinalG.drawImage(getLocalImage(), 0, 0, null); |
preFinalG.drawImage(getLocalImage(), 0, 0, null); |
1388 |
preFinalG.dispose(); |
preFinalG.dispose(); |
1389 |
|
|
1390 |
} else { |
} else { |
1391 |
preFinalImage = getLocalImage(); |
preFinalImage = getLocalImage(); |
1392 |
} |
} |
1393 |
|
|
1394 |
|
final Graphics2D finalG = getFinalImage().createGraphics(); |
1395 |
|
finalG.setBackground(getMapBackgroundColor()); |
1396 |
finalG.drawImage(getPreFinalImage(), imageOrigin.x, imageOrigin.y, |
finalG.drawImage(getPreFinalImage(), imageOrigin.x, imageOrigin.y, |
1397 |
getMapBackgroundColor(), null); |
getMapBackgroundColor(), null); |
1398 |
|
|
1410 |
return finalImage; |
return finalImage; |
1411 |
} |
} |
1412 |
|
|
1413 |
private Image getFinalImage() { |
private BufferedImage getFinalImage() { |
1414 |
|
// |
1415 |
if (finalImage == null) { |
if (finalImage == null) { |
1416 |
finalImage = null; |
// Rectangle curPaintArea = getVisibleRect(); |
1417 |
Rectangle curPaintArea = getVisibleRect(); |
finalImage = new BufferedImage(getBounds().width, |
1418 |
finalImage = new BufferedImage(curPaintArea.width, |
getBounds().height, BufferedImage.TYPE_INT_RGB); |
|
curPaintArea.height, BufferedImage.TYPE_INT_RGB); |
|
1419 |
|
|
1420 |
requestStartRendering(); |
requestStartRendering(); |
1421 |
} |
} |
1423 |
} |
} |
1424 |
|
|
1425 |
private Image getPreFinalImage() { |
private Image getPreFinalImage() { |
1426 |
if (preFinalImage == null) { |
// if (preFinalImage == null) { |
1427 |
preFinalImage = null; |
// |
1428 |
Rectangle curPaintArea = getVisibleRect(); |
// // Rectangle curPaintArea = getVisibleRect(); |
1429 |
|
// // preFinalImage = new BufferedImage(curPaintArea.width, |
1430 |
preFinalImage = new BufferedImage(curPaintArea.width, |
// // curPaintArea.height, BufferedImage.TYPE_INT_RGB); |
1431 |
curPaintArea.height, BufferedImage.TYPE_INT_RGB); |
// |
1432 |
|
// preFinalImage = createImage(getBounds().width, getBounds().height); |
1433 |
requestStartRendering(); |
// |
1434 |
} |
// requestStartRendering(); |
1435 |
|
// } |
1436 |
return preFinalImage; |
return preFinalImage; |
1437 |
} |
} |
1438 |
|
|
1441 |
* cached images while setting it together. |
* cached images while setting it together. |
1442 |
**/ |
**/ |
1443 |
Point imageOrigin = new Point(0, 0); |
Point imageOrigin = new Point(0, 0); |
1444 |
|
private final GTRenderer localRenderer; |
1445 |
|
|
1446 |
/** |
/** |
1447 |
* Starts rendering on one or two threads |
* Starts rendering on one or two threads |
1451 |
if (!isWellDefined()) |
if (!isWellDefined()) |
1452 |
return; |
return; |
1453 |
|
|
1454 |
if (bgExecuter != null){ |
if (bgExecuter != null) { |
1455 |
// Stop all renderers |
// Stop all renderers |
1456 |
bgExecuter.cancelTask(); |
bgExecuter.cancelTask(); |
1457 |
} |
} |
1458 |
|
|
1459 |
if (localExecuter != null){ |
if (localExecuter != null) { |
1460 |
localExecuter.cancelTask(); |
localExecuter.cancelTask(); |
1461 |
} |
} |
1462 |
|
|
1463 |
Rectangle curPaintArea = getVisibleRect(); |
Rectangle curPaintArea = getVisibleRect(); |
1464 |
|
|
|
labelCache.clear(); |
|
1465 |
|
|
1466 |
/** |
/** |
1467 |
* We have to set new renderer |
* We have to set new renderer |
1468 |
*/ |
*/ |
1469 |
|
|
1470 |
if (getBgContext() != null) { |
if (getBgContext() != null) { |
1471 |
bgExecuter = new RenderingExecutor(this, 333l); |
// bgExecuter = new RenderingExecutor(); |
1472 |
LOGGER.debug("starting bg renderer:"); |
// LOGGER.debug("starting bg renderer:"); |
1473 |
// /* System.out.println("rendering"); */ |
// // /* System.out.println("rendering"); */ |
1474 |
final GTRenderer createGTRenderer = GTUtil.createGTRenderer( |
// final GTRenderer createGTRenderer = GTUtil.createGTRenderer( |
1475 |
bgContext, getRendererHints()); |
// bgContext, getRendererHints()); |
1476 |
createGTRenderer.setJava2DHints(getJava2dHints()); |
// createGTRenderer.setJava2DHints(getJava2dHints()); |
1477 |
bgExecuter.submit(getBgContext().getAreaOfInterest(), curPaintArea, |
// bgExecuter.submit(getBgContext().getAreaOfInterest(), |
1478 |
(Graphics2D) getBgImage().getGraphics(), createGTRenderer); |
// curPaintArea, |
1479 |
|
// (Graphics2D) getBgImage().getGraphics(), createGTRenderer); |
1480 |
} |
} |
1481 |
|
|
1482 |
if (getContext() != null) { |
if (getContext() != null) { |
1483 |
// localExecuter = new RenderingExecutor(this, 150l); |
// localExecuter = new RenderingExecutor(this, 150l); |
1484 |
LOGGER.debug("starting local renderer:"); |
// LOGGER.debug("starting local renderer:"); |
1485 |
final GTRenderer createGTRenderer = GTUtil.createGTRenderer( |
|
1486 |
localContext, getRendererHints()); |
// Clear label cache |
1487 |
createGTRenderer.setJava2DHints(getJava2dHints()); |
labelCache.clear(); |
1488 |
localExecuter.submit(getContext().getAreaOfInterest(), |
Map<Object, Object> rh = localRenderer.getRendererHints(); |
1489 |
|
rh.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache); |
1490 |
|
localRenderer.setRendererHints(rh); |
1491 |
|
|
1492 |
|
boolean submitted = localExecuter.submit(getContext().getAreaOfInterest(), |
1493 |
curPaintArea, (Graphics2D) getLocalImage().getGraphics(), |
curPaintArea, (Graphics2D) getLocalImage().getGraphics(), |
1494 |
createGTRenderer); |
localRenderer, getWorldToScreenTransform()); |
1495 |
|
if (submitted) repainterTimer.restart(); |
1496 |
|
else requestStartRendering = true; // Try to start rendering again in a moment |
1497 |
} |
} |
1498 |
|
|
1499 |
updateCursor(); |
updateCursor(); |
1503 |
/** |
/** |
1504 |
* Lazyly initializes a {@link BufferedImage} for the background renderer. |
* Lazyly initializes a {@link BufferedImage} for the background renderer. |
1505 |
*/ |
*/ |
1506 |
private BufferedImage getBgImage() { |
private Image getBgImage() { |
1507 |
|
// |
1508 |
if (bgImage == null) { |
// if (bgImage == null) { |
1509 |
Rectangle curPaintArea = getVisibleRect(); |
// bgImage = createImage(getBounds().width, getBounds().height); |
1510 |
|
// } |
|
bgImage = new BufferedImage(curPaintArea.width + 1, |
|
|
curPaintArea.height + 1, BufferedImage.TYPE_INT_ARGB); |
|
|
} |
|
1511 |
|
|
1512 |
return bgImage; |
return bgImage; |
1513 |
} |
} |
1543 |
private BufferedImage getLocalImage() { |
private BufferedImage getLocalImage() { |
1544 |
|
|
1545 |
if (localImage == null) { |
if (localImage == null) { |
1546 |
|
localImage = new BufferedImage(getBounds().width, |
1547 |
Rectangle curPaintArea = getVisibleRect(); |
getBounds().height, BufferedImage.TYPE_INT_ARGB); |
|
|
|
|
localImage = new BufferedImage(curPaintArea.width + 1, |
|
|
curPaintArea.height + 1, BufferedImage.TYPE_INT_ARGB); |
|
1548 |
} |
} |
1549 |
|
|
1550 |
return localImage; |
return localImage; |
1551 |
} |
} |
1552 |
|
|
|
|
|
1553 |
/** |
/** |
1554 |
* Called by the {@linkplain XMapPane.RenderingTask} when rendering has been |
* Called by the {@linkplain XMapPane.RenderingTask} when rendering has been |
1555 |
* completed Publishes a {@linkplain MapPaneEvent} of type {@code |
* completed Publishes a {@linkplain MapPaneEvent} of type {@code |
1593 |
|
|
1594 |
} |
} |
1595 |
|
|
|
|
|
|
@Override |
|
|
public void propertyChange(final PropertyChangeEvent evt) { |
|
|
final String prop = evt.getPropertyName(); |
|
|
|
|
|
if (prop.equalsIgnoreCase("crs")) { |
|
|
localContext.setAreaOfInterest(localContext.getAreaOfInterest(), |
|
|
(CoordinateReferenceSystem) evt.getNewValue()); |
|
|
} |
|
|
} |
|
|
|
|
1596 |
/** |
/** |
1597 |
* Korrigiert den {@link Envelope} aka {@code mapArea} auf die beste |
* Korrigiert den {@link Envelope} aka {@code mapArea} auf die beste |
1598 |
* erlaubte Flaeche damit die Massstabsbeschaenkungen noch eingehalten |
* erlaubte Flaeche damit die Massstabsbeschaenkungen noch eingehalten |
1911 |
mapPaneListeners.remove(l); |
mapPaneListeners.remove(l); |
1912 |
} |
} |
1913 |
|
|
1914 |
/** Stored the time used for the last real rendering in ms. **/ |
// /** Stored the time used for the last real rendering in ms. **/ |
1915 |
private long lastRenderingDuration = Long.MAX_VALUE; |
// private long lastRenderingDuration = Long.MAX_VALUE; |
1916 |
|
|
1917 |
// if null, no quick preview will be shown |
// if null, no quick preview will be shown |
1918 |
private int quickPreviewHint = 0; |
private int quickPreviewHint = 0; |
1926 |
*/ |
*/ |
1927 |
private RenderingHints java2dHints; |
private RenderingHints java2dHints; |
1928 |
|
|
1929 |
/** |
// /** |
1930 |
* Returns in milli seconds the time the last rending of the |
// * Returns in milli seconds the time the last rending of the |
1931 |
* {@link SelectableXMapPane} took. #Long.MAX_VALUE if the JMapPane has not |
// * {@link SelectableXMapPane} took. #Long.MAX_VALUE if the JMapPane has not |
1932 |
* been rendered yet. |
// * been rendered yet. |
1933 |
*/ |
// */ |
1934 |
public long getLastRenderingDuration() { |
// public long getLastRenderingDuration() { |
1935 |
return lastRenderingDuration; |
// return lastRenderingDuration; |
1936 |
} |
// } |
1937 |
|
|
1938 |
/** |
/** |
1939 |
* Should be called when the {@link JMapPane} is not needed no more to help |
* Should be called when the {@link JMapPane} is not needed no more to help |
1947 |
public void dispose() { |
public void dispose() { |
1948 |
if (isDisposed()) |
if (isDisposed()) |
1949 |
return; |
return; |
1950 |
|
|
|
|
|
1951 |
setPainting(false); |
setPainting(false); |
1952 |
|
|
1953 |
|
resizeTimer.stop(); |
1954 |
|
startRenderThreadsTimer.stop(); |
1955 |
|
|
1956 |
disposed = true; |
disposed = true; |
1957 |
|
|
1961 |
} |
} |
1962 |
|
|
1963 |
if (localExecuter != null) { |
if (localExecuter != null) { |
1964 |
|
int i = 0; |
1965 |
localExecuter.cancelTask(); |
localExecuter.cancelTask(); |
1966 |
|
while (i++ < 10 && localExecuter.isRunning()){ |
1967 |
|
try { |
1968 |
|
Thread.sleep(200); |
1969 |
|
} catch (InterruptedException e) { |
1970 |
|
// TODO Auto-generated catch block |
1971 |
|
e.printStackTrace(); |
1972 |
|
} |
1973 |
|
} |
1974 |
|
if (localExecuter.isRunning()) { |
1975 |
|
System.out.println("BAD BAD BAD... still running the thread...."); |
1976 |
|
} |
1977 |
localExecuter.dispose(); |
localExecuter.dispose(); |
1978 |
} |
} |
1979 |
|
|
|
startRenderThreadsTimer.stop(); |
|
1980 |
|
|
1981 |
if (bgImage != null) |
if (bgImage != null) { |
1982 |
bgImage.flush(); |
bgImage = dispose(bgImage); |
1983 |
if (localImage != null) |
bgImage = null; |
1984 |
localImage.flush(); |
// LangUtil.gcTotal(); |
1985 |
if (finalImage != null) |
} |
1986 |
finalImage.flush(); |
|
1987 |
if (preFinalImage != null) |
if (localImage != null) { |
1988 |
preFinalImage.flush(); |
localImage = dispose(localImage); |
1989 |
|
localImage = null; |
1990 |
|
// LangUtil.gcTotal(); |
1991 |
|
} |
1992 |
|
|
1993 |
|
if (finalImage != null) { |
1994 |
|
finalImage = dispose(finalImage); |
1995 |
|
finalImage = null; |
1996 |
|
// LangUtil.gcTotal(); |
1997 |
|
} |
1998 |
|
|
1999 |
|
if (preFinalImage != null) { |
2000 |
|
preFinalImage = dispose(preFinalImage); |
2001 |
|
preFinalImage=null; |
2002 |
|
} |
2003 |
|
|
2004 |
|
// LangUtil.gcTotal(); |
2005 |
|
|
2006 |
// Alle mapPaneListener entfernen |
// Alle mapPaneListener entfernen |
2007 |
mapPaneListeners.clear(); |
mapPaneListeners.clear(); |
2017 |
removeAll(); |
removeAll(); |
2018 |
} |
} |
2019 |
|
|
2020 |
|
private BufferedImage dispose(BufferedImage bi) { |
2021 |
|
|
2022 |
|
// System.out.println("vorher = " |
2023 |
|
// + new MbDecimalFormatter().format(LangUtil.gcTotal())); |
2024 |
|
bi.flush(); |
2025 |
|
return bi = null; |
2026 |
|
// System.out.println("nacher = " |
2027 |
|
// + new MbDecimalFormatter().format(LangUtil.gcTotal())); |
2028 |
|
// |
2029 |
|
// System.out.println("\n"); |
2030 |
|
} |
2031 |
|
|
2032 |
/** |
/** |
2033 |
* A flag indicating if dispose() has already been called. If true, then |
* A flag indicating if dispose() has already been called. If true, then |
2034 |
* further use of this {@link SelectableXMapPane} is undefined. |
* further use of this {@link SelectableXMapPane} is undefined. |
2171 |
drawRectangle(graphics, startPos, lastPos); |
drawRectangle(graphics, startPos, lastPos); |
2172 |
} |
} |
2173 |
|
|
2174 |
|
graphics.dispose(); |
2175 |
|
|
2176 |
} |
} |
2177 |
|
|
2178 |
} |
} |
2183 |
*/ |
*/ |
2184 |
protected void drawRectangle(final Graphics graphics, Point startPos, |
protected void drawRectangle(final Graphics graphics, Point startPos, |
2185 |
Point e) { |
Point e) { |
2186 |
|
|
2187 |
if (!isWellDefined()) return; |
if (!isWellDefined()) |
2188 |
|
return; |
2189 |
|
|
2190 |
// undraw last box/draw new box |
// undraw last box/draw new box |
2191 |
final int left = Math.min(startPos.x, e.x); |
final int left = Math.min(startPos.x, e.x); |
2192 |
final int right = Math.max(startPos.x, e.x); |
final int right = Math.max(startPos.x, e.x); |
2224 |
} |
} |
2225 |
|
|
2226 |
public void onRenderingPending() { |
public void onRenderingPending() { |
2227 |
// LOGGER.debug("Pending rendering updates the preview..."); |
// LOGGER.debug("Pending rendering updates the preview..."); |
2228 |
updateFinalImage(); |
updateFinalImage(); |
2229 |
repaint(); |
repaint(); |
2230 |
} |
} |