Files
forum/Sources/GoogleMap.php

448 lines
16 KiB
PHP

<?php
// Google Maps Mod
// by
// TLM <the_lost_minded@yahoo.com>
// We calling this directly, if so, your evil...
if (!defined('SMF'))
die('Hacking attempt...');
function Map() {
global $db_prefix, $context;
// Are we allowed to view the map? Keep in mind here we should be a guest unless user is in IE!
isAllowedTo('googleMap_view');
//Lets try this to make it work on first click...
//loadUserSettings();
writeLog();
//Map using the internal XML File? Or the JS file?
if (isset($_GET['sa']) && $_GET['sa'] == '.xml')
return MapsXML();
if (isset($_GET['sa']) && $_GET['sa'] == '.js')
return MapsJS();
// Get the template ready.... not really much else to do.
//loadLanguage('MemberMap');
loadTemplate('GoogleMap');
$context['sub_template'] = 'map';
$context['page_title'] = "Member Map";
}
function MapsJS() {
global $db_prefix, $context, $scripturl, $txt, $modSettings, $user_info;
// Lets dump everything in the buffer and start clean and new and fresh
ob_end_clean();
if (!empty($modSettings['enableCompressedOutput']))
@ob_start('ob_gzhandler');
else
ob_start();
echo '
onerror=handleErr
var txt=""
function handleErr(msg,url,l)
{
txt="There was an error on this page.\n\n"
txt+="Error: " + msg + "\n"
txt+="URL: " + url + "\n"
txt+="Line: " + l + "\n\n"
txt+="Click OK to continue.\n\n"
//alert(txt)
return true
}
// Globals.
//Icon(s), and if gender is enabled, php will allow those to be defined.
var icon = new GIcon();
icon.image = "http://labs.google.com/ridefinder/images/mm_20_green.png";
icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);
// For that lovly clustering thing!
var clusterIcon = new GIcon();
clusterIcon.image = "http://labs.google.com/ridefinder/images/mm_20_purple.png";
clusterIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
clusterIcon.iconSize = new GSize(12, 20);
clusterIcon.shadowSize = new GSize(22, 20);
clusterIcon.iconAnchor = new GPoint(6, 20);
clusterIcon.infoWindowAnchor = new GPoint(5, 1);';
if ($modSettings['googleMapsPinGender'])
echo '
var iconm = new GIcon();
iconm.image = "http://labs.google.com/ridefinder/images/mm_20_blue.png";
iconm.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
iconm.iconSize = new GSize(12, 20);
iconm.shadowSize = new GSize(22, 20);
iconm.iconAnchor = new GPoint(6, 20);
iconm.infoWindowAnchor = new GPoint(5, 1);
var iconf = new GIcon();
iconf.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
iconf.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
iconf.iconSize = new GSize(12, 20);
iconf.shadowSize = new GSize(22, 20);
iconf.iconAnchor = new GPoint(6, 20);
iconf.infoWindowAnchor = new GPoint(5, 1);';
echo '
if (GBrowserIsCompatible()) {
// this variable will collect the html which will eventually be placed in the sidebar
var sidebar_html = "";
// arrays to hold copies of the markers and html used by the sidebar
// because the function closure trick doesnt work there
var gmarkers = [];
var htmls = [];
// A function to create the marker and set up the event window
function createMarker(marker_num, point, icon, name, html) {
var marker = new GMarker(point, icon);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
// save the info we need to use later for the sidebar
gmarkers[marker_num] = marker;
htmls[marker_num] = html;
// add a line to the sidebar html';
if ($modSettings['googleSidebar'] == 1)
echo '
sidebar_html += \'<a href="javascript:myclick(\' + marker_num + \')">\' + name + \'</a><br /> \';';
if ($modSettings['googleSidebar'] == 2)
echo '
sidebar_html += \'<a href="javascript:myclick(\' + marker_num + \')">\' + name + \'</a>, \';';
echo '
//Now that we cached it lets return the marker....
return marker;
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
gmarkers[i].openInfoWindowHtml(htmls[i]);
}
// create the map
var map = new GMap(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.addControl(new GScaleControl());
// Sets the map type based on admin prefrence
map.setMapType(' . $modSettings['googleMapsType'] . ');
// Lets load up the default long/lat/zoom for the map for those that like wine.
map.centerAndZoom(new GPoint(' . $modSettings['googleMapsDefaultLong'] . ', ' . $modSettings['googleMapsDefaultLat'] . '), ' . $modSettings['googleMapsDefaultZoom'] . ');
// This is so we can try to cluster some of those pins together so the map does not get over loaded?
var clusterer = new Clusterer( map );
clusterer.icon = clusterIcon;
clusterer.minMarkersPerClusterer = ' . $modSettings['googleMapsMinMarkerCluster'] . ';
clusterer.maxVisibleMarkers = ' . $modSettings['googleMapsMaxVisMarker'] . ';
clusterer.GridSize = ' . $modSettings['googleMapsMaxNumClusters'] . ';
clusterer.MaxLinesPerInfoBox = ' . $modSettings['googleMapsMaxLinesCluster'] . ';
// Read the data
var request = GXmlHttp.create();
request.open("GET", "'. $scripturl . '?action=googlemap;sa=.xml", true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var xmlDoc = request.responseXML;
// obtain the array of markers and loop through it
var markers = xmlDoc.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lng = parseFloat(markers[i].getAttribute("lng"));
var lat = parseFloat(markers[i].getAttribute("lat"));
var point = new GPoint(lng, lat);
var html = markers[i].getAttribute("html");
var label = markers[i].getAttribute("label");
// create the marker';
if ($modSettings['googleMapsPinGender'])
echo '
if (parseFloat(markers[i].getAttribute("gender")) == 0)
var marker = createMarker(i, point, icon, label, html);
if (parseFloat(markers[i].getAttribute("gender")) == 1)
var marker = createMarker(i, point, iconm, label, html);
if (parseFloat(markers[i].getAttribute("gender")) == 2)
var marker = createMarker(i, point, iconf, label, html);';
else
echo '
var marker = createMarker(i, point, icon, label, html);';
if ($modSettings['googleMapsEnableClusterer'])
echo '
clusterer.AddMarker(marker, label);';
else
echo '
map.addOverlay(marker);';
echo '
}
}';
if($modSettings['googleMasSideBar'])
echo'
// put the assembled sidebar_html contents into the sidebar div
document.getElementById("sidebar").innerHTML = sidebar_html;';
echo '
};
request.send(null);
} else {
alert("Sorry, the Google Maps API is not compatible with this browser");
}
';
obExit(false);
}
function MapsXML() {
global $db_prefix, $context, $scripturl, $txt, $modSettings, $user_info, $themeUser, $memberContext;
// Lets dump everything in the buffer and start clean and new and fresh
ob_end_clean();
if (!empty($modSettings['enableCompressedOutput']))
@ob_start('ob_gzhandler');
else
ob_start();
// XML Header, and should these not be UTF-8?
//header("Content-Type: plain/text; charset=ISO-8859-1");
header("Content-Type: application/xml; charset=UTF-8");
// Lets find number of members that set there map
$request = db_query("
SELECT COUNT(*) as TOTALFOUND
FROM {$db_prefix}members
WHERE latitude IS NOT NULL AND longitude IS NOT NULL
", __FILE__, __LINE__);
// Pull the answer and store it...
$totalSet = mysql_fetch_row($request);
// If the total people set there lat/long is greater than googleMapsPinNumber,
// We check for if we have any bounds that got passed from the JS,
// If no bounds we just pick the number of googleMapsPinNumber to show...
// If we are under the max allowed, just show them all!
if ($totalSet[0] >= $modSettings['googleMapsPinNumber']) {
// Lets set this to nothing, just to be safe if we dont have variables...
$sql_addon = "";
// Check to see if we have any ranges before we add to the SQL statment...
// This could stand to have a bit better security on it but its gonna be let by the side for now
if ((isset($_GET['minX'])) && (isset($_GET['maxX'])) && (isset($_GET['minY'])) && (isset($_GET['maxY']))) {
$sql_addon = " AND latitude > " . $_GET['minX'] . "
AND latitude < " . $_GET['maxX'] . "
AND longitude > " . $_GET['minY'] . "
AND longitude < " . $_GET['maxY'];
}
// Lets just make this simple for the query...
$maxPins = $modSettings['googleMapsPinNumber'];
// Load the data up at random to the ping count!
$query = "SELECT *
FROM {$db_prefix}members
WHERE latitude IS NOT NULL AND longitude IS NOT NULL
$sql_addon
ORDER BY RAND()
LIMIT 0, $maxPins";
} else {
// Looks like we passed under the max, Load everyone...
$query = "SELECT *
FROM {$db_prefix}members
WHERE latitude IS NOT NULL AND longitude IS NOT NULL
ORDER BY `realName` ASC ";
}
$request = db_query($query, __FILE__, __LINE__);
//Ok this is block of code takes care of the entire load all member data into $themeUser/$memberContext on per # basis
$temp = array();
while ($row = mysql_fetch_array($request, MYSQL_ASSOC))
$temp[] = $row['ID_MEMBER'];
loadMemberData($temp);
foreach ($temp as $v)
loadMemberContext($v);
// Seeing how SMF 1.0 uses $themeUser and SMF 1.1 uses $memberContext, lets just make our own now?
if (isset($memberContext))
$data = $memberContext;
elseif (isset($themeUser))
$data = $themeUser;
// Lets accualy start making XML Mr. PHP, and should this not be UTF-8?
echo '<?xml version="1.0" encoding="UTF-8"?> <markers>';
if (isset($data)) {
// Assuming we have data to work with...
foreach ($data as $marker) {
$datablurb = '
<table class="googleMaps" border="0">
<tr>
<td style="white-space: nowrap;" align="left"><a href="' . $marker['online']['href'] . '"><img src="' . $marker['online']['image_href'] . '" alt="' . $marker['online']['text'] .'" class="avatar" border="0" /></a> <a class="mapProfile" href="' . $marker['href'] .'">' . $marker['name'] . '</a></td>
<td rowspan="3">' . $marker['avatar']['image'] . '</td>
</tr><tr>
<td style="white-space: nowrap;">' . $marker['title'] . '</td>
</tr><tr>
<td style="white-space: nowrap;" colspan="2" align="left">';
if (($marker['website']['url'] != '') && ($marker['website']['title'] != ''))
$datablurb = $datablurb . '<a class="mapProfile" href="' . $marker['website']['url'] . '">' . $marker['website']['title'] . '</a>';
$datablurb = $datablurb . '</td>
</tr><tr>
<td class="mapProfile" style="white-space: nowrap;" colspan="2" align="left">' . $marker['blurb'] . '</td>
</tr>
</table>';
// This is to help against those funky chars... and protect against those " errors in XML!
$datablurb = htmlspecialchars($datablurb);
// Lets bring it all together...
$markers = '<marker lat="' . $marker['googleMap']['latitude'] . '" lng="' . $marker['googleMap']['longitude'] . '" ';
if ($marker['gender']['numeric'] == "1") {
$markers = $markers . 'gender="1"';
} elseif ($marker['gender']['numeric'] == "2") {
$markers = $markers . 'gender="2"';
} else {
$markers = $markers . 'gender="0"';
}
$markers = $markers . ' label="' . $marker['name'] . '" html="'. $datablurb . '" />';
echo $markers;
}
}
echo '
</markers>';
// Ok we should be done with output, dump it to user...
obExit(false);
}
function ShowKML () {
global $db_prefix, $context, $scripturl, $txt, $modSettings, $user_info, $mbname, $themeUser, $memberContext;
// Are we allowed to view the map? Keep in mind here we should be a guest unless user is in IE!
isAllowedTo('googleMap_view');
// If it's not enabled, die.
if (empty($modSettings['xmlnews_enable']))
obExit(false);
// This is an kml file, its like an XML file...
ob_end_clean();
if (!empty($modSettings['enableCompressedOutput']))
@ob_start('ob_gzhandler');
else
ob_start();
// Lets make sure its sent as KML
header('Content-type: application/keyhole;');
// It will be called ourforumname.kml
header('Content-Disposition: attachment; filename="' . $mbname . '.kml"');
// Load the data up, and seeing how its google earth, lets just send everything.
// If we get complaints about this, then we shall have to figure out how to limit it.
$request = db_query("
SELECT *
FROM {$db_prefix}members
WHERE latitude IS NOT NULL AND longitude IS NOT NULL
", __FILE__, __LINE__);
//Ok this is block of code takes care of the entire load all member data into $memberContext on per # basis
$temp = array();
while ($row = mysql_fetch_array($request, MYSQL_ASSOC))
$temp[] = $row['ID_MEMBER'];
loadMemberData($temp);
foreach ($temp as $v)
loadMemberContext($v);
// Seeing how SMF 1.0 uses $themeUser and SMF 1.1 uses $memberContext, lets just make our own now?
if (isset($memberContext))
$data = $memberContext;
elseif (isset($themeUser))
$data = $themeUser;
echo '<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Folder>
<name>' . $mbname . '</name>
<open>0</open>';
if (isset($data)) {
// Assuming we have data to work with...
foreach ($data as $marker) {
echo '
<Placemark>
<description>
<![CDATA[';
echo '
<table class="googleMaps" border="0" style="white-space: nowrap;">
<tr>
<td style="white-space: nowrap;" align="left"><a href="' . $marker['online']['href'] . '"><img src="' . $marker['online']['image_href'] . '" alt="' . $marker['online']['text'] .'" class="avatar" border="0" /></a> <a href="' . $marker['href'] .'">' . $marker['name'] . '</a></td>
<td rowspan="3">' . $marker['avatar']['image'] . '</td>
</tr><tr>
<td style="white-space: nowrap;">' . $marker['title'] . '</td>
</tr><tr>
<td style="white-space: nowrap;" align="center">
' . $marker['icq']['link'] . '
' . $marker['aim']['link'] . '
' . $marker['yim']['link'] . '
' . $marker['msn']['link'] . '
</td>
</tr><tr>
<td style="white-space: nowrap;" colspan="2" align="left">';
if (($marker['website']['url'] != '') && ($marker['website']['title'] != ''))
echo '<a href="' . $marker['website']['url'] . '">' . $marker['website']['title'] . '</a>';
echo ' </td>
</tr><tr>
<td style="white-space: nowrap;" colspan="2" align="left">' . $marker['blurb'] . '</td>
</tr>
</table>';
echo '
]]>
</description>
<name>' . $marker['name'] . '</name>
<LookAt>
<longitude>' . $marker['googleMap']['longitude'] . '</longitude>
<latitude>' . $marker['googleMap']['latitude'] . '</latitude>
<range>15000</range>
</LookAt>
<styleUrl>root://styles#default+icon=0x304</styleUrl>';
/* This does not appeal to me right now...
if ($modSettings['googleMapsPinGender']) {
echo '
<Style>
<IconStyle>
<color>';
if ($marker['gender']['name'] == "Male") {
echo 'ffff6464';
} elseif ($marker['gender']['name'] == "Female") {
echo 'ff6464ff';
} else {
echo 'ff64ff64';
}
echo ' </color>
</IconStyle>
</Style>';
}
*/
echo '
<Point>
<extrude>1</extrude>
<altitudeMode>absolute</altitudeMode>
<coordinates>' . $marker['googleMap']['longitude'] . ',' . $marker['googleMap']['latitude'] . ',8000</coordinates>
</Point>
</Placemark>';
}
}
echo '
</Folder>
</kml>';
// Ok done, should send everything now..
obExit(false);
}
?>