detecting visible google map markers after setZoom - google-maps

I'm using google map fitBounds, then I use map.setZoom to zoom-in one level (after google finds the best zoom level to fit my markers), then I want to check weather my markers are visible in viewport or not, how can I do so? it seems that map.getBounds().contains doesn't work, please take a look at this fiddle: fiddle
I want to check my marker is visible or not:
google.maps.event.addListenerOnce(map, "zoom_changed", function() {
map.setZoom(map.getZoom()+2);
if( map.getBounds().contains("35.700592","51.394773"))
alert('ok');
but there seems to be an error
//alert("the zoom level is now "+map.getZoom());
});

Why do you think "35.700592","51.394773" is a google.maps.LatLng? It is two strings separated by a comma.
This won't work:
google.maps.event.addListenerOnce(map, "zoom_changed", function() {
map.setZoom(map.getZoom()+2);
if( map.getBounds().contains("35.700592","51.394773"))
alert('ok');
});
This is the correct way to use "contains" (with a LatLng object):
google.maps.event.addListenerOnce(map, "zoom_changed", function() {
map.setZoom(map.getZoom()+2);
if( map.getBounds().contains(new google.maps.LatLng(35.700592,51.394773)))
alert('ok');
});
And you probably want to make an array containing your markers and use .getPosition() on the markers
http://jsfiddle.net/Npu36/10/embedded/result/

Related

Getting content of infowindow upon closing it (Google Maps)

I'm trying to get the content of a marker's infowindow upon closing it in Google Maps. The following code works after creating the infowindow:
console.log(infowindow.getContent());
However, on the close function, I think the infowindow is closed before I can view the content.
//Close Infowindow
google.maps.event.addListener(infowindow,'closeclick',function(){
console.log(infowindow.getContent());
});
How can I grab the content before the infowindow is completely gone?
I would try
google.maps.event.addListener(infowindow, 'closeclick', function () {
console.log(this.getContent());
});
or even
infowindow.addListener('closeclick', function () {
console.log(this.getContent());
});
An infowindow's content doesn't change on closeclick alone, so you should be able to pull it out with #getContent even if it's been closed.

Imitating Mouse click - point with known coordinates on a fusion table layer - google maps

I have been making a script using a fusion table's layer in google maps.
I am using geocoder and get the coordinates of a point that I need.
I put a script that changes the style of a polygon from the fusion table when you click on it, using the google.maps.event.addListener(layer, "click", function(e) {});
I would like to use the same function that I call in the case of a click on the layer, but this time with a click with the coordinates that I got.
I have tried google.maps.event.trigger(map, 'click', {latLng: new google.maps.LatLng(42.701487,26.772308)});
As well as the example here > Google Fusion Table Double Click (dblClick)
I have tried changing map with layer...
I am sorry if my question is quite stupid, but I have tried many options.
P.S. I have seen many post about getting the info from the table, but I do not need that. I want to change the style of the KML element in the selected row, so I do not see it happening by a query.
Here is the model of my script:
function initialize()
{
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
layer = new google.maps.FusionTablesLayer({
suppressInfoWindows:true,
map : map,
query : {
select: 'Местоположение',
from: '12ZoroPjIfBR4J-XwM6Rex7LmfhzCDJc9_vyG5SM'
}
});
google.maps.event.addListener(layer, "click", function(e) {
SmeniStilRaionni(layer,e);
marker.setMap(null);
});
}
function SmeniStilRaionni(layer,e)
{
...
}
function showAddress(address)
{
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var point = results[0].geometry.location;
//IMITATE THE CLICK
}
});
}
In response to geocodezip
This way you hide all the other elements... I do not wish that. It is like if I want to change the border of the selected element. And I do not wish for a new layer.
In the function that I use now I push the style of the options of the layer and then set the option. I use the e from google.maps.event.addListener(layer, "click", function(e)); by inserting e.row['Name'].value inside the where rule.
I would like to ask you if there is any info on the e variable in google.maps.event.addListener(layer, "click", function(e));
I found out how to get the results I wanted:
For my query after I get the point I use this:
var queryText ="SELECT 'Районен съд','Окръжен съд','Апелативен съд','Местоположение' FROM "+FusionTableID+" WHERE ST_INTERSECTS(\'Местоположение\', CIRCLE(LATLNG(" + point.toUrlValue(6) + "),0.5));";
queryText = encodeURIComponent(queryText);
document.getElementById("vij query").innerHTML = queryText;
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
And then I get these results:
var rsyd = response.getDataTable().getValue(0,0);
var osyd = response.getDataTable().getValue(0,1);
var apsyd = response.getDataTable().getValue(0,2);
And then, I use the following:
where: "'Районен съд' = '"+rsyd+"'",
Which is the same as:
where: "'Районен съд' = '"+e.row['Районен съд'].value+"'",
in the click function.
This is a working solution for my problem.
But still, I cannot find a way to Imitate a Mouse click.
The issue is this: the data(row) for the layers will be requested via AJAX when you click on a layer.
In theory it's possible to select a geometry(polygon) by a given LatLng, the geometry-library has a method for this: google.maps.geometry.poly.containsLocation().
Unfortunately the FusionTableAPI does not support such queries(ST_CONTAINS), you cannot select a row by supplying a LatLng and selecting the rows where the geometry contains the LatLng.
So what you can do: create a copy of the table that contains the columns needed to select a row(Община...the distinct value, and Местоположение.... the geometry). This copy may be requested via AJAX, but when the FusionTable will not be modified anymore I would suggest to use a hardcoded copy.
What to do now when you want to simulate the click:
Iterate over all rows of the copy, use the mentioned containsLocation()-method to check if the geometry(Местоположение) contains the LatLng and when it does apply the query by using the value of the distinct column Община .
Of course it would take some time to check all the geometries, but the FusionTable is not very large, it should be a possible approach in your case.
Here is a demo: http://jsfiddle.net/doktormolle/sSwj3/
The size of the stored data is approximately 500kb, you should store the data in an external script, so they may be cached.
You may notice that the highligthning of the selected layer will be much faster when triggered via the links, because there will no data be requested via AJAX. When the highlightning of the selected feature is the only thing you need you may ommit the observation of the layer-click completely and observe the map-click instead. Use the returned LatLng to retrieve the selected row from the data and set the style:
Demo: http://jsfiddle.net/doktormolle/swdX8/

