@Override public GeoSpatialFeature getCentroid() { // create the centroid geospatial feature set GeoSpatialFeature centroid = new GeoSpatialFeature(name); centroid.setValue( (clat), (clon) ); // return average lat, lon - very crude method of determining centroid for geo centroid.setWeight(weight); return centroid; }
@Override public void add(GeoSpatialFeature feature) { double addedWeight = feature.getWeight(); double newWeight = weight + addedWeight; // incrementally revise the centroid coordinates clat = (clat * weight + feature.getLatitude() * addedWeight) / newWeight; clon = (clon * weight + feature.getLongitude() * addedWeight) / newWeight; weight = newWeight; }
@Override public String toString() { return (this.getName() + ":[" + latitude + ";" + longitude + "]"); }
@Override public double distance(GeoSpatialFeature x, GeoSpatialFeature y) { double lat1 = x.getLatitude(); double lat2 = y.getLatitude(); double lon1 = x.getLongitude(); double lon2 = y.getLongitude(); // return normalized euclidean distance [0,1] return Math.sqrt(Math.pow(lat2 - lat1, 2) + Math.pow(lon2 - lon1, 2)) * normConst; }
public GeoSpatialFeature fieldToGeoSpatialFeature(String name) { Field field = fields.get(name); if (field == null) return null; GeoSpatialFeature feature = null; try { feature = new GeoSpatialFeature(field.name); String val = field.value.substring(1, field.value.length()-1); // strip off enclosing [ ] if (val.isEmpty()) return null; String[] tokens = val.split(";"); feature.setValue(Double.parseDouble(tokens[0]), Double.parseDouble(tokens[1])); } catch (Exception e) { e.printStackTrace(); } return feature; }
@Override public double distance(GeoSpatialFeature x, GeoSpatialFeature y) { double lat1 = Math.toRadians(x.getLatitude()); double lat2 = Math.toRadians(y.getLatitude()); double lon1 = Math.toRadians(x.getLongitude()); double lon2 = Math.toRadians(y.getLongitude()); double a = (lon2-lon1) * Math.cos((lat1+lat2)/2); double b = (lat2-lat1); double d = Math.sqrt(a*a + b*b); return d; } }
@Override public GeoSpatialFeature getCentroid() { double lat = 0, lon = 0, hyp = 0; // calculate average x,y,z coords double ax = cx/weight, ay = cy/weight, az = cz/weight; // convert the centroid cartesian coordinates to lat/lon lon = Math.toDegrees(Math.atan2(ay, ax)); hyp = Math.sqrt(ax * ax + ay * ay); lat = Math.toDegrees(Math.atan2(hyp, az)); // create the centroid geospatial feature set GeoSpatialFeature centroid = new GeoSpatialFeature(name); centroid.setValue(lat, lon); centroid.setWeight(weight); return centroid; }
@Override public void remove(GeoSpatialFeature feature) { double removedWeight = feature.getWeight(); double newWeight = weight - removedWeight; if (weight <= 0.0) { System.out.println("Attempt to remove from empty GeoSpatialCentroid"); } else { clat = (clat * weight - feature.getLatitude() * removedWeight) / newWeight; clon = (clon * weight - feature.getLongitude() * removedWeight) / newWeight; weight = newWeight; } }
@Override public double distance(GeoSpatialFeature x, GeoSpatialFeature y) { double lat1 = Math.toRadians(x.getLatitude()); double lat2 = Math.toRadians(y.getLatitude()); double lon1 = Math.toRadians(x.getLongitude()); double lon2 = Math.toRadians(y.getLongitude()); double d = Math.acos(Math.sin(lat1)*Math.sin(lat2) + Math.cos(lat1)*Math.cos(lat2) * Math.cos(lon2-lon1)); double normDist = d / Math.PI; return normDist; }
@Override public void remove(GeoSpatialFeature feature) { double removedWeight = feature.getWeight(); double x = 0, y = 0, z = 0, lat = 0, lon = 0; // convert lat/lon to cartesian coordinates lat = Math.toRadians(feature.getLatitude()); lon = Math.toRadians(feature.getLongitude()); x = Math.sin(lat) * Math.cos(lon); y = Math.sin(lat) * Math.sin(lon); z = Math.cos(lat); // decrement the centroid cartesian coordinates cx -= x * removedWeight; cy -= y * removedWeight; cz -= z * removedWeight; // Decrease the weight of this centroid according to what was removed. weight = weight - removedWeight; }
@Override public double distance(GeoSpatialFeature x, GeoSpatialFeature y) { double lat1 = x.getLatitude(); double lat2 = y.getLatitude(); double lon1 = x.getLongitude(); double lon2 = y.getLongitude(); double dLat = Math.toRadians(lat2 - lat1); double dLng = Math.toRadians(lon2 - lon1); double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLng / 2) * Math.sin(dLng / 2); double normDist = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) / Math.PI; return normDist; }
@Override public void add(GeoSpatialFeature feature) { double addedWeight = feature.getWeight(); double x = 0, y = 0, z = 0, lat = 0, lon = 0; // convert lat/lon to cartesian coordinates lat = Math.toRadians(feature.getLatitude()); lon = Math.toRadians(feature.getLongitude()); x = Math.sin(lat) * Math.cos(lon); y = Math.sin(lat) * Math.sin(lon); z = Math.cos(lat); // Increase the weight of this centroid according to what was added. weight += addedWeight; // revise the centroid cartesian coordinates cx += x * addedWeight; cy += y * addedWeight; cz += z * addedWeight; }
public double distanceInKM(GeoSpatialFeature x, GeoSpatialFeature y) { double lat1 = x.getLatitude(); double lat2 = y.getLatitude(); double lon1 = x.getLongitude(); double lon2 = y.getLongitude(); double dLat = Math.toRadians(lat2-lat1); double dLng = Math.toRadians(lon2-lon1); double a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLng/2) * Math.sin(dLng/2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); double dist = EARTH_RADIUS * c; return dist; } }
public double distanceInCartesianPlane(GeoSpatialFeature x, GeoSpatialFeature y) { double lat1 = Math.toRadians(x.getLatitude()); double lat2 = Math.toRadians(y.getLatitude()); double lon1 = Math.toRadians(x.getLongitude()); double lon2 = Math.toRadians(y.getLongitude()); double x1 = EARTH_RADIUS * Math.cos(lat1) * Math.cos(lon1); double x2 = EARTH_RADIUS * Math.cos(lat2) * Math.cos(lon2); double y1 = EARTH_RADIUS * Math.cos(lat1) * Math.sin(lon2); double y2 = EARTH_RADIUS * Math.cos(lat1) * Math.sin(lon2); double z1 = EARTH_RADIUS * Math.sin(lat1); double z2 = EARTH_RADIUS * Math.sin(lat2); // return normalized euclidean distance [0,1] return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) + Math.pow(z2 - z1, 2)) * normConst; } }