How to load multiple markers from json file? - javascript

I am developing a jquery mobile map application, I have map.html, map.js and map.json files as given below
function initialize() {
var latitude = 57.95,
longitude = 14.65,
radius = 8000, //how is this set up
center = new google.maps.LatLng(latitude,longitude),
bounds = new google.maps.Circle({center: center, radius: radius}).getBounds(),
mapOptions = {
center: center,
zoom: 9,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
setMarkers(center, radius, map);
}
function setMarkers(center, radius, map) {
var json = (function () {
var json = null;
$.ajax({
'async': false,
'global': false,
'url': "./map.json",
'dataType': "json",
'success': function (data) {
json = data;
}
});
return json;
})();
var circle = new google.maps.Circle({
strokeColor: '#000000',
strokeOpacity: 0.25,
strokeWeight: 1.0,
fillColor: '#ffffff',
fillOpacity: 0.1,
clickable: false,
map: map,
center: center,
radius: radius
});
var bounds = circle.getBounds();
//loop between each of the json elements
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
if(bounds.contains(latLng)) {
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: data.content
});
infoBox(map, marker, data);
}
}
circle.bindTo('center', marker, 'position');
}
function infoBox(map, marker, data) {
var infoWindow = new google.maps.InfoWindow();
// Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.content);
infoWindow.open(map, marker);
});
// Creating a closure to retain the correct data
// Note how I pass the current data in the loop into the closure (marker, data)
(function(marker, data) {
// Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.content);
infoWindow.open(map, marker);
});
})(marker, data);
}
google.maps.event.addDomListener(window, 'load', initialize);
[{
"lat": 57.95,
"lng": 14.65,
"content":"test content1"
},
{
"lat": 57.9,
"lng": 14.6,
"content":"test content2"
},
{
"lat": 57.85,
"lng": 14.55,
"content":"test content3"
}]
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 100% }
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.1.1.min.js"></script>
</script>
<script src="./map.js"></script>
</head>
<body>
<div id="map-canvas"/>
</body>
</html>
But in my code the markers are not seen.... when I tried to run a single html file without any external .js and .json file it worked but with this code I am not able to run..
i need to know where am going wrong and also neeed help on:
1. showing multiple markers in the map
2. on clicking the marker it should show the message in content tag
waiting for help...thanks in advance...

There is nothing wrong with the example, most likely the reason why you are getting this error since you are trying to opening html page directly from the browser (therefore to load map.json via file protocol).
Basically there two options available:
Option 1
You can either install a web server and access your page on localhost or upload the map.json somewhere on the web and change the url to http://example.com/map.json
Option 2
Allow the browser to access local files, for example in Chrome you could specify allow-file-access-from-files flag, for example:
> .\chrome.exe --allow-file-access-from-files

please review this code for both solution,
jQuery(function($) {
// Asynchronously Load the map API
var script = document.createElement('script');
script.src = "http://maps.googleapis.com/maps/api/js?sensor=false&callback=initialize";
document.body.appendChild(script);});
function initialize() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: 'roadmap'
};
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Multiple Markers
var markers = [
['London Eye, London', 51.503454,-0.119562],
['Palace of Westminster, London', 51.499633,-0.124755]
];
// Info Window Content
var infoWindowContent = [
['<div class="info_content">' +
'<h3>London Eye</h3>' +
'<p>The London Eye is a giant Ferris wheel situated on the banks of the River Thames. The entire structure is 135 metres (443 ft) tall and the wheel has a diameter of 120 metres (394 ft).</p>' + '</div>'],
['<div class="info_content">' +
'<h3>Palace of Westminster</h3>' +
'<p>The Palace of Westminster is the meeting place of the House of Commons and the House of Lords, the two houses of the Parliament of the United Kingdom. Commonly known as the Houses of Parliament after its tenants.</p>' +
'</div>']
];
// 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]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
// 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(14);
google.maps.event.removeListener(boundsListener);
});
}
Reference link: http://wrightshq.com/playground/placing-multiple-markers-on-a-google-map-using-api-3/

I found the DataLayer and GeoJSON features blocks are an easier way to draw static points or regions on the map. I recommend replacing your data file with GeoJSON & using the map.data.loadGeoJson(url) call.
The DataLayer link also explains how to load the URL. It talks about CORS and your issues.

This question has been answered,
run this in cmd to start chrome by letting it access local file.
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files
Rest all is correct, i could display multiple markers and onclick an info window would open..
for more readability, you can change the latlang initialized and the radius. in the above code snippet only 2 markers are visible although there are 3 in json file. increase the radius to see the 3rd marker
thanks to all for help

Related

Google Maps API loads from html file, but not on local host

I am trying to connect to the Google Maps API from a localhost through an AngularJS application but the map does not appear and the map request does not reach google. The javascript file is being found by the html, and test1 is being outputted in the console, but initMap is not being called and test2 is not outputted. I expect that it is failing because a https connection is not being made to Google.
When I open the html file in a browser, the map loads fine but when I run it on my localhost, nothing comes up.
Here is my html code:
<script src="client/services/maps.client.services.map.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key={{API_KEY}}&callback=initMap"></script>
and javascript (map.js):
console.log('test1');
function initMap() {
console.log('test2');
//Markers
var markers = [
['Cardiff', 51.4539, -3.1694, 'city/cardiff'],
['Swansea', 51.6148, -3.92927895, 'city/swansea']
];
// Initialise map
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: {lat: 51.4539, lng: -3.1694}
});
var bounds = new google.maps.LatLngBounds();
for( i = 0; i < markers.length; i++ ) {
// Plot pin for each place
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
window.location.href = markers[i][3];
}
})(marker, i));
}
// Zoom so all pins are in view
map.fitBounds(bounds);
}
Does anyone understand why the initMap function is not being called?
change the order of the script tags
<script src="https://maps.googleapis.com/maps/api/js?key={{API_KEY}}&callback=initMap"></script>
<script src="client/services/maps.client.services.map.js"></script>

Google maps stop showing points v3

Hi i have trouble to find what case a problem to showing the way point on goggle maps as there were no changes in the code for a wile. way point stop showing about last week. im not familiar with google api
var map = null;
var markerArray = []; //create a global array to store markers
var myPoints =
[ [52.664167, -8.509825,' HQ','favicon.ico'] ,[52.836346, -6.913117,'point 1','http://maps.google.com/mapfiles/ms/icons/red.png ' ],[52.836202, -6.912101,'point2','http://maps.google.com/mapfiles/ms/icons/red.png ' ]];
function initialize() {
var myOptions = {
zoom:7,
center: new google.maps.LatLng(53.112, -7.448),
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map"), myOptions);
var mcOptions = {
gridSize: 30,
maxZoom: 15
};
var mc = new MarkerClusterer(map, [], mcOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// Add markers to the map
// Set up markers based on the number of elements within the myPoints array
for(var i=0; i<myPoints.length; i++){
createMarker(new google.maps.LatLng(myPoints[i][0], myPoints[i][1]), myPoints[i][2], myPoints[i][3]);
}
mc.addMarkers(markerArray , true);
}
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150, 50)
});
function createMarker(latlng, html, icons) {
var contentString = html;
var links = icons;
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: links ,
zIndex: Math.round(latlng.lat() * -100000) << 5
});
// marker.setAnimation(google.maps.Animation.BOUNCE);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
markerArray.push(marker); //push local var marker into global array
}
window.onload = initialize;
<script src="https://maps.googleapis.com/maps/api/js?v=3"
type="text/javascript"></script>
<div id="map" style="width: 800px; height: 750px;" ></div>
Any suggestions?
It seems that you are using MarkerClusterer which is a part of google maps utility library, which was moved recently. Somebody probably referenced the library straight from code.google.com/svn/... in your project, where it's not available anymore and that's why it's broken. You need to find all libraries which are referenced from https://google-maps-utility-library-v3.googlecode.com/svn and replace then with your own links.
Check this SO question, user had very similar issues to yours.
Also! check this question and answers on SO!!, there are users who experienced issues with the same library, to get more information. Read all answers, as replacing https://google-maps-utility-library-v3.googlecode.com/svn with https://rawgit.com/googlemaps/... is not a correct solution, you should download the library assets into your project and reference them from there or use CDN (but not git!).

Google Maps centre changing issue

I'm using a combination of Google Maps, GeoXML and MarkerClusterer to map historic texts to places. The user can choose the texts they want to map, and the page goes and gets the KML for those group of texts and displays it with MarkerClusterer.
Something is causing the page to recenter over India/China when new texts are selected (bottom left corner: http://lakes.jhadley.net/lit_file.htm.
Here is the primary function that deals with the map:
function loadMap(myLat, myLong, zoomLevel, generatedUrl) {
var mapOptions = {
center: new google.maps.LatLng(myLat, myLong),
zoom: zoomLevel,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mcOptions = {gridSize: 80, maxZoom: 15};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
markerclusterer = new MarkerClusterer(map, [], mcOptions);
var myParser = new geoXML3.parser({
map: map,
singleInfoWindow:true,
suppressInfoWindows:true,
createMarker:function(placemark){
var point = placemark.latlng;
var info = "<pre" + placemark.name + "<br /><br />" + placemark.description + "</pre>";
var marker = new google.maps.Marker({position:point});
//Suppress the speachbubbles and have them appear in a text window instead
google.maps.event.addListener(marker, 'click', function() {
var text = placemark.description.replace(/ target="_blank"/ig, "");
showInContentWindow(text);
}); //Add listener
markerclusterer.addMarker(marker);
}
});
myParser.parse("http://lakes.jhadley.net/generateKml/"+generatedUrl);
function showInContentWindow(text) {
var sidediv = document.getElementById('kwic_window');
sidediv.innerHTML = text;
} //showInContentWindow
} //function loadMap
I can't personally see why the map centre is being repositioned over India/China when new texts are loaded. Can anyone tell me what I'm missing?
by default geoxml3 attempts to zoom to fit the data. If you don't want it to do that, set the "zoom" option to false. From the documentation:
zoom | boolean (true) | If true, the parser will automatically move the map to a best-fit of the geodata after parsing of a KML document completes.
That is where the "center" of the markers are:
http://www.geocodezip.com/geoxml3_test/v3_geoxml3_kmltest_linktoB.html?filename=http://www.geocodezip.com/geoxml3_test/SO_20140312_1,4.kml
http://www.geocodezip.com/geoxml3_test/v3_geoxml3_kmltest_linktoB.html?filename=http://www.geocodezip.com/geoxml3_test/SO_20140312_1.kml

Google Maps API v3 not loading without fitbounds, zooming causing infinite loop/stackoverflow

Previous question here:
stack overflow with Google maps API (IE7 IE8)
I found the following question in the mean time: Google Maps API v3: Can I setZoom after fitBounds?
The solution there works just fine, when I have more than one marker on the map. However when I visit a subpage of groupbke.young.netaffinity.net eg. https://groupbke.young.netaffinity.net/hotels/ireland/dublin/dublin/young-testing-hotel-liege/specials/bed-and-breakfast
the map will only load if map.fitBounds() is called. On the other hand, even if the map is not loaded, it will throw a stack overflow error when I scroll above the map canvas.
Will throw a stack overflow anyway, if I try to use setZoom.
Any ideas?
var hoteldata = [
['Young Testing Hotel - Liège', 53.33932, -6.261427, '<div class="nearby-hotel"> <h1>Young Testing Hotel - Liège</h1> <div class="star-rating-1"></div><div class="clear"></div> <div class="nearby-hotel-image l"> <img src="http://groupbke.young.netaffinity.net/bookings/images/imagecache/3/0C9DBC143E18ED64059C1696A52D2941-60x60.jpg" border="1" class="imagetype1"/> </a> </div> <div class="nearby-hotel-description l"> <a class="nearby-hotel-desc" href="/hotels/ireland/dublin/dublin/young-testing-hotel-liege">Dublin\'s most luxurious design hotel is located in the heart of the city. Experience the best of both worlds when staying at this chic haven, to one side the tranquility and calm of St Stephen\'s Green and to the other, Grafton Street, Dublin\'s finest shopping avenue. From its central location, in amongst this buzzing vibrant city it is an easy stroll to explore the leading cultural, historical and leisure attractions. Or just step out to the chic shopping, high energy bars, fine dining restaurants and chattering Cafes.</a> Book Now </div> <div class="clear"></div> </div>', 4]
];
function initialize(mapid) {
var myOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
};
var bounds = new google.maps.LatLngBounds();
var map = new google.maps.Map(document.getElementById(mapid), myOptions);
var infowindow = new google.maps.InfoWindow();
var markers = [];
for (i = 0; i < hoteldata.length; i++) {
var latLng = new google.maps.LatLng(hoteldata[i][1], hoteldata[i][2]);
bounds.extend(latLng);
var img = '/images/hotel-marker.png';
if (hoteldata[i][4] == 2) {
img = '/images/country-marker.png';
}
if (hoteldata[i][4] == 3) {
img = '/images/guesthouse-marker.png';
}
if (hoteldata[i][4] == 4) {
img = '/images/hotel-self-marker.png';
}
var marker = new google.maps.Marker({
position: latLng,
icon: img,
shadow: '/images/marker-shadow.png'
});
markers.push(marker);
bindInfoWindow(marker, map, infowindow, hoteldata[i][3]);
}
var clusterStyles = [
{
opt_textColor: 'white',
url: '/images/m3-blue.png',
height: 65,
width: 64
},
{
opt_textColor: 'white',
url: '/images/m3-green.png',
height: 65,
width: 64
},
{
opt_textColor: 'white',
url: '/images/m3-orange.png',
height: 65,
width: 64
}
];
var mcOptions = {
styles: clusterStyles,
maxZoom:14
};
if (markers.length>1){
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
map.fitBounds(bounds);
google.maps.event.addListenerOnce(map, 'zoom_changed', function() {
var oldZoom = map.getZoom();
map.setZoom(oldZoom + (-7)); //Or whatever
});
} else if (markers.length == 1){
markers[0].setMap(map);
//google.maps.event.clearListeners(map, 'zoom_changed');
//google.maps.event.addListenerOnce(map, 'zoom_changed', function() {
// var oldZoom = map.getZoom();
// map.setZoom(oldZoom + (-7)); //Or whatever
// setTimeout('roomSetter(globalmap,globalzoom)',300);
//});
//google.maps.event.trigger(map,'zoom_changed');
//google.maps.event.clearListeners(map, 'zoom_changed');
//map.fitBounds(bounds);
//var oldZoom = map.getZoom();
//map.setCenter(bounds.getCenter());
//map.setZoom(oldZoom+(-7));
//map.setZoom(3);
//globalmap=map;
//globalzoom=map.getZoom()+(-7);
//setTimeout('zoomSetter(globalmap,globalzoom)',300);
}
}
var globalmap;
var globalzoom;
function zoomSetter(map, zoom){
//map.setZoom(zoom);
}
function bindInfoWindow(marker, map, infowindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
});
}
function initmaps() {
initialize('map_canvas');
initialize('map_thumb');
}
google.maps.event.addDomListener(window, 'load', initmaps);
I've set up 3 testpages to demonstrate the problem:
http://groupbke.young.netaffinity.net/maptest1.html
this has the setZoom() function and throws a stackoverflow error, even though this should be correct
http://groupbke.young.netaffinity.net/maptest2.html
this does nothing beyond adding the marker to the map. scroll zooming on the map still throws a stack error.
http://groupbke.young.netaffinity.net/maptest3.html
this has fitBound(), which in theory is not good, but works. can NOT adjust the zoom level after that, or it will throw a stackoverflow error. scroll zooming works.
What I was missing from the answer from my previous question was that an initial zoom level and center has to be set.
var myOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
zoom:22,
center: new google.maps.LatLng(50.820645,-0.137376)
};
Also had to change the event to 'idle' on the multi marker zooming adjustment.
if (markers.length>1){
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
map.fitBounds(bounds);
google.maps.event.addListenerOnce(map, 'idle', function() {
var oldZoom = map.getZoom();
map.setZoom(oldZoom + (-7)); //Or whatever
});
}
Works like a charm after that.
When you have only one hotel, you create a LatLngBounds object containing only one point:
for (i = 0; i < hoteldata.length; i++) {
var latLng = new google.maps.LatLng(hoteldata[i][1], hoteldata[i][2]);
bounds.extend(latLng);
...}
but you then do a map.fitBounds(bounds) — this attempts an infinite zoom. While it's arguable that the API should be able to cope with that, it's equally arguable that it will attempt to do exactly what you tell it. It's possible that IE will behave differently to Firefox and other browsers.
Where you have commented out the fitBounds() in your quoted code in the question, that is present in your online page. Since that line only applies to instances where one marker is involved and the bounds object is a single point, I would replace it with a simple setZoom() instead.
map.setZoom(16);

