36 |
import org.geotools.geometry.jts.JTS; |
import org.geotools.geometry.jts.JTS; |
37 |
import org.geotools.geometry.jts.ReferencedEnvelope; |
import org.geotools.geometry.jts.ReferencedEnvelope; |
38 |
import org.geotools.map.DefaultMapContext; |
import org.geotools.map.DefaultMapContext; |
39 |
|
import org.geotools.map.DefaultMapLayer; |
40 |
import org.geotools.map.MapContext; |
import org.geotools.map.MapContext; |
41 |
import org.geotools.map.MapLayer; |
import org.geotools.map.MapLayer; |
42 |
import org.geotools.map.event.MapLayerEvent; |
import org.geotools.map.event.MapLayerEvent; |
49 |
import org.geotools.renderer.lite.LabelCache; |
import org.geotools.renderer.lite.LabelCache; |
50 |
import org.geotools.renderer.lite.RendererUtilities; |
import org.geotools.renderer.lite.RendererUtilities; |
51 |
import org.geotools.renderer.lite.StreamingRenderer; |
import org.geotools.renderer.lite.StreamingRenderer; |
52 |
|
import org.geotools.resources.image.ImageUtilities; |
53 |
|
import org.geotools.styling.Style; |
54 |
import org.geotools.swing.JMapPane; |
import org.geotools.swing.JMapPane; |
55 |
import org.geotools.swing.event.MapMouseEvent; |
import org.geotools.swing.event.MapMouseEvent; |
56 |
import org.geotools.swing.event.MapPaneEvent; |
import org.geotools.swing.event.MapPaneEvent; |
68 |
import schmitzm.geotools.io.GeoImportUtil; |
import schmitzm.geotools.io.GeoImportUtil; |
69 |
import schmitzm.geotools.map.event.JMapPaneListener; |
import schmitzm.geotools.map.event.JMapPaneListener; |
70 |
import schmitzm.geotools.map.event.MapLayerAdapter; |
import schmitzm.geotools.map.event.MapLayerAdapter; |
71 |
|
import schmitzm.geotools.styling.StylingUtil; |
72 |
import schmitzm.lang.LangUtil; |
import schmitzm.lang.LangUtil; |
73 |
import schmitzm.swing.JPanel; |
import schmitzm.swing.JPanel; |
74 |
import schmitzm.swing.SwingUtil; |
import schmitzm.swing.SwingUtil; |
125 |
return tool; |
return tool; |
126 |
} |
} |
127 |
|
|
128 |
|
/** |
129 |
|
* If the {@link JPanel} is disabled, it shows nothing and the images are disposed. |
130 |
|
*/ |
131 |
|
@Override |
132 |
|
public void setEnabled(boolean enabled) { |
133 |
|
super.setEnabled(enabled); |
134 |
|
if (enabled == false) |
135 |
|
disposeImages(); |
136 |
|
else |
137 |
|
requestStartRendering(); |
138 |
|
} |
139 |
|
|
140 |
private static final int IMAGETYPE_withAlpha = BufferedImage.TYPE_4BYTE_ABGR; |
private static final int IMAGETYPE_withAlpha = BufferedImage.TYPE_4BYTE_ABGR; |
141 |
|
|
142 |
private final static Logger LOGGER = Logger.getLogger(XMapPane.class); |
private final static Logger LOGGER = Logger.getLogger(XMapPane.class); |
625 |
*/ |
*/ |
626 |
public XMapPane(final MapContext localContext_, |
public XMapPane(final MapContext localContext_, |
627 |
final Map<Object, Object> rendererHints) { |
final Map<Object, Object> rendererHints) { |
628 |
|
|
629 |
super(true); |
super(true); |
630 |
|
|
631 |
|
blinkTimer = initBlinkTimer(); |
632 |
|
|
633 |
|
// A default setting |
634 |
|
RenderingHints hintsJava2d = ImageUtilities.NN_INTERPOLATION_HINT; |
635 |
|
setJava2dHints(hintsJava2d); |
636 |
|
|
637 |
setRendererHints(rendererHints); |
setRendererHints(rendererHints); |
638 |
|
|
639 |
setOpaque(true); |
setOpaque(true); |
741 |
@Override |
@Override |
742 |
public void actionPerformed(final ActionEvent e) { |
public void actionPerformed(final ActionEvent e) { |
743 |
synchronized (requestStartRendering) { |
synchronized (requestStartRendering) { |
744 |
if (requestStartRendering && isWellDefined()) { |
if (requestStartRendering && isWellDefined() && isEnabled()) { |
745 |
|
|
746 |
if (localExecuter.isRunning()) { |
if (localExecuter.isRunning()) { |
747 |
localExecuter.cancelTask(); |
localExecuter.cancelTask(); |
835 |
|
|
836 |
final Envelope maxAllowedExtend = getMaxExtend(); |
final Envelope maxAllowedExtend = getMaxExtend(); |
837 |
|
|
838 |
|
// This variable is used to break the loop if it runs forever... |
839 |
|
Envelope lastCalculatedArea = null; |
840 |
|
/* |
841 |
|
* If a maxAllowedExtend is set, we have to honour that... |
842 |
|
*/ |
843 |
while (maxAllowedExtend != null && !maxAllowedExtend.contains(newArea) |
while (maxAllowedExtend != null && !maxAllowedExtend.contains(newArea) |
844 |
&& newArea != null && !newArea.isNull() |
&& newArea != null && !newArea.isNull() |
845 |
&& !Double.isNaN(newArea.getMinX()) |
&& !Double.isNaN(newArea.getMinX()) |
846 |
&& !Double.isNaN(newArea.getMaxX()) |
&& !Double.isNaN(newArea.getMaxX()) |
847 |
&& !Double.isNaN(newArea.getMinY()) |
&& !Double.isNaN(newArea.getMinY()) |
848 |
&& !Double.isNaN(newArea.getMaxY())) { |
&& !Double.isNaN(newArea.getMaxY())) // Due to Double precision |
849 |
/* |
// problems, this may |
850 |
* If a maxExtend is set, we have to honour that... |
// iterate for ever |
851 |
*/ |
{ |
852 |
|
|
853 |
|
if (newArea.equals(lastCalculatedArea)) |
854 |
|
break; |
855 |
|
// Check that we are not iterating for ever due to double precision |
856 |
|
// rounding errors |
857 |
|
lastCalculatedArea = newArea; |
858 |
|
|
859 |
// Exceeds top? Move down and maybe cut |
// Exceeds top? Move down and maybe cut |
860 |
if (newArea.getMaxY() > maxAllowedExtend.getMaxY()) { |
if (newArea.getMaxY() > maxAllowedExtend.getMaxY()) { |
959 |
.getCoordinateReferenceSystem()), false); |
.getCoordinateReferenceSystem()), false); |
960 |
} |
} |
961 |
} |
} |
962 |
|
|
963 |
} |
} |
964 |
|
|
965 |
return new ReferencedEnvelope(newArea, env |
return new ReferencedEnvelope(newArea, env |
1275 |
return null; |
return null; |
1276 |
} |
} |
1277 |
|
|
1278 |
return JTSUtil |
return JTSUtil.fixAspectRatio(getVisibleRect(), |
1279 |
.fixAspectRatio(getVisibleRect(), addDefaultMargin(layerBounds), true); |
addDefaultMargin(layerBounds), true); |
1280 |
|
|
1281 |
} |
} |
1282 |
return maxExtend; |
return maxExtend; |
1977 |
private long lastRenderingDuration = 1000; |
private long lastRenderingDuration = 1000; |
1978 |
private XMapPaneTool tool = null; |
private XMapPaneTool tool = null; |
1979 |
|
|
1980 |
|
private Timer blinkTimer; |
1981 |
|
|
1982 |
/** |
/** |
1983 |
* Set the minimum (nearest) allowed zoom scale. This is the bigger number |
* Set the minimum (nearest) allowed zoom scale. This is the bigger number |
1984 |
* value of the two. If <code>null</code> is passed, Double.MAXVALUE are |
* value of the two. If <code>null</code> is passed, Double.MAXVALUE are |
2131 |
* X-Koordinate der BIS-Position |
* X-Koordinate der BIS-Position |
2132 |
* @param py |
* @param py |
2133 |
* Y-Koordinate der BIS-Position |
* Y-Koordinate der BIS-Position |
|
* @param winToGeotransform |
|
|
* Eine Window to Geo transform. If <code>null</code>, |
|
|
* {@link #getScreenToWorld()} is used. |
|
2134 |
*/ |
*/ |
2135 |
public Envelope tranformGeoToWindow(final double ox, final double oy, |
public Envelope tranformGeoToWindow(final double ox, final double oy, |
2136 |
final double px, final double py) { |
final double px, final double py) { |
2147 |
} |
} |
2148 |
|
|
2149 |
/** |
/** |
2150 |
|
* Transformiert einen Geo-Koordinate in eine Fenster-Koordinaten. |
2151 |
|
* |
2152 |
|
* @param x |
2153 |
|
* X-Koordinate der VON-Position |
2154 |
|
* @param y |
2155 |
|
* Y-Koordinate der VON-Position |
2156 |
|
*/ |
2157 |
|
public Point2D tranformGeoToWindow(final double x, final double y) { |
2158 |
|
return getWorldToScreenTransform().transform(new Point2D.Double(x, y), |
2159 |
|
null); |
2160 |
|
} |
2161 |
|
|
2162 |
|
/** |
2163 |
* Transformiert einen Fenster-Koordinaten-Bereich in Geo-Koordinaten. |
* Transformiert einen Fenster-Koordinaten-Bereich in Geo-Koordinaten. |
2164 |
* |
* |
2165 |
* @param ox |
* @param ox |
2282 |
SwingUtil.clearAround(finalG, painedArea, getVisibleRect(), |
SwingUtil.clearAround(finalG, painedArea, getVisibleRect(), |
2283 |
getMapBackgroundColor()); |
getMapBackgroundColor()); |
2284 |
|
|
2285 |
// addGadgets(finalG, false); |
addGadgets(finalG, false); |
2286 |
|
|
2287 |
finalG.dispose(); |
finalG.dispose(); |
2288 |
|
|
2719 |
return defaultMaxMapExtendMode; |
return defaultMaxMapExtendMode; |
2720 |
} |
} |
2721 |
|
|
2722 |
|
final static int BLINK_TIMER_DEPLAY = 800; |
2723 |
|
|
2724 |
|
private Timer initBlinkTimer() { |
2725 |
|
Timer timer = new Timer(BLINK_TIMER_DEPLAY, new ActionListener() { |
2726 |
|
|
2727 |
|
@Override |
2728 |
|
public void actionPerformed(ActionEvent e) { |
2729 |
|
XMapPane.this.repaint(300); |
2730 |
|
} |
2731 |
|
}); |
2732 |
|
timer.setDelay(BLINK_TIMER_DEPLAY); |
2733 |
|
timer.setRepeats(false); |
2734 |
|
return timer; |
2735 |
|
} |
2736 |
|
|
2737 |
|
/** |
2738 |
|
* Makes the given {@link FeatureCollection} bink in the map for a moment |
2739 |
|
*/ |
2740 |
|
public void blink( |
2741 |
|
FeatureCollection<SimpleFeatureType, SimpleFeature> features) { |
2742 |
|
{ |
2743 |
|
blinkTimer.stop(); |
2744 |
|
repaint(); |
2745 |
|
blinkTimer = initBlinkTimer(); |
2746 |
|
|
2747 |
|
DefaultMapContext mc = new DefaultMapContext(getMapContext() |
2748 |
|
.getCoordinateReferenceSystem()); |
2749 |
|
|
2750 |
|
Style style = StylingUtil.STYLE_FACTORY.createStyle(); |
2751 |
|
style.featureTypeStyles().add( |
2752 |
|
StylingUtil.createBlinkFeatureTypeStyle(features)); |
2753 |
|
|
2754 |
|
// style = StylingUtil.createStyleSimple(features, Color.pink, |
2755 |
|
// Color.WHITE); |
2756 |
|
|
2757 |
|
DefaultMapLayer dml = new DefaultMapLayer(features, style); |
2758 |
|
mc.addLayer(dml); |
2759 |
|
|
2760 |
|
GTRenderer renderer = new StreamingRenderer(); |
2761 |
|
|
2762 |
|
renderer.setJava2DHints(getJava2dHints()); |
2763 |
|
|
2764 |
|
renderer.setContext(mc); |
2765 |
|
|
2766 |
|
Graphics2D g2d = (Graphics2D) getGraphics(); |
2767 |
|
renderer.paint(g2d, getVisibleRect(), getMapArea()); |
2768 |
|
|
2769 |
|
blinkTimer.start(); |
2770 |
|
|
2771 |
|
} |
2772 |
|
|
2773 |
|
} |
2774 |
|
|
2775 |
} |
} |