PDA

View Full Version : OpenLayers with ExtJS 4



lukerothgda
3 May 2011, 9:38 AM
Has anybody tried using OpenLayers in an ExtJS 4 page? I've used the GeoExt library for previous projects, but it will be a while before that gets ported to ExtJS4. I'm working on just creating a simple OpenLayers map wrapped in a panel, but I'm not having any luck getting the map to render. Has anybody else been working on this? If I make some progress, I'll post my results.
Thanks,
Luke

maoherran
3 May 2011, 9:12 PM
I Have the same problem, if I found some solution I post too... please letme know if you found first the solution

christophe.geiser
5 May 2011, 1:03 AM
Also very interested in this - though I don't have much time to investigate now...
I guess exporting GeoExt to ExtJs 4 will include a quite lot of work, but in the same time it should simplify substantial part of the source code (e.g. layer and treelayer sync would be provided natively by ExtJs 4).

Given the new and exciting capabilities of Ext.draw, what would be nice is a tighter integration of draw features. Here I am especially thinking of GeoExt Vector Layer (that I use quite a bit) that could extend ExtJs sprites. It would not be trivial, but I guess not too complicated (should include a projection capabilities from KML to the map canvas, listen to zoomend and moveend events).
A lot of fun ... That I will post once I have some working stuff
Cheers
C.

ivanthecrazy
26 May 2011, 2:28 AM
I have used ExtJS with OpenLayers, and it works.

Here is example:



Ext.define('OpenlayersPanel', {
extend: 'Ext.panel.Panel',

initComponent: function() {
this.callParent(arguments);
this.on('afterrender', this.afterRender, this);
},

afterRender: function() {
var wh = this.ownerCt.getSize();
Ext.applyIf(this, wh);
this.callParent(arguments);
/*
* Creating map with OSM Layer
*/
this.map = new OpenLayers.Map(this.body.dom.id);
this.layer = new OpenLayers.Layer.OSM('OSM Map');
this.layer.setIsBaseLayer(true);
this.map.addLayer(this.layer);
}
});

jtiai
3 Aug 2011, 1:32 PM
Above code doesn't work. I tried to figure out for a while what goes wrong and this is what happens:

initComponent registers afterrender event to afterRender method. Documentation states: "The afterrender event is fired after this Component has been rendered, been postprocesed by any afterRender method defined for the Component."

Next thing defined is afterRender method! So method will be called twice creating map twice. It seem to confure OL and if you put panel somewhere, like in window or other resizeable container you will experience all kind of nasty side-effects when panning map or zooming to area after resize.

To fix this code remove event registration from initComponent and everything works as fine.

Hope that this helps people that have been struggling with same problem.

vahid4134
3 Aug 2011, 8:38 PM
Im working to convert GeoExt from version 3 to version 4. But GeoExt developer dost answer to me for this work.
sorry for my bad english

mathias.lin
5 Aug 2011, 7:05 AM
I'm looking for the same, actually I want to use BingMaps in my ExtJS 4.0.2a based application. Above code sample does display a map, despite that I get tons of javascript errors in Firebug when loading the app. So it doesn't look very stable and trustworthy just yet.
I'm using the latest ExtGeo and OpenLayers lib as of today.

For example:
"Ext.reg is not a function" in MapPanel.js,
"centerPx is null" in OpenLayers.js
"members is undefined" in ext-all-debug.js
... amongst others.

May the new 'sandboxing' feature in ExtJs 4 is the way to go?

vahid4134
5 Aug 2011, 10:23 AM
In Extjs 4 calss system is change
.
this sample code for GeoExt.Map



/**
* Copyright (c) 2008-2010 The Open Source Geospatial Foundation
*
* Published under the BSD license.
* See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
* of the license.
*/

/**
* @include GeoExt/data/LayerStore.js
*/

/** api: (define)
* module = GeoExt
* class = MapPanel
* base_link = `Ext.Panel <http://dev.sencha.com/deploy/dev/docs/?class=Ext.Panel>`_
*/
//Ext 4 no neead namespace
//Ext.namespace("GeoExt");