How to identify a google map marker on click?

I'm creating a Google Map from the developer API v3. It's populated with markers created dynamically from ColdFusion querying an MsSQL database.
<cfloop query="One">
<script>locations[<cfoutput>#One.userID#</cfoutput>
] = new google.maps.LatLng(<cfoutput>#One.latLng#</cfoutput>);
</script>
</cfloop>
I need a way to recognise the marker when its clicked so I can display address details in a box below the map and also higlight markers when a button is clicked lower on the page.
In general, you would typically assign your own custom properties to the Marker. Something like:
function markerClicked(e) {
console.log('Marker ' + marker.myData + ' has been clicked');
}
var marker = new google.maps.Marker(...);
marker.myData = 1; //this could be arbitrary data or even another object
google.maps.event.addListener(marker, 'click', markerClicked);
Adding custom data to any Google Maps API object has risks though. Google's code is obfuscated and the internal (non-documented) properties can and do change. Make sure your property is named in such a way that it won't conflict with any existing property or future property. Tip: Choose a property name longer than 3 letters.
If you are going to minify/compile/compress your maps code, then there are additional considerations.
What about :
google.maps.event.addListener(marker, "click", function (e) {
var clicked = this;
//...
});
This is pretty thoroughly documented/explained in the documentation.
https://developers.google.com/maps/documentation/javascript/overlays#InfoWindows
When you create markers, add dom listeners to the markers like this
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});

positioning google map stays in top left corner [duplicate]

