Here is couple of lines on using Leaflet with ExtJS. The Leaflet widget I’ve been using is based on a GitHub project by kazmiekr (@see Leaflet UX). Many thanks to that !!!
Setup
The setup is VERY easy. The only requirements are to add in index.html all the leaflet common requirements.
https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.css
src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js
The Leaflet Map Widget
As I wrote it above, the code is widely based on kazmiekr work (@see Leaflet UX). Couple of improvements:
- Multiple tiles providers support,
- Use of OpenStreetMap instead of CloudMade as default map,
- initMap function, called at the end of “afterrender” listener.
Ext.define('Ext.ux.LeafletMapView', {
extend: 'Ext.Component'
,alias: 'widget.leafletmapview'
/* // Optional: add an additionnal controller
// with alias: controller.leaflet-map
,requires: [
'Ext.ux.LeafletMapController'
]
,controller: 'leaflet-map'
*/
,config:{
initialLocation: null,
initialZoomLevel: null,
map: null,
layerControl: null,
useCurrentLocation: false
// Description of tiles providers
,tiles: {
osm: {
title: 'OSM'
,url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
,maxZoom: 18
,attribution: "OpenStreetmap"
}
,mapbox : {
title: 'MapBox v4'
,url: 'http://{s}.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token={key}'
,maxZoom: 18
,key: "MAPBOX API KEY"
,attribution: '© GGL/OSM'
}
}
,defaultTile: 'osm' // default tile provider
,initMap: function(map) {} // called afterRender
}
// Will be called by afterrender => add tiles selector
,initTiles: function(map) {
var tiles = {}, list = this.getTiles();
for(var i in list) {
var t = list[i]
,tile = L.tileLayer(t.url, t);
tiles[t.title] = tile;
if (i == this.getDefaultTile()) // Add Default map..
tile.addTo(map);
}
// Add Map Control
var layerControl = L.control.layers(tiles, {});
layerControl.addTo(map);
this.layerControl = layerControl;
}
// afterrender is called the 1st time the widget is created
,afterRender: function(t, eOpts){
this.callParent(arguments);
var leafletRef = window.L;
if (leafletRef == null){
this.update("No leaflet library loaded");
} else {
var map = L.map(this.getId());
this.setMap(map);
this.initTiles(map);
var initialLocation = this.getInitialLocation();
var initialZoomLevel = this.getInitialZoomLevel();
if (initialLocation && initialZoomLevel){
map.setView(initialLocation, initialZoomLevel);
} else {
map.fitWorld();
}
if (this.getUseCurrentLocation() == true){
map.locate({
setView: true
});
}
if (Ext.isFunction(this.initMap)) {
this.initMap(Ext.isDefined(this.scope) ? this.scope : this, map);
}
}
}
/** Called on Element resize => invalidate map **/
,onResize: function(w, h, oW, oH){
this.callParent(arguments);
var map = this.getMap();
if (map) map.invalidateSize();
}
});
Example : a Desktop window (with a Tree Panel on left)
Ext.define('Desktop.map.GlobalMapWindow', {
extend: 'Ext.ux.desktop.Module',
requires: [
'Ext.panel.Panel'
,'Ext.ux.LeafletMapView'
,'Ext.tree.Panel'
]
,id: 'panel-map-global'
,title: "Window Title"
,iconCls: 'fa fa-globe' // font-awesome icon
,init : function(){
this.launcher = { // start menu shortcut
text: this.title
,iconCls: this.iconCls
}
}
,config : {
mapWidget: null
,treeWidget : null
}
/**
* Create the Window
* @returns {*}
*/
,createWindow : function(){
//GLC.Config.log.log(this.id, 'createWindow');
var me = this,
app = this.app
,desktop = app.getDesktop()
,win = desktop.getWindow( this.id );
if(!win || win.isDestroyed){
// reset internal object cache
this.mapWidget = null;
this.treeWidget = null;
// create window
win = desktop.createWindow({
id: this.id,
title: this.title,
width: 740,
height: 480,
iconCls: this.iconCls,
animCollapse: false,
border: false,
constrainHeader: true,
layout: {
type: 'border'
}
,items: [
{ // Left Tree Panel
xtype: 'treepanel'
,region: 'west'
,title: null
,itemId: 'treelayers'
,rootVisible: true
,split: true
,collapsible: true
,collapsed: false
,width: 200
//,fields: ['name', 'description']
///*
,columns: []
,listeners: { }
} // eo TreePanel
,{ // The Map
xtype: 'leafletmapview'
,region: 'center'
,flex:2
,useCurrentLocation: true
,itemId: 'map'
/* // in case I need an additionnal
//afterrender function
,initMap: me.initMap
,scope: me
*/
}
]
});
}
//console.log(win);
return win;
}
/**
* Get the Leaflet.Map component with LeafletMap Widget
* @returns Leaflet.Map
*/
,getMap: function() { // retrieve the map
if (!this.mapWidget) this.mapWidget = Ext.ComponentQuery.query("#" + this.id + " > #map")[0];
return this.mapWidget.getMap();
}
/**
* Get the PanelTree component
* @returns Ext.tree.Panel
*/
,getTreeWidget: function() {
if (!this.treeWidget) this.treeWidget = Ext.ComponentQuery.query("#" + this.id + " > #treelayers")[0];
return this.treeWidget;
}
}); // eo Desktop.map.GlobalMapWindow
You must be logged in to post a comment.