Change infowindow marker based on variable in realtime - google-maps-api-3

How do I change the icon of a marker based on if a value is true or false.
I created an if function that checks the value of CameraStatus. I set it to false on default but the marker still won't change to RedStatus. It does change to RedStatus when I try a timer like this:
setTimeout(function () { MiamiMarker.setIcon(RedStatus) }, 10 * 1000);
It doesn't change to RedStatus when I try this:
var CameraStatus = false;
function CheckStatus() {
if (CameraStatus === false) {
MiamiMarker.SetIcon(RedStatus)
}
}
How do I change the marker based on my if function?
Eventually I want to change all my markers with boolean values I get from a home controller. The value of the boolean should decide if the marker has a GreenStats or RedStatus icon. First I'm trying to change one marker based on a hardcoded value. (See code below)
My code:
<script>
var map;
function initMap() {
var CenterLoc = { lat: 51.34, lng: 5.53 };
map = new google.maps.Map(document.getElementById('map'),
{
center: CenterLoc,
disableDefaultUI: true,
zoom: 3,
});
google.maps.event.addDomListener(window, 'load', initMap);
var Miami = { lat: 25.774266, lng: -80.193659 };
var MiamiMarker = new google.maps.Marker
({
position: Miami,
map: map,
icon: GreenStatus
});
//Replace standard google maps markers with colored dots
var GreenStatus = "#ViewBag.GreenStatus";
var OrangeStatus = "#ViewBag.OrangeStatus";
var RedStatus = "#ViewBag.RedStatus";
var CameraStatus = false;
function CheckStatus() {
if (CameraStatus === false) {
MiamiMarker.SetIcon(RedStatus)
}
}
var MiamiInfoCard = new google.maps.InfoWindow
({
content: '<div id="map-dialog"><h3>Miami</h3></div>'
});
MiamiMarker.addListener('click', function () {
MiamiInfoCard.open(map, MiamiMarker);
});
var position = new google.maps.LatLng(52.2305, 5.9924);
}
</script>

You can use an if else statement to change your Icon. Please note that it is .setIcon() and not *.SetIcon() just like in your code.
if (CameraStatus == false) {
MiamiMarker.setIcon(RedStatus)
} else {
MiamiMarker.setIcon(GreenStatus)
}
You can check this sample code that reproduces what you want in your use-case.
I used a toggle switch to set values for CameraStatus and call the CheckStatus() function passing the variables CameraStatus and MiamiMarker to be processed in the function.
var switchStatus = document.getElementById("mySwitch");
var CameraStatus;
switchStatus.addEventListener('change', function() {
if (switchStatus.checked) {
CameraStatus = false;
} else {
CameraStatus = true;
}
CheckStatus(CameraStatus, MiamiMarker);
});
I put the CheckStatus() function outside the initMap() function and passed the CameraStatus and MiamiMarker to change the marker's icon base on the value of CameraStatus.
function CheckStatus(CameraStatus, MiamiMarker) {
if (CameraStatus == false) {
MiamiMarker.setIcon(RedStatus)
} else {
MiamiMarker.setIcon(GreenStatus)
}
Hope this helps!

Related

Wordpress Plugin for Google Maps: How to return the Map

I have a PHP Site which takes Data from XML File to display Markers on a Google Maps. When I navigate direct to the page, everything is working. To integrate that code on my Wordpress Page, I thought about writing a plugin for that:
<? defined('ABSPATH') or die("Thanks for visting");
function showMap() { ?>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<div id="map"></div>
<script>
var customLabel = {
Location: {
label: 'L'
},
Brautaustatter: {
label: 'B'
},
Herrenausstatter: {
label: 'H'
},
Florist: {
label: 'F'
},
Konditor: {
label: 'K'
},
Sonstiges: {
label: 'S'
}
};
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(48.2048, 16.375),
zoom: 12
});
var infoWindow = new google.maps.InfoWindow;
// Change this depending on the name of your PHP or XML file
downloadUrl('showXML.php', function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName('marker');
Array.prototype.forEach.call(markers, function(markerElem) {
var id = markerElem.getAttribute('id');
var name = markerElem.getAttribute('location');
var address = markerElem.getAttribute('address');
var type = markerElem.getAttribute('type');
var point = new google.maps.LatLng(
parseFloat(markerElem.getAttribute('lat')),
parseFloat(markerElem.getAttribute('lng')));
var infowincontent = document.createElement('div');
var strong = document.createElement('strong');
strong.textContent = name
infowincontent.appendChild(strong);
infowincontent.appendChild(document.createElement('br'));
var text = document.createElement('text');
text.textContent = address
infowincontent.appendChild(text);
var icon = customLabel[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
label: icon.label
});
marker.addListener('click', function() {
infoWindow.setContent(infowincontent);
infoWindow.open(map, marker);
});
});
});
}
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=APIKEY&callback=initMap">
</script>
<? add_shortcode( 'show_google_maps', 'showMap' ); ?>
<? } ?>
Now I do not know how to return the whole map with the markers? How can I solve this? Do I have to create a "main" function where all the other functions are nested? Is that what I want to achieve possible with that piece of code? Thanks for any advice!
BR,
Stefan

