diff --git a/pom.xml b/pom.xml index f02d7e9247a08b10a51d0679293aebd2af6ea211..d8d8289fbde5e4a1579db0b1c59bf4206c0f1e3d 100755 --- a/pom.xml +++ b/pom.xml @@ -91,6 +91,16 @@ <artifactId>icu4j</artifactId> <version>52.1</version> </dependency> +<dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-api</artifactId> + <version>17.2</version> + </dependency> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-epsg-hsql</artifactId> + <version>17.2</version> + </dependency> <dependency> <groupId>org.renjin</groupId> <artifactId>renjin-script-engine</artifactId> @@ -162,6 +172,7 @@ </execution> </executions> </plugin> + </plugins> </build> </project> diff --git a/src/main/java/no/nibio/vips/gis/GISUtil.java b/src/main/java/no/nibio/vips/gis/GISUtil.java index 8b828319701bf65f7a3461574b295222af75812a..c5a938d69fdf032d3e70e80462c10c97f8305191 100644 --- a/src/main/java/no/nibio/vips/gis/GISUtil.java +++ b/src/main/java/no/nibio/vips/gis/GISUtil.java @@ -23,10 +23,22 @@ 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.Polygon; import com.vividsolutions.jts.geom.PrecisionModel; import java.util.ArrayList; import java.util.List; import java.util.Map; +import javax.measure.Measure; +import javax.measure.quantity.Area; +import javax.measure.unit.SI; +import org.geotools.geometry.jts.JTS; +import org.geotools.referencing.CRS; +import org.geotools.referencing.crs.DefaultGeographicCRS; +import org.opengis.geometry.MismatchedDimensionException; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; import org.wololo.geojson.Feature; import org.wololo.geojson.FeatureCollection; import org.wololo.geojson.GeoJSONFactory; @@ -164,4 +176,78 @@ public class GISUtil { return gf.createPoint(coordinate); } + /** + * Calculate distance between two points, courtesy of <a href="http://www.movable-type.co.uk/scripts/latlong.html">this page</a>. Explanation: + * <pre> + * This uses the "haversine" formula to calculate the great-circle distance between two points - + * that is, the shortest distance over the earth's surface, giving an 'as-the-crow-flies distance between the points (ignoring any hills, of course!). + Haversine formula: + a = sin²(?lat/2) + cos(lat1).cos(lat2).sin²(?long/2) + c = 2.atan2(?a, ?(1?a)) + d = R.c + where R is earth?s radius (mean radius = 6,371km); + Note that angles need to be in radians to pass to trig functions! + * </pre> + * @param coord1 + * @param coord2 + * @return distance in kilometers + */ + public Double getDistance(Coordinate coord1, Coordinate coord2) + { + Integer R = 6371; // km + Double dLat = Math.toRadians(coord2.y - coord1.y); + Double dLon = Math.toRadians(coord2.x - coord1.x); + Double lat1 = Math.toRadians(coord1.y); + Double lat2 = Math.toRadians(coord2.y); + + Double a = Math.sin(dLat/2) * Math.sin(dLat/2) + + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); + Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + Double d = R * c; + + return d; + } + + /** + * + * @param p + * @return Area in square meters + */ + public Measure<Double, Area> calcArea(Polygon p) { + Point centroid = p.getCentroid(); + try { + String code = "AUTO:42003," + centroid.getX() + "," + centroid.getY(); + CoordinateReferenceSystem auto = CRS.decode(code); + + MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto); + + Polygon projed = (Polygon) JTS.transform(p, transform); + return Measure.valueOf(projed.getArea(), SI.SQUARE_METRE); + } catch (MismatchedDimensionException | TransformException | FactoryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return Measure.valueOf(0.0, SI.SQUARE_METRE); + } + + /** + * Create a polygon with the given bounds + * @param north + * @param south + * @param east + * @param west + * @return + */ + public Polygon createRectangleFromBounds(Double north, Double south, Double east, Double west) + { + GeometryFactory gf = new GeometryFactory(new PrecisionModel(), 4326); + Coordinate[] coords = { + new Coordinate(west, south), + new Coordinate(west,north), + new Coordinate(east,north), + new Coordinate(east,south), + new Coordinate(west,south) + }; + return gf.createPolygon(coords); + } } diff --git a/src/main/java/no/nibio/vips/util/DateUtil.java b/src/main/java/no/nibio/vips/util/DateUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..68479be7a2382708ef6ae84318399f4cd951cc46 --- /dev/null +++ b/src/main/java/no/nibio/vips/util/DateUtil.java @@ -0,0 +1,62 @@ +/* + * 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.util; + +import java.util.Calendar; +import java.util.Date; + +/** + * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class DateUtil { + /** + * + * @param from + * @param to + * @return + */ + public int getDaysBetween(Date from, Date to) throws DateUtilException + { + if(to.before(from)) + { + throw new DateUtilException("Date to (" + to + ") is before date from (" + from + ")"); + } + Calendar cal = Calendar.getInstance(); + cal.setTime(from); + int fromYear = cal.get(Calendar.YEAR); + int fromDOY = cal.get(Calendar.DAY_OF_YEAR); + cal.setTime(to); + int toYear = cal.get(Calendar.YEAR); + int toDOY = cal.get(Calendar.DAY_OF_YEAR); + + int retVal = 0; + int currentYear = fromYear; + while(currentYear < toYear) + { + cal.set(Calendar.YEAR, currentYear); + retVal += currentYear == fromYear ? cal.getActualMaximum(Calendar.DAY_OF_YEAR) - fromDOY + : cal.getActualMaximum(Calendar.DAY_OF_YEAR); + currentYear++; + } + retVal += toDOY; + return retVal; + } +} diff --git a/src/main/java/no/nibio/vips/util/DateUtilException.java b/src/main/java/no/nibio/vips/util/DateUtilException.java new file mode 100644 index 0000000000000000000000000000000000000000..97e07d12aa0be87f9eedc30512eec26ebdfddf03 --- /dev/null +++ b/src/main/java/no/nibio/vips/util/DateUtilException.java @@ -0,0 +1,31 @@ +/* + * 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.util; + +/** + * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class DateUtilException extends Exception{ + public DateUtilException(String msg) + { + super(msg); + } +} diff --git a/src/main/java/no/nibio/vips/util/SystemUtil.java b/src/main/java/no/nibio/vips/util/SystemUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..b6b67ca063bfda1d4120b3fa3e447096a5967cff --- /dev/null +++ b/src/main/java/no/nibio/vips/util/SystemUtil.java @@ -0,0 +1,38 @@ +/* + * 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.util; + +/** + * @copyright 2017 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class SystemUtil { + + /** + * Based on this discussion: https://stackoverflow.com/questions/12807797/java-get-available-memory + * @return the approximate amount of memory available in this JVM + */ + public static Long getPresumableFreeMemory() + { + long allocatedMemory = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()); + long presumableFreeMemory = Runtime.getRuntime().maxMemory() - allocatedMemory; + return presumableFreeMemory; + } +} diff --git a/src/main/java/no/nibio/vips/util/XDate.java b/src/main/java/no/nibio/vips/util/XDate.java new file mode 100644 index 0000000000000000000000000000000000000000..1ab78ccfc17bd1f65a919f8b79a0aebc4415a6f2 --- /dev/null +++ b/src/main/java/no/nibio/vips/util/XDate.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 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.util; + +import java.util.Calendar; +import java.util.Date; + +/** + * Adding some utils to the java.util.Date class! + * @copyright 2018 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class XDate extends java.util.Date{ + + public XDate(){ + super(); + } + public XDate(Date date) + { + super(); + this.setTime(date.getTime()); + } + + public void add1Year() + { + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.YEAR, 1); + this.setTime(cal.getTime().getTime()); + } + + public void add1Week() + { + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.WEEK_OF_YEAR, 1); + this.setTime(cal.getTime().getTime()); + } + + public void add1Day() + { + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.DATE, 1); + this.setTime(cal.getTime().getTime()); + } + + public void add1Hour() + { + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.HOUR_OF_DAY, 1); + this.setTime(cal.getTime().getTime()); + } + + public void subtract1Year() + { + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.YEAR, -1); + this.setTime(cal.getTime().getTime()); + } + + public void subtract1Week() + { + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.WEEK_OF_YEAR, -1); + this.setTime(cal.getTime().getTime()); + } + + public void subtract1Day() + { + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.DATE, -1); + this.setTime(cal.getTime().getTime()); + } + + public void subtract1Hour() + { + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.HOUR_OF_DAY, -1); + this.setTime(cal.getTime().getTime()); + } + + public Date getYesterday(){ + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.HOUR_OF_DAY, -1); + return cal.getTime(); + } + + public Date getTomorrow(){ + Calendar cal = Calendar.getInstance(); + cal.setTime(this); + cal.add(Calendar.HOUR_OF_DAY, +1); + return cal.getTime(); + } +} diff --git a/src/test/java/no/nibio/vips/util/DateUtilTest.java b/src/test/java/no/nibio/vips/util/DateUtilTest.java new file mode 100644 index 0000000000000000000000000000000000000000..57b9348e93527fe4ac64d74e9a43c33a3a226826 --- /dev/null +++ b/src/test/java/no/nibio/vips/util/DateUtilTest.java @@ -0,0 +1,82 @@ +/* + * 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.util; + +import java.text.SimpleDateFormat; +import java.util.Date; +import junit.framework.TestCase; + +/** + * + * @author treinar + */ +public class DateUtilTest extends TestCase { + + public DateUtilTest(String testName) { + super(testName); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Test of getDaysBetween method, of class DateUtil. + */ + public void testGetDaysBetween() throws Exception { + System.out.println("getDaysBetween"); + SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd"); + + // Start and end year is not a leap year + Date from = f.parse("2015-12-31"); + Date to = f.parse("2017-12-22"); + DateUtil instance = new DateUtil(); + int expResult = 722; + int result = instance.getDaysBetween(from, to); + assertEquals(expResult, result); + + // Start is leap year, end is not, start date is after leap date + from = f.parse("2016-12-31"); + to = f.parse("2017-01-01"); + expResult = 1; + result = instance.getDaysBetween(from, to); + assertEquals(expResult, result); + + // Start is leap year, end is not, start date is before leap date + from = f.parse("2016-02-25"); + expResult = 311; + result = instance.getDaysBetween(from, to); + assertEquals(expResult, result); + + // Start is not leap year, end is, end is after leap date + from = f.parse("2015-04-01"); + to = f.parse("2016-06-01"); + expResult = 427; + result = instance.getDaysBetween(from, to); + assertEquals(expResult, result); + + } + +} diff --git a/src/test/java/no/nibio/vips/util/XDateTest.java b/src/test/java/no/nibio/vips/util/XDateTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4a607d238427fd652630e1b7e72ed8b64ef07291 --- /dev/null +++ b/src/test/java/no/nibio/vips/util/XDateTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 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.util; + +import java.util.Calendar; +import junit.framework.TestCase; + +/** + * + * @author treinar + */ +public class XDateTest extends TestCase { + + public XDateTest(String testName) { + super(testName); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Test of add1Day method, of class XDate. + */ + public void testAdd1Day() { + System.out.println("add1Day"); + XDate instance = new XDate(); + Calendar cal = Calendar.getInstance(); + cal.setTime(instance); + cal.add(Calendar.DATE, 1); + instance.add1Day(); + assertEquals(cal.getTime(), instance); + + } + +}