Long time reader/ first time poster here, with a question I suspect will be easy to answer but help me out no end.
I simply want to i) retrieve the user's location, ii) display an icon at this location, and iii) Have a button labelled 'Find Me' that pans the map to this location.
I have i) and ii) working, but although I have other buttons that pan to a particular location, this one doesn't seem to work:
var viewportHeight = $(window).height();
var mapHeight = viewportHeight - 93;
var map;
var union = new google.maps.LatLng(53.806828, -1.555999);
var userLocation;
var userIcon = 'userIcon.png';
var parkinson = new google.maps.LatLng(53.808, -1.553);
var unionDescription = '<div id="content">' + '<div id="siteNotice">' + '</div>' + '<h2 id="firstHeading" class="firstHeading">Your Union</h2>' + '<div id="bodyContent">' + '<p>Heres a bit about us</p>' + '</div>' + '</div>';
//Try and get the user's location
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var userLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
$('#map_canvas').gmap('addMarker', {
'position': userLocation,
'bounds': false,
'icon': userIcon
});
});
};
//initialise the map
$(function () {
$('#map_canvas').gmap({
'center': union,
'zoom': 16,
'mapTypeId': google.maps.MapTypeId.ROADMAP,
'styles': campusStyles,
'minZoom': 15,
'maxZoom': 17
}).bind('init', function (ev, map) {
$('#map_canvas').gmap('addMarker', {
'position': parkinson,
'bounds': false
}).click(function () {
$('#map_canvas').gmap('openInfoWindow', {
'content': 'Hello World!'
}, this);
});
$('#map_canvas').gmap('addMarker', {
'position': union,
'bounds': true
}).click(function () {
$('#map_canvas').gmap('openInfoWindow', {
'content': unionDescription
}, this);
});
$('#map_canvas').height(mapHeight);
google.maps.event.trigger(map, 'resize');
$('#unionButton').click(function () {
map.panTo(union);
});
$('#findMe').click(function () {
map.panTo(userLocation);
});
$('#map_canvas').height(mapHeight);
});
});
Thing I'm actually working on here: http://jdp.org.uk/tests/mapstest4.html
I don't know why but my navigator geolocation is not working, so I just bypassed that requirement and hard-coded a user LatLng. What worked for me was cutting and pasting the whole block if(navigator.geolocaton) to directly below the block with the line $('#unionButton').click(function(){map.panTo(union);});. It appears that map was not yet defined where you had the geolocation code.
From my testing, smooth panning only happens when the current position is close to the target. http://jsfiddle.net/EejRt/
I have:
$('#map_canvas').height(mapHeight);
google.maps.event.trigger(map, 'resize');
$('#unionButton').click(function(){map.panTo(union);});
$('#map_canvas').height(mapHeight);
//if (navigator.geolocation) {
// navigator.geolocation.getCurrentPosition(function(position) {
// var userLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
var userLocation = new google.maps.LatLng(53.8018,-1.553);
$('#map_canvas').gmap('addMarker', {'position': userLocation, 'bounds': false, 'icon' : userIcon });
$('#findMe').click(function(){map.panTo(userLocation)});
// });
// };
Related
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!
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
I am using Gridstack with Knockout.js. I am using http://troolee.github.io/gridstack.js/demo/knockout.html to create Gridstack widgets. I added a Google map in one of these widgets. The map appears with a scroll bar. Also, I need to have some kind of heading, as it is in its present state. The main problem is that the dimension of the map is fixed and when I resize the widget, the map does not fit in the widget automatically. Here is my full code:
ko.components.register('dashboard-grid', {
viewModel: {
createViewModel: function (controller, componentInfo) {
var ViewModel = function (controller, componentInfo) {
var grid = null;
this.widgets = controller.widgets;
this.id = controller.id;
this.afterAddWidget = function (items) {
if (grid == null) {
grid = $(componentInfo.element).find('.grid-stack').gridstack({
auto: false,
animate: true
}).data('gridstack');
}
var item = _.find(items, function (i) { return i.nodeType == 1 });
grid.addWidget(item);
ko.utils.domNodeDisposal.addDisposeCallback(item, function () {
grid.removeWidget(item);
});
};
};
return new ViewModel(controller, componentInfo);
}
},
template:
[
'<div class="grid-stack" data-bind="foreach: {data: widgets, afterRender: afterAddWidget}">',
' <div class="grid-stack-item" data-bind="attr: {\'data-gs-x\': $data.x, \'data-gs-y\': $data.y, \'data-gs-width\': $data.width, \'data-gs-height\': $data.height, \'data-gs-auto-position\': $data.auto_position}">',
' <div class="grid-stack-item-content" >',
' <header style="background-color: green;"> ',
' <button data-bind="click: $root.deleteWidget">Delete me</button><br>',
' <label><strong data-bind="text: $root.ids"></strong></label>',
' </header>',
' <div data-bind="attr: {id: $root.ids}">',
' </div>',
' </div>',
' </div>',
'</div> '
].join('')
});
$(function () {
var ids;
var Controller = function () {
var self = this;
this.widgets = ko.observableArray([]);
this.id = ko.observable("google-map");
this.ids = "";
this.addNewWidget = function () {
this.ids = this.id(); // this.ids is used to give id to div elements
this.widgets.push({
x: 0,
y: 0,
width:4,
height:5,
auto_position: true,
});
// calling method to draw map
createWidget(this.ids);
return false;
};
this.deleteWidget = function (item) {
self.widgets.remove(item);
return false;
};
};
ko.applyBindings(new Controller());
});
function createWidget(id) {
var dataArray, latitude, longitude, speed;
// Load the Visualization API and the corechart package.
try {
google.charts.load('current', {'packages':['map', 'gauge']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
}
catch ( err ) {
//console.log(err);
}
function drawChart() {
latitude = Number(12.93213);
longitude = Number(77.695185);
var mapOptions = {
showTooltip: true,
showInfoWindow: true,
zoomLevel: 16, // range: 0-21 for "roadmap" map type
mapType: 'roadmap',
enableScrollWheel: true,
draggable: false,
};
var coordinates = "Latitude : " + latitude + "\nLongitude : "+ longitude;
var mapData = google.visualization.arrayToDataTable([
['Lat', 'Long', 'Name'],
[latitude, longitude, coordinates]
] );
try {
//var chart = new google.visualization.Gauge(document.getElementById('gauge'));
var map = new google.visualization.Map(document.getElementById(id));
map.draw(mapData, mapOptions);
}
catch (err) {
console.log(err);
}
} // drawChart() ends here
} // createWidgets() ends here
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.
I'm trying to create multiple infowindow for multiple marker, But it seem like just refer to last infowindow
This is my code (in for loop, _lat and _long is unique value):
marker.addListener('click', function(){
//markerInfoWindow.close();
markerInfoWindow.setContent('Unsave place', true);
markerInfoWindow.open(map, this);
});
marker.setMap(map);
I tested with marker, marker show correctly but all of them link to the last infoWindow.
How can I make new infoWindow for each Marker?
Update:
This is fully my function after update:
function getListPosition(listMarkers, map){
db.transaction(function(tx){
tx.executeSql('SELECT * FROM Position', [], function(tx, rs) {
var numberOfItems = rs.rows.length;
var markerInfoWindow = new google.maps.InfoWindow();
var marker;
for (var i = 0; i < numberOfItems; i++) {
var _lat = rs.rows.item(i).Lat;
var _long = rs.rows.item(i).Long;
marker = new google.maps.Marker({
position: {lat: _lat , lng: _long}
});
listMarkers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker) {
return function() {
markerInfoWindow.setContent('Unsave place', true);
markerInfoWindow.open(map, marker);
}
})(marker));
// marker.addListener('click', function(){
// //markerInfoWindow.close();
// markerInfoWindow.setContent('Unsave place', true);
// markerInfoWindow.open(map, this);
// });
marker.setMap(map);
// Set map center to the last marker
if (i == numberOfItems - 1){
map.setCenter({lat: _lat, lng: _long});
}
}
});
}, function(err){
console.log('Error when get list position. Error code: ' + err.code);
});
}
You need function closure on the loop variables that are needed when the click listener function runs. In your case _lat and _lng. It would probably be simplest to just get those from the marker (this) though:
google.maps.event.addListener(marker, 'click', function(evt) {
markerInfoWindow.setContent('Unsave place', true);
markerInfoWindow.open(map, this);
});
(not tested)