I want to dynamically change the color/text of any google maps marker.
Run the code: http://jsbin.com/odimop/edit#javascript,html,live
As you can see the problem of using a variable (var styloo) is when properties change then all markers using that variable behave in the same way, in this case marker4 and marker5. This approach is cumbersome and tedious when the map has too many markers because each marker will need one styled variable
I'm looking for a solution that use something like: this.styleIcon.color = "00ff00";. But so far is not working.
Any idea? please!
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/styledmarker/src/StyledMarker.js"></script>
<script type="text/javascript">
var styleIcon;
function initialize() {
var myLatLng = new google.maps.LatLng(37.313477473067, -121.880502070713);
var myOptions = {
zoom: 10,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var marker2 = new StyledMarker({styleIcon:new StyledIcon(StyledIconTypes.BUBBLE,{color:"00ffff",text:"Hover Me, this doesn't work"}),position:new google.maps.LatLng(37.5, -121.880502070713),map:map});
var marker3 = new StyledMarker({styleIcon:new StyledIcon(StyledIconTypes.BUBBLE,{color:"ff0000",text:"Just a Marker"}),position:new google.maps.LatLng(37.4, -121.880502070713),map:map});
google.maps.event.addDomListener(marker2,"mouseover", function(o){
this.setAnimation(google.maps.Animation.BOUNCE);
this.styleIcon.color = "00ff00";
this.styleIcon.text = "it does not change :(";
});
styloo = new StyledIcon(StyledIconTypes.BUBBLE,{color:"#95AA7B",text:"click me!",fore:"#ffffff"});
var marker4 = new StyledMarker({styleIcon: styloo,position:new google.maps.LatLng(37.2, -121.88),map:map});
var marker5 = new StyledMarker({styleIcon: styloo,position:new google.maps.LatLng(37.1, -121.88),map:map});
google.maps.event.addDomListener(marker4,"click", function(o){
this.setAnimation(google.maps.Animation.BOUNCE);
styloo.set("fore","#ffffff");//test color
styloo.set("color","#C2554D");// background color
styloo.set("text","color changed");
});
}
</script>
</head>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map_canvas" style="width: 600px; height: 600px;"></div>
</body>
As per StyledMarker examples, you need to use the set(property, value) methods, like this:
styleIcon.set("text","Elevation: " + results[0].elevation + "m");
In your case, change the mouseover handler to this:
this.styleIcon.set('color', '00ff00');
this.styleIcon.set('text', 'it does not change :(');
As for the other problem, where both change at once, you'll need to create a StyledIcon for each StyledMarker. I'd just add a function that returns a new icon each time.
function createStyle() { return new StyledIcon(StyledIconTypes.BUBBLE,{color:"#95AA7B",text:"click me!",fore:"#ffffff"}); }
var marker4 = new StyledMarker({styleIcon: createStyle(),position:new google.maps.LatLng(37.2, -121.88),map:map});
var marker5 = new StyledMarker({styleIcon: createStyle(),position:new google.maps.LatLng(37.1, -121.88),map:map});
google.maps.event.addDomListener(marker4,"click", function(o){
this.setAnimation(google.maps.Animation.BOUNCE);
this.styleIcon.set("fore","#ffffff");//test color
this.styleIcon.set("color","#C2554D");// background color
this.styleIcon.set("text","color changed");
});
Related
My goal is to display a group of clustered data points and one data point of different nature that never goes to a cluster in the same layer, so they all can received hover mouse events.
Is it possible to tell H.clustering.Provider to always exclude some points from clusters, or create a custom H.map.provider.ObjectProvider that can do it?
P. S.
I tried creating two layers and setting pointer-events: none for them in CSS to catch hover events by all points, it worked but made the map too slow to use.
Update
Here is a demo code, the goal is to get a hover rectangle for both markers with a condition that the first market should never be included to a cluster
<html>
<head>
<script src="http://js.api.here.com/v3/3.0/mapsjs-core.js" type="text/javascript" charset="utf-8"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-service.js" type="text/javascript" charset="utf-8"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-clustering.js" type="text/javascript" charset="utf-8"></script>
<style>
svg:hover {
border: 2px solid red;
}
</style>
</head>
<body>
<div id="mapContainer"/>
<script>
var platform = new H.service.Platform({
'app_id': 'my id',
'app_code': 'my code'
});
var defaultLayers = platform.createDefaultLayers();
var map = new H.Map(
document.getElementById('mapContainer'),
defaultLayers.normal.map,
{
zoom: 10,
center: { lat: 51.5, lng: 13.4 }
});
//this marker should not go to clusters
var marker = new H.map.DomMarker({ lat: 51.5, lng: 13.4 });
map.addObject(marker);
//this marker should go to clusters if there is more data points
var dataPoints = [];
dataPoints.push(new H.clustering.DataPoint(51.5, 13.45));
var theme =
{
getClusterPresentation: function(cluster){
return new H.map.DomMarker(cluster.getPosition(), {});
},
getNoisePresentation: function(point){
return new H.map.DomMarker(point.getPosition(), {});
}
}
var clusteredDataProvider = new H.clustering.Provider(dataPoints, {
theme: theme,
});
var layer = new H.map.layer.ObjectLayer(clusteredDataProvider);
map.addLayer(layer);
</script>
</body>
</html>
The following example shows a cluster provider initialized with the parameters eps and minWeight. eps holds the value of the radius within which data points are considered for clustering, while minWeight holds the cumulative weight that points lying close to another must reach or exceed to be clustered. The value of minWeight is 3 in the example, which means that three points, each with the weight of one or two data points with the weight of 2 and 1, respectively, form a cluster. This will reduce the time of rendering the page. Also please refer the new documentation :
https://developer.here.com/documentation/examples/maps-js/clustering/marker-clustering
var clusteredDataProvider = new H.clustering.Provider(dataPoints, {
min: 4,
max: 10,
clusteringOptions: {
eps: 32,
minWeight: 3
}
});
I have created a map in Meteor using Leaflet JS. The problem is, I could only get map.panTo to work inside the Template.dynamicmap.rendered area. However, this makes it so anywhere you click on the map pans to the location.
This is the complete rendered area with id and access token removed.
Template.dynamicmap.rendered = function() {
var southWest = L.latLng(35.02035919622158, -121.21049926757814);
var northEast = L.latLng(42.4426214924114, -110.79740478515624);
var mybounds = L.latLngBounds(southWest, northEast);
var map = L.map('map_container',{zoomControl: false, maxBounds: [[37.00035919622158, -119.23049926757814],[40.4626214924114, -112.77740478515624]],}).setView([38.685509760012, -115.86181640625001], 10);
var w = window.innerWidth;
var h = window.innerHeight;
$('#map_container').css({width: w+'px', height: h+'px'});
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
bounds: mybounds,
maxZoom: 10,
minZoom: 9,
}).addTo(map);
L.Icon.Default.imagePath = 'packages/leaflet/images';
var marker = L.marker([38.685509760012, -115.86181640625001]).addTo(map);
map.fitBounds(bounds);
};
So I tried putting it in an Template event shown below, this button is not within the map area but still in the dynamicmap template. It does not work though.
Template.dynamicmap.events({
'click input.goto3':(function() {
map.panTo(L.latLng(38.685509760012, -115.86181640625001));
})
});
I receive the error:
"Uncaught ReferenceError: map is not defined"
in the console. Which I have been trying to wrap my head around but no luck. I was hoping someone here could point me in the right direction.
Here is my HTML Template.
<template name="dynamicmap">
<div class="containerbox">
<div class="map_container" id="map_container">
</div>
</div>
<input type="button" class="goto3" value="Go"/>
</template>
You need to make map a global variable:
var map = null;
Template.dynamicmap.rendered = function() {
var southWest = L.latLng(35.02035919622158, -121.21049926757814);
var northEast = L.latLng(42.4426214924114, -110.79740478515624);
var mybounds = L.latLngBounds(southWest, northEast);
map = L.map('map_container',{zoomControl: false, ...
...
Good afternoon,
I have an issue with a google map and css "transform:scale".
My aim is to scale the map to 1.1 if the map is hovered. But if i do this i cant click the markern anymore. I have tried to solve it with jquery but i got no success.
Anybody here who has a solution?
Here is a fiddle: JSFIDDLE
I tought that first switch the scaled size, then load the map, and then switch to old size will get it to work, but no success.
Here is my abortive try..
$("#map").hover(function(){
$("#map").width(880).height(617.1).load('/index.html', function () {
initialize();
}).width(800).height(561);
});
Thanks for helping
Manuel Strohmaier
The problem is quite easy to explain, but unfortunately I haven't good solution now.
Take a look: http://take.ms/2E3fV
On image I mark rectangle which shows where exactly is now an element wchich responds for a click action on google map marker. So simply, when You scale map with CSS, each image scales too but position coordinates (left, right, top, bottom) don't change.
Theoreticaly You can inspect Google Map's code and fix this position in any way, but:
it's not universal solution (not for dynamic pin for example)
it can be changed in future (class name, or even whole solution)
it's rather hack than solution
what's your intens using transform:scale ?
why don't you use zoom for that ?
check my code snippet i edited from yours, may be this help you...
function initialize() {
var myLatlng = new google.maps.LatLng(-25.363882, 131.044922);
var myLatlng2 = new google.maps.LatLng(-22.363882, 125.044922);
var mapOptions = {
zoom: 4,
center: myLatlng
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
var contentString = "Pls help me to get the right position :)"
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker1 = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'First Marker'
});
var marker2 = new google.maps.Marker({
position: myLatlng2,
map: map,
title: 'Sec Marker'
});
google.maps.event.addListener(marker1, 'mouseover', function () {
map.setZoom(14);
infowindow.open(map, marker1);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
#map {
height: 400px;
width: 400px;
margin: auto;
padding: 0px;
top:100px;
}
.scale {
transition: all .2s ease-in-out;
}
#map.scale:hover {
transform: scale(1.9);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<body>
<div id="map" class="map scale"></div>
</body>
I have the same question as asked here but provided no accepted answer has been given and that my procedure is different, I'm opening a new one.
I have a map inside a Foundation tab that is hidden at the beginning and it only displays part of the map when opened. I've read the issues related to that and tried the attempts there but no luck. I know I have to re-initialize the map on tab change but I can't make it work.
I have a function that holds all the map info:
function startMap(obj){
var markers = new Array();
var glat_center = $(obj).attr('data-glat');
var glong_center = $(obj).attr('data-glong');
var Latlng_center = new google.maps.LatLng(glat_center, glong_center);
var mapOptions = {
zoom: zoom,
scrollwheel: false,
center: Latlng_center,
mapTypeId: google.maps.MapTypeId.ROADMAP,
styles: mapStyles,
mapTypeControl: false,
streetViewControl: false,
minZoom: 4,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL,
position: google.maps.ControlPosition.TOP_RIGHT
}
};
var map = new google.maps.Map(obj, mapOptions);
if($(obj).attr('data-glat') && $(obj).attr('data-glong')){
var glat = $(obj).attr('data-glat');
var glong = $(obj).attr('data-glong');
var Latlng = new google.maps.LatLng(glat, glong);
var marker = new google.maps.Marker({
position: Latlng,
map: map
});
}
}
My html markup looks like this
<div class="tabs" data-section="auto">
<!--two more tabs here-->
<section class="property-location">
<a href="#" class="title" data-section-title>Title</a>
<div class="tab-content" data-slug="section3" data-section-content>
<div class="google-map" data-glat="123456" data-glong="123456" style="width: 100%; height: 440px;">
</div>
</div>
</section>
</div>
So then, what I'm trying to do is call this function when the tab is clicked, as I can't find any other tab events in Foundation docs. First I find the .title of the tab that contains the map, then look if a map exists (just in case) and then I call the function on the div holding the map.
$('.tabs .property-location').find('.title').click(function() {
if(($('.tab-content').find('.google-map')).length) {
//console.log('I found a map');
startMap($('.google-map'));
}
});
I know it's finding the map because I console.log it, but the console throws this error
NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMWindow.getComputedStyle]
which is on the following src http://maps.gstatic.com/intl/es_ALL/mapfiles/api-3/14/7/main.js
So it's the Google Maps JS that's throwing this error but I can't understand why.
I know it's difficult, but any ideas?
You pass a jQuery-element, but google maps needs a HTMLElement. Use
var map = document.querySelector('.google-map');
startMap(map);
instead of
startMap($('.google-map'));
Instead of querySelector you can use getElementsByClassName
var map = document.getElementsByClassName('google-map')[0];
But the always recommended approach is to refer to the map by an id :
<div id="the-google-map" class="google-map" data-glat="123456" data-glong="123456" style="width: 100%; height: 440px;"></div>
var map = document.getElementById('the-google-map');
I have the below code, based on one of the API samples. A click on the map creates a marker. A click on the marker opens up an info window. Now I want a click on the info window to do something. E.g. a click anywhere might close it, as opposed to the little cross in the corner. Or a click on it might open a new URL. Etc.
Unfortunately it seems there is no "click" event for info windows.
The closest I've got is shown as a commented out line below: I wrap my info window content in a div, and give that an onClick. This works, but there is a big border around it. I really want to be able to click anywhere in the info window box.
Is there a way?
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Click Test</title>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script>
google.maps.visualRefresh = true; //New look visuals.
function initialize() {
var useragent = navigator.userAgent;
var mapdiv = document.getElementById("map-canvas");
if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
mapdiv.style.width = '100%';
mapdiv.style.height = '100%';
} else {
mapdiv.style.width = '400px';
mapdiv.style.height = '600px';
}
var mapOptions = {
zoom:3,
center: new google.maps.LatLng(37.09024, -95.712891),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
function placeMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map
});
var infowindow = new google.maps.InfoWindow({
//content: "<div onClick='test1()'>(lat,lng):<br/>"+location.lat()+","+location.lng()+"</div>"
content: "(lat,lng):<br/>"+location.lat()+","+location.lng()
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(marker.get('map'), marker);
infowindow.addListener('click',test1); //Does nothing
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
function test1(){alert("test1");}
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
UPDATE:
This image shows the problem when I use a clickable div inside the content (background set to red to show the extent of the region I can make clickable, and also that I can style; if I set a negative margin I just get scrollbars, not a bigger region!). It is the whole white area I want to be clickable, not just that red rectangle.
I decided to use InfoBox found in the Google Maps Utility Library. So in the header add a link to the library. Then replace the new google.maps.InfoWindow() line with this one:
var infowindow = new InfoBox({
closeBoxURL:"",
content: '<div onClick="test1();return false;" style="background:white;opacity:0.8;padding:8px">(lat,lng):<br/>'+
location.lat()+","+location.lng()+"</div>"
});
By setting closeBoxUrl to a blank string I get no close option. I added a large padding just so you can see that clicking right to the edge does indeed work.
You can also do it this way. I also use the boxClass option so the formatting is done in CSS:
var infoContent=document.createElement('div');
infoContent.innerHTML="(lat,lng):<br/>"+location.lat()+","+location.lng();
infoContent.onclick=test1;
var infowindow = new InfoBox({
closeBoxURL:"",
boxClass:"marker_popup",
content: infoContent,
});
(Aside, if doing it this way, on just some browsers it creates a marker below the InfoBox! Simplest fix is to change test1 so it looks like: function test1(event){alert("test1");event.preventDefault();return false;} )
P.S. I chose InfoBox over InfoBubble, as the latter has no documentation, and it had no obvious advantages to compensate for that major flaw! InfoBox has documentation and a reference. (links are for version 1.1.9)