StreetViewPanorama - how to change to other image - javascript

I have a little problem and I can't find the solution; maybe someone will know how to fix it.
I have code below where Google StreetViewPanorama and everything (drag, zoom) is working okay. But when I init other image in this object, after the image loads in the object, it stops working: no zooming, edges are displayed, dragging is half-working.
Destroying object before changing image doesn't work.
Maybe is there some method to update this object?
function initPano() {
// Set up Street View and initially set it visible. Register the
// custom panorama provider function. Set the StreetView to display
// the custom panorama 'reception' which we check for below.
var panorama = new google.maps.StreetViewPanorama(
document.getElementById('map'), {
pano: 'reception',
visible: true,
panoProvider: getCustomPanorama
}
);
}
// Return a pano image given the panoID.
function getCustomPanoramaTileUrl(pano, zoom, tileX, tileY) {
// Note: robust custom panorama methods would require tiled pano data.
// Here we're just using a single tile, set to the tile size and equal
// to the pano "world" size.
return 'img/pano-1.jpg'; // <----------- HERE
}
// Construct the appropriate StreetViewPanoramaData given
// the passed pano IDs.
function getCustomPanorama(pano, zoom, tileX, tileY) {
if(pano === 'reception') {
return {
location: {
pano: 'reception',
description: 'Description'
},
links: [],
// The text for the copyright control.
copyright: 'Imagery (c) 2010 Google',
// The definition of the tiles for this panorama.
tiles: {
tileSize: new google.maps.Size(1024, 512),
worldSize: new google.maps.Size(1024, 512),
// The heading in degrees at the origin of the panorama
// tile set.
centerHeading: 105,
getTileUrl: getCustomPanoramaTileUrl
}
};
}
}

I figured out something like this, and for now it's working corectly..
var panorama;
function initialize() {
var panoOptions = {
pano: 'sfera-4',
visible: true,
panoProvider: getCustomPanorama
}
panorama = new google.maps.StreetViewPanorama(
document.getElementById('map'),
panoOptions
);
}
function getCustomPanoramaTileUrl(pano,zoom,tileX,tileY) {
return 'i/'+pano+'s.jpg';
}
function getCustomPanorama(pano,zoom,tileX,tileY) {
switch(pano) {
case 'sfera-4':
return {
location: {
pano: 'sfera-4',
description: 'Sfera 4'
},
copyright: 'Description',
tiles: {
tileSize: new google.maps.Size(4096,2048),
worldSize: new google.maps.Size(4096,2048),
centerHeading: 0,
getTileUrl: getCustomPanoramaTileUrl
}
};
break;
case 'sfera-7':
return {
location: {
pano: 'sfera-7',
description: 'Sfera 7'
},
copyright: 'Description',
tiles: {
tileSize: new google.maps.Size(4096,2048),
worldSize: new google.maps.Size(4096,2048),
centerHeading: 0,
getTileUrl: getCustomPanoramaTileUrl
}
};
break;
}
}
function setMap(id) {
panorama.setPano('sfera-'+id);
}
for changing image I just calling setMap(7)

Related

Using Prototypal Pattern with Creating a Leaflet Map: error with onEachFeature function

