PDA

View Full Version : Ext.ux.GMapPanel - Google Maps



Pages : [1] 2

VinylFox
6 Jul 2008, 4:41 PM
ExtJS Google Maps Panel Updated With Locale Support and More... (http://www.vinylfox.com/gmappanel-updated-with-locale-support-and-more-examples/)

This is an extension that adds Google Map functionality to any panel, or panel type of component. It has been tested with both 2.x and 3.x branches and appears to work fine in both.

There are separate versions that work with the Google Maps 2.x API and the 3.x API.

Features:

Render google map to a panels body
Add map controls
Set map center
Add markers
Geocode center location or markers
Localization for error messages
Use any Google map type, Moon, Sky, etc.


Working on:

Add map controls via config (no instantiated) - added July 31
Add multiple map controls - added July 31
Add listeners for marker interaction - added July 31
Add gmap config options - added July 31
Document code - added August 20th
Load KML file - added November 22nd
Document code better - added January 27th
Mars, Moon and Sky map support - added sky on March 19th (working on others still)
Add more examples - added tab example on March 19th (will add more as needed), added more on April 26th


Bugs:

setCenter killing controls when lat/lng used for center point instead of geocode - fixed August 20th
Too many to remember - fixed January 27th
setCenter kills the map when using lat/lng - unable to locate problem as of yet


*

The UX and Example code can be found on Github
https://github.com/VinylFox/ExtJS.ux.GMapPanel/

*

Please feel free to make modifications or additions and post them back to this thread - I will integrate them with the extension.

Blog Post:http://extjs.com/blog/2008/07/01/integrating-google-maps-api-with-extjs/

Live Example:http://www.extjs.com/playpen/gmaps/ux.gmaps.php (uses out-dated component code)

willgillen
6 Jul 2008, 6:50 PM
Can you please outline the Licensing?

NeonMonk
6 Jul 2008, 9:06 PM
Very cool!

JorisA
7 Jul 2008, 2:56 AM
Awesome, I created something similar a while ago with the ability to automaticly add markers from a datastore, but I din't really finish it.

EzBulka
7 Jul 2008, 9:11 AM
This might be old news but it's the first time I've discovered it. Apparently, if you copy the code in IE and paste it into your IDE, it pastes it as one line! Yikes. It works fine in the superior Firefox browser - at least 3.0 does. So in the future, could you post a link to the JS file to make it easier for use in IE? Thanks.

LouiSe
23 Jul 2008, 1:46 AM
Hi VinylFox,

This is an excellent extension! But i've a - maybe stupid - question, how can i POST selected Google Maps position (LAT, LANG) by SUBMIT with FormPanel?

VinylFox
23 Jul 2008, 9:11 AM
Hi VinylFox,

This is an excellent extension! But i've a - maybe stupid - question, how can i POST selected Google Maps position (LAT, LANG) by SUBMIT with FormPanel?

Not a stupid question at all...what you will need is the center point from the maps handlers that Google provides. You can get a reference to the Google map by using getMap()

For example:

Ext.getCmp('yourmapid').getMap().getCenterPoint();

That would return a GMaps GLatLng object (http://code.google.com/apis/maps/documentation/reference.html#GLatLng) which could be used to retrieve lat/long info.

ie:

var cur_glatlng = Ext.getCmp('yourmapid').getMap().getCenterPoint();
var cur_lat = cur_glatlng.lat();
var cur_lng = cur_glatlng.lng();

Hope that helps.

runnersixty
25 Jul 2008, 9:43 AM
thanks for the work.
I use this for map options:

just after this line

this.gmap = new GMap2(this.body.dom);



if(Ext.isArray(this.mapConfOpts)){
for(I=0;I<this.mapConfOpts.length;I++){
try{
eval('this.gmap.'+this.mapConfOpts[I]+'();');
}
catch(e){
alert(this.mapConfOpts[I]+' is not a map configuration method');
}
}
}

using this way:


addControl: new GSmallMapControl(),
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
.....


for sure not the best and clean way, but it works.

Davide.

LouiSe
28 Jul 2008, 12:44 AM
Thanks, this is helpful for me!

EzBulka
29 Jul 2008, 11:03 AM
Perhaps this problem exists outside of the GMapPanel as well. But if you move the Panel outside the bounds of the browser, there might be no way to get it back. If you try to grab the panel, of course, you will simply grab the map. I put this in to prevent that:

listeners:{
'move':{
fn:function(){
if (this.y < 0) this.setPosition(this.x,0);
}
}
}

sean
31 Jul 2008, 5:28 AM
Shea,

This is a nice start. I used it as an aide to learn the google api internals. Whipped this up in a few hours time:

http://mcdconsultingllc.com/demos/google/GoogleMaps.html

I added a couple of things that I needed, including the ability to pass in an string or array of strings to specify the various supported features like the google bar and continuous zoom . There is also a method to enable/disable a feature on the fly. I also added a mapTypes config option, something that can only be specified during the construction of the GMap2 instance, so that views beyond G_DEFAULT_MAP_TYPES can be supported, eg



mapTypes: G_DEFAULT_MAP_TYPES.concat(G_PHYSICAL_MAP),

Finally I added a control config option that specifies the controls to be rendered on the Map by default, eg



controls: [
new GLargeMapControl(),
new GScaleControl()
] ,

I added methods to add/remove controls on the fly also.

I'm thinking that I would also like to add the ability to relay all the GMap2 events. The api is pretty extensive so covering everything could prove to be laborious with the benefit of abstracting away most of the google API from users of the panel. Things start to get a little tricker when you cover markers, info windows, custom icons, etc. In any case just thought I would share.

btw: I think the Gmap2 is consuming the click events. I have a (non functional) toolbar in my prototype with a menu. The menu doesn't hide when I click on the Panel. Need to look into this.

Sean

VinylFox
31 Jul 2008, 5:56 AM
The 1st post has been updated with the improvements suggested by runnersixty and sean.

JorisA
31 Jul 2008, 10:36 PM
Wouldn't it be better to use the google.maps namespace instead of all the global vars? For example var point = new google.maps.LatLng(lat, lon); instead of new GLatLng().
Thats more est-ish as well.

mask_hot
1 Aug 2008, 12:57 AM
Hi, really nice ux!

should it be possible to add a JSON store feature to add markers from a DB?

EachOnSet
19 Aug 2008, 10:09 PM
Hello!

I've got a problem when using Lat, Lng instead of an addresse in the setCenter. The map is loosing its controls. It also has been reported here : http://extjs.com/forum/showthread.php?p=206565

Here's a snippet of the items :


{
xtype: 'gmappanel',
region: 'center',
zoomLevel: 17,
gmapType: 'map',
setCenter: {
lat: 46.779388,
lng: -71.269909
},
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
markers: [{
lat: 42.339641,
lng: -71.094224,
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
}


Any ideas? Thank you!

VinylFox
20 Aug 2008, 4:31 AM
The 1st post has been updated with a fix to the bug found by EachOnSet.

Basic documentation was also added to the code (in JSDoc format).

@EachOnSet - please update this post with any other bugs you find - thanks.

tobiu
21 Aug 2008, 10:59 AM
i really like this ux, good job!

first of all, a small feature suggestion: i tried a window with the config-option maximable:true. On scaling fullscreen, the map did not resize properly, i guess it is not implemented yet, is it?

the major point is: i would like to add routes. on code.google.com, i found an example like:



var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
var polyline = new GPolyline([
new GLatLng(37.4419, -122.1419),
new GLatLng(37.4519, -122.1519)
], "#ff0000", 10);
map.addOverlay(polyline);




is this already possible with the ux (and if how?) or shall i try to add / extend this by myself?


thanks, tobiu

ScarFreewill
22 Aug 2008, 3:55 AM
Thanks for the nice ux!

My site is in an internal network some users have internet some don't. I wrote a message box that asks the user when they open the GMap to ask them if they want to active it.



loadMaps : function(){
if(gmScriptActive) {
this.createWindow();
} else {
Ext.Msg.confirm('Enable?', 'Do you want to enable Google Maps?', function(btn){
if (btn == 'yes'){
gmScriptActive = true;
document.getElementById(\"load-google-maps-here\").innerHTML = '<script src=\"http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=MYKEY\" type=\"text/javascript\"></script>';
this.createWindow();
}
})
}
}


If it is possable I'd like the load the script at that point, like you can se I'm using dom to print the js, but it doesn't load. Can I use a command within my js to exec an external script?

ps sorry for being off-topic

Thanks

lokiofragnar
18 Sep 2008, 1:35 AM
Hi VinylFox,

I have been working with the GMapPanel for a few weeks now and I have a few points to make. Some bigger than others. Perhaps I misunderstand stuff please do flame :-).

Here is the GMapPanel.js



/*
* Ext JS Library 2.2
* Copyright(c) 2006-2008, Ext JS, LLC.
* licensing@extjs.com
*
* http://extjs.com/license
*/

/**
* @author Shea Frederick
*/



Ext.namespace('Ext.ux');

/**
*
* @class GMapPanel
* @extends Ext.Panel
*/
Ext.ux.GMapPanel = Ext.extend(Ext.Panel, {
initComponent : function(){

var defConfig = {
plain: true,
zoomLevel: 3,
yaw: 180,
pitch: 0,
zoom: 0,
gmapType: 'map',
border: false
};

Ext.applyIf(this,defConfig);

Ext.ux.GMapPanel.superclass.initComponent.call(this);

},
afterRender : function(){

var wh = this.ownerCt.getSize();
Ext.applyIf(this, wh);

Ext.ux.GMapPanel.superclass.afterRender.call(this);

if (this.gmapType === 'map'){
this.gmap = new GMap2(this.body.dom);
}

if (this.gmapType === 'panorama'){
this.gmap = new GStreetviewPanorama(this.body.dom);
}

if (typeof this.addControl == 'object' && this.gmapType === 'map') {
this.gmap.addControl(this.addControl);
}

if (typeof this.center === 'object') {
if (typeof this.center.geoCodeAddr === 'string'){
this.geoCodeLookup(this.center.geoCodeAddr);
}else{
if (this.gmapType === 'map'){
var point = new GLatLng(this.center.lat,this.center.lng);
this.gmap.setCenter(point, this.zoomLevel);
}
if (typeof this.center.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.center.marker,this.center.marker.clear);
}
}
if (this.gmapType === 'panorama'){
this.gmap.setLocationAndPOV(new GLatLng(this.center.lat,this.center.lng), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom});
}
}

GEvent.bind(this.gmap, 'load', this, function(){
this.onMapReady();
});

},

onMapReady : function(){
this.addMarkers(this.markers);
this.addMapControls();
this.addOptions();
},

repaint: function(zoomlevel){
this.gmap.clearOverlays();
if(zoomlevel){
this.zoomLevel = zoomlevel;
this.gmap.setZoom(zoomlevel);
}
this.onMapReady();
this.toCenter();
},

onResize : function(w, h){

if (typeof this.getMap() == 'object') {
this.gmap.checkResize();
}

Ext.ux.GMapPanel.superclass.onResize.call(this, w, h);

},
setSize : function(width, height, animate){

if (typeof this.getMap() == 'object') {
this.gmap.checkResize();
}

Ext.ux.GMapPanel.superclass.setSize.call(this, width, height, animate);

},
getMap : function(){

return this.gmap;

},
getCenter : function(){

return this.getMap().getCenter();

},

setCenter: function(center, zoomLevel){
if(zoomLevel){
this.zoomLevel = zoomLevel;
}
this.center = center;
this.repaint();
},

toCenter: function(){
if (typeof this.center === 'object') {
if (typeof this.center.geoCodeAddr === 'string'){
this.geoCodeLookup(this.center.geoCodeAddr);
}else{
if (this.gmapType === 'map'){
var point = new GLatLng(this.center.lat,this.center.lng);
this.gmap.setCenter(point, this.zoomLevel);
}
if (typeof this.center.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.center.marker,this.center.marker.clear);
}
}
if (this.gmapType === 'panorama'){
this.gmap.setLocationAndPOV(new GLatLng(this.center.lat,this.center.lng), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom});
}
}
},

getCenterLatLng : function(){

var ll = this.getCenter();
return {lat: ll.lat(), lng: ll.lng()};

},
addMarkers : function(markers) {

if (Ext.isArray(markers)){
for (var i = 0; i < markers.length; i++) {
var mkr_point = new GLatLng(markers[i].lat,markers[i].lng);
this.addMarker(
mkr_point,
markers[i].marker,
false,
markers[i].setCenter,
markers[i].listeners,
markers[i].options
);
}
}

},

setMarkers : function(markers, zoomlevel) {
if(zoomlevel){
this.zoomLevel = zoomlevel;
}
this.markers = markers;
this.repaint();
},

addMarker : function(point, marker, clear, center, listeners, options){

Ext.applyIf(marker,G_DEFAULT_ICON);

if (clear === true){
this.getMap().clearOverlays();
}
if (center === true) {
this.getMap().setCenter(point, this.zoomLevel);
}


var mark = new GMarker(point, marker);

if (typeof listeners === 'object'){
for (evt in listeners) {
// changed the event that should fire from
// this to mark. So that the mark can be configured
// to handle the request.
GEvent.bind(mark, evt, mark, listeners[evt]);
}
}

if(options){
mark.options = options;
}

this.getMap().addOverlay(mark);

},
addMapControls : function(){

if (this.gmapType === 'map') {
if (Ext.isArray(this.mapControls)) {
for(i=0;i<this.mapControls.length;i++){
this.addMapControl(this.mapControls[i]);
}
}else if(typeof this.mapControls === 'string'){
this.addMapControl(this.mapControls);
}else if(typeof this.mapControls === 'object'){
this.getMap().addControl(this.mapControls);
}
}

},
addMapControl : function(mc){

var mcf = window[mc];
if (typeof mcf === 'function') {
this.getMap().addControl(new mcf());
}

},
addOptions : function(){

if (Ext.isArray(this.mapConfOpts)) {
var mc;
for(i=0;i<this.mapConfOpts.length;i++){
this.addOption(this.mapConfOpts[i]);
}
}else if(typeof this.mapConfOpts === 'string'){
this.addOption(this.mapConfOpts);
}

},
addOption : function(mc){

var mcf = this.getMap()[mc];
if (typeof mcf === 'function') {
this.getMap()[mc]();
}

},
geoCodeLookup : function(addr) {
this.geocoder = new GClientGeocoder();
this.geocoder.getLocations(addr, this.addAddressToMap.createDelegate(this));

},
addAddressToMap : function(response) {

if (!response || response.Status.code != 200) {
Ext.MessageBox.alert('Error', 'Code '+response.Status.code+' Error Returned');
}else{
place = response.Placemark[0];
addressinfo = place.AddressDetails;
accuracy = addressinfo.Accuracy;
if (accuracy === 0) {
Ext.MessageBox.alert('Unable to Locate Address', 'Unable to Locate the Address you provided');
}else{
point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
if (typeof this.center.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.center.marker,this.center.marker.clear,true, this.center.listeners);
}
}
}

}

});

Ext.reg('gmappanel',Ext.ux.GMapPanel);
1. The setCenter property is now center
Not a big deal but I needed a way to adjust the center of the map. The only way I could figure was to change the property setCenter in to center and create a setCenter method.


2. repainting
The current panel more or less assumes that all content is static. The problem I am working on needed the ability to change the content. So I created a repaint method. Also I created a setMarkers method that takes an array with marker information, throws out the old markers and paints the new ones.

3. Marker events
The marker event handling was all done by the panel. This did not suit my application. It also seems to go a bit a against the object concepts. So I changed the way events are added to Markers making the GMarker the element that receives the event. But this created an extra problem. When I handle the event I need more information than what is currently stored in the GMarker. I added an (optional) options object to the marker array. These options are put in the GMarker and can be used by the eventhandlers to call other actions.

4. Level of detail for resolution of addresses.
The check on the level of detail for an address is removed. (not a huge deal, but I used Dutch zipcodes and they kept giving problems).

These changes have made it possible to use an XMLReader to get marker info from my own application server and show it on the GMapPanel. I can also change the center without experiencing problems.

Here is my wishlist (I am going to see what I can do about it).

- I would like to use the GMapPanel without having to worry about the internal workings of the Map. Much like i use a GridPanel. In order to do this i would like to 'broadcast' the map events from the underlying googlemap. This should not be extremely difficult.

- I would like to create a Ext.ux.GoogleMarker that holds all the application info for a marker on a GoogleMap. This way I can introduce events and event handling that goes beyond the 'GMapPanel' made markers, without having to change the GMapPanel code. (see my previous point on the event handling and the options' This would not have to be very diificult either. I will see what I can do about this in the next weeks.

That's about it for now. As a said I may be wrong on a lot of this stuff and I may have gone about a lot of things the wrong way. So feel free to correct.

cheers,
Aad

JoyfulBobHome
23 Sep 2008, 8:53 PM
Great extension!

I've got a working page, but when I add markers I only have the street address from our database, and I'm having trouble converting it to lat/lng for the addMarker function.

I've tried using getLatLng but am running into problems. I've tried about 5 different solutions to no avail. The Google maps API doc page's examples don't match the way ExtJS's is structured.

Thanks in advance! Our users will LOVE this app!

lokiofragnar
23 Sep 2008, 10:23 PM
Hi JFB,

If you take look at the following method from the GMapPanel you can see how the Google Map API and the GMapPanel interact:



geoCodeLookup : function(addr) {
this.geocoder = new GClientGeocoder();
this.geocoder.getLocations(addr, this.addAddressToMap.createDelegate(this));
}The Geocoder is created to map an addres. However, you will have to create your own instance since this method calls the this.addAddressToMap method which assumes that you are setting the center of the map.

In the response object that is returned from Google you can request the response code. The detailed response codes can be found here. http://code.google.com/apis/maps/documentation/services.html#Geocoding_Object The problems you have can stem from all kinds of sources the most common is either a detail level that is too low or an address that is misspelled. Hard to say without your code or some example of an address that causes problems :-?.

In the panel the markers that you add are 'processed' in the addmarker method of the Panel. This is the part I like least of the Panel since it makes it impossible to create the markers outside the panel and stay 'connected' with them once displayed. However from the code you can deduct that the Objects in the array need to have the following properties: lat, lng, marker, setCenter (is this marker the center of the map), listeners. Ignore the options object below since this was added by yours truly and this won't necessarily be added to the overall approach :D it only serves a purpose if you also change the way listeners are connected to the markers.



if (Ext.isArray(markers)){
for (var i = 0; i < markers.length; i++) {
var mkr_point = new GLatLng(markers[i].lat,markers[i].lng);
this.addMarker(
mkr_point,
markers[i].marker,
false,
markers[i].setCenter,
markers[i].listeners,
markers[i].options
);
}
}
So to come back to the original point. Without some examples of addresses it is hard to answer your question.

cheers,
Aad

Joyfulbob
25 Sep 2008, 4:31 AM
Thanks for your reply! I understand that code; however, my markes are coming from a database that contains street addresses; not latitudes/longitudes. I'm confused over this - because the center point is an address yet the markers are lat/lng? Isn't that inconsistent? What database stores lat/lng? Why wouldn't the markers be street addresses instead of lat/lng? :-/

Anyway, I understand this function; but I've don't have lat/lng to pass in to addMaker. Here's what I've got:

My panel code (lat, lng are placemarkers to hold the js values):

markers: [{
streetAddr: '9818 W HOWARD AVENUE, MILWAUKEE, WI 53228, USA',
lat: 0,
lng: 0,
title: 'Installer B',
mrkListeners: {
click: function(e){
Ext.Msg.alert('Installer B');
}
}
}


my .js:


addMarkers: function(markers) {

if (Ext.isArray(markers)){
for (var i = 0; i < markers.length; i++) {
// Convert to Lat Lng
// These 4 fields are global vars to hold marker data from the page
markerMarkers = this.markers[i];
markerStreetAddr = this.markers[i].streetAddr;
markerTag = this.markers[i].title;
markerListeners = this.markers[i].mrkListeners;

// Call a new FNC that gets lat/lng
this.geoCodeLookupLL(this.markers[i].streetAddr);
}
}

}
...
// BK..Convert street address to Lat/Long
geoCodeLookupLL: function(addr) {

this.geocoder = new GClientGeocoder();
this.markerStreetAddr = addr;
console.info( ' markerStreetAddr: ' + this.markerStreetAddr );
this.geocoder.getLatLng(addr,

function(point) {

if (!point) {
Ext.MessageBox.alert('Invalid marker', 'Unable to Locate the Address you provided');
console.info('Invalid addr: ' + addr + ' Point: ' + point );
}else{
// var markerLL = this.getMarkerLatLng();
// var mkr_point = new GLatLng(markerLL.lat,markerLL.lng);
console.info('markerTag: ' + markerTag + ' Point: ' + point + ' : ' + markerMarkers );
// var mkr_point = new GLatLng(markerMarkers.lat, markerMarkers.lng);
this.addMarker( point, markerTag, false, this.setCenter, markerListeners );
// this.addMarker( point, this.markers[i].title, false, this.markers[i].setCenter, this.markers[i].mrkListeners ); // this line throws the error
}
}
);

},


Function geoCodeLookupLL is where the problem is. I call getLatLng and it returns the point just fine, but then addMarker errors with ' not a function'. I know it's a socpe issue but can't firgure it out. addAddressToMap works fine when referring to this.setCenter.marker but my addMarker doesn't?

Error:


this.addMarker is not a function
(no name)((42.966158, -88.029658) xr=42.966158 Nb=-88.029658 x=-88.029658 y=42.966158)Ext.ux.GMapPanelL... (line 248)
jq(Object)main.js (line 1433)
iq(Object)main.js (line 1420)
Cl(Object)main.js (line 890)
[Break on this error] this.addMarker( point, markerTag, false, this.setCenter, markerListeners )...

Thanks in advance!

Animal
25 Sep 2008, 4:35 AM
Well, you sloped off yesterday implying that you'd understood what I had carefully explained.

But you didn't listen.

The "this" reference for that callback function needs to be defined.

Either that, or capture it into a variable which has the same scope as that function, and use that variable.

Joyfulbob
25 Sep 2008, 5:00 AM
Thanks, Animal. I did listen - for two hours at home last night! I just don't fully understand yet. ;) I'm having trouble translating your principle/rule into the actual code as I learn this concept.

By this
The "this" reference for that callback function needs to be defined. are you saying that I have to define this.addMarker? Why? Isn't it already defined? addAddressToMarker calls it just fine - how is my call different? The only difference I can see is that I'm calling it from a nested fnc in geoCodeLookupLL.

How do I define it? I had tried a new fnc but it didn't work:


addMarkerToMap: function(point) {

if (!point) {
Ext.MessageBox.alert('Invalid marker', 'Unable to Locate the Address you provided');
console.info('Invalid addr: ' + markerStreetAddr + ' Point: ' + point );
}else{
// var markerLL = this.getMarkerLatLng();
// var mkr_point = new GLatLng(markerLL.lat,markerLL.lng);
console.info('addr: ' + markerStreetAddr + ' Point: ' + point );
var mkr_point = new GLatLng(markerMarkers.lat, markerMarkers.lng);
this.addMarker( mkr_point, markerTag, false, markerMarkers.setCenter, markerListeners );
// this.addMarker( point, this.markers[i].title, false, this.markers[i].setCenter, this.markers[i].mrkListeners );
}
} // eo addMarkerToMap

I also tried:


Either that, or capture it into a variable which has the same scope as that function, and use that variable.

via:...


afterRender: function(){


var markerMarkers;
var markerStreetAddr;
var markerTag;
var markerListeners;
...
addMarkers: function(markers) {

if (Ext.isArray(markers)){
for (var i = 0; i < markers.length; i++) {
// BK..convert to Lat Lng
markerMarkers = this.markers[i];
markerStreetAddr = this.markers[i].streetAddr;
markerTag = this.markers[i].title;
markerListeners = this.markers[i].mrkListeners;

this.geoCodeLookupLL(this.markers[i].streetAddr);
// var mkr_point = new GLatLng(markers[i].lat,markers[i].lng);
// this.addMarker(mkr_point,markers[i].title,false,markers[i].setCenter, markers[i].mrkListeners);
}
}


...but that gave me errors as well.

Thanks again!

Animal
25 Sep 2008, 5:56 AM
You are just not reading what I write.

Inside that callback function, With me so far?

this will refer to the browser window. It has, as I explained NO WAY OF KNOWING WHAT TO SET IT TO.

How can Google's function POSSIBLY know what to set "this" to?

Capture "this" in a variable before you call the geocode, and then use that variable inthe callback instead of "this".

You really, really, really, really need to learn Javascript before you get into complex UI stuf like GMAPs. If you do not know what you are doing you will just hit problems over and over and over again. And if people just give you solutions because you flap around in front of them, you'll continue not to learn.

Joyfulbob
25 Sep 2008, 7:37 AM
Thanks for your patience. You're right; I do need to learn it better. I'll digest what you gave me. I've just been going along learning as needed to get ExtJS apps done. I know that's not the best way. You're right; when I get to complex apps like this I need to know JS better.

Thanks for your assistance! I do appreciate it! BTY, do you know of a good JS book/web site that deals with these topics in depth? I'd like to learn it in an orderly manner and not just as I need it (As I've been doing!).

Thanks again!

lokiofragnar
25 Sep 2008, 9:21 AM
Hi JFB,

This may get you started. An article that just covers scope

http://www.digital-web.com/articles/scope_in_javascript/

BTW: database with just coordinates are actually pretty handy, try doing calculations with addresses :)

Have fun with the article,
cheers,
Aad

Animal
25 Sep 2008, 9:36 AM
I've heard good things about Crockford's "Javascript: The Good Parts"

And he has lots of info on his site: http://javascript.crockford.com/

This is good http://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Closures

Animal
25 Sep 2008, 9:39 AM
Where that article mentions bind() see http://extjs.com/deploy/dev/docs/?class=Function&member=createDelegate

Joyfulbob
26 Sep 2008, 8:55 AM
Thanks, guy!

I had read the scope article before.

So I had the afternoon off yesterday and went to my local Barnes and Noble and browsed some JS books. Guess which one I ended up buying? Crockford's "javascript: The Good Parts"! It's quite good and I'm learning and understanding things I've already coded - I've said to myself, "Aha! That's why I coded it that way!" ;)

So, Animal, I'm understanding better what you've been explaining to me. When I get back to this app, I'm sure I'll get it working. Thanks!

Joyfulbob
28 Sep 2008, 3:36 PM
I got it! I read the JavaScript: The Good Parts book and studied examples and now understand this and scope. Thanks, Animal! =D>

Here's the solution. My two comments note the lines in question.



// Convert street address to Lat/Long
geoCodeLookupLL: function(addr,markerTitle,markerListeners) {

this.geocoder = new GClientGeocoder();
this.markerStreetAddr = addr;

map = this.getMap(); // Store the panel's map data in this fnc's scope...

var markerUrl = '<br><a href="http://www.drudgereport.com" target="_blank">Select this Installer</a>';

this.geocoder.getLatLng(addr,
function(point) {

if (!point) {
Ext.MessageBox.alert('Invalid marker', 'Unable to Locate the Address you provided');
}else{
Ext.applyIf(markerTitle,G_DEFAULT_ICON);
var mark = new GMarker(point,markerTitle);
for (evt in markerListeners) {
// GEvent.bind(mark, evt, this, markerListeners[evt]);
}

map.addOverlay(mark); // ...then we can refer to it here without an 'undefined' error

mark.bindInfoWindowHtml(markerTitle + '<br>' + addr + markerUrl);
}
}
);

},

Animal
28 Sep 2008, 11:07 PM
Yes, but you'll want to use "var map = this.getMap();"

Read up about global variables.

Joyfulbob
29 Sep 2008, 6:24 AM
Yup; you're right; missed that when I coded it.

yuki
30 Sep 2008, 6:27 PM
Hi VinylFox,

This is a really nice ux and I love it! Thanks for your work.

A small suggestion for a quick fix.

Since the GMap2 "load" event takes place after "setCenter" method, "onMapReady" method won't still start (and the markers won't be mapped) if I "setCenter" by latlng (will start if I use geocoder because it works aynchronously).

All you need to do is to move


GEvent.bind(this.gmap, 'load', this, function(){
this.onMapReady();
}); before "setCenter" is called.

Cheers

arthurakay
7 Oct 2008, 1:11 PM
I notice in your example you have an attribute "markers" which takes objects formatted as:


lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}


