miguelcobain / ember-leaflet Goto Github PK
View Code? Open in Web Editor NEW:fire: :leaves: Easy and declarative mapping for ember
Home Page: https://miguelcobain.github.io/ember-leaflet/
License: MIT License
:fire: :leaves: Easy and declarative mapping for ember
Home Page: https://miguelcobain.github.io/ember-leaflet/
License: MIT License
Hey,
I have a fullscreen map on a route. The route has lat
, lng
and zoom
query params used to control the map (when these change, a model refresh is fired and markers are grabbed from the server). I update these controller properties when the user moves the map.
Roughly, I have:
export default Ember.Controller.extend({
lat: null,
lng: null,
zoom: null,
actions: {
updatePosition(e) {
var map = e.target;
this.setProperties({
lat: map.getCenter().lat,
lng: map.getCenter().lng,
zoom: map.getZoom()
});
},
markerClicked(marker) {
this.transitionToRoute('my.route', {
queryParams: {
lat: marker.get('lat'),
lng: marker.get('lng'),
zoom: 16
}
});
},
}
});
and
{{#leaflet-map lat=lat lng=lng zoom=zoom onMoveend=(action "updatePosition")}}
{{tile-layer url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"}}
{{#each model as |place|}}
{{marker-layer ... onClick=(action "markerClicked" place)}}
{{/each}}
{{/leaflet-map}}
This is actually working really nicely, but there is a slight bug. When I use transitionToRoute
to change the position of the map via query params, it seems that the component is firing two events and one is cancelling the other out. The result is that when I transition, the zoom animation will work but the pan animation won't fire properly. Instead, the map will move a little bit and I will have to touch the map again to get the marker to center correctly.
I have temporarily fixed this by simply disabling the zoom animation:
{{#leaflet-map lat=lat lng=lng zoom=zoom zoomAnimation=false onMoveend=(action "updatePosition")}}
and now it works nicely but I was wondering is there anything that can be done to get both the animations working together?
Disclaimer
I have simplified the problem a bit. I know that I could simply change the lat
lng
properties when I click the marker and that would update the map component automatically but in my actual application the route with the map is actually a parent to another route which I am transitioning to so I have to use query params
Can you point me in the right direction? I'm thinking in several directions, but nothing what I would consider elegant solution.
The following is required for Leaflet to render assets correctly when doing a production build:
var app = new EmberApp(defaults, {
// Add options here
fingerprint: {
exclude: [
'images/layers-2x.png',
'images/layers.png',
'images/marker-icon-2x.png',
'images/marker-icon.png',
'images/marker-shadow.png'
]
}
});
Whenever I click on a marker-layer a popup appears.
How to disable this?
Currently leafletOptions
has hardcoded the leaflet options ('center', 'zoom', 'minZoom', 'maxZoom', 'maxBounds', 'crs',...
), and doesn't allow to pass custom properties to the map
.
I'm using leaflet-zoomslider
that requires to pass zoomsliderControl: true
when calling L.map
. I solved it extending the component and pushing the string to leafletOptions
on component init, but I think that this could be done in a better way :)
when using the map with zoom=0, this line is triggered
zoom=0 is a valid value though
Sorry that I do not take the time now to make a PR with a test for this...
I frequently subclass ember-leaflet components to get some specific behavior, and as such, I have events that the component should handle itself. It'd be handy to be able to do this:
export default BaseLayer.extend({
onMouseover() {
console.log(this.get('someValue'));
}
});
At present, code like the above results in an error, as this
is undefined. Instead, I have to use this workaround:
export default BaseLayer.extend({
init() {
this._super(...arguments);
this.set('onMouseover', () => console.log(this.get('someValue')));
}
});
After investigating, it appears that the culprit is the InvokeActionMixin, which invokes all action functions with a this
context of undefined
. I get that that's more in line with ES6 semantics, but it also makes this use case awkward. Is there a better way to do what I'm trying to do, and if not, could we find some way to pass the component context along to the action handler?
I'm plotting a number of markers that are built from Ember Data models:
{{#leaflet-map id="stop-explorer-map" lat=lat lng=lng zoom=zoom}}
{{tile-layer url="http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png"}}
{{#each model as |stop|}}
{{marker-layer location=stop.latLng title=stop.name onMouseover="startMarkerMouseover"}}
{{/each}}
{{/leaflet-map}}
I'd like to be able to modify the appropriate Ember Data model on mouseover start and end, to toggle a "selected" property. (That's going to highlight that same model in a different table view.)
I see how the startMarkerMouseover
event in my code only receives the Leaflet raw event. Is there a way to provide parameters to the action, so I can pass the stop model in the action handler?
I'm using a computed property to center the map on bounds calculeted from the set of markers added to the map:
bounds: Ember.computed('places', function(){
return L.latLngBounds(this.get('places').map(function(place){ return place.get('location'); }));
})
This works but not on the initial page load. On the first page load the map, the map is not zoomed. The set of markers is set on the controller from the route.
We have the situation, that we have to render a lot of markers (e.g. > 300). I could think of an optimization, that only markers which location is visible in the current "viewport" (depending on lat
, lng
and zoom
) actually get rendered onto the map. I think this could boost the performance a lot, since the amount of markers gets significantly reduced.
What do you think? Is there any downside?
http://www.ember-leaflet.com/docs/container doesn't display any map (tiles). In the javascript console following error is displayed: "TypeError: undefined is not an object (evaluating 'e.lat')"
It's my first ember addon / npm package etc., so I hope I didn't make some newbie mistake :-) But it works for me...
https://www.npmjs.com/package/ember-leaflet-multi-options-polyline
In my application I have a route called 'places' that shows all places as markers on the map. I also managed to get the markers clickable. After clicking a marker the route changes to 'places/:place_id' and detailed information are shown next to the map. This works without any problems. Now, I'm trying to highlight the selected marker on the map, but I couldn't find a way to do this without using ArrayController and ItemController as I did some time ago. Also only one marker should be selectable at one time.
I know that my question is more a general Ember question, sorry for that. But there aren't many resources on the internet on how to do these things without using the old controller class.
By the way: Thank you all for developing this nice ember-addon.
Is it possible to access to the underlying map
object directly?
I'd like to be able to call a method like #getBoundsZoom()
directly from the controller, in order to compute the zoom
for the map. It doesn't work to put the call in an action triggered by onLoad
because zoom
will need to be resolved before the onLoad
event can be fired.
this stackoverflow shows how to auto-center a leaflet map based on the points being displayed.
https://stackoverflow.com/questions/10246157/leaflet-js-fit-geojson-co-ordinates-on-map-view
How do I do the same with ember-leaflet?
Thanks in advance!
If I want to render a map using a relationship for attributes (lat/lng/zoom) the component fails with assertion error: You must provide either valid bounds or a center (or lat/lng) and a zoom value.
Example:
Now I need to workaround with:
The model
is loaded via the route and model.coordinate
is loaded on-demand via ember-data (belongsTo
relationship).
Hey!
I am not able to use custom icons in marker-layer
due to a changed leaflet-api.
Demo-Code
{{#marker-layer location=marker.location icon=marker.icon}}marker.text{{/marker-layer}}
See this issues for more infos: Leaflet/Leaflet#534
It really does not matter what the contents of marker.icon
are, you'll always receive
TypeError: options.icon.createIcon is not a function. (In 'options.icon.createIcon(this._icon)', 'options.icon.createIcon' is undefined)
The auto-fetched version of leaflet during ember install was ~0.7.7
Any plans to add L.rectangle
?
Hello,
Is it possible to calculate the route distance between two places and display it ?
Thanks.
In some cases, we need to have a reference to the map to call some leaflet functions. Is there an easy way to access the map?
There are several use cases:
lat
and lng
params, we need to call map.fitBounds(...)
based on the current data.leaflet.draw
which requires a reference of the map
.zoom
class that we need to add to the map: CustomZoom(...).addTo(map)
.L.control.scale(...).addTo(map)
In my app, when the user clicks on a marker, a promise needs to be resolved before the popup content is rendered by Ember.
The problem is that the width seems to be computed only once (at the time the popup opens) and the popup ends-up being not wide enough for the content.
Any idea how to fix this ?
I could not find a way to add a control to the ember-leaflet map without writing my own ember component.
I guess a control-layer/layers.control component would be a nice addition the ember-leaflet.
Have you ever considered this?
It seems leaflet made a lot of progress since 0.7, but it is all 'hidden' in the master 1.0 branch. The release schedule of leaflet is far behind schedule and my guess is that 1.0 should be ok to go. What is your roadmap; do you want to wait for the stable 1.0, is there a place for a separate ember-leaflet-1-0 addon, or is this repo a place where dev on 1.0 could start?
About my use case; I have some failing maps on mainly mobile Android devices. AFAIK the internals of Leaflet 1.0 changed a lot, so my hope is it fixes some of the weird issues too.
From what I gather, this should be a supported way of implementing event handlers:
// app/components/custom-map.js
import LeafletMap from 'ember-leaflet/components/leaflet-map';
export default LeafletMap.extend({
wasDragged: false,
onDragstart() {
this.set('wasDragged', true);
}
});
When I do this and start dragging the map, I get a "this" is undefined
error. And indeed if I check in the debugger, this
has no value and there seems to be no way to reach the component instance from the event handler.
I tried setting some breakpoints within the _addEventListeners
code in base-layer
, but no matter where I checked, this
was correctly pointing to the component instance. I couldn't figure out how to proceed from there; it doesn't look like there are any tests in the project that cover this functionality.
i need help, after installing ember-leaflet and put the template like this bellow :
{{#leaflet-map lat=lat lng=lng zoom=zoom}}
{{tile-layer url="http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png"}}
{{/leaflet-map}}}
and put in some javascript
export default Ember.Controller.extend({
lat: 45.519743,
lng: -122.680522,
zoom: 10
});
after i run ember server, the web didnt show anything, even the error
im using :
version: 1.13.13
node: 5.1.0
npm: 2.14.10
os: darwin x64
thanks
some recent changes should be mentioned in the docs (dummy app), notably:
fitBoundsOptions
and zoomPanOptions
by @gandalfarpopupOptions
by @IAmJulianAcostaMost of the component pages are rendered dynamically, but each of them renders a component to show additional custom info, if the component exists.
The line responsible for that is: https://github.com/miguelcobain/ember-leaflet/blob/master/tests%2Fdummy%2Fapp%2Ftemplates%2Fdocs%2Fcomponent.hbs#L3-L5
It basically looks for a component named ${component-name}-example
and renders it if it exists.
There are already some existing examples: https://github.com/miguelcobain/ember-leaflet/tree/master/tests/dummy/app/templates/components
So, we need to write about these features using that approach on leaflet-map
and marker-layer
pages respectively.
What is the prescribed way for calling leaflet's methods like getBounds or getCenter? In a non-Ember environment I would have the map stored in a variable and call the methods that way, but I'm still a little confused on where the map object is stored when it's an Ember component.
Any thought of adding support for GeoJSON layers?
On mobile Chrome, it's very easy to send lots and lots of zoom events really fast by using the finger-pinching method. As a result, and after some Chrome remote debugging, I can make the app stop functioning after sending off too many network requests for the map tiles.
I was thinking about debouncing zoom requests to ember-leaflet
but not sure how to do that yet. Just wondering if you've got any leads I can try before going down the rabbit hole. Thanks!
Hi, I am trying to define individual css styles for the popups of different maker-cluster-layers by adding classs to them. However I am not sure how to properly use the className Option on {{#marker-layer}} and can't get it to work. Could you provide an example how to add classes to popups?
Hi,
I'm fairly new to ember & this library, I noticed on leaflet that there are certain conversion methods available for maps such as latLngToLayerPoint, are they included in this library & can they be accessed somehow?
Right now marker-icons can only contain interactive elements inside of popups. It would be nice to have a marker-container that wraps for example a custom marker-icon in form of a ember-component. This would allow for realtime-icon-state-changes in an ember-way (think of places with state that can change over time).
After digging into the code this seems not possible right now, or did I oversee something?
I'm trying to open a popup using popupOpen
, but is not working.
{{#marker-layer popupOpen=true}}
foo
{{/marker-layer}}
The following function never executes because this._map
is undefined
when executed.
openPopup: function () {
if (this._popup && this._map && !this._map.hasLayer(this._popup)) {
this._popup.setLatLng(this._latlng);
this._map.openPopup(this._popup);
}
return this;
},
It seems that openPopup
is executing before L.marker.onAdd
, maybe this.popupOpenDidChange
is executing too early (executed in didCreateLayer
)?
I'm giving this addon a try and adding a map was very easy to do. However, I'm pretty new to ember, and I was hoping someone could provide an example of the best way to add a control to a leaflet-map.
Thanks!
I just started a new project with ember 2.4 and ember-leaflet and I'm having problems getting the marker icons to work.
I created a new ember 2.4 project with just an example in it and it also doesn't work.
Test Project Ember 2.4 and ember-leaflet
ember -v
version: 2.4.0
node: 5.5.0
os: linux x64
The md5 hash of the icons are not the same which is also strange and maybe can help you find the problem.
87f6ca46ac356e81dc438589630ae107 bower_components/leaflet/dist/images/marker-icon.png
d95f8980883dd995b4a9595825bf8366 dist/assets/images/marker-icon.png
I have a number of markers with popups on a map, I want to open a specific popup programmatically from an action triggered outside the leaflet-map component in the same controller.
Is this possible? Does it require interacting with leaflet directly?
We can use {{component componentName
to render an example in each component page.
I was trying to bound map dimensions to window size using https://github.com/mike-north/ember-resize but apparently there is no way to bind styles attributes of the .leaflet-container directly. I know I could use jquery but I'd like to stay way from it if possible.
Do you have a solution in mind ?
AWESOME!
Well, done! It's really a pleasure to use!
From discussion on Slack, it would be useful if we could do this:
I found this bug when modifying marker-layer
icon on runtime.
When I modify the icon, the observer of setIcon
executes, and executes L.Marker.setIcon
, which executes this.bindPopup(this._popup)
, that will open use L.Popup.prototype.options.offset
, because options
aren't passed to bindPopup
.
Is the same bug that I fixed in #66, but elsewhere.
@miguelcobain I hear suggestions about how could I fix this. You know better ember-leaflet, but my first idea is executing again this._layer.bindPopup(this._popup, this.get('popupOptions'))
after the observer, but not sure about it.
Hi there,
Thanks for this amazing library. We've upated from version 1 (gabesmed) and we've taken advantage of the maker layer to create some beautiful popups for our marker layers.
I would like have one of these popups open by default when the map is created but I'm struggling to figure out how to do it.
Is there a way to do this?
Thanks!
@miguelcobain I've tried to put the basic map but the tiles loaded partially, this is my template:
{{#leaflet-map lat=model.location.lat lng=model.location.lng zoom=15 zoomControl=false attributionControl=false id="map-body"}}
{{tile-layer url=mapURL}}
{{#marker-layer lat=model.location.lat lng=model.location.lng}}{{/marker-layer}}
{{/leaflet-map}}
And this is the result:
Maybe you can give me some direction how to solve this problem, thanks in advance.
Have you considered adding support for L.featureGroup? It would help for hiding/showing larger numbers of features, and also calculating getBounds()
on multiple features.
example code:
component.hbs
{{#leaflet-map lat=lat lng=lng zoom=zoom}}
{{tile-layer url="http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png"}}
{{#marker-layer location=location}}
<p>name</p>
{{#paper-button action="handler"}}paper{{/paper-button}}
<button {{action "handler"}}>nonpaper</button>
{{/marker-layer}}
{{/leaflet-map}}
component.js
import Ember from 'ember';
export default Ember.Component.extend({
lat: 45.519743,
lng: -122.680522,
zoom: 10,
location: [45.528298, -122.662986],
actions: {
handler(){
debugger;
}
}
});
Works fine with non paper button but hits Uncaught TypeError: Illegal invocation
with ember-paper
error trace:
event.srcEvent.stopPropagation @ propagating.js:205
L.DomEvent.stopPropagation @ leaflet-src.js:6464
L.Draggable.L.Class.extend._onDown @ leaflet-src.js:6659
handler @ leaflet-src.js:6380
I am new to ember-leaflet and wondering how to implement drawing polygon, circle, polyline overlays (similar to Leaflet.draw) on maps.
When I followed the docs and installed ember-leaflet
, I got the error:
Could not find module
ember-invoke-action
imported fromember-leaflet/components/base-layer
The problem is that the dependency ember-invoke-action
doesn't get installed automatically. I'm not too familiar with Ember, but I think that should be done in the blueprint?
Hi,
Can I able to achieve the same via this addon? Please help.
this.L.locate({
setView: true,
drawCircle: true,
markerClass: L.circleMarker
}).addTo(lmap);
Thanks in advance.
Should this addon be responsible for excluding the images in /assets/images from being modifed by broccoli-asset-rev? I just ran into an issue with production builds where broccoli-asset-rev is adding fingerprints to the image file names, causing broken images in my maps.
Of course us developers can exclude them manually in our build file, but I thought maybe there was a way for this to be built into the addon to prevent the problem for all users.
When I pass in bounds to the leaflet-map component, it triggers the assert here
didCreateLayer() {
//after base layer bound the events, we can now set the map's view
assert('You must provide either valid bounds or a center (or lat/lng) and a zoom value.',
(this.get('bounds') && (!this.get('center') && this.get('zoom') === undefined)) ||
(!this.get('bounds') && (this.get('center') && this.get('zoom') !== undefined))
);
if (this.get('bounds')) {
this._layer.fitBounds(this.get('bounds'), {
reset: true
});
} else {
this._layer.setView(this.get('center'), this.get('zoom'), {
reset: true
});
}
}
If I remove the assert, everything works great. Also, this addon is amazing, thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.