Removing Dynamically Created kmlLayer - google-maps

I have an application that contains an embedded browser window.
I want to have my application create a kmlLayer. I can do this on the fly with the following:
function addKmlLayer(kmlURL) {
var kmlLayer = new google.maps.KmlLayer({ url: kmlURL });
kmlLayer.setMap(my_map);
}
I'm going to allow my users to add several kmlLayers.
I also know that I can remove the layer by using kmlLayer.setMap(null).
How do I find my previous kmlLayer to set it to null? Is there a way to identify the kmlLayer (ID, Name, etc...)?

One option is to keep a global reference to the KmlLayer
var kmlLayer = null;
function addKmlLayer(kmlURL) {
kmlLayer = new google.maps.KmlLayer({ url: kmlURL });
kmlLayer.setMap(my_map);
}
Then to hide it, this will work:
kmlLayer.setMap(null);
Might want to do:
if ((kmlLayer != null) && kmlLayer.setMap) kmlLayer.setMap(null);

Related

GoogleMapsEvent vs google.maps.event

I am in the process of upgrading from Ionic 2 beta to RC3. In doing so, I also update the version of Google Maps to "google-maps": "^3.2.1". The Change in Google Maps, is that now it uses a GoogleMap object instead of google.maps.Map (see here).
I have been using google.maps.event., but now need to update it to use GoogleMapsEvent (I think). Because I get the following error on ionic serve:
Cannot find name 'google'.
google.maps.event.addListenerOnce(that.map, 'bounds_changed', function (event) {
let position: CameraPosition = that.map.getCameraPosition();
let zoom: number = position.zoom;
setTimeout(function () {
// let center: GoogleMapsLatLng = that.map.getCenter();
google.maps.event.trigger(that.map, 'resize');
// that.map.setCenter(center);
that.map.setZoom(zoom);
}, 100);
});
But GoogleMapsEvent does not have a addListenerOnce or trigger method.
Question
How do I update the code above to use GoogleMapsEvent instead of google.maps.event?
Thanks
From the documentation, this is how you can add eventlisteners.
// create a new map by passing HTMLElement
let element: HTMLElement = document.getElementById('map');
let map = new GoogleMap(element);
// listen to MAP_READY event
map.one(GoogleMapsEvent.MAP_READY).then(() => console.log('Map is ready!'));

Meteor and Google Place Autocomplete - InvalidValueError: not an instance of HTMLInputElement

I'm looking to use Google Place Autocomplete on one of my Meteor App Input.
When I initialize a session, I have an InvalidValueError: not an instance of HTMLInputElement, but when I refresh the page one time, the autocomplete works well.
What do I need to change on my code in order to have autocomplete working on first session?
My code:
if (Meteor.isClient) {
window.onload = function() {
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),{types:['geocode']}
);
google.maps.event.addListener(autocomplete,'place_changed',function(){
var place = autocomplete.getPlace();
});
};
}
Thanks for your help.
Call below code on-focus of input element.
var autocomplete = new google.maps.places.Autocomplete(
(document.getElementById('autocomplete')),{types:['geocode']}
);
You should try using Template instance:
Template.autocomplete.onRendered(function() {
// Your autocomplete function
// var autocomplete = ...
});
My template name is "autocomplete" in this example.

clearing a kml from google maps

I have a google map and I am wanting to show this KML file, I can load the KML but I haven't yet figured out how to clear it off the map. I load the KML on the map when the user click a check box, but whe they uncheck the box the KML wont go away. Here is the code that I am using to load the KML.
var isShowData = false;
//showEMSz(null);
var tileEMSz;
function showEMSz(obj) {
isShowData = !isShowData;
if (isShowData) {
tileEMSz = new google.maps.KmlLayer({
url: '/ELTSCAD.kml'
});
tileEMSz.setMap(map);
}
else
{
// remove Option
tileEMSz = null;
}
}
set the map-property of the layer to null:
if(tileEMSz){tileEMSz.setMap(null);}

google map v3 how fitbounds with zoom on user's location

I am using google v3, i want to fitbounds with center on userPinLoc object, i have the following code
var bounds = new google.maps.LatLngBounds();
bounds.extend(userPinLoc)// wants to center on userPinLocation
for (i in nearestEntitiesToZoom) {
entity = nearestEntitiesToZoom[i];
var googleLatLng = new google.maps.LatLng(entity.latitude,entity.longitude);
bounds.extend(googleLatLng);
}
bounds.extend(userPinLoc);
//googleMap.setCenter(userPinLoc) this not working
googleMap.fitBounds(bounds);
any quick fix after update i am pasting new code
function setInitialZoom() {
mapZoom = googleMap.getZoom();
var bounds = new google.maps.LatLngBounds();
bounds.extend(userPinLoc);
for (i in nearestEntitiesToZoom) {
entity = nearestEntitiesToZoom[i];
var googleLatLng = new google.maps.LatLng(entity.latitude,entity.longitude);
bounds.extend(googleLatLng);
}
google.maps.event.addDomListener(googleMap, 'bounds_changed', function() {
googleMap.setCenter(userPinLoc);
});
googleMap.fitBounds(bounds);
setTimeout(function() {
google.maps.event.clearListeners(googleMap, 'bounds_changed');
}, 3000);
}
Remove the setCenter from where it is currently. You need to have an event listener for when the map's bounds change. I think when you call fitBounds, you have to wait for it to redraw before you can adjust the centre. One way would be to use a timeout, but you can simply add this to your initialize function:
google.maps.event.addDomListener(googleMap, 'bounds_changed', updateCenter);
And then create a new function to update the centre, which takes the userPinLoc value (needs to be a global variable):
function updateCenter() {
googleMap.setCenter(userPinLoc);
}