Has there been any though given towards providing a string of the location's address rather than the Latitude/Longitude?

I ask because you allow us to give a string for the address of the centered marker, but not the other markers on the map. This would be extremely helpful for me... having to translate the Lat/Long of a list of locations would be painful.

Joyfulbob
8 Oct 2008, 5:36 AM
I coded that part myself. Our markers are addresses from our DB, which is a street address and not LatLng. Here's what I did:

The html page with the markers:

markers: [
{
id: 'I00025',
streetAddr: '9512 W HOWARD AVENUE, MILWAUKEE, WI 53228, USA',
title: 'I00025 - HOME - Type: C',
listeners: {
click: function(e){
Ext.Msg.alert('I00025 - 9512 W HOWARD AVENUE, MILWAUKEE, WI 53228, USA');
}
}
,
... // successive marker(s) here
...
}

Then in Ext.ux.GMapPanel.js I changed the addMarkers function to call a new function, geoCodeLookupLL, which gets the LatLng from Google and then adds that marker to the map:

addMarkers: function(markers) {

if (Ext.isArray(markers)){
for (var i = 0; i < markers.length; i++) {
// BK..convert to Lat Lng
this.geoCodeLookupLL(this.markers[i].streetAddr, this.markers[i].title, this.markers[i].mrkListeners, this.markers[i].id);
}
}

}
...
// BK..Convert street address to Lat/Long, then add the marker to the map
geoCodeLookupLL: function(addr, markerTitle, markerListeners, markerKey) {

this.geocoder = new GClientGeocoder();
this.markerStreetAddr = addr;
var map = this.getMap();
var keyVar = markerKey;
var markerUrl = '<br><a href="JavaScript:selectJS(\'' + keyVar + '\');">Select this Installer</a>';

this.geocoder.getLatLng(addr,

function(point) {

if (!point) {
Ext.MessageBox.alert('Invalid marker', 'Unable to Locate the Address you provided');
console.info('Invalid addr: ' + addr + ' Point: ' + point );
}else{
Ext.applyIf(markerTitle,G_DEFAULT_ICON);
var mark = new GMarker(point,markerTitle);
for (evt in markerListeners) {
// GEvent.bind(mark, evt, this, markerListeners[evt]);
}
map.addOverlay(mark);
mark.bindInfoWindowHtml(markerTitle + '<br>' + addr + markerUrl);
}
}
);
}


Hope this helps!

mauro.pelucchi
9 Oct 2008, 1:12 AM
i really like this ux, good job!

first of all, a small feature suggestion: i tried a window with the config-option maximable:true. On scaling fullscreen, the map did not resize properly, i guess it is not implemented yet, is it?

the major point is: i would like to add routes. on code.google.com, i found an example like:



var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
var polyline = new GPolyline([
new GLatLng(37.4419, -122.1419),
new GLatLng(37.4519, -122.1519)
], "#ff0000", 10);
map.addOverlay(polyline);


is this already possible with the ux (and if how?) or shall i try to add / extend this by myself?


thanks, tobiu

Try this...


onResize : function(w, h){
Ext.ux.GMapPanel.superclass.onResize.call(this, w, h);
if (typeof this.getMap() == 'object') {
this.gmap.checkResize();
}
}


bye
Mauro

mirgor
17 Oct 2008, 11:10 AM
Hi all.
I try work with gmap exemple. When I replaced geoCodeAddr on lat and lng , then markers of 'Boston Museum of Fine Arts' and 'Northeastern University' done invisible.


...
setCenter: {
lat: 42.339650,
lng: -71.094250,
//geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
lng: -71.094224,
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
...


How it to correct? :-/

bclinton
19 Oct 2008, 6:47 PM
Great extension! I love it!

I wasn't able to get the panorama view to work when sending an address via the 'geoCodeAddr' config, but could get it to work when specifying latitude and longitude.

I looked through the code and I think I found the problem. Here are the changes I made to get it to work. There's surely a better way to accomplish this, but I think the changes at least demonstrate the problem.

I added the bolded green lines to the end of the addAddressToMap function:



}else{
point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear,true);
}
if (this.gmapType === 'panorama'){
this.gmap.setLocationAndPOV(point, {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom});
}
}
then, I included panorama stuff that just uses lat and 'long' into the else of the if statement that checks if the geoCodeAddr is set:



if (typeof this.setCenter === 'object') {
if (typeof this.setCenter.geoCodeAddr === 'string'){
this.geoCodeLookup(this.setCenter.geoCodeAddr);
}else{
if (this.gmapType === 'map'){
alert('---> '+this.setCenter.lat+', '+this.setCenter['long']);
var point = new GLatLng(this.setCenter.lat,this.setCenter['long']);
this.gmap.setCenter(point, this.zoomLevel);
}
if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear);
}
if (this.gmapType === 'panorama'){
this.gmap.setLocationAndPOV(new GLatLng(this.setCenter.lat,this.setCenter['long']), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom});
}
}
}

GobbaF
29 Oct 2008, 4:16 AM
Great extension !

However, I try to use it in a tabpanel but I have the same problem as this one : http://extjs.com/forum/showthread.php?p=157154#post157154 - my map does not extend all the page.

Here the code :

/**
* @author Shea Frederick
*/

Ext.onReady(function(){

new Ext.Viewport({
title: 'GMap Panel',
layout: 'border',
items: {
region: 'center',
xtype: 'tabpanel',
activeTab: 0,
items: {
title: 'Cartographie',
xtype: 'gmappanel',
region: 'center',
zoomLevel: 14,
gmapType: 'map',
addControl: new GSmallMapControl(),
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
'long': -71.094224,
marker: {title: 'Boston Museum of Fine Arts'}
},{
lat: 42.339419,
'long': -71.09077,
marker: {title: 'Northeastern University'}
}]
}
}
});
});

Here the extension (unmodified) :

/**
* @author Shea Frederick
*/

Ext.namespace('Ext.ux');

/**
*
* @class GMapPanel
* @extends Ext.Panel
*/
Ext.ux.GMapPanel = Ext.extend(Ext.Panel, {
initComponent : function(){

var defConfig = {
plain: true,
zoomLevel: 3,
yaw: 180,
pitch: 0,
zoom: 0,
gmapType: 'map',
border: false
}

Ext.applyIf(this,defConfig);

Ext.ux.GMapPanel.superclass.initComponent.call(this);

},
afterRender : function(){

var wh = this.ownerCt.getSize();
Ext.applyIf(this, wh);

Ext.ux.GMapPanel.superclass.afterRender.call(this);

if (this.gmapType === 'map'){
this.gmap = new GMap2(this.body.dom);
}

if (this.gmapType === 'panorama'){
this.gmap = new GStreetviewPanorama(this.body.dom);
}

if (typeof this.addControl === 'object' && this.gmapType === 'map') {
this.gmap.addControl(this.addControl);
}

if (typeof this.setCenter === 'object') {
if (typeof this.setCenter.geoCodeAddr === 'string'){
this.geoCodeLookup(this.setCenter.geoCodeAddr);
}else{
if (this.gmapType === 'map'){
var point = new GLatLng(this.setCenter.lat,this.setCenter['long']);
this.gmap.setCenter(point, this.zoomLevel);
}
if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear);
}
}
if (this.gmapType === 'panorama'){
this.gmap.setLocationAndPOV(new GLatLng(this.setCenter.lat,this.setCenter['long']), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom});
}
}

var dt = new Ext.util.DelayedTask();
dt.delay(300, function(){
this.addMarkers(this.markers);
}, this);

},
onResize : function(w, h){

if (typeof this.gmap == 'object') {
this.gmap.checkResize();
}

Ext.ux.GMapPanel.superclass.onResize.call(this, w, h);

},
setSize : function(width, height, animate){

if (typeof this.gmap == 'object') {
this.gmap.checkResize();
}

Ext.ux.GMapPanel.superclass.setSize.call(this, width, height, animate);

},
getMap: function(){

return this.gmap;

},
addMarkers: function(markers) {

if (Ext.isArray(markers)){
for (var i = 0; i < markers.length; i++) {
var mkr_point = new GLatLng(markers[i].lat,markers[i]['long']);
this.addMarker(mkr_point,markers[i].marker,false,markers[i].setCenter);
}
}

},
addMarker: function(point, marker, clear, center){

Ext.applyIf(marker,G_DEFAULT_ICON);

if (clear === true){
this.gmap.clearOverlays();
}
if (center === true) {
this.gmap.setCenter(point, this.zoomLevel);
}

var mark = new GMarker(point,marker);
this.gmap.addOverlay(mark);

},
geoCodeLookup : function(addr) {

this.geocoder = new GClientGeocoder();
this.geocoder.getLocations(addr, this.addAddressToMap.createDelegate(this));

},
addAddressToMap : function(response) {

if (!response || response.Status.code != 200) {
Ext.MessageBox.alert('Error', 'Code '+response.Status.code+' Error Returned');
} else {
place = response.Placemark[0];
addressinfo = place.AddressDetails;
accuracy = addressinfo.Accuracy;
if (accuracy === 0) {
Ext.MessageBox.alert('Unable to Locate Address', 'Unable to Locate the Address you provided');
}else{
if (accuracy < 7) {
Ext.MessageBox.alert('Address Accuracy', 'The address provided has a low accuracy.<br><br>Level '+accuracy+' Accuracy (8 = Exact Match, 1 = Vague Match)');
}else{
point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear,true);
}
}
}
}

}

});
Ext.reg('gmappanel',Ext.ux.GMapPanel);

You can see an example here : http://88.191.39.115/fabien/temp/test.html

When I don't put the activeTab attribute, I don't have this problem.
Do you have any idea to help me ?

Cheers,

Fabien.

bclinton
29 Oct 2008, 7:10 AM
Great extension !

However, I try to use it in a tabpanel but I have the same problem as this one : http://extjs.com/forum/showthread.php?p=157154#post157154 - my map does not extend all the page.


I had that same problem. Just put your gmappanel inside another panel with layout set to 'fit' so your code starts off like this:



items: {
region: 'center',
xtype: 'tabpanel',
activeTab: 0,
items: {
layout: 'fit',
items: {
title: 'Cartographie',
xtype: 'gmappanel',
zoomLevel: 14,Also, I notice you have region: 'center' in your gmappanel config. You probably left it in there after making your center region a tab panel, but there's no reason for it to be there now because your gmappanel is not in a border layout.

GobbaF
29 Oct 2008, 11:40 AM
Thank you for help, it works now !

abraxxa
5 Nov 2008, 9:49 AM
I started using it today and have some suggestions for improvement.
First it would be great to make the accuracy limit configurable and/or add the marker after the warning popup.
Then I tried to add multiple markers with geoCodeLookup to the map based on a grid selection, which works, but the last one is the center of the map.
A function which loops through all markers and calculates the optimal center would be great, again with an option to autorun it on demand.

If you agree that this things make sense I'll try to implement them and paste my code here for addition to your great ux!

BTW geoCodeLookup should be renamed to something like addMarkerBygeoCodeLookup.

bclinton
5 Nov 2008, 10:15 AM
If you agree that this things make sense I'll try to implement them and paste my code here for addition to your great ux!

BTW geoCodeLookup should be renamed to something like addMarkerBygeoCodeLookup.

VinylFox hasn't posted on these boards in over two months. He may not be following this anymore. I think any improvements you make would be welcome.

abraxxa
6 Nov 2008, 8:06 AM
I've attached my version with support for autocenterandzoom and some other changes like using the address as title for geocoded markers instead of the title of the setCenter marker (which might not have one).


The new option is autocenterandzoom which defaults to false, if set to true all added markers will autocenterandzoom. ;-)

I use this config options to set a center on map creation which is needed by GMap2.

// workaround to be able to use getCodeLookup later which needs a center set
setCenter:{
lat:0,
lng:0
}

veerugadde
21 Nov 2008, 6:13 PM
Hello,

This extension is really good and a lot of applauds to you.I was trying to map kml files using above extension but unable to implement. Could you please explain me about any ideas which will be useful to implement the requirement.

Thanks,

veeru

VinylFox
22 Nov 2008, 11:15 AM
@veerugadde

It's quite easy to load a KML file. This extension exposes all of the GMaps built in functions via getMap(), so all we need to do is use the GMaps functions to do what we want.

For example, this is a button that loads a KML file (that I found randomly on the internet) and adds it as an overlay.



buttons: [{
text: 'Load KML',
handler: function(){
var geoXml = new GGeoXml("http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/DirectionsLA-NY.kml");
Ext.getCmp('my_map').getMap().addOverlay(geoXml);
}
}]


It would be nice if we could do that with a config option as well - maybe something like this...



...
items: {
xtype: 'gmappanel',
autoLoadKML: 'http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/DirectionsLA-NY.kml',
zoomLevel: 14,
gmapType: 'map',
...


and modify the ux with this handler...



addKMLOverlay : function(kmlfile){

if (typeof kmlfile === 'string' && kmlfile !== '') {
var geoXml = new GGeoXml(kmlfile);
this.getMap().addOverlay(geoXml);
}

},


Then modifying onMapReady in the ux like this:



onMapReady : function(){

this.addMarkers(this.markers);
this.addKMLOverlay(this.autoLoadKML);

},


I have committed these changes to SVN as well.
http://code.google.com/p/ext-ux-gmappanel/

Hope that helps.

@abraxxa

I plan on integrating your changes soon. Thanks for posting them.

veerugadde
24 Nov 2008, 8:26 AM
Hey

Thanks for your wonderful suggestion with adding kml option. I have tried to update the sample but was unable to display any kml files.Could you please help me out with the problem?

Thanks

abraxxa
24 Nov 2008, 9:24 AM
@VinylFox: great!

veerugadde
24 Nov 2008, 9:53 AM
Hello,

Could you please tell me if the kml option is working fine for you? if so,can you please explain me the possible mistakes with mine?

Thanks.

VinylFox
24 Nov 2008, 10:05 AM
@veerugadde

I would need to see your code or have you post error messages of some sort.

josh803316
24 Nov 2008, 11:56 AM
This may have already been covered but how do I get the normal pop-up google window, when I click the marker, that contains href links for getting directions as well as a picture of the address. Which function do I need to call for access to this?

veerugadde
24 Nov 2008, 1:37 PM
Hello

I figerd out the above problem and it is working fine although it has small problem.When i was loading the kml file from localhost server, it is not working.And also would you please suggest me solution to load a multiple kml files (i.e loading with selection option of check boxes)?

Thank you.

VinylFox
24 Nov 2008, 2:12 PM
Remember that you need to use the localhost API key when using the GMaps API on your local server. Other than that, it should work just the same.

You should also be able to add overlays (from KML files) as many times as you want, of course this would have to be done programatically instead of the config method. As far as checkboxes and such, that is a bit out of scope for this thread, I would suggest starting a new thread for that.

rlegend
3 Dec 2008, 11:39 AM
I found the following post for those trying to develop an app using maps but you cannot load local KML (which is quite frustrating from a development standpoint).


noon wrote:
> var feed = new GGeoXml(feedUrl);
> GMap2.addOverlay(feed);
> This works fine for a feedUrl like http://code.google.com/apis/kml/documentation/KML_Samples.kml
> and not at all for a feedUrl like http://localhost:81/myMapApp/lib/KML_Samples.kml



Note GGeoXml has a step in its processing where Googles servers
up/download the kml or in this case fail to download
from the url you pass... http://localhost:81 (http://localhost:81/) takes on whole new
meaning and is undefined for googles servers
you cant use GGeoXml in this context.
It is possible if you are processing your kml yourself or using
Mikes EGeoXml or for a more thorough implementation my GeoXml parser

Lance Dyas
GIS Programmer, Web App Developer, Graphic Artist.
http://www.dyasdesigns.com/geoxml I'll be taking a look at these tools shortly and will you let you all know how they work if there is any interest.

Ron


Hello

I figerd out the above problem and it is working fine although it has small problem.When i was loading the kml file from localhost server, it is not working.And also would you please suggest me solution to load a multiple kml files (i.e loading with selection option of check boxes)?

Thank you.

f1xxx3r
22 Jan 2009, 5:35 AM
Hello and thank you for the great plugin!
Can anyone guide me how to display the center marker with the standard "bubble" with the directions options? Like the one displayed when you search google maps manually.

Thank you very much.

VinylFox
22 Jan 2009, 7:19 AM
The Google Maps API is a great place to start - you will want to take a look at the GInfoWindow.

http://code.google.com/apis/maps/documentation/reference.html#GInfoWindow

I dont think there is the option for a directions window. You would likely have to create it yourself inside of a standard window.

abraxxa
23 Jan 2009, 6:28 AM
@VinylFox: have you had time to integrate my changes into the main code?

pop k
23 Jan 2009, 9:47 AM
Hi all,

Does anybody succeed in load markers from Ext.data.Store?
I tried but not succeed cause, the store data is not ready yet after load() .
It come asynchronously later.
So how can i declare gmappanel and set markers:mystore.data because the data is notready.

Thanks in advance
pop k.

VinylFox
24 Jan 2009, 6:05 AM
@abraxxa - I started to, but have not had time to finish. Ill get to it sooner or later :)

abraxxa
25 Jan 2009, 4:34 AM
Can I support you in any way?

z1nkum
25 Jan 2009, 11:13 AM
Hi! Thanks for a great job!

I have a little problem - cant catch any map events (try with 'click')
Full source of map part here http://nwmost.ru/clients/js/show_map.js

with GEvent:

GEvent.addListener(ClientsMap, "click", function(overlay, latlng) {
console.log("success on %o %o",overlay,latlng);
});

with 'listeners' of Ext.ux.GMapPanel object:


listeners: {
click: function(e){
console.log("success on %o", e);
}
}


have no effect :(

nunziofiore
26 Jan 2009, 12:44 PM
Hi all,
i have an URGENT problem, could you help me?

this is the code i use:


Ext.onReady(function(){

var mapwin;
//var button = Ext.get("+id+");/*show-btn*/
var button = Ext.get('pippo');


button.on('click', function(){

if(!mapwin){

mapwin = new Ext.Window({
layout: 'fit',
title: 'Una popup Orginale con i miei link',
closeAction: 'hide',
width:600,
height:400,
x: 140,
y: 145,
items: {
xtype: 'gmappanel',
region: 'center',
zoomLevel: 6,
gmapType: 'map',
mapControls: ['GLargeMapControl','GMapTypeControl'],
setCenter: {
lat: 44.499399,
lng: 11.203388,

marker: {title: 'CASA'},
listeners: {
click: function(e){
Ext.Msg.alert('ALTEDO', 'Questa � la citt� in cui abito!.');
}
}

},
markers: [

{
lat: 44.499199,
lng: 11.203308,
marker: {title: 'YOOX - Dove lavoro'},
listeners: {
click: function(e){
Ext.Msg.alert('YOOX', 'Questa � la societ� presso cui lavoro.<br>Vai al sito di <a href="http://www.yoox.com" target="_new">YOOX</a>.');
}
}
},

{

lat: 41.762571,
lng: 12.203308,
marker: {title: 'HTML.it - Articoli'},
listeners: {
click: function(e){
Ext.Msg.alert('HTML.it', 'Questa � la societ� per cui scrivo articoli e manuali informatici sul web 2.0.<br>Vai al sito di <a href="http://www.html.it" target="_new">HTML.it</a>.');
}
}
},

{

lat: 41.762571,
lng: 12.435308,
marker: {title: 'icTV - Video'},
listeners: {
click: function(e){
Ext.Msg.alert('icTV', 'Questa � la societ� per cui realizzo video e howto sul web 2.0.<br>Vai al sito di <a href="http://www.ictv.it" target="_new">icTV.it</a>.');
}
}
}]
}
});

}

mapwin.show();

});


var mapwin2;
//var button = Ext.get("+id+");/*show-btn*/
var button2 = Ext.get('pippo1');


button2.on('click', function(){

if(!mapwin2){

mapwin2 = new Ext.Window({
layout: 'fit',
title: 'Una popup Orginale con i miei link',
closeAction: 'hide',
width:600,
height:400,
x: 40,
y: 45,
items: {
xtype: 'gmappanel',
region: 'center',
zoomLevel: 6,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GLargeMapControl','GMapTypeControl'],
setCenter: {
geoCodeAddr: 'via Franchini 29, Altedo, 40051 Bologna, Italy',
marker: {title: 'CASA'},
listeners: {
click: function(e){
Ext.Msg.alert('ALTEDO', 'Questa � la citt� in cui abito!.');
}
}
},
markers: [

{
lat: 44.499199,
lng: 11.203308,
marker: {title: 'YOOX - Dove lavoro'},
listeners: {
click: function(e){
Ext.Msg.alert('YOOX', 'Questa � la societ� presso cui lavoro.<br>Vai al sito di <a href="http://www.yoox.com" target="_new">YOOX</a>.');
}
}
},

{

lat: 41.762571,
lng: 12.203308,
marker: {title: 'HTML.it - Articoli'},
listeners: {
click: function(e){
Ext.Msg.alert('HTML.it', 'Questa � la societ� per cui scrivo articoli e manuali informatici sul web 2.0.<br>Vai al sito di <a href="http://www.html.it" target="_new">HTML.it</a>.');
}
}
},

{

lat: 41.762571,
lng: 12.435308,
marker: {title: 'icTV - Video'},
listeners: {
click: function(e){
Ext.Msg.alert('icTV', 'Questa � la societ� per cui realizzo video e howto sul web 2.0.<br>Vai al sito di <a href="http://www.ictv.it" target="_new">icTV.it</a>.');
}
}
}]
}
});

}

mapwin2.show();

});

});



Where s the error? I noticed that if in map associated to button, i write an address as string, it runs... but with lat and lng, it break!

I appraciate a lot of your work... please, let me know what do you think !

Nunzio Fiore
(ps if you wanna see a video i posted some month ago on an italian web tv about this extension, you can look here (http://www.ictv.it/file/vedi/863/creare-originali-popup-con-google-maps-e-ext/)

prabhukm
27 Jan 2009, 6:48 AM
How can I removed the icon associated for the default location? I don't want to show the icon for setCenter.

nunziofiore
27 Jan 2009, 6:51 AM
i think you simply have to cut off the marker json object in deafult setCenter.

VinylFox
27 Jan 2009, 11:44 AM
@abraxxa - can you test the code I just committed and let me know what you find.

@z1nkum - I have not implemented any listeners/events for the component, just for the markers. I assume the default events exist for panel, but i have not tested any of that.

@nunziofiore - Please try again with the most recent code. Let me know if it works now.

@prabhukm - nunziofiore is correct, but there were some bugs that made this not work as it should have, you will need to grab the latest changes I committed just now.


UPDATED CODE! -> http://code.google.com/p/ext-ux-gmappanel/

prabhukm
28 Jan 2009, 6:17 AM
Thanks VinylFox. I've fixed in this way




addAddressToMap : function(response) {
.
.
.

if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){ //this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear,true, this.setCenter.listeners);
this.getMap().setCenter(point, this.zoomLevel);
}




And it works.

VinylFox
28 Jan 2009, 6:56 AM
@prabhukm - im sure that change works for your situation, but it has some design flaws when you step back and take a broad look. I would suggest using the updated version i posted yesterday.

daveh0
2 Feb 2009, 10:26 AM
I have created a map with a marker. I have added a listener for "click" for the marker and I'm trying to call the openInfoWindowHtml() method from the Gmap API when the marker is clicked. Hoping that a reference to the marker was passed to the listener, I tried this:



listeners: {
click: function(e){
//Ext.Msg.alert('Its fine', 'and its art.');
e.openInfoWindowHtml(''Its fine', 'and its art.'');
}
}
and got this error:


e.openInfoWindowHtml is not a functionWhen I just alert(e), it gives me the lat and lng... which seems weird to me. So based on all this, I have 2 questions:
How do I obtain a reference to the marker that was clicked so that I can call the openInfoWindowHtml() method?
What exactly are the parameters passed to the click event?

daveh0
3 Feb 2009, 6:44 AM
I have created a map with a marker. I have added a listener for "click" for the marker and I'm trying to call the openInfoWindowHtml() method from the Gmap API when the marker is clicked. Hoping that a reference to the marker was passed to the listener, I tried this:



listeners: {
click: function(e){
//Ext.Msg.alert('Its fine', 'and its art.');
e.openInfoWindowHtml(''Its fine', 'and its art.'');
}
}
and got this error:

When I just alert(e), it gives me the lat and lng... which seems weird to me. So based on all this, I have 2 questions:
How do I obtain a reference to the marker that was clicked so that I can call the openInfoWindowHtml() method?
What exactly are the parameters passed to the click event?


I have figured out that e is a point object that can be passed to the GMarker() method to create a new marker. In this case, the marker has already been created and we are trying to make something happen when it is clicked. I'd like to call the same function in the listener for each marker. The function will carry out different tasks depending on which marker was clicked but right now I have no way of telling which marker was clicked. All I know is that SOME marker was clicked but not which one...

This would be similar to adding a listener for the activate event on a tab within a TabPanel. In that case, a reference to the tab object is passed to the listener. From there, I can access all of the tab's properties (like tab.id) and create different actions for different tab clicks.

Any way to determine which marker was clicked?

VinylFox
3 Feb 2009, 8:45 AM
@daveh0 - The Google maps API was not much help in figuring out what arguments the click handler passes, but here is the relevant section anyway:


This event is fired when the user clicks on the map with the mouse. A click event passes different arguments based on the context of the click, and whether or not the click occured on a clickable overlay. If the click does not occur on a clickable overlay, the overlay argument is null and the latlng argument contains the geographical coordinates of the point that was clicked. If the user clicks on an overlay that is clickable (such as a GMarker, GPolygon, GPolyline, or GInfoWindow), the overlay argument contains the overlay object, while the overlaylatlng argument contains the coordinates of the clicked overlay. In addition, a click event is then also fired on the overlay itself.

I might be reading this wrong, but it seems like there should be two arguments passed to your handler, but there is only a latlng object. Im not sure at this point what is wrong, but ill keep looking.

Events in the GMap API are not quite as dynamic as their ExtJS counterparts your use to using.

daveh0
3 Feb 2009, 5:36 PM
Yeah that seems like a bit of a grey area...

I created a workaround to suit my purposes for the time being. Interested to hear what you think of it.

My overall goal is to be able to open a GMap Info window over each marker when it is clicked. And of course it would ideal to include the code to do this in the oclick handler for each marker. Since I need to access the marker objects after their creation, I modified the addMarker() method such that every time a marker is created, a reference to it (along with some other info to help identify it when the time comes) is stored in an array named 'gmarkers' . I did not create the array as part of the GMapPanel object (because I didn't know how) but I'm guessing that it should be...?

Next, in my onclick handeling code, I receive the lat/lang object and convert it to a string. I then match it up to the lat and lng defined for each marker in the gmappanel's config. When I find the right one, I then find the reference to the marker object in the gmarkers array. Once I have the marker, I can call marker.openInfoWindowHtml(). To do this, I added a method to the GMapPanel object:



openInfWinHtm : function(marker, html) {
marker.openInfoWindowHtml(html);
},



and call it from the onclick handler for each marker:



this.openInfWinHtm(marker, html);


marker is a reference to the desired marker in the gmarkers array. And I have a function that returns the HTML for various elements. I call this function for my marker and store the markup in my html variable that is then passed to openInfWinHtm().

Is that kind of on the right track? What about the gmarkers array? how would I go about making that mart of the GMapPanelobject?

prabhukm
4 Feb 2009, 8:57 AM
If I specify the complete Address with Door Number, Street Name, City, State, Country Zip Code, it works fine.

But If I specify the default address as City, State, Country I'm getting the following pop-up message

The address provided has a low accuracy. Level 4 Accuracy (8 = Exact Match, 1 = Vague Match)


So Do I need to specify the complete address as Door Number, Street Name, City, State, Country Zip Code ?

xantus
4 Feb 2009, 11:50 AM
Perhaps this problem exists outside of the GMapPanel as well. But if you move the Panel outside the bounds of the browser, there might be no way to get it back. If you try to grab the panel, of course, you will simply grab the map. I put this in to prevent that:

listeners:{
'move':{
fn:function(){
if (this.y < 0) this.setPosition(this.x,0);
}
}
}


If you are using the panel in a window, you can use contstrain: true and the window will stay in the viewable area.

VinylFox
4 Feb 2009, 2:11 PM
If I specify the complete Address with Door Number, Street Name, City, State, Country Zip Code, it works fine.

But If I specify the default address as City, State, Country...

You make a great point - you should be able to set a marker/center even if the accuracy is low. I actually keep a database with the lat/lng of the center of each state and the center of each zip code, so I have never found a need to place markers in this manner.

Anyway, I have added a configuration option that will let you set the min accuracy level.

http://code.google.com/p/ext-ux-gmappanel/source/detail?r=9

Enjoy!

dodgie
7 Mar 2009, 10:54 AM
Hey Shea,

Thanks for providing such a great component!

I know I can use

Ext.getCmp('my_map').getMap().setCenter(result);
to move the map to a new GLatLng position but how can I use the geocoder to do the same?

Also, is there a way to reset the zoom level after the map has been drawn? Ideally I'd like to start with a world view and then zoom in when a user enters a location, I'll use setCenter() to recenter the map on the new position, but at the moment it maintains the same zoom level as when the map was created.

Rich

sprestel
13 Mar 2009, 5:37 AM
how i can send a parameter with die coordinates of the "startcenterpoint"??

thanks for help

VinylFox
13 Mar 2009, 7:22 AM
Thanks for providing such a great component!

Thank you for your kind words - its much appreciated.


to move the map to a new GLatLng position but how can I use the geocoder to do the same?

Also, is there a way to reset the zoom level after the map has been drawn?

I was going to type out an answer to your questions, but I decided to just put up an example. I need a few more examples anyway.

examples/advanced/recenter-map.js (http://code.google.com/p/ext-ux-gmappanel/source/browse/trunk/examples/advanced/recenter-map.js)

This UX is documented quite well in the source, so if there are other things you need to figure out, check out the source to see if it has your answer.


how i can send a parameter with die coordinates of the "startcenterpoint"??

Your going to have to re-phrase this question in a form that I can understand.

GobbaF
13 Mar 2009, 12:37 PM
Hi,

I don't know if it can help, but
I added this piece of code for this great component to initialize the default layers :


if (this.gmapType === 'map'){
// update : default layers
if (Ext.isArray(this.layersDefault) && this.layersDefault.length != 0) {
this.gmap = new GMap2(this.body.dom,{mapTypes: this.layersDefault});
}
// end update
else{
this.gmap = new GMap2(this.body.dom);
}
}

And add something like this to the config option :

layersDefault: [G_NORMAL_MAP,G_PHYSICAL_MAP,G_SATELLITE_MAP,G_HYBRID_MAP,G_SATELLITE_3D_MAP,G_MARS_INFRARED_MAP],
or every map type defines here : http://code.google.com/intl/fr/apis/maps/documentation/reference.html#GMapType

Cheers,

Fabien

dolittle
14 Mar 2009, 1:11 PM
The google maps api docs recommend to clean stuff on unload:

<body onunload="GUnload()">

Don't we need something to prevent memory leaks?
Maybe call GUnload on the panel destroy because on a web app maps can be created and destroyed many times. Not sure if GUnload will kill other working map panels.

Thanks

VinylFox
18 Mar 2009, 9:54 AM
The google maps api docs recommend to clean stuff on unload:

<body onunload="GUnload()">

Don't we need something to prevent memory leaks?
Maybe call GUnload on the panel destroy because on a web app maps can be created and destroyed many times. Not sure if GUnload will kill other working map panels.

Thanks

Unfortunately, we cant call GUnload on the Panels destruction because it would indeed disable all the other maps on the page, along with the ability to generate new maps.

Not really sure if its needed to be honest, but then again, im not really sure what GUnload would even be "cleaning up". Destroying the panel removes any elements created by the google map.

Daz
18 Mar 2009, 7:39 PM
I gather the Google Map object is created in the GMapPanel afterRender event.
Is there a way the GMapPanel extension can be used if the Google Map object needs to be accessed prior to this event being fired?

For example, a multi-tab application:
* Tab-1 contains grid of address data (default tab)
* Tab-2 contains the Google Map

If a user clicks on a Tab-1 grid address, a marker would be created in the Tab-2 Google Map and the map centred. At any time, when the user clicks on Tab-2, it should display the markers with the Google Map centred on the last one created.

(As expected, this only works when Tab-2 has been clicked prior to addresses being selected in Tab-1)

VinylFox
18 Mar 2009, 7:47 PM
I gather the Google Map object is created in the GMapPanel afterRender event...

Its created in initComponent afterRender.

You might try adding deferredRender: false to your TabPanel.

Daz
18 Mar 2009, 8:17 PM
Will try re-testing the deferredRender:false, although didn't make a difference in my previous testing.

However, am I missunderstanding something here as I thought the Google Map object was being created in the afterRender function, hence the deferredRender:false not making any difference, as follows:


afterRender : function(){
...

Ext.ux.GMapPanel.superclass.afterRender.call(this);
if (this.gmapType === 'map'){
this.gmap = new GMap2(this.body.dom);
this.mapDefined = true;
this.mapDefinedGMap = true;
}

...
}

VinylFox
19 Mar 2009, 3:37 AM
Will try re-testing the deferredRender:false, although didn't make a difference in my previous testing.

However, am I missunderstanding something here as I thought the Google Map object was being created in the afterRender function, hence the deferredRender:false not making any difference...

Your correct, apparently I was a bit sleep deprived last night...but I thought that setting deferredRender:false should fix things up.

When you set deferredRender:false are all the panel elements created for the 2nd tab?

I will have to do some testing to see whats going on.

VinylFox
19 Mar 2009, 5:28 AM
@Daz - turning off deferred rendering worked fine for me, I threw together an example for you to take a look at...

examples/tabs/tabs-basic.js (http://code.google.com/p/ext-ux-gmappanel/source/browse/trunk/examples/tabs/tabs-basic.js)

Good luck.

Daz
19 Mar 2009, 6:32 AM
Thanks Shea - really appreciate your help.

rlegend
31 Mar 2009, 4:03 PM
Hey VinylFox,

Great UX btw, I love it.

The problem:

Multiple maps don't work on a single page if more than of the maps has the GOverviewMapControl.

It has to do with the way that GOverviewMapControl controls are instantiated. Here's a link to the a google groups thread on this subject.


http://groups.google.com/group/Google-Maps-API/browse_thread/thread/cc0f48cf1344a1e6/3593884f0a2358e1?lnk=gst&q=this.show+is+not+a+function#3593884f0a2358e1

I attempted, poorly, to solve the problem but was unsuccessful.

I ginned up a dead simple example illustrating the problem, based on the original sample for the UX.


mapwin is an GMapPanel with the GOverviewMapControl
mapwin2 is an GMapPanel without the GOverviewMapControl
the main viewport has a map with the GOverviewMapControl

The mapwin2 window consistently loads while the mapwin window fails with
'this.show is not a function' somewhere in the google api code.

Example Code (Just a hacked version of the original sample)



Ext.onReady(function(){



var mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width:400,
height:400,
x: 40,
y: 60,
items: {
xtype: 'gmappanel',
region: 'center',
mapControls: ['GOverviewMapControl','GLargeMapControl'],
zoomLevel: 14,
gmapType: 'map',
//mapControls: ['GOverviewMapControl'],
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
'long': -71.094224,
marker: {title: 'Boston Museum of Fine Arts'}
},{
lat: 42.339419,
'long': -71.09077,
marker: {title: 'Northeastern University'}
}]
}
});

var mapwin2 = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width:400,
height:400,
x: 40,
y: 60,
items: {
xtype: 'gmappanel',
region: 'center',
mapControls: ['GLargeMapControl'],
zoomLevel: 14,
gmapType: 'map',
//mapControls: ['GOverviewMapControl'],
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
'long': -71.094224,
marker: {title: 'Boston Museum of Fine Arts'}
},{
lat: 42.339419,
'long': -71.09077,
marker: {title: 'Northeastern University'}
}]
}
});

new Ext.Viewport({
title: 'GMap Panel',
layout: 'border',
items: {
xtype: 'gmappanel',
region: 'center',
zoomLevel: 14,
gmapType: 'map',
mapControls: ['GOverviewMapControl','GScaleControl','GLargeMapControl','GMapTypeControl'],
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
'long': -71.094224,
marker: {title: 'Boston Museum of Fine Arts'}
},{
lat: 42.339419,
'long': -71.09077,
marker: {title: 'Northeastern University'}
}],
tbar: [{
text: 'Broken, Fenway Park Map Window',
handler: function(){
mapwin.show();
}
}, {
text: 'Working, Fenway Park Map Window',
handler: function(){
mapwin2.show();
}
}]
}
});

});
The current work around is to use pre 2.149 Google Maps API or to not use the GOverviewMapControl control.

Hope this is helpful.

R

VinylFox
31 Mar 2009, 4:18 PM
@rlegend - I was not able to replicate this problem. Are you using the most recent version of this UX from my google code SVN, or the one included with the ExtJS SDK's examples?

rlegend
31 Mar 2009, 7:04 PM
@VinylFox

Thanks for the Quick reply.

I was using the latest version from Google Code for that example. I'll try to see if i can't find some web space to post the example.

The key is that the version for the Google Maps API must be above 2.148 for the error to occur.

I'll try get something more concrete.

Ron

VinylFox
31 Mar 2009, 8:13 PM
That's actually the server side version number, for this problem I think the client side version number is likely more relevant. You can tell what this number is by doing...


console.log(G_API_VERSION);

I am testing with the most recent (ver=2.x), which should be giving me the most recent 2.x branch version - currently client side version "151e".

When I loaded server side version 2.148 I get client side "148e".

Current stable version (ver=2) is "150c".

Not sure if this makes a difference, but im using my "tabs-basic" example to test with, and simply adding an overview control to each map.

PS: my tests worked using the 2.148 version.

rlegend
1 Apr 2009, 11:54 AM
Ok. Tried your tabs example and it works like a charm. When I combine your tabs example with your initial example it illustrates the problem I'm having.

Here's the demo. You can select between what api version you want to test. with 2.x,2,2.148 available.

The example only works with the 2.148 api or below.

http://kanaye.net/maps/tabs.php

I've also included a slightly modified version of the original example

http://kanaye.net/maps/original.php

rlegend
7 Apr 2009, 9:29 AM
I guess I'll just stick with 2.148 then.

VinylFox
7 Apr 2009, 11:20 AM
I never was able to replicate the problem on my end - even using your example.

What browser are you using?

rlegend
7 Apr 2009, 1:11 PM
I've had consistent results with the following browsers.

XP SP2
IE7
Firefox 3.0.8
OS X 10.5

Opera 9.64
Firefox 3.0.8
Safari 4 Beta

