// Aircraft on map
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
optimized: false,
internalid: planes[15],
zIndex: planes[3],
rotation: planes[4],
mouseovertxt: '<b>'+planes[11]+'</b><br />'+planes[0]+'-'+planes[13]+'-'+planes[14]+'<br />Status: '+planes[16]+'<br />Alt: '+planes[9]+'ft Speed: '+planes[10]+'kts<br />EET: '+planes[17]
});
// Aircraft route
line = new google.maps.Polyline({
path: [dep, myLatLng],
strokeColor: "#c3524f",
strokeOpacity: 1,
strokeWeight: 2,
geodesic: true,
map: map,
polylineID: i,
visible: true
});
line2 = new google.maps.Polyline({
path: [myLatLng, arr],
strokeColor: "#c3524f",
strokeOpacity: .5,
strokeWeight: 2,
geodesic: true,
map: map,
polylineID: i,
visible: true
});
// On mouse over
google.maps.event.addListener(marker, 'mouseover', function () {
infowindow.setContent(this.mouseovertxt);
infowindow.open(map, this);
line.setVisible(false);
line2.setVisible(false);
});
// On mouse out
google.maps.event.addListener(marker, 'mouseout', function () {
infowindow.close();
line.setVisible(true);
line2.setVisible(true);
});
}
}
setMarkers(map, planes);
});
Right now I've reversed the visibility of the lines just to show that the correct lines appear, but only one of them will change visible no matter what marker you hover. Is this because I have only one marker, or is there a simple fix to this? Also, I tried fixing the scrollbar bug, but with no luck. Will try some more though.
Possible approach:
store the lines as properties of the markers, than you may access them easily within the mouse-handlers:
// Aircraft on map
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
optimized: false,
internalid: planes[15],
zIndex: planes[3],
rotation: planes[4],
line1:new google.maps.Polyline({
path: [dep, myLatLng],
strokeColor: "#c3524f",
strokeOpacity: 1,
strokeWeight: 2,
geodesic: true,
map: map,
polylineID: i,
visible: true
}),
line2:new google.maps.Polyline({
path: [myLatLng, arr],
strokeColor: "#c3524f",
strokeOpacity: .5,
strokeWeight: 2,
geodesic: true,
map: map,
polylineID: i,
visible: true
}),
mouseovertxt: '<b>'+planes[11]+'</b><br />'+planes[0]+'-'+planes[13]+'-'+planes[14]+'<br />Status: '+planes[16]+'<br />Alt: '+planes[9]+'ft Speed: '+planes[10]+'kts<br />EET: '+planes[17]
});
// On mouse over
google.maps.event.addListener(marker, 'mouseover', function () {
infowindow.setContent(this.mouseovertxt);
infowindow.open(map, this);
this.get('line1').setVisible(false);
this.get('line2').setVisible(false);
});
// On mouse out
google.maps.event.addListener(marker, 'mouseout', function () {
infowindow.close();
this.get('line1').setVisible(true);
this.get('line2').setVisible(true);
});
Related
I am creating a google map for hiking. Each individual hike is displayed by a polyline. Each individual hike also has a start location and end location (at either end of the polyline). The start and end locations are each displayed by a marker (NOT a symbol). I have spent hours trying to add functionality such that when there is a mouseover event over EITHER the polyline OR either of the markers then both the polyline and both markers will "react" (in this case the opacity will change).
I have spent hours trying to find the solution. The closest I have got is the code below. In the code below, only if the mouse moves over the polyline will the polyline and markers react. But if the mouse moves over either marker, the polyline and markers do not react. I do understand my code is incorrect, but I cannot get closer to the solution.
I guess I somehow need to "group" each polyline and the respective 2 markers to one "object", "variable" or "layer" - but I simply cannot work this out.
Please note, the code below is simplified for only one marker (start location) per polyline (hike).
(At top of the code below is the gpx file from which the polyline and markers are created. Copy the gpx data into file and name google.gpx)
//start of the trimmed gpx data. Copy to new file and save as google.gpx
<lines>
<trkseg>
<trkpt lat="-33.879843" lng="151.225769"/>
<trkpt lat="-33.869843" lng="151.245769"/>
<trkpt lat="-33.859843" lng="151.255769"/>
</trkseg>
<trkseg>
<trkpt lat="-33.869843" lng="151.265769"/>
<trkpt lat="-33.869843" lng="151.275769"/>
</trkseg>
</lines>
//end of the trimmed gpx data
<style>
#map {
height: 100%;
}
</style>
<div id="map"></div>
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(-33.863276, 151.207977),
zoom: 12
});
downloadUrl('google.gpx', function(data) {
var xml = data.responseXML;
var trkseg = xml.querySelectorAll("trkseg");
for (var l = 0; l < trkseg.length; l++) {
var path = [],
trkPoints = trkseg[l].querySelectorAll('trkpt');
for (var p = 0; p < trkPoints.length; p++) {
var trkpt = trkPoints[p],
lat = parseFloat(trkpt.getAttribute("lat")),
lng = parseFloat(trkpt.getAttribute("lng")),
point = new google.maps.LatLng(lat, lng);
path.push(point);
}
var trkptMarker = trkPoints[0];
var startMarkerLat = parseFloat(trkptMarker.getAttribute("lat"));
var startMarkerLng = parseFloat(trkptMarker.getAttribute("lng"));
var startMarkerLatLng = {lat: startMarkerLat, lng: startMarkerLng};
var startIcon = 'https://stunninghikes.com/wp-content/uploads/2018/08/hike_start_pin_circular-e1534182115238.png';
var startIconImage = new google.maps.MarkerImage(startIcon);
var polyline = new google.maps.Polyline({
path: path,
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 2,
startMarker: new google.maps.Marker({
position: startMarkerLatLng,
map: map,
opacity: 0.5,
icon: startIconImage,
zIndex: 10
}),
});
polyline.setMap(map);
google.maps.event.addListener(polyline, 'mouseover', function(event) {
this.get('startMarker').setOptions({
opacity: 1.0,
});
this.setOptions({
strokeColor: '#128934',
strokeOpacity: 1,
strokeWeight: 5,
});
});
google.maps.event.addListener(polyline, 'mouseout', function(event) {
this.get('startMarker').setOptions({
opacity: 0.5,
});
this.setOptions({
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 2
});
});
}
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=GOOGLEKEY&&callback=initMap">
</script>
The simplest option given your existing code is to add the equivalent mouseover/mouseout listeners to the marker:
var startMarker = new google.maps.Marker({
position: startMarkerLatLng,
map: map,
opacity: 0.5,
icon: startIconImage,
zIndex: 10
});
var polyline = new google.maps.Polyline({
path: path,
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 2,
map: map,
startMarker: startMarker
});
startMarker.set("polyline", polyline);
google.maps.event.addListener(polyline, 'mouseover', function(event) {
this.get('startMarker').setOptions({
opacity: 1.0,
});
this.setOptions({
strokeColor: '#128934',
strokeOpacity: 1,
strokeWeight: 5,
});
});
google.maps.event.addListener(polyline, 'mouseout', function(event) {
this.get('startMarker').setOptions({
opacity: 0.5,
});
this.setOptions({
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 2
});
});
google.maps.event.addListener(startMarker, 'mouseover', function(event) {
this.setOptions({
opacity: 1.0,
});
this.get("polyline").setOptions({
strokeColor: '#128934',
strokeOpacity: 1,
strokeWeight: 5,
});
});
google.maps.event.addListener(startMarker, 'mouseout', function(event) {
this.setOptions({
opacity: 0.5,
});
this.get("polyline").setOptions({
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 2
});
});
proof of concept fiddle
code snippet:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var bounds = new google.maps.LatLngBounds();
var xml = parseXml(xmlStr);
var trkseg = xml.querySelectorAll("trkseg");
for (var l = 0; l < trkseg.length; l++) {
var path = [],
trkPoints = trkseg[l].querySelectorAll('trkpt');
for (var p = 0; p < trkPoints.length; p++) {
var trkpt = trkPoints[p],
lat = parseFloat(trkpt.getAttribute("lat")),
lng = parseFloat(trkpt.getAttribute("lng")),
point = new google.maps.LatLng(lat, lng);
path.push(point);
bounds.extend(point);
}
var trkptMarker = trkPoints[0];
var startMarkerLat = parseFloat(trkptMarker.getAttribute("lat"));
var startMarkerLng = parseFloat(trkptMarker.getAttribute("lng"));
var startMarkerLatLng = {
lat: startMarkerLat,
lng: startMarkerLng
};
var startIcon = 'https://stunninghikes.com/wp-content/uploads/2018/08/hike_start_pin_circular-e1534182115238.png';
var startIconImage = new google.maps.MarkerImage(startIcon);
var startMarker = new google.maps.Marker({
position: startMarkerLatLng,
map: map,
opacity: 0.5,
icon: startIconImage,
zIndex: 10
});
var polyline = new google.maps.Polyline({
path: path,
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 2,
map: map,
startMarker: startMarker
});
startMarker.set("polyline", polyline);
google.maps.event.addListener(polyline, 'mouseover', function(event) {
this.get('startMarker').setOptions({
opacity: 1.0,
});
this.setOptions({
strokeColor: '#128934',
strokeOpacity: 1,
strokeWeight: 5,
});
});
google.maps.event.addListener(polyline, 'mouseout', function(event) {
this.get('startMarker').setOptions({
opacity: 0.5,
});
this.setOptions({
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 2
});
});
google.maps.event.addListener(startMarker, 'mouseover', function(event) {
this.setOptions({
opacity: 1.0,
});
this.get("polyline").setOptions({
strokeColor: '#128934',
strokeOpacity: 1,
strokeWeight: 5,
});
});
google.maps.event.addListener(startMarker, 'mouseout', function(event) {
this.setOptions({
opacity: 0.5,
});
this.get("polyline").setOptions({
strokeColor: '#FF0000',
strokeOpacity: 0.5,
strokeWeight: 2
});
});
}
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, "load", initialize);
function parseXml(str) {
if (window.ActiveXObject) {
var doc = new ActiveXObject('MicrosoftXMLDOM');
doc.loadXML(str);
return doc;
} else if (window.DOMParser) {
return (new DOMParser()).parseFromString(str, 'text/xml');
}
}
var xmlStr = '<lines><trkseg><trkpt lat="-33.879843" lng="151.225769"/><trkpt lat="-33.869843" lng="151.245769"/><trkpt lat="-33.859843" lng="151.255769"/></trkseg><trkseg><trkpt lat="-33.869843" lng="151.265769"/><trkpt lat="-33.869843" lng="151.275769"/></trkseg></lines>';
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>
Google Maps circle looks like hand drawn.
Circle script is:
var circle = new google.maps.Circle({
center: myLatLng,
radius:1000,
strokeColor: "#000000",
strokeOpacity:1,
fillOpacity:0.4,
strokeWeight: 2,
fillColor: "#000000",
map:map
});
Can we make the circle more fine tuned.
My requirement is to show circle around marker with fine tuned circle border.
You could try using a symbol. I don't believe there's an option to change those circles from using the "hand-drawn" style. It's odd because their rectangles don't seem to be using that look.
Here is an example :
https://developers.google.com/maps/documentation/javascript/examples/marker-symbol-predefined
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(-25.363882, 131.044922)
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var myCircle = {
path: google.maps.SymbolPath.CIRCLE,
fillColor: 'red',
fillOpacity: 0.8,
scale: 20,
strokeColor: 'black',
strokeWeight: 3
};
var marker = new google.maps.Marker({
position: map.getCenter(),
icon: myCircle,
map: map
});
}
Here is an example of a circle around a marker :
function initialize() {
var myLatlng = new google.maps.LatLng(16.5083,80.64);var mapOptions = {zoom: 12,center: myLatlng};
var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
var marker = new google.maps.Marker({map: map,position: myLatlng});
var circle = new google.maps.Circle({
map: map,
radius: 2000,
fillColor: '#000000',
fillOpacity: 0.4,
strokeColor: '#000000',
strokeWeight: 2
});
circle.bindTo('center', marker, 'position');
}
google.maps.event.addDomListener(window, 'load', initialize);
For some reason my infoBox'es turn up behind the markers. I know this is supposed to be impossible, but it is never the less the case. Here is the code for my markers:
var yellowCircle={
path: google.maps.SymbolPath.CIRCLE,
scale: 5,
fillColor: '#faeadd',
strokeColor: 'black',
fillOpacity: 1.0,
strokeWeight: 0.5,
zIndex:-10
};
var yellowBlackCircle={
path: google.maps.SymbolPath.CIRCLE,
scale: 5,
fillColor: '#faeadd',
strokeColor: 'black',
fillOpacity: 1.0,
strokeWeight: 1.5,
zIndex:-10
};
var marker = new google.maps.Marker({
position: new google.maps.LatLng(Lat,Lng),
map: map,
title: name,
icon:yellowCircle,
url:url,
zIndex:-1,
});
google.maps.event.addListener(marker, 'mouseover', function() {
marker.setIcon(yellowBlackCircle);
});
google.maps.event.addListener(marker, 'mouseout', function() {
marker.setIcon(yellowCircle);
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = url;
});
And the code for my infoboxes:
var myOptions = {
content: name
,boxStyle: {
border: "1px solid black"
,textAlign: "center"
,fontSize: "12pt"
,fontType: "arial"
,backgroundColor: "#faeadd"
,fontWeight: "bold"
,zIndex:1
}
,disableAutoPan: true
,pixelOffset: new google.maps.Size(-getTextWidth(name, "bold 12pt arial")/2,-30)
,position: new google.maps.LatLng(49.47216, -123.76307)
,closeBoxURL: ""
,isHidden: false
,pane: "mapPane"
,enableEventPropagation: true
,zIndex:1
};
var infobox = new InfoBox(myOptions);
google.maps.event.addListener(marker, 'mouseover', function() {
infobox.open(map,marker);
});
google.maps.event.addListener(marker, 'mouseout', function() {
infobox.close();
});
You can see that I have even tried setting the zIndex'es as well, but it has no effect. I believe this is the same question as was asked in google maps infobox above all other content z-index does not work.
I apologize for not attaching a jsfiddle - I couldn't seem to make it work, even after I uploaded the infobox_packed.js to a repository so I could add is as external resource. Instead, here is the whole thing:
http://www.kaarebmikkelsen.dk/wp-content/uploads/2014/05/test2.html
The info-box code is mostly copied from https://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/examples.html.
Your code came from the example that makes "map labels" and you are attaching the infoBox to the mapPane:
pane: "mapPane"
That will put it behind the markers. If you want it to be an infowindow replacement, copy the code from that example:
pane: "floatPane"
from the documentation you reference
I have this code where when the user clicks on the map like 3 times a polygon is created as well as a marker in each nodal point. Anyone knows how I could calculate the middle point of the polygon and drop a marker there as well ? thanks. here is my code.
var poly;
var map;
function initialize()
{
map = new google.maps.Map(document.getElementById('map'),
{
zoom: 14,
center: new google.maps.LatLng(12.303022,76.644917),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
poly = new google.maps.Polygon(
{
strokeColor: '#000000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#000000",
fillOpacity: 0.26
});
poly.setMap(map);
google.maps.event.addListener(map, 'click', addLatLng);
}
function addLatLng(event)
{
var path = poly.getPath();
path.push(event.latLng);
var marker = new google.maps.Marker(
{
position: event.latLng,
title: '#' + path.getLength(),
map: map
});
}
I've seen discussions on this topic on this site, and I've followed the proposed codes as closely as possible without luck. Can anyone tell me if the following code has any chance of being fixed, or if it's breaking a fundamental Google law? What it's trying to do is use one array of rectangles for two maps on the same page using the same geolocation code to position the marker representing the user's location. I have provided 2 sets of options as the zoom, center and functionality of the two maps are different (as is the size of the div in which each is displayed). The first map is zoomed to street level with the user's position in the center; the second is a wide view centered so as to show the full extent of the rectangle layer with the user's location wherever it happens to be on the map. This is a bit more complicated than the examples I've seen, so maybe it can't work and I just have to have two completely separate blocks of code. It would be a shame though to have to repeat the full rectangle array code...
Thanks for any suggestions.
<script src="http://maps.google.com/maps/api/js?sensor=false">
</script><script type="text/javascript">
if (navigator.geolocation) {navigator.geolocation.getCurrentPosition(function(position){
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var coords = new google.maps.LatLng(latitude, longitude);
var map,map2;
var mapOptions1 = {
zoom: 16,
center: coords,
draggable: false,
zoomControl: false,
scrollwheel: false,
disableDoubleClickZoom: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mapOptions2 = {
zoom: 5,
center: new google.maps.LatLng(0, 0),
mapTypeControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("mapContainer1"), mapOptions1);
map2 = new google.maps.Map(document.getElementById("mapContainer2"), mapOptions2);
var marker = new google.maps.Marker({
position: coords,
map: map,map2
});
marker.setIcon('sites/default/files/YourLocation_0.png')
var rectangles = [];
rectangles[0]=new google.maps.Rectangle({
bounds:new google.maps.LatLngBounds(new google.maps.LatLng(a,b),new google.maps.LatLng(x, y)),
map:map,map2,
fillOpacity: 0,
strokeOpacity: 0,
url: 'http://example.com',
clickable: true
});
rectangles[1]=new google.maps.Rectangle({
bounds:new google.maps.LatLngBounds(new google.maps.LatLng(aa, bb),new google.maps.LatLng(xx, yy)),
map:map,map2,
fillOpacity: 0,
strokeOpacity: 0,
url: 'http://example2.com',
clickable: true
});
rectangles[2]=new google.maps.Rectangle({
bounds:new google.maps.LatLngBounds(new google.maps.LatLng(aaa, bbb),new google.maps.LatLng(xxx, yyy)),
map:map,map2,
fillOpacity: 0,
strokeOpacity: 0,
url: 'http://example3.com',
clickable: true
});
[.....lots more rectangles....]
for ( i = 0; i < rectangles.length; i++ ){google.maps.event.addListener(rectangles[i], 'click', function() {window.location.href = this.url;
});
}
layer.setMap(map);
layer.setMap(map2);
});
}else {
alert("Geolocation API is not supported in your browser.");
}
This will not work:
rectangles[0]=new google.maps.Rectangle({
bounds:new google.maps.LatLngBounds(new google.maps.LatLng(a,b),new google.maps.LatLng(x, y)),
map:map,map2,
fillOpacity: 0,
strokeOpacity: 0,
url: 'http://example.com',
clickable: true
});
You need to create a separate rectangle for each map (the rectangle can only be on one map at a time) something like this (which creates a two dimensional array, [1] for map, [2] for map2):
rectangles[1][0]=new google.maps.Rectangle({
bounds:new google.maps.LatLngBounds(new google.maps.LatLng(a,b),new google.maps.LatLng(x, y)),
map:map,
fillOpacity: 0,
strokeOpacity: 0,
url: 'http://example.com',
clickable: true
});
rectangles[2][0]=new google.maps.Rectangle({
bounds:new google.maps.LatLngBounds(new google.maps.LatLng(a,b),new google.maps.LatLng(x, y)),
map:map2,
fillOpacity: 0,
strokeOpacity: 0,
url: 'http://example.com',
clickable: true
});