我有一个应用程序,可以找到用户与多边形之间的最短距离。
我想将多边形转换为Geofence,以检查用户与区域之间的距离,以便向用户提供准确的信息。
我该怎么做?
这是MapsActivity
public class MinimumDistanceTask extends AsyncTask<String, Void, Integer>{
private int closeLocation;
// private String points;
private GetMinimumDistanceListener listener;
public MinimumDistanceTask(GetMinimumDistanceListener listener){
// this.points = points;
this.listener = listener;
}
@Override
protected Integer doInBackground(String... params) {
HttpsURLConnection connection = null;
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
int minimumDis = -1;
String address = params[0];
try {
URL url = new URL(address);
connection = (HttpsURLConnection) url.openConnection();
if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
return -1;
}
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
builder.append(line);
}
///get the json data
JSONObject jsonObject1 = new JSONObject(builder.toString());
JSONArray points = jsonObject1.getJSONArray("rows");
JSONObject jsonObject2 = points.getJSONObject(0);
JSONArray elements = jsonObject2.getJSONArray("elements");
for (int i = 0; i < elements.length(); i++) {
JSONObject jsonObject3 = elements.getJSONObject(i);
JSONObject distance = jsonObject3.getJSONObject("distance");
if( distance.getInt("value") < minimumDis || minimumDis == -1) {
minimumDis = distance.getInt("value");
closeLocation = i;
}
}
} catch (MalformedURLException | JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return closeLocation;
}
@Override
protected void onPostExecute(Integer closeLocation) {
listener.getMinimumDistance(closeLocation);
}
public interface GetMinimumDistanceListener{
void getMinimumDistance(int closeLocation);
}
}
这是我的AsyncTask以获得最小距离点
DbContext(string)
非常感谢:)。
答案 0 :(得分:9)
您可以使用以下函数计算由List<LatLng>
和给定LatLng
定义的多边形中的最近点。
它使用Google Maps Android API Utility Library中的PolyUtil.distanceToLine
来计算测试LatLng
与列表的每个细分之间的距离,以及基于distanceToLine
方法的方法https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java计算某个点上某个点的投影。
private LatLng findNearestPoint(LatLng test, List<LatLng> target) {
double distance = -1;
LatLng minimumDistancePoint = test;
if (test == null || target == null) {
return minimumDistancePoint;
}
for (int i = 0; i < target.size(); i++) {
LatLng point = target.get(i);
int segmentPoint = i + 1;
if (segmentPoint >= target.size()) {
segmentPoint = 0;
}
double currentDistance = PolyUtil.distanceToLine(test, point, target.get(segmentPoint));
if (distance == -1 || currentDistance < distance) {
distance = currentDistance;
minimumDistancePoint = findNearestPoint(test, point, target.get(segmentPoint));
}
}
return minimumDistancePoint;
}
/**
* Based on `distanceToLine` method from
* https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java
*/
private LatLng findNearestPoint(final LatLng p, final LatLng start, final LatLng end) {
if (start.equals(end)) {
return start;
}
final double s0lat = Math.toRadians(p.latitude);
final double s0lng = Math.toRadians(p.longitude);
final double s1lat = Math.toRadians(start.latitude);
final double s1lng = Math.toRadians(start.longitude);
final double s2lat = Math.toRadians(end.latitude);
final double s2lng = Math.toRadians(end.longitude);
double s2s1lat = s2lat - s1lat;
double s2s1lng = s2lng - s1lng;
final double u = ((s0lat - s1lat) * s2s1lat + (s0lng - s1lng) * s2s1lng)
/ (s2s1lat * s2s1lat + s2s1lng * s2s1lng);
if (u <= 0) {
return start;
}
if (u >= 1) {
return end;
}
return new LatLng(start.latitude + (u * (end.latitude - start.latitude)),
start.longitude + (u * (end.longitude - start.longitude)));
}
您可以使用以下代码对其进行测试:
List<LatLng> points = new ArrayList<>();
points.add(new LatLng(2, 2));
points.add(new LatLng(4, 2));
points.add(new LatLng(4, 4));
points.add(new LatLng(2, 4));
points.add(new LatLng(2, 2));
LatLng testPoint = new LatLng(3, 0);
LatLng nearestPoint = findNearestPoint(testPoint, points);
Log.e("NEAREST POINT: ", "" + nearestPoint); // lat/lng: (3.0,2.0)
Log.e("DISTANCE: ", "" + SphericalUtil.computeDistanceBetween(testPoint, nearestPoint)); // 222085.35856591124