Automatically opening marker info pane on google map

I've created a custom map with most things I want on it (custom icon and custom info bubble), however I can't find a solution to automatically open the markers info window on load, I've done alot of searching but can't seem to find anything the code I have so far is as follows, any help would be much appreciated:
function initialize() {
var myLatlng = new google.maps.LatLng(54.325109,-2.742226);
var myOptions = {
zoom: 15,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var countries = [
{
title:'Remedy',
lat:54.3210,
lon:-2.7438,
content:"<h2>Remedy</h2><p>address, <br />location, <br />postcode</p> <p><b>T:</b> 07595 153 835 <br /><b>E:</b> <a href='mailto:email'>email</a></p>"
}
];
for (var i = 0; i < countries.length; i++) {
var c = countries[i];
c.marker = new google.maps.Marker({
position: new google.maps.LatLng(c.lat, c.lon),
map: map,
icon: '/wp-content/themes/remedy/display_images/google_map_icon.png',
title: c.title});
c.infowindow = new google.maps.InfoWindow({content: c.content});
google.maps.event.addListener(c.marker, 'click', makeCallback(c));
}
function makeCallback(country) {
return function () {
country.infowindow.open(map, country.marker);
};
}
infowindow.open(map, marker);
}
Maybe it's not working because you just created the instance of the Map and didn't wait for the complete load of the map to open the InfoWindow.
Try something like this:
google.maps.event.addListenerOnce(map, 'tilesloaded', function(event) {
infowindow.open(map, marker);
});
According to the reference:
http://code.google.com/intl/en/apis/maps/documentation/javascript/reference.html#Map
tilesloaded - This event is fired when the visible tiles have finished loading.
Hmm, inforwindow does not refer to anything in your code, which is why it is not working.
Since you have one country in the list as of now you can do a quick test and intialize the infowindow variable with an actual info window, or better yet also since you have 1 item in the list, just define c to be outside the loop so you can access it and then open the popup passing it the map and the marker, something like this (assuming c has been defined outside the loop)
c.infowindow.open(map, c.marker);
var infowindow = new google.maps.InfoWindow({
content: "Test Route",
position: new google.maps.LatLng(38.8709866, -77.208055),
});
infowindow.open(map);

Categories