Skip to content
Snippets Groups Projects
gmap.module 39.8 KiB
Newer Older
webgeer's avatar
webgeer committed
<?php
/* $Id$ */

define('GMAP_LOAD_METHOD', variable_get('gmap_method','Static'));
define('GMAP_WIDTH', variable_get('gmap_default_width', '300px'));
define('GMAP_HEIGHT', variable_get('gmap_default_height', '200px'));
webgeer's avatar
webgeer committed
define('GMAP_ZOOM', variable_get('gmap_default_zoom', 3));
define('GMAP_CONTROL', variable_get('gmap_default_control', 'Small'));
//define('GMAP_ALIGNMENT', variable_get('gmap_default_allignment', ???));
// variable still defined as gmap_default_latlong to avoid having to upgrade the database
webgeer's avatar
webgeer committed
define('GMAP_LONGLAT', variable_get('gmap_default_latlong', '40,0'));
define('GMAP_TYPE', variable_get('gmap_default_type', 'Map'));
define('GMAP_LINECOLOR1', variable_get('gmap_default_line1_color', '#00cc00'));
define('GMAP_LINECOLOR2', variable_get('gmap_default_line2_color', '#ff0000'));
define('GMAP_LINECOLOR3', variable_get('gmap_default_line3_color', '#0000ff'));
webgeer's avatar
webgeer committed
//define('GMAP_XMAPS', variable_get('gmap_xmaps',0));
define ('GMAP_XMAPS',0); //xmaps not currently compatible with v2 of google maps api
define('GMAP_XMAPS_SCRIPT', variable_get('gmap_xmaps_script','misc/xmaps.1c.js'));
define('GMAP_CLUSTER', variable_get('gmap_cluster',0));
webgeer's avatar
webgeer committed
/**
 * @file
 * GMap Filters is a module to include Google Map in a module
 *
 * GMap filter allows the insertion of a googlemap in a module.  It has
 * a page to creat a macro and then a filter to convet the macro into the
 * html and javascript code required to insert a google map.
 */

function gmap_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('Filter to allow insertion of a google map into a node');
  }
}

function gmap_perm() {
  return array('create macro', 'override defaults', 'show user map', 'user locations');
webgeer's avatar
webgeer committed
}

/**
 *
 * Returns the html required to insert a map from a gmap associative array.
 *
 * @param $gmap
 * An associative array with the following variables set:
 *
 *  id - the id of the map every map on a page must have a unique id
 *  width - width of the map
 *  height - height of the map
webgeer's avatar
webgeer committed
 *  center - a string of the latitude, longitude of the centre of the map
webgeer's avatar
webgeer committed
 *  zoom - the zoom factor of the google map
 *  align - the alignment of the map 'right', 'left' or 'center'
 *  control - the control shown on the map 'Large', 'Small', or 'None'
 *  tcontrol - whether the type control is on the map or not: 'off' or 'on'
webgeer's avatar
webgeer committed
 *  type - 'Map', 'Hybrid' or 'Satellite'
 *  drag - 'yes' or 'no' map is draggable.  Default is 'yes'
webgeer's avatar
webgeer committed
 *  markers - an array of associative arrays for the markers.
 *  shapes - an array of associative arrays for the overlays.
 *  track - a file containing a series of points in .plt format to be
 *  inserted into the node.
webgeer's avatar
webgeer committed
 *  feeds - an associative array of rss feeds
 *
 *  Xmaps must be enabled for circle and polygon to work.
webgeer's avatar
webgeer committed
 *
 * @param $javascript
 * Some javascript to insert into function after drawing the map.
 * note that '{id}' will be replaced with the map id.
webgeer's avatar
webgeer committed
 *
 * @return
 * A string with the google map ready to be inserted into a node.
 *
 */