/** api: example
* Sample code to create a panel with a new map:
*
* .. code-block:: javascript
*
* var mapPanel = new GeoExt.MapPanel({
* border: false,
* renderTo: "div-id",
* map: {
* maxExtent: new OpenLayers.Bounds(-90, -45, 90, 45)
* }
* });
*
* Sample code to create a map panel with a bottom toolbar in a Window:
*
* .. code-block:: javascript
*
* var win = new Ext.Window({
* title: "My Map",
* items: [{
* xtype: "gx_mappanel",
* bbar: new Ext.Toolbar()
* }]
* });
*/

/** api: constructor
* .. class:: MapPanel(config)
*
* Create a panel container for a map.
*/

Ext.define('GeoExt.panel.Map', {
extend: 'Ext.panel.Panel',

requires: [
// 'GeoExt.data.LayerStore'
],
alias: 'widget.gx_mappanel',
alternateClassName: 'GeoExt.MapPanel',

/** api: config[map]
* ``OpenLayers.Map or Object`` A configured map or a configuration object
* for the map constructor. A configured map will be available after
* construction through the :attr:`map` property.
*/

/** api: property[map]
* ``OpenLayers.Map`` or ``Object`` A map or map configuration.
*/
map: null,

/** api: config[layers]
* ``GeoExt.data.LayerStore or GeoExt.data.GroupingStore or Array(OpenLayers.Layer)``
* A store holding records. The layers provided here will be added to this
* MapPanel's map when it is rendered.
*/

/** api: property[layers]
* :class:`GeoExt.data.LayerStore` A store containing
* :class:`GeoExt.data.LayerRecord` objects.
*/
layers: null,


/** api: config[center]
* ``OpenLayers.LonLat or Array(Number)`` A location for the map center. If
* an array is provided, the first two items should represent x & y coordinates.
*/
center: null,

/** api: config[zoom]
* ``Number`` An initial zoom level for the map.
*/
zoom: null,

/** api: config[prettyStateKeys]
* ``Boolean`` Set this to true if you want pretty strings in the MapPanel's
* state keys. More specifically, layer.name instead of layer.id will be used
* in the state keys if this option is set to true. But in that case you have
* to make sure you don't have two layers with the same name. Defaults to
* false.
*/
prettyStateKeys: false,

/** api: config[extent]
* ``OpenLayers.Bounds or Array(Number)`` An initial extent for the map (used
* if center and zoom are not provided. If an array, the first four items
* should be minx, miny, maxx, maxy.
*/
extent: null,

/** private: property[stateEvents]
* ``Array(String)`` Array of state events
*/
stateEvents: ["aftermapmove",
"afterlayervisibilitychange",
"afterlayeropacitychange"],

/** private: method[initComponent]
* Initializes the map panel. Creates an OpenLayers map if
* none was provided in the config options passed to the
* constructor.
*/
initComponent: function(){
if(!(this.map instanceof OpenLayers.Map)) {
this.map = new OpenLayers.Map(
Ext.applyIf(this.map || {}, {allOverlays: true})
);
}
var layers = this.layers;
if(!layers || layers instanceof Array) {

this.layers = Ext.create('GeoExt.data.LayerStore',{
layers: layers,
map: this.map.layers.length > 0 ? this.map : null
});
}

if(typeof this.center == "string") {
this.center = OpenLayers.LonLat.fromString(this.center);
} else if(this.center instanceof Array) {
this.center = new OpenLayers.LonLat(this.center[0], this.center[1]);
}
if(typeof this.extent == "string") {
this.extent = OpenLayers.Bounds.fromString(this.extent);
} else if(this.extent instanceof Array) {
this.extent = OpenLayers.Bounds.fromArray(this.extent);
}

this.callParent();

this.addEvents(
/** private: event[aftermapmove]
* Fires after the map is moved.
*/
"aftermapmove",

/** private: event[afterlayervisibilitychange]
* Fires after a layer changed visibility.
*/
"afterlayervisibilitychange",

/** private: event[afterlayeropacitychange]
* Fires after a layer changed opacity.
*/
"afterlayeropacitychange"
);
this.map.events.on({
"moveend": this.onMoveend,
"changelayer": this.onLayerchange,
scope: this
});
},

/** private: method[onMoveend]
*
* The "moveend" listener.
*/
onMoveend: function() {
this.fireEvent("aftermapmove");
},

/** private: method[onLayerchange]
* :param e: ``Object``
*
* The "changelayer" listener.
*/
onLayerchange: function(e) {
if(e.property) {
if(e.property === "visibility") {
this.fireEvent("afterlayervisibilitychange");
} else if(e.property === "opacity") {
this.fireEvent("afterlayeropacitychange");
}
}
},

/** private: method[applyState]
* :param state: ``Object`` The state to apply.
*
* Apply the state provided as an argument.
*/
applyState: function(state) {

// if we get strings for state.x, state.y or state.zoom
// OpenLayers will take care of converting them to the
// appropriate types so we don't bother with that
this.center = new OpenLayers.LonLat(state.x, state.y);
this.zoom = state.zoom;

// set layer visibility and opacity
var i, l, layer, layerId, visibility, opacity;
var layers = this.map.layers;
for(i=0, l=layers.length; i<l; i++) {
layer = layers[i];
layerId = this.prettyStateKeys ? layer.name : layer.id;
visibility = state["visibility_" + layerId];
if(visibility !== undefined) {
// convert to boolean
visibility = (/^true$/i).test(visibility);
if(layer.isBaseLayer) {
if(visibility) {
this.map.setBaseLayer(layer);
}
} else {
layer.setVisibility(visibility);
}
}
opacity = state["opacity_" + layerId];
if(opacity !== undefined) {
layer.setOpacity(opacity);
}
}
},

/** private: method[getState]
* :return: ``Object`` The state.
*
* Returns the current state for the map panel.
*/
getState: function() {
var state;

// Ext delays the call to getState when a state event
// occurs, so the MapPanel may have been destroyed
// between the time the event occurred and the time
// getState is called
if(!this.map) {
return;
}

// record location and zoom level
var center = this.map.getCenter();
state = {
x: center.lon,
y: center.lat,
zoom: this.map.getZoom()
};

// record layer visibility and opacity
var i, l, layer, layerId, layers = this.map.layers;
for(i=0, l=layers.length; i<l; i++) {
layer = layers[i];
layerId = this.prettyStateKeys ? layer.name : layer.id;
state["visibility_" + layerId] = layer.getVisibility();
state["opacity_" + layerId] = layer.opacity == null ?
1 : layer.opacity;
}

return state;
},

/** private: method[updateMapSize]
* Tell the map that it needs to recalculate its size and position.
*/
updateMapSize: function() {
if(this.map) {
this.map.updateSize();
}
},

/** private: method[renderMap]
* Private method called after the panel has been rendered or after it
* has been laid out by its parent's layout.
*/
renderMap: function() {
var map = this.map;
map.render(this.body.dom);

this.layers.bind(map);

if(map.layers.length > 0) {
if(this.center || this.zoom != null) {
// both do not have to be defined
map.setCenter(this.center, this.zoom);
} else if(this.extent) {
map.zoomToExtent(this.extent);
} else {
map.zoomToMaxExtent();
}
}
},

/** private: method[afterRender]
* Private method called after the panel has been rendered.
*/
afterRender: function() {
this.callParent(arguments);
if(!this.ownerCt) {
this.renderMap();
} else {
this.ownerCt.on("move", this.updateMapSize, this);
this.ownerCt.on({
"afterlayout": {
fn: this.renderMap,
scope: this,
single: true
}
});
}
},

/** private: method[onResize]
* Private method called after the panel has been resized.
*/
onResize: function() {
this.callParent(arguments);
this.updateMapSize();
},

/** private: method[onBeforeAdd]
* Private method called before a component is added to the panel.
*/
onBeforeAdd: function(item) {
if(typeof item.addToMapPanel === "function") {
item.addToMapPanel(this);
}
this.callParent(arguments);
},

/** private: method[remove]
* Private method called when a component is removed from the panel.
*/
remove: function(item, autoDestroy) {
if(typeof item.removeFromMapPanel === "function") {
item.removeFromMapPanel(this);
}
this.callParent(arguments);
},

/** private: method[beforeDestroy]
* Private method called during the destroy sequence.
*/
beforeDestroy: function() {
if(this.ownerCt) {
this.ownerCt.un("move", this.updateMapSize, this);
}
if(this.map && this.map.events) {
this.map.events.un({
"moveend": this.onMoveend,
"changelayer": this.onLayerchange,
scope: this
});
}
// if the map panel was passed a map instance, this map instance
// is under the user's responsibility
if(!this.initialConfig.map ||
!(this.initialConfig.map instanceof OpenLayers.Map)) {
// we created the map, we destroy it
if(this.map && this.map.destroy) {
this.map.destroy();
}
}
delete this.map;
this.callParent(arguments);
}

});

