Could someone help me with this code?
In my Rails project (I don't think it matters what project it is) I have a header that is fixed in position, called 'fixed_header'. There are links on this page, which load new pages underneath, when clicked.
One of the pages which loads, when clicked, has a div called 'map_canvas'. I want the code in my 'fixed_header' page to check for the existence of a div called 'map_canvas', and then, if it is there, load a map into it.
My code below is taken from snippets throughout my application, which work, but I can't make it work for this particular thing. Any help would be appreciated.
<script>
//Is 'ready' the code to use? This code is in 'fixed_header'
//My idea is that, once
//a link in 'fixed_header' is clicked, a new page loads
//underneath the header. The div 'map_canvas' is
//searched for and the function activates if it is found.
$(document).on("ready", function () {
if ($("#map_canvas").length > 0) {
initialize_google_maps();
}
});
function initialize_google_maps() {
var currentlatlng = new google.maps.LatLng(user_latitude, user_longitude);
var zoom = 10;
var myOptions = {
zoom: zoom,
center: currentlatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP, // ROADMAP, SATELLITE, HYBRID
streetViewControl: false
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var marker = new google.maps.Marker({
map: map,
position: currentlatlng,
icon: {
oppacity: 0
}
});
var circle = new google.maps.Circle({
map: map,
fillOpacity: 0,
strokeWeight: 2,
strokeOpacity: 0.7,
radius: 10000,
});
circle.bindTo('center', marker, 'position');
}
</script>
Because you want to check the div existence in real time when user clicks on link the you should change your code
$(document).on("ready", function () {
if ($("#map_canvas").length > 0) {
initialize_google_maps();
}
});
as below
$('a').live('click',function() {
if ($("#map_canvas").length > 0) {
initialize_google_maps();
}
}
use the anchor selector according to your link classes or ids.
Related
Trying to modify an example and use markerLabel class instead of google.maps.marker.
Searched for a resolution here but couldn't find anything.
The markerwithlabel is declared as var marker = new MarkerWithLabel({
I get this error
Uncaught TypeError: this.setValues is not a function
Please check the codepen bellow.
https://codepen.io/anon/pen/LgOzRO
I tried to include only the code related to this issue and the minimal code required to reproduce this.
var map;
var locations = [];
function initialiseMap() {
$.getJSON("https://sheets.googleapis.com/v4/spreadsheets/1fBLlw8xlO_yhL8rYfFlQnzvKR-swEtE7NRX41ysARCk/values/Sheet1!A2:Q?key=AIzaSyD112yF6ORTtrx1-ugfhJLcx1VHDOla1Vs", function(data) {
// data.values contains the array of rows from the spreadsheet. Each row is also an array of cell values.
// Modify the code below to suit the structure of your spreadsheet.
$(data.values).each(function() {
var location = {};
location.title = this[2];
location.latitude = parseFloat(this[15]);
location.longitude = parseFloat(this[16]);
locations.push(location);
});
// Center on (0, 0). Map center and zoom will reconfigure later (fitbounds method)
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(0, 0)
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
setLocations(map, locations);
});
}
function setLocations(map, locations) {
var bounds = new google.maps.LatLngBounds();
// Create nice, customised pop-up boxes, to appear when the marker is clicked on
var infowindow = new google.maps.InfoWindow({
content: "Content String"
});
for (var i = 0; i < locations.length; i++) {
var new_marker = createMarker(map, locations[i], infowindow);
bounds.extend(new_marker.position);
}
map.fitBounds(bounds);
}
function createMarker(map, location, infowindow) {
// Modify the code below to suit the structure of your spreadsheet (stored in variable 'location')
var position = {
lat: parseFloat(location.latitude),
lng: parseFloat(location.longitude)
};
var marker = new MarkerWithLabel({
position: position,
map: map,
title: location.title,
labelClass: "labels", // the CSS class for the label
labelInBackground: false,
icon: pinSymbol('red')
});
google.maps.event.addListener(marker, 'click', function() {
});
return marker;
}
function pinSymbol(color) {
return {
path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
fillColor: color,
fillOpacity: 1,
strokeColor: '#000',
strokeWeight: 2,
scale: 2
};
}
You're having a sequencing issue on the HTML side. When loading Javascript with a <script> tag, you should use async or defer, not both. In this case, the Google API should be loaded after the page's Javascript such that the callback, initialiseMap, is defined in time, so it should have the defer attribute. However, the Google API needs to be loaded before the V3 MarkerWithLabel is loaded, so the V3 script also needs the defer attribute and needs to go after the Google API script.
So your HTML should be
<script defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD112yF6ORTtrx1-ugfhJLcx1VHDOla1Vs&callback=initialiseMap"></script>
<script defer src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerwithlabel/src/markerwithlabel.js"></script>
I am trying to follow this tutorial to create a circle upon map on click event. Here is the initialization of the map under tab1.js:
function initMap() {
forecastmap = new google.maps.Map(document.getElementById('forecastmap'), {
center: {lat: 1.352083, lng: 103.81983600000001},
zoom: 11
});
forecastmap.addListener('click', function(e) {
createBuffer(e.latLng, forecastmap);
});
geocoder = new google.maps.Geocoder();
infowindow = new google.maps.InfoWindow();
}
Then inside my tab2.js where I perform all the logic to add the markers:
function createBuffer(coord, forecastmap) {
console.log('come in');
var marker = new google.maps.Marker({
position: coord,
map: forecastmap
});
clusterData.push(marker);
marker = new google.maps.Circle({
center: coord,
map: forecastmap,
strokeColor: '#000',
strokeWeight: 2,
strokeOpacity: 0.5,
fillColor: '#f0f0f0',
fillOpacity: 0.5,
radius: 20 * 1000
});
clusterData.push(marker);
}
I inserted a dummy message to check if the click event is registered. However, the message did not even printed out. I wonder which part of the code was wrong.
My HTML div:
<div class="box-body">
<div id="forecastmap" style="width:100%;height:350px" onclick="initMap();"></div>
</div>
Thanks!
Note that addListener is not a valid method, and you're either looking for the native addEventListener(), or Google's addDomListener().
I'm not too familiar with Google Maps, but considering the map is generated dynamically, the forecastmap variable may not available on page load. As such, you'll need to hoist the scope to an element that is available on page load, and make use of event delegation.
Instead of:
forecastmap.addListener('click', function(e) {
createBuffer(e.latLng, forecastmap);
});
You probably need something like:
document.getElementsByTagName('body')[0].addEventListener("click", function(e) {
// Check that the click target is #forecastmap
if (e.target && e.target.id == "forecastmap") {
createBuffer(e.latLng, forecastmap);
}
});
Hope this helps! :)
You have a click listener on the map div (the div with id="forecastmap"), that calls the initMap() function (onclick="initMap()"), recreating the map, losing any circle you may have added. If I remove that, and add a google.maps.event.addDomListenerOnce(document.getElementById("forecastmap"), ... that initialized the map on the first click (only), then I get markers and circles.
proof of concept fiddle
code snippet:
var forecastmap;
function initMap() {
forecastmap = new google.maps.Map(document.getElementById('forecastmap'), {
center: {
lat: 1.352083,
lng: 103.81983600000001
},
zoom: 11
});
forecastmap.addListener('click', function(e) {
createBuffer(e.latLng, forecastmap);
});
geocoder = new google.maps.Geocoder();
infowindow = new google.maps.InfoWindow();
}
// google.maps.event.addDomListener(window, 'load', function() {
google.maps.event.addDomListenerOnce(document.getElementById('forecastmap'), "click", initMap);
// });
function createBuffer(coord, forecastmap) {
console.log('come in');
var marker = new google.maps.Marker({
position: coord,
map: forecastmap
});
// clusterData.push(marker);
marker = new google.maps.Circle({
center: coord,
map: forecastmap,
strokeColor: '#000',
strokeWeight: 2,
strokeOpacity: 0.5,
fillColor: '#f0f0f0',
fillOpacity: 0.5,
radius: 20 * 1000
});
// clusterData.push(marker);
}
html,
body,
#forecastmap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div class="box-body">
<div id="forecastmap" style="width:100%;height:350px"></div>
</div>
I have a problem with google maps on mobile browsers.
The project I'm working on requires about 500 markers to be shown on a map, but when adding them, the ui freezes.
I'm using markerclusterer to add markers, and performance is fine once the markers are on the page. Is there a way to add the markers asynchronously, or to pause adding markers once the user starts scrolling?
This is the code we're using:
var mcOptions = { gridSize: 50, maxZoom: 15, zoomOnClick: false };
var mc = new MarkerClusterer(context.map, [], mcOptions);
getMarkerLocations().then(function(branches){
branches.forEach(function(branch) => {
var marker = new google.maps.Marker({
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 2,
strokeColor: 'red',
fillColor: 'red',
strokeWeight: 2,
fillOpacity: 1
},
position: new google.maps.LatLng(branch.Latitude, branch.Longitude),
visible: true
});
mc.addMarker(marker);
});
});
Thank you geocodezip, that worked like a charm! For anyone else with the same problem, here's how I fixed it:
.then(function(branches){
var loopFunction = function(branchesToAdd) => {
if (branchesToAdd.length === 0) return;
var item = branchesToAdd.pop();
var marker = new google.maps.Marker({
....
});
mc.addMarker(marker);
setTimeout(function(){loopFunction(branchesToAdd)}, 30);
};
loopFunction(branchesToShow);
});
Add the markers asynchronously, use setTimeout to schedule the addition of each marker, which will give the browser some time to render and respond to the UI.
I am trying to make tabs using js to have more data on the site.
Please view: http://dev.ateo.dk/officelab-konferencecenter/
The two tabs at the top ("Billeder" and "kort") are made using js.
If i go into the tap called "kort", the google maps will not load completely - however if i right-click and choose "Inspect Element (Q)" using firefox, the map suddenly loads.
Also, the map is not centered. on the specific location - the location is in the top left corner.
You may notice a blank square below the tab div. This is the exact same code as used within the js tab. If i comment out the in js tab, the square which is blank, will work perfectly. So it somehow seems that the js tab combined with the js google maps are not working. Can this be the case, and if so, how is it fixed?
Below i am showing the code which will init the google maps and the taps on the page:
if($('body.single-konferencested').length > 0)
{
tabs();
}
if($('body.single-konferencested').length > 0)
{
$(document).ready(function() {
function initialize() {
var myLatlng = new google.maps.LatLng(place_lat,place_lng);
var mapOptions = {
zoom: 9,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById('gmap'), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
clickable : true
});
var pinIcon = new google.maps.MarkerImage(
"http://dev.ateo.dk/wp-content/themes/ateo/img/pin_marker.png",
null, /* size is determined at runtime */
null, /* origin is 0,0 */
null, /* anchor is bottom center of the scaled image */
new google.maps.Size(24, 40)
);
marker.setIcon(pinIcon);
var content_string = '<div id="gmap_info">'+
'<div id="siteNotice">'+
'</div>'+
'<h3 id="firstHeading" class="firstHeading">'+place_title+'</h3>'+
'<div id="bodyContent">'+
'<p>'+place_address+'<br />'+place_city_zip+'</div>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: content_string
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
});
}
This following is the html showing the DOM for the "Kort" tab:
<div class="tabContent" id="kort" style="padding: 5px 10px;">
<h2>Kort</h2>
<div id="gmap" style="width: 600px; height: 400px;"></div>
<h2>test</h2>
</div>
Best regards
Patrick
If the div in which the map is going to live is not visible on page load the map will not load correctly. You should fire a resize once the div has come into view.
google.maps.event.trigger(map, 'resize');
You should bind this to the first click of the map tab.
It looks like the map is commented out of the second tab currently. If you could uncomment it it would be easier to help you more specifically!
EDIT:
to bind the function once, try this:
var tab = jQuery('ul#tabs li')[1]
jQuery(tab).one('click', function(){
google.maps.event.trigger(map, 'resize');
});
In order for the resize to work you will need access to the map variable from your init function.
It would also be easier to select the correct tab if you drop a class on it. That would be more reliable then getting the 2nd li in the tabs ul.
EDIT 2:
try adding the click function in your initialize code. Something similar to the following
var mapOptions = {
zoom: 9,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById('gmap'), mapOptions);
//add the code here, after the map variable has been instantiated
var tab = jQuery('ul#tabs li')[1]
jQuery(tab).one('click', function(){
google.maps.event.trigger(map, 'resize');
//fire a center event after the resize, this is also useful
// if bound to a window resize
map.setCenter(myLatlng)
});
//end of new code
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
clickable : true
});
It can be solved easily by re-initialize the Google Map on Tab click.
$('#kort').click(function(e) {
initialize();
resetMap(map);
});
This simple solution has found from here - How to Display Google Map Inside of a Hidden Div
I have this js code to render my map :
function loadMap(address)
{
console.log(address);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ "address": address }, function (results, status)
{
var pos = new google.maps.LatLng(53.681602, -1.911672); // default.
if (status === google.maps.GeocoderStatus.OK) {
pos = results[0].geometry.location;
} else {
alert("Error : Unable to locate!");
}
console.log(pos);
var mapOptions = {
center: pos,
zoom: 10,
zoomControl: true,
zoomControlOptions: { position: google.maps.ControlPosition.RIGHT_TOP },
mapTypeControl: false,
panControl: false,
scaleControl: false,
streetViewControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions);
var marker = new google.maps.Marker({
map: map,
position: pos,
animation: google.maps.Animation.DROP
});
});
}
Problem is first time it executes the map shows fine, but the 2nd time, the postcode is still the same, the lat/long come out the same yet the map shows partially, with only about a 1/4th of it showing in the top-left of the div.
Anything I am doing incorrectly?
EDIT:
After jterrys suggestions it still looks the same :
HTML/CSS :
#mapCanvas
{
width: 655px;
height: 472px;
border: 1px solid #ccc;
}
<div id="mapCanvas"></div>
I am using JQuery 2.0, I have also had this before when I was using <2.0
Set up the mapoptions and map just once, outside of the geocode callback - then update the marker instead of recreating the entire map.
Fiddle showing one geocode, then another, and back to the first... div positioning looks normal.
Per the updated question, This Fiddle waits for the actual activation of the second tab before rendering the map... I had the exact same issue when creating my tabbed map.
$("#two").click(function() {
init();
}
This could be much more robust and tie into the tabs events that are fired when users interact with them, but this quick example illustrates the solution.
As a side bonus, this also conserves the resources needed to display the map (as well as any quota) until the user actually activates the tab!