diff --git a/jbossmodule/no/bioforsk/vips/VIPSCommon/main/module.xml b/jbossmodule/no/bioforsk/vips/VIPSCommon/main/module.xml
index 508273e5068d3dbc1a644dbd3ba8894cc02e554d..a93e7dcf606bee5b5ffb480b0db8bea378689a3b 100755
--- a/jbossmodule/no/bioforsk/vips/VIPSCommon/main/module.xml
+++ b/jbossmodule/no/bioforsk/vips/VIPSCommon/main/module.xml
@@ -19,6 +19,7 @@
 		<module name="javax.servlet.api" export="false"/>
                 <module name="org.apache.commons.io" export="false"/>
                 <module name="org.apache.commons.codec" export="false"/>
+		<module name="com.vividsolutions.jts" export="false"/>
     </dependencies>
     
 </module>
diff --git a/pom.xml b/pom.xml
index 3e07131b1bbc9315176f76716baf4267e48fdf13..f02d7e9247a08b10a51d0679293aebd2af6ea211 100755
--- a/pom.xml
+++ b/pom.xml
@@ -15,7 +15,7 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
   </properties>
-
+  
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -26,7 +26,7 @@
     <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-annotations</artifactId>
-      <version>2.4.1</version>
+      <version>2.8.10</version>
     </dependency>
     <dependency>
       <groupId>commons-validator</groupId>
@@ -37,12 +37,12 @@
     <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-core</artifactId>
-      <version>2.4.1</version>
+      <version>2.8.10</version>
     </dependency>
     <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-databind</artifactId>
-      <version>2.4.1</version>
+      <version>2.8.10</version>
     </dependency>
     <dependency>
       <groupId>org.apache.httpcomponents</groupId>
@@ -101,6 +101,12 @@
   <artifactId>jts</artifactId>
   <version>1.13</version>
 </dependency>
+<dependency>
+        <groupId>com.github.bjornharrtell</groupId>
+          <!--groupId>org.wololo</groupId-->
+        <artifactId>jts2geojson</artifactId>
+        <version>0.10.0</version>
+    </dependency>
 </dependencies>
 <repositories>
   <repository>
@@ -108,6 +114,10 @@
     <name>bedatadriven public repo</name>
     <url>https://nexus.bedatadriven.com/content/groups/public/</url>
   </repository>
+    <repository>
+        <id>jitpack.io</id>
+        <url>https://jitpack.io</url>
+    </repository>
 </repositories>
   <build>
     <plugins>
