<?php

/**
 * Define range of map for epsg3857
 */
define('MERCATOR'true);
define('X_RANGE'40075016.685578);
define('Y_RANGE'40075016.685578);
define('MIN_X', -20037508.342789);
define('MAX_Y'20037508.342789);

/**
 * POI database in (latitude, longitude, name) format
 */
$database = array(
  array(
13.73703100.45074'Place 1'),
  array(
13.76587100.67459'Place 2'),
  array(
13.90457100.65811'Place 3'),
  array(
14.15863100.37247'Place 4'),
  array(
14.00208100.99319'Place 5'),
  array(
13.50632100.81055'Place 6'),
  array(
13.53104100.87097'Place 7'),
  array(
13.57635100.60593'Place 8'),
  array(
14.30832100.29968'Place 9'),
  array(
13.70819100.16235'Place 10'),
);

//////////////////
// Server side  //
//////////////////
if ($_REQUEST["imgid"] && $_REQUEST["res"]) {
  
/**
   * Find boundary of this tile
   */
  
$bound imgid_to_boundary($_REQUEST["imgid"], $_REQUEST["res"]);
  
$result = array();
  
  
/**
   * Search database for POI in boundary
   * 
   * For PostGIS use
   * select name, astext(the_geom) as geom from database where the_geom@GeomFromText('LINESTRING($minlon, $minlat, $maxlon, $maxlat)')
   */
  
foreach($database as $data) {
    if (
$data[0] < $bound->minLat || $data[0] > $bound->maxLat || $data[1] < $bound->minLon || $data[1] > $bound->maxLon) continue;
    
    
$item = new stdClass();
    
$item->lat $data[0];
    
$item->lon $data[1];
    
$item->name $data[2];
    
$result[] = $item;
  }
  
  
/**
   * return POI data in json format
   */
  
echo(json_encode($result));
  return;
}

/**
 * Find boundary of tile from imageid and resolution
 * imageid = (y * resolution) + x
 */
function imgid_to_boundary($imgid$res) {
  
/**
   * Find boundary in normal unit
   */
  
$sizeX X_RANGE $res;
  
$sizeY Y_RANGE $res;
  
$left MIN_X + (mod($imgid$res) * $sizeX);
  
$top MAX_Y - (intval($imgid $res) * $sizeY);
  
$bound = new stdClass();
  
$bound->minLat $top $sizeY;
  
$bound->minLon $left;
  
$bound->maxLat $top;
  
$bound->maxLon $left $sizeX;
  
/**
   * Translate to WGS84 if required
   */
  
if (MERCATOR) {
    
$bound->minLat norm_to_lat($bound->minLat);
    
$bound->minLon norm_to_lon($bound->minLon);
    
$bound->maxLat norm_to_lat($bound->maxLat);
    
$bound->maxLon norm_to_lon($bound->maxLon);
  }
  return 
$bound;
}

/**
 * php modulus is 32-bit operation but imageid > 32bit
 */
function mod($a$n) {
  return 
$a - ($n floor($a $n));
}

/**
 * Translate Mercator normal value to WGS84 longitude
 */
function norm_to_lon($norm) {
  return 
360 $norm X_RANGE;
}

/**
 * Translate Mercator normal value to WGS84 latitude
 */
function norm_to_lat($norm) {
  return 
360 * (atan(exp(M_PI $norm Y_RANGE 2)) - (M_PI 4)) / M_PI;
}

//////////////////
// Client side  //
//////////////////
?>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Custom POI</title>
    <style>
      body { margin: 0; padding: 0; }
      .poi { width: 16px; height: 16px; background: #0000ff; }
    </style>
    <script type="text/javascript" src="http://mmmap15.longdo.com/mmmap/mmmap.php?map=epsg3857"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
    <script type="text/javascript">
      var mmmap;
      var tileHasPoi = new Object();
      $(function() {
        mmmap = new MMMap($('#mapdiv')[0], 13.767734, 100.5351375, 10, 'gray');
        /**
         * Set minimum zoom level that show POIs
         */
        mmmap.showpoi = 5;
        /**
         * Reset map's POI cache
         */
        mmmap.setAllImagesUsedButNotSetToEmpty();
        /**
         * Map api call this function when it needs to show POIs
         */
        mmmap.setMyGetPOIsFunction(function(imgid, objidx, resolution) {
          var zoom = Math.log(resolution) / Math.log(2);
          var id = zoom + '-' + imgid;
          if (tileHasPoi[id]) return;
          
          /**
           * Get POI data from server
           */
          $.ajax({
            type: 'GET',
            cache: true,
            url: '?imgid=' + imgid + '&res=' + resolution,
            dataType: 'json',
            success: function(msg) {
              tileHasPoi[id] = true;
              /**
               * Draw each POI with drawCustomDiv
               */
              $.each(msg, function(index, value) {
                var icon = document.createElement('div');
                icon.className = 'poi';
                mmmap.drawCustomDivLevel(icon, value.lat, value.lon, value.name, zoom, zoom);
              });
            }
          });
        });
        
        $(window).resize(function() {
          chkWinSize();
          mmmap.setSize(ww, wh);
          mmmap.rePaint();
        }).resize();
      });
    </script>
  </head>
  <body>
    <div id="mapdiv"></div>
  </body>
</html>