Custom Menu in Google Maps API v3

I am working with google maps api v3 for some time, isn’t perfect (check memory bugs) but it’s faster than api v2.

Since default menu isn’t pretty and doesn’t include a street button, I start tweaking around the api / forums/ blogs to build my own custom menu and I’m gonna show you how you can do it in your site.

Firstly, let’s make a sprite for our buttons background. Chris explains better how to do it in his Sprite Post.

Ignore the +/- buttons, aren’t used in this post.

Well, there is no text on buttons, we’ll put the text in javascript code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
.mycontrol {
width:186px; height:22px; margin-top:10px; padding-right:20px;

}
.mycontrol a {
color: #2E5896; font-family: Tahoma, sans-serif; font-size:11px; font-weight:bold;text-decoration:none; cursor:pointer;display:block;float:left;text-align:center; padding-top:3px;height:20px;background:url('http://images.joover.com/map01_sprite.png');
}
.mycontrol a:hover {
color: #fff;
}
.mycontrol a.map {
background-position: -70px -1px; width:36px;

}
.mycontrol a.map:hover, .mycontrol a.map_hover {
background-position: -70px -25px;color: #fff; width:36px;
}
.mycontrol a.street {
background-position: -106px -1px; width:45px;
}
.mycontrol a.street:hover, .mycontrol a.street_hover {
background-position: -106px -25px; color: #fff; width:45px;
}
.mycontrol a.satellite {
background-position: -151px -1px; width:55px;
}
.mycontrol a.satellite:hover, .mycontrol a.satellite_hover {
background-position: -151px -25px; color: #fff; width:55px;
}
.mycontrol a.hybrid {
background-position: -206px -1px; width:50px;
}
.mycontrol a.hybrid:hover, .mycontrol a.hybrid_hover {
background-position: -206px -25px; color: #fff; width:50px;
}
.mycontrol {         width:186px; height:22px; margin-top:10px; padding-right:20px;        }
.mycontrol a {    color: #2E5896; font-family: Tahoma, sans-serif; font-size:11px; font-weight:bold;text-decoration:none;    cursor:pointer;display:block;float:left;text-align:center; padding-top:3px;height:20px;    background:url('http://images.joover.com/map01_sprite.png'); }
.mycontrol a:hover {    color: #fff; }
.mycontrol a.map {    background-position: -70px -1px; width:36px;     }
.mycontrol a.map:hover, .mycontrol a.map_hover {    background-position: -70px -25px;color: #fff; width:36px;  }
.mycontrol a.street {    background-position: -106px -1px; width:45px;        }
.mycontrol a.street:hover, .mycontrol a.street_hover {    background-position: -106px -25px; color: #fff; width:45px;      }
.mycontrol a.satellite {    background-position: -151px -1px; width:55px; }
.mycontrol a.satellite:hover, .mycontrol a.satellite_hover {    background-position: -151px -25px; color: #fff; width:55px;}
.mycontrol a.hybrid {    background-position: -206px -1px; width:50px;      }
.mycontrol a.hybrid:hover, .mycontrol a.hybrid_hover {    background-position: -206px -25px; color: #fff; width:50px;         }

Explanations on above css code:
- mycontrol class represents the whole menu div
- mycontrol a, a:hover – general link properties (all common properties)
- mycontrol a.map, a.street, a.satellite, a.hybrid – menu buttons properties
- mycontrol a.map:hover, a.street:hover, a.satellite:hover, a.hybrid:hover – menu buttons properties with hover

Now, let me exaplain JS code for the map type menu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/**
Declare variables needed in this code
*/


    var map = null;
    var pano = null;  
    var menu = null;

    var _DLAT = 33.029125000000; // latitude
    var _DLNG = -117.287231000000; // longitude
    var _DNAME = "main_map"; // map div ID
   
/**
- declare new object ta (namespace)
- adding a new method to ta which initialize a menu and return the code for menu
**/


    ta = {};                        
    ta.addMapType = function (d, sf) {
        var b = d.init(sf);
        return b.c;
    }
/**
- declare new object type MyMapType representing the menu
*/
   
    ta.MyMapType = function () {
       
/**
- init method creates a div with four links
- adding listener to each button (this.listen)
- if sf is 0 then we activate Map button on first load (this.activeLink(this.c, this.map);)
*/

 
        this.init = function (sf) {
            this.c = document.createElement('DIV');  
            this.c.className = 'mycontrol';      
            this.map = document.createElement('A');
            this.map.className = this.map.id =  'map';
            this.map.innerHTML = 'Map';
            this.listen([this.map, this.c, google.maps.MapTypeId.ROADMAP,'map']);
            this.c.appendChild(this.map);

            this.street = document.createElement('A');
            this.street.className = this.street.id = 'street';
            this.street.innerHTML = 'Street';            
            this.listen([this.street, this.c, 0,'street']);
            this.c.appendChild(this.street);

            this.satellite = document.createElement('A');
            this.satellite.className = this.satellite.id = 'satellite';
            this.satellite.innerHTML = 'Satellite';
            this.listen([this.satellite, this.c, google.maps.MapTypeId.SATELLITE,'satellite']);
            this.c.appendChild(this.satellite);
           
            this.hybrid = document.createElement('A');
            this.hybrid.className = this.hybrid.id = 'hybrid';
            this.hybrid.innerHTML = 'Hybrid';            
            this.listen([this.hybrid, this.c, google.maps.MapTypeId.HYBRID,'hybrid']);
            this.c.appendChild(this.hybrid);
                       
            if (!sf) this.activeLink(this.c, this.map);
           
            return this;    
        }
     
/**
- set active link (hover)
- co represents menu div
- d represents link name we want to make it active
*/

 
        this.activeLink = function(co, d){
            var b,c;            
            b = co.getElementsByTagName('A');
            for(c=0; c < b.length; c++){
                b[c].className = b[c].id;
            }            
            d.className = d.id + '_hover';            
        };
 
/**
- add a DOM listener to each link
- dt is an array with link object, menu object, google map type, and link name
*/

       
        this.listen = function (dt) {
            var e = this;                                  
                                   
            google.maps.event.addDomListener(dt[0], 'click', function(){                              
             
// if object isn't street link, then
// - make street panorama not visible,
// - set map type
// - set active link
   
                if (dt[3] != 'street') {
                   
                    pano.setVisible(false);
                    map.setMapTypeId(dt[2]);                                
                    e.activeLink(dt[1], dt[0]);
                   
                } else {                          
// else make pano visible                    
                    pano.setVisible(true);  
                   
                }                
               
            });                                
        }
    }
// initialize google map    
    function init() {
// making a new googla map latLng object using _DLAT, _DLNG
// _DLAT, _DLNG are defined at the beginning of the script        
        var point_0 = new google.maps.LatLng(_DLAT, _DLNG);
// map options        
        var myOptions = {
            zoom: 16,
            center: point_0,                    
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            navigationControl: true,
            navigationControlOptions: {
                style: google.maps.NavigationControlStyle.SMALL
            },
            mapTypeControl: false,
            mapTypeControlOptions: {
                mapTypeIds: [google.maps.MapTypeId.ROADMAP,
                            google.maps.MapTypeId.SATELLITE,
                            google.maps.MapTypeId.HYBRID]
            },
            streetViewControl: true
        }
// make a new map object
// adding a new marker with custom icon
        map = new google.maps.Map(document.getElementById(_DNAME), myOptions);
        var marker = new google.maps.Marker({
            position: point_0,
            map: map,
            icon: 'http://images.joover.com/icons/home6.png'
        });

        var panoramaOptions = {
          position: point_0,
          pov: {
            heading: 34,
            pitch: 10,
            zoom: 1
          }
        };
// making a new streetPanorama object        
        pano = new google.maps.StreetViewPanorama(document.getElementById(_DNAME),
                                                        panoramaOptions);                
        menu = new ta.MyMapType;
       
// adding the menu to pano
           pano.controls[google.maps.ControlPosition.TOP_RIGHT].push(ta.addMapType(menu, 1));        
// adding the menu to map          

 map.controls[google.maps.ControlPosition.TOP_RIGHT].push(ta.addMapType(menu, 0));
// because I use same container for both panorama and map
// I check for for visible_changed event on pano object
        google.maps.event.addListener(pano, 'visible_changed', function(ev){
// if street is visible, make street link active,
// remove last control, add new control div
            if (this.getVisible()) {
                menu.activeLink(menu.c, menu.street);
                pano.controls[google.maps.ControlPosition.TOP_RIGHT].pop();                                
                pano.controls[google.maps.ControlPosition.TOP_RIGHT].push(menu.c);        
            } else {                
                map.controls[google.maps.ControlPosition.TOP_RIGHT].pop();
                map.controls[google.maps.ControlPosition.TOP_RIGHT].push(menu.c);      
            }
        });                
        // default settings
        pano.setVisible(false);              
        map.setStreetView(pano);                        
       
   
    }
    // we call init on onload
    window.onload = init;

Map Selected

Map Type on Google Map Custom Menu

Street Selected

Street Type on Google Map Custom Menu

Live Sample

If you have questions or notes about this menu contact me;)

To read:
http://code.google.com/apis/maps/documentation/javascript/
groups.google.com/group/google-maps-js-api-v3

Windows 7 install error – cannot create system disk

After few years of hard use i found out that my hdd is dying, some bad sectors appeared on it (1% of the surface).
If you notice slow editor (any) file loading, saving do a hdd check for safety (hdtune), if it’s green you are physically good, the problem might be on your bios or window settings.

Still being a xp user on a multiple core notebook in w7 era and with my friends bugging me to install a better os (not best) i said to give it a try.

Do you think microsft made the install easier? NO!
On disk chooser menu I got “can’t create a system disk” with no other explanation, even you select the right disk / partition. Then, what’s wrong?

After few searches and reboots I found a solution: w7 install doesn’t like usb hdd’s plugged into your computer, and that is weird logic in my opinion.

Way to go Microsoft !

WordPress and Google Ads

WordPress developers are offering a lot of plugin for users to install. Most of the admins don’t know that plugins are adding extra code to the core, making WP sites slower.

Today I’m gonna talk about how to insert google ads in home page posts. Google doesn’t allow more than 3 ads per page and with WP displaying all posts in a loop you have two options:
- use a plugin to manage ads code and how to display them on site
- learn how to edit wp theme and do the modifications by yourself (the code is very simple)

1. Go in theme editor (theme-editor.php) and open index.php file (main index template).
2. Find the line

1
<?php if (have_posts()) : ?>

Replace it with

1
2
<?php if (have_posts()) : ?>
<?php $post_count_g = 0; ?>

$post_count_g counts number of posts in the loop
We know we have 10 or 20 posts per page and only 3 ads to display but we don’t know when to stop displaying the ads.

3. Find the line:

1
<p class="postmetadata">

Replace it with:

1
2
3
4
5
6
7
8
9
10
<?php if ($post_count_g < 3) { ?>

GOOGLE ADS CODE HERE

<?php
}
$post_count_g++;
?>

<p class="postmetadata">

On each iteration of while (have_posts()) we check if post_count_g is below 3, when it reaches 3 ads are no longer displayed.
Depends on your ad type you can change the 3 value ($post_count_g < 3) to whatever ads number are you allowed to display in your page.

Enjoy blogging ;)

Tags :

I’m lazy

After a long break I’m back blogging.  I was accused of being a lazy dude, it’s true, all developers are at some point :) , but I will try with this new blog to deliver more words on some common IT problems and not only.

Hang on with me;)

Tags :