Commit b6ea5d7f authored by Matija Obreza's avatar Matija Obreza
Browse files

Use guava cache

parent e4cb8f24
......@@ -2,3 +2,6 @@
/.classpath
/.project
/data/
/*.kml
/*.csv
/*.kmz
......@@ -64,11 +64,21 @@
<artifactId>gt-epsg-wkt</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-swing</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>3.6</version>
</dependency>
</dependencies>
<build>
<plugins>
......
......@@ -5,6 +5,8 @@ import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
......@@ -23,6 +25,9 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
......@@ -40,6 +45,8 @@ public class LandOrSeaServiceImpl implements LandOrSeaService {
private static final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
private FeatureSource<SimpleFeatureType, SimpleFeature> sourceLand;
private FeatureSource<SimpleFeatureType, SimpleFeature> sourceWater;
private LoadingCache<LonLatCacheKey, Boolean> waterCache;
private LoadingCache<LonLatCacheKey, String> classifierCache;
static {
try {
......@@ -66,6 +73,69 @@ public class LandOrSeaServiceImpl implements LandOrSeaService {
sourceLand = dataStoreLand.getFeatureSource(dataStoreLand.getTypeNames()[0]);
sourceWater = dataStoreWater.getFeatureSource(dataStoreWater.getTypeNames()[0]);
waterCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(5, TimeUnit.SECONDS)
.build(new CacheLoader<LonLatCacheKey, Boolean>() {
public Boolean load(LonLatCacheKey key) throws Exception {
// System.err.println("Loading");
return _isOnLand(key.getLongitude(), key.getLatitude(), key.getAllowedDistanceFromLand());
}
});
classifierCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(5, TimeUnit.SECONDS)
.build(new CacheLoader<LonLatCacheKey, String>() {
public String load(LonLatCacheKey key) throws Exception {
// System.err.println("Loading");
return _classifyLocation(key.getLongitude(), key.getLatitude(),
key.getAllowedDistanceFromLand());
}
});
}
public String classifyLocation(float longitude, float latitude, int allowedDistanceFromLand) throws Exception {
try {
return classifierCache.get(new LonLatCacheKey(longitude, latitude, allowedDistanceFromLand));
} catch (ExecutionException e) {
throw new Exception(e.getCause());
}
}
private String _classifyLocation(float longitude, float latitude, int allowedDistanceFromLand) throws Exception {
Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
Filter filterExact = ff.contains(ff.property("the_geom"), ff.literal(point));
try {
if (sourceWater.getFeatures(filterExact).size() > 0) {
// Create a buffer and check for Land
Filter filterBuffered = ff.intersects(ff.property("the_geom"),
ff.literal(getPointBuffer(point, allowedDistanceFromLand)));
if (sourceLand.getFeatures(filterBuffered).size() > 0) {
return "Coastal";
} else {
return "Water";
}
} else if (sourceLand.getFeatures(filterExact).size() > 0) {
// Create a buffer and check for Land
Filter filterBuffered = ff.intersects(ff.property("the_geom"),
ff.literal(getPointBuffer(point, allowedDistanceFromLand)));
if (sourceWater.getFeatures(filterBuffered).size() > 0) {
return "Coastal";
} else {
return "Land";
}
} else {
throw new Exception("Can't figure out the result for " + longitude + "," + latitude + " with distance="
+ allowedDistanceFromLand);
}
} catch (Exception e) {
throw e;
}
}
/*
......@@ -75,8 +145,14 @@ public class LandOrSeaServiceImpl implements LandOrSeaService {
*/
@Override
public Boolean isOnLand(float longitude, float latitude, int allowedDistanceFromLand) throws Exception {
// Filter filter = Filter.INCLUDE; //
// ECQL.toFilter("BBOX(THE_GEOM, 10,20,30,40)")
try {
return waterCache.get(new LonLatCacheKey(longitude, latitude, allowedDistanceFromLand));
} catch (ExecutionException e) {
throw new Exception(e.getCause());
}
}
private Boolean _isOnLand(float longitude, float latitude, int allowedDistanceFromLand) throws Exception {
Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
......@@ -131,4 +207,5 @@ public class LandOrSeaServiceImpl implements LandOrSeaService {
DataStore dataStore = DataStoreFinder.getDataStore(map);
return dataStore;
}
}
package org.genesys.geotools;
import java.io.Serializable;
public class LonLatCacheKey implements Serializable {
private static final long serialVersionUID = -3626533849742141104L;
private float longitude;
private float latitude;
private int allowedDistanceFromLand;
public LonLatCacheKey(float longitude, float latitude, int allowedDistanceFromLand) {
this.longitude = longitude;
this.latitude = latitude;
this.allowedDistanceFromLand = allowedDistanceFromLand;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Float.floatToIntBits(latitude);
result = prime * result + Float.floatToIntBits(longitude);
result = prime * result + allowedDistanceFromLand;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LonLatCacheKey other = (LonLatCacheKey) obj;
if (Float.floatToIntBits(latitude) != Float.floatToIntBits(other.latitude))
return false;
if (Float.floatToIntBits(longitude) != Float.floatToIntBits(other.longitude))
return false;
if (allowedDistanceFromLand != other.allowedDistanceFromLand)
return false;
return true;
}
public float getLatitude() {
return latitude;
}
public float getLongitude() {
return longitude;
}
public int getAllowedDistanceFromLand() {
return allowedDistanceFromLand;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment