rungwiroon / BlazorGoogleMaps

Blazor interop for GoogleMap library
MIT License
319 stars 102 forks source link

Marker Selection #262

Closed nnikos123 closed 1 year ago

nnikos123 commented 1 year ago

Hello Is it possible to select & identify markers and/or clusters, by drawing a closed area/shape (e.g. circle, polygon, rectangle) around them? This will be a very useful feature when we need to identify markers/clusters and process business objects attached to them

Any idea will be very appreciated.

valentasm1 commented 1 year ago

Nah. You should create your own. Get bounds of rectangle then check if marker coordintes is inside it.

nnikos123 commented 1 year ago

Nah. You should create your own. Get bounds of rectangle then check if marker coordintes is inside it.

sure for the rectangle case is very simple but for more complex geometries is not so easy. For example mapbox utilize turf.js which exposes "pointsWithinPolygon" . But as you said your lib does not have such tools. anyway thank you for your quick reply N

valentasm1 commented 1 year ago

I did this and it is quite easy. https://stackoverflow.com/questions/217578/how-can-i-determine-whether-a-2d-point-is-within-a-polygon/2922778#2922778

public static bool IsPointInPolygon(ICoordinate p, IList<CoordinateGrpc> polygon)
        {
            double minX = polygon[0].Latitude;
            double maxX = polygon[0].Latitude;
            double minY = polygon[0].Longitude;
            double maxY = polygon[0].Longitude;
            for (int i = 1; i < polygon.Count; i++)
            {
                var q = polygon[i];
                minX = Math.Min(q.Latitude, minX);
                maxX = Math.Max(q.Latitude, maxX);
                minY = Math.Min(q.Longitude, minY);
                maxY = Math.Max(q.Longitude, maxY);
            }

            if (p.Latitude < minX || p.Latitude > maxX || p.Longitude < minY || p.Longitude > maxY)
            {
                return false;
            }

            // https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html
            bool inside = false;
            for (int i = 0, j = polygon.Count - 1; i < polygon.Count; j = i++)
            {
                if ((polygon[i].Longitude > p.Longitude) != (polygon[j].Longitude > p.Longitude) &&
                    p.Latitude < (polygon[j].Latitude - polygon[i].Latitude) * (p.Longitude - polygon[i].Longitude) / (polygon[j].Longitude - polygon[i].Longitude) + polygon[i].Latitude)
                {
                    inside = !inside;
                }
            }

            return inside;
        }