21 |
import java.awt.geom.Point2D; |
import java.awt.geom.Point2D; |
22 |
import java.awt.image.BufferedImage; |
import java.awt.image.BufferedImage; |
23 |
import java.io.IOException; |
import java.io.IOException; |
24 |
|
import java.util.ArrayList; |
25 |
import java.util.HashMap; |
import java.util.HashMap; |
26 |
import java.util.Map; |
import java.util.Map; |
27 |
import java.util.Vector; |
import java.util.Vector; |
58 |
import schmitzm.geotools.GTUtil; |
import schmitzm.geotools.GTUtil; |
59 |
import schmitzm.geotools.JTSUtil; |
import schmitzm.geotools.JTSUtil; |
60 |
import schmitzm.geotools.gui.SelectableXMapPane; |
import schmitzm.geotools.gui.SelectableXMapPane; |
61 |
|
import schmitzm.geotools.io.GeoImportUtil; |
62 |
import schmitzm.geotools.map.event.JMapPaneListener; |
import schmitzm.geotools.map.event.JMapPaneListener; |
63 |
import schmitzm.geotools.map.event.MapLayerAdapter; |
import schmitzm.geotools.map.event.MapLayerAdapter; |
64 |
import schmitzm.lang.LangUtil; |
import schmitzm.lang.LangUtil; |
185 |
.getPredefinedCursor(Cursor.WAIT_CURSOR); |
.getPredefinedCursor(Cursor.WAIT_CURSOR); |
186 |
|
|
187 |
final static Font waitFont = new Font("Arial", Font.BOLD, 30); |
final static Font waitFont = new Font("Arial", Font.BOLD, 30); |
188 |
|
final String waitMsg = SwingUtil.R("WaitMess"); |
189 |
|
final static Font errorFont = new Font("Arial", Font.BOLD, 13); |
190 |
|
|
191 |
/** |
/** |
192 |
* Flag fuer Modus "Heran zoomen". |
* Flag fuer Modus "Heran zoomen". |
247 |
|
|
248 |
@Override |
@Override |
249 |
public void layerAdded(final MapLayerListEvent event) { |
public void layerAdded(final MapLayerListEvent event) { |
250 |
event.getLayer().addMapLayerListener(bgMapLayerListener); |
|
251 |
|
MapLayer layer = event.getLayer(); |
252 |
|
|
253 |
|
layer.addMapLayerListener(bgMapLayerListener); |
254 |
|
|
255 |
if (localContext.getLayers().length == 0 |
if (localContext.getLayers().length == 0 |
256 |
&& bgContext.getLayers().length == 1) { // the first one and |
&& bgContext.getLayers().length == 1) { // the first one and |
459 |
}; |
}; |
460 |
|
|
461 |
private final GTRenderer localRenderer = GTUtil.createGTRenderer(); |
private final GTRenderer localRenderer = GTUtil.createGTRenderer(); |
462 |
|
|
463 |
private final GTRenderer bgRenderer = GTUtil.createGTRenderer(); |
private final GTRenderer bgRenderer = GTUtil.createGTRenderer(); |
464 |
|
|
465 |
/** |
/** |
530 |
// if null, no quick preview will be shown |
// if null, no quick preview will be shown |
531 |
private int quickPreviewHint = 0; |
private int quickPreviewHint = 0; |
532 |
|
|
533 |
private Map<Object, Object> rendererHints; |
private Map<Object, Object> rendererHints = GTUtil |
534 |
|
.getDefaultGTRendererHints(localRenderer); |
535 |
|
|
536 |
private volatile Boolean requestStartRendering = false; |
private volatile Boolean requestStartRendering = false; |
537 |
|
|
572 |
public final ZoomXMapPaneMouseListener zoomMapPaneMouseListener = new ZoomXMapPaneMouseListener( |
public final ZoomXMapPaneMouseListener zoomMapPaneMouseListener = new ZoomXMapPaneMouseListener( |
573 |
this); |
this); |
574 |
|
|
575 |
|
/** Is set if a renderer has an error **/ |
576 |
|
protected ArrayList<Exception> renderingErrors = new ArrayList<Exception>(); |
577 |
|
|
578 |
// TODO doku |
// TODO doku |
579 |
public XMapPane() { |
public XMapPane() { |
580 |
this(null, null); |
this(null, null); |
602 |
|
|
603 |
setOpaque(true); |
setOpaque(true); |
604 |
|
|
|
localRenderer.setJava2DHints(getJava2dHints()); |
|
|
|
|
605 |
if (localContext_ != null) |
if (localContext_ != null) |
606 |
setLocalContext(localContext_); |
setLocalContext(localContext_); |
607 |
|
|
908 |
localExecuter.cancelTask(); |
localExecuter.cancelTask(); |
909 |
while (i++ < 10 && localExecuter.isRunning()) { |
while (i++ < 10 && localExecuter.isRunning()) { |
910 |
try { |
try { |
911 |
Thread.sleep(200); |
Thread.sleep(100); |
912 |
} catch (final InterruptedException e) { |
} catch (final InterruptedException e) { |
913 |
// TODO Auto-generated catch block |
// TODO Auto-generated catch block |
914 |
e.printStackTrace(); |
e.printStackTrace(); |
1035 |
|
|
1036 |
SwingUtil.clearAround(graphics, painedArea, visibleArea); |
SwingUtil.clearAround(graphics, painedArea, visibleArea); |
1037 |
|
|
1038 |
addGadgets(graphics); |
addGadgets(graphics, true); |
1039 |
|
|
1040 |
quickPreviewHint = 0; |
quickPreviewHint = 0; |
1041 |
|
|
1042 |
|
repaintTimer.restart(); |
1043 |
|
|
1044 |
graphics.dispose(); |
graphics.dispose(); |
1045 |
|
|
1046 |
// Something has been drawn |
// Something has been drawn |
1104 |
* |
* |
1105 |
* @return |
* @return |
1106 |
*/ |
*/ |
1107 |
public Envelope getMapArea() { |
public ReferencedEnvelope getMapArea() { |
1108 |
if (mapArea == null) { |
if (mapArea == null) { |
1109 |
ReferencedEnvelope mapArea_ = null; |
ReferencedEnvelope mapArea_ = null; |
1110 |
try { |
try { |
1115 |
|
|
1116 |
if (mapArea_ != null) { |
if (mapArea_ != null) { |
1117 |
mapImageInvalid = true; /* note we need to redraw */ |
mapImageInvalid = true; /* note we need to redraw */ |
1118 |
// setMapArea(mapArea_); // results in a loop |
// setMapArea(mapArea_); // results in a loop |
1119 |
mapArea = bestAllowedMapArea(mapArea_); |
mapArea = bestAllowedMapArea(mapArea_); |
1120 |
} |
} |
1121 |
} |
} |
1123 |
if (mapArea == null) |
if (mapArea == null) |
1124 |
return null; |
return null; |
1125 |
|
|
1126 |
return new Envelope(mapArea); |
if (localContext.getCoordinateReferenceSystem() == null) |
1127 |
|
try { |
1128 |
|
localContext.setCoordinateReferenceSystem(GeoImportUtil |
1129 |
|
.getDefaultCRS()); |
1130 |
|
} catch (TransformException e) { |
1131 |
|
// TODO Auto-generated catch block |
1132 |
|
e.printStackTrace(); |
1133 |
|
} catch (FactoryException e) { |
1134 |
|
// TODO Auto-generated catch block |
1135 |
|
e.printStackTrace(); |
1136 |
|
} |
1137 |
|
|
1138 |
|
return new ReferencedEnvelope(mapArea, localContext |
1139 |
|
.getCoordinateReferenceSystem()); |
1140 |
} |
} |
1141 |
|
|
1142 |
/** |
/** |
1220 |
} |
} |
1221 |
|
|
1222 |
public Map<Object, Object> getRendererHints() { |
public Map<Object, Object> getRendererHints() { |
1223 |
|
// Clear label cache |
1224 |
|
labelCache.clear(); |
1225 |
|
rendererHints.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache); |
1226 |
|
|
1227 |
return rendererHints; |
return rendererHints; |
1228 |
} |
} |
1229 |
|
|
1404 |
repaintTimer.stop(); |
repaintTimer.stop(); |
1405 |
updateFinalImage(); |
updateFinalImage(); |
1406 |
repaint(); |
repaint(); |
1407 |
|
if (renderingErrors.size() > 0) |
1408 |
|
renderingErrors.remove(0); |
1409 |
} |
} |
1410 |
|
|
1411 |
/** |
/** |
1419 |
* @see MapPaneListener#onRenderingStopped(org.geotools.swing.event.MapPaneEvent) |
* @see MapPaneListener#onRenderingStopped(org.geotools.swing.event.MapPaneEvent) |
1420 |
*/ |
*/ |
1421 |
public void onRenderingFailed(final Exception renderingError) { |
public void onRenderingFailed(final Exception renderingError) { |
1422 |
|
this.renderingErrors.add(renderingError); |
1423 |
|
if (renderingErrors.size() > 3) |
1424 |
|
renderingErrors.remove(0); |
1425 |
repaintTimer.stop(); |
repaintTimer.stop(); |
1426 |
LOGGER.warn("Rendering failed", renderingError); |
LOGGER.warn("Rendering failed", renderingError); |
1427 |
updateFinalImage(); |
updateFinalImage(); |
1443 |
// Maybe update the cursor and maybe stop the repainting timer |
// Maybe update the cursor and maybe stop the repainting timer |
1444 |
updateCursor(); |
updateCursor(); |
1445 |
|
|
1446 |
super.paintComponent(g); // candidate for removal |
// super.paintComponent(g); // candidate for removal |
1447 |
|
|
1448 |
boolean paintedSomething = false; |
boolean paintedSomething = false; |
1449 |
|
|
1886 |
} |
} |
1887 |
|
|
1888 |
private void setRendererHints(final Map<Object, Object> rendererHints) { |
private void setRendererHints(final Map<Object, Object> rendererHints) { |
1889 |
this.rendererHints = rendererHints; |
if (rendererHints != null) |
1890 |
|
this.rendererHints = rendererHints; |
1891 |
} |
} |
1892 |
|
|
1893 |
/** |
/** |
1946 |
*/ |
*/ |
1947 |
|
|
1948 |
if (getBgContext() != null) { |
if (getBgContext() != null) { |
1949 |
|
bgRenderer.setJava2DHints(getJava2dHints()); |
1950 |
|
bgRenderer.setRendererHints(getRendererHints()); |
1951 |
|
|
1952 |
// bgExecuter = new RenderingExecutor(); |
// bgExecuter = new RenderingExecutor(); |
1953 |
// LOGGER.debug("starting bg renderer:"); |
// LOGGER.debug("starting bg renderer:"); |
1954 |
// // /* System.out.println("rendering"); */ |
// // /* System.out.println("rendering"); */ |
1964 |
// localExecuter = new RenderingExecutor(this, 150l); |
// localExecuter = new RenderingExecutor(this, 150l); |
1965 |
// LOGGER.debug("starting local renderer:"); |
// LOGGER.debug("starting local renderer:"); |
1966 |
|
|
1967 |
// Clear label cache |
localRenderer.setJava2DHints(getJava2dHints()); |
1968 |
labelCache.clear(); |
localRenderer.setRendererHints(getRendererHints()); |
1969 |
final Map<Object, Object> rh = localRenderer.getRendererHints(); |
|
1970 |
rh.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache); |
ReferencedEnvelope areaOfInterest = getMapArea(); |
1971 |
localRenderer.setRendererHints(rh); |
final boolean submitted = localExecuter.submit(areaOfInterest, |
1972 |
|
curPaintArea, (Graphics2D) getLocalImage().getGraphics(), |
1973 |
final boolean submitted = localExecuter.submit(getContext() |
localRenderer, getWorldToScreenTransform()); |
|
.getAreaOfInterest(), curPaintArea, |
|
|
(Graphics2D) getLocalImage().getGraphics(), localRenderer, |
|
|
getWorldToScreenTransform()); |
|
1974 |
if (submitted) |
if (submitted) |
1975 |
repaintTimer.restart(); |
repaintTimer.restart(); |
1976 |
else |
else |
2049 |
} else { |
} else { |
2050 |
// Allow one last rendering |
// Allow one last rendering |
2051 |
if (repaintTimer.isRunning()) { |
if (repaintTimer.isRunning()) { |
2052 |
|
System.out.println("one last rendering...."); |
2053 |
repaintTimer.stop(); |
repaintTimer.stop(); |
2054 |
updateFinalImage(); |
updateFinalImage(); |
2055 |
repaint(); |
repaint(); |
2126 |
imageOrigin.y, finalImageWidth, finalImageHeight); |
imageOrigin.y, finalImageWidth, finalImageHeight); |
2127 |
SwingUtil.clearAround(finalG, painedArea, getVisibleRect()); |
SwingUtil.clearAround(finalG, painedArea, getVisibleRect()); |
2128 |
|
|
2129 |
addGadgets(finalG); |
addGadgets(finalG, false); |
2130 |
|
|
2131 |
finalG.dispose(); |
finalG.dispose(); |
2132 |
|
|
2136 |
/** |
/** |
2137 |
* Paints some optional stuff into the given {@link Graphics2D}. Usually |
* Paints some optional stuff into the given {@link Graphics2D}. Usually |
2138 |
* called as the last layer when {@link #updateFinalImage()} |
* called as the last layer when {@link #updateFinalImage()} |
2139 |
|
* |
2140 |
|
* @param forceWait |
2141 |
|
* if <code>true</code>, a Wait-message will be painted even |
2142 |
|
* though the rendering threads may not yet have started. If |
2143 |
|
* <code>false</code>, it will only depend on |
2144 |
|
* {@link #localExecuter.isRunning} and #bgExecuter.isRunning |
2145 |
*/ |
*/ |
2146 |
private void addGadgets(final Graphics2D graphics) { |
private void addGadgets(final Graphics2D graphics, boolean forceWait) { |
2147 |
|
|
2148 |
// Paint a logo to the bottom right if available |
// Paint a logo to the bottom right if available |
2149 |
if (mapImage != null) { |
if (mapImage != null) { |
2151 |
- mapImage.getWidth() - 10, getBounds().height |
- mapImage.getWidth() - 10, getBounds().height |
2152 |
- mapImage.getHeight() - 10, null); |
- mapImage.getHeight() - 10, null); |
2153 |
} |
} |
2154 |
|
|
2155 |
|
|
2156 |
|
int y = 17; |
2157 |
|
|
2158 |
// If the rendering process is still running, indicate this is the image |
// If the rendering process is still running, indicate this is the image |
2159 |
if (bgExecuter != null && bgExecuter.isRunning() |
if (forceWait || bgExecuter != null && bgExecuter.isRunning() |
2160 |
|| localExecuter != null && localExecuter.isRunning()) { |
|| localExecuter != null && localExecuter.isRunning()) { |
2161 |
|
|
2162 |
|
y+=8; |
2163 |
|
|
2164 |
final Color c = graphics.getColor(); |
final Color c = graphics.getColor(); |
2165 |
graphics.setFont(waitFont); |
graphics.setFont(waitFont); |
2166 |
String waitStr = "Wait..."; //i8n |
// String waitStr = "Wait..."; // i8n |
2167 |
|
|
2168 |
graphics.setColor(Color.WHITE); |
graphics.setColor(getMapBackgroundColor()); |
2169 |
graphics.drawString(waitStr, 39, 69); |
graphics.drawString(waitMsg, 5, y); |
2170 |
|
graphics.setColor(getMapBackgroundColor()); |
2171 |
|
graphics.drawString(waitMsg, 7, y+2); |
2172 |
graphics.setColor(Color.BLACK); |
graphics.setColor(Color.BLACK); |
2173 |
graphics.drawString(waitStr, 40, 70); |
graphics.drawString(waitMsg, 6, y+1); |
2174 |
|
|
2175 |
|
graphics.setColor(c); |
2176 |
|
|
2177 |
|
y += 24; |
2178 |
|
} |
2179 |
|
|
2180 |
|
if (renderingErrors != null) { |
2181 |
|
|
2182 |
|
final Color c = graphics.getColor(); |
2183 |
|
graphics.setFont(errorFont); |
2184 |
|
|
2185 |
|
for (Exception ex : renderingErrors) { |
2186 |
|
|
2187 |
|
if (ex instanceof java.lang.IllegalArgumentException |
2188 |
|
&& ex.getMessage().equals( |
2189 |
|
"Argument \"sourceCRS\" should not be null.")) |
2190 |
|
continue; |
2191 |
|
|
2192 |
|
String errStr = ex.getLocalizedMessage(); |
2193 |
|
|
2194 |
|
graphics.setColor(Color.WHITE); |
2195 |
|
graphics.drawString(errStr, 5, y); |
2196 |
|
graphics.setColor(Color.RED); |
2197 |
|
graphics.drawString(errStr, 6, y + 1); |
2198 |
|
|
2199 |
|
y += 19; |
2200 |
|
} |
2201 |
|
|
2202 |
graphics.setColor(c); |
graphics.setColor(c); |
2203 |
} |
} |
2205 |
} |
} |
2206 |
|
|
2207 |
/** |
/** |
2208 |
* Sets the {@link #mapArea} to best possibly present the given features. If only one |
* Sets the {@link #mapArea} to best possibly present the given features. If |
2209 |
* single point is given, the window is moved over the point. |
* only one single point is given, the window is moved over the point. |
2210 |
* |
* |
2211 |
* @param features |
* @param features |
2212 |
* if <code>null</code> or size==0, the function doesn nothing. |
* if <code>null</code> or size==0, the function doesn nothing. |