function gmap_draw_map($gmap, $javascript='') {
  global $base_url;
    _gmap_doheader();
webgeer's avatar
webgeer committed

    $clusterset=false;
    (!isset($gmap['width'])) ? $gmap['width']=GMAP_WIDTH: NULL;
    (!isset($gmap['height'])) ? $gmap['height']=GMAP_HEIGHT:NULL;
    (!isset($gmap['zoom'])) ? $gmap['zoom']=GMAP_ZOOM:NULL;
webgeer's avatar
webgeer committed
    (!isset($gmap['align'])) ? $gmap['align']='':NULL;
    (!isset($gmap['id'])) ? $gmap['id']='map':NULL;
    (!isset($gmap['control'])) ? $gmap['control']=GMAP_CONTROL:NULL;
    (!isset($gmap['type'])) ? $gmap['type']=GMAP_TYPE:NULL;
    (!isset($gmap['tcontrol'])) ? $gmap['tcontrol']='off':NULL;
    (!isset($gmap['drag'])) ? $gmap['drag']='yes':NULL;
webgeer's avatar
webgeer committed

webgeer's avatar
webgeer committed
    if (!isset($gmap['center'])&& isset($gmap['latlong'])){
      //backwards compatible with macros created by previous version of this program
      $gmap['center']=$gmap['latlong'];
    }
    elseif (!isset($gmap['center'])){
webgeer's avatar
webgeer committed
    }

    $style='width: '.gmap_todim($gmap['width']).'; height: '.gmap_todim($gmap['height']).';';
webgeer's avatar
webgeer committed

    switch (strtolower($gmap['align'])) {
      case 'left':
        $style .= ' float: left;';
        break;
      case 'right':
        $style .= ' float: right;';
        break;
      case 'center':
      case 'centre':
        $style .= ' margin-left: auto; margin-right: auto;';
webgeer's avatar
webgeer committed
//    $outtext .= "\n<!--\n\n".print_r($gmap)."\n\n -->\n";
    $outtext.='<div id="'.$gmap['id'].'" style="'.$style.'"></div>
webgeer's avatar
webgeer committed
              //<![CDATA[
              //initialize gmap variables
              var mycontrol=null;
              var mytypecontrol=null;
              var '.$gmap['id'].'=null;
              
              addLoadEvent(gmap_init);  
              addLoadEvent(gmap_load_'.$gmap['id'].');
           
webgeer's avatar
webgeer committed
              function gmap_load_'.$gmap['id'].'() {
webgeer's avatar
webgeer committed
                 '.$gmap['id'].' = new GMap2($("'.$gmap['id'].'"));
                 '.$gmap['id'].'.setCenter(new GLatLng('.$gmap['center'].'), '.$gmap['zoom'].');
webgeer's avatar
webgeer committed
                 ';
    switch (strtolower($gmap['control'])) {
      case 'small':
        $outtext .='mycontrol=new GSmallMapControl();
webgeer's avatar
webgeer committed
                '.$gmap['id'].'.addControl(mycontrol);
                 ';
        break;
      case 'large':
      $outtext .='mycontrol=new GLargeMapControl();
webgeer's avatar
webgeer committed
              '.$gmap['id'].'.addControl(mycontrol);
              ';
    }
webgeer's avatar
webgeer committed

    if (strtolower($gmap['tcontrol'])=='on' || strtolower($gmap['tcontrol'])=='yes') {
      $outtext .= $gmap['id'].'.addControl(mytypecontrol=new GMapTypeControl());
                ';
    }

webgeer's avatar
webgeer committed
    switch (strtolower($gmap['type'])) {
      case 'hybrid':
webgeer's avatar
webgeer committed
        $outtext .= $gmap['id'].".setMapType(G_HYBRID_MAP); \n";
webgeer's avatar
webgeer committed
        break;
webgeer's avatar
webgeer committed
        $outtext .= $gmap['id'].".setMapType(G_SATELLITE_MAP); \n";
webgeer's avatar
webgeer committed
    }
    if (isset($gmap['drag']) && strtolower($gmap['drag'])=='no') {
webgeer's avatar
webgeer committed
      $outtext .= $gmap['id'].".disableDragging(); \n";
webgeer's avatar
webgeer committed
    else {
      $outtest .= "keyboardhandler=new GKeyboardHandler(map);\n";
    }
webgeer's avatar
webgeer committed
    $outext .= $gmap['id'].'.setCenter(new GLatLng('.$gmap['center'].'), '.$gmap['zoom'].");\n";
webgeer's avatar
webgeer committed

webgeer's avatar
webgeer committed
    if (isset($gmap['tracks'])) {
      foreach ($gmap['tracks'] as $value) {
        $tt['points']=array();
        if($trackFH = fopen($tt['filename'], "r")) {
          while(!feof($trackFH)) {
            $line = fgets($trackFH, 4096);
            $line_exploded = explode(",", $line);
            if(count($line_exploded) == 7) {
              $tt['points'][]= trim($line_exploded[0]).', '.trim($line_exploded[1]);
            }
          }
          fclose($trackFH);
        }
webgeer's avatar
webgeer committed
      }
    }
      if (GMAP_CLUSTER) {
        $outtext .="\n var clusterer = new Clusterer(".$gmap['id'].");\n";
webgeer's avatar
webgeer committed
        $clusterset=true;
      $lastmarker='';
      foreach ($gmap['markers'] as $item) {
        $mymarker='';
        $mytext='';
        if (isset($item['markername'])){
          if ($item['markername']==$lastmarker) {
            $i++;
          }
          else {
            $lastmarker=$item['markername'];
            $i=1;
          }
          if (file_exists(variable_get('gmap_markerfiles','modules/gmap/markers').'/'.$item['markername'].$i.'.png')) {
            $mymarker=$base_url.'/'.variable_get('gmap_markerfiles','modules/gmap/markers').'/'.$item['markername'].$i.'.png';
          }
          elseif (file_exists(variable_get('gmap_markerfiles','modules/gmap/markers').'/'.$item['markername'].'.png')) {
            $mymarker=$base_url.'/'.variable_get('gmap_markerfiles','modules/gmap/markers').'/'.$item['markername'].'.png';
          }
        }
        if (isset($item['label']) && strlen($item['label'])>0) {
          $mytext=$item['label'];
webgeer's avatar
webgeer committed
        }
        if (GMAP_CLUSTER) {
webgeer's avatar
webgeer committed
          $outtext .='clusterer.AddMarker(createGMarker(new GLatLng('.$item['point'].'),\''.$mytext.'\',\''.$mymarker."'));\n";
webgeer's avatar
webgeer committed
          $clusterset=true;
        }
        else {
webgeer's avatar
webgeer committed
          $outtext .=$gmap['id'].'.addOverlay(createGMarker(new GLatLng('.$item['point'].'),\''.$mytext.'\',\''.$mymarker."'));\n";
webgeer's avatar
webgeer committed
      }
    }
    if (isset($gmap['shape']) && !variable_get('gmap_xmaps',0)) {
webgeer's avatar
webgeer committed
      //if xmaps is not enabled then just show the lines using straight google maps.
      foreach ($gmap['shape'] as $value) {
        $style ='';
        if (trim($value['type'])=='line') {
          if (isset($value['color'])) {
            $style .=",'".$value['color']."'";
            if (isset($value['width'])) {
              $style .=','.$value['width'];
              if (isset($value['opacity'])) {
                $style .=','.$value['opacity'];
              }
            }
          }
webgeer's avatar
webgeer committed
          $linetxt ='new GLatLng('.implode('), new GLatLng(',$value['points']).')';
//          foreach ($value['points'] as $lvalue) {
//            if (strlen($linetxt)>0) {
//              $linetxt .= ', ';
//            }
//            $linetxt .="new GPoint(".$lvalue.")";
//          }
          $outtext .="\n".$gmap['id'].".addOverlay(new GPolyline([$linetxt] $style));";
    elseif (isset($gmap['shape'])) {
      foreach ($gmap['shape'] as $value) {
        $linestyle=array();
        $fillstyle=array();
          $linestyle[] = 'color: "'.$value['color'].'" ';
          $linestyle[] = 'weight: '.$value['width'];
          $linestyle[] = 'opacity: '.$value['opacity'];
          $linestyle[] = 'pattern: ['.$value['pattern'].'] ';
          $linestyle[] = 'text: "'.$value['text'].'" ';
          $fillstyle[] = 'color: "'.$value['fillcolor'].'" ';
        }
        if (isset($value['fillopacity'])){
          $fillstyle[] = 'opacity: '.$value['fillopacity'];
        $outtext .= 'var lineStyle = {'.implode(',',$linestyle)."};\n";
        if (count($fillstyle)>0) {
          $outtext .= 'var fillStyle = {'.implode(',',$fillstyle)."};\n";
webgeer's avatar
webgeer committed
        }
        else {
          $outtext .= "var fillStyle = null;\n";
        }

        switch ($value['type']) {
          case 'line':
            $outtext .= "var points = []; \n";

            foreach ($value['points'] as $lvalue) {
              $outtext .="points.push(new GPoint(".$lvalue."));\n";
            }
            $outtext .= $gmap['id'].".addOverlay(new XPolyline(points, lineStyle));\n";
            break;
          case 'circle':
            //create a circle by using a radius in km
            if (empty($value['sides'])){
              $value['sides']=36;
            }
            $outtext .= 'var radius = new XDistance('.$value['radius'].",XDistance.KM);\n";
            $outtext .= 'var centre = new GPoint('.$value['center'].");\n";
            $outtext .= $gmap['id'].".addOverlay(XPolygon.createRegularPolygonFromRadius(centre, radius, ".$value['sides'].", 0, lineStyle, fillStyle));\n";
            break;
          case 'rpolygon':
            if (isset($value['sides'])){
              $value['sides']=36;
            }
            $outtext .= "var centre = new GPoint(".$value['center'].");\n";
            $outtext .= $gmap['id'].".addOverlay(XPolygon.createRegularPolygonFromPoint( new GPoint(".$value['center']."), new GPoint(".$value['point']."), 36, lineStyle, fillStyle));\n";
            break;
          case 'polygon':
            $outtext .= "var points=[];\n";
            foreach ($value['points'] as $pvalue) {
              $outtext .= "points.push(new GPoint($pvalue));\n";
            }
            $outtext .= $gmap['id'].".addOverlay(new XPolygon(points, lineStyle, fillStyle));\n";
webgeer's avatar
webgeer committed
    if (isset($gmap['feeds'])) {
//      if (GMAP_CLUSTER && !$clusterset) {
//        $outtext .="\n var clusterer = new Clusterer(".$gmap['id'].");\n";
 //     }
      foreach ($gmap['feeds'] as $item) {
        $mymarker='';
        if (isset($item['markername'])){
          if (file_exists(variable_get('gmap_markerfiles','modules/gmap/markers').'/'.$item['markername'].'.png')) {
            $mymarker=$base_url.'/'.variable_get('gmap_markerfiles','modules/gmap/markers').'/'.$item['markername'].'.png';
          }
        }
        if (isset($item['url'])) {
          $outtext.= "parseGeoRSS(".$gmap['id'].",'".$item['url']."','$mymarker');\n";
        }
      }
    }
    if (strlen($javascript)>0) {
      $javascript=str_replace('{id}',$gmap['id'],$javascript);
      $outtext .=$javascript;
    }
    $outtext .="\n } \n   //]]>
               </script>";
webgeer's avatar
webgeer committed
    return $outtext;
}

/**
 *
 * Cleans the gmap variables to prevent javascript interjection
 *
 * @param $gmap
 * A Gmap variable
 *
 * @return
 * A GMap variable with any dangerous text removed.
webgeer's avatar
webgeer committed
 *
 * This does not really do much of anything right now.
webgeer's avatar
webgeer committed
 */
webgeer's avatar
webgeer committed
  //sanitizes the gmap variables to reduce the possibility of javascript inserts
webgeer's avatar
webgeer committed
  reset($gmap);
  $value=current($gmap);
  do {
    if (key($gmap)=='id') {
            $out = array();
      preg_match('([a-zA-Z1-9_-]*)', $value, $out);
webgeer's avatar
webgeer committed
      if (strlen($out[0])==0) $out[0]='map';
      $gmap[key($gmap)]=$out[0];
webgeer's avatar
webgeer committed
    }
    else {
webgeer's avatar
webgeer committed
      $gmap[key($gmap)]=str_replace(';','',$value);
webgeer's avatar
webgeer committed
    }
webgeer's avatar
webgeer committed
  } while ($value=next($gmap));
webgeer's avatar
webgeer committed
 *
 * @param $instring
 * A string with the settings of gmap insertion in the format var=setting|var2=setting2
 *  The possible variables are
 *  id - the id of the map every map on a page must have a unique id
 *  width - width of the map
 *  height - height of the map
webgeer's avatar
webgeer committed
 *  center - a string of the longitude and latitude of the centre of the map
webgeer's avatar
webgeer committed
 *  zoom - the zoom factor of the google map
 *  align - the alignment of the map 'right', 'left' or 'center'
 *  control - the control shown on the map 'Large', 'Small', or 'None'
 *  type - 'Map', 'Hybrid' or 'Satellite'
 *  points/markers - a string of points to mark on the map with + between
 *          each point
 *  line - the line is defined by a set of points separated by a +
 *  track - Draws a line based on the points in the .plt file
 *  The following shape types require XMaps:
 *  circle - a circle based on a center point and a radius in km separated
 *          by a + and optionally can include the number of sizes.
 *  rpolygon - a regular polygon is defined by the center point and a point
 *          on the permiter separated by a +
 *  polygon - a polygon is defined by a set of points
 *
 *  Each of the shapes types can optionally have charecteristics of colour,
 *  width, opacity, pattern, text, fill colour, fill opacity.  Pattern, text
 *  and fill are all only used by xmaps.
 *      color - hexadecimal for the colour include the '#'
webgeer's avatar
webgeer committed
 *
webgeer's avatar
webgeer committed
 * @return
 * A string with the google map ready to be inserted into a node.
 *
 */
webgeer's avatar
webgeer committed
function gmap_parse_macro($instring,$ver=2) {
webgeer's avatar
webgeer committed
  $statements=explode('|', $instring);
  $j=0;
webgeer's avatar
webgeer committed
  while (isset($statements[$j])) {
webgeer's avatar
webgeer committed
    $t=explode('=', $statements[$j],2);
webgeer's avatar
webgeer committed
      case 'center':
        $gmap['center']=gmap_dopoint(trim($t[1]),$ver);
        break;
        
      case 'points':
      case 'markers':
        unset($markername);
        if (strpos($t[1],'::')) { // note: we don't care about case starting with ':'
          list($markername,$t[1])=explode('::',$t[1],2);
        }
        unset($ttt);
        $ttt = explode('+',$t[1]);
        for ($i =0; $i<count($ttt); $i++) {
          unset($tt);
          if (strpos($ttt[$i],':')) {
            list($tt['point'],$tt['label']) = explode(':',$ttt[$i],2);
webgeer's avatar
webgeer committed
            $tt['point']=gmap_dopoint($tt['point'],$ver);
webgeer's avatar
webgeer committed
            $tt['point']=gmap_dopoint($ttt[$i],$ver);
          }
          if (isset($markername)){
            $tt['markername']=$markername;
          }
          $gmap['markers'][]=$tt;
        }
        break;

      case 'track':
        if (strpos($t[1],':')) { // note: we don't care about case starting with ':'
          list($configs,$t[1])=explode(':',$t[1],2);
          list($tt['color'],$tt['width'],$tt['opacity'],$tt['pattern'],$tt['text'])=explode('/',$configs);
        }
        $tt['filename'] =$t[1];
webgeer's avatar
webgeer committed
        $gmap['tracks'][] = $tt;
webgeer's avatar
webgeer committed
        
      case 'feed':

        $tt['url'] =$t[1];
        $gmap['feeds'][] = $tt;
        break;
      case 'line2':
        if (empty($tt['color'])){
        }
      case 'line3':
        if (empty($tt['color'])){
        }
      case 'line':
        if (strpos($t[1],':')) { // note: we don't care about case starting with ':'
          list($configs,$t[1])=explode(':',$t[1],2);
          list($tt['color'],$tt['width'],$tt['opacity'],$tt['pattern'],$tt['text'])=explode('/',$configs);
        }
        $tt['points'] = explode('+',$t[1]);
webgeer's avatar
webgeer committed
        if ($ver==1) {
          foreach ($tt['points'] as $key=>$value) {
            $tt['points'][$key]=gmap_dopoint($value,$ver);
          }
        }
        $tt['type'] = 'line';
        $gmap['shape'][] = $tt;
        break;

      case 'rpolygon':
        if (strpos($t[1],':')) { // note: we don't care about case starting with ':'
          list($configs,$t[1])=explode(':',$t[1],2);
          list($tt['color'],$tt['width'],$tt['opacity'],$tt['pattern'],$tt['text'],$tt['fillcolor'],$tt['fillopacity'])=explode('/',$configs);
        }
        list($tt['center'],$tt['point'],$tt['sides']) = explode('+',$t[1]);
        $tt['type']='rpolygon';
        $gmap['shape'][] = $tt;
        break;

      case 'circle':
        if (strpos($t[1],':')) { // note: we don't care about case starting with ':'
          list($configs,$t[1])=explode(':',$t[1],2);
          list($tt['color'],$tt['width'],$tt['opacity'],$tt['pattern'],$tt['text'],$tt['fillcolor'],$tt['fillopacity'])=explode('/',$configs);
        }
        list($tt['center'],$tt['radius'],$tt['sides'])= explode('+',$t[1]);
        $tt['type']='circle';
        $gmap['shape'][] = $tt;
        break;

      case 'polygon':
        if (strpos(':',$t[1])) { // note: we don't care about case starting with ':'
          list($configs,$t[1])=explode(':',$t[1],2);
          list($tt['color'],$tt['width'],$tt['opacity'],$tt['pattern'],$tt['text'],$tt['fillcolor'],$tt['fillopacity'])=explode('/',$configs);
        }
        $tt['points'] = explode('+',$t[1]);
        $tt['type']='polygon';
        $gmap['shape'][] = $tt;
        break;


      default:
        $gmap[trim($t[0])] = trim($t[1]);
      }
webgeer's avatar
webgeer committed
    $j++;
  }
/**
 *
 * Creates a map that can be interactively used to fill a form with a
 * location (latitude, longitude and zoom level)
 *
 * @param $map_macro
 * A macro to use as the base map for setting a location.
 * @param $lonform
 * A form element for the longitude to be set.  Should be an associative array in drupal form format.
 * @param $latform
 * A form element for the latitude to be set.
 * @param $zoomform
 * A form element for the zoom to be set.
 * @return
 * A string with the google map code to be inserted onto the page.
 *
 */
webgeer's avatar
webgeer committed
function gmap_set_location($map_macro,&$lonform,&$latform) {
//&$zoomform=NULL) {
  $map=gmap_parse_macro($map_macro);
webgeer's avatar
webgeer committed
  $zoom=$map['zoom'];

//  $form['coordinates']=array('#type' => 'fieldset','#title' => t('Coordinates'));
  $latform['#id']='gmap-latitude';
  $latform['#attributes']['onchange']='gmap_textchange('.$map['id'].');';
  $lonform['#id']='gmap-longitude';
  $lonform['#attributes']['onchange']='gmap_textchange('.$map['id'].');';
webgeer's avatar
webgeer committed

  if ($lonform['#default_value']!=0 || $latform['#default_value']!=0) {
webgeer's avatar
webgeer committed
    $myjava .= '{id}.panTo(new GLatLng('.$latform['#default_value'].', '.$lonform['#default_value'].'));'."\n".
             '{id}.addOverlay(thispoint=new GMarker(new GLatLng('.$latform['#default_value'].', '.$lonform['#default_value'].')));'."\n";
  }
//  else {
//    $startat='map.centerAndZoom(new GPoint(0, 30), zoom);';
//  }
//  $out='<div id="map" style="width: 100%; height: 300px;"></div> ';
webgeer's avatar
webgeer committed
  $myjava .=  '   GEvent.addListener({id}, "click", function(overlay, point) {
                  {id}.checkResize();
webgeer's avatar
webgeer committed
                    {id}.panTo(point);
                    if (thispoint) {
                      {id}.removeOverlay(thispoint);
                    }
                    {id}.addOverlay(thispoint=new GMarker(point));
webgeer's avatar
webgeer committed
                    {id}.zoomIn();
                    $("gmap-latitude").value=point.lat();
                    $("gmap-longitude").value=point.lng();
webgeer's avatar
webgeer committed
                GEvent.addListener({id}, "dragend", function() {{id}.checkResize();} )
              ';
  $out=gmap_draw_map($map,$myjava);
  return $out;
}

function _gmap_doheader(){
  static $gmap_initialized = FALSE;
  if (variable_get('gmap_method','Static')=='None' || $gmap_initialized) {
webgeer's avatar
webgeer committed

  theme_add_style(drupal_get_path('module','gmap'). '/gmap.css');
  drupal_add_js('misc/drupal.js');
  drupal_add_js(drupal_get_path('module','gmap'). '/gmap.js');
  $js = '<script src="http://maps.google.com/maps?file=api&v=2&key='.variable_get('googlemap_api_key', '').'" type="text/javascript"></script>';
  drupal_set_html_head($js);
  if (variable_get('gmap_xmaps',0)) {
    drupal_add_js(variable_get('gmap_xmaps_script','misc/xmaps.1c.js'));
  }
  if (GMAP_CLUSTER) {
    drupal_add_js('http://www.acme.com/javascript/Clusterer2.js');
  }
webgeer's avatar
webgeer committed
function _gmap_prepare($intext) {
webgeer's avatar
webgeer committed
  $mapexp = '/\[gmap([^\[\]]+ )* \] /x';
webgeer's avatar
webgeer committed
  preg_match_all($mapexp, $intext, $matches);
webgeer's avatar
webgeer committed

  while (isset($matches[1][$i])) {
    $out[0][$i] = $matches[0][$i];
webgeer's avatar
webgeer committed
    if ($matches[1][$i][0]=='1'){
      $ver=1;
      $matches[1][$i]=substr($matches[0][$i],1);
    }
    else {
      $ver=2;
    }
    $out[1][$i] = gmap_draw_map(gmap_parse_macro($matches[1][$i],$ver));
webgeer's avatar
webgeer committed
    $i++;
  } // endwhile process macro
  return $out;
}

function gmap_todim($instring) {
  if (strpos($instring,'px')) {
    return intval($instring).'px';
  }
  elseif (strpos($instring,'%')) {
    return intval($instring).'%';
  }
  else {
    return intval($instring).'px';
  }
}

webgeer's avatar
webgeer committed
function gmap_dopoint($point,$ver) {
  if ($ver==1) {
    $lonlat=explode(',',$point,2);
    return $lonlat[1].','.$lonlat[0];
  }
  else {
    return $point;
  }
}

webgeer's avatar
webgeer committed
function gmap_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
    case 'list':
      return (array(0 => t('GMap filter')));

    case 'name':
      return t('Google map filter');

    case 'description':
      return t('converts a google map  macro into the html required for inserting a google map.');
webgeer's avatar
webgeer committed
    case 'process':
      $gmaps=_gmap_prepare($text);   //returns an array of $tables[0] = table macro $table[1]= table html
      if ($gmaps) {                    // there are table macros in this node
        return str_replace($gmaps[0], $gmaps[1], $text);
      }
      else {
        return $text;
      }

    case 'prepare':
      return $text;

    
      return (variable_get('gmap_method', 'Static')=='Dynamic');
webgeer's avatar
webgeer committed
  }
}

function gmap_filter_tips($delta, $format, $long = false) {
  return t('Insert Google Map macro. <a href="%href" target="_blank" >Create a macro</a>', array('%href' => url('gmapmacro')));
webgeer's avatar
webgeer committed
}

function gmap_menu($may_cache) {
  $items=array();

  if ($may_cache) {
    $items[] = array('path' => 'gmapmacro',
      'type' => MENU_SUGGESTED_ITEM,
      'title' => t('Create a Google Map Macro'),
      'access' => user_access('create macro'),
      'callback' => 'gmap_macro_page' );
    if (variable_get('gmap_user',0)) {
      $items[] = array('path' => 'map/users',
webgeer's avatar
webgeer committed
        'title' => t('user locations'),
        'access' => user_access('show user map'),
        'callback' => 'gmap_users_page');
webgeer's avatar
webgeer committed
  }
webgeer's avatar
webgeer committed
  if (!$may_cache && (strlen(variable_get('googlemap_api_key', '')) > 0)) {
    if (variable_get('gmap_method', 'Static')=='Static') {
      _gmap_doheader();
    }
webgeer's avatar
webgeer committed
  }
  return $items;
}

function gmap_users_page() {
  // get array of users for lookups.  There is probably a better way of doing this, but I'm not
  // sure what it is.  Only necessary if user has view
 /* if (user_access('user locations')) {
    $result=db_query('SELECT uid, name, picture FROM {users}');
    $usernames=array();
    while ($u=db_fetch_array($result)) {
      $username[$u['uid']]=$u['name'];
      $userpicture[$u['uid']]=$u['picture'];
    }
  } */
  $output .='<p>'.variable_get('gmap_user_map_header', t('This map illustrates the extent of users of this website. Each marker indicates a user that has entered their locations.'))."</p>\n";


  $result=db_query("SELECT * FROM {location} WHERE (longitude !=0 OR latitude !=0) AND type='user'");
  $thismap = gmap_parse_macro(variable_get('gmap_user_map', '[gmap|id=usermap|center=0,30|zoom=16|width=100%|height=400px]'));
  if (empty($thismap['markers'])) {
    $thismap['markers']=array();
  }
  while ($u=db_fetch_object($result)) {
    if (user_access('user locations')) {
      $account = user_load(array('uid' => $u->oid));

      $newmarker['label'] = theme('user_picture', $account);
      $newmarker['label'] .= theme('username', $account);
      $newmarker['point']= $u->longitude.','.$u->latitude;
//      $newmarker['markername']='usermarker';
    }
    else {
      $newmarker['point']= $u->longitude.','.$u->latitude;
    }
    $thismap['markers'][]=$newmarker;
  }
  $output .= '<p>'.gmap_draw_map($thismap);
  return $output;
}

function gmap_user($op, &$edit, &$user, $category = NULL) {
  if (variable_get('gmap_user',0)) {
    switch ($op) {
      case 'categories':
        return array(array('name'=>'gmap_user', 'title'=> t('location map'),'weight'=>5));
      case 'validate':
        if (isset($edit['gmap_latitude'])){
          if (!is_numeric($edit['gmap_latitude']) || abs($edit['gmap_latitude'])>90) {
            form_set_error('gmap_latitude', t('Latitude must be between -90 and 90'));
          }
        }
        if (isset($edit['gmap_longitude'])){
          if (!is_numeric($edit['gmap_longitude']) || abs($edit['gmap_longitude'])>180) {
            form_set_error('gmap_longitude', t('Longitude must be between -180 and 180'));
        $res=db_query("SELECT * FROM {location} WHERE oid=%d AND type='user'",$user->uid);
        if ($gmap_user=db_fetch_array($res)) {
          $user->latitude=$gmap_user['latitude'];
          $user->longitude=$gmap_user['longitude'];
          $user->location=TRUE;
        if ((isset($edit['gmap_latitude']) && $edit['gmap_latitude'] !=0) && (isset($edit['gmap_longitude']) && $edit['gmap_longitude'] !=0)) {
          db_query("INSERT INTO {location} (oid, type, latitude, longitude, source) VALUES (%d, 'user', %f, %f, %d)", $user->uid, $edit['gmap_latitude'],$edit['gmap_longitude'], 1); // based on location.module LOCATION_LATLON_USER_SUBMITTED=1
        }
        return;
        if ((isset($edit['gmap_latitude']) && $edit['gmap_latitude'] !=0) && (isset($edit['gmap_longitude']) && $edit['gmap_longitude'] !=0)) {
          if (isset($user->location)) {
            db_query("UPDATE {location} SET latitude='%f', longitude='%f', source='%d' WHERE oid='%d' AND type='user'",  $edit['gmap_latitude'],$edit['gmap_longitude'], 1,$user->uid);
webgeer's avatar
webgeer committed
     // debug message
     //       drupal_set_message(sprintf("UPDATE {location} SET latitude='%f', longitude='%f', source='%d' WHERE oid='%d' AND type='user'",  $edit['gmap_latitude'],$edit['gmap_longitude'], 1,$user->uid));
            db_query("INSERT INTO {location} (oid, type, latitude, longitude, source) VALUES (%d, 'user', '%f', '%f', '%d')", $user->uid, $edit['gmap_latitude'],$edit['gmap_longitude'], 1); // based on location.module LOCATION_LATLON_USER_SUBMITTED=1
        return;

        //db_query ("UPDATE {gmap_user} SET latitude='%f', longitude='%f', zoom=%d WHERE uid=%d", $user->uid, $edit['gmap_latitude'],$edit['gmap_longitude'], $edit['gmap_zoom']);
        //return;
      case 'delete':
        db_query ("DELETE from {location} WHERE oid=%d AND type='user'", $user->uid);
      case 'form':
        if ($category=='gmap_user') {
//          if (isset($user->latitude) && isset($user->longitude)) {
//            $usermap=_gmap_user_form($user->longitude,$user->latitude, $user->gmap_zoom);
//          }
//          else {
//            $usermap = _gmap_user_form();
//          }
          $form['map']=array('#type' => 'fieldset','#title' => t('Google Map'));
          $form['map']['gmap_user']=array('#type'=>'markup','#value'=>'');
          $form['coordinates']=array('#type' => 'fieldset','#title' => t('Coordinates'));
          $form['coordinates']['gmap_latitude']=array('#type'=>'textfield',
                                                      '#id'=>'gmap-latitude',
                                                      '#title'=>t('Latitude'),
                                                      '#default_value'=>$user->latitude,
                                                      '#size'=>30,
                                                      '#maxlength'=>120,
                                                      '#description'=>t('The latitude will automatically be entered here (or you can do it manually).'),
                                                      '#attributes'=>array('onchange'=>'gmap_textchange();'));
          $form['coordinates']['gmap_longitude']=array('#type'=>'textfield',
                                                       '#title'=>t('Longitude'),
                                                       '#default_value'=>$user->longitude,
                                                       '#size'=>30,
                                                       '#maxlength'=>120,
                                                       '#description'=>t('The longitude will automatically be entered here (or you can do it manually).'),
                                                       '#attributes'=>array('onchange'=>'gmap_textchange();'));


          $form['map']['gmap_user']['#value']= gmap_set_location(variable_get('gmap_user_map', '[gmap|id=usermap|center=0,30|control=Large|zoom=16|width=100%|height=400px]'),
                                                 $form['coordinates']['gmap_longitude'],
webgeer's avatar
webgeer committed
                                                 $form['coordinates']['gmap_latitude']);
          return  $form;
 /*
          $form2 = form_textfield(t('Latitude'), 'gmap_latitude', $user->latitude, 30,120, t('The latitude will automatically be entered here (or you can do it manually).'), array('onchange'=>'gmap_textchange();') );
          $form2 .= form_textfield(t('Longitude'), 'gmap_longitude', $user->longitude, 30,120, t('The longitude will automatically be entered here (or you can do it manually).'), array('onchange'=>'gmap_textchange();') );
          $form2 .= form_hidden('gmap_zoom', variable_get('gmap_user_zoom', 15));

          return array(array('title'=>t('Google Map'), 'data'=>$form, 'weight'=>0),array('title'=>t('Coordinates'), 'data'=>$form2, 'weight'=>1));
*/
        }
    }
  }
}

webgeer's avatar
webgeer committed
function gmap_settings() {
  //note the same google api key variable name as in the googlemap module is used
webgeer's avatar
webgeer committed
  //note the name of the variable for center of the map is latlong although the format is actually longitude, latitude

  $form['initialization']=array('#type' => 'fieldset','#title' => t('Google Map Initialize'));
  $form['initialization']['googlemap_api_key']=array('#type' => 'textfield', '#title' => t('Google map API key'), '#default_value'=>variable_get('googlemap_api_key', ''), '#size' => 50, '#maxlength' => 255,'#description' => t('Your personal Googlemaps API key.  You must get this for each separate website at <a href="http://www.google.com/apis/maps/">Google Map API website</a>.'));
  $form['initialization']['gmap_method']=array('#type' => 'select', '#title' => t('Google map method'),  '#options'=> array('Static'=>t('Static'), 'Dynamic'=>t('Dynamic'), 'None'=>t('None')),'#default_value'=>GMAP_LOAD_METHOD,'#description' => t('How is the Google Map initialization script run:<br /><strong>Static</strong> - Loaded on every page, <br /><strong>Dynamic</strong> - Initialization script runs only on pages with google maps, but all pages with the gmap filter will not be cached. <br /><strong>None</strong> - Google map initialization script must be loaded some other way.'));
webgeer's avatar
webgeer committed
// xmaps not compatible with v2 of the Google Map API
//  $form['initialization']['gmap_xmaps']=array('#type'=>'checkbox', '#title'=>t('Enable Xmaps features (circles and polygons)'), '#default_value'=>GMAP_XMAPS,'#description'=>t('Enables XMaps features.  XMaps is currently a <em>beta</em> release available from <a href="http://xmaps.busmonster.com/">xmaps.busmonser.com</a>. '));
//  $form['initialization']['gmap_xmaps_script']=array('#type' => 'textfield', '#title' => t('Location of XMaps script'), '#default_value'=>GMAP_XMAPS_SCRIPT, '#size' => 25, '#maxlength' => 50);
  $form['initialization']['gmap_cluster']=array('#type'=>'checkbox', '#title'=>t('Enable clusterer.js'), '#default_value'=>GMAP_CLUSTER,'#description'=>t('Enables Jef Poskanzer\'s excellent <a href="http://www.acme.com/javascript/#Clusterer">clusterer.js</a> script. (useful for a large number of markers on a single map)'));

  $form['defaults']=array('#type' => 'fieldset', '#title' => t('Default map settings'));
  $form['defaults']['gmap_default_width']=array('#type'=>'textfield', '#title'=>t('Default width'), '#default_value'=>GMAP_WIDTH, '#size'=>25, '#maxlength'=>6, '#description'=>t('The default width of a Google map.'));
  $form['defaults']['gmap_default_height']=array('#type'=>'textfield', '#title'=>t('Default height'), '#default_value'=>GMAP_HEIGHT, '#size'=>25, '#maxlength'=>6, '#description'=>t('The default height of a Google map.'));
  $form['defaults']['gmap_default_latlong']=array('#type'=>'textfield', '#title'=>t('Default center'), '#default_value'=>GMAP_LONGLAT, '#size'=>50, '#maxlength'=>255, '#description'=>t('The default longitude, latitude of a Google map.'));
  $form['defaults']['gmap_default_zoom']=array('#type'=>'select', '#title'=>t('Default zoom'), '#default_value'=>GMAP_ZOOM, '#options' => drupal_map_assoc(range(0, 17)), '#description'=>t('The default zoom level of a Google map.'));
  $form['defaults']['gmap_default_control']=array('#type'=>'select', '#title'=>t('Default control type'), '#default_value'=>GMAP_CONTROL, '#options'=>array('None'=>t('None'),'Small'=>t('Small'),'Large'=>t('Large')));
  $form['defaults']['gmap_default_type']=array('#type'=>'select', '#title'=>t('Default map type'), '#default_value'=>GMAP_TYPE, '#options'=>array('Map'=>t('Map'),'Satellite'=>t('Satellite'),'Hybrid'=>t('Hybrid')));
  $form['defaults']['gmap_default_line1_color']=array('#type'=>'textfield', '#title'=>t('Default Line 1 Color'), '#default_value'=>GMAP_LINECOLOR1, '#size'=>25, '#maxlength'=>7 );
  $form['defaults']['gmap_default_line2_color']=array('#type'=>'textfield', '#title'=>t('Default Line 2 Color'), '#default_value'=>GMAP_LINECOLOR2, '#size'=>25, '#maxlength'=>7 );
  $form['defaults']['gmap_default_line3_color']=array('#type'=>'textfield', '#title'=>t('Default Line 3 Color'), '#default_value'=>GMAP_LINECOLOR3, '#size'=>25, '#maxlength'=>7 );

  $form['user']=array('#type' => 'fieldset', '#title' => t('User map settings'));
  $form['user']['gmap_user']=array('#type'=>'checkbox', '#title'=>t('Enable Mapping of user locations'), '#default_value'=>variable_get('gmap_user',0),'#description'=>t('Ensure that the database table gmap_user is created before turning on the user location mapping functions.'));
  $form['user']['gmap_user_map']=array('#type'=>'textfield', '#title'=>t('Default user map'), '#default_value'=>variable_get('gmap_user_map', '[gmap|id=usermap|center=0,40|zoom=16|width=100%|height=400px]'), '#size'=>50, '#description'=>t('The gmap macro where the user information will be diplayed on.'));
  $form['user']['gmap_user_map_header']=array('#type'=>'textarea', '#title'=>t('Text at the top of the map/users page'), '#default_value'=>variable_get('gmap_user_map_header', t('This map illustrates the extent of users of this website. Each marker indicates a user that has entered their locations.')), '#cols'=>50, '#rows'=>6 );
webgeer's avatar
webgeer committed
}

function gmap_macro_page() {
  drupal_add_js(drupal_get_path('module','gmap'). '/gmapmacro.js');
webgeer's avatar
webgeer committed
  _gmap_doheader();
function gmap_macro_form() {
  
        $form['macroform'] = array(
    '#type' => 'fieldset',
    '#title' => t('Gmap macro creation'),
    '#theme' => 'gmap_macro',
  );
  $linecolors = array(GMAP_LINECOLOR1, GMAP_LINECOLOR2, GMAP_LINECOLOR3); 
  $form['macroform']['mapdiv']=array('#type'=>'markup','#value'=>'<div id="map" style="width: '.GMAP_WIDTH.'; height: '.GMAP_HEIGHT.';"></div>');
  $form['macroform']['javascript'] = array(
    '#value' => drupal_call_js('gmap_set_line_colors', $linecolors),
  );
  $form['macroform']['mapid'] = array(
    '#type' => 'textfield',
    '#id' => 'gmap-mapid',
    '#title' => t('Map id attribute'),
    '#default_value' => variable_get('gmap_default_mapid', 'map'),
    '#attributes' => array('onchange' => 'set_gmap_mapid(this.value)'),
  );
  $form['macroform']['maptype'] = array(
    '#type' => 'select', 
    '#id' => 'gmap-maptype',
    '#title' => t('Map type'), 
    '#options' => drupal_map_assoc(array('Map', 'Satellite', 'Hybrid')), 
    '#default_value' => GMAP_TYPE,
    '#required' => FALSE,
    '#attributes' => array('onchange' => 'set_gmap_type(this.value);'),
  );
  $form['macroform']['controltype'] = array(
    '#type' => 'select', 
    '#id' => 'gmap-controltype',
    '#title' => t('Controls'), 
    '#options' => drupal_map_assoc(array('None', 'Small', 'Large')), 
    '#required' => FALSE,
    '#default_value' => GMAP_CONTROL,
    '#attributes' => array('onchange' => 'set_control_type(this.value);')
  );  
webgeer's avatar
webgeer committed
  $form['macroform']['latlong'] = array(
webgeer's avatar
webgeer committed
    '#id' => 'gmap-latlong',
    '#title' => t('The Latitude and Longitude of the centre of the map'),
    '#default_value' => GMAP_LONGLAT,
    '#size' => 50,
webgeer's avatar
webgeer committed
    '#attributes' => array('onchange' => 'set_gmap_latlong(this.value);'),
  );
  $form['macroform']['width'] = array(
    '#type' => 'textfield',
    '#id' => 'gmap-width',
    '#title' => t('Map width'),
    '#default_value' => GMAP_WIDTH,
    '#size' => 25,
    '#attributes' => array('onchange' => 'set_gmap_dimension(this, \'width\');'),
  ); 
  $form['macroform']['height'] = array(
    '#type' => 'textfield',
    '#title' => t('Map height'),
    '#id' => 'gmap-height',
    '#default_value' => GMAP_HEIGHT,
    '#size' => 25,
    '#attributes' => array('onchange' => 'set_gmap_dimension(this, \'height\');'),
  ); 
  $form['macroform']['alignment'] = array(
    '#type' => 'select', 
    '#id' => 'gmap-alignment',
    '#title' => t('Alignment'), 
    '#options' => drupal_map_assoc(array('None', 'Right', 'Left', 'Center')), 
//    '#default_value' => GMAP_ALIGNMENT,
    '#required' => FALSE,
    '#attributes' => array('onchange' => 'set_gmap_alignment(this.value);')
  );  
  $form['macroform']['clicktype'] = array(
    '#type' => 'select', 
    '#id' => 'gmap-clicktype',
    '#title' => t('What happens when you click on the map'), 
    '#options' => drupal_map_assoc(array('Points', 'Line1', 'Line2', 'Line3')), 
    '#required' => FALSE,
    '#default_value' => 'Points',
//    '#attributes' => array('onchange' => 'docontrol(this.value);')
  );    
  $form['macroform']['zoom'] = array(
    '#type' => 'select', 
    '#id' => 'gmap-zoom',
    '#title' => t('The current magnification of the map'),
    '#default_value' => GMAP_ZOOM,
    '#options' => drupal_map_assoc(range(0, 17)),
webgeer's avatar
webgeer committed
    '#attributes' => array('onchange' => 'setgmapZoom(this.value);'),
  );
  $form['macroform']['textarea'] = array(
    '#type' => 'textarea',
    '#id' => 'gmap-macrotext',
    '#title' => t('Macro text'),
  );
  return drupal_get_form('macroform', $form);