angular-google-maps icon indicating copy to clipboard operation
angular-google-maps copied to clipboard

Set map bounds to circle bounds? (polyline, polygon, marker, circle)

Open ollietreend opened this issue 10 years ago • 14 comments

Hi,

Intro I am currently building a search tool which will plot search results on a map, similar to your typical store locator. The user chooses a location (lat/lon) to search from and a radius. A database is queried for records which are within the specified radius of the user's location. These results are returned back to the browser to be plotted on a Google Map with angular-google-maps.

I am using <markers> directive to display the results on the map. I am also using a <circle> directive to show the search radius, setting the "center" property to be the user's chosen location, and the "radius" property to be the search radius.

The Problem I would like to have the map fit to the bounds of the circle. I understand that I can set the "bounds" property on the <google-map> directive. However I'm not sure how I can retrieve the bounds of the circle.

Potential Solution The google.maps.Circle class has the method getBounds() which returns a LatLngBounds object. However I'm not sure if I'm able to access the Circle object of the <circle> directive in order to retrieve its bounds.

Even if I am able to retrieve the bounds of the <circle>, I'm not sure how I would store that in a scope model in order to assign it to the <google-map>.

Do you know how I could achieve the above using angular-google-maps?

Also Tried I have also tried setting "fit" to true on the <markers> directive. This works as expected, however because it fits the map based on the returned results, it doesn't center the map based on the initial search location, nor does it fit to the radius circle.

I want to show the search location in the center, even if the results only exist within the southern region of the radius circle. Therefore this approach doesn't achieve what I'm looking for.

Thanks

ollietreend avatar May 29 '14 15:05 ollietreend

I'll get back to you.

nmccready avatar May 29 '14 15:05 nmccready

I could easily add in a control object to the Circle and for that matter many objects so you could get the reference directly. Lastly if there is an events attribute you can listen on the events for the circle and the circle's reference is passed as the first argument.

Also see here for fit on a circle. http://stackoverflow.com/questions/9768439/how-to-google-map-circles-fit-the-map

(HACK) Lastly if that is not to you liking you can just do a fit on for mock markers that are all the same radius at 0, 90, 180, 270 degrees from the circle and that should produce a fit result.

nmccready avatar May 31 '14 15:05 nmccready

Well crap none of these options ( events, options, or control) exist on Circle.

https://github.com/nlaplante/angular-google-maps/blob/1.1.0/src/coffee/directives/circle.coffee

This would need to be an improvement, which should not take long. I can do it or if you would like to do it let me know as it would save me time to do other bugs.

nmccready avatar May 31 '14 15:05 nmccready

Please responds as I will not move on this until I hear back.

nmccready avatar May 31 '14 15:05 nmccready

Thanks for looking into this @nmccready.

I'm afraid pretty new to the world of GitHub & open source, and have yet to learn CoffeeScript (I'm primarily a PHP guy, but am starting to explore AngularJS).

If you could find the time to implement this feature, it would be much appreciated. I'll be sure to pick apart your changes to try and learn from them too.

ollietreend avatar Jun 01 '14 22:06 ollietreend

So, is there any enhancements for this feature?

Jerome2606 avatar Sep 01 '15 19:09 Jerome2606

No but I just added it to the milestone list. Feel free to have at it.

nmccready avatar Sep 01 '15 19:09 nmccready

OP here. The original project is long gone now (as of about 1 year), and I'm trying to remember how I worked around this (in case it's of any help to @Jerome2606). IIRC I did something along the lines of – centre the map based on the initial search lat/lon, and then 'guesstimated' the appropriate zoom level based on the user's chosen search radius.

The map in question needed to be responsive down to mobile devices, so unfortunately that added another variable into the mix. I think I played around with changing the zoom level based on screen width (window.matchMedia came in handy here), but that made things rather complicated so I gave up on that and stuck with 1 zoom level per radius.

YMMV, but that's the solution I went with. (Again, IIRC.)

Of course a proper solution to this would be ideal, but this doesn't seem to be a highly requested feature.