stolsma
7 Apr 2009, 11:35 PM
I have the same problem too.. But the problem pops up after I remove a window with a GMap (and destroying it, can't destroy the GMap though as we know...) and then create a new window with a GMap. I'm busy creating a examples page...

Edit: Don't need to create an examples page.. rlegend's example is giving the same results as I have.. At initialisation everything goes well (see the two created tabs with maps in the example) but the error pops up when creating a new window later on..

Edit2: Just today others are signaling the same on the GMaps forum: Here (http://groups.google.com/group/Google-Maps-API/browse_thread/thread/f41fd1310c33b26c/bd10b7bb1669cb60?lnk=gst&q=GOverviewMapControl#bd10b7bb1669cb60)

IT100
10 Apr 2009, 4:13 AM
Hi all.

I've got my gmap running using the Ext.ux.GMapPanel.js extension.

Problem: the gmap tiles don't render at the bottom. I get a gray area.

if I collapse/expand the west panel all is displayed correct.

Can't seem to get it tiled from start!!


code:





Ext.onReady(function(){

//set long, lat, zoom
var googleSetCenterLng = <?=$lng;?>;
var googleSetCenterLat = <?=$lat;?>;
var googleZoomlevel = <?=$zoom;?>;

var viewport = new Ext.Viewport({
id:'Viewport',
contentEl:'viewPort',
layout:'tdgi_border',
items:[


/*
{
region:'north',
id:'north-panel'
},
{
region:'south',
id:'south-panel'
},
{
region:'east',
id:'east-panel'
},

*/
{
region:'west',
id:'west-panel',
contentEl:'gridData',
title:'iloveo.be',
split:true,
width: 340,
minSize: 175,
collapsible: true,
margins:'0 0 0 0',
layout:'accordion',
collapsedTitle: {
element : {
tag : 'img',
src : 'http://www.a-place-to-be.be/images/info-zoekopties.png'
}
},
layoutConfig:{
animate:true
}

,
items: [
{
id:'dataGridAcPa',
title:'Gegevens - index',
border:false,
iconCls:'house',
layout:'fit',
xtype:'gridEngine'
}]
},
new Ext.TabPanel({
region:'center',
id:'center-panel',
deferredRender:false,
activeTab:0,
items:[{
contentEl:'googleMap',
id: 'gMapContainer',
iconCls:'map-go',
title: 'Gegevens - map',
xtype: 'gmappanel',
region: 'center',
gmapType: 'map'
},{
contentEl:'slideshow',
id: 'Slideshow',
title: 'Slideshow',
iconCls: 'movie',
closable:false,
autoScroll:false
}]
})
]
});




// globals & defaults after viewport creation:
mapControl = getMapControls(); // uses gmapcontrols.js

// set proper map controls and positions:
gMapContainer = Ext.getCmp('gMapContainer');
gMapContainer.gmap.setCenter(new GLatLng(googleSetCenterLat, googleSetCenterLng), googleZoomlevel);
gMapContainer.gmap.addControl(new GLargeMapControl());
gMapContainer.gmap.addControl(mapControl);

// set panels default.
Ext.getCmp('west-panel').expand();


Ext.getCmp('west-panel').on('collapse', function(){
viewport.render();
});

Ext.getCmp('west-panel').on('expand', function(){
viewport.render();
});

}); // end ext-on ready



Thanks for any kind help,

Regards,
chris.

VinylFox
10 Apr 2009, 1:33 PM
Why would you specify a contentEl when the panels body is a map?


{
contentEl:'googleMap',
id: 'gMapContainer',
iconCls:'map-go',
title: 'Gegevens - map',
xtype: 'gmappanel',
region: 'center',
gmapType: 'map'
}

Lets start by getting rid of that.

While were at it, this is bad form...

gMapContainer.gmap.setCenter(...)

I could decide to change that name 'gmap' at any time and leave you stuck with either no upgrade path or having to update your code references.

Do this instead...

gMapContainer.getMap().setCenter(...)

stolsma
11 Apr 2009, 12:14 AM
Found out that the problem with the adding of GOverviewMapControl is already in the buglist of the Google Map API team. The problem described there is 'GOverviewMapControl crashes if mod_overviewmapcontrol is already loaded', as we are seeing I presume.. ;)

Bug is described here (http://code.google.com/p/gmaps-api-issues/issues/detail?id=1206&q=apitype:Javascript&sort=-id&colspec=ID%20Type%20Status%20Introduced%20Fixed%20Summary%20Internal%20Stars). And the fix is ready but not yet in the newest release, you can subscribe to a email message if accepted and implemented..

ripun008
15 Apr 2009, 10:39 AM
If I specify the complete Address with Door Number, Street Name, City, State, Country Zip Code, it works fine.

But If I specify the default address as City, State, Country I'm getting the following pop-up message

The address provided has a low accuracy. Level 4 Accuracy (8 = Exact Match, 1 = Vague Match)


So Do I need to specify the complete address as Door Number, Street Name, City, State, Country Zip Code ?

Just reduce the accurary (say...accuray<3)...it should work fine for you

VinylFox
15 Apr 2009, 10:55 AM
Just reduce the accurary (say...accuray<3)...it should work fine for you

The minGeoAccuracy config was added to address this need.

http://code.google.com/p/ext-ux-gmappanel/source/detail?r=9

ripun008
15 Apr 2009, 12:18 PM
Great extension! I love it!

I wasn't able to get the panorama view to work when sending an address via the 'geoCodeAddr' config, but could get it to work when specifying latitude and longitude.

I looked through the code and I think I found the problem. Here are the changes I made to get it to work. There's surely a better way to accomplish this, but I think the changes at least demonstrate the problem.

I added the bolded green lines to the end of the addAddressToMap function:



}else{
point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear,true);
}
if (this.gmapType === 'panorama'){
this.gmap.setLocationAndPOV(point, {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom});
}
}
then, I included panorama stuff that just uses lat and 'long' into the else of the if statement that checks if the geoCodeAddr is set:



if (typeof this.setCenter === 'object') {
if (typeof this.setCenter.geoCodeAddr === 'string'){
this.geoCodeLookup(this.setCenter.geoCodeAddr);
}else{
if (this.gmapType === 'map'){
alert('---> '+this.setCenter.lat+', '+this.setCenter['long']);
var point = new GLatLng(this.setCenter.lat,this.setCenter['long']);
this.gmap.setCenter(point, this.zoomLevel);
}
if (typeof this.setCenter.marker === 'object' && typeof point === 'object'){
this.addMarker(point,this.setCenter.marker,this.setCenter.marker.clear);
}
if (this.gmapType === 'panorama'){
this.gmap.setLocationAndPOV(new GLatLng(this.setCenter.lat,this.setCenter['long']), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoom});
}
}
}



Hello,
I used the ExtJS code on this forum to create google maps. The problem which i am facing is that when i supply lat/longs i get the street view sometimes and sometimes i don't.
If i supply the geocodeAddress then i get the following error:


this.getMap().setCenter is not a function
http://localhost:1586/Versentia.Web.UI/extjs/Ext.ux.GMapPanel.js
Line 150

addMarker()((40.746541, -74.045474) $e=40.746541 Na=-74.045474 x=-74.045474 y=40.746541, Object title=Rips Home, undefined, true, undefined)Ext.ux.G...pPanel.js (line 150)
addAddressToMap()(Object name=70 bowers st, jersey city, NJ, 07307, USA)Ext.ux.G...pPanel.js (line 235)
createDelegate()()Ext.js (line 720)
f()(Object name=70 bowers st, jersey city, NJ, 07307, USA)MRn4KKV4...uQA%3D%3D (line 1)
$r()()main.js (line 1035)
geo?output=json&oe=utf-8&q=70%20bowers%20st%2C%20jersey%20city%2C%20NJ%2C%2007307%2C%20USA&key=ABQIAAAAltYAoyDSwiTZmjQlkmGRgxTRW_qX1wy5EeIC8NpwVKekweLPZBTjheK5cy1YVpQRC758QwBIHTvbRw&callback=_xdc_._2ftkgemuq()()geo?outp...2ftkgemuq (line 20)

chrome://firebug/content/blank.gif this.getMap().setCenter(point, this.zoomLevel);
What i am doing is that first i am loading the google maps in a panel and below it i am loading the street view in a different panel. code where I am including street-view which is as follows:

streetViewPanel = new GMapPanel(new GMapPanelConfig()
//.setCenter(latlongs)
.setCenter(center)
.yaw(-180)
.pitch(-15)
.zoomLevel(1)
.gmapType("panorama")
.width(800)
.height(250)
.autoShow(true)
.border(true)
.ToDictionary());I even put a delay after the google map gets loaded so that the street view may load properly but still i get the same problem (soometimes loading and sometimes not).
Besides I also modified the code as you had suggested but no luck yet.
If you want me to put some portion of the code which you think might be a problem then do let me know.
I would appreciate if one of you great Ext guys could tell me where I am going wrong.

Thanks in advance

stolsma
15 Apr 2009, 3:23 PM
this.getMap().setCenter is not a function
http://localhost:1586/Versentia.Web.UI/extjs/Ext.ux.GMapPanel.js
Line 150
<snip> .. <snip>

I even put a delay after the google map gets loaded so that the street view may load properly but still i get the same problem (soometimes loading and sometimes not).


It looks like this problem is also related to the asynchronous loading of the different google.maps javascript modules (the guys down at google try to modularize their code to get a performance upgrade...) and as such not an Ext problem but probably a GMaps bug. (for me the 'this.getMap().setCenter is not a function' looks like the '...show() function does not exists' error for GMapControl described here earlier). BTW Saw a lot of bug related to asynchronous module loading in de GMaps buglist... But maybe someone else has another opinion ???

Hope to have a look at this tomorrow, have to fix an almost hacked server first... (:|

ripun008
16 Apr 2009, 5:56 AM
thanks for your reply. I would appreciate if you could look into this issue when you get time. Any other suggestion guys?

Thanks in advance

VinylFox
17 Apr 2009, 3:57 AM
Hello,
I used the ExtJS code on this forum to create google maps. The problem which i am facing is that when i supply lat/longs i get the street view sometimes and sometimes i don't.
If i supply the geocodeAddress then i get the following error:
[code][COLOR=Red]
this.getMap().setCenter is not a function
http://localhost:1586/Versentia.Web.UI/extjs/Ext.ux.GMapPanel.js
Line 150

Geocoding addresses for the panorama view has not been implemented, that's why your receiving this error. There is NO setCenter function for a panorama map, the viewing location must be set by using setLocationAndPOV, which my geocoding handler does not support.

VinylFox
17 Apr 2009, 4:03 AM
It looks like this problem is also related to the asynchronous loading of the different google.maps javascript modules...[snip]...for me the 'this.getMap().setCenter is not a function' looks like the '...show() function does not exists' error for GMapControl described here earlier). BTW Saw a lot of bug related to asynchronous module loading in de GMaps buglist... But maybe someone else has another opinion ???

I just have to address this post so people that come across it do not get misguided...

This has nothing to do with asynchronous loading, and nothing to do with the GMapControl problem explained earlier. ripun008 simply tried to call a function on a map type that does not support that method, hence the "not a function" error.

IT100
18 Apr 2009, 8:11 AM
thanks for the advice vinylFox, Ive changed the code to your suggestion but the googlemap still isn't showing in its full display.

here's the url

http://www.iloveo.be/navigate

thanks for your kind help.

chris.

:-?:-?

GobbaF
20 Apr 2009, 12:03 PM
thanks for the advice vinylFox, Ive changed the code to your suggestion but the googlemap still isn't showing in its full display.

here's the url

http://www.iloveo.be/navigate

thanks for your kind help.

chris.

:-?:-?

Just put your gmappanel inside another panel with layout set to 'fit' so your code starts off like this:



items: {
region: 'center',
xtype: 'tabpanel',
activeTab: 0,
items: {
layout: 'fit',
items: {
title: 'Gegevens map',
xtype: 'gmappanel',

IT100
20 Apr 2009, 10:54 PM
Just put your gmappanel inside another panel with layout set to 'fit' so your code starts off like this:



items: {
region: 'center',
xtype: 'tabpanel',
activeTab: 0,
items: {
layout: 'fit',
items: {
title: 'Gegevens map',
xtype: 'gmappanel',

Thanks GobbaF!

Just reflecting how delicate these items are. I've been working with extjs for some 6 months now, on regular basis. Used all the major parts, but I still get stuck on these issues. Maybe I should re-examin DOM stuff or so. Anyway thanks for your kind help!

regards,
Chris.

Working code:




new Ext.TabPanel({

region:'center',

id:'center-panel',

xtype:'tabpanel',

deferredRender:false,

activeTab:0,

items:[{

layout:'fit',

iconCls:'map-go',

title:'Gegevens - map',

items:{

id:'gMapContainer',

xtype:'gmappanel',

gmapType:'map'}

},{
id:'Slideshow',

title:'Slideshow',

iconCls:'movie',

closable:false,

autoScroll:false

}]
})

treadmill
22 Apr 2009, 4:16 AM
I'm having problems with the setCenter parameter, using lat,lng. However, if I use geoCodeAddr, it works just fine.

The the marker (mrk variable) never gets loaded when using lat,lng, but does when using geoCodeAddr. Any ideas as to why this is?

I've downloaded the latest version of Ext.ux.GMapPanel.js, as of today.



Ext.onReady(function() {
Ext.BLANK_IMAGE_URL = '/extjs/resources/images/default/s.gif'; // Ext 2.0

var mrk = { marker: {
title: 'Bangers'
},
lng: "-0.08628129959106445",
lat: "51.51898470926469",
winebar: "Bangers",
address: "Eldon House, 2-12 Wilson Street EC2M 2TE",
telephone: "0207 377 6326",
livebooking: "109079",
listeners: {
click: function(e){
Ext.Msg.alert("Bangers");
}
}
};

new Ext.Viewport({
layout: 'border',
items: [{
region: 'north',
html: '<div style="background-color:#FFFFFF;"><img src="/images/logo.gif" width="191" height="53" style="margin:8px; border:0px;" /></div>',
height:53,
autoHeight: true,
border: false,
margins: '0 0 0 0'
}, {
id: 'product_tree',
region: 'west',
collapsible: true,
title: 'Davy&rsquo;s Winebars',
xtype: 'treepanel',
width: 300,
autoScroll: true,
split: true,
loader: new Ext.tree.TreeLoader(),
root: new Ext.tree.AsyncTreeNode({
text: 'Product catalogue',
expanded: true,
"children": [{
"id": 1,
"text": 'A leaf Node',
"leaf": true},
{
"id": 2,
"text": 'A folder Node',
"children": [{
"id": 3,
"text": 'A child Node',
"leaf": true
}]
}]
}),
rootVisible: true,
listeners: {
click: function(n) {
Ext.Msg.alert('Navigation Tree Click', 'You clicked: "' + n.attributes.text + '"');
}
}
}, {
region: 'center',
xtype: 'panel',
layout: 'fit',
id: 'winebar-map',
title: 'Google map',
items: {
contentEl: 'gmap',
xtype: 'gmappanel',
zoomLevel: 2,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
setCenter: {
lat:51.502759,
lng:-0.126343
//,geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
//marker: {title: 'Fenway Park'}
},
markers: [mrk]
}
}, {
region: 'south',
collapsible: false,
html: '<div class="footer">Copyright &copy; 2008-2009 Davy &amp; Co Limited. All rights reserved.</div>',
split: false,
height: 25,
minHeight: 25,
margins: '0 0 0 0'
}]
});
});

davidrolli
22 Apr 2009, 5:48 AM
It seems to me that this bug reported and "fixed" (http://extjs.com/forum/showthread.php?t=40534&page=2) is back!? Controls are not displayed when I set the lat/lng instead of geoCodeAddr.



if(!mapwin){
mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width: 400,
height: 400,
x: 300,
y: 160,
items: {
xtype: 'gmappanel',
region: 'center',
gmapType: 'map',
zoomLevel: 16,
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
setCenter: {
lat: 47.48249575527873,
lng: 7.745361328125,
marker: {
title: 'Gartenbad Liestal'
}
}
}
});
}

treadmill
22 Apr 2009, 5:51 AM
I'm glad (in a way) that someone else (davidrolli) is experiencing my exact problem I reported just before his post. Any fix to this?

VinylFox
22 Apr 2009, 6:17 AM
Im looking into it now. In the middle of adding a few new samples, error messages and locale support, so once I get through that ill be able to debug this problem in more detail.

treadmill
22 Apr 2009, 6:22 AM
That's great, looking forward to a fix. B)

Im looking into it now. In the middle of adding a few new samples, error messages and locale support, so once I get through that ill be able to debug this problem in more detail.

whdanj
23 Apr 2009, 5:09 AM
Load JsonStore data into gmappanel?

It is great to find this thread about the GMapPanel, I just started to use GMapPanel in my Ext application, could anyone help me this?

I have a jsonStore, which stores the data returned from server, all rows include a Latitude and Longitude, how can i load all the data into the Ext gmappanel,

Do I need to convert my JsonStore data into KML format, then load into gmappanel?
or can I load from JsonStrore into gmappanel directly?

An example would be great. Thank you very much!

treadmill
24 Apr 2009, 5:08 AM
Is there any news on a fix for this?


Im looking into it now. In the middle of adding a few new samples, error messages and locale support, so once I get through that ill be able to debug this problem in more detail.

whdanj
27 Apr 2009, 5:39 AM
I figure it out and post here for the beginners like me:

I create an array from jsonstore:

var mk_array = sourceStore.getRange();

then in gmappanel:


{
xtype: 'gmappanel',
region: 'center',
//zoomLevel: 14,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],

setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},

markers: mk_array
}

Then the data can be passed into "addMarkers" function and each mark is added into the google map.




Load JsonStore data into gmappanel?

It is great to find this thread about the GMapPanel, I just started to use GMapPanel in my Ext application, could anyone help me this?

I have a jsonStore, which stores the data returned from server, all rows include a Latitude and Longitude, how can i load all the data into the Ext gmappanel,

Do I need to convert my JsonStore data into KML format, then load into gmappanel?
or can I load from JsonStrore into gmappanel directly?

An example would be great. Thank you very much!

nctag
28 Apr 2009, 2:07 AM
I'm currently testing this extension with Ext 3.0. I haven't find any issues up to now. So I want to ask you whether am I really right? Does this extension fully work with current Ext 3.0 SVN version?

VinylFox
28 Apr 2009, 6:07 AM
I cant think of any reason it wouldn't work with 3.x. It extends Panel which has largely stayed the same, minus bug fixes and some additions for fbar and whatnot.

Ive actually been using 3.x to test my new samples and other updates, and I haven't run into any problems yet.

nctag
28 Apr 2009, 6:31 AM
Thank you VynylFox for your confirmation. I also took a look at the code with the same finding. Maybe it would help to write it down in the title or at least in the entire post of the thread. This would help the next users how will be asking (themselves) the same again.

treadmill
29 Apr 2009, 1:37 AM
Is there a fix for using lat/lng with setCenter yet?

VinylFox
29 Apr 2009, 11:59 AM
@treadmill - I haven't had the free time to figure this out lately, please feel free to debug yourself and post any findings, I can almost guarantee it will help lead to a solution.

ripun008
30 Apr 2009, 7:30 AM
This has nothing to do with asynchronous loading, and nothing to do with the GMapControl problem explained earlier. ripun008 simply tried to call a function on a map type that does not support that method, hence the "not a function" error.


I tried to pass the lat/long also into the street view but still i get the same problem (sometimes loading and sometimes not). What would be the possible solution in your opinion?

VinylFox
30 Apr 2009, 8:05 AM
@ripun008 - im not sure why you quoted my response to @stolsma, its un-related to your problem.

As for your problem, I really cant do much unless you provide an example. At the very least you could provide the lat/lng/yaw/pitch/zoom so I could try it in my examples.

rubyaryat
1 May 2009, 11:06 AM
I had a similar issue with the controls not displaying on the map when configuring map with setCenter using lat and lng.

As a workaround I added a call to the addMapControls function after setCenter (line 63 Ext.ux.GMapPanel.js), which resolved my problem:


if (this.gmapType === 'map'){
var point = new GLatLng(this.setCenter.lat,this.setCenter.lng);
this.gmap.setCenter(point, this.zoomLevel);
this.addMapControls();//rubyaryat
}Rubyaryat

VinylFox
1 May 2009, 11:49 AM
@rubyaryat - Thank you very much for finding the problem, I love the fact that your first post on the forums is to help fix a problem - wish there were more like you out there.

I have fixed it in my code (slightly different approach from yours, but same idea/problem) and update Google code with the new version.

http://code.google.com/p/ext-ux-gmappanel/source/detail?r=18

Thanks again rubyaryat

davidrolli
4 May 2009, 10:44 PM
Hi VinylFox,

I tried your new Version rt16 of Ext.ux.GMapPanel.js and got the error 'G_GEO_BAD_REQUEST is not defined'!

Any tips ?

Thanks in advance David

VinylFox
5 May 2009, 4:27 AM
That error code is one of three new codes that was added to the Google Maps API in version 2.81, if your using a version below that then you will get the error your seeing.

There are two options for you...

1) Grab the fix I committed just now, which defines those three constants statically.
2) Update your Google Maps API include to use "v=2.x" or "v=2" instead of "v=2.0"

davidrolli
5 May 2009, 4:55 AM
... and include Google Maps API before your extension 8-|.

Thanks a lot, works now as it should !

David

ripun008
6 May 2009, 7:15 AM
sry vinylfox i quoted you by mistake. I have now got the problem fixed. I will upload my work pretty soon so every one can have a look at it and also give their feedback on the same.

VinylFox
6 May 2009, 7:49 AM
sry vinylfox i quoted you by mistake. I have now got the problem fixed. I will upload my work pretty soon so every one can have a look at it and also give their feedback on the same.

Im guessing you put a check in the addAddressToMap handler to check the gmapType and decide to use either setCenter or setLocationAndPOV ?

Be sure to add the appropriate error codes as well.

see: GStreetviewClient (http://code.google.com/apis/maps/documentation/reference.html#GStreetviewClient)


Load JsonStore data into gmappanel?

...

An example would be great. Thank you very much!

Ok, here ya go: http://code.google.com/p/ext-ux-gmappanel/source/browse/trunk/examples/fullscreen/border-layout.js

ripun008
6 May 2009, 3:13 PM
yes Vinyl Fox i pretty much did the same. I did not use the setCenter method but instead used setLocationAndPOV to get the street view and it worked for me.

ripun008
7 May 2009, 5:54 AM
Have a look at the attached file. It has the StreetView support as well as basic map functionalities. I basically modified Vinyl Fox's code to enable the street view.

* Changes Made:
* (1) Street View on the click of a marker
* (2) Takes an Array of addresses from a JSon Store and maps them using AddMarkers
* (3) Each marker can be removed on right-click
* (4) Error code can checked (I have not done an extensive checking as i don't need it as of now)

Any suggestions/bug detection would be appreciated B):s

13492
Screenshot: 13493

stolsma
8 May 2009, 6:42 AM
Found out that the problem with the adding of GOverviewMapControl is already in the buglist of the Google Map API team. The problem described there is 'GOverviewMapControl crashes if mod_overviewmapcontrol is already loaded', as we are seeing I presume.. ;)

Bug is described here (http://code.google.com/p/gmaps-api-issues/issues/detail?id=1206&q=apitype:Javascript&sort=-id&colspec=ID%20Type%20Status%20Introduced%20Fixed%20Summary%20Internal%20Stars). And the fix is ready but not yet in the newest release, you can subscribe to a email message if accepted and implemented..

The bug described in the quote is solved in GMap version 2.155 implemented April 29. Tested it with my own application and everything works as normal again with multiple dynamic maps with GOverviewMapControl.

Jangla
19 May 2009, 4:21 AM
Have a look at the attached file. It has the StreetView support as well as basic map functionalities. I basically modified Vinyl Fox's code to enable the street view.

* Changes Made:
* (1) Street View on the click of a marker
* (2) Takes an Array of addresses from a JSon Store and maps them using AddMarkers
* (3) Each marker can be removed on right-click
* (4) Error code can checked (I have not done an extensive checking as i don't need it as of now)

Any suggestions/bug detection would be appreciated B):s

13492
Screenshot: 13493

Any guidance on the format of the expected JSON? Also, a working example of a JSON version would be a great help so we can see how you've called everything.

Jangla
19 May 2009, 6:34 AM
Also, while I think about it, has anyone had any success using custom marker images with this extension? I've currently playing around with it but it doesn't seem to like me setting the baseIcon where I'd expect it to be defined.

abraxxa
20 May 2009, 5:44 AM
@abraxxa - can you test the code I just committed and let me know what you find.

UPDATED CODE! -> http://code.google.com/p/ext-ux-gmappanel/

@VinylFox: sorry for the huge delay, but I had to work on other parts of the app first.
I assume you mean r5 in the repo?!
Using an address as center location might be useful but not for what I'm doing.
If you look at my patch again you will see that a center point plus zoom factor is calculated to show all markers added to the map.

Jangla
20 May 2009, 7:58 AM
Ok, here ya go: http://code.google.com/p/ext-ux-gmappanel/source/browse/trunk/examples/fullscreen/border-layout.js
Strictly speaking, that's not an example of loading the map markers in via JSON - it's an example of loading a side bar with results using JSON.

So, does anyone have a working JSON example, replete with the necessary php to output the JSON string?

VinylFox
20 May 2009, 8:56 AM
Strictly speaking, that's not an example of loading the map markers in via JSON - it's an example of loading a side bar with results using JSON.

So, does anyone have a working JSON example, replete with the necessary php to output the JSON string?

Yeah, let me just got ahead and write all the code for you.

The example your referring to has all the required bits and pieces to load a map with markers from a store. Be creative.

VinylFox
20 May 2009, 9:00 AM
Also, while I think about it, has anyone had any success using custom marker images with this extension? I've currently playing around with it but it doesn't seem to like me setting the baseIcon where I'd expect it to be defined.

Care to share any of your config with us, so we might have some idea what your trying to do and where its gone wrong? A sentence describing your code is useless to anyone trying to help.

Jangla
20 May 2009, 10:21 AM
Yeah, let me just got ahead and write all the code for you.

The example your referring to has all the required bits and pieces to load a map with markers from a store. Be creative.

Fair enough, although will it literally accept any format/order of data items in the JSON response?


Care to share any of your config with us, so we might have some idea what your trying to do and where its gone wrong? A sentence describing your code is useless to anyone trying to help.
Solved it - at least in a minor way. At the moment I've added a little code to chuck in a custom marker but my intention is to make the marker image more dynamic i.e. in my case it will be a flag representing the country in which the marker resides.

Happy to post code now or when it's finished if anyone is interested.

VinylFox
20 May 2009, 10:41 AM
will it literally accept any format/order of data items in the JSON response?

Not quite sure I understand what your asking for, but were just talking about loading a store with data and looping through each item in the store to place a marker on the map.

ie: (completely un-tested, just off the top of my head here)


myMap = [YOUR GMAP];

myMarkers = new Ext.data.JsonStore({
fields: ['lat', 'lng', 'marker', 'bla', 'bla'],
url: 'mymarkers.php',
root: 'Data',
id: 'ID'
});

myMarkers.on('load', function(){
myMarkers.each(function(rec){
myMap.addMarker(new GLatLng(rec.data.lat, rec.data.lng, rec.data.marker);
});
});

myMarkers.load();




At the moment I've added a little code to chuck in a custom marker but my intention is to make the marker image more dynamic i.e. in my case it will be a flag representing the country in which the marker resides.

You should just be able to create a marker object (just like Google Maps takes) and pass it in the 'marker' config of each item in your array of points. The google maps API has details on the format of the marker object. Or console.log(G_DEFAULT_ICON) to see the general format.

VinylFox
21 May 2009, 2:34 AM
Thanks for posting your code, that makes it much easier to help debug. So lets start with a basic fix here...


myMarkers.load();
var mk_array = myMarkers.getRange();
myMap = Ext.getCmp('property-map');
myMap.addMarkers(mk_array);

The keyword here is "asynchronous"

On line one, your asking the store to load, which makes a request to the server in the background, letting your code continue on to line two. At line two your asking for the data back from your store, only problem is that your server side script that returns the data is still diddling around in the background formatting the data and whatnot, so it has not been sent back to the store from the server yet. This is why we use events to determine when the data has returned and been loaded into the store.


myMarkers.on('load', function(){
var mk_array = myMarkers.getRange();
myMap = Ext.getCmp('property-map');
myMap.addMarkers(mk_array);
});
myMarkers.load();


On to problem number two. Each of your data items looks like this:


{"id":"3331","propertyname":"Property 1","lat":"47.227081","lng":"0.915441"}

Now addMarkers has no idea what "propertyname" is, or even "id". Thats why my example loops through the data in the store, that way im able to format each item. This will need to be formatted into something that addMarkers can understand. At the least, the above method should load up default style markers with no title.

Jangla
21 May 2009, 2:43 AM
Sorry, deleted my post when I realised I needed a callback - 2 mins before you posted.

Hadn't noticed the other issue you've picked up on though - still working out how to best get the markers added only when the map is loaded. As the map is on a tab that's not active on load, I think my best option is to add it to the tabchange event of the tab panel and check for the right tab.

But what you're essentially saying is that each record in the JSON should look more like this:



{"lat":"47.227081","lng":"0.915441","marker":"{title: 'Property 1'}"}

Jangla
21 May 2009, 4:37 AM
@VinylFox: sorry for the huge delay, but I had to work on other parts of the app first.
I assume you mean r5 in the repo?!
Using an address as center location might be useful but not for what I'm doing.
If you look at my patch again you will see that a center point plus zoom factor is calculated to show all markers added to the map.
I've had a look at what I think is the latest code and can't find this functionality in it.

Also, I have a feature request: use the gmap marker manager for better preformance when there are lots of markers.

Jangla
22 May 2009, 7:11 AM
I've noticed that performance suffers when you get to around 50 or 60 markers or more - it basically hangs the browser until it's done rendering all the markers. I've a requirement to render at least 150 and this will hopefully scale dramatically.

Having a look around at various non-Ext version of gmaps (in particular I'm looking at integrating a progress bar from the open source projects here: http://code.google.com/p/gmaps-utility-library-dev/source/browse/#svn/trunk), a lot of developers have used the following code methodology to give the thing a more responsive render (this snippet is from the code repository of the progress bar I'm trying to implement):



var map;
var progressBar;

function load() {
map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(52, 4), 7);
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
progressBar = new ProgressbarControl(map, {width:150});
}

var markersArray = [];
var maxNum = 200;
var num = 0;

function loadMarkers(){
progressBar.start(maxNum);
setTimeout('createMarker()', 10);
}

function createMarker(){
num++;
progressBar.updateLoader(1);

var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
var latlng = new GLatLng(southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random());
var marker = new GMarker(latlng);
markersArray.push(marker);
map.addOverlay(marker);

if (num < maxNum) {
setTimeout('createMarker()', 10);
} else {
progressBar.remove();
num = 0;
}
}


function removeMarkers(){
progressBar.start(markersArray.length);
setTimeout("removeMarker()", 10);
}


function removeMarker(){
progressBar.updateLoader(1);
map.removeOverlay(markersArray.pop());
if (markersArray.length > 0) {
setTimeout("removeMarker()", 10);
} else {
progressBar.remove();
}
}



Basically the code example creates a number of random markers and uses a self-calling setTimeout call to render each marker. Only thing is, I'm struggling to work out how (or even if) this could be achieved in the current gmap extension. A push in the right direction would be a great help.

If anyone is interested in the progress bar code as a whole and would like to see the rendering happening without hanging the browser (in case it helps the future dev of this extension), it's here: http://gmaps-utility-library-dev.googlecode.com/svn/trunk/progressbarcontrol/examples/markerloader.html

LouiSe
25 May 2009, 8:13 AM
I've found a nice example to zoom and fit all markers on map: http://911-need-code-help.blogspot.com/2009/03/zoom-to-fit-all-markers-polylines-or.html

Could you extend this ux with this feature?



// map: an instance of GMap2
// latlng: an array of instances of GLatLng
var latlngbounds = new GLatLngBounds();
for (var i = 0; i < latLng.length; i++) {
latlngbounds.extend(latlng[i]);
}
map.setCenter(latlngbounds.getCenter(), map.getBoundsZoomLevel(latlngbounds));

achebe
4 Jun 2009, 1:56 PM
I had some trouble with the map resizing properly in an Ext.Window until I flipped the order of the onResize and setSize functions to call checkResize() after the call to the GMapPanel's superclass. I didn't really dig into it but it seems to have fixed my resize issues.

Any change of adding a mapReady event to the onMapReady method? I needed to hook in to the click event for the map and ended up overriding that function so that I could use GEvent.bind(), an event to hook into would be much nicer.

Thanks,
Chris

Jangla
5 Jun 2009, 12:59 AM
Has anyone else noticed a problem with the code that automatically set the zoom and bounds levels to the markers on the map? The code itself seems sound, but the map seems to behave as if it's unaware of the bottom half of itself. I always end up with the map zoomed to the point that the markers are all visible in the top half of the map. :-/

abraxxa
5 Jun 2009, 8:20 AM
That does exactly what I have coded month ago but it wasn't included by VinylFox. :(

Jangla
5 Jun 2009, 8:23 AM
That does exactly what I have coded month ago but it wasn't included by VinylFox. :(
If that's a response to my post then I'd be relieved if I were you - it doesn't work properly :D

Still trying to figure it out but having done the odd stand alone gmap before I think it's something to do with the map not being properly aware of it's size and position in the window - google's code is pretty famously crap at that particular aspect and usually has to be forced to realise it's surroundings.

abraxxa
5 Jun 2009, 8:32 AM
No that was @LouiSe (http://extjs.com/forum/member.php?u=41513)

VinylFox
7 Jun 2009, 5:53 AM
I had some trouble with the map resizing properly in an Ext.Window until I flipped the order of the onResize and setSize functions to call checkResize() after the call to the GMapPanel's superclass. I didn't really dig into it but it seems to have fixed my resize issues.

Not seeing this problem, but in theory I understand why it would happen. I have committed this change (http://code.google.com/p/ext-ux-gmappanel/source/detail?r=22), but can I get your example of this problem to verify it?


Any change of adding a mapReady event to the onMapReady method? I needed to hook in to the click event for the map and ended up overriding that function so that I could use GEvent.bind(), an event to hook into would be much nicer.

Sounds like a great idea, I have committed this change. (http://code.google.com/p/ext-ux-gmappanel/source/detail?r=21)

VinylFox
7 Jun 2009, 5:58 AM
Has anyone else noticed a problem with the code that automatically set the zoom and bounds levels to the markers on the map? The code itself seems sound, but the map seems to behave as if it's unaware of the bottom half of itself. I always end up with the map zoomed to the point that the markers are all visible in the top half of the map. :-/
An example of your problem would help us help you.

achebe
9 Jun 2009, 7:45 AM
I had some trouble with the map resizing properly in an Ext.Window until I flipped the order of the onResize and setSize functions to call checkResize() after the call to the GMapPanel's superclass. I didn't really dig into it but it seems to have fixed my resize issues.With this code when I maximize the window the map doesn't resize to fit the window, I'm guessing it's because the window hasn't been sized yet?




<html>

<head>
<!--- google maps API --->
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" type="text/javascript"></script>


<link rel="stylesheet" type="text/css" media="screen" href="/ext-2.0-svn/resources/css/ext-all.css"></link>
<link id="theme" rel="stylesheet" type="text/css" media="screen" href="/ext-2.0-svn/resources/css/xtheme-gray.css"></link>
<script type="text/javascript" src="/ext-2.0-svn/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="/ext-2.0-svn/ext-all-debug.js"></script>

<script type="text/javascript" src="Ext.ux.GMapPanel.js"></script>
</head>

<body>
<script>
Ext.onReady(function(){

var stage = new Ext.Viewport({layout:'fit'});

var win = new Ext.Window({
layout: 'fit',
title: 'Map of Project ',
width: 640,
height: 480,
resizable: true,
renderTo:stage.getEl(),
minimizable: true,
maximizable: true
});

var map = win.add({
xtype: 'gmappanel',
zoomLevel: 14,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom', 'enableDoubleClickZoom', 'enableDragging'],
mapControls: ['GSmallMapControl', 'GMapTypeControl', 'NonExistantControl'],
setCenter: {
lat: 64.344,
lng: -149.186,
marker: {
title: 'Project'
}
}
});

win.center().show();

});
</script>
</body>

</html>
Sounds like a great idea, I have committed this change. (http://code.google.com/p/ext-ux-gmappanel/source/detail?r=21)Great!

Thanks,
Chris

nikhilkrishnan
25 Jun 2009, 2:45 AM
Hi,

I am getting a GMap2 undefined error when opening the gpanel in IE. It works fine with FF.

fsa3
30 Jun 2009, 6:39 PM
Great Extension.

One question, how do I add functionality so that when I click a marker a 'popup' appears with additional information?

Is this done by creating the marker object using the standard Google API and passing it to addMarker?

Thanks.

Jangla
7 Jul 2009, 1:47 AM
An example of your problem would help us help you.

I think it's more down to the way I've implemented the function:



zoomToMarkers : function() {

this.getMap().checkResize();
var bounds = new GLatLngBounds();
for (var i=0; i< points.length; i++) {
bounds.extend(points[i]);
}

this.getMap().setCenter( bounds.getCenter( ), this.getMap().getBoundsZoomLevel( bounds ) );

},


Naturally I've added a points array at the top of the module to hold the points for each marker.

bounds seems to say undefined but throws no error and contains the default bounds settings of the whole world map.

Didn't you mention earlier in the thread that zoom to markers functionality was added to the code? I can't find it anywhere so had to add the above myself....and I still can't get it to work :D

Also, the GMapPanel code doesn't seem to add the GUnload function to the body unload event - this may result in memory leaks.

luisparada
7 Jul 2009, 10:52 PM
Hello, I'm trying to set the hibrid map by default, but I just cant, how can I do this?, and Iam also trying to add the markers information just like google, I dont want the extjs to create Ext.msg boxes or stuff, I want google API to work with this.
Thanks

The Transporter
13 Jul 2009, 7:32 AM
When you have to display many markers on a map, it's better to use the marker manager provided by google.

I've set it up here: http://pol-dev.be/where/index3.php

It's a WIP !

sabiola
15 Jul 2009, 11:44 PM
Hello,

how can I recenter the map to a new position using Lat/Lng?

Thanks for your help,
Stefan

VinylFox
22 Jul 2009, 7:56 AM
how can I recenter the map to a new position using Lat/Lng?

Im not trying to be a jerk here, but you could have found this out by searching the forums, reading through this thread, or looking at the examples that come with this UX (http://code.google.com/p/ext-ux-gmappanel/source/browse/trunk/examples/advanced/recenter-map.js?spec=svn22&r=22). Please do that first, then I will be happy to address any other questions you have.

cyfl
23 Jul 2009, 4:33 AM
Hello !

I woul'd like to know if it's possible to do this :
http://gmaps-samples.googlecode.com/svn/trunk/gdirections/directions-static.html

generate the direction, time and Km, between two points.

Thanks !

abraxxa
23 Jul 2009, 7:22 AM
@VinylFox: are you planning to include my changes to center the map based on multiple markers or not?

VinylFox
23 Jul 2009, 7:30 AM
@VinylFox: are you planning to include my changes to center the map based on multiple markers or not?

Not sure what your referring to, so apparently I overlooked it. I would love to include any changes you might have, so could you please refresh my memory about what exactly the changes are?

abraxxa
23 Jul 2009, 7:38 AM
This one:
http://extjs.com/forum/showthread.php?p=247895#post247895

VinylFox
23 Jul 2009, 7:39 AM
I woul'd like to know if it's possible to do this :
http://gmaps-samples.googlecode.com/svn/trunk/gdirections/directions-static.html

generate the direction, time and Km, between two points.

Yes, its possible, using the getMap handler that my UX provides.

For example, the code on that page:


map = new GMap2(document.getElementById("map_canvas"));
gdir = new GDirections(map, document.getElementById("directions"));

Would be updated to look something like this:


map = Ext.getCmp('your_map_cmp_id').getMap();
gdir = new GDirections(map, Ext.get("directions"));

You would need to account for timing as well, making sure this code was executed only after the map is available. Check out the 'mapready' event in my UX.

The Transporter
28 Jul 2009, 1:32 AM
Any news on porting it on the new Google Map API (V3) ?

Thanks :)

VinylFox
28 Jul 2009, 5:41 AM
Any news on porting it on the new Google Map API (V3)

Im hoping to do that soon - my friend was working with the V3 API as I peered over his shoulder last week, and it seems like they have made some great improvements.

My backlog list for this UX is getting longer and longer every day, so Im not sure what the time line is like for this change. Also wondering if I need to branch this UX to have a GMap API v2 and v3 versions.

Feel free to make changes and post them back here so I can integrate them with the main UX.

presedo
7 Aug 2009, 3:38 PM
I'm trying to get an example where a listener is apply to the map and not only to markers. All examples I have seen have listeners applied to markers, to generate a popup.

I want to let users to click anywhere on maps, and a new marker appears on it.

Before EXTJS, I was using an JS code like this :



GEvent.addListener(map, 'click', function(overlay, point) {
if (prev_pin) {
map.removeOverlay(prev_pin);
prev_pin = null;
}
if (point) {
pin = new GMarker(point);
map.addOverlay(pin);
prev_pin = pin;

document.form.gps_lat.value = point.y;
document.form.gps_lng.value = point.x;
}
});
gps_lat and gps_lng are two hidden input that are receiving the gps position of the new marker.

Now, with ExtJS, I don't know how to set it up. I tried to add a listener to the map like this ...


{
xtype: 'gmappanel',
region: 'center',
zoomLevel: 14,
height : 200,
width : 849,
gmapType: 'map',
id: 'map',
listeners: {
click: function(e) {
Ext.Msg.alert('je click');
console.info(e);
},
},
[...]
},
... but it doesn't work.

FYI, the map is used as an item in a PanelForm ... maybe that's why .... The picture attached shows you how I used it...

Thanks for your help...

Matt Bittner
11 Aug 2009, 10:34 AM
Forgive the instrusion, but is there any documentation for this ux?

TIA!

VinylFox
11 Aug 2009, 11:10 AM
The documentation is included in the JS file in JSDoc format. You can use a tool called ext-doc to generate Ext style documentation from the JSDoc comments ive included.

Here is what the output looks like -http://www.vinylfox.com/docs/?class=Ext.ux.panel.GMapPanel

Matt Bittner
11 Aug 2009, 11:10 AM
Awesome, thanks!!

moegal
11 Aug 2009, 2:17 PM
I'm trying to get an example where a listener is apply to the map and not only to markers. All examples I have seen have listeners applied to markers, to generate a popup.

I want to let users to click anywhere on maps, and a new marker appears on it.

Before EXTJS, I was using an JS code like this :



GEvent.addListener(map, 'click', function(overlay, point) {
if (prev_pin) {
map.removeOverlay(prev_pin);
prev_pin = null;
}
if (point) {
pin = new GMarker(point);
map.addOverlay(pin);
prev_pin = pin;

document.form.gps_lat.value = point.y;
document.form.gps_lng.value = point.x;
}
});
gps_lat and gps_lng are two hidden input that are receiving the gps position of the new marker.

Now, with ExtJS, I don't know how to set it up. I tried to add a listener to the map like this ...


{
xtype: 'gmappanel',
region: 'center',
zoomLevel: 14,
height : 200,
width : 849,
gmapType: 'map',
id: 'map',
listeners: {
click: function(e) {
Ext.Msg.alert('je click');
console.info(e);
},
},
[...]
},
... but it doesn't work.

FYI, the map is used as an item in a PanelForm ... maybe that's why .... The picture attached shows you how I used it...

Thanks for your help...

Try adding the following override.



var originalAfterRender = Ext.ux.GMapPanel.prototype.afterRender;
Ext.override(Ext.ux.GMapPanel, {
initEvents: Ext.ux.GMapPanel.prototype.initEvents.createSequence(function(){
this.addEvents(
'click'
);
}),
afterRender: function(){
originalAfterRender.apply(this, arguments);
GEvent.bind(this.getMap(), 'click', this, this.onClick);
},
onClick: function(overlay, latlng, overlaylatlng){
this.fireEvent('click', overlay, latlng, overlaylatlng);
}
});


The listener would be 'click' with the following args: overlay, latlng, overlaylatlng
I think you are then looking for latlng.x and latlng.y

Marty

satishyl
28 Aug 2009, 7:50 AM
Hi,
I am using the GMapPanel extension and I have a strange problem. I am not sure if it is related to this extension but some of you may have faced the same situation. When I load the google map API with an invalid key (key generated for a different server), I get the error message "The Google Maps API server rejected your request..." but it continues to load the maps without any problem. How do I make it not load the maps when the error happens or not show the error message at all? Any help is very much appreciated.

Thanks,
Satish

VinylFox
28 Aug 2009, 8:19 AM
I use different keys for different domains/servers, so I have never run into this problem. It seems like the obvious solution is to generate a valid key for whatever domain your on.

You can scour the Google Maps API ref (http://code.google.com/apis/maps/documentation/reference.html) to see if you can find another solution.

Im also working on an updated GMapPanel for v3 of the Google Maps API, which does not require an API key. Should be out in a couple weeks.

satishyl
28 Aug 2009, 8:31 AM
Thanks Shea. I will wait for the updated API :).

shinkenno
31 Aug 2009, 10:08 AM
Hi everyone,

Firstly, thanks Shea for providing this VERY useful extension !

I am begining to play with GMapPanel extension since today. I was wandering how markers can be stored in an array (I want to extract these markers information dynamically from a database).

I have tried this very basic thing (in my file.js):


var mymarkers = new Array();

mymarkers[0] = new Array();
mymarkers[1] = new Array();

mymarkers[0]['lat']=0;
mymarkers[0]['lng']=0;
mymarkers[0]['listeners']='{click: function(e){Ext.Msg.alert("Its fine", "and it is art.");}}'

mymarkers[1]['lat']=0;
mymarkers[1]['lng']=90;
mymarkers[1]['marker']="{title: 'mytest'}";



then later in the viewport description:


...
layout: 'fit',
title: 'Network',
closeAction: 'hide',
width:600,
height:400,
items: {
xtype: 'gmappanel',
zoomLevel: 1,
gmapType: 'map',
id: 'network_map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GLargeMapControl3D','GMenuMapTypeControl','NonExistantControl'],
setCenter: {
lat: 0,
lng: 0
},
markers: mymarkers
...



The 2 markers appear correctly and at the right place. Unfortunately, title and listeners don't work...Is there any problem with my code syntaxe ? Or is there something I missed ?

Thanks for your responses !

shinkenno
2 Sep 2009, 8:09 AM
Found a solution:

mymarkers[1]['marker'] and mymarkers[1]['listeners'] have to be declared as arrays.


mymarkers[1]['marker'] = new Array();
mymarkers[1]['listeners'] = new Array();


Then you can filll their values as:


mymarkers[1]['marker']['title']='mytest';
mymarkers[1]['listeners']['click']=function(e){Ext.Msg.alert("True", "really true.")};


I am sure there is a more elegant way to do it, but it is perfectly working with this method.

mnask79
11 Sep 2009, 11:42 AM
hi guys ,

i'm trying to use google map with extjs , the problem is when i u my mp

and i change setCenter



setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},


to



setCenter: {
lat: 31.95,
lng: 35.933
},


nothing work like before,no markers,i dont see zoom in/out etc..., u can see the attached image 16162

whyyy ?

VinylFox
11 Sep 2009, 12:17 PM
@mnask79 - please post a working example

mnask79
11 Sep 2009, 12:38 PM
/*!
* Ext JS Library 3.0.0
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.onReady(function(){
var mapwin;
var button = Ext.get('show-btn');
button.on('click', function(){
// create the window on the first click and reuse on subsequent clicks
if(!mapwin){
mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width:400,
height:400,
x: 40,
y: 60,
items: {
xtype: 'gmappanel',
region: 'center',
zoomLevel: 14,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
lng: -71.094224,
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
}
});

}

mapwin.show();

});

});


this is the working example , its already exust at extjs samples

i just changed



setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},


to


setCenter: {
lat: 31.9565783,
lng: 35.933
},


full script is



/*!
* Ext JS Library 3.0.0
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.onReady(function(){
var mapwin;
var button = Ext.get('show-btn');
button.on('click', function(){
// create the window on the first click and reuse on subsequent clicks
if(!mapwin){
mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width:400,
height:400,
x: 40,
y: 60,
items: {
xtype: 'gmappanel',
region: 'center',
zoomLevel: 14,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
/* setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},*/
setCenter: {
lat: 31.9565783,
lng: 35.933
},
markers: [{
lat: 42.339641,
lng: -71.094224,
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
}
});

}

mapwin.show();

});

});