/** api: function[guess]
* :return: ``GeoExt.MapPanel`` The first map panel found by the Ext
* component manager.
*
* Convenience function for guessing the map panel of an application. This
* can reliably be used for all applications that just have one map panel
* in the viewport.
*/
GeoExt.MapPanel.guess = function() {
return Ext.ComponentMgr.all.find(function(o) {
return o instanceof GeoExt.panel.Map;
});
};

slemmon
13 Aug 2011, 3:18 PM
I've got one working now in 4. Basically (and I'm summarizing a bit here) it's:


Ext.define('JSLibrary.panel.Olmap', {
extend: 'Ext.panel.Panel'
, alias: 'widget.jslolmappanel'


// private config options
, initComponent: function () {


this.layout = 'fit'


this.defMapControls = {
layerSwitcher: new OpenLayers.Control.LayerSwitcher()
, panZoomBar: new OpenLayers.Control.PanZoomBar()
, zoomBox: new OpenLayers.Control.ZoomBox()
}


this.mapControls = this.mapControls || {} // sets mapControls to what has been passed by the constructor or an empty object
this.mapControls = Ext.merge(this.defMapControls, this.mapControls)


this.defMapConfig = {
// taken from http://apds.qintra.com/apds/javascript/qvolite/qvolitemain.js
projection: new OpenLayers.Projection("EPSG:900913")
, units: 'm'
, numZoomLevels: 25
, maxResolution: 156543.0339
, maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508.34)
, fallThrough: true
//, allOverlays: true // THIS SEEMS TO BREAK THE BASE LAYERS SELECTOR
}


this.mapConfig = this.mapConfig || {}
this.mapConfig = Ext.merge(this.defMapConfig, this.mapConfig);


// initComponent must always end in this.callParent();
this.callParent(arguments);
}


, afterRender: function () {


OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
OpenLayers.Util.onImageLoadErrorColor = "transparent";


this.mapConfig.div = this.body.dom


this.map = new OpenLayers.Map(this.mapConfig)
this.map.removeControl(this.map.controls[1]);


this.mapMarkers = new OpenLayers.Layer.Markers("Markers", { displayInLayerSwitcher: false });


var gmap = new OpenLayers.Layer.Google(
"Google Streets"
, {
numZoomLevels: 20
}
);


var gsat = new OpenLayers.Layer.Google(
"Google Satellite"
, {
type: google.maps.MapTypeId.SATELLITE
, numZoomLevels: 22
}
);


var ghyb = new OpenLayers.Layer.Google(
"Google Hybrid"
, {
type: google.maps.MapTypeId.HYBRID
, numZoomLevels: 20
}
);


//this.map.addLayers([gmap, gsat, ghyb]);
this.addBaseLayers([gmap, gsat, ghyb])


this.centerLoc = this.centerLoc || this.getLonLatObject(-105.076532, 39.649783)
this.setCenter(this.centerLoc);
this.mapCenter;
this.setMapCenter();
// ..... etc.


Basically the OLMap wants to be rendered to a div and so after the panel is rendered you instantiate the map and tell it the div it wants to render to is the body of the owning panel. Then I started wrapping the OpenLayers' functions in my panel so when you see this.addBaseLayers that ends up being a wrapper function for the OpenLayers' function for adding a layer. But that way I can just execute adding layers, markers, etc by interfacing with my custom map panel component itself.

pef
30 Aug 2011, 9:19 AM
Hi Vahid !

I rather like the way you solved this problem : starting to port GeoExt to ExtJS 4...

Do you happen to have ported more of it ? Or did you just port MapPanel ?

In particular, I saw that MapPanel uses data/LayerStore... did you have to port this as well ? Or did you manage to do without it ?

slemmon
30 Aug 2011, 9:32 AM
I've not looked at GeoExt before. I've only used the panel.body.dom as the div to render an openLayers map to. Basically I looked at the Google maps example that's on the Sencha examples pages and just started stripping Google out of it and putting in OpenLayers map stuff in its place.

pef
30 Aug 2011, 9:37 AM
@slemmon : Yes, I noticed that in your own solution. Actually, my post was addressed to Vahid :)

I rather like his solution, since I'm also trying to make geoext work with extjs 4...

slemmon
30 Aug 2011, 9:40 AM
Gotcha. Best of luck.

vahid4134
1 Sep 2011, 9:54 PM
I convert 50% of GeoExt

DiscoBoy
16 Sep 2011, 2:33 AM
Hi pef!

Any progress on porting GeoExt 4?
I'm in the same need of a Mapping framework encapsulated in nice ExtJS classes....would be interested how you solved it in the meanwhile or what the current status of porting GeoExt is?

christophe.geiser
16 Sep 2011, 4:33 AM
Hi all

Just started to use polymaps (http://polymaps.org (http://polymaps.org/)) instead of geoExt/openLayers. Looks to work pretty well. It is small, fast, but not as comprehensive than openLayers and requires SVG browser support.
As a starter, see below

Cheers
C.



//====================
// Map
//====================
Ext.define('Ext.ux.maps.Map',
{extend : 'Ext.Component',
alias : 'widget.maps.map',
mapStyle : '2',
mapType : 'cloudMade',
buildUrl: {
cloudMade : function() {
return "http://{S}tile.cloudmade.com"
+ "/" + --put your cloudmade API key--
+ "/"+ (this.mapStyle ? this.mapStyle : '1') + "/256/{Z}/{X}/{Y}.png"
},
nasa: function(){
return "http://s3.amazonaws.com/com.modestmaps.bluemarble/{Z}-r{Y}-c{X}.jpg"
}
},
setBaseLayer: function(cfg) {
var me = this, po = org.polymaps, bL = me.baseLayer;
if(cfg) {Ext.apply(me, cfg)};
me.baseLayer= po.image()
.url(po.url(me.buildUrl[me.mapType].apply(me))
.hosts(["a.", "b.", "c.", ""]));
me.map.add(me.baseLayer);
if(bL) {me.map.remove(bL)}
},
onRender: function() {

var po = org.polymaps,
me = this;
me.callParent(arguments)
me.map = po.map()
.container(me.getEl().dom.appendChild(po.svg("svg")))
.add(po.interact());
//.add(po.hash());
me.setBaseLayer();
me.map.add(po.compass()
.pan("none"));

// resize the map when this component is resized
me.on('resize', me.map.resize, me.map)
}
});

win = Ext.widget('window',{title: 'map',height: 400,width: 400,layout: 'fit',items : [{ xtype: 'maps.map'}]}).show()

pef
18 Sep 2011, 10:09 PM
Hi pef!
Any progress on porting GeoExt 4?

Hi ! No, I haven't made any progress. Actually, I emailed vahid about that and he told me he had already converted 50% of it.

Unfortunately, he's currently very busy so we'll have to be patient. I haven't had a chance to look at his code yet.

In my case, this can wait since other parts of my application must first be implemented before the map can be of any use : in the mean time, I just display it using slemmon's solution.

vahid4134
19 Sep 2011, 8:04 AM
Hi pef
please email again to me

lukerothgda
3 Oct 2011, 1:19 PM
To everyone working on porting GeoExt to ExtJS 4 (Vahid, pef, ...) - would it you be interested in some assistance? I'm working on a site using ExtJS / OpenLayers and I have some time over the next few weeks to contribute, if you'd like to share your work in progress and some items that you'd like me to work on.
Luke

vahid4134
6 Oct 2011, 7:31 AM
I start github project

https://github.com/vahid-sohrabloo/GeoExt4

first example on extjs 4

http://vahid-sohrabloo.github.com/GeoExt4/examples/mappanel-div.html

I working for convert GeoExt to GeoExt4

everyone can help to me please join to me on gitbub

lukerothgda
6 Oct 2011, 7:39 AM
Cool, thanks! I'll go check it out. Do you mind if I mention this project to the GeoExt mailing list? We might get a few more volunteers.
Luke


I start github project

https://github.com/vahid-sohrabloo/GeoExt4

first example on extjs 4

http://vahid-sohrabloo.github.com/GeoExt4/examples/mappanel-div.html

I working for convert GeoExt to GeoExt4

everyone can help to me please join to me on gitbub

vahid4134
6 Oct 2011, 8:52 AM
Cool, thanks! I'll go check it out. Do you mind if I mention this project to the GeoExt mailing list? We might get a few more volunteers.
Luke

Ok
thx

xuejinruan
21 Oct 2011, 3:52 PM
Hi Slemmon,<br>
<br>
Thanks so much for the code example. I used Extjs4 mvc structure with Openlayers. And I defined my map panel following your example. However, my mappanel only displays part of the opanlayer map in firefox or chrome when the application first starts up. I need a zoom in or zoom out or whatever mouse click event on the map panel to get the whole map displayed. In IE, nothing was displayed except for Openlayers navigation bar when the application first starts, and again it needs an event on the map map panel to get the map displayed. What could I miss?

28794

Thanks so much,

Xuejin

vahid4134
21 Oct 2011, 9:47 PM
Please give me your code

DiscoBoy
23 Oct 2011, 10:37 PM
Having the same problems...
which dissapear if i resize my browser window and than expand it to desktop screen size again. This hapens for me also with the leaflet-Map Library.

xuejinruan
24 Oct 2011, 11:00 AM
Hi Vahid,

Thanks so much for the reply. My code examples are as follows (I could send you the zip file the whole project if you could give me your email). Currently I am not sure the problem is on OpenLayer side, or Extjs4 MVC side. I truly appreciate your time!

MapPanel.js:

//define the data boundary
var bounds = new OpenLayers.Bounds(1009428.376,409005.2844,1464539.488,864116.3956);
//define the restricted area, which we want to display
var extent = new OpenLayers.Bounds(1046000,506000,1428000,768000);

Ext.define('quickview.view.MapPanel' , {
extend: 'Ext.Panel',
alias : 'widget.mapPanel',
contentEl: 'mapDisplay',
id: 'mapPanel',
initComponent:function(){
this.layout = 'fit';

this.getMap = function() {
return this.map;
}


this.defMapConfig = {
id: 'quickViewMap',
// taken from http://apds.qintra.com/apds/javascript/qvolite/qvolitemain.js
projection: new OpenLayers.Projection("EPSG:2927"),
maxExtent : bounds,
restrictedExtent : extent,
resolutions : new Array(444.4444444, 222.2222222, 111.1111111,
55.55555556, 27.77777778, 13.88888889, 6.944444444,
3.472222222, 1.736111111, 0.868055556),
maxResolution : 444.4444444,
units: 'feet',
numZoomLevels: 10,
controls: [new OpenLayers.Control.Navigation(), new OpenLayers.Control.PanZoomBar()],
fallThrough: true
//, allOverlays: true // THIS SEEMS TO BREAK THE BASE LAYERS SELECTOR
};
this.mapConfig = this.mapConfig || {};
this.mapConfig = Ext.merge(this.defMapConfig, this.mapConfig);

// initComponent must always end in this.callParent();
this.callParent(arguments);
},
afterRender: function () {
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
OpenLayers.Util.onImageLoadErrorColor = "transparent";

this.map = new OpenLayers.Map(this.mapConfig);

this.mapMarkers = new OpenLayers.Layer.Markers("Markers", { displayInLayerSwitcher: false });

//Add WMS layer
zipcodelayer = new OpenLayers.Layer.WMS("ZipCode", "http://[servername]/geoserver/wms",
{
layers: "zip_codes",
format : "image/gif",
transparent : "true"
}, {
isBaseLayer : true,
visibility : true,
singleTile : true
});
this.map.addLayer(zipcodelayer);

//add some more control:
this.map.addControl(new OpenLayers.Control.LayerSwitcher());
this.map.addControl(new OpenLayers.Control.MousePosition());
this.map.addControl(new OpenLayers.Control.KeyboardDefaults());

this.map.render("mapDisplay");
this.map.zoomTo(5);
//this.map.zoomToExtent(extent);
}

});


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

And Viewport.js
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ext.define('quickview.view.Viewport', {
extend: 'Ext.container.Viewport',
requires: ['Ext.data.Store',
'Ext.data.StoreManager',
'Ext.data.HasManyAssociation',
'Ext.data.BelongsToAssociation',
'Ext.container.Viewport',
'Ext.grid.*',
'Ext.util.*',
'Ext.state.*',
'Ext.form.*',
'quickview.view.*',
'quickview.model.*',
'quickview.store.*',
'quickview.controller.*',
'*'],
id: 'viewport',
layout: {
type: 'border',
padding: 5
},
defaults: {
split: true
},
items: [
{
region: 'north',
contentEl:'north_banner',
id:'north',
collapsible: true,
closable:true,
title: 'Quick View',
split: true,
height: 100,
bodyStyle:'background-image: url(styles/images/testBanner.jpg); background-repeat: repeat; background-position: center;'
},
{
region: 'west',
contentEl:'west_display',
id:'west',
collapsible: true,
title: 'Parcel Search',
width: 400,
layout: {
type: 'vbox',
align : 'stretch',
pack : 'start'
},
items:[
{
xtype:'panel',
html: 'Search Form',
height: 100,
contentEl:'parcelSearch'
},
{

xtype:'panel',
flex: 1,
contentEl: 'parcelDisplay',
layout:'accordion',
id:'parcelDisplayAccordion',
collapsible: false,
autoScroll:true,
containerScroll : true,
layoutConfig: {
// layout-specific configs go here
titleCollapse:true,
animate: true,
activeOnTop:false
},
items:[
{
xtype: 'panel',
title: 'Selected Parcels',
html: 'Parcel Selected List',
contentEl: 'parcelSelected'
},
{
xtype: 'panel',
title: 'Parcel Quick View Info',
html: 'Parcel Quick Detailed Info',
contentEl: 'parcelDetailedInfo'
},
{
xtype: 'panel',
collapsed: false, //the Accordion souce code is looking for collapse === false, not looking for collapse == true
contentEl: 'layerList'
},
{
xtype: 'panel',
contentEl: 'openAt'
}
]
}
]
},
{
region: 'center',
contentEl:'center_mapdisplay',
id: 'center',
layout: 'border',
border: false,
items: [
{
region: 'center',
contentEl:'mapDisplay',
id: 'centerMap',
collapsible: false,
xtype: 'mapPanel'
},
{
region: 'south',
height: 80,
autoScroll:true,
collapsed:false,
contentEl:'disclaimer',
id: 'disclaimer',
collapsible: true,
title:'Disclaimer',
html: 'Disclaimer goes here'
}
]
}
]
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

And app.js
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ext.Loader.setConfig({
enabled: true
});
Ext.require(['Ext.data.Store',
'Ext.data.StoreManager',
'Ext.data.HasManyAssociation',
'Ext.data.BelongsToAssociation',
'Ext.container.Viewport',
'Ext.grid.*',
'Ext.util.*',
'Ext.state.*',
'Ext.form.*',
'*']);

Ext.create('Ext.app.Application', {
name: 'quickview',
autoCreateViewport: true,
appFolder: 'app',
models: [],
stores:[],
views:['MapPanel', 'Viewport'],
controllers: ['QuickViewController', 'MapPanelController'],
launch: function() {
window.console && console.log("In app.js, " + this.controllers);
}
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

And index.html
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<html>
<head>
<title>Quick View</title>

<!-- ExtJS css -->
<link rel="stylesheet" type="text/css" href="extjs4/resources/css/ext-all.css" />

<link rel="stylesheet" type="text/css" href="styles/quickview.css" />

<!-- ExtJS js -->
<script type='text/javascript' src="extjs4/ext-all-debug.js"></script>

<!-- OpenLayers js -->
<script type='text/javascript' src="OpenLayers-2.10/OpenLayers.js"></script>
<!-- App js -->
<script type='text/javascript' src="app.js"></script>


</head>
<body>
<div id="north_banner">
</div>
<div id="west_display" class="x-hide-display" style="background-color:F9F9F9">
<div id="parcelSearch" class="x-hide-display"></div>
<div id="parcelDisplay" class="x-hide-display">
<div id="parcelSelected" class="x-hide-display"></div>
<div id="parcelDetailedInfo" class="x-hide-display"></div>
<div id="layerList" class="x-hide-display"></div>
<div id="openAt" class="x-hide-display"></div>
</div>
</div>
<div id="center_mapdisplay" class="x-hide-display">
<div id="mapDisplay" class="x-hide-display">
<div id="toolBar" class="x-hide-display"></div>
</div>
<div id="disclaimer" class="x-hide-display"></div>
</div>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




Please give me your code

vahid4134
14 Jan 2012, 3:19 AM
I start again GeoExt4
https://github.com/vahid-sohrabloo/GeoExt4

marcoG
15 Feb 2012, 8:49 AM
Hello everybody, I think I'm a little late ... but here is my humble contribution.Here (http://benevolentcode.net/blog/blog1.php/extjs-4-and-openlayers) you can find a small example, showing how to render OpenLayers map inside an ExtJS4 Panel.31732 (http://benevolentcode.net/blog/blog1.php/extjs-4-and-openlayers)Hope this helps.

the_skua
15 Feb 2012, 11:17 AM
Has anybody made an progress on handling OpenLayers events through the new MVC architecture?

vondervick
9 Aug 2012, 6:18 AM
http://github.com/geoext/geoext2

Matt Bittner
24 Jan 2013, 8:51 AM
Hello everybody, I think I'm a little late ... but here is my humble contribution.Here (http://benevolentcode.net/blog/blog1.php/extjs-4-and-openlayers) you can find a small example, showing how to render OpenLayers map inside an ExtJS4 Panel.31732 (http://benevolentcode.net/blog/blog1.php/extjs-4-and-openlayers)Hope this helps.

marcoG, do you have this code anywhere else? I can't get into the link you've provided. Thanks.

marcoG
31 Jan 2013, 5:40 AM
Sorry Matt,

I had to take my site offline due to some sort of attack.

Anyway you can find the code without my almost useless blether right here (http://www.benevolentcode.net/lab/olPanel/index.html).

marco

Espin
16 Oct 2013, 3:16 AM
Hi Ayari, your code works.
You only must define width and height of your "map" div. Try:
<div id="map" style="width:100%; height:100%;"><div>

If you achieve a layer tree panel, legen panel, get info feature pop up tool or a pint tool, please show me how.
I tried to use OL with Extjs4 but i dont know how mix both correctly.