ollietreend avatar Sep 01 '15 19:09 ollietreend

I found a way to get Circle:

Use control attribute to circle directive and it's populate an object with function getCircle:

<ui-gmap-circle events="map.circle.events" control="map.circle.gObject"></ui-gmap-circle>

After you can simply do:

$scope.map.circle = {
    ...
    gObject: {},
                    events:{
                        radius_changed: function(){

                            $scope.map.control.getGMap().fitBounds($scope.map.circle.gObject.getCircle().getBounds());
                        }
                    }
};

Jerome2606 avatar Sep 02 '15 07:09 Jerome2606

@Jerome2606 perfect! It looks like the control object on the circle directive is new – that wasn't possible when I opened this ticket.

A 'fit' attribute on the circle directive would be the ideal solution, but the use of the control object is a nice workaround.

ollietreend avatar Sep 02 '15 07:09 ollietreend

Yeah I'll add fit since im in the midst of adding it to polyline, polygon, and marker.

nmccready avatar Sep 02 '15 13:09 nmccready

I'm running into a similar issue, but what I'm trying to do is use fitBounds method on my map (or the bounds config) to fit the map bounds to an array of Circles that are being drawn with the ui-gmap-circle directive.

Is there anyway to access the raw, underlying google.maps.Circle object for each of these after they are drawn on the map? I can figure out the bounding logic quite easily if I had access to the getBounds() methods on the Circle's themselves.

Pretty standard layout here:

                  <ui-gmap-google-map
                      center="detail.map.center"
                      options="detail.mapOptions"
                      zoom="detail.map.zoom"
                      events="detail.mapEvents">
                      <ui-gmap-circle
                          id="zone.id"
                          ng-repeat="zone in detail.profile.zones"
                          center='zone.center'
                          radius='zone.radius'
                          fill='zone.fill'
                          stroke='zone.stroke'
                          name="zone.name"
                          clickable='true'
                          draggable='true'
                          editable='true'
                          visible='true'
                          events='detail.zoneEvents'
                          >
                      </ui-gmap-circle>
                  </ui-gmap-google-map>

I've tried inspecting the map instance itself and it doesn't appear that anything is being added in terms of seeing which shapes are present on the map.

Any ideas on how I can access the raw Circle instances? I'm not sure the control solution that @Jerome2606 suggested will work in this case for repeated elements.

Additionally, is there some hook or event I can listen for to see when the circles have actually been added to the map? I've tried using the addFeature event on map, but that doesn't seem to fire.

Thanks!

dmackerman avatar Jan 19 '16 19:01 dmackerman

After a lot of sturggle, I came up with a modified version of the solution from @Jerome2606, maybe it will help someone to workaround this:

<ui-gmap-circle
    ...
    events="mapObjects.circle.events"
>
</ui-gmap-circle>
events:{
    dragend: function(circle, eventName, scope) {
        circle.getMap().fitBounds(circle.getBounds());
    },
    radius_changed: function(circle, eventName, scope) {
        circle.getMap().fitBounds(circle.getBounds());
    }
}

This will automatically zoom to the cricles bounds.

For polygons, this should work for dragging:

<ui-gmap-polygon
    ...
    events="mapObjects.polygon.events"
>
</ui-gmap-polygon>
events:{
    dragend: function(polygon, eventName, scope) {
        var bounds = new google.maps.LatLngBounds();
        var paths = polygon.getPaths();
        var path;
        for (var i = 0; i < paths.getLength(); i++) {
            path = paths.getAt(i);
            for (var ii = 0; ii < path.getLength(); ii++) {
                bounds.extend(path.getAt(ii));
            }
        }

        polygon.getMap().fitBounds(bounds);
    }
}

blaues0cke avatar May 03 '16 09:05 blaues0cke

Hi,

Is there any feature for drawing curved /Arc polyline between two latitude and longitude. If so can you please give me some info...?

ROJAHEMA avatar Mar 22 '18 17:03 ROJAHEMA