]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/geotools/swing/GisFieldViewer.java
GisFieldViewer before leaving to field trip
[gpl/argeo-slc.git] / runtime / org.argeo.slc.support.gis / src / main / java / org / argeo / slc / geotools / swing / GisFieldViewer.java
index a79cfb5f9bc1e763d450726d64174e74b16758dd..b9eb10c5396124a4f46460c0ffc39be5746de20f 100644 (file)
@@ -1,6 +1,12 @@
 package org.argeo.slc.geotools.swing;
 
 import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
 import java.io.IOException;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -14,28 +20,29 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.slc.core.deploy.DefaultResourceSet;
 import org.argeo.slc.core.deploy.ResourceSet;
 import org.argeo.slc.geotools.BeanFeatureTypeBuilder;
-import org.argeo.slc.gis.model.Position;
+import org.argeo.slc.gis.model.FieldPosition;
 import org.argeo.slc.jts.PositionProvider;
 import org.geotools.data.FileDataStoreFinder;
 import org.geotools.data.WorldFileReader;
-import org.geotools.feature.DefaultFeatureCollection;
-import org.geotools.feature.FeatureCollection;
 import org.geotools.gce.image.WorldImageFormat;
+import org.geotools.geometry.DirectPosition2D;
+import org.geotools.geometry.Envelope2D;
 import org.geotools.map.DefaultMapContext;
-import org.geotools.map.DefaultMapLayer;
 import org.geotools.map.MapContext;
 import org.geotools.map.MapLayer;
 import org.geotools.styling.RasterSymbolizer;
-import org.geotools.styling.SLD;
 import org.geotools.styling.Style;
 import org.geotools.styling.StyleBuilder;
 import org.geotools.swing.JMapFrame;
 import org.geotools.swing.JMapPane;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
+import org.geotools.swing.event.MapPaneAdapter;
+import org.geotools.swing.event.MapPaneEvent;
+import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.core.io.Resource;
 
+import com.vividsolutions.jts.geom.Coordinate;
+
 /**
  * GeoTools Quickstart demo application. Prompts the user for a shapefile and
  * displays its contents on the screen in a map frame
@@ -44,11 +51,11 @@ import org.springframework.core.io.Resource;
  *         http://svn.osgeo.org/geotools/trunk/demo/example/src/main/java/org
  *         /geotools/demo/Quickstart.java $
  */
