For the life of me, I can not get this to work. I'm trying to pass the Marker Clusterers to my Google Map - but it's not working. I've got this map set up through Google Maps API and it's for a Wordpress website. The user can add locations using a Custom Post type. There are a lot of locations in close proximities, so I'm trying to use the MarkerCluster to lighten it up a bit. I've never used the MarkerCluster before, so it could be a small thing, too... not sure.
'var mc = new MarkerClusterer(map);' --This draws an error of: "Uncaught ReferenceError: MarkerClusterer is not defined"
Any insight? Any help is greatly appreciated!!
<?php // Index template
get_header(); ?>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<div class="twelve column">
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="intro">
<?php the_excerpt(); ?>
<hr>
</div>
<?php the_content(); ?>
<header class="clearfix"></header>
<div id="mapcanvas"></div>
<?php
// For creating multiple, customized loops.
// http://codex.wordpress.org/Class_Reference/WP_Query
$custom_query = new WP_Query('post_type=locations'); // exclude category 9
while($custom_query->have_posts()) : $custom_query->the_post(); ?>
<?php if(get_field('link')): ?>
<div>
<?php while(has_sub_field('link')): ?>
<div>
<p><?php the_sub_field('url'); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
<?php endwhile; ?>
<?php wp_reset_postdata(); // reset the query ?>
<?php
function get_single_term($post_id, $taxonomy)
{
$terms = wp_get_object_terms($post_id, $taxonomy);
if(!is_wp_error($terms)) {
return ''.$terms[0]->name.'';
}
}
$i = 0;
// For creating multiple, customized loops.
// http://codex.wordpress.org/Class_Reference/WP_Query
$custom_query = new WP_Query('post_type=location&posts_per_page=-1');
while($custom_query->have_posts()) : $custom_query->the_post();
$title = get_the_title(); // Location title
$map = get_field('location'); // ACF location contains address and coordinates
$terms = strip_tags( get_the_term_list( $post->ID, 'distributors', '', ' & ' )); // Get distributor terms and rm links
$info = '<strong>' . $title . '</strong><br>' . $map['address']; // Info window content
$link = get_field('link');
if($link){
$info .= '<br>'. $link .'';
}
$location[$i][0] = $title; // Store the post title
$location[$i][1] = $map['coordinates']; // Store the ACF coordinates
$location[$i][2] = json_encode($info); // Store info window content
$location[$i][3] = strip_tags( get_single_term( $post->ID, 'distributors' )); // Get first term for marker icon
$i ++;
endwhile; ?>
<?php wp_reset_postdata(); // reset the query ?>
<script>
$(function initialize() {
geocoder = new google.maps.Geocoder();
// Center map on our main location
var myLatLng = new google.maps.LatLng(41.583013,-93.63701500000002);
var bounds = new google.maps.LatLngBounds();
// https://developers.google.com/maps/documentation/javascript/styling
// Create an array of styles.
var styles = [
{
stylers: [
{ saturation: -99.9 }
]
}
];
// Create a new StyledMapType object, passing it the array of styles,
// as well as the name to be displayed on the map type control.
var styledMap = new google.maps.StyledMapType(styles, {name: 'exile'});
// Create a map object, and include the MapTypeId to add
// to the map type control.
var mapOptions = {
mapTypeId: 'roadmap',
center: myLatLng,
zoom: 14,
disableDefaultUI: false,
scrollwheel: true,
draggable: true
};
// Display a map on the page
var map = new google.maps.Map(document.getElementById("mapcanvas"), mapOptions);
var mc = new MarkerClusterer(map);
map.setTilt(45);
//Associate the styled map with the MapTypeId and set it to display.
map.mapTypes.set('exile', styledMap);
map.setMapTypeId('exile');
// Marker icons
typeObject = {
"Others" : {
"icon" : new google.maps.MarkerImage('http://exilebrewing.com/site/img/beer-mug.png', new google.maps.Size(18,26), new google.maps.Point(0,0), new google.maps.Point(9,26)),
"shadow" : new google.maps.MarkerImage('http://maps.google.com/mapfiles/shadow50.png', new google.maps.Size(40,34))
}
}
// http://wrightshq.com/playground/placing-multiple-markers-on-a-google-map-using-api-3/
// Multiple Markers
var markers = [
["Exile Brewing Co", 41.583013,-93.63701500000002,"Others"],
<?php
if (count($location)>0) {
foreach ($location as $key => $value){
if ($key < (count($location)-1)){
echo '["' . $location[$key][0] . '",' . $location[$key][1] . ',"' . $location[$key][3] . '"], ' . "\n";
} else {
echo '["' . $location[$key][0] . '",' . $location[$key][1] . ',"' . $location[$key][3] . '"]';
}
}
}
?>
];
var markers = [];
for (var i = 0; i < 100; i++) {
var latLng = new google.maps.LatLng(data.photos[i].latitude,
data.photos[i].longitude);
var marker = new google.maps.Marker({'position': latLng});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
// Info Window Content
var infoWindowContent = [
["<strong>Exile Brewing Co.</strong><br>1514 Walnut Street, Des Moines"],
<?php
if (count($location)>0) {
foreach ($location as $key => $value){
if ($key < (count($location)-1)) {
echo '[' . $location[$key][2] . '], ' . "\n";
} else {
echo '[' . $location[$key][2] . ']';
}
}
}
?>
];
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]); // ACF coordinates
var icon = typeObject[markers[i][3]]['icon'];
var shadow = typeObject[markers[i][3]]['shadow'];
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0],
icon: icon,
shadow: shadow
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
// Automatically center the map fitting all markers on the screen
//map.fitBounds(bounds);
}
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(15);
google.maps.event.removeListener(boundsListener);
});
});
</script>
<div id="map-canvas"></div>
<footer class="clearfix"></footer>
<?php endwhile;?>
<?php endif; ?>
</div>
</div>
<?php get_footer(); ?>
As per my comments :
You need to download the script ( here ) and then Include it in your page.
Marker clusterer is not a built-in feature of google maps , but an addon script ..
<script src="markerclusterer.js" type="text/javascript"></script>
or in the "correct" wordpress way :
wp_register_script( 'js_marker_clusterer', plugins_url( '/scripts/MarkerClusterer.js', __FILE__ ),'jquery' ); // or other dependencies descendents - preferably map JS or your custom.
wp_enqueue_script('js_marker_clusterer');
( change to your paths )
Also, look at the examples ( HERE ) and check their code ( and includes )
You need to include the third party marker clusterer script if you want to use it.
As specified in the documentation:
Note: Be sure to include markerclusterer.js or markerclusterer_packed.js in your HTML document.
<script src="/path/to/markerclusterer.js" type="text/javascript"></script>
Related
I am creating a shortcode that grabs specific content from an url which i passed as a shortcode attribute. The problem happens when this a shortcode is used more than once on a single post. Then the second shortcode overrides the first one. Here is the code. Two values are displayed on the page both both are the same and are pulled from the second shortcode attribute. There should be two separate and different values.
Here is the shortcode code:
<?php
function grabUrl_func( $atts ) {
$url = $atts['url'];
$label = $atts['label'];
$productId = $atts['id'];
?>
<script>
var urlFromSc = <?php echo json_encode($url) ?>;
var buttonLabel = <?php echo json_encode($label) ?>;
jQuery(document).ready(function() {
jQuery.get(urlFromSc, function(response) {
// grab product name
var productName = jQuery(response).find('.product-name');
var productNameContent = productName[1]['innerHTML'];
jQuery('.g-title').append(productNameContent);
// grab image
var productImage = jQuery(response).find('.product-image-gallery');
var productImageContent = productImage[0]['innerHTML'];
jQuery('.g-image').append(productImageContent);
jQuery('.g-image img').slice(1).remove();
// grab price
var productPrice = jQuery(response).find('.price-box');
var productPriceContent = productPrice[0]['innerHTML'];
jQuery('.g-price').append(productPriceContent);
// grab rating
var productRating = jQuery(response).find('.yotpo');
var productRatingContent = productRating[0]['outerHTML'];
var productId = jQuery(productRatingContent).attr('data-product-id');
var link = jQuery('<a class="productLink" href="' + urlFromSc + '">' + buttonLabel + '</a>' );
jQuery('.g-link').append(link);
});
});
</script>
<?php
$output = '<div class="g-wrapper">'
. '<div class="g-image"></div>'
. '<div class="g-title"></div>'
. '<div class="g-price"></div>'
. '<div class="g-rating">'
. '<div class="yotpo yotpo-main-widget" data-product-id="'.$productId.'"></div>'
. '</div>'
.'<div class="g-link"></div>'
.'</div>';
return $output;
}
add_shortcode( 'grabUrl', 'grabUrl_func' );
?>
Thanks in advance for your help!
I'm building a website with a page that shows all locations (Custom Post Type) on a Google map. I use ACF (Advanced Custom Fields) to add the map location to the specific location. Furthermore I give each location a category (Parking, Hotel, ect.).
At this point all locations are show on the map correctly. But I'm trying to find a way to toggle these locations based on their category. So initially I want to hide all markers on the map and toggle their visibility based on a click (anchor or checkbox, doesn't matter).
I did see some answers that looked promising, but I can't figure this out with the code provided by ACF. I hope someone can help me with this. And can tell me where to add some extra code to setvisibility and toggle this based on a category select.
The code provide by ACF is shown below:
<script type="text/javascript">
(function($) {
/*
* new_map
*
* This function will render a Google Map onto the selected jQuery element
*
* #type function
* #date 8/11/2013
* #since 4.3.0
*
* #param $el (jQuery element)
* #return n/a
*/
function new_map( $el ) {
// var
var $markers = $el.find('.marker');
// vars
var args = {
zoom : 16,
center : new google.maps.LatLng(0, 0),
mapTypeId : google.maps.MapTypeId.ROADMAP
};
// create map
var map = new google.maps.Map( $el[0], args);
// add a markers reference
map.markers = [];
// add markers
$markers.each(function(){
add_marker( $(this), map );
});
// center map
center_map( map );
// return
return map;
}
/*
* add_marker
*
* This function will add a marker to the selected Google Map
*
* #type function
* #date 8/11/2013
* #since 4.3.0
*
* #param $marker (jQuery element)
* #param map (Google Map object)
* #return n/a
*/
function add_marker( $marker, map ) {
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map
});
// add to array
map.markers.push( marker );
// if marker contains HTML, add it to an infoWindow
if( $marker.html() )
{
// create info window
var infowindow = new google.maps.InfoWindow({
content : $marker.html()
});
// show info window when marker is clicked
google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
});
}
}
/*
* center_map
*
* This function will center the map, showing all markers attached to this map
*
* #type function
* #date 8/11/2013
* #since 4.3.0
*
* #param map (Google Map object)
* #return n/a
*/
function center_map( map ) {
// vars
var bounds = new google.maps.LatLngBounds();
// loop through all markers and create bounds
$.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
// only 1 marker?
if( map.markers.length == 1 )
{
// set center of map
map.setCenter( bounds.getCenter() );
map.setZoom( 16 );
}
else
{
// fit to bounds
map.fitBounds( bounds );
}
}
/*
* document ready
*
* This function will render each map when the document is ready (page has loaded)
*
* #type function
* #date 8/11/2013
* #since 5.0.0
*
* #param n/a
* #return n/a
*/
// global var
var map = null;
$(document).ready(function(){
$('.acf-map').each(function(){
// create map
map = new_map( $(this) );
});
});
})(jQuery);
</script>
The code that renders my markers is as follows:
<div class="acf-map">
<?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
<?php
$location = get_field('google_maps_adres');
if( !empty($location) ):
?>
<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>">
<h4 class="marker__title"><?php the_title(); ?></h4>
<div class="marker__address">
<?php $contact_address = get_field('google_maps_adres');$address = explode( "," , $contact_address['address']); ?>
<div class="marker__address-street"><?php echo $address[0].', ';?></div>
<div class="marker__address-city"><?php echo $address[1];?></div>
</div>
<a class="marker__link" href="<?php the_permalink();?>">Meer informatie</a>
</div>
<?php endif; ?>
<?php endwhile;?>
<?php wp_reset_postdata(); ?>
</div>
I could help with this but maybe it's already answered here. Take a look and try the solution proposed there. If that doesn't work for you let me know and we can work it together ;)
EDIT:
Ok, let´s try to do this then. First of all you need to distinguish each marker, with a class or an ID. Let's do it with classes since we are using the categories and each marker can belong to several categories.
Change your code as follows:
<?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
<?php $cats = get_the_category(); //this gives me the categories of the post (marker) ?>
<?php $catsString = implode(", ",$cats); // this gives me the categories as a String separated with ", " ?>
<?php
$location = get_field('google_maps_adres');
if( !empty($location) ):
?>
<div class="marker <?php echo $catsString; ?>" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>">
<h4 class="marker__title"><?php the_title(); ?></h4>
<div class="marker__address">
<?php $contact_address = get_field('google_maps_adres');$address = explode( "," , $contact_address['address']); ?>
<div class="marker__address-street"><?php echo $address[0].', ';?></div>
<div class="marker__address-city"><?php echo $address[1];?></div>
</div>
<a class="marker__link" href="<?php the_permalink();?>">Meer informatie</a>
</div>
<?php endif; ?>
<?php endwhile;?>
All I've done is for each marker get the categories and used them as classes for the main marker container.
Now you have all your markers with their classes set. That's good. The next step is to use some input to control the visibility of those markers. Let's use a checkbox for example.
For each category you should have a checkbox:
<?php $categories = get_categories();
foreach( $categories as $category ) {
echo '<label><input class="markerToggle" type="checkbox" id="'. $category->name .'">'. $category->name .'</label>';
}
?>
Then you would need some simple Javascript to hide/show each marker
$('.markerToggle').change(function() {
if($(this).is(":checked")) {
//'checked' event code
$('.marker.' + this.id).show();
return;
}
$('.marker.' + this.id).hide();
//'unchecked' event code
});
I am using Advanced Custom Fields to set the location of a post and display it on a map within my custom post template and it works great. But I have also created a google map that plots all the locations of my custom posts types on one map.
My problem is that I can’t get it to pull content or a link into the infowindow from those custom posts. I also can't get it to change the marker depending on a true/false field.
I’ve looked around the internet and tried to use the code that google suggests as well as the users on this site, but I seem to be doing something wrong. All it does is display the title followed by a weird symbol. Any help would be appreciated :)
This is the code I am using:
<section>
<?php
$args = array(
'post_type' => 'offices',
'posts_per_page' => -1
);
// query
$wp_query = new WP_Query( $args );
$NUM = 0;
?>
<div id="map"></div>
<script src='http://maps.googleapis.com/maps/api/js?sensor=false' type='text/javascript'></script>
<script type="text/javascript">
var locations = [<?php while( $wp_query->have_posts() ){
$wp_query->the_post();
$location = get_field('location'); // IMPORTANT << Change this for your Google map field name !!!!!!
?>
['<?php the_title(); ?>', <?php echo $location['lat']; ?>, <?php echo $location['lng'];?>, <?php $NUM++ ?> ],
<?php } ?> ];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 7, /*Here you change zoom for your map*/
center: new google.maps.LatLng(42.6, -76.0), /*Here you change center map first location*/
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
</script>
</section>
Yes, I got your problem. As per me you are doing well but you need to modify your code slightly.
Just make an array of values in your while loop like for markers :
$marker[] = '"'.get_the_title().'"'.','.$event_lat.','.$event_long;
and for marker details like :
$marker_details[] = get_the_title().'_sunil_'.get_the_content($post->ID).'_sunil_'.$ev_location.'_sunil_'.get_permalink($post->ID);
Then after this just place your script using foreach loop and explode above $marker_details array by separator sunil.
The code will be :
var markers = [
<?php foreach ($marker as $mar){
echo "[".$mar."],";
};?>
];
var infoWindowContent = [
<?php foreach ($marker_details as $mar_det){
$check_val = explode('_sunil_',$mar_det);?>
['<div class="info_content">' +
'<h3 style="display:block"><?php echo $check_val[0];?></h3><strong style="display:block;text-transform:capitalize;"><?php echo "Location : ".$check_val[2];?></strong>' +
'<p><?php echo substr($check_val[1], 0, 200);?>...</p>Read More' + '</div>'],
<?php }?>
];
Do not disturb structure by even a single comma while making it dynamic using loops. Just take a fresh html and implementation instructions from here : http://www.wptricks24.com/map-with-multiple-markers
I'm using Wordpress, and am successful at displaying a map on my site with multiple markers using GMaps. Unfortunately, I was hoping to have the "location name" hyperlinked to the relevant post on my site. For some reason though, I can't add a hyperlink to the infowindow without crashing the whole map.
Below is the functioning code, as soon as I remove the strip_tags(); function the map no longer displays. I'm guessing it's related to having too many ", but I can't figure out how to get it working.
$str = '';
foreach($loop as $p){
//get the meta and taxonomy data
$name = strip_tags(get_the_term_list($p, "mountains"));
$wtr_long = get_post_meta($p,"wtr_longitude",true);
$wtr_lat = get_post_meta($p,"wtr_latitude",true);
//Add to Array
$map_string .= '{latitude: "' . $wtr_lat . '", longitude: "' . $wtr_long . '", html: "' . $name .'"},~!~';
//$map_string .= '{latitude: "' . $wtr_lat . '", longitude: "' . $wtr_long . '", html: "name"},~!~';
}
//Remove last three "~!~" characters from the string not to have one too many arrays when exploding
$clean_map_string = substr($map_string, 0, -3);
//Now I can use explode on ~!~ to get arrays with my string
$map_array = explode('~!~', $clean_map_string);
?>
<!--Map implementation-->
<div id="map" style="width:880px; height: 600px; background-color:grey;"></div>
<script type="text/JavaScript">
$("#map").gMap({
scrollwheel: false,
maptype: G_PHYSICAL_MAP,
markers: [
<?php
$i = 0;
$length = count($map_array)-1;
//Inserts all the markers
foreach($map_array as $value){
if( $i != $length ){
echo $value;
}
else {
echo str_replace("},", "}],", $value);
}
$i++;
}
?>
popup: false,
zoom: 2 });
</script>
InfoWindows usually have no problems with tags. You are trying to create a JSON-string there, use json_encode() instead of this mixture of string-functions to avoid invalid characters inside the string.
<?php
$markers=array();
foreach($loop as $p){
$markers[]=array(
'latitude' => get_post_meta($p,"wtr_latitude",true),
'longitude' => get_post_meta($p,"wtr_longitude",true),
'html' => get_the_term_list($p, "mountains")
);
}
?>
<!--Map implementation-->
<div id="map" style="width:880px; height: 600px; background-color:grey;"></div>
<script type="text/JavaScript">
$("#map").gMap({
scrollwheel: false,
maptype: G_PHYSICAL_MAP,
markers: <?php echo json_encode($markers);?>,
popup: false,
zoom: 2 });
</script>
I have a set of different map types (styles). As you can see in the simplified example, I try to switch the map types with an onClick event.
This works great for the default - by google.maps provided - styles. But when I try to switch to my custom style, I have a delay of ~2-3 seconds (local environment) and then get a completely grey map (nothing on the tiles).
I know that the map style itself works (not the same as in the linked example), because it's my initial map style. So only the switch back to my custom style is not working. Sadly I get nothing in the console and don't know how I could debug this.
<?php
// Inside the init(); function:
?>
var custom_style = [
{
featureType: 'water'
,stylers: [
{ hue: "#009ee0" }
,{ saturation: 100 }
,{ lightness: 0 }
]
}
];
var CUSTOMMAPTYPE = new google.maps.StyledMapType(
custom_style,
// Options:
{
alt: "Show Custom style",
name: "custom"
}
);
<?php
// Inside the view
$map_types = array(
'Roadmap'
,'Terrain'
,'Satellite'
,'Hybrid'
,'CustomMapType'
);
foreach ( $map_types as $index => $type )
{
?>
<span
class="map-type"
onClick="
my_map.setMapTypeId( google.maps.MapTypeId.<?php echo strtoupper( $type ); ?> );
// This is funny: I can access all mapType objects without a problem:
console.log( my_map.mapTypes.<?php echo strtolower( $type ); ?> );
"
id="<?php echo strtolower( $type ); ?>"
>
<?php echo $type; ?>
</span>
<?php
}
?>
Any help is highly appreciated.
Thanks in advance
EDIT:
Here's something other I tried (from inside my init(); fn, that does the setup for the map):
// The map type control DOM/UI Element
var map_type_controls = document.getElementsByClassName( 'map-type' );
// using jQuery to add a DOM listener function for click events to the UI elements:
jQuery.each( map_type_controls, function() {
google.maps.event.addDomListener( this, 'click', function() {
var control_id = jQuery( this ).attr( 'id' );
var control = control_id.toUpperCase();
// uncomment to debug:
// Shows all map type control DOM element correct
// console.log( control );
// Shows all registered mapType objects incl. the custom one correct:
// console.log( my_map.mapTypes );
my_map.setMapTypeId( google.maps.MapTypeId[ control ] );
// Per recommendation - doesn't help
google.maps.event.trigger( atlas_map, "resize" );
} );
} );
Normally when you modified a property of a map, let's say a new coordinates or a zoom, even if you change the size of the container (div), you should trigger the event called resize it's the only way to avoid this problem, now, i don't know if this works when you change the type of the map but you should try, the code it's the following:
google.maps.event.trigger(map, "resize");