Im trying to load the google maps api's dynamically.
I'm using the following code:
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'http://www.google.com/jsapi?key=<MY_KEY>;
head.appendChild(script);
but when trying to create the map
map = new GMap2(document.getElementById("map"));
or
map = new google.maps.Map2(document.getElementById("map"));
I'm getting an error that google (or GMap2) is undefined.
You can do this. You can add a callback function name in the url. It'll be called when the API gets loaded. That callback function must be accessible in the document's scope.
I did that some time ago by triggering a custom event on the window with jQuery: http://jsfiddle.net/fZqqW/5/
used "http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback"
window.gMapsCallback = function(){
$(window).trigger('gMapsLoaded');
}
$(document).ready((function(){
function initialize(){
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),mapOptions);
}
function loadGoogleMaps(){
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
}
$(window).bind('gMapsLoaded', initialize);
loadGoogleMaps();
})());
Asynchronously Loading the API
You may wish to load the Maps API JavaScript code after your page has
finished loading, or on demand. To do so, you can inject your own
tag in response to a window.onload event or a function call,
but you need to additionally instruct the Maps JavaScript API
bootstrap to delay execution of your application code until the Maps
JavaScript API code is fully loaded. You may do so using the callback
parameter, which takes as an argument the function to execute upon
completing loading the API.
The following code instructs the application to load the Maps API
after the page has fully loaded (using window.onload) and write the
Maps JavaScript API into a tag within the page. Additionally,
we instruct the API to only execute the initialize() function after
the API has fully loaded by passing callback=initialize to the Maps
See HERE : https://developers.google.com/maps/documentation/javascript/tutorial
Make sure that you aren't instantiating the map before the Javascript has finished loading.
Also, If you want to use the AJAX API loader, you need to do it like this:
<script src="http://www.google.com/jsapi?key=ABCDEFG" type="text/javascript"></script>
<script type="text/javascript">
google.load("maps", "2.x");
// Call this function when the page has been loaded
function initialize() {
var map = new google.maps.Map2(document.getElementById("map"));
map.setCenter(new google.maps.LatLng(37.4419, -122.1419), 13);
}
google.setOnLoadCallback(initialize);
</script>
Otherwise, just use the regular Maps API script source:
<script src="http://maps.google.com/maps?file=api&v=2&key=abcdefg&sensor=true_or_false" type="text/javascript"></script>
I've done it like so... this example uses jQuery and google map v3.x
$.getScript("http://maps.google.com/maps/api/js?sensor=true®ion=nz&async=2&callback=MapApiLoaded", function () {});
function MapApiLoaded() {
//.... put your map setup code here: new google.maps.Map(...) etc
}
This works for me:
const myApiKey = `12345`;
const lat = -34.397;
const lng = 150.644;
const zoom = 8;
const parentElement = document.getElementById(`map`); // a <div>
const script = document.createElement(`script`);
script.src = `https://maps.googleapis.com/maps/api/js?key=${myApiKey}`;
script.async = true;
script.defer = true;
script.onload = function () {
new google.maps.Map(parentElement, {
center: {lat, lng},
zoom
});
};
parentElement.insertBefore(script, null);
Related
Trying out polymer and wanted to know how to add a marker element to the polymer element. I know how to add the marker to a standard google map. Should I just insert a marker object into the google-map elements marker array? If so whats the signature and is there an example? Do I need to call some sort of map init or refresh after I do so, or does it update automatically?
(function() {
Polymer({
is: 'users-map',
created: function(){
this.loadMap(this.data[0]);
},
loadMap: function(row) {
var map = document.querySelector('#users-location-map');
row.users.forEach(function (user) {
var location = user.location;
var markerOptions = {
position: {lat: location[1], lng: location[0]},
//map: map //can't set this otherwise it throws an error on finding the google library
};
if (!user.online) {
markerOptions.icon = 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|666666';
}
map.markers.push(something); //how should I instanstiate this something
// new google.maps.Marker(markerOptions); //normally I would just do this
});
},
The answer below works if I comment out the map assingment.
It depends if you are using the google-map and google-map-marker or the google map API directly.
If you use the google-map and google-map-marker elements this approach should work:
marker = document.createElement('google-map-marker');
marker.longitude = location[0];
marker.latitude = location[1];
marker.icon = 'ICON_UR'
Polymer.dom(this.$.map).appendChild(marker);
If you use the google map API directly your normal appraoch with new google.maps.Marker(markerOptions); should work fine.
I had same task early and have solution by this question. I hope my example will have in future for solution.
For example we have google-map polymer in our html:
<google-map map="{{map}}" latitude="40.730610" longitude="-73.935242" zoom="5" click-events="true" mouse-events="true" api-key="{{you_api_key}}" disable-default-ui>
</google-map>
And for dynamically create marker on google-map by click and add EventListener for drag event I write script like this:
<script> var map = document.querySelector('google-map');
map.addEventListener('google-map-click', function (e) {
let marker = document.createElement('google-map-marker');
let latLng = e.detail.latLng;
marker.setAttribute('latitude', latLng.lat());
marker.setAttribute('longitude', latLng.lng());
marker.setAttribute('title', "Marker name");
marker.setAttribute('draggable', true);
marker.setAttribute('click-events', true);
marker.setAttribute('mouse-events', true);
marker.addEventListener('google-map-marker-dragend', function (e) {
let latLng = e.detail.latLng;
marker.setAttribute('latitude', latLng.lat());
marker.setAttribute('longitude', latLng.lng());
});
Polymer.dom(map).appendChild(marker);
});
</script>
Hope it help in future. Thanks.
I have learned to use the API V3 making use of HTML + JavaScript, as I did here: http://jsfiddle.net/hCymP/4/
HTML:
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
JAVASCRIPT:
var mapContainer = document.createElement('div');
mapContainer.setAttribute('style',"width: 500px; height: 300px");
document.body.appendChild(mapContainer);
var mapOptions = {
center: new google.maps.LatLng(-35.000009, -58.197645),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(mapContainer,mapOptions);
but now I need to move it to a firefox addon (it's a "Firefox for Android" addon but I think this problem can be applied to desktop addon too and chrome addons).
The problem is you need to do everything via javascript in addons, so I can not include the following line:
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
SO I try to resolve that with loadSubScript, but it returned an empty div:
Components.utils.import("resource://gre/modules/Services.jsm");
Services.scriptloader.loadSubScript("https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false", window, "utf8");
var mapContainer = window.content.document.createElement('div');
mapContainer.setAttribute('id', "map");
mapContainer.setAttribute('style',"width: 250px; height: 250px");
var mapOptions = {
center: new window.google.maps.LatLng(latitude, longitude),
zoom: 5,
mapTypeId: window.google.maps.MapTypeId.ROADMAP
}
var map = new window.google.maps.Map(mapContainer,mapOptions);
return mapContainer;
So I tryed looking inside https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false to "copy" that code and call it from my addon. And I downloaded the Google Maps Api file and I included into my project to be able to retrieve the catch errors... But returned me an empty div too:
Components.utils.import("resource://gre/modules/Services.jsm");
// Same as HTML <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
window.google = window.google || {};
window.google.maps = window.google.maps || {};
var modules = window.google.maps.modules = {};
window.google.maps.__gjsload__ = function(name, text) { modules[name] = text;};
window.google.maps.Load = function(apiLoad) {
delete window.google.maps.Load;
apiLoad([0.009999999776482582,[[["https://mts0.googleapis.com/vt?lyrs=m#227000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.googleapis.com/vt?lyrs=m#227000000\u0026src=api\u0026hl=en-US\u0026"],null,null,null,null,"m#227000000"],[["https://khms0.googleapis.com/kh?v=134\u0026hl=en-US\u0026","https://khms1.googleapis.com/kh?v=134\u0026hl=en-US\u0026"],null,null,null,1,"134"],[["https://mts0.googleapis.com/vt?lyrs=h#227000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.googleapis.com/vt?lyrs=h#227000000\u0026src=api\u0026hl=en-US\u0026"],null,null,null,null,"h#227000000"],[["https://mts0.googleapis.com/vt?lyrs=t#131,r#227000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.googleapis.com/vt?lyrs=t#131,r#227000000\u0026src=api\u0026hl=en-US\u0026"],null,null,null,null,"t#131,r#227000000"],null,null,[["https://cbks0.googleapis.com/cbk?","https://cbks1.googleapis.com/cbk?"]],[["https://khms0.googleapis.com/kh?v=80\u0026hl=en-US\u0026","https://khms1.googleapis.com/kh?v=80\u0026hl=en-US\u0026"],null,null,null,null,"80"],[["https://mts0.googleapis.com/mapslt?hl=en-US\u0026","https://mts1.googleapis.com/mapslt?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt/ft?hl=en-US\u0026","https://mts1.googleapis.com/mapslt/ft?hl=en-US\u0026"]],[["https://mts0.googleapis.com/vt?hl=en-US\u0026","https://mts1.googleapis.com/vt?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt/loom?hl=en-US\u0026","https://mts1.googleapis.com/mapslt/loom?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt?hl=en-US\u0026","https://mts1.googleapis.com/mapslt?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt/ft?hl=en-US\u0026","https://mts1.googleapis.com/mapslt/ft?hl=en-US\u0026"]]],["en-US","US",null,0,null,null,"https://maps.gstatic.com/mapfiles/","https://csi.gstatic.com","https://maps.googleapis.com","https://maps.googleapis.com"],["https://maps.gstatic.com/intl/en_us/mapfiles/api-3/13/11","3.13.11"],[2256293068],1.0,null,null,null,null,0,"",null,null,1,"https://khms.googleapis.com/mz?v=134\u0026",null,"https://earthbuilder.googleapis.com","https://earthbuilder.googleapis.com",null,"https://mts.googleapis.com/vt/icon"], loadScriptTime);
};
var loadScriptTime = (new window.Date).getTime();
//I can't use document.write but use loadSubScript insthead
Services.scriptloader.loadSubScript("chrome://googleMaps/content/Google-Maps-V3.js", window, "utf8"); //chrome://MoWA/content/Google-Maps-V3.js", window, "utf8");
var mapContainer = window.content.document.createElement('div');
mapContainer.setAttribute('id', "map");
mapContainer.setAttribute('style',"width: 500px; height: 300px");
mapContainer.style.backgroundColor = "red";
var mapOptions = {
center: new window.google.maps.LatLng(latitude, longitude),
zoom: 5,
mapTypeId: window.google.maps.MapTypeId.ROADMAP
}
var map = new window.google.maps.Map(mapContainer,mapOptions);
return mapContainer;
Any idea?
Project source code: https://www.dropbox.com/sh/zhsyhebsygh74nw/RV4CxPiK8d
Using the Addon SDK, you can use a pagemod to modify the contents of a page (looks like you're injecting the maps on a page). There, you can specify contentScriptFiles, where one can be your local version of the google maps JS API, and the other your specific addon code that will run on the page. This will save you from having to deal with sandboxed/scope madness with loadSubScript.
let { url: getLocal } = require("sdk/self").data;
let { PageMod } = require("sdk/page-mod");
pageMod.PageMod({
include: "*.mozilla.org",
contentScriptFile: [
getLocal("googlemaps.js"),
getLocal("my-script.js")
]
});
I am trying to write a module`to load a Stamen tile map under Require.js, but I'm unsure how to best use it with Require.
If you haven't seen Stamen maps before, their site is at Stamen Maps.
This is the code for the map view, view.js
define([
'jquery',
'underscore',
'backbone',
'maps',
'text!templates/map/view.html'
], function($, _, Backbone, maps, mapTemplate){
var mapView = Backbone.View.extend({
el: $(".map"),
displayMap: function() {
this.options = {
center: new maps.LatLng(-37.8, 144.9),
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
};
this.render();
},
render: function(){
var compiledTemplate = _.template(mapTemplate);
var $el = $(this.el);
$el.html(compiledTemplate);
this.map = new maps.Map($el.find('.map').get(0), this.options);
}
});
return new mapView;
});
I am loading the maps API following modules:
map.js
define(['google!maps/3/sensor=false'], function() {
return google.maps;
});
Which has the dependency of google.js
define(['http://www.google.com/jsapi?key=THE_API_KEY&callback=define'], {
load: function( name, req, load, config ) {
if (config.isBuild) {
onLoad(null);
} else {
var request = name.split('/');
google.load(request[0], request[1], {
callback: load,
language: 'en',
other_params: ((typeof request[2] === 'string')?request[2]:'')
});
}
}
});
The issue is that the Stamen maps layers appear to edit the Google Maps instance directly. You can see the Stamen maps implementation here:
http://maps.stamen.com/js/tile.stamen.js?v1.1.1
google.maps.StamenMapType = function(name) {
//Implementation
}
It seems to rely on the global google.maps object, which is where I believe the issue is coming from.
I'm unsure how to best rewrite the Stamen plugin to be require.js friendly, or if I need to, and I am really keen on using it. Unless I take Google Maps and Stamen out of Require.js and load them normally (like I do with Modernizr) but I'd much prefer to try and do it the Require.js way. If there is such a thing.
Any advice or tips would be much appreciated.
I'm responsible for tile.stamen.js. Sorry for the headache.
The problem here is that our script needs access to the Google Maps namespace (google.maps) so that it can create the StamenMapType class and have it inherit methods from Google's ImageMapType. If you absolutely need to use RequireJS (which I wouldn't suggest, exactly because it makes simple stuff like this awkward), you'll need to rewrite the whole Google-specific portion of tile.stamen.js (lines 155-177) to look something like this:
exports.makeStamenMapType = function(name, gmaps) {
if (!gmaps) gmaps = google.maps;
var provider = getProvider(name);
return new gmaps.ImageMapType({
"getTileUrl": function(coord, zoom) {
var index = (zoom + coord.x + coord.y) % SUBDOMAINS.length;
return [
provider.url
.replace("{S}", SUBDOMAINS[index])
.replace("{Z}", zoom)
.replace("{X}", coord.x)
.replace("{Y}", coord.y)
];
},
"tileSize": new gmaps.Size(256, 256),
"name": name,
"minZoom": provider.minZoom,
"maxZoom": provider.maxZoom
});
};
Then you'd use:
var toner = makeStamenMapType("toner", gmaps);
where gmaps is your required Google Maps API object.
I'm new to the Google Maps API and I'm working on localhost.
I want to add the ability for a user to upload their .gpx file and visualize it on the Google Map.
I've found this AJAX function wich works fine when I hardcode the .gpx file, but when I try to import the file from my computer, I got a grey screen for short second which then disappears.
Any idea or solution for this problem is more than welcome.
Thanks in advance.
function get_file() {
var fileInput = document.getElementById("file_upload");
var filename = fileInput.value;
var myOptions = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
loadGPXFileIntoGoogleMap(map, filename);
}
function loadGPXFileIntoGoogleMap(map, filename) {
$.ajax({url: filename,
dataType: "xml",
success: function(data) {
var parser = new GPXParser(data, map);
parser.setTrackColour("#ff0000"); // Set the track line colour
parser.setTrackWidth(5); // Set the track line width
parser.setMinTrackPointDelta(0.001); // Set the minimum distance between track points
parser.centerAndZoom(data);
parser.addTrackpointsToMap(); // Add the trackpoints
parser.addWaypointsToMap(); // Add the waypoints
}
});
}
There is no way to access filesystem from JavaScript.
This is a security issue. To resolve your issue I can see only one option: You should have server-side functionality that will temporary store user uploaded data. And then you can load user defined .gpx files from server.
Is there any way to create a "sidebar" from a KML file when using the Google Maps API?
I'm loading the markers on the map using something like this:
var myMarkerLayer = new google.maps.KmlLayer('http://example.com/WestCoast.kml');
This works great so far, but how can I grab that data and loop through the points?
I would like to avoid using a third party library, if possible- although jQuery is OK.
KML is just an XML document so you can just process it using jQuery to extract the data you need. You can store the coordinates and placenames in a local array and use this data for any purpose you want eg. you can use it to navigate to a point on the map when a person clicks on a place name on a sidebar.
Below is an example on how to process the KML file and implement the navigation based on the data in the file..One word of caution I would not do this with large KML files as it doubles the load time (browser has to load the file to process the features)...
<script type="text/javascript" src= "http://maps.google.com/maps/api/js?sensor=false">
</script>
<script src="../js/jquery-1.4.2.min.js">
</script>
<script>
var map;
var nav = [];
$(document).ready(function(){
//initialise a map
init();
$.get("kml.xml", function(data){
html = "";
//loop through placemarks tags
$(data).find("Placemark").each(function(index, value){
//get coordinates and place name
coords = $(this).find("coordinates").text();
place = $(this).find("name").text();
//store as JSON
c = coords.split(",")
nav.push({
"place": place,
"lat": c[0],
"lng": c[1]
})
//output as a navigation
html += "<li>" + place + "</li>";
})
//output as a navigation
$(".navigation").append(html);
//bind clicks on your navigation to scroll to a placemark
$(".navigation li").bind("click", function(){
panToPoint = new google.maps.LatLng(nav[$(this).index()].lng, nav[$(this).index()].lat)
map.panTo(panToPoint);
})
});
function init(){
var latlng = new google.maps.LatLng(-43.552965, 172.47315);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
}
})
</script>
<html>
<body>
<div id="map" style="width:600px;height: 600px;">
</div>
<ul class="navigation">
</ul>
</body>
</html>
This isn't possible. Check the docs:
http://code.google.com/apis/maps/documentation/javascript/overlays.html#KMLLayers
Under "KML Feature Data":
Because KML may include a large number of features, you may not access feature data from the KmlLayer object directly. Instead, as features are displayed, they are rendered to look like clickable Maps API overlays.