How to show dynamically multiple popup in openlayers 3 map

Can anyone tell me how to show all popup of markers in openlayers 3 map. I searched many sites but couldn't get any answer please anyone know about this then help me
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.TileJSON({
url: 'https://api.tiles.mapbox.com/v3/mapbox.geography-class.json?secure',
crossOrigin: 'anonymous'
})
})
],
overlays: [overlay],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([0, 50]),
zoom: 2
})
});
var vectorSource = new ol.source.Vector({
features: [
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([16.37, 48.2])),
name: 'London'
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([-0.13, 51.51])),
name: 'NY'
}),
new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([30.69, 55.21])),
name: 'Paris'
})
]
});
var markers = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
image: new ol.style.Icon({
src: '//openlayers.org/en/v3.12.1/examples/data/icon.png',
anchor: [0.5, 1]
})
})
});
map.addLayer(markers);
function showpopup(){
// For showing popups on Map
var arrayData = [1];
showInfoOnMap(map,arrayData,1);
function showInfoOnMap(map, arrayData, flag) {
var flag = 'show';
var extent = map.getView().calculateExtent(map.getSize());
var id = 0;
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element,
positioning: 'center'
});
map.addOverlay(popup);
if (arrayData != null && arrayData.length > 0) {
arrayData.forEach(function(vectorSource) {
/* logMessage('vectorSource >> ' + vectorSource); */
if (vectorSource != null && markers.getSource().getFeatures() != null && markers.getSource().getFeatures().length > 0) {
markers.getSource().forEachFeatureInExtent(extent, function(feature) {
/* logMessage('vectorSource feature >> ' + feature); */
console.log("vectorSource feature >> " + markers.getSource().getFeatures());
if (flag == 'show') {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
popup.setPosition(coord);
/* var prop;
var vyprop = ""; */
$(element).popover({
'position': 'center',
'placement': 'top',
'template':'<div class="popover"><div class="popover-content"></div></div>',
'html': true,
'content': function() {
var string = [];
var st = feature.U.name;
if (st != null && st.length > 0) {
var arrayLength = 1;
string = "<table>";
string += '<tr><td>' + st + "</table>";
}
return string;
}
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
}
});
}
};
}
I used this code in my file but it show only one popup on all markers please someone tell me how to show all markers popup simultaneously.
I'm not sure exactly what you're trying to show in your popups, but I would probably try this approach. This extends the ol.Overlay class, allowing you to get the map object and attach a listener which you can use to grab the feature that was clicked. Is this what you're trying to accomplish?
function PopupOverlay() {
var element = document.createElement('div');
$(element).popover({
template: '<div class="popover"><div class="popover-content"></div></div>',
placement: 'top',
position: 'center',
html: true
});
ol.Overlay.call(this, {
element: element
});
}
ol.inherits(PopupOverlay, ol.Overlay);
PopupOverlay.prototype.setMap = function (map) {
var self = this;
map.on('singleclick', function (e) {
map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
ol.Overlay.prototype.setPosition.call(self, feature.getGeometry().getCoordinates());
var el = self.getElement();
$(el).data('bs.popover').options.content = function () {
// EDIT THE POPOVER CONTENT
return feature.get('name');
};
$(el).popover('show');
});
});
ol.Overlay.prototype.setMap.call(this, map);
};
Check out this example
So after your comment, I see what you're trying to do now. I would say that you want to take the same basic approach, make a class that overrides ol.Overlay, but this time just loop through all the features, creating an overlay for each feature.
This Updated Example
function PopoverOverlay(feature, map) {
this.feature = feature;
var element = document.createElement('div');
$(element).popover({
template: '<div class="popover"><div class="popover-content"></div></div>',
placement: 'top',
position: 'center',
html: true
});
ol.Overlay.call(this, {
element: element,
map: map
});
};
ol.inherits(PopoverOverlay, ol.Overlay);
PopoverOverlay.prototype.togglePopover = function () {
ol.Overlay.prototype.setPosition.call(this, this.feature.getGeometry().getCoordinates());
var self = this;
var el = this.getElement();
$(el).data('bs.popover').options.content = function () {
// EDIT THE POPOVER CONTENT
return self.feature.get('name');
};
$(el).popover('toggle');
};
// create overlays for each feature
var overlays = (function createOverlays () {
var popupOverlays = [];
vectorSource.getFeatures().forEach(function (feature) {
var overlay = new PopoverOverlay(feature, map);
popupOverlays.push(overlay);
map.addOverlay(overlay);
});
return popupOverlays;
})();
// on click, toggle the popovers
map.on('singleclick', function () {
for(var i in overlays) {
overlays[i].togglePopover();
}
});
Now when you click anywhere on the map, it should call the togglePopover method and toggle the popover on the individual element.

map.setCenter and map.Panto will not shift map

I have tried to change the .onchange function multiple times to change map zoom level and center point. Zoom change takes affect, but the map does not change locations.
Any help would be appreciated. I've removed my api key, but otherwise the map will function on its own.
<script>
function detectBrowser() {
var useragent = navigator.userAgent;
var mapdiv = document.getElementById("map");
if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
mapdiv.style.width = '100%';
mapdiv.style.height = '100%';
} else {
mapdiv.style.width = '600px';
mapdiv.style.height = '800px';
}
}
function initMap() {
var central = {lat: 39.8282, lng: -98.5795};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: central
});
var fops = 'http://coleprojects.000webhostapp.com/sqteam.png';
document.getElementById("FieldTeamMember").onchange = function() {
map.setZoom(8);
alert(this.value)
map.setCenter(new google.maps.LatLng(this.value));
};
A clue in the javascript console:
InvalidValueError: in property lat: not a number
You need to pass a google.maps.LatLng (or google.maps.LatLngLiteral) to the map.setCenter method:
document.getElementById("FieldTeamMember").onchange = function() {
map.setZoom(8);
var coords=this.value.split(',');
var latLng = new google.maps.LatLng(parseFloat(coords[0]), parseFloat(coords[1]));
map.setCenter(latLng);
};

