我有一个带Geopoints的数据库。 我需要进行查询以获得半径为X米的所有地理点。
我该怎么做?
我认为最好的方法是获得最小纬度/长度可能点,最大纬度/长点并得到所有这些点:geopoint > minPoint AND geopoint < MaxPoint
其他想法?
答案 0 :(得分:2)
您可以使用此类来获得点之间的距离:
使用方法:
double distInKm = GeoMath.getDistance(12.345, -8.788, 12.33, -8.77);
或者,如果point1和point2是GeoPoint:
double distInKm = GeoMath.getDistance(point1, point2);
您还可以计算一个Geopoint,它是您和轴承之间的距离。
这计算从point1向北5公里的点:
GeoPoint northPointAt5 = GeoMath.getGeoPointAlongBearing(point1, 0, 5);
您可以计算90度,180度和270度的其他点来计算minPoint和MaxPoint。
GeoMath类:
public class GeoMath {
public static final int EARTH_MEAN_RADIUS = 6371; // earth's mean radius in Km
public static double getDistance(double startLatitude, double startLongitude,
double endLatitude, double endLongitude){
return distHaversine(startLatitude,startLongitude,endLatitude,endLongitude);
}
public static double getDistance(GeoPoint point1, GeoPoint point2){
return distHaversine(point1.getLatitudeE6()/1E6, point1.getLongitudeE6()/1E6,
point2.getLatitudeE6()/1E6, point2.getLongitudeE6()/1E6);
}
private static double getSpanInRadians(double max, double min){
return Math.toRadians(max - min);
}
//Distance in Km between point1 (lat1,lon1) and point2 (lat2,lon2) Haversine formula
private static double distHaversine(double lat1, double lon1, double lat2, double lon2) {
double dLat = getSpanInRadians(lat2,lat1);
double dLon = getSpanInRadians(lon2,lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon/2) * Math.sin(dLon/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = EARTH_MEAN_RADIUS * c;
return Math.round(dist * 1000)/1000; //3 decimal places
}
// Get GeoPoint at distance along a bearing
// bearing in degrees
// distance in Km
public static GeoPoint getGeoPointAlongBearing(GeoPoint location, double bearing, double distance){
double PI = Math.PI;
double NM = 1.852; //1 nm = 1.852 Km -> nm = Km/NM
GeoPoint geoPointAlongBearing;
double locationLatRad = Math.toRadians(location.getLatitudeE6()/1E6);
double locationLongRad = Math.toRadians(location.getLongitudeE6()/1E6)*(-1.0d);
double distanceRad = distance/NM * PI/(180*60);
double bearingRad = Math.toRadians(bearing);
double latAlongBearingRad = Math.asin(Math.sin(locationLatRad) *
Math.cos(distanceRad) +
Math.cos(locationLatRad) *
Math.sin(distanceRad) *
Math.cos(bearingRad));
double lonAlongBearingRad = mod(locationLongRad -
Math.asin(Math.sin(bearingRad) *
Math.sin(distanceRad) /
Math.cos(latAlongBearingRad)) + PI, 2 * PI) - PI;
double latAlongBearing = rad2lat(latAlongBearingRad);
double lonAlongBearing = rad2lng(lonAlongBearingRad) * (-1);
geoPointAlongBearing = new GeoPoint((int)(latAlongBearing*1E6),(int)(lonAlongBearing*1E6));
return geoPointAlongBearing;
}
private static double mod(double y, double x) {
return y - x * Math.floor(y/x);
}
}
答案 1 :(得分:0)
根据您的查询,我认为您会找到位于您所在位置且边长为X的正方形内的所有点。
之后,yuo可以获得以半径X为中心的圆圈内的所有点。
这个伪代码怎么样:
//create your location
Location yourLocation=new Location("myLoc");
double latitude = geoPointYourLocation.getLatitudeE6() / 1E6;
double longitude = geoPointYourLocation.getLongitudeE6() / 1E6;
yourLocation.setLatitude(latitude);
yourLocation.setLongitude(longitude);
//Browse geopoints from DB, convert to GeoPoint and check if it is at a distance less than X
for (geoPointTemp in in query geopoint of your DDBB inside square) {
//create the location of the geopoint
Location locTemp=new Location("locTemp");
double latitude = geoPointTemp.getLatitudeE6() / 1E6;
double longitude = geoPointTemp.getLongitudeE6() / 1E6;
locTemp.setLatitude(latitude);
locTemp.setLongitude(longitude);
//calculate the distance between you and de temporary location
double distance=yourLocation.distanceTo(locTemp);
if(distance<X){
//do something
}
答案 2 :(得分:0)
使用Mysql,您可以使用内置的空间函数,例如GLength,linestring ....