mnask79
11 Sep 2009, 12:42 PM
this is working example , it already exist at extjs samples



/*!
* Ext JS Library 3.0.0
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.onReady(function(){
var mapwin;
var button = Ext.get('show-btn');
button.on('click', function(){
// create the window on the first click and reuse on subsequent clicks
if(!mapwin){
mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width:400,
height:400,
x: 40,
y: 60,
items: {
xtype: 'gmappanel',
region: 'center',
zoomLevel: 14,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
lng: -71.094224,
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
}
});

}

mapwin.show();

});

});


and i just changed setCenter


/*!
* Ext JS Library 3.0.0
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
Ext.onReady(function(){
var mapwin;
var button = Ext.get('show-btn');
button.on('click', function(){
// create the window on the first click and reuse on subsequent clicks
if(!mapwin){
mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width:400,
height:400,
x: 40,
y: 60,
items: {
xtype: 'gmappanel',
region: 'center',
zoomLevel: 14,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
/* setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},*/
setCenter: {
lat: 31.9565783,
lng: 35.9456951
},
markers: [{
lat: 31.9565783,
lng: 35.9456951,
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
}]
}
});

}

mapwin.show();

});

});

mnask79
11 Sep 2009, 2:36 PM
excuse me , u have already fixed this issue

what about shape ?, if i want to draw shape 16170
how i can do this ?

thanks a lot man ..great job

mnask79
12 Sep 2009, 3:24 AM
hi again ,

can u help me please ?

first i have added the following script to draw something on my map



var map = Ext.getCmp('my_map');
//console.log(map.getMap());
var cur_glatlng = map.getMap().getCenter();
var lat = cur_glatlng.lat();
var lon = cur_glatlng.lng();

var latOffset = 0.01;
var lonOffset = 0.01;
var polygon = new GPolygon([
new GLatLng(lat, lon - lonOffset),
new GLatLng(lat + latOffset, lon),
new GLatLng(lat, lon + lonOffset),
new GLatLng(lat - latOffset, lon),
new GLatLng(lat, lon - lonOffset)
], "#f33f00", 5, 1, "#ff0000", 0.2);

map.addOverlay(polygon);


i get error addOverlay is not a function , what is instead of addOverlay in extjs ?

how i can draw circle based on one latitude and longitude, i mean latitude and longitude will be the center of this circle
can u help me please ????

regards

mnask79
12 Sep 2009, 4:03 AM
ok about first issue , i have added



addOverlay : function(param){


this.getMap().addOverlay(param);


},


but still trying to know how to draw a circle based on center point this point is latitude and longitude

regards

mnask79
12 Sep 2009, 6:20 AM
u can use this fuction to draw circle



function drawCircle(mapObj,center, radius, nodes, liColor, liWidth, fillColor, fillOpa, liOpa)
{
//console.log(center.lat());
//calculating km/degree
var latConv = center.distanceFrom(new GLatLng(center.lat()+0.1, center.lng()))/100;
var lngConv = center.distanceFrom(new GLatLng(center.lat(), center.lng()+0.1))/100;
//
//Loop
var points = [];
var step = parseInt(360/nodes)||10;

for(var i=0; i<=360; i+=step)
{
var pint = new GLatLng(center.lat() + (radius/latConv * Math.cos(i * Math.PI/180)), center.lng() +
(radius/lngConv * Math.sin(i * Math.PI/180)));
points.push(pint);
//bounds.extend(pint); //this is for fit function
}
fillColor = fillColor||liColor||"#f33f00";
liWidth = liWidth||1;
var poly = new GPolygon(points,liColor,liWidth,liOpa,fillColor,fillOpa);

map.addOverlay(poly);
}


its working now

regards

mnask79
12 Sep 2009, 2:06 PM
i hope this time someone help me

i want the marker icon color to another color not the default one (red) , i want it to be green or i use my own image , please help me how i can do it , i have demo tomorrow

my sorce is



map.addMarkers([{
lat: Ext.getCmp('lat').getValue(),
lng: Ext.getCmp('lng').getValue(),
marker: {title: 'Northeastern University'},
listeners: {
click: function(e){
Ext.Msg.alert('check', 'welcome to blue zone service ');
}
},
clear : true
}]) ;


regards

VinylFox
13 Sep 2009, 6:37 AM
Your quite persistent, ill give you that much. And please dont PM spam me with the exact same question you just posted on the forums.

The Google API playground is great for experimenting to see how things work. Below is a link that will direct you to a relevant example.

http://code.google.com/apis/ajax/playground/?exp=maps#map_icon_simple

PS. all of your questions have been related to the Google Maps API, and not GMapPanel, that is why your not getting any responses.

PPS. use getMap() when you want to call Google Maps API methods, the GMapPanel is not a map, its a panel that contains a map.

mnask79
14 Sep 2009, 3:53 AM
first i'm sorry , but really i did not mean 'PM spam' you , i just was trying to see my post
anyway , thanks a lot about everythings

regards

shinkenno
22 Sep 2009, 2:23 AM
Hi dear GMapPanel users,

I have 2 questions:

1/----------------------------------------------------------------------------------------------------------------

My map panel is defined like this (where the id is based on parameters of the function which created the map in a new tab):


...{ // Map

title: 'Network',
width: 600,
height: 400,

items: {
xtype: 'gmappanel',
zoomLevel: 1,
gmapType: 'map',
id: srcname+'_'+start+'_map',
mapConfOpts: ['enableDoubleClickZoom','enableDragging','enableInfoWindow'],
mapControls: ['GLargeMapControl3D','GMenuMapTypeControl','NonExistantControl'],
setCenter: {
lat: 0,
lng: 0
},
markers: mymarkers
} //eof google map

When I do:

var myPanel = Ext.getCmp(srcname+'_'+start+'_map');
console.info(myPanel);

I get a correct answer from firebug:

Object initialConfig=Object xtype=gmappanel zoomLevel=1

But when I try this:

var myMap = Ext.getCmp(srcname+'_'+start+'_map').getMap();
console.info(myMap);

Firebug displays:

undefined

What does this means ?

2/----------------------------------------------------------------------------------------------------------------

I would like to display for my makers (stored in an array with lat, long, title) a tab info window containing various info (short description, image, website url, etc.).

I saw that it is possible to set listeners directly within the markers array (read by the addMarkers/addMarker functions). I would like to build a listening function (on click event) that takes as parameters the additional info described above and binds it to the corresponding marker.

Here id the skeleton of what I want to do (I know it does not work):


// Click on map
function clickonmap(stname, stcode, stcodelong, stcountry, stlat, stlong, stalt, stweb, stdesc, stwebcam){

var html1 = "<div style='width: 400px'><b>" + stname +"</b><br /><br />"+ stlat +" "+ stlong +"</b><br />"+stcountry+"...etc.</div>";
var html2 = "<div style='width: 400px'>Map zoomed<br /></div>";
var html3 = "<div style='width: 400px'>Other info</div>";

// personnal options for info window
var openInfoWindowTabsOptions = {
maxWidth: '400px',
selectedTab: 0
};

openInfoWindowTabsHtml([new GInfoWindowTab('Infos',html1), new GInfoWindowTab('Zoom in',html2), new GInfoWindowTab('Webcam',html3)], openInfoWindowTabsOptions);

* I know I have to get the map object/id or the maker id/object somewhere, but I don't know how and where exactly ?

* Can I just add the following directly to the marker array ?

mymarkers[i]['listeners']['click']=clickonmap(stname, stcode, stcodelong, stcountry, stlat, stlong, stalt, stweb, stdesc, stwebcam);


Thanks for your answers (and sorry for the long description...)

VinylFox
22 Sep 2009, 3:20 AM
As for question 1, its likely that your map is just not ready yet, Google maps are a complex thing and take more time than the panel to become ready. Use the 'mapready' event to wait for the map to become available.


Ext.getCmp(srcname+'_'+start+'_map').on('mapready', function(myMap){
console.info(myMap);
});

shinkenno
22 Sep 2009, 3:58 AM
Thanks Shea !

Waiting for the map to be ready done the thing ; now firebug successfully displays the map object:

Object l=div#ext-gen75.x-panel-body Ga=[3] U=Object


So I suppose that If, for example, I want to add makers, I have to replace the console command by addMarkers (or any other function) as:


var myMap= Ext.getCmp(srcname+'_'+start+'_map');
myMap.on('mapready', function(myMap){

myMap.addMarkers(mymarkers);
// or any other function...

});

Thanks a lot !
Any idea with the 2nd point ?

VinylFox
22 Sep 2009, 4:48 AM
Note the difference between the Panel and the Map in this code below, they are separate entities.


var myMapPanel= Ext.getCmp(srcname+'_'+start+'_map');
myMapPanel.on('mapready', function(myMap){
myMap.addMarkers(mymarkers);
// or any other function...
});

And yes, you can add markers that way. They could also be added in the markers config.

Take a look in the examples folder on my GMapPanel Google code site, those should help as well. (the link is in my signature)

Jangla
24 Sep 2009, 1:32 AM
Is it possible to have a loading message on this? If it's not got a loadingMask attribute, is it possible to create one manually and then destroy it once all markers are loaded?

I've tried using:



var mapLoadingMask = new Ext.LoadMask(Ext.getCmp("map-properties-panel").getEl() ,{msg : "Please wait..."});
mapLoadingMask.show();


...to no avail.

abraxxa
24 Sep 2009, 1:38 AM
This one:
http://extjs.com/forum/showthread.php?p=247895#post247895

Any news on incorporating my changes?

Jangla
25 Sep 2009, 6:00 AM
I've been attempting to add a "zoom to markers" function to this script so it automatically sets the centre of the map and the zoom level to incorporate all visible markers on the map.

Big problems though: If you use a gmap on a tabpanel that uses deferredRender: false and the map isn't on the top-most tab, attempting to zoom to markers doesn't work. You will always end up with the map zoomed right back to global level.

Someone on the google map forums suggested changing the GMap2 instatiation to include a GSize value but that doesn't work either :(

Anyone had any success with this or something similar?

abraxxa
25 Sep 2009, 6:01 AM
My code does exactly that but instantly after all markers are placed.

Jangla
25 Sep 2009, 6:16 AM
My code does exactly that but instantly after all markers are placed.
Even if the map is on a tab panel and is not the top-most tab?

abraxxa
25 Sep 2009, 6:50 AM
I don't know, you have to try it out.

Jangla
25 Sep 2009, 7:40 AM
Unfortunately the answer is no - I used very similar code to yours in the first place trying to get it to work but with no joy. Apparently there's a visibility plugin (or something) that may help so I'll post back if and when it becomes workable.

In the meantime, if anyone's managed to get a loading mask working on the map, I'd love to see it. So far it only seems to appear when there's an error in my code - possibly as it doesn't have time to render while markers are being added and when the code falls over it can catch up??? :-?

By the way, I'm sure you have your reasons for doing it this way, but why do this:



getLatLngBoundsforMarkers : function(){
var markers = this.getMarkers();
if (Ext.isArray(markers)){
// check for the existance of the google map in case setSize is called too early
if (typeof this.getMap() == 'object') {
var glatlng_sw_lat;
var glatlng_sw_lng;
var glatlng_ne_lat;
var glatlng_ne_lng;

for (var i = 0; i < markers.length; i++) {
var marker = markers[i];
var marker_lat = marker.getLatLng().lat();
var marker_lng = marker.getLatLng().lng();
if (marker_lat < glatlng_sw_lat || !glatlng_sw_lat) {
glatlng_sw_lat = marker_lat;
}
if (marker_lat > glatlng_ne_lat || !glatlng_ne_lat) {
glatlng_ne_lat = marker_lat;
}

if (marker_lng < glatlng_sw_lng || !glatlng_sw_lng) {
glatlng_sw_lng = marker_lng;
}
if (marker_lng > glatlng_ne_lng || !glatlng_ne_lng) {
glatlng_ne_lng = marker_lng;
}
}

var glatlng_sw = new GLatLng(glatlng_sw_lat,glatlng_sw_lng);
var glatlng_ne = new GLatLng(glatlng_ne_lat,glatlng_ne_lng);
return new GLatLngBounds(glatlng_sw, glatlng_ne);
}
}
},
... when you can just do this:




getLatLngBoundsforMarkers : function(){
var markers = this.getMarkers();
if (Ext.isArray(markers)){
// check for the existance of the google map in case setSize is called too early
if (typeof this.getMap() == 'object') {
var bounds = new GLatLngBounds();
var markersLen = markers.length;
for (var i = 0; i < markersLen; i++) {
var marker = markers[i];
bounds.extend(markers.getLatLng().lat(), marker.getLatLng().lng());
}
return bounds;
}
}
},
...or something similar - the point I'm making is that you can declare a bounds variable and then just use .extend with the lat and lng values to come up with your final boundaries. Im my version I've actually kept a track of the bounds as each marker is added so *theoretically* all you have to do is make a single call to zoom to the right point once you've added all markers.

Note if you use var markersLen = markers.length; before looping and then use that in your for loop, you'll get quicker results as you don't have to re-evaluate the length of the array every time you loop. Depending on the length of the array, you could also consider looping through it backwards to get more performance.

hendricd
25 Sep 2009, 9:50 AM
@Jangla: This is common problem with masking iteration-intensive processes. Keep in mind -- the browser is a single-threaded beast!

Give the rendering engine a chance to do your bidding:


var M = Ext.getCmp("map-properties-panel");
if(M){
M.bwrap.mask("Please wait...");
(function(){
this.centerTheMap(this.getLatLngBoundsforMarkers());
this.bwrap.unmask();
}).defer(60, M);
}

If the iteration includes remote Map API methods (Ajax), you'll have to use a final callback signal to unmask.

rb4i
2 Oct 2009, 10:24 AM
Shea,

This is an excellent Extension and it saved lot of my time already. I am experiencing few performance issues in loading and heard that Google Map API V3 resolved a bunch of them. I read somewhere in the thread that you are working on migrating the extension to support V3 ? Are you close to complete ?

Thanks a lot.

Balaji

VinylFox
3 Oct 2009, 6:50 AM
... experiencing few performance issues in loading and heard that Google Map API V3 resolved a bunch of them. ...

The v3 API renders and responds to user interaction much quicker, its quite a big performance boost. Its also nice to see that they have cleaned up the global namespace with v3. I have a version of the extension for v3 right now, just doing some more testing before releasing it.

Keep in mind that there are things that exist in the v2 API that are not present in v3.

Polylines (just added last week)
KML
Directions
StreetView
Localization
Many Controls are missing

Jangla
9 Oct 2009, 4:17 AM
@Jangla: This is common problem with masking iteration-intensive processes. Keep in mind -- the browser is a single-threaded beast!

Give the rendering engine a chance to do your bidding:


var M = Ext.getCmp("map-properties-panel");
if(M){
M.bwrap.mask("Please wait...");
(function(){
this.centerTheMap(this.getLatLngBoundsforMarkers());
this.bwrap.unmask();
}).defer(60, M);
}

If the iteration includes remote Map API methods (Ajax), you'll have to use a final callback signal to unmask.

I've noticed when implementing a mask like this, you don't get the little spinner animation (at least I don't!). Is there any way of making this happen?

Can't find anything in the docs about bwrap so I'm kind of wroking blind here :)

hendricd
9 Oct 2009, 4:38 AM
I've noticed when implementing a mask like this, you don't get the little spinner animation (at least I don't!). Is there any way of making this happen?
@Jangla -- Hehe :)

Yeah, that's yet another example of the single-threaded nature of browsers. The math involved (iteration) in that sort of process does not yield enough time to browser's rendering engine to give that animated-GIF enough 'face-time'.

In recent work with the Google Earth plugin, I've used Gears Workers (threads) to perform compute-intensive stuff like that, so it doesn't impact the UI much. HTML5 browsers have support for Workers, but for older browser that do not, I use this:



/**
* @argument work Array to act as argument for each fn Function call
*/
window.Yield = function(work, fn, fnScope, callback, cbScope, quantas){
var w = [].concat(work), q = quantas || 100, results=null, index = 0;
if(typeof fn === 'function'){
if(!!w.length){
setTimeout(function(){
var item = w.shift();
var r= fn.call(fnScope||item, item, index++);
if(callback && r !== undefined){
(results || (results = [])).push(r);
}
if (!!w.length){
setTimeout(arguments.callee, q);
return;
}
if(typeof callback === 'function'){
callback.call(cbScope,results);
}
}, q);
}else if(typeof callback === 'function'){
callback.call(cbScope,results);
}
}
};
Using Yield, you would pass in your array of LatLong extents and it smooths out the iterations (with slight delays for each item) to keep the rendering engine active and you get a callback when things are done. :-?


Can't find anything in the docs about bwrap so I'm kind of wroking blind here :)

Ext.Panel's and descendants have two main rendering canvas(..eseses) :)

The bwrap element is the DOM Container for the body and any toolbars. The body is where all rendered content goes only. I chose bwrap in that example figuring you might not want them firing toolbar events during your calc-soup. ;)

FabianIB
20 Nov 2009, 9:00 AM
Hi there!


... I have a version of the extension for v3 right now, just doing some more testing before releasing it...

Is there any news about this new version? (Using google maps V3).

Thanks!

VinylFox
20 Nov 2009, 12:06 PM
...Is there any news about this new version? (Using google maps V3)...

Its a work in progress, not everything works yet, but give it a whirl and let me know what you think.

http://code.google.com/p/ext-ux-gmappanel/source/detail?r=24

chickenwings
24 Nov 2009, 12:26 AM
Is there a way I can add properties to a custom control? I am adding the DragZoomControl from a third party script:

http://gmaps-utility-library.googlecode.com/svn/trunk/dragzoom/1.2/docs/examples.html

If I add it like all the examples given, it works and I see a 'zoom' button. However I'm not sure how I can add the customizations as outlined in the drag zoom examples. They are all given as map.addControl(etc.etc.) I've tried creating a javascript var and passing that but it wont display anything. Any ideas? Thanks for reading.

This works but I'd like to customize it as shown at the bottom:


<script type="text/javascript" src="lib/dragzoom/dragzoom.js"></script>

region: 'center',
xtype: 'gmappanel',
tbar: tbar,
zoomLevel: 12,
gmapType: 'map',
id: 'my_map',
border: true,
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging',
'enableGoogleBar'],
mapControls: ['GSmallMapControl','GMapTypeControl','GOverviewMapControl',
'DragZoomControl'],



DragZoomControl example:



/* first set of options is for the visual overlay.*/
var boxStyleOpts = {
opacity:.2,
border:"2px solid red"
}

/* second set of options is for everything else */
var otherOpts = {
buttonHTML:"<img src='zoom-button.gif' />",
buttonZoomingHTML:"<img src='zoom-button-activated.gif' />",
buttonStartingStyle:{width:'24px',height:'24px'}
};

/* third set of options specifies callbacks */
var callbacks = {
buttonclick:function(){display("Looks like you activated DragZoom!")},
dragstart:function(){display("Started to Drag . . .")},
dragging:function(x1,y1,x2,y2){display("Dragging, currently x="+x2+",y="+y2)},
dragend:function(nw,ne,se,sw,nwpx,nepx,sepx,swpx){display("Zoom! NE="+ne+";SW="+sw)}
};

map.addControl(new DragZoomControl(boxStyleOpts, otherOpts, callbacks));

VinylFox
24 Nov 2009, 5:22 AM
Is there a way I can add properties to a custom control?..

Yes. I just made a tweak to the code to allow the following...


mapControls: [new YourControl(some, arguments, here), 'DragZoomControl']

The mapControls config can now accept either a string representation (for pure JSON configs) or the actual instantiated class itself.

http://code.google.com/p/ext-ux-gmappanel/source/detail?r=25

Enjoy.

chickenwings
26 Nov 2009, 12:28 AM
Yes. I just made a tweak to the code to allow the following...


mapControls: [new YourControl(some, arguments, here), 'DragZoomControl']The mapControls config can now accept either a string representation (for pure JSON configs) or the actual instantiated class itself.

http://code.google.com/p/ext-ux-gmappanel/source/detail?r=25

Enjoy.

Thank you this works great.

lorezyra
8 Dec 2009, 2:13 AM
Is there a demo to show this UX within a very simple Panel? The example provided by EXTjs.com is in a window and others I have found are in viewports...

I'm looking for a method to display a "static" container with gmaps in my travel log...


http://richiebartlett.com/blog/travel.php

Hints and pointers are appreciated.

VinylFox
8 Dec 2009, 6:26 AM
This UX is a Panel, so it can be used wherever a Panel can be used.