-public class GisFieldViewer implements InitializingBean {
+public class GisFieldViewer implements InitializingBean, DisposableBean {
        private final static Log log = LogFactory.getLog(GisFieldViewer.class);
 
-       protected final static BeanFeatureTypeBuilder<Position> POSITION = new BeanFeatureTypeBuilder<Position>(
-                       Position.class);
+       protected final static BeanFeatureTypeBuilder<FieldPosition> POSITION = new BeanFeatureTypeBuilder<FieldPosition>(
+                       FieldPosition.class);
 
        private DateFormat fieldPositionDateFormat = new SimpleDateFormat(
                        "yyyyMMdd-HHmmss");
@@ -61,15 +68,21 @@ public class GisFieldViewer implements InitializingBean {
        private ResourceSet rasters = new DefaultResourceSet();
 
        private JMapPane mapPane;
+       private JMapFrame mapFrame;
 
        /** in s */
-       private Integer positionRefreshPeriod = 10;
+       private Integer positionRefreshPeriod = 1;
+
+       private FieldPosition currentPosition = null;
+       private Boolean positionProviderDisconnected = false;
+       private VersatileZoomTool versatileZoomTool;
 
        public static void main(String[] args) throws Exception {
                new GisFieldViewer().afterPropertiesSet();
        }
 
        public void afterPropertiesSet() {
+               new Thread(new PositionUpdater()).start();
 
                // Create map context
                MapContext mapContext = new DefaultMapContext();
@@ -77,24 +90,41 @@ public class GisFieldViewer implements InitializingBean {
 
                // Now display the map
                // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-               final JMapFrame frame = new JMapFrame(mapContext);
-               frame.enableStatusBar(true);
-               frame.enableToolBar(false);
-               frame.enableLayerTable(true);
-               frame.initComponents();
-               frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+               mapFrame = new JMapFrame(mapContext);
+               mapFrame.enableStatusBar(true);
+               mapFrame.enableToolBar(false);
+               mapFrame.enableLayerTable(true);
+               mapFrame.initComponents();
+               mapFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
 
-               frame.setSize(800, 600);
+               mapFrame.setSize(800, 600);
 
-               mapPane = frame.getMapPane();
-               mapPane.setCursorTool(new VersatileZoomTool());
+               mapPane = mapFrame.getMapPane();
+               versatileZoomTool = new VersatileZoomTool();
+               mapPane.setCursorTool(versatileZoomTool);
+
+               mapPane.addMapPaneListener(new CustomMapPaneListener());
 
                SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
-                               frame.setVisible(true);
+                               // Fullscreen
+                               // GraphicsEnvironment ge = GraphicsEnvironment
+                               // .getLocalGraphicsEnvironment();
+                               // GraphicsDevice[] devices = ge.getScreenDevices();
+                               // if (devices.length < 1)
+                               // throw new RuntimeException("No device available");
+                               // GraphicsDevice gd = devices[0];
+                               // mapFrame.setUndecorated(true);
+                               // // http://ubuntuforums.org/showthread.php?t=820924
+                               // mapFrame.setResizable(true);
+                               // gd.setFullScreenWindow(mapFrame);
+                               mapFrame.setVisible(true);
                        }
                });
 
+               // Center on position in order to facten first rendering
+               centerOnPosition();
+
                // Rasters
                prepareJaiForRasters();
                StyleBuilder styleBuilder = new StyleBuilder();
@@ -126,7 +156,11 @@ public class GisFieldViewer implements InitializingBean {
                        }
                }
 
-               new Thread(new PositionUpdater()).start();
+       }
+
+       public void destroy() throws Exception {
+               if (mapFrame != null)
+                       mapFrame.dispose();
        }
 
        private void prepareJaiForRasters() {
@@ -145,6 +179,37 @@ public class GisFieldViewer implements InitializingBean {
                }
        }
 
+       protected void receiveNewPosition(FieldPosition position) {
+               if (position != null && versatileZoomTool != null) {
+                       positionProviderDisconnected = false;
+                       currentPosition = position;
+                       Point2D point2d = new DirectPosition2D(currentPosition
+                                       .getLocation().getCoordinate().x, currentPosition
+                                       .getLocation().getCoordinate().y);
+                       versatileZoomTool.setFieldPosition(point2d);
+                       drawPositionLocation();
+               } else {
+                       positionProviderDisconnected = true;
+               }
+       }
+
+       protected void centerOnPosition() {
+               if (currentPosition == null)
+                       return;
+               Envelope2D env = new Envelope2D();
+               final double increment = 1d;
+               Coordinate positionCoo = currentPosition.getLocation().getCoordinate();
+               env.setFrameFromDiagonal(positionCoo.x - increment, positionCoo.y
+                               - increment, positionCoo.x + increment, positionCoo.y
+                               + increment);
+               getMapPane().setDisplayArea(env);
+
+       }
+
+       protected JMapPane getMapPane() {
+               return mapPane;
+       }
+
        public void setPositionProvider(PositionProvider positionProvider) {
                this.positionProvider = positionProvider;
        }