diff --git a/src/main/java/no/nibio/vips/gis/GISUtil.java b/src/main/java/no/nibio/vips/gis/GISUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b828319701bf65f7a3461574b295222af75812a
--- /dev/null
+++ b/src/main/java/no/nibio/vips/gis/GISUtil.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2017 NIBIO <http://www.nibio.no/>. 
+ * 
+ * This file is part of VIPSCommon.
+ * VIPSCommon is free software: you can redistribute it and/or modify
+ * it under the terms of the NIBIO Open Source License as published by 
+ * NIBIO, either version 1 of the License, or (at your option) any
+ * later version.
+ * 
+ * VIPSCommon is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * NIBIO Open Source License for more details.
+ * 
+ * You should have received a copy of the NIBIO Open Source License
+ * along with VIPSCommon.  If not, see <http://www.nibio.no/licenses/>.
+ * 
+ */
+
+package no.nibio.vips.gis;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.PrecisionModel;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.wololo.geojson.Feature;
+import org.wololo.geojson.FeatureCollection;
+import org.wololo.geojson.GeoJSONFactory;
+import org.wololo.jts2geojson.GeoJSONReader;
+import org.wololo.jts2geojson.GeoJSONWriter;
+
+/**
+ * Handy tools for GIS operations
+ * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a>
+ * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
+ */
+public class GISUtil {
+    
+    /**
+     * Calculates the coordinates of a nearby destination
+     * @param origin WGS84 where to start from
+     * @param distance Distance in km
+     * @param initialBearing The initial bearing, given as degrees clockwise starting from North
+     * @return 
+     */
+    public Coordinate getNearbyDestination(Coordinate origin, Double distance, Double initialBearing)
+    {
+        // Constant
+        Double R = 6371.0; // The average radius of the earth in km
+        // Convert to radians
+        Double bearing = this.toRadians(initialBearing);
+        Double longitude = this.toRadians(origin.x);
+        Double latitude = this.toRadians(origin.y);
+        
+        // Latitude is seemingly easy
+        Double angularDistance = distance/R;
+        Double deltaLat = angularDistance * Math.cos(bearing);
+        Double newLat = latitude + deltaLat;
+        
+        // check for some daft bugger going past the pole, normalize latitude if so
+        if(Math.abs(newLat) > Math.PI/2)
+        {
+            newLat = newLat > 0 ? Math.PI - newLat : -Math.PI - newLat;
+        }
+        
+        // Longitude
+        Double projectedLatitudeDifference = Math.log(Math.tan(newLat/2 + Math.PI/4)/Math.tan(latitude/2 + Math.PI/4));
+        Double q = Math.abs(projectedLatitudeDifference) > 10e-12 ? deltaLat/projectedLatitudeDifference : Math.cos(latitude); // E-W course becomes ill-conditioned with 0/0
+        Double deltaLong = angularDistance * Math.sin(bearing)/q;
+        Double newLong = longitude + deltaLong;
+        
+        return new Coordinate(this.toDegrees(newLong), this.toDegrees(newLat));
+    }
+    
+    /**
+     * 
+     * @param degrees
+     * @return radian value
+     */
+    public Double toRadians(Double degrees)
+    {
+        return degrees * Math.PI / 180;
+    }
+    
+    /**
+     * 
+     * @param radians
+     * @return degree value
+     */
+    public Double toDegrees(Double radians)
+    {
+        return radians * 180 / Math.PI;
+    }
+    
+    /**
+     * Parses all features from GeoJSON string, returns as JTS Geometry objects
+     * @param json
+     * @return 
+     */
+    public List<Geometry> getGeometriesFromGeoJSON(String json)
+    {
+        FeatureCollection featureCollection = (FeatureCollection) GeoJSONFactory.create(json);
+        GeoJSONReader reader = new GeoJSONReader();
+        List<Geometry> retVal = new ArrayList<>();
+        for(Feature feature: featureCollection.getFeatures())
+        {
+            retVal.add(reader.read(feature.getGeometry()));
+        }
+        return retVal;
+    }
+    
+    /**
+     * Hand in your JTS Geometry objects, get GEOJSON back
+     * @param geometries
+     * @param properties these props will be attached to all features
+     * @return 
+     */
+    public String getGeoJSONFromGeometries(List<Geometry> geometries, Map<String, Object> properties)
+    {
+        if(geometries == null || geometries.isEmpty())
+        {
+            return "";
+        }
+        List<Feature> features = new ArrayList<>();
+        GeoJSONWriter writer = new GeoJSONWriter();
+        geometries.stream().forEach((geometry)->features.add(new Feature(writer.write(geometry), properties)));
+        FeatureCollection json = writer.write(features);
+        return json.toString();
+    }
+    
+    /**
+     * Convert one JTS Geometry object into a GeoJSON feature
+     * @param geometry
+     * @param properties
+     * @return 
+     */
+    public String getGeoJSONFromGeometry(Geometry geometry,Map<String, Object> properties)
+    {
+        if(geometry == null)
+        {
+            return "";
+        }
+        List<Feature> features = new ArrayList<>();
+        GeoJSONWriter writer = new GeoJSONWriter();
+       
+        features.add(new Feature(writer.write(geometry), properties));
+        
+        FeatureCollection json = writer.write(features);
+        return json.toString();
+    }
+    
+    /**
+     * If you have WGS84 coordinates, th
+     * @param coordinate in WGS84 system
+     * @return 
+     */
+    public Point createPointWGS84(Coordinate coordinate)
+    {
+        GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326);
+        return gf.createPoint(coordinate);
+    }
+
+}
diff --git a/src/test/java/no/nibio/vips/gis/GISUtilTest.java b/src/test/java/no/nibio/vips/gis/GISUtilTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..81559a42cb91d0fab98c92b35b00baffd46a8c83
--- /dev/null
+++ b/src/test/java/no/nibio/vips/gis/GISUtilTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2017 NIBIO <http://www.nibio.no/>. 
+ * 
+ * This file is part of VIPSCommon.
+ * VIPSCommon is free software: you can redistribute it and/or modify
+ * it under the terms of the NIBIO Open Source License as published by 
+ * NIBIO, either version 1 of the License, or (at your option) any
+ * later version.
+ * 
+ * VIPSCommon is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * NIBIO Open Source License for more details.
+ * 
+ * You should have received a copy of the NIBIO Open Source License
+ * along with VIPSCommon.  If not, see <http://www.nibio.no/licenses/>.
+ * 
+ */
+package no.nibio.vips.gis;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Point;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author treinar
+ */
+public class GISUtilTest extends TestCase {
+    
+    public GISUtilTest(String testName) {
+        super(testName);
+    }
+    
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+    
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test of getNearbyDestination method, of class GISUtil.
+     *
+    public void testGetNearbyDestination() {
+        System.out.println("getNearbyDestination");
+        Coordinate origin = null;
+        Double distance = null;
+        Double initialBearing = null;
+        GISUtil instance = new GISUtil();
+        Coordinate expResult = null;
+        Coordinate result = instance.getNearbyDestination(origin, distance, initialBearing);
+        assertEquals(expResult, result);
+        // TODO review the generated test code and remove the default call to fail.
+        fail("The test case is a prototype.");
+    }
+
+    /**
+     * Test of toRadians method, of class GISUtil.
+     *
+    public void testToRadians() {
+        System.out.println("toRadians");
+        Double degrees = null;
+        GISUtil instance = new GISUtil();
+        Double expResult = null;
+        Double result = instance.toRadians(degrees);
+        assertEquals(expResult, result);
+        // TODO review the generated test code and remove the default call to fail.
+        fail("The test case is a prototype.");
+    }
+
+    /**
+     * Test of toDegrees method, of class GISUtil.
+     *
+    public void testToDegrees() {
+        System.out.println("toDegrees");
+        Double radians = null;
+        GISUtil instance = new GISUtil();
+        Double expResult = null;
+        Double result = instance.toDegrees(radians);
+        assertEquals(expResult, result);
+        // TODO review the generated test code and remove the default call to fail.
+        fail("The test case is a prototype.");
+    }
+
+    /**
+     * Test of getGeometriesFromGeoJSON method, of class GISUtil.
+     *
+    public void testGetGeometriesFromGeoJSON() {
+        System.out.println("getGeometriesFromGeoJSON");
+        String json = "";
+        GISUtil instance = new GISUtil();
+        List<Geometry> expResult = null;
+        List<Geometry> result = instance.getGeometriesFromGeoJSON(json);
+        assertEquals(expResult, result);
+        // TODO review the generated test code and remove the default call to fail.
+        fail("The test case is a prototype.");
+    }
+
+    /**
+     * Test of getGeoJSONFromGeometries method, of class GISUtil.
+     *
+    public void testGetGeoJSONFromGeometries() {
+        System.out.println("getGeoJSONFromGeometries");
+        List<Geometry> geometries = null;
+        Map<String, Object> properties = null;
+        GISUtil instance = new GISUtil();
+        String expResult = "";
+        String result = instance.getGeoJSONFromGeometries(geometries, properties);
+        assertEquals(expResult, result);
+        // TODO review the generated test code and remove the default call to fail.
+        fail("The test case is a prototype.");
+    }
+
+    /**
+     * Test of getGeoJSONFromGeometry method, of class GISUtil.
+     *
+    public void testGetGeoJSONFromGeometry() {
+        System.out.println("getGeoJSONFromGeometry");
+        Geometry geometry = null;
+        Map<String, Object> properties = null;
+        GISUtil instance = new GISUtil();
+        String expResult = "";
+        String result = instance.getGeoJSONFromGeometry(geometry, properties);
+        assertEquals(expResult, result);
+        // TODO review the generated test code and remove the default call to fail.
+        fail("The test case is a prototype.");
+    }
+
+    /**
+     * Test of createPointWGS84 method, of class GISUtil.
+     *
+    public void testCreatePointWGS84() {
+        System.out.println("createPointWGS84");
+        Coordinate coordinate = null;
+        GISUtil instance = new GISUtil();
+        Point expResult = null;
+        Point result = instance.createPointWGS84(coordinate);
+        assertEquals(expResult, result);
+        // TODO review the generated test code and remove the default call to fail.
+        fail("The test case is a prototype.");
+    }
+    /**
+     * Test of getGeometriesFromGeoJSON method, of class GISEntityUtil.
+     */
+
+    public void testRoundtrip() {
+        System.out.println("testRoundtrip");
+        String json = "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[10.669097900390623,59.753628151319106],[10.612792968749998,59.70309199431276],[10.726776123046873,59.705863076677105],[10.669097900390623,59.753628151319106]]]},\"properties\":{\"observationId\":12}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[10.704803466796873,59.64831609639066]},\"properties\":{\"observationId\":12}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[10.649871826171871,59.67051458978321],[10.791320800781248,59.67328836837126]]},\"properties\":{\"observationId\":12}}]}";
+        System.out.println("JSON=" + json);
+        GISUtil instance = new GISUtil();
+        //List<Geometry> expResult = null;
+        List<com.vividsolutions.jts.geom.Geometry> geometries = instance.getGeometriesFromGeoJSON(json);
+        Map<String, Object> properties = new HashMap<>();
+        properties.put("observationId", 12);
+        String result = instance.getGeoJSONFromGeometries(geometries, properties);
+        //System.out.println(result);
+        assertEquals(json, result);
+        
+        
+    }
+    
+}