Following are the instructions and code needed to update ocUsermap so that it uses Google maps API v3 and Marker Clustering to group nearby member on the map together.
Here is an example of the updated ocUsermap in use:
Once you have this base, you can then customise to your hearts content by changing just the template. In keeping with my site's gaming theme, my map looks like this:
OK. Now for the instructions.
Step 1:
In /sources_custom/blocks/main_google_map_users.php, replace the run() function with this:
function run($map) { require_code('catalogues'); require_javascript('javascript_ajax'); require_lang('main_google_map_users');
$latitude_cpf_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_custom_fields f LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'translate t ON f.cf_name=t.id','f.id',array('text_original'=>'ocp_latitude')); $longitude_cpf_id=$GLOBALS['FORUM_DB']->query_value_null_ok('f_custom_fields f LEFT JOIN '.$GLOBALS['FORUM_DB']->get_table_prefix().'translate t ON f.cf_name=t.id','f.id',array('text_original'=>'ocp_longitude'));
if(is_null($longitude_cpf_id) || is_null($latitude_cpf_id)) return new ocp_tempcode();
$members_to_show=$GLOBALS['FORUM_DB']->query('SELECT * FROM '.$GLOBALS['FORUM_DB']->get_table_prefix().'f_member_custom_fields f WHERE field_'.$longitude_cpf_id.'<>"" AND field_'.$latitude_cpf_id.'<>""');
if(!is_array($members_to_show) || count($members_to_show)==0) return new ocp_tempcode();
if (!array_key_exists('title',$map)) $map['title']=''; if (!array_key_exists('username_prefix',$map)) $map['username_prefix']='Member: '; if (!array_key_exists('latfield',$map)) $map['latfield']='-37.813187'; // Google API v3 requires a center to be defined if (!array_key_exists('longfield',$map)) $map['longfield']='144.962980'; // Google API v3 requires a center to be defined $mapwidth=array_key_exists('width',$map)?strval($map['width']):'100%'; $mapheight=array_key_exists('height',$map)?strval($map['height']):'300px'; $setZoom=array_key_exists('zoom',$map)?strval($map['zoom']):'3'; $setCenter=array_key_exists('center',$map)?strval($map['center']):'0';
$member_data_js = "var data=["; foreach($members_to_show as $member_data) { $member_data_js.="['".$GLOBALS['FORUM_DRIVER']->get_username($member_data['mf_member_id'])."',".$member_data['field_'.$latitude_cpf_id].",".$member_data['field_'.$longitude_cpf_id]."],"; } $member_data_js = substr($member_data_js, 0, strlen($member_data_js)-1); //drop the trailing ',' from the last entry in the array. $member_data_js.="];";
function initialize() { var bounds = new google.maps.LatLngBounds(); var center = new google.maps.LatLng({LAT},{LONG}); var map = new google.maps.Map(document.getElementById('map_canvas'), { zoom: {ZOOM}, center: center, mapTypeId: google.maps.MapTypeId.ROADMAP, overviewMapControl: true, overviewMapControlOptions: { opened: true }, });
var infoWindow = new google.maps.InfoWindow();
// Close InfoWindow when clicking anywhere on the map. google.maps.event.addListener(map, 'click', function () { infoWindow.close(); });
{DATA}
var markers = []; for (var i = 0; i < data.length; i++) { var latLng = new google.maps.LatLng(data[i][1], data[i][2]); bounds.extend(latLng);
var marker = new google.maps.Marker({ position: latLng, title: '{USERNAME_PREFIX}' + data[i][0] });
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function (argMarker, argMember) { return function () { // Dynamically load a specific members details only when their marker is clicked. var reply = load_XML_doc("{$BASE_URL}/data_custom/get_member_tooltip.php?member=" + argMember, null); var content = reply.responseXML.documentElement.getElementsByTagName('result')[0].firstChild.nodeValue; if (content != "") { infoWindow.setContent(content); infoWindow.open(map, argMarker); } }; })(marker, data[i][0])); // These are the args passed to the dynamic function above. }
var markerCluster = new MarkerClusterer(map, markers);
// Fit the map around the markers, but only if we don't want the map centered. if (!{CENTER}) { map.fitBounds(bounds); } } google.maps.event.addDomListener(window, 'load', initialize);
Funnily enough I was asked to look at that clustering thing last night for an upcoming project. Would you like me to take this code and put it into a new version of the map block, and re-credit it to yourself? I just need you to put out as public domain or BSD license for this.
If not, please let us know how we can do better (please make suggestions that are economically viable and scalable, not just requests to do more for free).
If so, please let others know about ocPortal whenever you see the opportunity.
This information has not loaded yet. It will be generated in the background, please come back later.
If I answered something that you think should be in the documentation, please take the initiative and add it to the community documentation. We really need people to help out here and build a well-organised large support resource.
Putting it into a new map block would make it easier for some people to implement, so please go ahead.
I was originally considering doing that, but decided against it only because I knew you made a few changes to ocUsermap to fix custom profile field creation problems so did not want to mess with it. That, and the fact that I'm still using v7.01 which don't include your fixes yet.
Notes about the block assistant:
* API keys are no longer required (which I'm sure you were aware of) so you can remove references to it. * When the centre check box is unchecked the initial map is displayed such that all clusters and markers are visible on the map. This may or may-not me noteworthy. * Title description refers to time instead of title * Inconsistent use of centre/center
Do you have a Samsung Galaxy S / Galaxy S II ? If so, why not check out my ScreenFree FM Radio .
If not, please let us know how we can do better (please make suggestions that are economically viable and scalable, not just requests to do more for free).
If so, please let others know about ocPortal whenever you see the opportunity.
This information has not loaded yet. It will be generated in the background, please come back later.
If I answered something that you think should be in the documentation, please take the initiative and add it to the community documentation. We really need people to help out here and build a well-organised large support resource.
Thank you Chris for incorporating it with the block!
Yes, this is cool on both counts! I second Jean's comments
Art and Imagination
of David L Friend http://davidlfriend.com My Art Gallery powered by ocPortal
Prehistorics Illustrated http://prehistoricsillustrated.com Another ocPortal powered website &
The Fascinating World of Dinosaurs & Prehistoric Creatures of all Kinds
Consider this beta, but it seems to work perfectly on my tests (only tried Google Chrome though).
Changes
incorporates temp1024's code above, and his suggestions
user geolocation from within the block is still there (temp1024 stripped it) but it is controlled by a block option which explains it will ask the users permission if the option is enabled
Fixed missnamed block options: longfield/latfield renamed to longitude/latitude
API key code is still there but not advertised, just in case Google bring API keys back
temp1024's clustering is controlled by a block option
general code cleanups, meets our standard better, more user friendly
block parameter to filter results based on username
block parameter to filter results based on primary usergroup
better performance (no longer uses 1 query per user)
if no longitude/latitude is given for the default position it will geolocate the current user
new option for specifying the Google maps region code (defines how it looks for local expectations)
example code on how to give different usergroups different marker icons (commented out inside template)
example code on how to grab longitude/latitude of mouse clicks (useful for developers)
If not, please let us know how we can do better (please make suggestions that are economically viable and scalable, not just requests to do more for free).
If so, please let others know about ocPortal whenever you see the opportunity.
This information has not loaded yet. It will be generated in the background, please come back later.
If I answered something that you think should be in the documentation, please take the initiative and add it to the community documentation. We really need people to help out here and build a well-organised large support resource.
If not, please let us know how we can do better (please make suggestions that are economically viable and scalable, not just requests to do more for free).
If so, please let others know about ocPortal whenever you see the opportunity.
This information has not loaded yet. It will be generated in the background, please come back later.
If I answered something that you think should be in the documentation, please take the initiative and add it to the community documentation. We really need people to help out here and build a well-organised large support resource.
user geolocation from within the block is still there (temp1024 stripped it)
I thought I did leave it in, what did I miss ? The code in the template was untouched, and main_google_map_users.php could not know about any new location because they are only passed to set_coordinates.php.
Chris Graham said
Equivalent updates to ocdatamap.
I suspected that you would do that also.
EDIT: Just had a bit of a play and I can't get filters to work properly.
* For usergroup filter, tried "administrators" and "staff", neither of which worked. * For term filter "testc6" works, but not "test*", but I note that it does not say that is supports ocFilter like the usergroup filter. Is it supposed to? If not why not?
'SET_COORD_URL' was not referenced in it. I'm not accusing you (), I think not having it is good for 50% of cases because of that browser permissions request it generates. Hence why I put it back but only as an option.
For usergroup filter, tried "administrators" and "staff", neither of which worked.
Numeric IDs.
For term filter "testc6" works, but not "test*", but I note that it does not say that is supports ocFilter like the usergroup filter. Is it supposed to? If not why not?
It's an SQL LIKE clause, but I think I also tied it to a substring, so you don't need the wildcards. If you do want wildcards, they have to be SQL ones: % and ?. ocFilter doesn't do wildcard string searching, the operators provided in that are for ranges or subtree selection. However this isn't ocFilter because there are no "ranges"/"trees" as far as usernames are concerned.
If not, please let us know how we can do better (please make suggestions that are economically viable and scalable, not just requests to do more for free).
If so, please let others know about ocPortal whenever you see the opportunity.
This information has not loaded yet. It will be generated in the background, please come back later.
If I answered something that you think should be in the documentation, please take the initiative and add it to the community documentation. We really need people to help out here and build a well-organised large support resource.
It wasn't referenced in my template changes, but it was in the rest of the template. My instructions were to only replace {CONTENT}, not the entire template.
I'm not accusing you ()
And I'm not saying you can't read instructions .
Thanks for clarification on the filters .
Do you have a Samsung Galaxy S / Galaxy S II ? If so, why not check out my ScreenFree FM Radio .
If not, please let us know how we can do better (please make suggestions that are economically viable and scalable, not just requests to do more for free).
If so, please let others know about ocPortal whenever you see the opportunity.
This information has not loaded yet. It will be generated in the background, please come back later.
If I answered something that you think should be in the documentation, please take the initiative and add it to the community documentation. We really need people to help out here and build a well-organised large support resource.
1 guests and 0 members have just viewed this: None