angular-ui / ui-leaflet

AngularJS directive to embed an interact with maps managed by Leaflet library
http://angular-ui.github.io/ui-leaflet
Other
315 stars 137 forks source link

Cannot use leaflet directive multiple time at once. #11

Open nmccready opened 8 years ago

nmccready commented 8 years ago

From @wayofspark on March 19, 2014 15:58

Hello,

The _leafletMap directive variable singleton in the root directive cause leaflet to crash in various way if more than one map is used at the same time in the application. ( all maps use the variable, causing previous maps to loose reference to their own map at one point )

Fix should be easy using a scope variable instead of directive singleton to store the map promise.

Copied from original issue: tombatossals/angular-leaflet-directive#331

nmccready commented 8 years ago

From @tombatossals on March 20, 2014 13:27

Hi, have you tried passing an id to the "leaflet" tag? The leafletData object stores a leaflet object based on the id, so it will be able to fetch the required map object when you ask for it.

For example:

<leaflet id="first" center="london"></leaflet>
<leaflet id="second" center="paris"></leaflet>

Then you can use:

leafletData.getMap("first").then(function(map) {
    console.log(map);
});

Take a look at this example code: http://tombatossals.github.io/angular-leaflet-directive/examples/double-map-example.html

I think this will solve the behaviour you are experiencing.

nmccready commented 8 years ago

From @wixo on March 21, 2014 5:36

This is kind of happening to me too with async loaded views, when I go back and forth between these views the current leaflet map inherits the center of the previous leaflet map. I am using the ids as advised.

nmccready commented 8 years ago

From @tombatossals on March 21, 2014 6:46

Can you guys code a simple case where I can see this behaviour?

You could fork this jsfiddle example as a starting point:

http://jsfiddle.net/tombatossals/4PhzC/

nmccready commented 8 years ago

From @dnazarov on March 21, 2014 8:27

Is this example OK? You may change some of scope preperties directly through the scope methods. http://jsfiddle.net/4PhzC/36/

nmccready commented 8 years ago

From @ugaz on April 23, 2014 22:48

There is an issue with the _layersControl when you have multiple maps: it is also a singleton. I have fixed it replacing "var _layersControl;" by "var _layersControl = [];" and every occurrence of the variable "_layersControl" by "_layersControl[mapId]". Seemed to work for me, though I am sort of newbie both in angularjs and leaflet, and I'm not sure if this is the best solution. Hope you hackers could take it from here, maybe...

By the way, thanks for the good job!!

nmccready commented 8 years ago

From @Splaktar on September 24, 2014 19:3

I'm seeing this as well. All of the markers which are on layers (feature group) are applied to the first map on the page. This includes using marker clustering. If the markers are not on layers, then the markers get applied to the proper map. But our use case requires that all of the markers be in separate layers/feature groups.

So this limits us to using only one map per page, which is a significant limitation that we would like to see removed.

nmccready commented 8 years ago

From @michaelryancaputo on October 8, 2014 14:16

Having this issue as well. Having an issue building a dynamic map that has the ability to toggle various geojson and popup data. I've settled on having multiple maps on the page, and show/hiding them, but now that i've built that, I'm finding that I can't have more than one map showing different data on one page. I've tried passing the id solution as above with no luck unfortunately.

nmccready commented 8 years ago

From @tombatossals on October 8, 2014 14:28

Hey guys, can anyone make a jsfiddle where I can see this behaviour?

nmccready commented 8 years ago

From @tombatossals on October 8, 2014 14:32

@flashpunk, do you mean that you can't show two maps on the web page with different markers on each one? Is there some more complexity on your code?

I'm going to try to make a jsfiddle myself

nmccready commented 8 years ago

From @tombatossals on October 8, 2014 14:39

http://jsfiddle.net/4PhzC/168/

This jsfidle could be an starting point. Could anyone ellaborate a more complex example where we can see the failure?

nmccready commented 8 years ago

From @michaelryancaputo on October 8, 2014 19:30

I'm using multiple maps with different geojson data on each one (not markers) - also including data, style, and onEachFeature popups for each geojson boundary.

