First working GPS position provider
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 6 May 2010 18:57:06 +0000 (18:57 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 6 May 2010 18:57:06 +0000 (18:57 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@3565 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCall.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java [new file with mode: 0644]
runtime/org.argeo.slc.support.gis/build.properties
runtime/org.argeo.slc.support.gis/pom.xml
runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/geotools/Quickstart.java
runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/gpsbabel/GpsBabelCall.java [new file with mode: 0644]
runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/gpsbabel/GpsBabelPositionProvider.java [new file with mode: 0644]
runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/jts/PositionProvider.java [new file with mode: 0644]

index 6a3b3df940708813ff7bc9458a008b72f83c7dfa..9d8ebdcf8785920a459be223eed70596ea693e5c 100644 (file)
@@ -8,6 +8,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Writer;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -37,6 +38,8 @@ import org.springframework.core.io.Resource;
 
 /** Execute an OS specific system call. */
 public class SystemCall extends TreeSRelatedHelper implements Runnable {
+       public final static String LOG_STDOUT = "System.out";
+
        private final Log log = LogFactory.getLog(getClass());
 
        private String execDir;
@@ -54,6 +57,9 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
        private Resource stdInFile = null;
        private Boolean redirectStdOut = false;
 
+       private List<SystemCallOutputListener> outputListeners = Collections
+                       .synchronizedList(new ArrayList<SystemCallOutputListener>());
+
        private Map<String, List<Object>> osCommands = new HashMap<String, List<Object>>();
        private Map<String, String> osCmds = new HashMap<String, String>();
        private Map<String, String> environmentVariables = new HashMap<String, String>();
@@ -177,6 +183,9 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                // Execute
                ExecuteResultHandler executeResultHandler = createExecuteResultHandler(commandLine);
 
+               //
+               // THE EXECUTION PROPER
+               // 
                try {
                        if (synchronous)
                                try {
@@ -202,6 +211,21 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
 
        }
 
+       public synchronized String function() {
+               final StringBuffer buf = new StringBuffer("");
+               SystemCallOutputListener tempOutputListener = new SystemCallOutputListener() {
+                       public void newLine(SystemCall systemCall, String line,
+                                       Boolean isError) {
+                               if (!isError)
+                                       buf.append(line);
+                       }
+               };
+               addOutputListener(tempOutputListener);
+               run();
+               removeOutputListener(tempOutputListener);
+               return buf.toString();
+       }
+
        public String asCommand() {
                return createCommandLine().toString();
        }
@@ -291,14 +315,14 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                                                : new LogOutputStream() {
                                                        protected void processLine(String line, int level) {
                                                                if (line != null && !line.trim().equals(""))
-                                                                       log(stdOutLogLevel, line);
+                                                                       logStdOut(line);
                                                                if (stdOutWriter != null)
                                                                        appendLineToFile(stdOutWriter, line);
                                                        }
                                                }, new LogOutputStream() {
                                        protected void processLine(String line, int level) {
                                                if (line != null && !line.trim().equals(""))
-                                                       log(stdErrLogLevel, line);
+                                                       logStdErr(line);
                                                if (stdErrWriter != null)
                                                        appendLineToFile(stdErrWriter, line);
                                        }
@@ -314,8 +338,8 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                        public void onProcessComplete(int exitValue) {
                                String msg = "System call '" + commandLine
                                                + "' properly completed.";
-                               if (log.isDebugEnabled())
-                                       log.debug(msg);
+                               if (log.isTraceEnabled())
+                                       log.trace(msg);
                                if (testResult != null) {
                                        forwardPath(testResult, null);
                                        testResult.addResultPart(new SimpleResultPart(
@@ -360,6 +384,18 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                }
        }
 
+       protected void logStdOut(String line) {
+               for (SystemCallOutputListener outputListener : outputListeners)
+                       outputListener.newLine(this, line, false);
+               log(stdOutLogLevel, line);
+       }
+
+       protected void logStdErr(String line) {
+               for (SystemCallOutputListener outputListener : outputListeners)
+                       outputListener.newLine(this, line, true);
+               log(stdErrLogLevel, line);
+       }
+
        /** Log from the underlying streams. */
        protected void log(String logLevel, String line) {
                if ("ERROR".equals(logLevel))
@@ -372,7 +408,7 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                        log.debug(line);
                else if ("TRACE".equals(logLevel))
                        log.trace(line);
-               else if ("System.out".equals(logLevel))
+               else if (LOG_STDOUT.equals(logLevel))
                        System.out.println(line);
                else if ("System.err".equals(logLevel))
                        System.err.println(line);
@@ -527,6 +563,19 @@ public class SystemCall extends TreeSRelatedHelper implements Runnable {
                this.redirectStdOut = redirectStdOut;
        }
 
+       public void addOutputListener(SystemCallOutputListener outputListener) {
+               outputListeners.add(outputListener);
+       }
+
+       public void removeOutputListener(SystemCallOutputListener outputListener) {
+               outputListeners.remove(outputListener);
+       }
+
+       public void setOutputListeners(
+                       List<SystemCallOutputListener> outputListeners) {
+               this.outputListeners = outputListeners;
+       }
+
        private class DummyexecuteStreamHandler implements ExecuteStreamHandler {
 
                public void setProcessErrorStream(InputStream is) throws IOException {
diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/execution/tasks/SystemCallOutputListener.java
new file mode 100644 (file)
index 0000000..7972cdc
--- /dev/null
@@ -0,0 +1,5 @@
+package org.argeo.slc.core.execution.tasks;
+
+public interface SystemCallOutputListener {
+       public void newLine(SystemCall systemCall, String line, Boolean isError);
+}
index a4e488caff9cd253cc653ddd07536813438ec1ad..73ed796e9d9c984bde7d9855e2afa9f14916f7de 100644 (file)
@@ -1,4 +1,6 @@
-source.. = src/main/java/
+source.. = src/main/java/,\
+           src/main/resources/,\
+           src/test/resources/
 output.. = target/classes/
 bin.includes = META-INF/,\
                .
index efa20eafcdf040846e7ef33473bd2e62ed5730a1..8a5b14c5acf4bb598cf17a0691666a20fd04c49f 100644 (file)
@@ -23,6 +23,7 @@
                                                </Export-Package>
                                                <Import-Package>*,
                                                        org.opengis.feature.simple,
+                                                       org.argeo.slc.structure
                                                </Import-Package>
                                        </instructions>
                                </configuration>
                </plugins>
        </build>
        <dependencies>
+               <!-- SLC -->
+               <dependency>
+                       <groupId>org.argeo.slc.runtime</groupId>
+                       <artifactId>org.argeo.slc.core</artifactId>
+               </dependency>
+
                <dependency>
                        <groupId>org.slf4j</groupId>
                        <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
                </dependency>
 
+               <!-- GIS -->
                <dependency>
                        <groupId>org.argeo.dep.osgi</groupId>
                        <artifactId>org.argeo.dep.osgi.jts</artifactId>
index 25c624490f9827f3320573edc16aaf5877368ea1..48ff7d003e54970061b4b709bb4d26a5687cefcd 100644 (file)
@@ -9,6 +9,7 @@
  */
 package org.argeo.slc.geotools;
 
+import java.awt.Color;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
 import java.io.File;
@@ -18,19 +19,29 @@ import javax.swing.SwingUtilities;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.geotools.data.FeatureSource;
-import org.geotools.data.FileDataStore;
+import org.argeo.slc.gpsbabel.GpsBabelPositionProvider;
+import org.argeo.slc.jts.PositionProvider;
 import org.geotools.data.FileDataStoreFactorySpi;
 import org.geotools.data.FileDataStoreFinder;
+import org.geotools.feature.DefaultFeatureCollection;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
 import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.map.DefaultMapContext;
+import org.geotools.map.DefaultMapLayer;
 import org.geotools.map.MapContext;
+import org.geotools.map.MapLayer;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.geotools.styling.SLD;
+import org.geotools.styling.Style;
 import org.geotools.swing.JMapFrame;
 import org.geotools.swing.JMapPane;
-import org.geotools.swing.event.MapMouseAdapter;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
 
+import com.vividsolutions.jts.geom.Point;
+
 /**
  * GeoTools Quickstart demo application. Prompts the user for a shapefile and
  * displays its contents on the screen in a map frame
@@ -62,18 +73,19 @@ public class Quickstart {
                File dir = new File(
                                "/home/mbaudier/gis/projects/100122-EasternBalkans2010/data");
 
-               FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = FileDataStoreFinder
-                               .getDataStore(new File(dir, "countries-EuroMed-NEarth.shp"))
-                               .getFeatureSource();
+               // FeatureSource<SimpleFeatureType, SimpleFeature> featureSource =
+               // FileDataStoreFinder
+               // .getDataStore(new File(dir, "countries-EuroMed-NEarth.shp"))
+               // .getFeatureSource();
 
                // Create a map context and add our shapefile to it
-               MapContext map = new DefaultMapContext();
-               map.setTitle("Quickstart");
+               MapContext mapContext = new DefaultMapContext();
+               mapContext.setTitle("Quickstart");
 
                // Now display the map
                // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
 
-               final JMapFrame frame = new JMapFrame(map);
+               final JMapFrame frame = new JMapFrame(mapContext);
                frame.enableStatusBar(true);
                frame.enableToolBar(true);
                frame.enableLayerTable(true);
@@ -122,15 +134,61 @@ public class Quickstart {
                        }
                });
 
-               map.addLayer(FileDataStoreFinder.getDataStore(
-                               new File(dir, "cities-EuroMed-NEarth.shp")).getFeatureSource(),
-                               null);
-               map.addLayer(FileDataStoreFinder.getDataStore(
+               // Create position type
+               SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
+               builder.setName("Position");
+               builder.setNamespaceURI("http://localhost/");
+               builder.setCRS(DefaultGeographicCRS.WGS84);
+
+               // add attributes in order
+               builder.add("Location", Point.class);
+               builder.add("ID", Integer.class);
+               builder.add("Name", String.class);
+
+               // build the type
+               final SimpleFeatureType POSITION = builder.buildFeatureType();
+
+               PositionProvider positionProvider = new GpsBabelPositionProvider();
+
+               // FeatureSource<SimpleFeatureType, SimpleFeature> fs =
+               // FileDataStoreFinder
+               // .getDataStore(new File(dir, "countries-EuroMed-NEarth.shp"))
+               // .getFeatureSource();
+
+               // mapContext.addLayer(FileDataStoreFinder.getDataStore(
+               // new File(dir, "cities-EuroMed-NEarth.shp")).getFeatureSource(),
+               // null);
+               mapContext.addLayer(FileDataStoreFinder.getDataStore(
                                new File(dir, "countries-EuroMed-NEarth.shp"))
                                .getFeatureSource(), null);
-               map.addLayer(FileDataStoreFinder.getDataStore(
-                               new File(dir, "highways-EastBalkan-OSM.shp"))
-                               .getFeatureSource(), null);
-
+                mapContext.addLayer(FileDataStoreFinder.getDataStore(
+                new File(dir, "highways-EastBalkan-OSM.shp"))
+                .getFeatureSource(), null);
+
+               MapLayer mapLayer = null;
+               while (true) {
+                       SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(
+                                       POSITION);
+
+                       // add the attributes
+                       featureBuilder.add(positionProvider.currentPosition());
+                       featureBuilder.add(12);
+                       featureBuilder.add("My Name");
+
+                       // build the feature
+                       SimpleFeature feature = featureBuilder.buildFeature("Flag.12");
+                       FeatureCollection<SimpleFeatureType, SimpleFeature> collection = new DefaultFeatureCollection(
+                                       "testCollection", POSITION);
+                       collection.add(feature);
+                       if (mapLayer != null)
+                               mapContext.removeLayer(mapLayer);
+                       Style style = SLD.createSimpleStyle(POSITION, Color.RED);
+                       mapLayer = new DefaultMapLayer(collection, style, "");
+                       mapContext.addLayer(mapLayer);
+                       // mapContext.addLayer(collection,null);
+
+                       Thread.sleep(1000);
+               }
        }
+
 }
\ No newline at end of file
diff --git a/runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/gpsbabel/GpsBabelCall.java b/runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/gpsbabel/GpsBabelCall.java
new file mode 100644 (file)
index 0000000..4b0db1f
--- /dev/null
@@ -0,0 +1,56 @@
+package org.argeo.slc.gpsbabel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.tasks.SystemCall;
+import org.springframework.beans.factory.InitializingBean;
+
+public class GpsBabelCall extends SystemCall implements InitializingBean {
+       private String executable = "/usr/bin/gpsbabel";
+       private String inputFormat;
+       private String inputFile;
+       private String outputFormat;
+       private String outputFile;
+
+       public GpsBabelCall() {
+               super();
+       }
+
+       public GpsBabelCall(String inputFormat, String inputFile,
+                       String outputFormat, String outputFile) {
+               super();
+               this.inputFormat = inputFormat;
+               this.inputFile = inputFile;
+               this.outputFormat = outputFormat;
+               this.outputFile = outputFile;
+               try {
+                       afterPropertiesSet();
+               } catch (Exception e) {
+                       throw new SlcException("Cannot configure gpsbabel call", e);
+               }
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               List<Object> command = new ArrayList<Object>();
+               command.add(executable);
+               command.add("-i");
+               command.add(inputFormat);
+               command.add("-f");
+               command.add(inputFile);
+               command.add("-o");
+               command.add(outputFormat);
+               command.add("-F");
+               command.add(outputFile);
+               setCommand(command);
+
+               setStdOutLogLevel(LOG_STDOUT);
+       }
+
+       public final static void main(String[] args) {
+               String output = new GpsBabelCall("garmin,get_posn", "usb:", "csv", "-")
+                               .function();
+               System.out.println("output='" + output + "'");
+       }
+}
diff --git a/runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/gpsbabel/GpsBabelPositionProvider.java b/runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/gpsbabel/GpsBabelPositionProvider.java
new file mode 100644 (file)
index 0000000..8e1a8f7
--- /dev/null
@@ -0,0 +1,37 @@
+package org.argeo.slc.gpsbabel;
+
+import java.util.StringTokenizer;
+
+import org.argeo.slc.jts.PositionProvider;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Point;
+
+public class GpsBabelPositionProvider implements PositionProvider {
+       private GpsBabelCall gpsBabelCall;
+
+       private GeometryFactory geometryFactory = new GeometryFactory();
+
+       private String inputFormat = "garmin,get_posn";
+       private String inputFile = "usb:";
+
+       public void init() {
+               gpsBabelCall = new GpsBabelCall(inputFormat, inputFile, "csv", "-");
+       }
+
+       public Point currentPosition() {
+               // lazy init
+               if (gpsBabelCall == null)
+                       init();
+
+               String output = gpsBabelCall.function();
+               StringTokenizer st = new StringTokenizer(output, ",");
+               Double latitude = Double.parseDouble(st.nextToken());
+               Double longitude = Double.parseDouble(st.nextToken());
+               Point position = geometryFactory.createPoint(new Coordinate(longitude,
+                               latitude));
+               return position;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/jts/PositionProvider.java b/runtime/org.argeo.slc.support.gis/src/main/java/org/argeo/slc/jts/PositionProvider.java
new file mode 100644 (file)
index 0000000..caae525
--- /dev/null
@@ -0,0 +1,7 @@
+package org.argeo.slc.jts;
+
+import com.vividsolutions.jts.geom.Point;
+
+public interface PositionProvider {
+       public Point currentPosition();
+}