Jun 05 2010

Google map v3 Cakephp Helper

Classified in: CakePHP,Google,Google Maps,PHP,Web toolspaomic at 9:06 am

Recetly I found out a nice google maps helper for Cakephp, but it is based on version 2. There is a new versione of the API, v3, which has many improvements,  including faster loading time, better compatibility with mobile devices and more. Since I could not find an helper for this new version, I decided to create it on my own, and here is it!!

First, create the googlemap.php file under views / helpers, and copy/paste this:

<?php
/*
 * CakeMap -- a google maps integrated application built on CakePHP framework.
 * Based on initial versione from Garrett J. Woodworth : gwoo@rd11.com
 * Rewritten by  : http://www.small-software-utilities.com
 *
 * @author      info@small-software-utilities.com
 * @version     0.2
 * @license     OPPL
 *
 * Modified by     Mahmoud Lababidi <lababidi@bearsontherun.com>
 * Date        Dec 16, 2006
 * Rewritten by small software utilities <info@small-software-utilities.com>
 * Date        May, 2010
 */
class GoogleMapHelper extends Helper {
    var $errors = array();
    var $key = "your key here, not needed for v3";
    var $url ="http://maps.google.com/maps/api/js?sensor=false";
    function map($default, $style = 'width: 400px; height: 400px' )
    {
        //if (empty($default)){return "error: You have not specified an address to map"; exit();}
        $out = "<div id=\"map\"";
        $out .= isset($style) ? "style=\"".$style."\"" : null;
        $out .= " ></div>";
        $out .= "
        <script type=\"text/javascript\">
        //<![CDATA[
     var directionDisplay;
    var directionsService = new google.maps.DirectionsService();
    var map;
    var iconimage = \"http://labs.google.com/ridefinder/images/mm_20_red.png\";
         var iconshadow = \"http://labs.google.com/ridefinder/images/mm_20_shadow.png\";
         var myOptions = {
            zoom: ".$default['zoom'].",
            center: new google.maps.LatLng(".$default['lat'].", ".$default['long']."),
            mapTypeId: google.maps.MapTypeId.ROADMAP,
        streetViewControl: true
          };
      var map = new google.maps.Map(document.getElementById(\"map\"), myOptions);
      // global infowindow object
      var globalInfowindow = new google.maps.InfoWindow();
      function cleardirs()
      {
          if(directionsDisplay)
              directionsDisplay.setMap(null);
          div = document.getElementById('".(isset($default['directions_div'])?$default['directions_div']:'directions_div')."');
          if(div)
              div.innerHTML = \"\";
      }
               ";
    if(isset($default['directions_div']))
            {
                $out .= "
                  directionsDisplay = new google.maps.DirectionsRenderer();
              directionsDisplay.setMap(map);
              directionsDisplay.setPanel(document.getElementById('".$default['directions_div']."'));
              function calcRoute(fromid,tolat,tolon) {
              directionsDisplay.setMap(map);
                from = document.getElementById(fromid).value;
              var start = from;
              var end = new google.maps.LatLng(tolat,tolon);
              var request = {
                origin:start,
                destination:end,
                travelMode: google.maps.DirectionsTravelMode.DRIVING
              };
              directionsService.route(request, function(result, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                  directionsDisplay.setDirections(result);
                }
              });
}
                ";
            }
        $out .="
        //]]>
        </script>";
        return $out;
    }
    function addMarkers(&$data, $icon=null)
    {
        $out = "
            <script type=\"text/javascript\">
            //<![CDATA[
            ";
            if(is_array($data))
            {
                $i = 0;
                foreach($data as $n=>$m){
                    $keys = array_keys($m);
                    $point = $m[$keys[0]];
                    if(!preg_match('/[^0-9\\.\\-]+/',$point['longitude']) &&
preg_match('/^[-]?(?:180|(?:1[0-7]\\d)|(?:\\d?\\d))[.]{1,1}[0-9]{0,15}/',$point['longitude'])
                        && !preg_match('/[^0-9\\.\\-]+/',$point['latitude']) &&
preg_match('/^[-]?(?:180|(?:1[0-7]\\d)|(?:\\d?\\d))[.]{1,1}[0-9]{0,15}/',$point['latitude']))
                    {
                        $out .= "
                            var point".$i." = new google.maps.LatLng(".$point['latitude'].",".$point['longitude'].");
                            var marker".$i." = new google.maps.Marker({
                                  position: point".$i.",
                      map: map,
                      title:\"".(isset($point['title'])?$point['title']:'')."\",
                      shadow: iconshadow,
                    icon: iconimage,
                            });";
                        if(isset($point['title'])&&isset($point['html']))
                        {
                           $out .= " var infowindow$i = new google.maps.InfoWindow({
                          content: \"$point[title]$point[html]\"
                      });
                      google.maps.event.addListener(marker".$i.", 'click', function() {
                  infowindow$i.open(map,marker".$i.");
                });";
                        }
                        $data[$n][$keys[0]]['js']="marker$i.openInfoWindowHtml(marker$i.html);";
                        $i++;
                    }
                }
            }
        $out .=    "
                //]]>
            </script>";
        return $out;
    }
    function addClick($var, $script=null)
    {
        $out = "
            <script type=\"text/javascript\">
            //<![CDATA[
            $script
            google.maps.event.addListener(map, 'click', ".$var.", true);
            //]]>
            </script>";
        return $out;
    }
    function addMarkerOnClick($innerHtml = null)
    {
        $mapClick = '
            var mapClick = function (event) {
                var marker = new google.maps.Marker({
                position:event.latLng,
                icon: iconimage,
                map:map
                });
                var infowindow = new google.maps.InfoWindow({
            content: \"'.$innerHtml.'\"
        });
        google.maps.event.addListener(marker, \'click\', function() {
              infowindow.open(map,marker);
        });
            }
        ';
        return $this->addClick('mapClick', $mapClick);
    }
    function moveMarkerOnClick($lngctl, $latctl, $innerHtml = null)
    {
        $mapClick = '
            var mapClick = function (event) {
                marker0.setPosition(event.latLng);
                lngctl = document.getElementById(\''.$lngctl.'\');
                latctl = document.getElementById(\''.$latctl.'\');
                if(lngctl)
                 lngctl.value = event.latLng.lng();
                if(latctl)
                 latctl.value = event.latLng.lat();
            }
        ';
        return $this->addClick('mapClick', $mapClick);
    }
}
?>

To use you just need to add the helper to the controller, or to AppController if you want this in every other controller, like this:

<?php
class MyController extends AppController {
    var $helpers = array( 'Googlemap');
....
}

Then, in the view, add these line:

        $default = array('type'=>'0','zoom'=>13,'lat'=>'42.5846353751749',
'long'=>'11.5191650390625');
        $points = array();
        $points[0]['Point'] = array('longitude' =>$default['long'],'latitude' =>$default['lat']);
        $key = $googlemap->key;
        echo $javascript->link($googlemap->url);
        echo $googlemap->map($default,'width: 600px; height: 400px');
        echo $googlemap->addMarkers($points);
        echo $googlemap->moveMarkerOnClick('StructureLongitudine','StructureLatitudine');

A simple explanation:

points is the array where your store, guess, points! The map methos writes out the js for the map, the addMarkers method add markers to the page. The last method, moveMarkerOnClick, was useful to me, for user placement. With this code you can create a map where the user can click to move the marker. Note that the marker which moves is always the one called marker0. The two methos parameters are the ids of two input boxes, representing latitude and longitude. This id is created automatically by CakePHP by using the usual syntax ControllernameInputname.  The default variable contains map type, zoom level, center of the map respectively. You can also add directions to your map by adding a div, setting and id for it and then passing the id in the default array like this:

'directions_div'=>'directions_div'

You can also use the addMarkerOnClick function, which adds a marker when you click on the map. InfoWindows are supported, just add a title and html item to the point array, they will be used to create an infowindow to be displayed when you click on the marker icon.

Hope this helps!

PS: please not that this is a initial version of the helper, use it at your own risk! But please leave here some comments, feature request, bug, or else!

Thanks!

EDIT: According to Amjith, to use this in cakephp v1.3 you must use:

$this->GoogleMap-> instead of $googlemap->

and name the file helper as google_map.php

EDIT 2: According to Duckula, for compatibility with Cake 1.3, you should use:

var $helpers = array( ‘GoogleMap’);

with capital M.

Sorry for these, but I still did not have the chance to try out v1.3, but I will soon!

Tags:

Feb 15 2009

Megamenu Google penalization

Classified in: Google,SEOpaomic at 3:19 pm

I had a website about Umbria (a region of Italy). It ranked well for tourism-related keywords and had a good number of daily visits. Suddently, visit dropped to 1/10, and they continued to drop. Of course, I mean visits from Google. After some searching and talks with friends, I tought it could be a megamenu penalization. This penalization usually happens when you have large menus shared by all the website pages. I tried to remove the menu, making it different for different cities in the reagion, and after a cuople of days the visits went back (almost) to their original status. Did you ever have a similar penalization?

Tags:

Jul 30 2008

Watch Out, Google, They’re Behind Yooooou…

Classified in: Google,Technology newsje at 9:09 am

Apparently, a group of ex-Google employees have gotten together to give their former employer a run for its money by setting up their very own search engine called Cuil (pronounced ‘cool’). Cuil believe that the service they offer is more efficient and that they possess at least triple the index size that Google has.

A certain IT analyst responded by saying that Cuil is not likely to keep Google awake at night.

But stranger things have happened. You just never know what Cuil is capable of especially as, being former Google employees, they have insider information – they know how Google ticks – and what makes it tick – its strengths and weaknesses (yes, I’m sure that even Google has its weak spot/s). Who’s to say Cuil can’t take some of those weaknesses, spin it on its head and turn it into a strength that propels it head and shoulders above the rest?

Cuil = David; Google = Goliath. Never say never.

I wish them luck. Google has too much power and it’s time their feathers were ruffled a little. Even if Cuil don’t succeed, I hope they at least get Google hot under the collar, leading the way for another company to possibly take it a step further in unhinging them from the top spot. It’s time someone else tried the top spot on for size.

One thing Cuil definitely has over Google is that it doesn’t hold onto personal data (unlike Google who’d love to know how many times you blinked the last time you were online).

Cuil’s design and usability is being criticised by some, but I’d like to see how Google used to look back in the day.

Regardless of how it pans out for Cuil, I admire them for having the courage to challenge Google.

Tags:

May 19 2008

Microsoft Returns / Unused Emails…

Classified in: Google,Microsoft,Software,Technology newsje at 7:22 am

Aaagh! What is up with Microsoft? Do they perhaps need a technical equivalent of a shrink? No sooner did they withdraw their billion-dollar takeover bid for Yahoo, and now they go ahead and change their minds. On Sunday afternoon, they announced that they’re putting in a fresh bid for Yahoo, but apparently this time, it’s not for all of Yahoo’s assets, just some (whatever that means).

How is Microsoft to be taken seriously with the back-and-forths? I wouldn’t. Especially as they were the ones that pulled out of the negotiating table in the first place.

Maybe it’s best for different parts of Yahoo to be owned by more than one company, anyway. It might be healthier that way. I hear Google are working on a deal with Yahoo (for Yahoo to utilise Google search ads on their network).

In other news, did you know that a fifth of Americans, over 20 million of them, have never used email? Ever?

I find that amazing.

Maybe it’s ignorant of me as I’m so used to using the web / emailing, but I do find the findings intriguing especially coming from a developed country, an apparent super power.

My immediate hunch was that age plays a factor in this. And I was right. According to the survey, half of those surveyed were over 65 years old. Education also comes into play with 56% not having gone beyond high-school level. (It’d be interesting to find out the breakdown of the other 50%.)

There were other findings such as 30% of Americans never having created a document on a computer before.

I expect that a lot of this isn’t necessarily down to age and education. Some people who’ve never touched a computer or have never been online might simply be scared of the unknown.

Tags:

May 06 2008

Microsoft Has Left the Building (?)

Classified in: Google,Microsoft,Technology newsje at 2:21 pm

If you ask me, the whole Microsoft bid to takeover Yahoo is getting to be a bit of a joke, don’t you think?

After 3 months of negotiations, you’d think that the finest minds in the technology world would be able to wrap up a deal – but nope, Microsoft and Yahoo are right back where they started (which was where exactly? Maybe they were never anywhere in the first place. Maybe Yahoo was never interested in giving up their goodies and were merely interested in getting some inside information on Microsoft.)

First of all, there’s the embarrassment of looking ‘stoopid’ when things don’t go according to plan – which is exactly why Microsoft should have kept its pretty lil digital mouth firmly shut and not blubbered to the whole world and their mama that they were looking to buy Yahoo out (who does their PR for god’s sake?). I call it cockiness. Serves them right.

In terms of a super-duper advertising network, Yahoo is almost Google; almost, but not quite, but will do very nicely for Microsoft, because Google sure as hell ain’t gonna give up their golden jewels to Microsoft. (Maybe Microsoft was never really looking to take over Yahoo anyway, but were just trying to puff up their chests to Google, i.e. ‘We’ve still got the technical funk, itty bitty Google. And you’d do well to remember that, or else next time we try bedding Yahoo, we’ll win. WO-HA-HAAA.’)

As much as I don’t particularly like Google (or Microsoft, for that matter), I think Google should try stirring things up a bit with their pocket change and make a Yahoo bid of their own. That should take the heat off Britney for a while!

Ah well, I guess we’ll have to watch this space and see what ole’ four-eyed Billy boy’s next move will be.

(Update: Well, it looks like Microsoft have dropped their bid altogether. Apparently, Yahoo asked for a $55bn minimum to the $47.5bn Microsoft offered (up from the $44.6bn previously offered), but neither party could agree on a final figure. Oh well, Google, here’s your chance …if ya think you’re hard enough).

Tags:

Next Page »