question regarding SpatialRestrictions.intersects

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

question regarding SpatialRestrictions.intersects

sommeralex
Hello!

I would like to cache weather information from a weather service. But it seems, that i am doing something wrong. 

If one of my clients is asking for a local weather, the weather should be cached on my server for the next client for some amount of time to reduce the requests to the weather service.

The weather is stored as a scope / area. And all clients requesting the weather of that area should get the same weather.

What i am doing so far is to ask, if a cached weather exists. If yes, the weather is returned, if not, i am requesting the weather from the 3rd party weather service. A background task is deleting all old caches regularly (after some amount of time)

What i dont understand is, that getWeatherOfGepoint is always returning a weather, no matter how far the geoPoint is away. 

hope someone can guide me into the right direction..


public Weather getWeatherOfGeopoint(GeoPoint geoPoint, int meters) {

Polygon scopePolygon = GeometryService.getPolygon(geoPoint, meters);

@SuppressWarnings("unchecked")

List<Weather> weatherList = getSession()

.createCriteria(Weather.class)

.add(SpatialRestrictions.intersects("scope", scopePolygon))

.addOrder(Order.asc("createdAt"))

.setMaxResults(1)

.list();

if (!weatherList.isEmpty()){

return weatherList.get(0);

}

return null;

}




@Embeddable

public class GeoPoint {

private Double latitude;

private Double longitude;

public GeoPoint(double latitude, double longitude){

this.latitude = latitude;

this.longitude = longitude;

}

@SuppressWarnings("unused") // For Hibernate

private GeoPoint(){}

@Transient

public Double getLatitude() {

return latitude;

}

public void setLatitude(Double latitude) {

Assert.notNull(longitude, "latitude of a GPSPoint may not be set to null");

this.latitude = latitude;

}

@Transient

public Double getLongitude() {

return longitude;

}

public void setLongitude(Double longitude) {

Assert.notNull(longitude, "longitude of a GPSPoint may not be set to null");

this.longitude = longitude;

}

// FOR HIBERNATE

@Column(name="latitude")

private Double getLat(){

return this.latitude;

}

@SuppressWarnings("unused")

private void setLat(Double latitude){

this.latitude = latitude;

}

@Column(name="longitude")

private Double getLng(){

return this.longitude;

}

@SuppressWarnings("unused")

private void setLng(Double longitude){

this.longitude = longitude;

}

// END: FOR HIBERNATE

@Transient

public Point toPoint(){

Coordinate coo = new Coordinate(this.longitude, this.latitude);

Point point = GeometryService.getGeometryFactory().createPoint( coo );

point.setSRID(GeometryService.SRID);

return point;

}

}




public class GeometryService {

private static final GeometryFactory geoFactory = new GeometryFactory();

public static final int SRID = 4326;

public static GeometryFactory getGeometryFactory(){

return geoFactory;

}

public static double[] computeGeoPropotions(double latitude) {

double lat = Math.toRadians(latitude);


double m1 = 111132.92;

double m2 = -559.82;

double m3 = 1.175;

double m4 = -0.0023;

double p1 = 111412.84;

double p2 = -93.5;

double p3 = 0.118;


// Calculate the length of a degree of latitude and longitude in meters

double latlen = m1 + (m2 * Math.cos(2 * lat)) + (m3 * Math.cos(4 * lat)) + (m4 * Math.cos(6 * lat));

double longlen = (p1 * Math.cos(lat)) + (p2 * Math.cos(3 * lat)) + (p3 * Math.cos(5 * lat));

return new double[]{latlen, longlen};

}

/**

* Does not work accurately for very distant points. 

* Calculation based on the middle of latitudes. 

* @param p1

* @param p2

* @return

*/

public static double computeDistanceInMeters(GeoPoint p1, GeoPoint p2){

double latDistance = Math.abs(p1.getLatitude() - p2.getLatitude());

double lngDistance = Math.abs(p1.getLongitude() - p2.getLongitude());

double[] propotions = computeGeoPropotions( p1.getLatitude() + (latDistance / 2) );

double latMeters = latDistance * propotions[0];

double lngMeters = lngDistance * propotions[1];

// calculate hypotenuse

return Math.sqrt( Math.pow(latMeters,2) + Math.pow(lngMeters,2) );

}

public static Polygon getPolygon(GeoPoint point, int scopeInMeters){

double latitude = point.getLatitude();

double longitude = point.getLongitude();

double[] propotions = computeGeoPropotions(latitude);

double latMeters = ((double)scopeInMeters) / propotions[0];

double lonMeters = ((double)scopeInMeters) / propotions[1];

Coordinate[] coordinates = new Coordinate[]{

new Coordinate(longitude - lonMeters, latitude - latMeters),

new Coordinate(longitude + lonMeters, latitude - latMeters),

new Coordinate(longitude + lonMeters, latitude + latMeters),

new Coordinate(longitude - lonMeters, latitude + latMeters),

new Coordinate(longitude - lonMeters, latitude - latMeters)

};

LinearRing shellRing = geoFactory.createLinearRing(coordinates);

Polygon polygon = geoFactory.createPolygon(shellRing, null);

polygon.setSRID(SRID);

return polygon;

}

}


@Entity

public class Weather extends BaseEntity {

private GeoPoint geoPoint;

@Type(type = "org.hibernatespatial.GeometryUserType")

private Geometry scope;

private String weatherType;

private String weatherDegree;


public String getWeatherType() {

return weatherType;

}


public void setWeatherType(String weatherType) {

this.weatherType = weatherType;

}


public String getWeatherDegree() {

return weatherDegree;

}


public void setWeatherDegree(String weatherDegree) {

this.weatherDegree = weatherDegree;

}


public GeoPoint getGeoPoint() {

return geoPoint;

}


public void setGeoPoint(GeoPoint geoPoint) {

this.geoPoint = geoPoint;

}

@Type(type = "org.hibernatespatial.GeometryUserType")

public Geometry getScope() {

return scope;

}


public void setScope(Geometry scope) {

this.scope = scope;

}

@Override

@Transient

public JSONObject toJSON(){

JSONObject js = new JSONObject();


js.put("weatherDegree", this.getWeatherDegree().toString());

js.put("weatherType", this.getWeatherType().toString());

return js;

}



}


_______________________________________________
hibernatespatial-users mailing list
[hidden email]
http://www.hibernatespatial.org/cgi-bin/mailman/listinfo/hibernatespatial-users