Polygon Touch detection Google Map API V2

后端 未结 6 2088
小蘑菇
小蘑菇 2020-11-28 11:22

I\'m trying to figure out how best to do this, I have a map with one Polygon drawn on it. Since it doesn\'t seem as though the Google Maps API V2 has a touch de

6条回答
  •  难免孤独
    2020-11-28 12:16

    Though user1504495 has answered in short as I have used it. But instead of using whole Map Utility Library Use this methods.

    From your activity class pass params accordingly:

    if (area.containsLocation(Touchablelatlong, listLatlong, true))
                    isMarkerINSide = true;
                else
                    isMarkerINSide = false;
    

    and put following in a Separate class :

    /**
         * Computes whether the given point lies inside the specified polygon.
         * The polygon is always cosidered closed, regardless of whether the last point equals
         * the first or not.
         * Inside is defined as not containing the South Pole -- the South Pole is always outside.
         * The polygon is formed of great circle segments if geodesic is true, and of rhumb
         * (loxodromic) segments otherwise.
         */
        public static boolean containsLocation(LatLng point, List polygon, boolean geodesic) {
            final int size = polygon.size();
            if (size == 0) {
                return false;
            }
            double lat3 = toRadians(point.latitude);
            double lng3 = toRadians(point.longitude);
            LatLng prev = polygon.get(size - 1);
            double lat1 = toRadians(prev.latitude);
            double lng1 = toRadians(prev.longitude);
            int nIntersect = 0;
            for (LatLng point2 : polygon) {
                double dLng3 = wrap(lng3 - lng1, -PI, PI);
                // Special case: point equal to vertex is inside.
                if (lat3 == lat1 && dLng3 == 0) {
                    return true;
                }
                double lat2 = toRadians(point2.latitude);
                double lng2 = toRadians(point2.longitude);
                // Offset longitudes by -lng1.
                if (intersects(lat1, lat2, wrap(lng2 - lng1, -PI, PI), lat3, dLng3, geodesic)) {
                    ++nIntersect;
                }
                lat1 = lat2;
                lng1 = lng2;
            }
            return (nIntersect & 1) != 0;
        }
    
        /**
         * Wraps the given value into the inclusive-exclusive interval between min and max.
         * @param n   The value to wrap.
         * @param min The minimum.
         * @param max The maximum.
         */
        static double wrap(double n, double min, double max) {
            return (n >= min && n < max) ? n : (mod(n - min, max - min) + min);
        }
    
        /**
         * Returns the non-negative remainder of x / m.
         * @param x The operand.
         * @param m The modulus.
         */
        static double mod(double x, double m) {
            return ((x % m) + m) % m;
        }
    
        /**
         * Computes whether the vertical segment (lat3, lng3) to South Pole intersects the segment
         * (lat1, lng1) to (lat2, lng2).
         * Longitudes are offset by -lng1; the implicit lng1 becomes 0.
         */
        private static boolean intersects(double lat1, double lat2, double lng2,
                                          double lat3, double lng3, boolean geodesic) {
            // Both ends on the same side of lng3.
            if ((lng3 >= 0 && lng3 >= lng2) || (lng3 < 0 && lng3 < lng2)) {
                return false;
            }
            // Point is South Pole.
            if (lat3 <= -PI/2) {
                return false;
            }
            // Any segment end is a pole.
            if (lat1 <= -PI/2 || lat2 <= -PI/2 || lat1 >= PI/2 || lat2 >= PI/2) {
                return false;
            }
            if (lng2 <= -PI) {
                return false;
            }
            double linearLat = (lat1 * (lng2 - lng3) + lat2 * lng3) / lng2;
            // Northern hemisphere and point under lat-lng line.
            if (lat1 >= 0 && lat2 >= 0 && lat3 < linearLat) {
                return false;
            }
            // Southern hemisphere and point above lat-lng line.
            if (lat1 <= 0 && lat2 <= 0 && lat3 >= linearLat) {
                return true;
            }
            // North Pole.
            if (lat3 >= PI/2) {
                return true;
            }
            // Compare lat3 with latitude on the GC/Rhumb segment corresponding to lng3.
            // Compare through a strictly-increasing function (tan() or mercator()) as convenient.
            return geodesic ?
                    tan(lat3) >= tanLatGC(lat1, lat2, lng2, lng3) :
                    mercator(lat3) >= mercatorLatRhumb(lat1, lat2, lng2, lng3);
        }
    
        /**
         * Returns tan(latitude-at-lng3) on the great circle (lat1, lng1) to (lat2, lng2). lng1==0.
         * See http://williams.best.vwh.net/avform.htm .
         */
        private static double tanLatGC(double lat1, double lat2, double lng2, double lng3) {
            return (tan(lat1) * sin(lng2 - lng3) + tan(lat2) * sin(lng3)) / sin(lng2);
        }
    
        /**
         * Returns mercator Y corresponding to latitude.
         * See http://en.wikipedia.org/wiki/Mercator_projection .
         */
        static double mercator(double lat) {
            return log(tan(lat * 0.5 + PI/4));
        }
    
        /**
         * Returns mercator(latitude-at-lng3) on the Rhumb line (lat1, lng1) to (lat2, lng2). lng1==0.
         */
        private static double mercatorLatRhumb(double lat1, double lat2, double lng2, double lng3) {
            return (mercator(lat1) * (lng2 - lng3) + mercator(lat2) * lng3) / lng2;
        } 
    

提交回复
热议问题