I display cruise routes on a google map and mark each port with an infobox. Unfortunately these infoboxes regularly overlap. How can this be avoided?
I've already tried spiderfy but it's not suitable in this instance.
Changing the zoom level of the map is also not an option. The ideal would be a plugin or something similar that can recognize overlapping infoboxes at creation and rearrange them. However, I haven't been able to find something like this anywhere.
A second possibility would be to change the position via javascript, but given my lack of expertise with javascript & google maps, I haven't been able to achieve this. Nor have I found an example that I could hack.
Would appreciate some info/advice/pointers in the right direction.
Thanks
MK
Here's my code:
function initialize() {
var arrayMarkers = [];
var idx = 0;
var mapLatlng = new google.maps.LatLng(-27.6264198719, 146.9179666042);
var mapOptions = { center: mapLatlng,
zoom: 13,
mapTypeId: google.maps.MapTypeId.SATELLITE };
var map = new google.maps.Map(document.getElementById("karte"), mapOptions);
var bounds = new google.maps.LatLngBounds();
arrayMarkers[idx] = [];
arrayMarkers[idx]['breite'] = -33.859261813133;
arrayMarkers[idx]['laenge'] = 151.200070381165;
arrayMarkers[idx]['farbe'] = "http://new.kfb.localhost:8888/img/ico/button2_gruen.png";arrayMarkers[idx]['hafen'] = "Abfahrt Sydney";
arrayMarkers[idx]['link'] = "Karte, Wetter und<br>Landausflüge für<br><a href='hafen.php?hafen=528'>Sydney</a><br>Do, 07.02.13";idx++;
arrayMarkers[idx] = [];
.
.
. etc.
To add the markers and infoboxes to the map, I call this function:
function create_markers_v3(map, bounds, arrayMarkers) {
var latLng = [];
var img = [];
var marker = [];
var optionsPort = [];
var ib = [];
var infoWindow = [];
for (i = 0; i < arrayMarkers.length; i++)
{
latLng[i] = new google.maps.LatLng(arrayMarkers[i]['breite'], arrayMarkers[i]['laenge']);
bounds.extend(latLng[i]);
map.fitBounds(bounds);
img[i] = arrayMarkers[i]['farbe'];
marker[i] = new google.maps.Marker(
{
position: latLng[i],
map: map,
icon: img[i]
});
optionsPort[i] = {
content: arrayMarkers[i]['hafen'],
disableAutoPan: false,
pixelOffset: new google.maps.Size(3, -20),
position: new google.maps.LatLng(arrayMarkers[i]['breite'], arrayMarkers[i]['laenge']),
zIndex: null,
boxStyle: {
opacity: 0.81,
fontSize: "6pt",
backgroundColor: "#ffffff",
padding: "0 2px 1px 3px",
lineHeight: "1em",
border: "1px solid #333333"
},
closeBoxURL: "",
isHidden: false,
pane: "floatPane",
enableEventPropagation: true
};
if (arrayMarkers[i]['hafen'].length > 0)
{
ib[i] = new InfoBox(optionsPort[i]);
ib[i].open(map, marker[i]);
arrayMarkers[i]['ib'] = ib[i];
if (arrayMarkers[i]['link'].length > 0)
{
addInfoWindow(map, arrayMarkers[i], marker[i], i);
}
}
}
return arrayMarkers;
}
Related
I am trying to work out how to show custom data when a Google Maps markerclusterer marker is clicked but can't find this documented anywhere.
My markerclusterer code looks like this but my attempt at capturing the click event on a marker is not working:
var markerClusterer = null;
var map = null;
var imageUrl = 'http://chart.apis.google.com/chart?cht=mm&chs=24x32&' +
'chco=FFFFFF,008CFF,000000&ext=.png';
google.maps.event.addDomListener(window, 'load', initialize);
function refreshMap() {
if (markerClusterer) {
markerClusterer.clearMarkers();
}
var markers = [];
var markerImage = new google.maps.MarkerImage(imageUrl,
new google.maps.Size(24, 32));
/*
for (var i = 0; i < 1000; ++i) {
var latLng = new google.maps.LatLng(data.photos[i].latitude,
data.photos[i].longitude)
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage
});
markers.push(marker);
}
*/
for (var i = 0; i < numItemsToShow; ++i) {
var latLng = new google.maps.LatLng(itemsToShow[i].lat, itemsToShow[i].long);
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage
});
markers.push(marker);
}
var zoom = parseInt(document.getElementById('zoom').value, 10);
var size = parseInt(document.getElementById('size').value, 10);
var style = parseInt(document.getElementById('style').value, 10);
zoom = zoom == -1 ? null : zoom;
size = size == -1 ? null : size;
style = style == -1 ? null: style;
markerClusterer = new MarkerClusterer(map, markers, {
maxZoom: zoom,
gridSize: size,
styles: styles[style]
});
}
function initialize() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: new google.maps.LatLng(39.91, 116.38),
mapTypeId: google.maps.MapTypeId.ROADMAP,
//styles: [{"featureType":"administrative","elementType":"labels.text.fill","stylers":[{"color":"#444444"}]},{"featureType":"administrative.land_parcel","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2f2f2"}]},{"featureType":"landscape.natural","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"on"},{"color":"#052366"},{"saturation":"-70"},{"lightness":"85"}]},{"featureType":"poi","elementType":"geometry.fill","stylers":[{"saturation":"-100"},{"lightness":"0"}]},{"featureType":"poi","elementType":"labels","stylers":[{"visibility":"simplified"},{"lightness":"-53"},{"weight":"1.00"},{"gamma":"0.98"}]},{"featureType":"poi","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"labels.icon","stylers":[{"visibility":"off"},{"lightness":"0"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"hue":"#3dff00"},{"saturation":"-100"}]},{"featureType":"road","elementType":"all","stylers":[{"saturation":-100},{"lightness":45},{"visibility":"on"}]},{"featureType":"road","elementType":"geometry","stylers":[{"saturation":"-18"}]},{"featureType":"road","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"road.local","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.local","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"all","stylers":[{"color":"#57677a"},{"visibility":"on"}]},{"featureType":"water","elementType":"geometry.fill","stylers":[{"lightness":"40"}]}]
styles: [{"featureType":"water","stylers":[{"visibility":"on"},{"color":"#b5cbe4"}]},
{"featureType":"landscape","stylers":[{"color":"#efefef"}]},
{"featureType":"road.highway","elementType":"geometry","stylers":[{"color":"#83a5b0"}]},
{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#bdcdd3"}]},
{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"}]},
{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#e3eed3"}]},
{"featureType":"administrative","stylers":[{"visibility":"on"},{"lightness":33}]},
{"featureType":"road"},
{"featureType":"poi.park","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":20}]},{},
{"featureType":"road","stylers":[{"lightness":20}]}]
});
var refresh = document.getElementById('refresh');
google.maps.event.addDomListener(refresh, 'click', refreshMap);
var clear = document.getElementById('clear');
google.maps.event.addDomListener(clear, 'click', clearClusters);
google.maps.event.addListener(markerClusterer, 'click', function () {
// do something with this marker ...
this.setTitle('I am clicked');
});
refreshMap();
}
function clearClusters(e) {
e.preventDefault();
e.stopPropagation();
markerClusterer.clearMarkers();
}
This works for me (it opens an infowindow when you mouseover the cluster icon, if you click on the cluster icon, the default behavior is to zoom to the cluster bounds, which makes it hard to see the change of the tooltip/title on the cluster icon):
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(markerClusterer, 'mouseover', function (cluster) {
// do something with this cluster ...
infoWindow.setContent("Mouseover<br>"+cluster.getCenter().toUrlValue());
infoWindow.setPosition(cluster.getCenter());
infoWindow.open(map);
});
I am trying to delete a polygon when my marker is being clicked,but i could not get how to make this work that the polygon will be deleted.I appreciate someone will help me to make this work.
This my demo in jsfiddle.
Demo
here is my code it's not working.
var map;
var count = 0;
var polycolor = '#ED1B24';
var polyarray = [];
var marker;
var markers = [];
var path = new google.maps.MVCArray;
function initialize() {
var initial = new google.maps.LatLng(53.199246241276875, -105.76864242553711);
var mapOptions = {
zoom: 16,
center: initial,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE
},
mapTypeControl: false
};
poly.setPaths(new google.maps.MVCArray([path]));
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
google.maps.event.addListener(map, 'click', function (e) {
addMarker(e);
addPolygon(e);
});
}
var deletepolygon = function (pt) {
i = 0;
var thepath = poly.getPath();
thepath.forEach(function (ltlng) {
i++;
if ((ltlng.lat() + "," + ltlng.lng()) == pt) {
path.removeAt(i);
}
});
}
How would you put a white frame behind a dynamically loaded marker icon, now, that the new Google Maps "VisualRefresh" doesn´t allow shadows anymore? 1
Open http://jsfiddle.net/FSffv/3/ with google.maps.visualRefresh = false; to see the white frame around the marker icon and google.maps.visualRefresh = true; to have it disappear.
var map;
var m_NormalImageSize = 15;
var m_NormalShadowSize = m_NormalImageSize+5;
var elevator;
var myOptions = {
zoom: 6,
center: new google.maps.LatLng(47, 8),
mapTypeId: 'terrain'
};
// turn VisualRefresh on/off
google.maps.visualRefresh = false;
map = new google.maps.Map($('#map')[0], myOptions);
var img = new Image();
img.src = "http://t2.gstatic.com/images?q=tbn:ANd9GcQUnmYVY5sWfZtBlw_IELax3W8E7-jZcCXLd2HUZYtpk_AeuK4CRnJmMHj0";
var img_ratio = img.height / img.width;
if (isNaN(img_ratio))
img_ratio = 1;
var icon_size = new google.maps.Size(m_NormalImageSize, m_NormalImageSize * img_ratio);
var shadow_size = new google.maps.Size(m_NormalShadowSize, m_NormalShadowSize * img_ratio);
var image = new google.maps.MarkerImage(
"http://t2.gstatic.com/images?q=tbn:ANd9GcQUnmYVY5sWfZtBlw_IELax3W8E7-jZcCXLd2HUZYtpk_AeuK4CRnJmMHj0",
icon_size,
new google.maps.Point(0, 0),
new google.maps.Point(-3, m_NormalImageSize * img_ratio + 3 * img_ratio),
icon_size
);
// the frame around the marker icon as a shadow
var shadow = new google.maps.MarkerImage(
"http://alsotoday.com/jpg/placemarkbackground_white.png",
shadow_size,
new google.maps.Point(0, 0),
new google.maps.Point(0, m_NormalShadowSize * img_ratio),
shadow_size
);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(47, 8),
map: map,
icon: image,
shadow: shadow,
title: "hallo"
});
One way to do this would be to use a custom HTML overlay. Then you can style it any way you like.
Here's a working example using this code:
function ImageMarker( options ) {
this.setValues( options );
this.$inner = $('<div>').css({
position: 'relative',
left: '-50%', top: '-50%',
fontSize: '1px',
lineHeight: '1px',
border: '2px solid red',
padding: '2px',
backgroundColor: 'white',
cursor: 'default'
});
this.$div = $('<div>')
.append( this.$inner )
.css({
position: 'absolute',
display: 'none'
});
};
ImageMarker.prototype = new google.maps.OverlayView;
ImageMarker.prototype.onAdd = function() {
$( this.getPanes().overlayMouseTarget ).append( this.$div );
};
ImageMarker.prototype.onRemove = function() {
this.$div.remove();
};
ImageMarker.prototype.draw = function() {
var marker = this;
var projection = this.getProjection();
var position = projection.fromLatLngToDivPixel( this.get('position') );
this.$div.css({
left: position.x,
top: position.y,
display: 'block'
})
this.$inner
.html( '<img src="' + this.get('image') + '"/>' )
.click( function( event ) {
var events = marker.get('events');
events && events.click( event );
});
};
function initialize() {
var latLng = new google.maps.LatLng( 40.708762, -74.006731 );
var map = new google.maps.Map( $('#map_canvas')[0], {
zoom: 15,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var marker = new ImageMarker({
map: map,
position: latLng,
image: 'http://cdn.sstatic.net/stackoverflow/img/favicon.ico',
events: {
click: function( event ) {
alert( 'Clicked marker' );
}
}
});
};
$( initialize );
How about having one more image with borders and make a statement like below:
if (google.maps.visualRefresh) {
image = new google.maps.MarkerImage(
"http://s24.postimg.org/lfamj2ktd/image.png",
icon_size,
new google.maps.Point(0, 0),
new google.maps.Point(-3, m_NormalImageSize * img_ratio + 3 * img_ratio),
icon_size);
}
Check this JSFiddle.
I am trying to port my google api v2 to v3 but it does not work....i get an "Polyline is not defined" error... :/ the old Polyline is GPolyline and the new is new google.maps.Polyline
https://developers.google.com/maps/documentation/javascript/overlays?hl=de-DE#Polylines
var map = "";
var mapConfig = "";
var mapElements = "";
var curActiveMenuButton = "";
var clickHandlerElementCount = "";
//window.onload = function() {
//window.addEvent('domready', function() {
//document.addEvent('domready', function() {
//alert("The DOM is ready.");
//initializeMap();
//});
/*
* function initializeMap()
*
* Initalisierung der Google-Map.
*/
function initializeMap(){
// Karte ins DOM einhängen
map = new google.maps.Map($('map_canvas'), myOptions);
//place the map on the canvas
//map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var latlng = new google.maps.LatLng(51.05758110879136, 10.451431274414062);
// default zoomlevel and center point
var myOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
navigationControl: true,
mapTypeControl: true,
scaleControl: true,
};
// default zoomlevel and center point
var encodedPolyline = new google.maps.Polyline();
// find bounding polyline and recalculate map center
for (var i = 0; i < mapElements.length; i++) {
if (mapElements[i]['titel'] == "nationalparkhainich") {
encodedPolyline = Polyline.fromEncoded({
points: mapElements[i]['pol'],
levels: mapElements[i]['lev']
});
mapCenter = encodedPolyline.getBounds().getCenter();
i = mapElements.length;
}
}
// Kartenmenue initialisieren
//initializeMapMenue();
}
Polyline is indeed not defined. You use it here:
encodedPolyline = Polyline.fromEncoded({
Version 3 doesn't include fromEncoded() — it appears that you need to use the geometry library (which needs to be explicitly loaded separately) and
encodedPolyline.setPath(
google.maps.geometry.encoding.decodePath(mapElements[i]['pol'])
);
[split on to separate lines here for clarity]
I wonder whether someone may be able to help me please.
I've been working on a tooltip for markers that I place on a google map. I can get this to work showing the information that I would like the user to see, in this case the fields name and address, so the code line is title: name+address.
Could someone please tell me how I could put a space between these so the tooltip would read 'name address' rather than 'nameaddress'.
I've tried all sorts of things using e.g.title: name'_'+ address, title: name' '+address and I can't get it to work.
Any help would be greatly appreciated.
Many thanks
Chris
You can try this
name + ' ' + address
NB: you need a space in the quotes and a + on either side.
I use this function to initialize started values:
//Inicialize map values
function initialize() {
latCenterMap=41.50347;
lonCenterMap=-5.74638;
zommCeneterMap=14;
latPoint=41.50347;
lonPoint=-5.74638;
//Values default initialize
var latlng = new google.maps.LatLng(latCenterMap, lonCenterMap);
var mapOptions = {
zoom: zommCeneterMap,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas_'), mapOptions);
codePoint(map, lat, lon);
}
I used this function to set values point position into map
//Get position by Latitude and Longitude
function codePoint(map, lat, lon) {
var latlng = new google.maps.LatLng(parseFloat(lat), parseFloat(lon));
var title = "Your text";
var iconPoint = new google.maps.MarkerImage('images/pointBlue.png',
//Measure image
new google.maps.Size(25,25),
new google.maps.Point(0,0),
//Half measure image
new google.maps.Point(12.5,12.5)
);
marker = new google.maps.Marker({
position: latlng,
map: map,
icon: iconPoint,
tooltip: title
});
customTooltip(marker);
}
I use this function to create a tooltip to point position
//TOOLTIP
function customTooltip(marker){
// Constructor function
function Tooltip(opts, marker) {
// Initialization
this.setValues(opts);
this.map_ = opts.map;
this.marker_ = marker;
var div = this.div_ = document.createElement("div");
// Class name of div element to style it via CSS
div.className = "tooltip";
this.markerDragging = false;
}
Tooltip.prototype = {
// Define draw method to keep OverlayView happy
draw: function() {},
visible_changed: function() {
var vis = this.get("visible");
this.div_.style.visibility = vis ? "visible" : "hidden";
},
getPos: function(e) {
var projection = this.getProjection();
// Position of mouse cursor
var pixel = projection.fromLatLngToDivPixel(e.latLng);
var div = this.div_;
// Adjust the tooltip's position
var gap = 15;
var posX = pixel.x + gap;
var posY = pixel.y + gap;
var menuwidth = div.offsetWidth;
// Right boundary of the map
var boundsNE = this.map_.getBounds().getNorthEast();
boundsNE.pixel = projection.fromLatLngToDivPixel(boundsNE);
if (menuwidth + posX > boundsNE.pixel.x) {
posX -= menuwidth + gap;
}
div.style.left = posX + "px";
div.style.top = posY + "px";
if (!this.markerDragging) {
this.set("visible", true);
}
},
// This is added to avoid using listener (Listener is not working when Map is quickly loaded with icons)
getPos2: function(latLng) {
var projection = this.getProjection();
// Position of mouse cursor
var pixel = projection.fromLatLngToDivPixel(latLng);
var div = this.div_;
// Adjust the tooltip's position
var gap = 5;
var posX = pixel.x + gap;
var posY = pixel.y + gap;
var menuwidth = div.offsetWidth;
// Right boundary of the map
var boundsNE = this.map_.getBounds().getNorthEast();
boundsNE.pixel = projection.fromLatLngToDivPixel(boundsNE);
if (menuwidth + posX > boundsNE.pixel.x) {
posX -= menuwidth + gap;
}
div.style.left = posX + "px";
div.style.top = posY + "px";
if (!this.markerDragging) {
this.set("visible", true);
}
},
addTip: function() {
var me = this;
var g = google.maps.event;
var div = me.div_;
div.innerHTML = me.get("text").toString();
// Tooltip is initially hidden
me.set("visible", false);
// Append the tooltip's div to the floatPane
me.getPanes().floatPane.appendChild(this.div_);
// In IE this listener gets randomly lost after it's been cleared once.
// So keep it out of the listeners array.
g.addListener(me.marker_, "dragend", function() {
me.markerDragging = false; });
// Register listeners
me.listeners = [
// g.addListener(me.marker_, "dragend", function() {
// me.markerDragging = false; }),
g.addListener(me.marker_, "position_changed", function() {
me.markerDragging = true;
me.set("visible", false); }),
g.addListener(me.map_, "mousemove", function(e) {
me.getPos(e); })
];
},
removeTip: function() {
// Clear the listeners to stop events when not needed.
if (this.listeners) {
for (var i = 0, listener; listener = this.listeners[i]; i++) {
google.maps.event.removeListener(listener);
}
delete this.listeners;
}
// Remove the tooltip from the map pane.
var parent = this.div_.parentNode;
if (parent) parent.removeChild(this.div_);
}
};
function inherit(addTo, getFrom) {
var from = getFrom.prototype; // prototype object to get methods from
var to = addTo.prototype; // prototype object to add methods to
for (var prop in from) {
if (typeof to[prop] == "undefined") to[prop] = from[prop];
}
}
// Inherits from OverlayView from the Google Maps API
inherit(Tooltip, google.maps.OverlayView);
var tooltip = new Tooltip({map: map}, marker);
tooltip.bindTo("text", marker, "tooltip");
google.maps.event.addListener(marker, 'mouseover', function() {
tooltip.addTip();
tooltip.getPos2(marker.getPosition());
});
google.maps.event.addListener(marker, 'mouseout', function() {
tooltip.removeTip();
});
}
I use this style to css file
//CSS
.tooltip {
position:absolute;
top:0;
left:0;
z-index: 300;
width: 11.5em;
padding: 5px;
font-size: 12pt;
font-family: klavika;
color: #fff;
background-color: #04A2CA;
border-radius: 10px;
box-shadow: 2px 2px 5px 0 rgba(50, 50, 50, 0.75);
}