Geocoder and two different Tables

6 posts by 2 authors in: Forums > CMS Builder: Plugins & Add-ons
Last Post: July 22, 2019   (RSS)

By mbareara - July 18, 2019 - edited: July 18, 2019

Goodevening 

is it possible to have only one map but with items from two different tables? 

For example in a same map  RESTAURANTS and BAR or HOTEL ?

Thank you in advance  for your answer 

Orazio

By gregThomas - July 19, 2019

Hey Ozazio, 

This is possible, you just need to adapt sample_map_multi.php (which is included with the plugin) to load the records from the different sections. Below is some sample code that shows how you could load data from sections called hotel and bars, but you can extend this to work with as many sections as you'd like. 

Step 1) Load all the records that are required on line 13 of the plugin. Replace:

  // get records
  list($myRecords, $myMetaData) = getRecords(array(
    'tableName' => $GLOBALS['GEOCODER_SAMPLE_TABLENAME'],
  ));

with the sections, you need to get the data from:

  // get records
  list($bars, $myMetaData) = getRecords(array(
    'tableName' => 'bars',
  ));

  list($hotels, $myMetaData) = getRecords(array(
    'tableName' => 'hotels',
  ));

Step 2) Update the JS at the top of the page to add each marker. Replace:

<?php
foreach ($myRecords as $record) {
  if (!$record['latitude'] || !$record['longitude']) { continue; }
  $jsFunctionArgs = "{$record['latitude']}, {$record['longitude']}, {$record['num']}, '" .jsEncode($record['_link']). "'";
  print "  _geocoder_addMarker($jsFunctionArgs);\n";
}
?>

With the same code block, but make it loads the records you retrieved previously:

foreach ($bars as $record) {
  if (!$record['latitude'] || !$record['longitude']) { continue; }
  $jsFunctionArgs = "{$record['latitude']}, {$record['longitude']}, {$record['num']}, '" .jsEncode($record['_link']). "'";
  print "  _geocoder_addMarker($jsFunctionArgs);\n";
}
foreach ($hotels as $record) {
  if (!$record['latitude'] || !$record['longitude']) { continue; }
  $jsFunctionArgs = "{$record['latitude']}, {$record['longitude']}, {$record['num']}, '" .jsEncode($record['_link']). "'";
  print "  _geocoder_addMarker($jsFunctionArgs);\n";
}

Step 3) Duplicate the marker code at the bottom of the page. Update:

    <?php foreach ($myRecords as $record): ?>

      <?php // marker_infowindow_### is the content displayed in the info-window on click ?>
      <div id="marker_infowindow_<?php echo $record['num']; ?>">
        <h3><?php echo htmlencode( @$record['address']); ?></h3>
        Add any extra content you like here...<br/>
        <a href="<?php echo $record['_link']; ?>">details</a>
      </div>

    <?php endforeach ?>

So that it is called for each set of records (as we've done above). So we'd duplicate this code twice then replace $myRecords with $blog and $hotels in each code block.

Finally, you'll need to update line 81 from this:

  <?php $hasAddresses = array_filter(array_pluck($myRecords, 'latitude')); ?>

To this:

  <?php $hasAddresses = true; ?>

Cheers,

Greg

Greg Thomas







PHP Programmer - interactivetools.com

By mbareara - July 20, 2019 - edited: July 20, 2019

WOW! THank you Greg!

now i have all the markers form the two tables on map... but... when i click on the markers, both restaurants and bars give me information (name, link etc) about restaurants. Of course on restaurants is correct, on bars... no.

By mbareara - July 20, 2019

<?php 
  // load viewer library
  $libraryPath = 'lib/viewer_functions.php';
  $dirsToCheck = array('../','../../','../../../','../../../../');
  foreach ($dirsToCheck as $dir) { if (@include_once("$dir$libraryPath")) { break; }}
  if (!function_exists('getRecords')) { die("Couldn't load viewer library, check filepath in sourcecode."); }

  // error checking
  if (!@$GLOBALS['GEOCODER_PLUGIN'])         { die("You must activate the Geocoder plugin before you can access this page."); }
  if (!@$GLOBALS['GEOCODER_GOOGLE_API_KEY']) { die("You must have a Google Maps API key to display a map, see the readme file for instructions on getting one."); }

  // get records
  list($ristoranti, $myMetaData) = getRecords(array(
      'tableName'   => 'ristoranti',  
  ));
 list($birrifici, $myMetaData) = getRecords(array(
    'tableName' => 'birrifici',
  ));

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

<title>Show map with multiple addresses</title>
<style>
      html, body {
        margin: 0;
        padding: 0;
        height: 100%;
        width: 100%;
      }
      #map {
        height: 400px;
        width: 100%;
      }
      #legend {
        font-family: Arial, sans-serif;
        background: #fff;
        padding: 10px;
        margin: 10px;
        border: 3px solid #000;
      }
      #legend h3 {
        margin-top: 0;
      }
      #legend img {
        vertical-align: middle;
      }
    </style>

