Finden Sie den nächstgelegenen Punkt auf dem Polygon zum Benutzerstandort

Ich habe eine App, die die kürzeste Entfernung zwischen meinem Benutzer und einem Polygon ermittelt.

Ich möchte das Polygon in Geofence konvertieren, um den Abstand zwischen dem Benutzer und dem Bereich zu überprüfen und dem Benutzer genauere Informationen zu geben.

wie kann ich das machen

dies ist die MapsActivity

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, MinimumDistanceTask.GetMinimumDistanceListener {
    private GoogleMap mMap;
    private  LocationManager manager;
    private double lat, lng;
    private KmlLayer layer;
    private LatLng latLngTest;
    private  boolean contains = false;
    private  ArrayList<LatLng> outerBoundary;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
        manager = (LocationManager) getSystemService(LOCATION_SERVICE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        String provider = LocationManager.GPS_PROVIDER;

        //take the user location every second
        try {
            manager.requestLocationUpdates(provider, 1000, 0, this);
        }catch (SecurityException e){

        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
    }

    @Override
    public void onLocationChanged(Location location) {
        //clear map before create new location
        mMap.clear();
        try {
            //load the kml file
            layer = new KmlLayer(mMap, R.raw.polygon_layer, this);
            layer.addLayerToMap();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }

        lat = location.getLatitude();
        lng = location.getLongitude();
        latLngTest = new LatLng(lat,lng);
        // Add a marker in user location
        LatLng userLocation = new LatLng(latLngTest.latitude, latLngTest.longitude);
        mMap.addMarker(new MarkerOptions().position(userLocation).title("you are here"));
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));

        //check if the user in the polygon
        boolean inside = ifUserInside();

        if(inside){
            Toast.makeText(MapsActivity.this, "you are in the polygon", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(MapsActivity.this, "you are outside the polygon", Toast.LENGTH_SHORT).show();
            //create the string address for the url
            String address = "";
            for (int i = 0; i < outerBoundary.size(); i++) {
                address += (outerBoundary.get(i).toString() + "|");
                address = address.replace("lat/lng:", "");
                address = address.replace(" ", "");
                address = address.replace("(", "");
                address = address.replace(")", "");
            }
            MinimumDistanceTask task = new MinimumDistanceTask(this);
            task.execute("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+latLngTest.latitude+ "," + latLngTest.longitude
                    + "&destinations=" + address + "&mode=walking");
        }

    }

    @Override
    public void getMinimumDistance(int closeLocation) {
        //check if you get results properly
        if(closeLocation != -1) {
            GetDirection direction = new GetDirection();
            direction.execute("https://maps.googleapis.com/maps/api/directions/json?origin=" + latLngTest.latitude + "," + latLngTest.longitude
                    + "&destination=" + outerBoundary.get(closeLocation).latitude + "+" + outerBoundary.get(closeLocation).longitude);
        }
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    public boolean ifUserInside(){
        if (layer.getContainers() != null) {
            for (KmlContainer container : layer.getContainers()) {
                if (container.getPlacemarks() != null) {
                    for (KmlPlacemark placemark : container.getPlacemarks()) {
                        contains = false;

                        if (placemark.getGeometry() instanceof KmlPolygon) {
                            KmlPolygon polygon = (KmlPolygon) placemark.getGeometry();

                            // Get the outer boundary and check if the test location lies inside
                            outerBoundary = polygon.getOuterBoundaryCoordinates();
                            contains = PolyUtil.containsLocation(latLngTest, outerBoundary, true);



                            if (contains) {
                                // Get the inner boundaries and check if the test location lies inside
                                ArrayList<ArrayList<LatLng>> innerBoundaries = polygon.getInnerBoundaryCoordinates();
                                if (innerBoundaries != null) {
                                    for (ArrayList<LatLng> innerBoundary : innerBoundaries) {
                                        // If the test location lies in a hole, the polygon doesn't contain the location
                                        if (PolyUtil.containsLocation(latLngTest, innerBoundary, true)) {
                                            contains = false;

                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return contains;
    }

    public class GetDirection extends AsyncTask<String , Void, String> {
        HttpsURLConnection connection = null;
        BufferedReader reader = null;
        StringBuilder builder = new StringBuilder();
        @Override
        protected String doInBackground(String... params) {
            String address = params[0];

            try {
                URL url = new URL(address);
                connection = (HttpsURLConnection) url.openConnection();
                if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
                    return "Error from server";
                }

                reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                while ((line = reader.readLine()) != null){
                    builder.append(line);
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return builder.toString();
        }

        @Override
        protected void onPostExecute(String s) {
        //get the polyline string
            String polygonPoints = "";

            try {
                JSONObject object = new JSONObject(s);
                JSONArray array = object.getJSONArray("routes");
                for (int i = 0; i < array.length(); i++) {
                    JSONObject arrObj1 = array.getJSONObject(i);
                    JSONObject points = arrObj1.getJSONObject("overview_polyline");
                    polygonPoints = points.getString("points");

                }
                //convert the string to polyline;
                ArrayList<LatLng> a = new ArrayList<>(decodePolyPoints(polygonPoints));
                //add polyline to the map
                mMap.addPolyline(new PolylineOptions().addAll(a).width(10).color(Color.BLUE));

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    //the method that convert the string to polyline
    public static ArrayList<LatLng> decodePolyPoints(String encodedPath){
        int len = encodedPath.length();

        final ArrayList<LatLng> path = new ArrayList<LatLng>();
        int index = 0;
        int lat = 0;
        int lng = 0;

        while (index < len) {
            int result = 1;
            int shift = 0;
            int b;
            do {
                b = encodedPath.charAt(index++) - 63 - 1;
                result += b << shift;
                shift += 5;
            } while (b >= 0x1f);
            lat += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);

            result = 1;
            shift = 0;
            do {
                b = encodedPath.charAt(index++) - 63 - 1;
                result += b << shift;
                shift += 5;
            } while (b >= 0x1f);
            lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);

            path.add(new LatLng(lat * 1e-5, lng * 1e-5));
        }

        return path;
    }
}

Dies ist meine AsyncTask, um den Mindestentfernungspunkt zu erhalten

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);
    }
}

Vielen Dank :

Antworten auf die Frage(2)

Ihre Antwort auf die Frage