limiting google maps autocomplete to UK address only

I've been looking at the example on:
http://code.google.com/apis/maps/documentation/javascript/examples/places-autocomplete.html
and have decided to incorporate it into my site.
Is it possible to limit the addresses to UK addresses only?
Try this:
var input = document.getElementById('searchTextField');
var options = {
types: ['(cities)'],
componentRestrictions: {country: 'tr'}//Turkey only
};
var autocomplete = new google.maps.places.Autocomplete(input,options);
You can't strictly/hard limit the locations that it finds, although there is a feature request in the system to do so, but you can set a 'bias' on the results. It's passed in as an argument to the autocomplete method as a google maps bounds object. Autocomplete will then favor locations within those boundaries. Note, however, that since this isn't a hard boundary, if there are matches for the search outside the boundaries it will return those.
From my usage it seems a bit buggy and can use some improvement - especially considering that anything outside your boundary is not tagged by proximity at all, so something one block outside the boundary is just as likely to show as something 1000 miles outside, so make sure you play around with getting the boundaries working right.
You can intercept the JSONP results that are returned by the google.maps.places.Autocomplete functionality and use them as you see fit, such as to limit by country and display the results.
Basically you redefine the appendChild method on the head element, and then monitor the javascript elements that the Google autocomplete code inserts into the DOM for JSONP. As javascript elements are added, you override the JSONP callbacks that Google defines in order to get access to the raw autocomplete data.
It's a bit of a hack, here goes (I'm using jQuery but it's not necessary for this hack to work):
//The head element, where the Google Autocomplete code will insert a tag
//for a javascript file.
var head = $('head')[0];
//The name of the method the Autocomplete code uses to insert the tag.
var method = 'appendChild';
//The method we will be overriding.
var originalMethod = head[method];
head[method] = function () {
if (arguments[0] && arguments[0].src && arguments[0].src.match(/GetPredictions/)) { //Check that the element is a javascript tag being inserted by Google.
var callbackMatchObject = (/callback=([^&]+)&|$/).exec(arguments[0].src); //Regex to extract the name of the callback method that the JSONP will call.
var searchTermMatchObject = (/\?1s([^&]+)&/).exec(arguments[0].src); //Regex to extract the search term that was entered by the user.
var searchTerm = unescape(searchTermMatchObject[1]);
if (callbackMatchObject && searchTermMatchObject) {
var names = callbackMatchObject[1].split('.'); //The JSONP callback method is in the form "abc.def" and each time has a different random name.
var originalCallback = names[0] && names[1] && window[names[0]] && window[names[0]][names[1]]; //Store the original callback method.
if (originalCallback) {
var newCallback = function () { //Define your own JSONP callback
if (arguments[0] && arguments[0][3]) {
var data = arguments[0][4]; //Your autocomplete results
//SUCCESS! - Limit results here and do something with them, such as displaying them in an autocomplete dropdown.
}
}
//Add copy all the attributes of the old callback function to the new callback function. This prevents the autocomplete functionality from throwing an error.
for (name in originalCallback) {
newCallback[name] = originalCallback[name];
}
window[names[0]][names[1]] = newCallback; //Override the JSONP callback
}
}
//Insert the element into the dom, regardless of whether it was being inserted by Google.
return originalMethod.apply(this, arguments);
};
James Alday is correct:
http://code.google.com/apis/maps/documentation/javascript/places.html#places_autocomplete
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(49.00, -13.00),
new google.maps.LatLng(60.00, 3.00));
var acOptions = {
bounds: defaultBounds,
types: ['geocode']
};
it is somewhat annoying as searching for Durham gives Durham, North Carolina as the second result, regardless of how you try to persuade it to region bias - you can set it to viewport map bounds and it'll still try to suggest NC state... The jQuery solution can be found here, but doesn't seem to give as many results as the v3 API.
http://code.google.com/p/geo-autocomplete/
The best way you would go about doing this, is to query the places api yourself and appending the queried string with your country. Or, of course, use the geo-autocomplete jQuery plugin.
Just change the google domain for the maps to your country domain and it will automatically search within your country only:
So:
http://maps.google.com/maps/api/geocode/xml?address={0}&sensor=false&language=en
To:
http://maps.google.nl/maps/api/geocode/xml?address={0}&sensor=false&language=nl
Try something like this.
// Change Bangalore, India to your cities boundary.
var bangaloreBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(12.864162, 77.438610),
new google.maps.LatLng(13.139807, 77.711895));
var autocomplete = new google.maps.places.Autocomplete(this, {
bounds: bangaloreBounds,
strictBounds: true,
});
autocomplete.addListener('place_changed', function () {
});
I find that if you set the map to roughly where you want then set bounds to it, the search finds places in that area first. You do not to physically show the map.
It works better than giving random overseas addresses first, setting to country does not work.
The code for autocomplete to get latln is:
<div id="map_canvas"></div>
<input type="text" name="location" id="location" placeholder="Type location...">
<input type="text" name="loc_latitude" id="latitude">
<input type="text" name="loc_longitude" id="longitude">
and the JS is:
$(document).ready(function () {
var mapOptions = {
center: new google.maps.LatLng(52.41041560, -1.5752999),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'),
mapOptions);
var autocomplete;
autocomplete = new google.maps.places.Autocomplete((document.getElementById(searchInput)), {
types: ['geocode'],
});
autocomplete.bindTo('bounds', map);
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var near_place = autocomplete.getPlace();
document.getElementById('latitude').value = near_place.geometry.location.lat();
document.getElementById('longitude').value = near_place.geometry.location.lng();
});
});
$(document).on('change', '#'+searchInput, function () {
document.getElementById('latitude').value = '';
document.getElementById('longitude').value = '';
});
Not exactly what you asked for but it works for me.