<!-- STEP1: Map with multiple addresses: Put this in the <head> of your page, rename $myRecords if needed -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<?php echo htmlEncode($GLOBALS['GEOCODER_GOOGLE_API_KEY']); ?>"></script>
<script type="text/javascript">
function initialize() {
  var mapCanvasId = 'map';
  var mapOptions  = { mapTypeId: google.maps.MapTypeId.ROADMAP };
  var map         = new google.maps.Map(document.getElementById(mapCanvasId), mapOptions, {
          zoom: 10,  });
  var bounds      = new google.maps.LatLngBounds();
  var infowindow  = new google.maps.InfoWindow();
	var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
<?php
foreach ($ristoranti as $record) {
  if (!$record['latitude'] || !$record['longitude']) { continue; }
  $jsFunctionArgs = "{$record['latitude']}, {$record['longitude']}, {$record['num']}, '" .jsEncode($record['_link']). "'";
  print "  _geocoder_addMarker($jsFunctionArgs);\n";
}
foreach ($birrifici as $record) {
  if (!$record['latitude'] || !$record['longitude']) { continue; }
  $jsFunctionArgs = "{$record['latitude']}, {$record['longitude']}, {$record['num']}, '" .jsEncode($record['_link']). "'";
  print "  _geocoder_addMarker($jsFunctionArgs);\n";
}
?>

  //
  function _geocoder_addMarker(latitude, longitude, recordNum, detailLink) {
    var latLng       = new google.maps.LatLng(latitude, longitude);
    var infowindowEl = document.getElementById('marker_infowindow_' + recordNum);
    var marker       = new google.maps.Marker({ map: map, position: latLng });
    google.maps.event.addListener(marker, 'click', function() {
      if (infowindowEl) {
        infowindow.setContent(infowindowEl.innerHTML);
        infowindow.open(map, marker);
      }
      else {
        window.location = detailLink;
      }
    });
	  
    bounds.extend(latLng);
  }

  //
  map.fitBounds(bounds);
}

</script>
<!-- STEP1: Map with multiple addresses -->


</head>


<!-- STEP2: Map with multiple addresses: add this to body tag: onload="initialize() -->
<body onload="initialize()">
<!-- STEP2: Map with multiple addresses -->


  <h1>How To Sicily - Restaurant Reviews Map</h1>


  <!-- STEP3: Map with multiple addresses: Put this where you want your map displayed, rename $myRecords if needed -->
<?php $hasAddresses = true; ?>
  <?php if ($hasAddresses): ?>
    <div id="map" style="width: 1200px; height: 500px;; float: left; margin: 0px 15px;"></div>
  <?php endif ?>

  <?php if (!$hasAddresses): ?>
    <div style="width: 1200px; height: 500px;; float: left; margin: 0px 15px; border: 1px solid #000;">
      <div style="text-align: center; padding-top: 135px">
        No map available!
      </div>
    </div>
  <?php endif ?>
  <!-- STEP3: /Map with multiple addresses -->


  <p>TIP: Click on markers for more details.</p>


  <!-- STEP4: Map with multiple addresses: Set the popup window content, rename $myrecords if needed -->
  <div id="marker_details" style="display: none;">
   <?php foreach ($ristoranti as $record): ?>

      <?php // marker_infowindow_### is the content displayed in the info-window on click ?>
      <div id="marker_infowindow_<?php echo $record['num']; ?>">
        <h3><?php echo htmlencode( @$record['address']); ?></h3>
        add content you like here...<br/>
        <a href="<?php echo $record['_link']; ?>">details</a>
      </div>

    <?php endforeach ?>
	     <?php foreach ($birrifici as $record): ?>

      <?php // marker_infowindow_### is the content displayed in the info-window on click ?>
      <div id="marker_infowindow_<?php echo $record['num']; ?>">
        <h3><?php echo htmlencode( @$record['address']); ?></h3>
        add any extra content you like here...<br/>
        <a href="<?php echo $birrificirecord['_link']; ?>">details</a>
      </div>

    <?php endforeach ?>
	  
  </div>
  <!-- STEP4: Map with multiple addresses -->


</body>
</html>

By gregThomas - July 22, 2019

Hey Orazio,

The issue is that some of the records share the same num value, and this is being used to detect which HTML content needs to be displayed when a marker is clicked on. I've updated your code in a way that should fix the problem:

<?php 
  // load viewer library
  $libraryPath = 'lib/viewer_functions.php';
  $dirsToCheck = array('../','../../','../../../','../../../../');
  foreach ($dirsToCheck as $dir) { if (@include_once("$dir$libraryPath")) { break; }}
  if (!function_exists('getRecords')) { die("Couldn't load viewer library, check filepath in sourcecode."); }

  // error checking
  if (!@$GLOBALS['GEOCODER_PLUGIN'])         { die("You must activate the Geocoder plugin before you can access this page."); }
  if (!@$GLOBALS['GEOCODER_GOOGLE_API_KEY']) { die("You must have a Google Maps API key to display a map, see the readme file for instructions on getting one."); }

  // get records
  list($ristoranti, $myMetaData) = getRecords(array(
      'tableName'   => 'ristoranti',  
  ));
 list($birrifici, $myMetaData) = getRecords(array(
    'tableName' => 'birrifici',
  ));

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