I see your site is using Tabs, have you seen the Tabs example (http://code.google.com/p/ext-ux-gmappanel/source/browse/#svn/trunk/examples/tabs)?

lorezyra
8 Dec 2009, 7:11 PM
This UX is a Panel, so it can be used wherever a Panel can be used.

I see your site is using Tabs, have you seen the Tabs example (http://code.google.com/p/ext-ux-gmappanel/source/browse/#svn/trunk/examples/tabs)?

Actually, I did figure it out... I just needed to sleep so I can start thinking straight...

See: http://www.extjs.com/forum/showthread.php?p=416499#post416499


While my site is using tabs, I don't want the GMap to come up in a tab (by itself)... Rather I need it as a embedded panel within the external content loaded into the tab...


BTW, THANK YOU for this excellent UX!!!! =D>

Margusja
9 Dec 2009, 7:14 AM
Hi, I am trying to get lng,lat,marker data from db via php.

at the moment I have php code:



1 <?php
2
3 $arr = array(
4 array("lat" => "47.227081", "lng" => "0.915441", "marker" => "{title: 'Property 1'}"),
5 array("lat" => "47.227077", "lng" => "0.915444", "marker" => "{title: 'Property 2'}"),
6 );
7
8 echo $jsonresult = json_encode($arr);
9 ?>


extjs code:



340 var mapwin = new Ext.Window({
341 id: 'mapwin',
342 layout: 'fit',
343 title: 'GMap Window',
344 closeAction: 'hide',
345 width:1000,
346 height:800,
347 x: 40,
348 y: 60,
349 items: {
350 xtype: 'gmappanel',
351 zoomLevel: 14,
352 gmapType: 'map',
353 id: 'my_map',
354 mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
355 mapControls: [new GSmallMapControl(),'GMapTypeControl','NonExistantControl'],
356 setCenter: {
357 lat: 58.88611,
358 lng: 25.55638,
359 marker: {title: 'Paide'}
360 },
361 markers: mrk /*[{
362 lat: 58.89864,
363 lng: 25.53834,
364 marker: {title: 'Boston Museum of Fine Arts'}
365 },{
366 lat: 58.86944,
367 lng: 25.58701,
368 marker: {title: 'Northeastern University'}
369 }]*/
370 }
371 });




557 var myMarkers = new Ext.data.JsonStore({
558 fields: ['lat', 'lng', 'marker'],
559 url: 'markers.php',
560 root: '',
561 id: 'ID'
562 });
563
564
565 myMarkers.on('load', function(){
566 var mk_array = myMarkers.getRange();
567 myMap = Ext.getCmp('mapwin');
568 myMarkers.each(function(rec){
569 myMap.addMarker(mk_array);
570 });
571 });
572
573
574 myMarkers.load();


The error appears is: myMap.addMarker is not a function
[Break on this error] myMap.addMarker(mk_array);\n

Margusja
9 Dec 2009, 7:18 AM
change one line:



565 myMarkers.on('load', function(){
566 var mk_array = myMarkers.getRange();
567 myMap = Ext.getCmp('my_map'); // Old was mapwin
568 myMarkers.each(function(rec){
569 myMap.addMarker(mk_array);
570 });
571 });


Now I got: this.getMap() is undefined
[Break on this error] this.getMap().addOverlay(mark);\r\n

Margusja
9 Dec 2009, 7:23 AM
One more explanation

At the moment I have static array in extjs



var mrk = [{
331 lat: 58.89864,
332 lng: 25.53834,
333 marker: {title: 'Kirik 1'}
334 },{
335 lat: 58.86944,
336 lng: 25.58701,
337 marker: {title: 'Maa 2'}
338 }];


It works. But I want to get data via php from db. Tried here lot's of examples but I think I do something totally wrong :(

VinylFox
9 Dec 2009, 9:55 AM
Well...there are many problems with your code. Keep track of your variables.

Try this...

myMarkers.on('load', function(){
myMap = Ext.getCmp('my_map'); // Old was mapwin
myMarkers.each(function(rec){
myMap.addMarker(rec.data);
});
});

Margusja
9 Dec 2009, 11:35 AM
getting still this:
this.getMap() is undefined
anonymous(Object lat=47.227081 lng=0.915441, Object name=marker, Object name=clear, Object name=center, Object name=listeners)Ext.ux.G...pPanel.js (line 460)
anonymous(Object phantom=true id=ext-record-255 data=Object)list.js (line 569)
anonymous(function(), Object name=scope)ext-all-debug.js (line 11115)
anonymous(function(), Object name=scope)ext-all-debug.js (line 31194)
anonymous()list.js (line 568)
anonymous(Object scope=Object options=Object)ext-all-debug.js (line 2124)
anonymous([Object scope=Object options=Object 0=Object], function(), Object name=E)ext-base.js (line 7)
anonymous()ext-all-debug.js (line 2122)
anonymous()ext-all-debug.js (line 1809)
anonymous(Object success=true records=[2] totalRecords=2, Object params=Object, true)ext-all-debug.js (line 31054)
anonymous("read", Object request=Object reader=Object scope=Object, Object tId=1 status=200 statusText=OK)ext-all-debug.js (line 33001)
anonymous(Object request=Object reader=Object scope=Object, true, Object tId=1 status=200 statusText=OK)ext-all-debug.js (line 32965)
handleResponse(Object tId=1 status=200 statusText=OK)ext-all-debug.js (line 8553)
f(Object conn=XMLHttpRequest tId=1, Object scope=Object argument=Object timeout=30000, Object name=r, Object name=q)ext-base.js (line 7)
anonymous()ext-base.js (line 7)
[Break on this error] this.getMap().addOverlay(mark);\r\n

I am not sure that the problem is in following part.



5 myMarkers.on('load', function(){
566 //var mk_array = myMarkers.getRange();
567 myMap = Ext.getCmp('my_map');
568 myMarkers.each(function(rec){
569 myMap.addMarker(rec.data);
570 });
571 });

Margusja
9 Dec 2009, 12:12 PM
My bad. I haven't call my_map. And I try to use it :)

Margusja
9 Dec 2009, 1:19 PM
Great. Got it to work.
Thi magic line was to me: var point = new GLatLng(rec.data.lat, rec.data.lng, rec.data.marker);



2 emailGrid = new Ext.grid.EditorGridPanel({
533 title: 'Andmed',
534 id: 'listGrid',
535 store: listStore,
536 columns: listColumnModel,
537 renderTo: 'list',
538 width: 'auto',
539 stripeRows: true,
540 autoHeight: true,
541 frame: false,
542 plugins: this.action,
543 trackMouseOver: true,
544 //bbar: new Ext.PagingToolbar({
545 // pageSize: 15,
546 // store: listStore,
547 // displayInfo: true
548 //})
549 tbar: [{
550 text: 'Lisa kirje',
551 tooltip: 'Lisa kirje',
552 iconCls:'add',
553 handler: displayAddFormWindow
554 }
555 ,{
556 text: 'Vaata kaarti',
557 tooltip: 'Vaata kaart',
558 iconCls: 'gmap-icon',
559 handler: function () {
560 myMarkers.load();
561 myMarkers.on('load', function(){
562 myMap = Ext.getCmp('my_map');
563 myMarkers.each(function(rec){
564 var point = new GLatLng(rec.data.lat, rec.data.lng, rec.data.marker);
565 myMap.addMarker(point);
566 console.log(point);
567 });
568 });
569 mapwin.show();
570 }
571 }
572 ]
573
574 })

Margusja
10 Dec 2009, 12:32 AM
Hi again. I have one more small problem.
I can see my markers on map now. But I can't see marker titles.

Here I get data from php


5 var myMarkers = new Ext.data.JsonStore({
386 fields: ['lat', 'lng', 'marker'],
387 url: 'data.php?action=getMarkers',
388 root: '',
389 id: 'ID'
390 });


My Json object is:
[{"lat":"58.82404","lng":"25.9539","marker":""},{"lat":"58.62097","lng":"25.52935","marker":" Vene kirik "}]

I think something is wrong with my Json object.
If I look in to addMarker source then I am not sure what exactli is point and what exactli is marker :)
Does poin need to contain title:Property or doesn't?

Then I add it to map


myMarkers.load();
600 myMarkers.on('load', function(){
601 myMap = Ext.getCmp('my_map');
602 myMarkers.each(function(rec){
603 var point = new GLatLng(rec.data.lat, rec.data.lng, rec.data.marker);
604 myMap.addMarker(point);
605 //console.log(point);
606 });
607 });

VinylFox
10 Dec 2009, 6:13 AM
'marker' is an object, just like it is in the Google Maps API, and all of the examples I have created.


{
lat: 58.86944,
lng: 25.58701,
marker: {title: 'Northeastern University'}
}

Margusja
10 Dec 2009, 8:10 AM
Tnx for your answer.
My result is from php:
[{"lat":"58.82404","lng":"25.9539","marker":"{lat: 58.82404, lng: 25.9539, marker:{title:'sadasdasdasas'}}"},{"lat":"58.62097","lng":"25.52935","marker":"{lat: 58.62097, lng: 25.52935, marker:{title:'sadasdasdasas'}}"},{"lat":"58.056","lng":"25.368","marker":"{lat: 58.056, lng: 25.368, marker:{title:'sadasdasdasas'}}"}]


here you see how I assigne it:


myMarkers.each(function(rec){
var point = new GLatLng(rec.data.lat, rec.data.lng);
myMap.addMarker(point, rec.data.marker);
console.log(rec.data.marker);
});

But somehow that is not an object.
This is more like just a string: "{lat: 58.056, lng: 25.368, marker:{title:'sadasdasdasas'}}"

VinylFox
10 Dec 2009, 8:30 AM
Yes, when you place quotes around text it is a string.

That result from your PHP script is so far from what it needs to be, im not even sure where to start. You need to pick up a book on JavaScript and possibly on PHP as well, read through it and then approach this task again.

Margusja
10 Dec 2009, 11:53 AM
Okei.
As you see I am creating point object in same way as marker.
And I use them in same way.
myMap.addMarker(point, rec.data.marker);
So I have question why point is object and marker is not :) But Ok tnx. I am quite strong in php but JS is not so good. So I digging into JS books.

VinylFox
10 Dec 2009, 12:31 PM
Well, here is what your PHP output should look like:


[{
"lat": "58.82404",
"lng": "25.9539",
"marker": {
title: "sadasdasdasas"
}
}, {
"lat": "58.62097",
"lng": "25.52935",
"marker": {
marker: "sadasdasdasas"
}
}, {
"lat": "58.056",
"lng": "25.368",
"marker": {
marker: "sadasdasdasas"
}
}]

Margusja
10 Dec 2009, 12:37 PM
I got it work. Tnx VinylFox.

php code


if($nbrows>0){
160 while($rec = mysql_fetch_array($result)){
161 $rec2['lat'] = $rec['lat_d'].".".$rec['lat_m'];
162 $rec2['lng'] = $rec['lng_d'].".".$rec['lng_m'];
163 $rec2['marker'] = iconv("ISO-8859-1", "UTF-8", $rec['nimi']);
164 $arr[] = $rec2;
165 }
166 //var_dump($arr);
167 return json_encode($arr);
168 } else {
169 return 0;
170 }


it generates:
[{"lat":"58.82404","lng":"25.9539","marker":""},{"lat":"58.62097","lng":"25.52935","marker":" Vene kirik "},{"lat":"58.056","lng":"25.368","marker":"Kaasiku "}]

JS code


myMarkers.each(function(rec){
603 var point = new GLatLng(rec.data.lat, rec.data.lng);
604 var mrk = {lat: rec.data.lat, lng: rec.data.lng, title:rec.data.marker}
605 myMap.addMarker(point, mrk);
606 console.log(mrk);
607 });

lorezyra
11 Dec 2009, 12:28 AM
I have a new challenge that is quite annoying at the moment...
I'm working to enhance my blog features to use GMapPanel to display locations I have visited...

I'm able to load the "external" page by itself with no issues.
http://www.richiebartlett.com/blog/showThread.php?blogid=12

However, when I render that same page into the tabpanel, I see the page load and the scripts start to run. Shortly after Google Maps JS code runs, the browser is redirected to a blank page! Huh?? I've added FireBug console output to assist with troubleshooting. But I'm at a loss as to why I see this issue...
http://www.richiebartlett.com/blog/travel.php

I see that the GMapPanel is never rendered due to this JS error :


types[config.xtype || defaultType] is not a constructor
/EXTjs/ext-all-debug.js
Line 13870
Perhaps someone could point me in the right direction?


showThread.php GMap code:


var myPanel = new Ext.Panel({
title: 'Google Mapped',
id: "<?php echo "Blog_$blogid"; ?>",
frame: false,
layout: 'border',
collapsible: true,
collapsed: true,
preventBodyReset: true,
width:400,
height:400,
items: {
xtype: 'gmappanel',
region: 'center',
zoomLevel: <?php echo $bText["geoZoom"]; ?>,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
setCenter: {
//<?php echo "$bText[geoLat], $bText[geoLng]\n"; ?>
geoCodeAddr: '<?php echo $bText["geoCodeAddr"]; ?>',
marker: {title: '<?php echo $bText["subject"]; ?>'}
}
}

});
myPanel.on({
"beforerender": { fn: function(){ if(Ext.isGecko) console.log(" // gMap Rendered //");}},
"beforecollapse": { fn: function(){ if(Ext.isGecko) console.log(" // gMap collapsed //");}},
"beforeexpand": { fn: function(){ if(Ext.isGecko) console.log(" // gMap expanded //");}}
});
myPanel.render("<?php echo "gMapped$blogid"; ?>");


I'm not certain (as of yet), but it seems that Google is redirecting my page...

lorezyra
11 Dec 2009, 1:09 AM
Never mind... I found the problem.

Just FYI, if you need to run scripts from external pages (loaded into tabs)... Be sure to include the external Ext.ux.*.js scripts in the page that loads the tabs. If you try loading new external scripts from a newly loaded tab, your page can be redirected...

I figured this out when I looked at how the scripts are added to the headers in FireBug. In this case, the "header" was the div of the tab... and that is where the redirect was forced...

Margusja
16 Dec 2009, 2:14 AM
Hi, I am back again.

A problem is that I can't get listeners: click to work if I click on some marker on my map.



// Markers
385 var myMarkers = new Ext.data.JsonStore({
386 fields: ['lat', 'lng', 'marker'],
387 url: 'data.php?action=getMarkers',
388 root: '',
389 id: 'ID'
390 });
391
392 var mapwin = new Ext.Window({
393 id: 'mapwin',
394 layout: 'fit',
395 title: 'GMap Window',
396 closeAction: 'hide',
397 width:1000,
398 height:800,
399 x: 40,
400 y: 60,
401 items: {
402 xtype: 'gmappanel',
403 zoomLevel: 8,
404 gmapType: 'map',
405 id: 'my_map',
406 mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
407 mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
408 setCenter: {
409 lat: 58.88611,
410 lng: 25.55638
411 }
412
413 }
414 });


handler in grid:


97 handler: function () {
598 myMarkers.load();
599 myMarkers.on('load', function(){
600 myMap = Ext.getCmp('my_map');
601 myMarkers.each(function(rec){
602 var point = new GLatLng(rec.data.lat, rec.data.lng);
603 var mrk = {lat: rec.data.lat, lng: rec.data.lng, title:rec.data.marker
604 ,listeners: {
605 click: function(e){
606 Ext.Msg.alert('Its fine', 'and its art.');
607 }
608 }}
609 myMap.addMarker(point, mrk);
610 console.log(mrk);
611 //var marker = new GMarker(point,'Hello World');
612 //marker.openInfWinHtm(marker, 'Hello World');
613 });
614 });
615 mapwin.show();
616 }


I can see mrk object:
listeners Object
click function(e) ... so looks like I have object.

But if I click on my marker there is no actions.

Any ideas?

Best regards, Margusja

Margusja
22 Dec 2009, 12:58 AM
Hi again.
I am still in darkness. I can see object in my marker object but can't click. Just nothing hapen.

Any hint please :)?

Margusja
22 Dec 2009, 4:14 AM
Yes, I got it work



0 myMarkers.on('load', function(){
601 myMap = Ext.getCmp('my_map');
602 myMarkers.each(function(rec){
603 var point = new GLatLng(rec.data.lat, rec.data.lng);
604 var mark = new GMarker(point, rec.data.marker);
605 var mrk = {lat: rec.data.lat, lng: rec.data.lng, title:rec.data.marker};
606 var l = new Array();
607 l['click']=function(e){Ext.Msg.alert("True", "really true.")};
608 myMap.addMarker(point, mrk, null, null, l);
609 //console.log(mark);
610 //var marker = new GMarker(point,'Hello World');
611 //marker.openInfWinHtm(marker, 'Hello World');
612 });
613 });

ExtSwede
18 Jan 2010, 5:55 AM
Hi

Want to say that this is a great implementation for Ext.

I'm just having problems with displaying the directions from point a to point b. I've seen a post regarding this at http://www.extjs.com/forum/showthread.php?p=359068
However I don't quite understand how to implement this properly.

Maybe i'm just missing some file or so, so I'll start by saying that I got GMapPanel.js and the GMapApi + the Ext library, am I missing something else?

If thats not one of the things then I believe thats i just a code issue. I've been searching the net and the forum all day for a solution.


gdir = new GDirections(map, Ext.get("directions"));How do you use gdir after this? In the google API they use GEvent.addListener for calling the onGDirectionsLoad() function wich uses polylines, and after all that is done it ends with setDirections. Should I do the same, or is it any other solution for this?

Thankful for any replies for information or directions on where I could find more information.

TigersWay
18 Jan 2010, 6:12 PM
Hi,

My first word is a big thank! I have build my new gmap panel in less than 1 hour with everything I needed so far!

But reading around, I learned that the google maps api v3 is significantly more efficient, and I'd love to use it.
Your 'border-layout' sample - only one officially v3 - is not working for me in v3 (but great in v2), the map does not even load!
Is there anything I should be aware of or take care about?

Thanks,
Ben

moegal
21 Jan 2010, 11:10 AM
I added some infoWindowHtml support, unless there is a better way, please let me know. It is optional so you can just lease it blank. To use you would add:



markers: [
{
lat: 26.70673,
lng: -81.846468,
marker: {title: 'Fort Myers Office'} ,
infoWindowHtml: 'This is <b>COOL</b>'
},{
lat: 25.596308,
lng: -80.364216,
marker: {title: 'Miami Office'},
infoWindowHtml: 'This is <b>COOLER</b>'
}
],


I also added single quotes around the respErrors. I see on your google code page that that was done but not on the latest version I downloaded. And a new event called 'zoomended'.



Ext.namespace('Ext.ux.panel');