@@ -166,26 +231,38 @@ public class GisFieldViewer implements InitializingBean {
                public void run() {
                        MapLayer mapLayer = null;
                        while (true) {
-                               Position currentPosition = positionProvider.currentPosition();
-
-                               if (mapPane.getDisplayArea().contains(
-                                               currentPosition.getLocation().getCoordinate())) {
-                                       SimpleFeature feature = POSITION
-                                                       .buildFeature(currentPosition);
-                                       FeatureCollection<SimpleFeatureType, SimpleFeature> collection = new DefaultFeatureCollection(
-                                                       "Field Position "
-                                                                       + fieldPositionDateFormat
-                                                                                       .format(currentPosition
-                                                                                                       .getTimestamp()), POSITION
-                                                                       .getFeatureType());
-                                       collection.add(feature);
-                                       if (mapLayer != null)
-                                               mapPane.getMapContext().removeLayer(mapLayer);
-                                       Style style = SLD.createSimpleStyle(POSITION
-                                                       .getFeatureType(), Color.RED);
-                                       mapLayer = new DefaultMapLayer(collection, style, "");
-                                       mapPane.getMapContext().addLayer(mapLayer);
+                               FieldPosition currentPosition = positionProvider
+                                               .currentPosition();
+
+                               receiveNewPosition(currentPosition);
+                               // versatileZoomTool.setFieldPosition(new
+                               // Point2D(currentPosition
+                               // .getLocation().getX(), currentPosition.getLocation()
+                               // .getY()));
+
+                               if (currentPosition != null) {
+
+                                       // if (mapPane.getDisplayArea().contains(
+                                       // currentPosition.getLocation().getCoordinate())) {
+                                       // SimpleFeature feature = POSITION
+                                       // .buildFeature(currentPosition);
+                                       // FeatureCollection<SimpleFeatureType, SimpleFeature>
+                                       // collection = new DefaultFeatureCollection(
+                                       // "Field Position "
+                                       // + fieldPositionDateFormat
+                                       // .format(currentPosition
+                                       // .getTimestamp()),
+                                       // POSITION.getFeatureType());
+                                       // collection.add(feature);
+                                       // if (mapLayer != null)
+                                       // mapPane.getMapContext().removeLayer(mapLayer);
+                                       // Style style = SLD.createSimpleStyle(POSITION
+                                       // .getFeatureType(), Color.RED);
+                                       // mapLayer = new DefaultMapLayer(collection, style, "");
+                                       // mapPane.getMapContext().addLayer(mapLayer);
+                                       // }
                                }
+
                                try {
                                        Thread.sleep(positionRefreshPeriod * 1000);
                                } catch (InterruptedException e) {
@@ -194,6 +271,70 @@ public class GisFieldViewer implements InitializingBean {
                        }
                }
        }
+
+       protected void drawPositionLocation() {
+               SwingUtilities.invokeLater(new Runnable() {
+                       public void run() {
+                               if (currentPosition == null)
+                                       return;
+
+                               AffineTransform tr = getMapPane().getWorldToScreenTransform();
+                               DirectPosition2D geoCoords = new DirectPosition2D(
+                                               currentPosition.getLocation().getCoordinate().x,
+                                               currentPosition.getLocation().getCoordinate().y);
+                               tr.transform(geoCoords, geoCoords);
+                               geoCoords.setCoordinateReferenceSystem(getMapPane()
+                                               .getMapContext().getCoordinateReferenceSystem());
+
+                               final int halfRefSize = 3;
+                               Rectangle rect = new Rectangle((int) Math.round(geoCoords
+                                               .getX()
+                                               - halfRefSize), (int) Math.round(geoCoords.getY()
+                                               - halfRefSize), halfRefSize * 2 + 1,
+                                               halfRefSize * 2 + 1);
+                               Graphics2D g2D = (Graphics2D) getMapPane().getGraphics();
+                               if (g2D == null)
+                                       return;
+                               g2D.setColor(Color.WHITE);
+                               if (positionProviderDisconnected)
+                                       g2D.setXORMode(Color.ORANGE);
+                               else
+                                       g2D.setXORMode(Color.RED);
+                               g2D.drawRect(rect.x, rect.y, rect.width, rect.height);
+                               g2D.drawRect(rect.x - 1, rect.y - 1, rect.width + 2,
+                                               rect.height + 2);
+                       }
+               });
+       }
+
+       private class CustomMapPaneListener extends MapPaneAdapter {
+
+               @Override
+               public void onRenderingStopped(MapPaneEvent ev) {
+                       drawPositionLocation();
+               }
+
+               @Override
+               public void onDisplayAreaChanged(MapPaneEvent ev) {
+                       drawPositionLocation();
+               }
+
+               @Override
+               public void onRenderingProgress(MapPaneEvent ev) {
+                       drawPositionLocation();
+               }
+
+               @Override
+               public void onRenderingStarted(MapPaneEvent ev) {
+                       drawPositionLocation();
+               }
+
+               @Override
+               public void onResized(MapPaneEvent ev) {
+                       drawPositionLocation();
+               }
+
+       }
 }
 
 // File rasterDir = new