Google Map: Link to the map according to feature type

I have a google Map with markers on a webpage.
Each marker has a unique feature position and type
This is the scenario I would like to put in place:
On another webpage I have static links to different markers of the map.
If you click on one of those links, you are directed to the map in which, one of these markers is centered (and its info window open).
But the markers latitude and longitude might change while the links will never change.
This means, I need the links not to use latitude and longitude info but markers feature type instead (which are remain the same).
How can I do that?
Here is my sample google Map script so far:
<script>
function initMap() {
var mapDiv = document.getElementById('map');
var map = new google.maps.Map(mapDiv, {
center: {lat: 48.85639, lng: 2.33625}, // default centering
zoom: 18,
styles:
[
{featureType: 'poi',stylers: [{ visibility: 'off' }]},
{featureType: 'transit.station',stylers: [{ visibility: "off" }]}
]
});
var features = [
{position: new google.maps.LatLng(48.85659, 2.33555),type: 'markerone'},
{position: new google.maps.LatLng(48.85619, 2.33695),type: 'markertwo'}
];
var icons = {
'markerone': {icon: 'icon_one.png'},
'markertwo': {icon: 'icon_two.png'}
};
var contents= {
'markerone': {text: 'Content 1'},
'markertwo': {text: 'Content 2'}
};
for (var i = 0, feature; feature = features[i]; i++)
{
var marker = new google.maps.Marker({
position: feature.position,
icon: icons[feature.type].icon,
map: map
});
var content = contents[feature.type].text;
var infowindow = new google.maps.InfoWindow()
google.maps.event.addListener(marker,'mouseover', (function(marker,content,infowindow){
return function() {
infowindow.setContent(content);
infowindow.open(map,marker);
};
})(marker,content,infowindow));
google.maps.event.addListener(marker,'mouseout', (function(marker,content,infowindow){
return function() {
infowindow.close(map,marker);
};
})(marker,content,infowindow));
}
}
</script>
In this sample, I have to markers.
One has a feature type of "markerone" and the second is "markertwo".
How can I set my links to redirect and center the map around a specific marker in this kind of fashion:
http://www.mywebsite.com/mymap.php?myvariable=markertwo
Thank you.
First you would have to get the parameters. The example below gets all parameters and put them into an array. There you can search for your certain paramater like "markerType" and check if it's given or not. If not you have to perform a default action, otherwise you can handle the certain markerType like finding the correct marker, setting the map center to it and open the corrosponding infoWindow.
You just have to call the focusMarkerType-method onload of your page.
function getSearchParameters() {
var prmstr = window.location.search.substr(1);
return prmstr != null && prmstr != "" ? transformToAssocArray(prmstr) : {};
}
function transformToAssocArray( prmstr ) {
var params = {};
var prmarr = prmstr.split("&");
for ( var i = 0; i < prmarr.length; i++) {
var tmparr = prmarr[i].split("=");
params[tmparr[0]] = tmparr[1];
}
return params;
}
function focusMarkerType(){
var params = getSearchParameters();
if(params.markerType!=null){
//Handling the certain marker type
var found = false;
for (var i = 0, feature; feature = features[i]; i++) {
if (feature.type == params.markerType) {
found = true;
map.setCenter(feature.position);
//more...
break;
}
}
if (!found) {
console.log("unknown type")
}
}else{
//Handling default behaviour if no marker type is given
}
}