/**
* @author Shea Frederick - http://www.vinylfox.com
* @class Ext.ux.panel.GMapPanel
* @extends Ext.Panel
* <p>A simple component that adds Google maps functionality to any panel or panel based component
* (ie: windows). For information about the Google Maps API see http://code.google.com/apis/maps/index.html.</p>
* <p>Sample usage:</p>
* <pre><code>
var panwin = new Ext.Window({
layout: 'fit',
closeAction: 'hide',
title: 'GPanorama Window',
width:400,
height:300,
x: 480,
y: 60,
items: {
xtype: 'gmappanel',
gmapType: 'panorama',
setCenter: {
lat: 42.345573,
lng: -71.098326
}
}
});
* </code></pre>
* <p>Another example:</p>
* <pre><code>
var mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
id: 'my_map',
closeAction: 'hide',
width: 400,
height: 400,
x: 40, y: 60,
items: {
xtype: 'gmappanel',
zoomLevel: 14,
gmapType: 'map',
id: 'my_map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
{@link #markers}: [{
geoCodeAddr: '465 Huntington Avenue, Boston, MA, 02215-5597, USA',
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and it is art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
}
});
* </code></pre>
* <p>Additional functionality from the Google Maps API may be implemented using <b><code>{@link #getMap}</code></b>.
* For example:<pre><code>
buttons: [{
text: '+',
minWidth: 30,
handler: function(){
var c = Ext.getCmp('my_map');
var m = c.{@link #getMap}();
m.setZoom(m.getZoom()+1);
c.zoomLevel = m.getZoom();
}
},{
text: '-',
minWidth: 30,
handler: function(){
var c = Ext.getCmp('my_map');
var m = c.{@link #getMap}();
m.setZoom(m.getZoom()-1);
c.zoomLevel = m.getZoom();
}
}]
* </code></pre></p>
* <p>This class is maintained at http://code.google.com/p/ext-ux-gmappanel/</p>
* <p>For Yahoo maps see: http://developer.yahoo.com/maps/ajax/</p>
* @xtype gmappanel
*/
Ext.ux.GMapPanel = Ext.extend(Ext.Panel, {
/**
* @cfg {Boolean} border
* Defaults to <tt>false</tt>. See {@link Ext.Panel}.<code>{@link Ext.Panel#border border}</code>.
*/
border: false,

/**
* @cfg {Array} respErrors
* An array of msg/code pairs.
*/
respErrors: [{
code: 400, // G_GEO_BAD_REQUEST
msg: 'A directions request could not be successfully parsed. For example, the request may have been rejected if it contained more than the maximum number of waypoints allowed.'
},{
code: 'G_GEO_SERVER_ERROR',
msg: 'A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.'
},{
code: 601, // G_GEO_MISSING_QUERY
msg: 'The HTTP q parameter was either missing or had no value. For geocoding requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.'
},{
code: 'G_GEO_MISSING_ADDRESS',
msg: 'Synonym for G_GEO_MISSING_QUERY.'
},{
code: 'G_GEO_UNKNOWN_ADDRESS',
msg: 'No corresponding geographic location could be found for the specified address. This may be due to the fact that the address is relatively new, or it may be incorrect.'
},{
code: 'G_GEO_UNAVAILABLE_ADDRESS',
msg: 'The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.'
},{
code: 604, // G_GEO_UNKNOWN_DIRECTIONS
msg: 'The GDirections object could not compute directions between the points mentioned in the query. This is usually because there is no route available between the two points, or because we do not have data for routing in that region.'
},{
code: 'G_GEO_BAD_KEY',
msg: 'The given key is either invalid or does not match the domain for which it was given.'
},{
code: 'G_GEO_TOO_MANY_QUERIES',
msg: 'The given key has gone over the requests limit in the 24 hour period or has submitted too many requests in too short a period of time. If you\'re sending multiple requests in parallel or in a tight loop, use a timer or pause in your code to make sure you don\'t send the requests too quickly.'
}],
/**
* @cfg {String} respErrorTitle
* Defaults to <tt>'Error'</tt>.
*/
respErrorTitle : 'Error',
/**
* @cfg {String} geoErrorMsgUnable
* Defaults to <tt>'Unable to Locate the Address you provided'</tt>.
*/
geoErrorMsgUnable : 'Unable to Locate the Address you provided',
/**
* @cfg {String} geoErrorTitle
* Defaults to <tt>'Address Location Error'</tt>.
*/
geoErrorTitle : 'Address Location Error',
/**
* @cfg {String} geoErrorMsgAccuracy
* Defaults to <tt>'The address provided has a low accuracy.<br><br>Level {0} Accuracy (8 = Exact Match, 1 = Vague Match)'</tt>.
*/
geoErrorMsgAccuracy : 'The address provided has a low accuracy.<br><br>Level {0} Accuracy (8 = Exact Match, 1 = Vague Match)',
/**
* @cfg {String} gmapType
* The type of map to display, generic options available are: 'map', 'panorama'.
* Defaults to <tt>'map'</tt>.
* More specific maps can be used by specifying the google map type:
* <div class="mdetail-params"><ul>
* <li><b><code>G_NORMAL_MAP</code></b> : <div class="sub-desc"><p>
* Displays the default road map view
* </p></div></li>
* <li><b><code>G_SATELLITE_MAP</code></b> : <div class="sub-desc"><p>
* Displays Google Earth satellite images
* </p></div></li>
* <li><b><code>G_HYBRID_MAP</code></b> : <div class="sub-desc"><p>
* Displays a mixture of normal and satellite views
* </p></div></li>
* <li><b><code>G_DEFAULT_MAP_TYPES</code></b> : <div class="sub-desc"><p>
* Contains an array of the above three types, useful for iterative processing.
* </p></div></li>
* <li><b><code>G_PHYSICAL_MAP</code></b> : <div class="sub-desc"><p>
* Displays a physical map based on terrain information.
* </p></div></li>
* <li><b><code>G_MOON_ELEVATION_MAP</code></b> : <div class="sub-desc"><p>
* Displays a shaded terrain map of the surface of the Moon, color-coded by altitude.
* </p></div></li>
* <li><b><code>G_MOON_VISIBLE_MAP</code></b> : <div class="sub-desc"><p>
* Displays photographic imagery taken from orbit around the moon.
* </p></div></li>
* <li><b><code>G_MARS_ELEVATION_MAP</code></b> : <div class="sub-desc"><p>
* Displays a shaded terrain map of the surface of Mars, color-coded by altitude.
* </p></div></li>
* <li><b><code>G_MARS_VISIBLE_MAP</code></b> : <div class="sub-desc"><p>
* Displays photographs taken from orbit around Mars.
* </p></div></li>
* <li><b><code>G_MARS_INFRARED_MAP</code></b> : <div class="sub-desc"><p>
* Displays a shaded infrared map of the surface of Mars, where warmer areas appear brighter and colder areas appear darker.
* </p></div></li>
* <li><b><code>G_SKY_VISIBLE_MAP</code></b> : <div class="sub-desc"><p>
* Displays a mosaic of the sky, as seen from Earth, covering the full celestial sphere.
* </p></div></li>
* </ul></div>
* Sample usage:
* <pre><code>
* gmapType: G_MOON_VISIBLE_MAP
* </code></pre>
*/
gmapType : 'map',
/**
* @cfg {Object} setCenter
* The initial center location of the map. The map needs to be centered before it can be used.
* A marker is not required to be specified.
* More markers can be added to the map using the <code>{@link #markers}</code> array.
* For example:
* <pre><code>
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},

// or just specify lat/long
setCenter: {
lat: 42.345573,
lng: -71.098326
}
* </code></pre>
*/
/**
* @cfg {Number} zoomLevel
* The zoom level to initialize the map at, generally between 1 (whole planet) and 40 (street).
* Also used as the zoom level for panoramas, zero specifies no zoom at all.
* Defaults to <tt>3</tt>.
*/
zoomLevel: 3,
/**
* @cfg {Number} yaw
* The Yaw, or rotational direction of the users perspective in degrees. Only applies to panoramas.
* Defaults to <tt>180</tt>.
*/
yaw: 180,
/**
* @cfg {Number} pitch
* The pitch, or vertical direction of the users perspective in degrees.
* Defaults to <tt>0</tt> (straight ahead). Valid values are between +90 (straight up) and -90 (straight down).
*/
pitch: 0,
/**
* @cfg {Boolean} displayGeoErrors
* True to display geocoding errors to the end user via a message box.
* Defaults to <tt>false</tt>.
*/
displayGeoErrors: false,
/**
* @cfg {Boolean} minGeoAccuracy
* The level (between 1 & 8) to display an accuracy error below. Defaults to <tt>7</tt>. For additional information
* see <a href="http://code.google.com/apis/maps/documentation/reference.html#GGeoAddressAccuracy">here</a>.
*/
minGeoAccuracy: 7,
/**
* @cfg {Array} mapConfOpts
* Array of strings representing configuration methods to call, a full list can be found
* <a href="http://code.google.com/apis/maps/documentation/reference.html#GMap2">here</a>.
* For example:
* <pre><code>
* mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
* </code></pre>
*/
/**
* @cfg {Array} mapControls
* Array of strings representing map controls to initialize, a full list can be found
* <a href="http://code.google.com/apis/maps/documentation/reference.html#GControlImpl">here</a>.
* For example:
* <pre><code>
* mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl']
* </code></pre>
*/
/**
* @cfg {Array} markers
* Markers may be added to the map. Instead of specifying <code>lat</code>/<code>lng</code>,
* geocoding can be specified via a <code>geoCodeAddr</code> string.
* For example:
* <pre><code>
markers: [{
//lat: 42.339641,
//lng: -71.094224,
// instead of lat/lng:
geoCodeAddr: '465 Huntington Avenue, Boston, MA, 02215-5597, USA',
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
* </code></pre>
*/
// private
mapDefined: false,
// private
mapDefinedGMap: false,
// private
initComponent : function(){

this.addEvents(
/**
* @event mapready
* Fires when the map is ready for interaction
* @param {GMapPanel} this
* @param {GMap} map
*/
'mapready',
'zoomended'
);
Ext.ux.GMapPanel.superclass.initComponent.call(this);

},
// private
afterRender : function(){

var wh = this.ownerCt.getSize();
Ext.applyIf(this, wh);

Ext.ux.GMapPanel.superclass.afterRender.call(this);

if (this.gmapType === 'map'){
this.gmap = new GMap2(this.body.dom);
this.mapDefined = true;
this.mapDefinedGMap = true;
}

if (this.gmapType === 'panorama'){
this.gmap = new GStreetviewPanorama(this.body.dom);
this.mapDefined = true;
}

if (!this.mapDefined && this.gmapType){
this.gmap = new GMap2(this.body.dom);
this.gmap.setMapType(this.gmapType);
this.mapDefined = true;
this.mapDefinedGMap = true;
}

GEvent.bind(this.getMap(), 'load', this, this.onMapReady);
GEvent.bind(this.getMap(), 'zoomend', this, this.onZoomEnd);

if (typeof this.setCenter === 'object') {
if (typeof this.setCenter.geoCodeAddr === 'string'){
this.geoCodeLookup(this.setCenter.geoCodeAddr, this.setCenter.marker, false, true, this.setCenter.listeners);
}else{
if (this.gmapType === 'map'){
var point = this.fixLatLng(new GLatLng(this.setCenter.lat,this.setCenter.lng));
this.getMap().setCenter(point, this.zoomLevel);
}
if (typeof this.setCenter.marker === 'object' && typeof point === 'object') {
this.addMarker(point, this.setCenter.marker, this.setCenter.marker.clear);
}
}
if (this.gmapType === 'panorama'){
this.getMap().setLocationAndPOV(new GLatLng(this.setCenter.lat,this.setCenter.lng), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoomLevel});
}
}

},
// private
onMapReady : function(){

this.addMapControls();
this.addOptions();

this.addMarkers(this.markers);
this.addKMLOverlay(this.autoLoadKML);

this.fireEvent('mapready', this, this.getMap());

},
// private
onZoomEnd : function(e){
this.fireEvent('zoomended', e);
},
// private
onResize : function(w, h){

Ext.ux.GMapPanel.superclass.onResize.call(this, w, h);

// check for the existance of the google map in case the onResize fires too early
if (typeof this.getMap() == 'object') {
this.getMap().checkResize();
}

},
// private
setSize : function(width, height, animate){

Ext.ux.GMapPanel.superclass.setSize.call(this, width, height, animate);

// check for the existance of the google map in case setSize is called too early
if (typeof this.getMap() == 'object') {
this.getMap().checkResize();
}

},
/**
* Returns the current google map which can be used to call Google Maps API specific handlers.
* @return {GMap} this
*/
getMap : function(){

return this.gmap;

},
/**
* Returns the maps center as a GLatLng object
* @return {GLatLng} this
*/
getCenter : function(){

return this.fixLatLng(this.getMap().getCenter());

},
/**
* Returns the maps center as a simple object
* @return {Object} this has lat and lng properties only
*/
getCenterLatLng : function(){

var ll = this.getCenter();
return {lat: ll.lat(), lng: ll.lng()};

},
/**
* Creates markers from the array that is passed in. Each marker must consist of at least
* <code>lat</code> and <code>lng</code> properties or a <code>geoCodeAddr</code>.
* @param {Array} markers an array of marker objects
*/
addMarkers : function(markers) {

if (Ext.isArray(markers)){
for (var i = 0; i < markers.length; i++) {
if (typeof markers[i].geoCodeAddr == 'string') {
this.geoCodeLookup(markers[i].geoCodeAddr, markers[i].marker, false, markers[i].setCenter, markers[i].listeners, markers[i].infoWindowHtml);
}else{
var mkr_point = this.fixLatLng(new GLatLng(markers[i].lat, markers[i].lng));
this.addMarker(mkr_point, markers[i].marker, false, markers[i].setCenter, markers[i].listeners, markers[i].infoWindowHtml);
}
}
}

},
/**
* Creates a single marker.
* @param {Object} point a GLatLng point
* @param {Object} marker a marker object consisting of at least lat and lng
* @param {Boolean} clear clear other markers before creating this marker
* @param {Boolean} center true to center the map on this marker
* @param {Object} listeners a listeners config
* @param {Object} infoWindowHtml to add (optional).
*/
addMarker : function(point, marker, clear, center, listeners, infoWindowHtml){

Ext.applyIf(marker,G_DEFAULT_ICON);

if (clear === true){
this.getMap().clearOverlays();
}
if (center === true) {
this.getMap().setCenter(point, this.zoomLevel);
}

var mark = new GMarker(point,marker);
if (typeof listeners === 'object'){
for (evt in listeners) {
GEvent.bind(mark, evt, this, listeners[evt]);
}
}
if(infoWindowHtml){
GEvent.addListener(mark, "click", function() {
mark.openInfoWindowHtml(infoWindowHtml);
});
}
this.getMap().addOverlay(mark);

},
// private
addMapControls : function(){

if (this.gmapType === 'map') {
if (Ext.isArray(this.mapControls)) {
for(i=0;i<this.mapControls.length;i++){
this.addMapControl(this.mapControls[i]);
}
}else if(typeof this.mapControls === 'string'){
this.addMapControl(this.mapControls);
}else if(typeof this.mapControls === 'object'){
this.getMap().addControl(this.mapControls);
}
}

},
/**
* Adds a GMap control to the map.
* @param {String/Object} mc a string representation of the control to be instantiated or an already instantiated control.
*/
addMapControl : function(mc){

if (Ext.isObject(mc)) {
this.getMap().addControl(mc);
} else {
var mcf = window[mc];
if (typeof mcf === 'function') {
this.getMap().addControl(new mcf());
}
}

},
// private
addOptions : function(){

if (Ext.isArray(this.mapConfOpts)) {
var mc;
for(i=0;i<this.mapConfOpts.length;i++){
this.addOption(this.mapConfOpts[i]);
}
}else if(typeof this.mapConfOpts === 'string'){
this.addOption(this.mapConfOpts);
}

},
/**
* Adds a GMap option to the map.
* @param {String} mo a string representation of the option to be instantiated.
*/
addOption : function(mo){

var mof = this.getMap()[mo];
if (typeof mof === 'function') {
this.getMap()[mo]();
}

},
/**
* Loads a KML file into the map.
* @param {String} kmlfile a string URL to the KML file.
*/
addKMLOverlay : function(kmlfile){

if (typeof kmlfile === 'string' && kmlfile !== '') {
var geoXml = new GGeoXml(kmlfile);
this.getMap().addOverlay(geoXml);
}

},
/**
* Looks up and address and optionally add a marker, center the map to this location, or
* clear other markers. Sample usage:
* <pre><code>
buttons: [
{
text: 'Fenway Park',
handler: function(){
var addr = '4 Yawkey Way, Boston, MA, 02215-3409, USA';
Ext.getCmp('my_map').geoCodeLookup(addr, undefined, false, true, undefined);
}
},{
text: 'Zoom Fenway Park',
handler: function(){
Ext.getCmp('my_map').zoomLevel = 19;
var addr = '4 Yawkey Way, Boston, MA, 02215-3409, USA';
Ext.getCmp('my_map').geoCodeLookup(addr, undefined, false, true, undefined);
}
},{
text: 'Low Accuracy',
handler: function(){
Ext.getCmp('my_map').geoCodeLookup('Paris, France', undefined, false, true, undefined);
}
},{

text: 'Bogus Address',
handler: function(){
var addr = 'Some Fake, Address, For, Errors';
Ext.getCmp('my_map').geoCodeLookup(addr, undefined, false, true, undefined);
}
}
]
* </code></pre>
* @param {String} addr the address to lookup.
* @param {Object} marker the marker to add (optional).
* @param {Boolean} clear clear other markers before creating this marker
* @param {Boolean} center true to set this point as the center of the map.
* @param {Object} listeners a listeners config
* @param {Object} infoWindowHtml to add (optional).
*/
geoCodeLookup : function(addr, marker, clear, center, listeners, infoWindowHtml) {

if (!this.geocoder) {
this.geocoder = new GClientGeocoder();
}
this.geocoder.getLocations(addr, this.addAddressToMap.createDelegate(this, [addr, marker, clear, center, listeners, infoWindowHtml], true));

},
// private
addAddressToMap : function(response, addr, marker, clear, center, listeners, infoWindowHtml){
if (!response || response.Status.code != 200) {
this.respErrorMsg(response.Status.code);
}else{
place = response.Placemark[0];
addressinfo = place.AddressDetails;
accuracy = addressinfo.Accuracy;
if (accuracy === 0) {
this.geoErrorMsg(this.geoErrorTitle, this.geoErrorMsgUnable);
}else{
if (accuracy < this.minGeoAccuracy) {
this.geoErrorMsg(this.geoErrorTitle, String.format(this.geoErrorMsgAccuracy, accuracy));
}else{
point = this.fixLatLng(new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]));
if (center){
this.getMap().setCenter(point, this.zoomLevel);
}
if (typeof marker === 'object') {
if (!marker.title){
marker.title = place.address;
}
Ext.applyIf(marker, G_DEFAULT_ICON);
this.addMarker(point, marker, clear, false, listeners, infoWindowHtml);
}
}
}
}

},
// private
geoErrorMsg : function(title,msg){
if (this.displayGeoErrors) {
Ext.MessageBox.alert(title,msg);
}
},
// private
respErrorMsg : function(code){
Ext.each(this.respErrors, function(obj){
if (code == obj.code){
Ext.MessageBox.alert(this.respErrorTitle, obj.msg);
}
}, this);
},
// private
// used to inverse the lat/lng coordinates to correct locations on the sky map
fixLatLng : function(llo){
if (this.getMap().getCurrentMapType()) {
if (this.getMap().getCurrentMapType().QO == 'visible') {
llo.lat(180 - llo.lat());
llo.lng(180 - llo.lng());
}
}
return llo;
}
});

Ext.reg('gmappanel',Ext.ux.GMapPanel);

moegal
21 Jan 2010, 1:27 PM
SORRY, double post.

TigersWay
1 Feb 2010, 6:55 AM
Trying to save and recover a marker position, I never succeed to go back exactly in the same position.

Reading from the db, I can find the last exact "dragend" position.
Adding a new marker with that same position.....
... And I am a little bit out! Not much, but at least 1 street away :-?

Any idea, what I am doing wrong?
(The default center point is in Bangkok)



var values = panelForm.getForm().getFieldValues();
map.addMarker(
new GLatLng(values.Lat?values.Lat:13.740208, values.Lng?values.Lng:100.562882),
{title:'MyCenter', draggable:true, icon:getIcon()},
null,
true,
{dragend: function(ll) {
//console.dir(ll);
panelForm.getForm().setValues({Lat:ll.lat(), Lng:ll.lng()});
}
});

extjsuser2010
3 Mar 2010, 2:04 AM
hi i am getting an error - "Gmap2 is Undefined". can you please tell me why this is happening....

madcity
27 Mar 2010, 9:32 PM
I am using the r28 version with the Google 3 api. I have setup a basic test using the code for generating a window. The code works great when I supply the lat/lng but when I set the address using the geoCodeAddr, it just returns and empty window with the google controls.




xtype: "trigger",
fieldLabel: "Street",
name: "street",
id: "aStreet",
width: 227,
onTriggerClick: function(){
// create the window on the first click and reuse on subsequent clicks
var mapwin;
if(!mapwin){
mapwin = new Ext.Window({
layout: 'fit',
title: 'Office Location',
closeAction: 'hide',
width:550,
height:550,
x: 60,
y: 100,
items: {
xtype: 'gmappanel',
zoomLevel: 14,
gmapType : 'map',
setCenter: {
//lat: 42.345573,
//lng: -71.098326
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA'
}
}
});
}
mapwin.show();
},
triggerConfig: {
tag: "img",
src: Ext.BLANK_IMAGE_URL,
cls: "x-form-trigger x-form-search-trigger",
qtip: 'Click to show in Google Maps.'}


There are no errors thrown in Firebug. I must be missing something here. Any ideas?

ADP-LMY
20 Apr 2010, 6:48 AM
Hello,

i have the same probem as MAdcity : The (google)map is not displayed when i put a geoCodeAddr in replacement of a lat/lng.

Any ideas ?

VinylFox
23 Apr 2010, 8:28 AM
You setting a marker for that center point?

Try setting a breakpoint in the addAddressToMap method and see what's happening.

a06mikkl
28 Apr 2010, 10:56 PM
I'm having some trouble getting the gmappanel working. When I run the GMapWindow example from the ext examples everything works fine, but when I try to make my own page with a gmappanel I get the following error:

b[d.xtype || e] is not a constructorI include ext-base.js, ext-all.js and Ext.ux.GMapPanel.js in that order. I also have my own working google maps key, and my script is basicly the same as in the example:

Ext.onReady(function(){

var mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width:400,
height:400,
x: 40,
y: 60,
items: {
xtype: 'gmappanel',
zoomLevel: 14,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
lng: -71.094224,
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
}
});

mapwin.show();
});I must have missed something very basic, so please help me out :)

thanks!

a06mikkl
28 Apr 2010, 11:11 PM
I'm having some trouble getting the gmappanel working. When I run the GMapWindow example from the ext examples everything works fine, but when I try to make my own page with a gmappanel I get the following error:

b[d.xtype || e] is not a constructorI include ext-base.js, ext-all.js and Ext.ux.GMapPanel.js in that order. I also have my own working google maps key, and my script is basicly the same as in the example:

Ext.onReady(function(){

var mapwin = new Ext.Window({
layout: 'fit',
title: 'GMap Window',
closeAction: 'hide',
width:400,
height:400,
x: 40,
y: 60,
items: {
xtype: 'gmappanel',
zoomLevel: 14,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
setCenter: {
geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
marker: {title: 'Fenway Park'}
},
markers: [{
lat: 42.339641,
lng: -71.094224,
marker: {title: 'Boston Museum of Fine Arts'},
listeners: {
click: function(e){
Ext.Msg.alert('Its fine', 'and its art.');
}
}
},{
lat: 42.339419,
lng: -71.09077,
marker: {title: 'Northeastern University'}
}]
}
});

mapwin.show();
});I must have missed something very basic, so please help me out

thanks!

a06mikkl
29 Apr 2010, 11:27 PM
Sorry for the double post, and nevermind the problem I had before. I am now using the GMapPanel3.js version and I don't get that error message anymore.

However, I do have some other problems.
I want to add a GOverviewMapControl to the map, but it won't get added. Looking in the GMapPanel3.js file i notice that the controls gets added in the onMapReady function:

onMapReady : function(){

this.addMapControls();
this.addOptions();

this.addMarkers(this.markers);

this.fireEvent('mapready', this, this.getMap());

},I tried to put a simple alert() in that fuction for debugging and it turns out that the function never gets called. Do I have to add some kind of eventlistener to my GMapPanel?

this is my code for creating the mappanel:

var extMap = new Ext.ux.GMapPanel({
id:'extMap',
title: 'Map',
zoomLevel: 13,
gmapType: 'map',
mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
mapControls: ['GSmallMapControl','GMapTypeControl','GOverviewMapControl'],
setCenter: {
lat: 58.400,
lng: 13.850
}
});

cdt3pm
26 May 2010, 12:29 PM
I think my co-worker figured out the setCenter problem. In the GMapPanel.js file, move the following code to before the "if (typeof this.setCenter === 'object') {" line

GEvent.bind(this.gmap, 'load', this, function(){
this.onMapReady();
});

keckeroo
3 Jun 2010, 8:45 AM
I've noticed a coding error in the GMapPanel3.js which breaks the use of geoCodeAddr in the setCenter config option. Just in case others were having the same problem I was having in maps not rendering when using addresses only.



addAddressToMap : function(response, status, addr, marker, clear, center, listeners){
if (!response || status !== 'OK') {
this.respErrorMsg(status);
}else{
var place = response[0].geometry.location;
var accuracy;
if (false && accuracy === 0) {
this.geoErrorMsg(this.geoErrorTitle, this.geoErrorMsgUnable);
}else{
if (false && accuracy < this.minGeoAccuracy) {
this.geoErrorMsg(this.geoErrorTitle, String.format(this.geoErrorMsgAccuracy, accuracy));
}else{

/// Changed place.af, place.cf to place.lat(), place.lng()

point = this.fixLatLng(new google.maps.LatLng(place.lat(), place.lng()));

if (center){
this.getMap().setCenter(point, this.zoomLevel);
}
if (typeof marker === 'object') {
if (!marker.title){
marker.title = response.formatted_address;
}
Ext.applyIf(marker, {});
this.addMarker(point, marker, clear, false, listeners);
}
}
}
}

VinylFox
3 Jun 2010, 9:04 AM
Thanks for the fix, ill make your changes and commit it later this evening.

keckeroo
3 Jun 2010, 9:16 AM
Also notice the error 'markers' is undefined - so i also added the private variable

markers: [],

just after the first config option.

The absence of this prevented the use of 'marker' in the setCenter config option.

Lovely API - thanks for all your hard work.

Kev

madcity
5 Jun 2010, 9:42 PM
keckeroo, thanks you fixed the problems I was having with r28!