Skip to content
Snippets Groups Projects
Commit 568c499c authored by Tor-Einar Skog's avatar Tor-Einar Skog
Browse files

Refactoring GISUtil stuff from VIPSLogic to VIPSCommon

parent 81e40af0
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
<module name="javax.servlet.api" export="false"/> <module name="javax.servlet.api" export="false"/>
<module name="org.apache.commons.io" export="false"/> <module name="org.apache.commons.io" export="false"/>
<module name="org.apache.commons.codec" export="false"/> <module name="org.apache.commons.codec" export="false"/>
<module name="com.vividsolutions.jts" export="false"/>
</dependencies> </dependencies>
</module> </module>
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId> <artifactId>jackson-annotations</artifactId>
<version>2.4.1</version> <version>2.8.10</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-validator</groupId> <groupId>commons-validator</groupId>
...@@ -37,12 +37,12 @@ ...@@ -37,12 +37,12 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId> <artifactId>jackson-core</artifactId>
<version>2.4.1</version> <version>2.8.10</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.4.1</version> <version>2.8.10</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
...@@ -101,6 +101,12 @@ ...@@ -101,6 +101,12 @@
<artifactId>jts</artifactId> <artifactId>jts</artifactId>
<version>1.13</version> <version>1.13</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.bjornharrtell</groupId>
<!--groupId>org.wololo</groupId-->
<artifactId>jts2geojson</artifactId>
<version>0.10.0</version>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>
<repository> <repository>
...@@ -108,6 +114,10 @@ ...@@ -108,6 +114,10 @@
<name>bedatadriven public repo</name> <name>bedatadriven public repo</name>
<url>https://nexus.bedatadriven.com/content/groups/public/</url> <url>https://nexus.bedatadriven.com/content/groups/public/</url>
</repository> </repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories> </repositories>
<build> <build>
<plugins> <plugins>
......
/*
* 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);
}
}
/*
* 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);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment