I'm working on a project where I'd like to show the choosen event on google maps with some additional information. (ex. all gas stations radius 2km).
Google doesn't allow a nearby search with multiple types.
Restricts the results to places matching the specified type. Only one type may be specified (if more than one type is provided, all types following the first entry are ignored).
So for now I'd like to change the type (ex. gas_station or store) if I click to a custom button I added.
(used the google document example)
Screenshot: http://imgur.com/qYwLuw4
Question:
Which is the best way to change the type and refresh the map with the new information?
I'd like to present you our solution.
We wrote a clear() and a showType() function, which will erase all markers and let the right ones appear on click. By the way we give the button a state class called "selected" for CSS styling.
We didn't find a solution to show both (washstation AND fuelstation).
<script type="text/javascript">
var map;
var infowindow;
var service;
var eventLocation = {lat: <?= $arrCoordinates['latitude']?>, lng: <?= $arrCoordinates['longitude']?>};
var markers = [];
var wash = document.getElementById('wash'); //washbutton
var fuel = document.getElementById('fuel'); //fuelstation button
function initMap() {
map = new google.maps.Map(document.getElementById('eventmap'), {
center: eventLocation,
zoom: 13,
});
infowindow = new google.maps.InfoWindow();
service = new google.maps.places.PlacesService(map);
showType('gas_station');
fuel.classList.add("selected");
typeControl(map);
}
// Type control function
function typeControl ( map ) {
google.maps.event.addDomListener(fuel, 'click', function() {
wash.classList.remove("selected");
fuel.classList.remove("selected");
clear()
showType('gas_station')
this.classList.add("selected");
});
google.maps.event.addDomListener(wash, 'click', function() {
wash.classList.remove("selected");
fuel.classList.remove("selected");
clear()
showType('car_wash')
this.classList.add("selected");
});
}
function showType(type) {
service.nearbySearch({
location: eventLocation,
radius: 10000,
type: [type]
}, callback);
}
function clear() {
markers.forEach(marker => marker.setMap(null));
markers = [];
}
function callback(results, status) {
clear()
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
createTuningEventMarker();
}
}
function createTuningEventMarker(place) {
var eventLocation = {lat: <?= $arrCoordinates['latitude']?>, lng: <?= $arrCoordinates['longitude']?>};
var eventIcon = {
url: 'https://www.foo.lol/img/icons/pin.svg',
// This marker is 20 pixels wide by 32 pixels high.
scaledSize: new google.maps.Size(60, 60),
// The origin for this image is (0, 0).
origin: new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at (0, 32).
anchor: new google.maps.Point(30,60)
};
var marker = new google.maps.Marker({
map: map,
icon:eventIcon,
position: eventLocation
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<?= $event['name']?>');
infowindow.open(map, this);
});
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name + "<br>Adress: " + place.vicinity);
infowindow.open(map, this);
});
}
</script>
Related
Hi I am using Google maps alongside algolia where I have an index 'locations' with 'lat' and 'lng'.
I am getting user location and watching position, I am also displaying markers from database based on lng and lat however I want to add a bit to it:
So I have followed that link:
https://www.algolia.com/doc/guides/geo-search/geo-search-overview/
And came up with:
#extends('master') #section('title', 'Live Oldham')
#section('extrafiles')
<script type="text/javascript" src="https://maps.google.com/maps/api/js?v=3&key=AIzaSyAirYgs4Xnt9QabG9v56jsIcCNfNZazq50&language=en"></script>
<script type="text/javascript" src="{!! asset('js/homesearch.js') !!}"></script>
#endsection
#section('content')
<div id="map_canvas" style="height:600px;"></div>
#endsection
and js:
$(document).ready(function() {
var map;
function initializeMap(){
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 19,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
function locError(error) {
// the current position could not be located
alert("The current position could not be found!");
}
function setCurrentPosition(position) {
currentPositionMarker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude
),
title: "Current Position"
});
map.panTo(new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude
));
}
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
console.log(latitude);
console.log(longitude);
function displayAndWatch(position) {
// set current position
setCurrentPosition(position);
// watch position
watchCurrentPosition(position);
console.log(position);
}
function watchCurrentPosition(position) {
var positionTimer = navigator.geolocation.watchPosition(
function (position) {
setMarkerPosition(
currentPositionMarker,
position,
)
});
}
function setMarkerPosition(marker, position) {
marker.setPosition(
new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude)
);
}
function initLocationProcedure() {
initializeMap();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(displayAndWatch, locError);
}else{
alert("Your browser does not support the Geolocation API");
}
}
$(document).ready(function() {
initLocationProcedure();
});
var APPLICATION_ID = '75RQSC1OHE';
var SEARCH_ONLY_API_KEY = 'f2f1e9bba4d7390fc61523a04685cf12';
var INDEX_NAME = 'locations';
var PARAMS = { hitsPerPage: 100 };
// Client + Helper initialization
var algolia = algoliasearch(APPLICATION_ID, SEARCH_ONLY_API_KEY);
var algoliaHelper = algoliasearchHelper(algolia, INDEX_NAME, PARAMS);
// Map initialization
var markers = [];
//alert("heelo");
var fitMapToMarkersAutomatically = true;
algoliaHelper.on('result', function(content) {
renderHits(content);
var i;
// Add the markers to the map
for (i = 0; i < content.hits.length; ++i) {
var hit = content.hits[i];
console.log(hit)
var marker = new google.maps.Marker({
position: {lat: hit.longitude, lng: hit.latitude},
map: map,
title: hit.slug
});
markers.push(marker);
}
// Automatically fit the map zoom and position to see the markers
if (fitMapToMarkersAutomatically) {
var mapBounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
mapBounds.extend(markers[i].getPosition());
}
map.fitBounds(mapBounds);
}
});
function renderHits(content) {
$('#container').html(JSON.stringify(content, null, 2));
}
algoliaHelper.setQueryParameter('aroundRadius', 5000).search(); // 5km Radius
});
However there are few problems with this that I don't know how to tackle:
When user is moving, it doesn't center the map on the marker.
At this moment marker jumps between location when user moves, I would like for the marker to dynamically move on the map when user moves.
I want to use algolia to dynamically set markers, so I want to show markers with 5km radius from user location, and dynamically add or remove markers that are outside it.
I can't help you much with those questions since it's mostly about how to use GMap JS lib and I'm not experienced with it. However, something else catched my eyes:
var marker = new google.maps.Marker({
position: {lat: hit.longitude, lng: hit.latitude},
map: map,
title: hit.slug
});
You should put your coordinates in the _geoloc field in order to be able to use the geo-search features. It looks like this:
_geoloc: {
lat: 40.639751,
lng: -73.778925
}
I want create a click event using angular js google map api.
On click on the marker I want to call a function without opening the info window.
How can I do this ?
$scope.map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: { lat: parseFloat(Center_lat) , lng: parseFloat(center_lang) }
});
$scope.infowindow = new google.maps.InfoWindow({
// content: ''
});
angular.forEach($scope.panoramas, function(value, index) {
var latLang = $scope.panoramas[index].project_latLng ;
// console.log(latLang)
var LatLngArr = latLang.split(",");
var lat = LatLngArr[0];
var lang = LatLngArr[1];
console.log("lat " ,lat);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(lat), parseFloat(lang)),
map: $scope.map,
icon:"images/map-circle.png",
draggable:true,
label: {
color: 'black',
fontWeight: 'bold',
text: $scope.panoramas[index].panoId,
},
title: $scope.panoramas[index].panoId
});
var content = '<a ng-click="ShowCenterPano(' + index + ')" class="btn btn-default">View details</a>';
var compiledContent = $compile(content)($scope)
google.maps.event.addListener(marker, 'click', (function(marker, content, scope) {
return function() {
scope.infowindow.setContent(content);
scope.infowindow.open(scope.map, marker);
};
})(marker, compiledContent[0], $scope));
$scope.ShowCenterPano = function(index) {
// alert(JSON.stringify($scope.panoramas[index]));
}
Here Info window is opening. How can I remove the info window and directly call the ShowCenterPano() function.
Everything you want to happen when you click on the marker is inside the listener.
I think you are making your code needlessly complicated. Just put a listener on your marker marker.addListener('click', function() {}); and in this function you run ShowCenterPano()
And the reason the infowindow is opening is because you ask it to open with this line of code scope.infowindow.open(scope.map, marker);
I have been playing around with Google Maps, and would like to center on a marker and open the appropriate infoWindow when I click on an element outside the map.
For example I have;
<div id="map"></div>
Store A
Opening Hours: 10-10
Store B
Opening Hours: 10-4
Store C
Opening Hours: 9-9
Store D.
Opening Hours: 8-9
I would like it to work, when I click on one of the stores in the list (outside of the map), it call the appropriate marker, centres on it and opens the attached infoWindow.
The infoWindow is working on marker click.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 11,
center: {
lat: -33.800426,
lng: 142.038494
}
});
setMarkers(map);
}
// Data for the markers consisting of a name, a LatLng and a zIndex for the
// order in which these markers should display on top of each other.
var stores = [
['A', -33.771624, 142.888128, 1],
['B', -33.843956, 142.994875, 2],
['C', -33.818086, 142.995699, 3],
['C', -33.812697, 143.229200, 4],
];
function setMarkers(map) {
// Adds markers to the map.
for (var i = 0; i < stores.length; ++i) {
var store = stores[i];
const marker = new google.maps.Marker({
position: {
lat: store[1],
lng: store[2]
},
map: map,
animation: google.maps.Animation.DROP,
title: store[0],
zIndex: store[3],
});
attachStoreTitle(marker);
}
}
// Attaches an info window to a marker with the provided message. When the
// marker is clicked, the info window will open with message.
function attachStoreTitle(marker) {
var infowindow = new google.maps.InfoWindow({
content: marker.title
});
marker.addListener('click', function() {
infowindow.open(marker.get('map'), marker);
});
}
initMap()
Completed fiddle at https://jsfiddle.net/00e58pba/8/
Attach event listener to markers and then open correct infoWindow -
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
// Close all other infoboxes
for (var j = 0; j < markers.length; j++) {
markers[j].infobox.close(map);
}
// Open correct info box
markers[i].infobox.open(map, markers[i]);
}
})(marker, i));
If I've understood what you're asking, I think you should be able to do this:
marker.addListener('click', function() {
infowindow.open(marker.get('map'), marker);
marker.get('map').setCenter(this.getPosition());
});
I am trying to create listeners for some map markers. I can create the markers and they are on the map but, no matter which marker I click on it tells me "Uncaught TypeError: Cannot call method 'open' of undefined" . When I break at the open code it is showing markers[46] which is one more that the highest index. And it doesnt matter which marker I click on its always the same index.
EDIT: I edited the code and pasted all of it. No errors, but nothing happens when I click a marker. I am looking in Chrome and it looks like there isnt a event handler registered
<script>
var map;
var nav = [];
$(document).ready(function () {
//initialise a map
init();
var infowindow = new google.maps.InfoWindow({});
$.get("xxxxxx.kml", function (data) {
html = "";
//loop through placemarks tags
i = 1;
$(data).find("Placemark").each(function (index, value) {
//get coordinates and place name
coords = $(this).find("coordinates").text();
contentString = $(this).find("description").text();
var partsOfStr = coords.split(',');
var lat = parseFloat(partsOfStr[0]);
var lng = parseFloat(partsOfStr[1]);
var myLatLng = new google.maps.LatLng(lng, lat);
place = $(this).find("name").text();
createMarker(myLatLng, place, contentString, i)
//store as JSON
c = coords.split(",")
nav.push({
"place": place,
"lat": c[0],
"lng": c[1]
})
//output as a navigation
html += "<li>" + place + "</li>";
i++;
});
//output as a navigation
$(".navigation").append(html);
//bind clicks on your navigation to scroll to a placemark
$(".navigation li").bind("click", function () {
panToPoint = new google.maps.LatLng(nav[$(this).index()].lng, nav[$(this).index()].lat)
map.panTo(panToPoint);
})
});
markers = [];
function createMarker(myLatLng, title, contentString, i) {
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: title
});
google.maps.event.addListener(markers, 'click', function () {
infoWindow.setContent(contentString);
infowindow.open(map, markers[i]);
});
markers[i] = marker;
return marker
}
function init() {
//google.maps.event.addDomListener(window, 'init', Initialize);
var latlng = new google.maps.LatLng(39.047050, -77.131409);
var myOptions = {
zoom: 4,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
}
})
This is almost a FAQ. When your loop ends, the value of i is 46 (based on your statement). There is no marker 46, so all the click listeners fail. It can be solved with function closure (a createMarker function which holds the association between the marker and the infowindow contents).
Something like this in your example (not tested), call it from inside your marker creation loop, requires a global markers array, but doesn't require the global infowindow array:
//global markers array
markers = [];
// global infowindow
var infowindow = new google.maps.InfoWindow({});
// createMarker function
function createMarker(myLatLng, title, contentString, i)
{
var marker = new google.maps.Marker({
position: myLatlng ,
map: map,
title:title
});
google.maps.event.addListener(markers, 'click', function() {
infoWindow.setContent(contentString);
infowindow.open(map,markers[i]);
});
markers[i] = marker;
return marker
}
I have a map with multiple polylines and would like to open a line-specific-infowindow when clicking the line.
So far my code only shows the content of the last iteration.
I found two very nice examples of what I want but after hours of trying I am still no further.
Example 1: http://srsz750.appspot.com/api3/polylines-multiple.html
Example 2: http://www.geocodezip.com/v3_GenericMapBrowser.asp?filename=flights090414.xml
So your are my last shot :-S
Here is my code that shows only the content of the last iteration:
for (var i = 0; i < locations.length; i++) {
var route = locations[i]; // locations is an array of route-arrays.
//route is an array with details. route[0] contains the description.
var imageStart = 'img/rijder.png';
var polyOptions = {
strokeColor: '#0000FF',
strokeOpacity: 1.0,
strokeWeight: 3
}
poly = new google.maps.Polyline(polyOptions, info);
var path = poly.getPath();
//line text
var info = route[0];
google.maps.event.addListener(poly, 'click', function(event) {
infowindow.setContent(info);
infowindow.position = event.latLng;
infowindow.open(map);
});
//startmarker
var startLatLng = new google.maps.LatLng(route[1], route[2]);
var smarker = new google.maps.Marker({
position: startLatLng,
map: map,
icon: imageStart,
title: route[7],
html: route[0]
});
path.push(startLatLng);
//starttext
google.maps.event.addListener(smarker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
//endmarker
var endLatLng = new google.maps.LatLng(route[4], route[5]);
var emarker = new google.maps.Marker({
position: endLatLng,
map: map,
icon: imageEnd,
title: route[8],
html: route[3]
});
path.push(endLatLng);
//endtext
google.maps.event.addListener(emarker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
//close line and put on the map
poly.setMap(map);
}
}
And here is the code I would expect to work but all lines disappeared (only the relevant code, I also added a mouseover function):
//line text
google.maps.event.addListener(poly, 'click', (function(event,index){
return function(){
var routeinfw = locations[index];
var inf = routeinfw[0];
infowindow.setContent(inf);
infowindow.position = mouselocation;
infowindow.open(map);
};
})(event,i));
//starticon
Just like in the example you posted, create a function to create the click events listeners and call it from inside the locations loop:
function createInfoWindow(poly,content) {
google.maps.event.addListener(poly, 'click', function(event) {
infowindow.content = content;
infowindow.position = event.latLng;
infowindow.open(map);
});
}
And you can call this at the end of the loop:
createInfoWindow(poly,info);