This question already has answers here:
Google map only loading half of itself
(4 answers)
Closed 2 years ago.
I just added a googlemap to a website. I is placed as presented in the toturials in a map_canvas div, and this div is nested inside another div like:
now the problem is that the map tiles stayes in the topleft corner but not the map background like this http://screencast.com/t/jeUSKijjwE
what could be wrong?
This is usually a problem with showing, hiding, or resizing a map.
In google maps v3, I believe you can call google.maps.event.trigger(map, 'resize'); where map is the reference to your google maps object.
I suggest load map with some time delay after checking the div is visible or not which is going to hold the map . Worked for me
$(document).ready(function () {
$('.togglebtn').click(function () {
if(!$('#map_canvas').is(':visible')){
setTimeout(function(){initialize()}, 500);
}
});
});
//your function
function initialize() {
var mapOptions = {
zoom: 3,
center : new google.map.LatLng(31.510474,80.352287),
center: new google.maps.LatLng(44.510474, 50.352287),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var contentSC_PAK = "SoftCircles Pakistan";
.....
.....
and rest of your map code to initialize map
});
}
I had this problem and discovered that in my case the issue was that I was creating the map_canvas div with javascript innerHTML.
The map would display correctly the first time, but the second time I'd call it (different map though) it would display the same map (wrong map), and the third time I'd call another map it would display it only in the top left corner. It would be in the top corner for all the rest of the calls.
All I had to do was put the div in the original HTML, and it works perfectly from there on out.
Hope this helps someone!
You have to use autosizse option. I had same issue, and i solved it.
Here the code when you open a modal and inside it, call a locationpicker.
$scope.map_picker = function(){
$("#map_modal").modal('show');
$('.us2').locationpicker({
location: {latitude: 33.997215339647724, longitude: -81.02654766235355},
radius: 300,
inputBinding: {
latitudeInput: $('.us2-lat'),
longitudeInput: $('.us2-lon'),
radiusInput: $('#us2-radius'),
locationNameInput: $('#us2-address')
}
});
**$('#map_modal').on('shown.bs.modal', function () {
$('.us2').locationpicker('autosize');
});**
}
The main logic is just have to use this line:
$('.us2').locationpicker('autosize');
But it is important how and where you are calling this line.

Keep a Google Maps v3 Map hidden, show when needed

Is there a way of preventing a Google Maps (JS, v3) map being displayed from the get-go? I'm doing some pre-processing and would like to show my 'Loading' spinner until everything is good to go (more eloquently put, hide the map -- e.g. the container div – until all pre-processing is complete – at which point, show the map).
Hooking up the map's idle event doesn't help that much, since the map is already displayed when this event hits.
I know that the container div gets inline-styled by GMaps after loading, my first idea was to clear out the style attribute (whilst listening to the idle event), but it would be interesting to see if there is a way of creating the map and not displaying it until all pre-processing is done.
Maybe by using an argument to the new google.maps.Map constructor, or a MapOption ?
Any thoughts on this?
Thank you in advance!
Also remember to call:
google.maps.event.trigger(map, 'resize');
if you have changed the size of the <div>. A display:none <div> has no size.
Or you could just hide it like with css visablility or css opacity.
$("#GoogleMap").css({ opacity: 0, zoom: 0 });
initialize();
google.maps.event.addListener(map,"idle", function(){
$('#Loader').hide();
$("#GoogleMap").css({ opacity: 1, zoom: 1 });
});
This works for me. I'm using the JQuery library.
$(document).ready(function(){
$('#Checkbox').click(function(){
$('#googleMapDiv').toggle();
initialize(); // initialize the map
});
});
another way to show the hidden map when map is first time rendering the <div> is to set style: visibility.
When firstly hidden, use visibility = hidden; to show use visibility = visible
the reason is: visibility:hidden means that the contents of the element will be invisible, but the element stays in its original position and size.
this works fine for me, I use jquery tabs
setTimeout(function() {
google.maps.event.trigger(map, "resize");
map.setCenter(new google.maps.LatLng(default_lat, default_lng));
map.setZoom(default_map_zoom);
}, 2000);
om this link https://code.google.com/p/gmaps-api-issues/issues/detail?id=1448
This will work
google.maps.event.addListener(map, "idle", function ()
{
google.maps.event.trigger(map, 'resize');
});
better way:
gmap.redraw = function() {
gmOnLoad = true;
if(gmOnLoad) {
google.maps.event.trigger(gmap, "resize");
gmap.setCenter(gmlatlng);
gmOnLoad = false;
}
}
and in show click event:
$("#goo").click(function() {
if ($("#map_canvas").css("display") == "none") {
$("#YMapsID").toggle();
$("#map_canvas").toggle();
if (gmap != undefined) {
gmap.redraw();
}
}
});
depending on what you are doing another posibility could be to have multiple bools you set to true when each process is done.
For example:
if you have a geocode service running which you want to wait for, you could have a var called
GeoState
and in the result part of the geocoder set GeoState to true,
then have a timed function check if all the services have returned true, when they have, make the map visible.