Check streetview exists when displaying it in infowindow - google-maps-api-3

following this example http://www.keypointpartners.com/test/mab/fromxml1.html and Google Maps API v3 documentation (https://developers.google.com/maps/documentation/javascript/streetview) I've put together a map that loads markers from an XML file and display a tabbed infowindow for each loaded marker. Wishing to check if a location actually has a streetview available, I've modified my createMarker to this:
function createMarker(latlng, name, html) {
//var contentString = html;
var contentString = [
'',
'',
name,
'',
'',
'Località',
'Struttura',
'Voli',
//'Opzioni',
'Streetview',
'',
html,
''
].join('');
// Create a marker
var marker = new google.maps.Marker({
position: latlng,
title: name,
map: inc_map
});
// Add a listener to the marker to populate and open the infowindow
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(inc_map, marker);
google.maps.event.addListener(infowindow, 'domready', function() {
inc_sv.getPanoramaByLocation(marker.position, 50, processSVData);
//console.log("Adding tabs");
$('#tabs').tabs();
});
});
Tha callback function used by getPanoramaByLocation is as follows:
function processSVData(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
google.maps.event.addListener(infowindow, 'domready', function() {
$('#stv-lnk').click(function() {
var panoramaOptions = {
position: data.location.latLng,
visible: true,
linksControl: false,
panControl: false,
addressControl: false,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
enableCloseButton: false
};
var panorama = new google.maps.StreetViewPanorama(document.getElementById("stvpano"), panoramaOptions);
inc_map.setStreetView(panorama);
});
});
} else {
google.maps.event.addListener(infowindow, 'domready', function() {
$('#stv-lnk').click(function() {});
document.getElementById("stvpano").innerHTML = "Streetview non è disponibile per questo luogo"
});
}
}
Now, what happens is that first streetview tab doesn't show anything, while next clicked streetview tabs show previous tab's streetview. Comparing to the abovementioned example from API docs, I build a separate StreetViewPanorama object for each tab (while the example uses a global panorama var to hold it).
Is this my mistake? Or...?
Link at the actual page: http://turom-mice.it/condorincentive/incentive.html
Any help/suggestion greatly appreciated!
Cheers,
rash*
EDIT: ok, I solved one of the problems. I was nesting too many eventListener: I removed the ones inside function processSVData and each infowindow nows show the correct streetview. The code now looks like this:
function processSVData(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
$('#stv-lnk').click(function() {
var panoramaOptions = {
position: data.location.latLng,
visible: true,
linksControl: false,
panControl: false,
addressControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
enableCloseButton: false
};
var panorama = new google.maps.StreetViewPanorama(document.getElementById("stvpano"), panoramaOptions);
inc_map.setStreetView(panorama);
});
} else {
$('#stv-lnk').click(function() {
inc_map.setStreetView(null);
document.getElementById("stvpano").innerHTML = "Streetview non è disponibile per questo luogo"
});
}
}
Now, the problem is that the 'else' branch seems doing nothing: when a location has no streetview available, you see last shown streetview, no matter I've set it to null and put some warning text inside the div (I should show a link to a substitute gallery page though). question is: is this correct? Or...?
As usual, any help/hint/suggestion...
Ciao,
rash*
EDIT 2: ok, solved completely. The else branch didn't manage the click event, so putting it back in place solved. The code just above has been edited to reflect the solution.
Thanks anyway, waiting for an answer made me re-think the whole thing. Hope this could be of some help to anybody.
rash*

Related

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
}
}

How to Add osm Coordinates to my Collection in meteor

I am working on a simple map on a dashboard that registers click events and save the locations into a collection and also creates a marker on the location clicked. However, only the locations clicked get saved and the markers do not show up. Here is my code below
Template.osm.onRendered(function(){
var map = L.map('osm-container', {
center: [6.54, 3.33],
zoom: 13
});
var markers = {};
var id;
L.tileLayer('http://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Imagery from MapBox — Map data © OpenStreetMap',
subdomains: 'abcd',
id: 'REMOVED',
accessToken: 'REMOVED'
}).addTo(map);
var coordinates = {};
map.on('click', function(event) {
var randm = Math.ceil(10000*Math.random());
var entry = Coordinates.insert({
lat: event.latlng.lat,
lng: event.latlng.lng,
seq: randm });
id = entry;
});
Coordinates.find().observe({
added: function (document) {
L.marker({ lat: Coordinates.find({_id:id},{lat:1, _id:0}),
lng: Coordinates.find({_id:id},{lng:1,_id:0}) },{
clickable : true,
draggable: true,
keyboard: true,
riseOnHover: true
}).addTo(map);
map.on('dragend', function(event) {
todo
});
// markers[id] = mark;
},
changed: function(newDocument, oldDocument) {
// todo;
},
removed: function (oldDocument) {
// todo
}
});
});
Please can anyone help
There seem to be multiple things wrong, but one thing for sure is that you are not actually setting the lat/lng for the markers (they are both "1" in your code). Also, you don't need to find there once more. The document is already given to you in whole, so you can just take the fields you need:
Coordinates.find().observe({
added: function (document) {
L.marker({ lat: document.lat,
lng: document.lng, }, {
...

Google map resize not solving partial display issue within a modal dialogue

I known this question has been raised and answered many times but I can't seem to make the suggested solutions work for me...
I'm displaying a google map within a simplemodal dialogue.
Outside the modal dialogue the map displays correctly.
However, once inside a modal wrapper only part of the map is shown on the first iteration (see below).
The solution would appear to involve binding a 'resize' event to the map but it isn't working for me...
First iteration:
On opening the modal for the first iteration, my map displays with the partial section displaced over to the top RHS and overlaid on the full map.
On closing the first dialogue the screen returns to it's initial state.
Second and subsequent iterations:
On subsequent iterations the map displays correctly but on closing the background color of the map canvas is visible.
HTML:
<body>
<button class="modalMap">With Modal </button>
<button class="nonModalMap">Without Modal </button>
<div id="mapCanvas"></div>
</body>
CSS:
#simplemodal-overlay {background-color:#000;}
#simplemodal-container {color:#999; background-color:#fff;}
#simplemodal-container a{color:#ddd;}
.modalMap:hover,.nonModalMap:hover {
cursor:pointer;
}
#mapCanvas {
position:relative;
width:480px;height:300px;
}
JS:
$(document).ready(function(){
var myMap;
$('.modalMap').click(function(){
buildMap();
$('#mapCanvas').modal(
{onOpen:function(dialog){
dialog.overlay.fadeIn('fast',function(){
dialog.data.hide();dialog.container.fadeIn('fast',function(){
dialog.data.slideDown('fast');
});
});
}
,onClose:function(dialog){
dialog.data.fadeOut('fast',function(){
dialog.container.hide('fast',function(){
dialog.overlay.slideUp('fast',function(){
$.modal.close();
});
});
});
}
});
});
/* But without the modal the map displays correctly... */
$('.nonModalMap').click(function(){
buildMap();
});
});
function buildMap() {
var kpl = {
Place: function (data, map) {
var self = this;
this.data = data;
var coords = data.geo_coords.split(',');
this.position = new google.maps.LatLng(coords[0], coords[1]);
this.marker = new google.maps.Marker({
position: this.position,
map: map
});
google.maps.event.addListener(this.marker, 'click', function() {
if (self.data.url) {
window.location.href = self.data.url
}
});
},
MapManager: function (div, data) {
this.map = new google.maps.Map(div, {
zoom: 15,
center: new google.maps.LatLng(53.818298, -1.573263),
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false,
backgroundColor: '#cccccc',
streetViewControl: false,
navigationControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
});
saveCenter = this.map.center;
this.places = [];
for (var i in data) {
if (data.hasOwnProperty(i)) {
this.places.push(new kpl.Place(data[i], this.map));
}
}
}
};
myMap = new kpl.MapManager($('#mapCanvas').get(0), [{
url: "mailto:info#????.com",
geo_coords: "53.818298, -1.573263",
name: "Kensington Property LS6"
}]);
}
/* plus the simplemodal library... */
I've recreated the code in jsfiddle - http://jsfiddle.net/redApples/j23ue0n1/32/
Can anybody rescue my sanity...?

MarkerClusterer & jQuery UI Map: clusters not showing

I am using the jquery-ui-map plugin together with markerclusterer.
Markers are loaded from an external JSON file. This works great to add the markers and content for each info window. No problems so far.
jQuery, jQuery UI Map and MarkerClusterer scripts are properly referenced in my document. However, I can't seem to cluster the markers.
Here my script to show the map. Have I overseen something?
$('#map_canvas').gmap().bind('init', function(event, map) {
$.getJSON( MY_JSON_URL, function(data) {
$.each( data.posts, function(i, marker) {
$('#map_canvas').gmap('addMarker', {
'position': new google.maps.LatLng(marker.custom_fields._cmb_tatort_map_latitude, marker.custom_fields._cmb_tatort_map_longitude)
}).click(function() {
$('#map_canvas').gmap('openInfoWindow', {
//some content here
}, this );
});
});
});
$('#map_canvas').gmap('set', 'MarkerClusterer', new MarkerClusterer($('#map_canvas').gmap('get', 'map'), $('#map_canvas').gmap('get', 'markers')));
});
You need to create the marker clusterer after the markers have been added to the map, not before.
$('#map_canvas').gmap().bind('init', function(event, map) {
$.getJSON( MY_JSON_URL, function(data) {
$.each( data.posts, function(i, marker) {
$('#map_canvas').gmap('addMarker', {
'position': new google.maps.LatLng(marker.custom_fields._cmb_tatort_map_latitude, marker.custom_fields._cmb_tatort_map_longitude)
}).click(function() {
$('#map_canvas').gmap('openInfoWindow', {
//some content here
}, this );
});
});
$('#map_canvas').gmap('set', 'MarkerClusterer', new MarkerClusterer($('#map_canvas').gmap('get', 'map'), $('#map_canvas').gmap('get', 'markers')));
});
});

Capture Coordinates in Google Map on User Click

I'm using this code to capture the co-ordinates when user clicks on the map by using below event listener:
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
However this function doesn't get called when user click on already marked location in Map.
Meaning this function is not called for points where mouse pointer changes to hand icon on Google Map.
Need help on capturing these kind of locations.
You should add the click listener on marker will give you the position of marker.
//Add listener
google.maps.event.addListener(marker, "click", function (event) {
var latitude = event.latLng.lat();
var longitude = event.latLng.lng();
console.log( latitude + ', ' + longitude );
}); //end addListener
Edit:
You need something like this
//Add listener
google.maps.event.addListener(marker, "click", function (event) {
var latitude = event.latLng.lat();
var longitude = event.latLng.lng();
console.log( latitude + ', ' + longitude );
radius = new google.maps.Circle({map: map,
radius: 100,
center: event.latLng,
fillColor: '#777',
fillOpacity: 0.1,
strokeColor: '#AA0000',
strokeOpacity: 0.8,
strokeWeight: 2,
draggable: true, // Dragable
editable: true // Resizable
});
// Center of map
map.panTo(new google.maps.LatLng(latitude,longitude));
}); //end addListener
Another solution is to place a polygon over the map, same size as the map rectangle, and collect this rectangles clicks.
function initialize() {
var mapDiv = document.getElementById('map-canvas');
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, 'bounds_changed', function() {
var lat1 = 37.41463623043073;
var lat2 = 37.46915383933881;
var lng1 = -122.1848153442383;
var lng2 = -122.09898465576174;
var rectangle = new google.maps.Polygon({
paths : [
new google.maps.LatLng(lat1, lng1),
new google.maps.LatLng(lat2, lng1),
new google.maps.LatLng(lat2, lng2),
new google.maps.LatLng(lat1, lng2)
],
strokeOpacity: 0,
fillOpacity : 0,
map : map
});
google.maps.event.addListener(rectangle, 'click', function(args) {
console.log('latlng', args.latLng);
});
});
}
Now you get LatLng's for places of interest (and their likes) also.
demo -> http://jsfiddle.net/qmhku4dh/
You're talking about the Point of Interest icons that Google puts on the map.
Would it work for you to remove these icons entirely? You can do that with a Styled Map. To see what this would look like, open the Styled Map Wizard and navigate the map to the area you're interested in.
Click Point of interest under Feature type, and then click Labels under Element type. Finally, click Visibility under Stylers and click the Off radio button under that.
This should remove all of the point of interest icons without affecting the rest of the map styling. With those gone, clicks there will respond to your normal map click event listener.
The Map Style box on the right should show:
Feature type: poi
Element type: labels
Visibility: off
If the result looks like what you want, then click Show JSON at the bottom of the Map Style box. The resulting JSON should like this this:
[
{
"featureType": "poi",
"elementType": "labels",
"stylers": [
{ "visibility": "off" }
]
}
]
You can use that JSON (really a JavaScript object literal) using code similar to the examples in the Styled Maps developer's guide. Also see the MapTypeStyle reference for a complete list of map styles.
This example demonstrates the use of click event listeners on POIs (points of interest). It listens for the click event on a POI icon and then uses the placeId from the event data with a directionsService.route request to calculate and display a route to the clicked place. It also uses the placeId to get more details of the place.
Read the google documentation.
<!DOCTYPE html>
<html>
<head>
<title>POI Click Events</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<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;
}
.title {
font-weight: bold;
}
#infowindow-content {
display: none;
}
#map #infowindow-content {
display: inline;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="infowindow-content">
<img id="place-icon" src="" height="16" width="16">
<span id="place-name" class="title"></span><br>
Place ID <span id="place-id"></span><br>
<span id="place-address"></span>
</div>
<script>
function initMap() {
var origin = {lat: -33.871, lng: 151.197};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 18,
center: origin
});
var clickHandler = new ClickEventHandler(map, origin);
}
/**
* #constructor
*/
var ClickEventHandler = function(map, origin) {
this.origin = origin;
this.map = map;
this.directionsService = new google.maps.DirectionsService;
this.directionsDisplay = new google.maps.DirectionsRenderer;
this.directionsDisplay.setMap(map);
this.placesService = new google.maps.places.PlacesService(map);
this.infowindow = new google.maps.InfoWindow;
this.infowindowContent = document.getElementById('infowindow-content');
this.infowindow.setContent(this.infowindowContent);
// Listen for clicks on the map.
this.map.addListener('click', this.handleClick.bind(this));
};
ClickEventHandler.prototype.handleClick = function(event) {
console.log('You clicked on: ' + event.latLng);
// If the event has a placeId, use it.
if (event.placeId) {
console.log('You clicked on place:' + event.placeId);
// Calling e.stop() on the event prevents the default info window from
// showing.
// If you call stop here when there is no placeId you will prevent some
// other map click event handlers from receiving the event.
event.stop();
this.calculateAndDisplayRoute(event.placeId);
this.getPlaceInformation(event.placeId);
}
};
ClickEventHandler.prototype.calculateAndDisplayRoute = function(placeId) {
var me = this;
this.directionsService.route({
origin: this.origin,
destination: {placeId: placeId},
travelMode: 'WALKING'
}, function(response, status) {
if (status === 'OK') {
me.directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
};
ClickEventHandler.prototype.getPlaceInformation = function(placeId) {
var me = this;
this.placesService.getDetails({placeId: placeId}, function(place, status) {
if (status === 'OK') {
me.infowindow.close();
me.infowindow.setPosition(place.geometry.location);
me.infowindowContent.children['place-icon'].src = place.icon;
me.infowindowContent.children['place-name'].textContent = place.name;
me.infowindowContent.children['place-id'].textContent = place.place_id;
me.infowindowContent.children['place-address'].textContent =
place.formatted_address;
me.infowindow.open(me.map);
}
});
};
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap"
async defer></script>
</body>
</html>
If you are using npm load-google-maps-api with webpack this worked for me:
const loadGoogleMapApi = require("load-google-maps-api");
loadGoogleMapApi({ key: process.env.GOOGLE_MAP_API_KEY }).then(map => {
let mapCreated = new map.Map(mapElem, {
center: { lat: lat, lng: long },
zoom: 7
});
mapCreated.addListener('click', function(e) {
console.log(e.latLng.lat()); // this gives you access to the latitude value of the click
console.log(e.latLng.lng()); // gives you access to the latitude value of the click
var marker = new map.Marker({
position: e.latLng,
map: mapCreated
});
mapCreated.panTo(e.latLng); // finally this adds red marker to the map on click.
});
});
Next if you are integrating openweatherMap in your app you can use the value of e.latLng.lat() and e.latLng.lng() which I console logged above in your api request. This way:
http://api.openweathermap.org/data/2.5/weather?lat=${e.latLng.lat()}&lon=${e.latLng.lng()}&APPID=${YOUR_API_KEY}
I hope this helps someone as it helped me.
Cheers!

Resources