nmccready commented 8 years ago

From @michaelryancaputo on October 9, 2014 14:27

Ok, so i've been playing with your example above, with some of the extra features i'm using and it seems to be working... Going to go back again and try and re implement it again.

http://jsfiddle.net/flashpunk/vosru6t9/

nmccready commented 8 years ago

From @tombatossals on October 9, 2014 17:10

Fantastic example. Would you mind if I put this code in the project as an example of how to use multiple maps and geojson data at the same time?

nmccready commented 8 years ago

From @michaelryancaputo on October 9, 2014 17:38

Just found this bug with ng-show/ng-hide - the map on the show/hide doesn't seem to want to draw: http://jsfiddle.net/flashpunk/vosru6t9/1/

Sure feel free to use the example.

nmccready commented 8 years ago

From @tombatossals on October 16, 2014 6:38

Yes, the ng-show/ng-hide behaviour is related with leaflet, which needs to call "invalidateSize" when the size of the div is changed. You can easily solve this using ng-if instead of ng-show:

http://jsfiddle.net/bL69rzch/1/

I'll add your example to the project, thanks.

nmccready commented 8 years ago

From @michaelryancaputo on October 16, 2014 15:33

FYI, I ended up scrapping this method, and using this gist: https://gist.github.com/pospi/85c31530c4a93cf091ce

It destroys the layer and recreates a new one. I've also had to hack a way to destroy the legend and create a new one whenever the button was created (that was done with angular.element('.legend.leaflet-control').remove();)

Can probably create a fiddle at some point with an example for anyone else needing this type of functionality.

nmccready commented 8 years ago

From @tombatossals on October 17, 2014 15:33

Hi @flashpunk, just added your example here:

http://tombatossals.github.io/angular-leaflet-directive/examples/double-map-sharing-attributes.html

Thanks for sharing

nmccready commented 8 years ago

From @Splaktar on October 22, 2014 20:59

That example is helpful but it still isn't quite what I need. I debugged this a lot more today.

Basically, I need to pass in dynamic names to the directive via the attribs. But since the directive uses isolated scope with = (two way data binding) you cannot use data binding in the attribs. Do you really need to be bound in both directions? Should the directive really be modifying the event-broadcast, markers, paths, or layers objects? It seems like these should be input only?

Here is what I need to work:

  <leaflet id="{{map.uuid}}" center="'{{ 'leaflet.center.' + map.name }}" markers="{{ 'leaflet.markers.' + map.name }}"
           layers="{{'leaflet.layers.' + map.name}}" controls="controls" paths="{{'leaflet.paths.' + map.name}}"
           event-broadcast="{{'leaflet.events.' + map.name}}"
           class="leaflet-map"></leaflet>

But this fails with Angular exceptions since you can't use data binding for these attributes.

nmccready commented 8 years ago

From @michaelryancaputo on October 22, 2014 23:16

@Splaktar This isn't the full answer you're looking for, but in the end I was able to render multiple different maps by modifying and using this directive: https://gist.github.com/pospi/85c31530c4a93cf091ce

nmccready commented 8 years ago

From @kuanb on June 5, 2015 21:26

Wondering if anyone has any insight on the following TypeError (seems to likely be related to this issue). I have two maps, map_left and map_right. When adding new layers, using leafletData.getMap('map_xxx').then(function(map) { ... } works great but whichever map I attempt to var.addTo(map) second (after one map has already been interacted with), results in the following TypeError:

Uncaught TypeError: Cannot read property 'min' of undefined
o.LineUtil._getBitCode @ leaflet.js:8
o.LineUtil.clipSegment @ leaflet.js:8
o.Polyline.o.Path.extend._clipPoints @ leaflet.js:8
o.Polyline.o.Path.extend._updatePath @ leaflet.js:8
o.Mixin.Events.fireEvent @ leaflet.js:6
o.Util.bind @ leaflet.js:6

I should not this occurred when employing leafletData.getMap('map_left').then(function(map) { ... }.

tfendt commented 8 years ago

Did this ever get fixed? I am still having this issue.

nmccready commented 8 years ago

Related #261 #250 #87