<title>Show map with multiple addresses</title>
<style>
      html, body {
        margin: 0;
        padding: 0;
        height: 100%;
        width: 100%;
      }
      #map {
        height: 400px;
        width: 100%;
      }
      #legend {
        font-family: Arial, sans-serif;
        background: #fff;
        padding: 10px;
        margin: 10px;
        border: 3px solid #000;
      }
      #legend h3 {
        margin-top: 0;
      }
      #legend img {
        vertical-align: middle;
      }
    </style>

<!-- STEP1: Map with multiple addresses: Put this in the <head> of your page, rename $myRecords if needed -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<?php echo htmlEncode($GLOBALS['GEOCODER_GOOGLE_API_KEY']); ?>"></script>
<script type="text/javascript">
function initialize() {
  var mapCanvasId = 'map';
  var mapOptions  = { mapTypeId: google.maps.MapTypeId.ROADMAP };
  var map         = new google.maps.Map(document.getElementById(mapCanvasId), mapOptions, {
          zoom: 10,  });
  var bounds      = new google.maps.LatLngBounds();
  var infowindow  = new google.maps.InfoWindow();
	var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
<?php
foreach ($ristoranti as $record) {
  if (!$record['latitude'] || !$record['longitude']) { continue; }
  $jsFunctionArgs = "{$record['latitude']}, {$record['longitude']}, 'r{$record['num']}', '" .jsEncode($record['_link']). "'";
  print "  _geocoder_addMarker($jsFunctionArgs);\n";
}
foreach ($birrifici as $record) {
  if (!$record['latitude'] || !$record['longitude']) { continue; }
  $jsFunctionArgs = "{$record['latitude']}, {$record['longitude']}, 'b{$record['num']}', '" .jsEncode($record['_link']). "'";
  print "  _geocoder_addMarker($jsFunctionArgs);\n";
}
?>

  //
  function _geocoder_addMarker(latitude, longitude, recordNum, detailLink) {
    var latLng       = new google.maps.LatLng(latitude, longitude);
    var infowindowEl = document.getElementById('marker_infowindow_' + recordNum);
    var marker       = new google.maps.Marker({ map: map, position: latLng });
    google.maps.event.addListener(marker, 'click', function() {
      if (infowindowEl) {
        infowindow.setContent(infowindowEl.innerHTML);
        infowindow.open(map, marker);
      }
      else {
        window.location = detailLink;
      }
    });
	  
    bounds.extend(latLng);
  }

  //
  map.fitBounds(bounds);
}

</script>
<!-- STEP1: Map with multiple addresses -->


</head>


<!-- STEP2: Map with multiple addresses: add this to body tag: onload="initialize() -->
<body onload="initialize()">
<!-- STEP2: Map with multiple addresses -->


  <h1>How To Sicily - Restaurant Reviews Map</h1>


  <!-- STEP3: Map with multiple addresses: Put this where you want your map displayed, rename $myRecords if needed -->
<?php $hasAddresses = true; ?>
  <?php if ($hasAddresses): ?>
    <div id="map" style="width: 1200px; height: 500px;; float: left; margin: 0px 15px;"></div>
  <?php endif ?>

  <?php if (!$hasAddresses): ?>
    <div style="width: 1200px; height: 500px;; float: left; margin: 0px 15px; border: 1px solid #000;">
      <div style="text-align: center; padding-top: 135px">
        No map available!
      </div>
    </div>
  <?php endif ?>
  <!-- STEP3: /Map with multiple addresses -->


  <p>TIP: Click on markers for more details.</p>


  <!-- STEP4: Map with multiple addresses: Set the popup window content, rename $myrecords if needed -->
  <div id="marker_details" style="display: none;">
   <?php foreach ($ristoranti as $record): ?>

      <?php // marker_infowindow_### is the content displayed in the info-window on click ?>
      <div id="marker_infowindow_r<?php echo $record['num']; ?>">
        <h3><?php echo htmlencode( @$record['address']); ?></h3>
        add content you like here...<br/>
        <a href="<?php echo $record['_link']; ?>">details</a>
      </div>

    <?php endforeach ?>
	     <?php foreach ($birrifici as $record): ?>

      <?php // marker_infowindow_### is the content displayed in the info-window on click ?>
      <div id="marker_infowindow_b<?php echo $record['num']; ?>">
        <h3><?php echo htmlencode( @$record['address']); ?></h3>
        add any extra content you like here...<br/>
        <a href="<?php echo $birrificirecord['_link']; ?>">details</a>
      </div>

    <?php endforeach ?>
	  
  </div>
  <!-- STEP4: Map with multiple addresses -->


</body>
</html>

I've updated the ID's on the hidden markers so that they are unique again by prefixing them with either b or r depending on if they're restaurants or bars.

Cheers,

Greg

Greg Thomas







PHP Programmer - interactivetools.com