I have the following code that I call to create a copy object of map, and initialize the Leaflet map. This works and loads properly. However, the onEachFeature and/or the clickFeature functions are not working properly.
var map = {
mapUrl: "",
maxZoom: 18,
minZoom: 2,
map: L.map('worldMap').setView([51.505, -0.09], 2),
create: function(values) {
var instance = Object.create(this);
Object.keys(values).forEach(function(key) {
instance[key] = values[key];
});
return instance;
},
initLeafletMap: function() {
L.tileLayer(this.mapUrl, {
attribution: '',
maxZoom: this.maxZoom,
minZoom: this.minZoom,
id: 'mapbox.streets'
}).addTo(this.map);
//add continents' outlines
$.getJSON("/static/continents.json",
(function(style, onEachFeature, map) {
return function(continents) {
console.log(typeof(continents));
L.geoJson(continents, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
};
}(this.style, this.onEachFeature, this.map))
);
},
style: function() {
return {
weight: 2,
opacity: 1,
color: 'beige',
dashArray: '3',
fillOpacity: 0
};
},
onEachFeature: function(feature, layer) {
layer.on({
click: this.clickFeature
});
},
clickFeature: function(e) {
do something here();
},
So when I click on the map, I know the onEachFeature function is called, but it does not call clickFeature. Instead I get this error in the console:
leaflet.js:5 Uncaught TypeError: Cannot read property 'call' of undefined
at e.fire (leaflet.js:5)
at e._fireDOMEvent (leaflet.js:5)
at e._handleDOMEvent (leaflet.js:5)
at HTMLDivElement.r (leaflet.js:5)
Much probably simply need to bind the this context when you pass your onEachFeature method as argument of your IIFE to build the callback to your AJAX call:
this.onEachFeature.bind(this)
See also Leaflet- marker click event works fine but methods of the class are undefined in the callback function
BTW you could also attach your click event listener directly on the Leaflet GeoJSON Layer Group instead of doing it for each child layer.

Google Maps Api v3 - several Marker hovers with Javascript

I want to set different hovers for different marker icons i use on my map.
This is my marker icon array
//Marker Icons
var markerIcon = {
unvisitedMarker: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(15, 15)
},
unvisitedMarkerHover: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(30, 0),
anchor: new google.maps.Point(15, 15)
},
activeMarker: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(60, 0),
anchor: new google.maps.Point(15, 15)
},
visitedMarker: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(90, 0),
anchor: new google.maps.Point(15, 15)
},
visitedMarkerHover: {
url: 'img/marker.png',
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(120, 0),
anchor: new google.maps.Point(15, 15)
}
I got all icons in one sprite.
I want to set the hover effect for the 'unvisitedMarker' with 'unvisitedMarkerHover' and for 'visitedMarker with 'visitedMarkerHover'. If the marker has the 'activeMarker' icon it should not get a hover effect.
My Problem with this is - i don't know how to set the "if" requirement for that.
//marker hover effect
marker.addListener('mouseover', function() {
if (???) { ... }
});
marker.addListener('mouseout', function() {
if (???) { ... }
});
After that i know i can set the icon with:
marker.setIcon(markerIcon['unvisitedMarker']);
So if someone could help me with the if requirement - that would be awesome!
This one is not that simple. Since I don't have the details such as the URL to your images, I created a sample application in which we have at least 90% similarity. Important: Please don't use the images I've used to avoid copyright issues.
First, I've created public variables: map, markers. "markers" is an empty array.
var map;
var markers = [];
I've also created my own version of markerIcon object.
var markerIcon = {
url : 'http://oi68.tinypic.com/30idv0z.jpg',
unvisitedMarkerHover: 'http://oi65.tinypic.com/jgo3r8.jpg',
originlUrl: 'http://oi68.tinypic.com/30idv0z.jpg',
visitedMarkerHover: 'http://oi65.tinypic.com/ejbn88.jpg',
status: {
unvisitedMarker : {
statusName: 'unvisitedMarker',
},
activeMarker : {
statusName: 'activeMarker',
},
visitedMarker : {
statusName: 'visitedMarker',
}
}
};
I've used a coordinate in San Francisco for my map's center and for Google Maps Javascript API Places Library. I've used Nearby Search as a Place Search and used San Francisco's coordinate for the location property. The radius is set to 500 (measured in meters). This is essential as a combination of the location property - specifying the center of the circle as a LatLng object. For the types, i restricted it only to stores. To learn more about supported types, please check list of supported types.
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: myLatLng,
radius: '500',
type: ['store']
}, callback);
In Nearby Search callback, it returns an array of results. This is what I did:
function createMarker(place, markerId) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
id: markerId,
map: map,
position: placeLoc,
title: 'Hello World!',
anchor: new google.maps.Point(15, 15),
icon: {
url : markerIcon.url,
},
currentStatus: '',
status: markerIcon.status.unvisitedMarker.statusName,
size: new google.maps.Size(30,30),
});
markers.push(marker);
}
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i],i);
}
}
}
I created a createMarker() function that accepts two arguments: the
place object, and markerId.
What the function does is it creates a new Google Maps Javascript
API
Marker
and then set the property and its values accordingly. And also, after
creating the new "marker" object, it will be pushed in to
markers array.
You will also notice that I've added custom properties:
currentStatus, and status. This will play a very important role in
our mouse events.
Since the callback results is an array, I iterate through each array
and called createMarker() function.
This is where the fun begins, in createMarker(), I've also added lines for Google Maps Javascript API Events. This is what I did on my end. Whenever there's a mouseover on a marker, it checks first the currentStatus property of the mouseovered marker. If the currentStatus is an empty string '', it will do another checking for the status property. If the status is 'unvisited', the current icon will now change to a new one. When a mouseout has been detected, the new icon will change to the original one.
Meanwhile, when a marker is clicked, the currentStatus property will be updated to "activeMarker" and then the "status" property is changed to "visitedMarker" as well. You will notice that if the marker has an "activeMarker" currentStatus, nothing will happen when there's a mouseover.
In order to remove the "activeMarker" currentStatus, you will have to click another marker. The "activeMarker" now is transferred to this "another marker". You will also notice that there's a new mouseover effect on the previous marker because I've set a new icon if the marker's status is "unvisitedMarker". You can all find all icon URLs in the markerIcon object.
google.maps.event.addListener(marker, 'mouseover', function() {
if ( this.currentStatus !== markerIcon.status.activeMarker.statusName ) {
if ( this.status === markerIcon.status.unvisitedMarker.statusName ) {
this.setIcon(markerIcon.unvisitedMarkerHover);
} else {
this.setIcon(markerIcon.visitedMarkerHover);
}
this.setPosition(this.position);
console.log(this.currentStatus, this.status, this.id);
}
});
google.maps.event.addListener(marker, 'mouseout', function() {
this.setIcon(markerIcon.originlUrl);
});
google.maps.event.addListener(marker, 'click', function() {
for ( var i = 0; i < markers.length; i++ ) {
markers[i].currentStatus = '';
}
this.currentStatus = markerIcon.status.activeMarker.statusName;
this.status = markerIcon.status.visitedMarker.statusName;
console.log(this.currentStatus, this.status);
});
Whole code below:
var map;
var markers = [];
var markerIcon = {
url : 'http://oi68.tinypic.com/30idv0z.jpg',
unvisitedMarkerHover: 'http://oi65.tinypic.com/jgo3r8.jpg',
originlUrl: 'http://oi68.tinypic.com/30idv0z.jpg',
visitedMarkerHover: 'http://oi65.tinypic.com/ejbn88.jpg',
status: {
unvisitedMarker : {
//origin: new google.maps.Point(0, 0),
statusName: 'unvisitedMarker',
},
activeMarker : {
//origin: new google.maps.Point(60, 0),
statusName: 'activeMarker',
},
visitedMarker : {
//origin: new google.maps.Point(90, 0),
statusName: 'visitedMarker',
},
}
};
function initMap() {
var myLatLng = {lat: 37.773972, lng: -122.431297};
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: myLatLng
});
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: myLatLng,
radius: '500',
type: ['store']
}, callback);
}
function createMarker(place, markerId) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
id: markerId,
map: map,
position: placeLoc,
title: 'Hello World!',
anchor: new google.maps.Point(15, 15),
icon: {
url : markerIcon.url,
},
currentStatus: '',
status: markerIcon.status.unvisitedMarker.statusName,
size: new google.maps.Size(30,30),
});
markers.push(marker);
google.maps.event.addListener(marker, 'mouseover', function() {
if ( this.currentStatus !== markerIcon.status.activeMarker.statusName ) {
if ( this.status === markerIcon.status.unvisitedMarker.statusName ) {
this.setIcon(markerIcon.unvisitedMarkerHover);
} else {
this.setIcon(markerIcon.visitedMarkerHover);
}
this.setPosition(this.position);
//console.log(this.currentStatus, this.status, this.id);
}
});
google.maps.event.addListener(marker, 'mouseout', function() {
this.setIcon(markerIcon.originlUrl);
});
google.maps.event.addListener(marker, 'click', function() {
for ( var i = 0; i < markers.length; i++ ) {
markers[i].currentStatus = '';
}
this.currentStatus = markerIcon.status.activeMarker.statusName;
this.status = markerIcon.status.visitedMarker.statusName;
});
}
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i],i);
}
}
}
/* 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;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyCzjs-bUR6iIl8yGLr60p6-zbdFtRpuXTQ&callback=initMap"
async defer></script>
Hope this application could help and happy coding!

Uncaught TypeError: Cannot read property 'properties' of undefined in Leaflet smap-responsive

I am building a map with multiple geojsons in Leaflet and it has worked well on a normal size computer screen. It doesn't however work on smaller screens or Apple products and so I am attemting to move my code over to Smap-responsive https://github.com/getsmap/smap-responsive .
I have added a geojson following the given example and styled it based upon attributes, it looks how I want it to and the pop ups work how I want them to. The problem comes when I try to add a second geojson. When I click points on the first layer it works as it should but when I turn off that layer and turn on the second layer the popups don’t work on the second layer. If I refresh the page and try the second layer first, those popups work but then they don’t work on the first layer. The error i get is:
“Uncaught TypeError: Cannot read property 'properties' of undefined”
Here is the code:
var config = {
// These params are default and can be overridden by calling the map with e.g. http://mymap?center=13.1,55.6&zoom=17
params: {
// The map's centering from start. Coordinates should be in WGS 84 and given like [easting, northing] i.e. [longitude, latitude]
center: [14.0, 55.52],
// The initial zoom of the map, In this example I zoom out slightly if the screen is smaller than given number of pixels
zoom: $(window).width() < 600 ? 11 : 11
},
// Optional configuration object for the Leaflet map object. You can use all options specified here: http://leafletjs.com/reference.html#map-class
// mapConfig: {
// maxBounds: [ // Optional. Limit panning of the map. Given as [[north, west], [south, east]]
// [55.71628170645908, 12.6507568359375],
// [55.42589636057864, 13.34564208984375]
// ],
// minZoom: 11, // Optional. Limit how much you can zoom out. 0 is maximum zoomed out.
// maxZoom: 18 // Optional. Limit how much you can zoom in. 18 is usually the maximum zoom.
// },
smapOptions: {
// The text of the <title>-tag
title: "webbkartan",
// The favicon to be used
favIcon: "//assets-cdn.github.com/favicon.ico"
},
// -- Baselayers (background layers) --
bl: [
// -- An openstreetmap layer. Note that all layer types used as overlays can also be used as baselayers, and vice versa (see more layers below). --
{
init: "L.TileLayer",
url: '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
options: {
layerId: "osm",
displayName: "OSM",
attribution: '<span>© OpenStreetMap contributors</span> | <span>Tiles Courtesy of MapQuest <img src="//developer.mapquest.com/content/osm/mq_logo.png"></span>',
maxZoom: 18
}
}
],
// -- Overlays --
ol: [
{
init: "L.GeoJSON.WFS",
url: document.URL.search(/dev.html?/) > 0 ? "examples/data/recipient.geojson" : "../examples/data/recipient.geojson",
options: {
displayName: "Totalkväve halt",
category: ["Status"],
layerId: "kvave",
attribution: "",
inputCrs: "EPSG:4326",
uniqueKey: "Nr",
selectable: true,
reverseAxis: false,
reverseAxisBbox: true,
geomType: "POINT",
legend:"examples/data/legend/kvave_legend.jpg",
popup:
'<h4>Punkt ${Nr} </h4>'+
'<br><img src="examples/data/diagram/' + '${Ar_kvav}' + '"/ width=400>'+
'<img src="examples/data/diagram/' + '${Man_kvav}' + '"/ width=400>'+
'<p><font size=2>'+ '${Plats}'+
'<br><b> Frekvens: </b>${frekvens_g}/år'+
'<br><b> Senast provtagning: </b> ${sist_anv}'+
'<br><b> Nuvarande status: </b> ${Status_fos} status'+
'<br><b> Senaste uppdaterad: </b> ${uppdaterad}</p>',
style:function(feature){
switch (feature.properties.Status_kva){
case "Extremt hög halt" : return {color: '#FF000D'};
case "Mycket hög halt": return {color: '#FFBB00'};
case null: return {color: '#8C8C89'};
};
}
}
},
{
init: "L.GeoJSON.WFS",
url: document.URL.search(/dev.html?/) > 0 ? "examples/data/recipient.geojson" : "../examples/data/recipient.geojson",
options: {
displayName: "Totalfosfor status",
category: ["Status"],
layerId: "fosfor",
attribution: "",
inputCrs: "EPSG:4326",
uniqueKey: "OBJECTID",
selectable: true,
reverseAxis: false,
reverseAxisBbox: true,
geomType: "POINT",
legend:"examples/data/legend/fos_legend.jpg",
popup:
'<h4>Punkt ${Nr} </h4>'+
'<br><img src="examples/data/diagram/' + '${Ar_fos}' + '"/ width=400>'+
'<img src="examples/data/diagram/' + '${Man_fos}' + '"/ width=400>'+
'<p><font size=2>'+ '${Plats}'+
'<br><b> Frekvens: </b>${frekvens_g}/år'+
'<br><b> Senast provtagning: </b> ${sist_anv}'+
'<br><b> Nuvarande status: </b> ${Status_fos} status'+
'<br><b> Senaste uppdaterad: </b> ${uppdaterad}</p>',
style:function(feature){
switch (feature.properties.Status_fos){
case "Hög" : return {color:'#02A0F5', fillColor: '#02A0F5', fillOpacity:1};
case "God" : return {color:'#29D637', fillColor: '#29D637', fillOpacity:1};
case "Otillfredsställande" : return {color: '#F5AA07', fillColor: '#F5AA07', fillOpacity:1};
case "Dålig": return {color:'#FC0000', fillColor: '#FC0000', fillOpacity:1};
case null: return {color:'#8C8C89', fillColor: '#8C8C89',fillOpacity:1 };
};
}
}
},
],
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Plugins are Leaflet controls. The options of a control
// given here, will override the options in the control.
// Thereby, you can manage everything the control lets
// you manage from this config file – without having to
// edit the plugin itself.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
plugins: [
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Scale is Leaflet's in-built scale bar control. See options: http://leafletjs.com/reference.html#control-scale
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Scale",
options: {
imperial: false
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// LayerSwitcher is a responsive layer menu for both overlays and baselayers.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.LayerSwitcher",
options: {
toggleSubLayersOnClick: false, // If true, all layers below this header will be turned on when expanding it.
unfoldOnClick: true, // If true, clicking anywhere on a header will unfold it. If false, user has to click on the icon next the header text.
unfoldAll: false, // If true, all subheaders will be unfolded when unfolding a header.
olFirst: false, // If true, the overlays panel is shown at the top
pxDesktop: 992, // Breakpoint for switching between mobile and desktop switcher
btnHide: true, // Show a hide button at the top header
catIconClass: "fa fa-chevron-right" // Icon class for foldable headers
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Zoombar creates a custom zoombar with [+] and [-] buttons.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Zoombar",
options: {}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Geolocate shows the users position. Based on the HTML5 geolocation API.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Geolocate",
options: {
position: 'bottomright', // Button's position
locateOptions: {
maxZoom: 17, // Maximum auto-zoom after finding location
enableHighAccuracy: true // true: Will turn on GPS if installed (better accuracy but uses more battery)
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// SelectVector is needed to make WMS layers selectable
// using getfeatureinfo requests.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.SelectWMS",
options: {
wmsVersion: "1.3.0", // The WMS version to use in the getfeatureinfo request
info_format: "text/plain", // The fallback info format to fetch from the WMS service. Overridden by layer's info_format in layer's selectOptions.
maxFeatures: 20, // Max features to fetch on click
buffer: 12, // Buffer around click (a larger number makes it easier to click on lines and points)
useProxy: false // If you want call the URL with a prepended proxy URL (defined in ws above)
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// SelectVector is needed in order to make vector (e.g. WFS) layers selectable.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.SelectVector",
options: {
// The select style.
selectStyle: {
weight: 5,
color: '#00FFFF',
fillColor: '#00FFFF',
opacity: 1,
fillOpacity: .5
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Search connects to a autocomplete and geolocate service and places a marker
// at the geolocated location.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Search",
options: {
_lang: {
// Watermark/placeholder for text entry. Language dependent.
"en": {search: "Search address or place"}, // english
"sv": {search: "Sök adress eller plats"} // swedish
},
gui: true, // If false, entry is not shown but the plugin can still take the POI URL parameter
whitespace: "%20", // How to encode whitespace.
wsOrgProj: "EPSG:3008", // The projection of the returned coordinates from the web service
useProxy: false, // If you want call the URL with a prepended proxy URL (defined in ws above)
wsAcUrl: "//kartor.malmo.se/api/v1/addresses/autocomplete/", // Required. Autocomplete service.
wsLocateUrl: "//kartor.malmo.se/api/v1/addresses/geolocate/", // Required. Geolocate service.
acOptions: { // typeahead options (Bootstrap's autocomplete library)
items: 100 // Number of options to display on autocomplete
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Print creates a downloadable image server-side. Requires Geoserver and the plugin "Mapfish print".
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// {
// init: "L.Control.Print",
// options: {
// printUrl: "//kartor.malmo.se/print-servlet/leaflet_print/", // The print service URL
// position: "topright" // Button's position
// }
// },
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// ShareLink adds a button which, on click, will create a
// URL which recreates the map, more or less how it looked like.
// It is up to other plugins to add and receive URL parameters by
// listening to the events:
// - Create params: "smap.core.createparams"
// - Apply params: "smap.core.beforeapplyparams" or "smap.core.applyparams"
// For instance:
//
// smap.event.on("smap.core.createparams", function(e, paramsObject) {
// paramsObject.myparameter = 3;
// });
// smap.event.on("smap.core.applyparams", function(e, paramsObject) {
// alert(paramsObject.myparameter);
// });
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.ShareLink",
options: {
position: "topright",
root: location.protocol + "//malmo.se/karta?" // location.protocol + "//kartor.malmo.se/init/?appid=stadsatlas-v1&" // Link to malmo.se instead of directly to map
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// RedirectClick opens a new browser tab when the user clicks on the map.
// The easting ${x} and northing ${y} is sent along to the url. See example below.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init : "L.Control.RedirectClick", // Pictometry
options: {
position: "topright", // Button's position
url: "http://kartor.malmo.se/urbex/index.htm?p=true&xy=${x};${y}", // Malmö pictometry
btnClass: "fa fa-plane", // Button's icon class
cursor: "crosshair" // Cursor shown in map before click
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Info simply creates a toggleable Bootstrap modal which you can fill with any info below.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.Info",
options: {
addToMenu: false, // Create toggle button or not
position: "topright", // Button's position (requires addToMenu == true)
autoActivate: false, // Open from start
// Here follows the content of the modal – language dependent!
_lang: {
"en": {
titleInfo: "<h4>A header</h4>",
bodyContent:
'<p>Some content</p>'
},
"sv": {
titleInfo: "<h4>En rubrik</h4>",
bodyContent:
'<p>Lite innehåll</p>'
}
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// MeasureDraw is a combined measure and drawing tool. The created
// markers, lines or polygons can be shared with others
// (geometries and attributes sent along as a URL parameter).
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.MeasureDraw",
options: {
position: "topright", // Button's position
saveMode: "url", // So far url is the only option
layerName: "measurelayer", // The internal layerId for the draw layer
stylePolygon: { // Draw style for polygons
color: '#0077e2',
weight: 3
},
stylePolyline: { // Draw style for polylines
color: '#0077e2',
weight: 9
}
}
},
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// ToolHandler takes care of making all buttons inside the top-right div responsive.
// When the screen width is smaller than the defined breakpoint, the buttons are contained
// within a Bootstrap popover which can be toggled by a single button.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
{
init: "L.Control.ToolHandler",
options: {
showPopoverTitle: false // Show title (header) in the popover
}
}
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// Add2HomeScreen creates a popover on iOS devices supporting
// "Add To Homescreen", which advices the user to add the website
// to the homescreen, making it look almost like a native app.
// <><><><><><><><><><><><><><><><><><><><><><><><><><>
// {
// init: "L.Control.Add2HomeScreen",
// options: {}
// }
]
};
The error points to "feature.properties." in the function that sets the colors of the first layer I turn on and it comes when I click to get a pop up on the second layer I have turned on. I haven't had this problem when using Leaflet without smap-resonsive.
I have tried moving the function out to an external js. file, defining the functions with "var something =". I have tried calling the colors direct from an attribute also but all give the same error.
I am new to Leaflet and Javascript, any help appreciated!
The error was caused by bug which meant that only the uppermost layer was selectable. Described here:
https://github.com/getsmap/smap-responsive/issues/198
Thanks to Johan Lahti for a quick reposonse in solving the problem!

When clicking cluster, how to show Infowindow which has markers's values?

I have been trying to use google map with angularJS.
I have learned how to use it through https://angular-ui.github.io/angular-google-maps/#!/.
Everything goes well.
For each marker, I can show InfoWindow which has an element information of myList.
But I have got stuck in InfoWindow with cluster.
When cluster is clicked, I want to show the information list of markers in cluster.
Even I can't show simple InforWindow when clicking the cluster.
Below sources are my code.
Please tell me if it is not enough to solve my problem.
Please tell me what is wrong and how to solve this.
Have a nice day.
* javascript
$scope.map.map = {
center: { latitude: $scope.map.myList[0].lat, longitude: $scope.map.myList[0].lng },
zoom: 17,
events : {
tilesloaded: function (map) {
$scope.$apply(function () {
google.maps.event.addDomListener(window, 'resize', function() {
var lat = $scope.map.myList[$scope.map.markerPosition-1].lat;
var lng = $scope.map.myList[$scope.map.markerPosition-1].lng;
var center = new google.maps.LatLng(lat, lng);
map.setCenter(center);
});
});
}
},
markersEvents: {
click: function(marker, eventName, model) {
model.show = !model.show;
return;
}
},
clusterOptions : { // options of cluster
gridSize: 40,
ignoreHidden: true,
zoomOnClick : false,
averageCenter : true,
styles: [
{
height: 53,
url: "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/images/m3.png",
width: 53,
textColor : 'white'
}
]
},
clusterEvent: { // when cluster's clicked
click: function(map, markers) {
var contentString = 'ABCD';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
infowindow.open(map, markers);
return;
}
}
};
$scope.map.options = {
streetViewControl : false
};
$scope.map.markers = [];
* html
<ui-gmap-google-map center='map.map.center' zoom="map.map.zoom" options="map.options" events="map.map.events">
<ui-gmap-markers models="map.markers" coords="'self'" icon="a" events="map.map.markersEvents" options="'options'"
doCluster="true" clusterOptions="map.map.clusterOptions" clusterEvents="map.map.clusterEvent">
<ui-gmap-windows show="show">
<div ng-non-bindable>{{id}}</div>
</ui-gmap-windows>
</ui-gmap-markers>
Answer myself.
var infoWindowOptions = {
content: "asdfasdf"
};
var infowindow = new google.maps.InfoWindow(infoWindowOptions);
infowindow.open(map.map_, *marker*);

Gmap3 Clear Directions

I need to recalculate the directions, when another marker is clicked or when my origin marker is dragged to another location.
at the moment, I am inserting a marker when a user inserts his/her address then when the users clicks on any existing marker it calculates the directions. Unfortunately it doesn't clear the previous directions.
Any Help at all will be greatly appreciated.
Here's the code:
jQuery(document).ready(function() {
jQuery.getJSON('./index.php', {
option: "com_locate",
view: "branches",
tmpl: "component",
format: "json",
},
function(json){
jQuery(function(){
jQuery("#googleMap").gmap3({
map:{
options: {
center:[-29.8191,25.3499],
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false
}
},
marker: {
values: json,
options: {
icon: new google.maps.MarkerImage("http://maps.gstatic.com/mapfiles/icon_green.png")
},
events:{
mouseover: function(marker, event, context){
jQuery(this).gmap3(
{clear:"overlay"},
{
overlay:{
id: "tooltip",
latLng: marker.getPosition(),
options:{
content: "<div class='infobulle"+(context.data.drive ? " drive" : "")+"'>" +
"<div class='bg'></div>" +
"<div class='text'>" + context.data.city + " (" + context.data.telephone + ")</div>" +
"</div>" +
"<div class='arrow'></div>",
offset: {
x:-46,
y:-73
}
}
}
});
},
mouseout: function(){
jQuery(this).gmap3({clear:"overlay"});
},
click: function(marker, event, context){
markerSelected(context.id);
}
}
}
});
///////////////
jQuery('#test-ok').click(function(){
var addr = jQuery('#test-address').val();
if ( !addr || !addr.length ) return;
jQuery("#googleMap").gmap3({
getlatlng:{
address: addr,
callback: function(results){
if ( !results ) return;
jQuery("#googleMap").gmap3({
clear:{id:"user"}
},
{
marker:{
latLng:results[0].geometry.location,
id:"user",
name:"user",
options:{
draggable: true
}
},
map:{
center: true,
zoom: 5
}
});
}
}
});
});
jQuery('#test-address').keypress(function(e){
if (e.keyCode == 13){
jQuery('#test-ok').click();
}
});
///////////////
///////////////
function markerSelected(id){
var marker = jQuery('#googleMap').gmap3({get:id});
var usermarker = jQuery('#googleMap').gmap3({get:"user"});
jQuery("#googleMap").gmap3({
getroute:{
options:{
origin:[usermarker.getPosition().lat(),usermarker.getPosition().lng()],
destination:[marker.getPosition().lat(),marker.getPosition().lng()],
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
if (!results) return;
jQuery(this).gmap3({
map:{
options:{
}
},
directionsrenderer:{
container: jQuery(document.createElement("div")).addClass("googlemap").insertAfter(jQuery("#googleMap")),
options:{
directions:results
}
}
});
}
}
});
}
});
});
});
The code you're using creates a new DOM element each time you do a directions request, without removing any existing such elements or replacing content in any existing elements. The pertinent part of your code is this:
directionsrenderer:{
container: jQuery(document.createElement("div")).addClass("googlemap").insertAfter(jQuery("#googleMap")),
// The above creates a new DOM element every time markerSelected() is called!
options:{
directions:results
}
}
You want to create that only once. If you want, you can do it directly in the HTML markup.
Use the below as a replacement for your getroute callback function. I've plugged in a unique ID for the container element and left the "googlemap" class intact in case it's needed for CSS or other sections of code. Since you specifically want only one set of directions to be visible, though, let's select your container by ID.
callback: function(results){
if (!results) return;
if (!jQuery("#dircontainer").length>0) {
jQuery("<div id='dircontainer' class='googlemap'></div>").insertAfter("#googleMap");
} // Creates your directions container if it doesn't already exist.
else {
jQuery("#dircontainer").html("");
} /* I'm clearing the existing contents of the container in case gmap3 doesn't
automatically clear it when the new directions are inserted.
You can experiment with removing this else statement. */
jQuery(this).gmap3({
map:{
options:{
}
},
directionsrenderer:{
container: jQuery("#dircontainer"),
options:{
directions:results
}
}
});
}
I'm making some assumptions here about the way the gmap3 plugin works; I've worked with jQuery and the Google Maps JS API, but not with this plugin.

Categories