close InfoWindow before open another

I have a problem with InfoWindow. I have an ajax function that retrieves data via JSON, but I can not get close InfoWindow automatically when you open another.
My code is this:
var mapOptions = {
center: new google.maps.LatLng(44.49423583832911, 11.346244544982937),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("mappa_locali"),mapOptions);
$.ajax({
type:'GET',
url:"locali_json.php"+urlz,
success:function(data){
var json = JSON.parse(data);
for (var i=0; i<json.length; i++) {
point = new google.maps.LatLng(json[i].latitudine,json[i].longitudine);
var infowindow = new google.maps.InfoWindow;
infowindow.setContent(''+json[i].nome_locale+'<br>'+json[i].address);
addMarkerz(point,infowindow);
}
}
})
}
function addMarkerz(point,infowindow) {
position: point,
map: map
});
google.maps.event.addListener(marker,'mouseover',infoCallback(infowindow, marker));
markers.push(marker);
infos.push(infowindow);
}
function infoCallback(infowindow, marker) {
return function() {
infowindow.close();
infowindow.open(map, marker);
};
}
Does anyone know where decreased mistake? Or do you have any advice for me?
The suggestion is only create one infowindow (in the global scope), reuse it and change its contents when a marker is clicked, close it if the user clicks on the map.
code snippet (removes the dependency on the AJAX call):
// global variables
var map;
var markers = [];
var infowindow = new google.maps.InfoWindow();
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(44.49423583832911, 11.346244544982937),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("mappa_locali"), mapOptions);
var json = JSON.parse(data);
for (var i = 0; i < json.length; i++) {
point = new google.maps.LatLng(json[i].latitudine, json[i].longitudine);
var infowindowHtml = '' + json[i].nome_locale + '<br>' + json[i].address;
addMarkerz(point, infowindowHtml);
}
}
function addMarkerz(point, infowindowHtml) {
var marker = new google.maps.Marker({
position: point,
map: map
});
google.maps.event.addListener(marker, 'mouseover', infoCallback(infowindowHtml, marker));
markers.push(marker);
}
function infoCallback(infowindowHtml, marker) {
return function() {
infowindow.close();
// update the content of the infowindow before opening it
infowindow.setContent(infowindowHtml)
infowindow.open(map, marker);
};
}
var data = JSON.stringify([{
latitudine: 44.494887,
longitudine: 11.3426163,
id_locale: "0",
nome_locale: "Bologna",
address: "Bologna, Italy"
}, {
latitudine: 44.4946615,
longitudine: 11.314634999999953,
id_locale: "0",
nome_locale: "Quartiere Saragozza",
address: "Quartiere Saragozza, Bologna, Italy"
}]);
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#mappa_locali {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="mappa_locali"></div>
function infoCallback(infowindow, marker) {
return function() {
infowindow.close();
infowindow.open(map, marker);
};
}
should be changed to
function infoCallback(infowindow, marker) {
return function() {
//Close active window if exists
if (activeWindow != null) {
activeWindow.close();
}
//Open new window
infowindow.open(map,marker);
//Store new window in global variable
activeWindow = infowindow;
};
}
and declare activeWindow as a global variable in your .js file as var activeWindow.
I think I have a simple solution. I just save the last open mark. On the next click first of all I close the last mark.
var markers = [];
var infowindows = [];
function addMarkes(facilityID) {
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < variants.length; i++) {
var v = variants[i];
var position = new google.maps.LatLng(v.Lat, v.Long);
bounds.extend(position);
markers[i] = new google.maps.Marker({
position: position,
title: v.Title,
map: map,
animation: google.maps.Animation.DROP,
icon: v.Icon,
infoWindowIndex: i //synchronize with infoWindows
});
var localContent = '<div><span class="address">' + v.Address + '</span></div>';
infowindows[i] = new google.maps.InfoWindow({
content: localContent
});
//Just for multiple marks.
if (variants.length > 0) {
var lastOpen = -1; //Save the last open mark
google.maps.event.addListener(markers[i], 'click', function (innerKey) {
return function () {
//Close the last mark.
if (lastOpen > -1) {
infowindows[lastOpen].close();
}
infowindows[innerKey].open(map, markers[innerKey]);
lastOpen = innerKey;
}
}(i));
}
}
map.fitBounds(bounds);
}

Resources