Hide Watermark by clicking on it, on the leaflet map? - javascript

Please help with the code to hide the watermark by clicking on watermark. LiveUrl: http://breamap.hostronavt.ru
L.Control.Watermark = L.Control.extend({
onAdd: function(map) {
var img = L.DomUtil.create('img');
img.src = 'images/art/Baby_512.png';
img.style.width = '250px';
return img;
},
onRemove: function(map) {
// Nothing to do here
}
});
L.control.watermark = function(opts) {
return new L.Control.Watermark(opts);
}
L.control.watermark({ position: 'bottomleft' })
.addTo(Dont_Think_Group);

It should also work in IE11;)
let map = L.map('map', {
center: [40, 0],
zoom: 1
});
let positron = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors, © CARTO'
}).addTo(map);
L.Control.Watermark = L.Control.extend({
onAdd(map) {
let img = L.DomUtil.create('img');
img.src = 'https://leafletjs.com/docs/images/logo.png';
img.style.width = '200px';
img.addEventListener('click', function(e) {
let target = e.target;
target.parentNode.removeChild(target);
});
return img;
},
onRemove(map) {}
});
L.control.watermark = function(opts) {
return new L.Control.Watermark(opts);
};
L.control.watermark({
position: 'bottomleft'
}).addTo(map);
html,
body {
height: 100%;
margin: 0;
}
#map {
width: 600px;
height: 400px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js"></script>
<div id='map'></div>
Update - Adding a button showing/hiding the watermark
let map = L.map('map', {
center: [40, 0],
zoom: 1
});
let positron = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors, © CARTO'
}).addTo(map);
let customControl = L.Control.extend({
options: {
position: 'topleft'
},
onAdd(map) {
let container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
container.style.backgroundColor = 'white';
container.style.backgroundSize = '30px 30px';
container.style.width = '30px';
container.style.height = '30px';
container.style.cursor = 'pointer';
container.classList.add('watermark-button');
container.innerText = 'hide';
container.onclick = function() {
const watermarkCheck = document.querySelector('.watermark-hidden');
const watermark = document.querySelector('.watermark');
if (watermarkCheck) {
container.innerText = 'hide';
watermark.classList.remove('watermark-hidden');
} else {
container.innerText = 'show';
watermark.classList.add('watermark-hidden');
}
};
return container;
}
});
L.Control.Watermark = L.Control.extend({
onAdd(map) {
let img = L.DomUtil.create('img');
img.src = 'https://leafletjs.com/docs/images/logo.png';
img.style.width = '200px';
img.classList.add('watermark');
img.addEventListener('click', function(e) {
const watermarkButton = document.querySelector('.watermark-button');
let target = e.target;
watermarkButton.innerText = 'show';
target.classList.add('watermark-hidden');
});
return img;
},
onRemove(map) {}
});
L.control.watermark = function(opts) {
return new L.Control.Watermark(opts);
};
L.control.watermark({
position: 'bottomleft'
}).addTo(map);
map.addControl(new customControl());
html,
body {
height: 100%;
margin: 0;
}
#map {
width: 600px;
height: 400px;
}
.watermark-hidden {
display: none;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js"></script>
<div id='map'></div>

Related

Show OverlayView marker in street view

I wanted to create custom "HTMLMarker" for google maps, but I just found out, it is not displaying in the street view. I have searched docs, but nothing is written there. (Googled: "show OverlayView marker in street view")
interface HTMLMarkerOptions {
position: google.maps.LatLng | google.maps.LatLngLiteral;
content: HTMLElement;
}
class HTMLMarker extends google.maps.OverlayView {
private _element: HTMLElement;
private _isAppended = false;
private _position: google.maps.LatLng;
constructor(options: HTMLMarkerOptions) {
super();
this._position = this._createLatLng(options.position)
this._element = document.createElement('div');
this._element.style.position = 'absolute';
this._element.appendChild(options.content);
}
_appendDivToOverlay() {
const panes = this.getPanes();
panes.overlayMouseTarget.appendChild(this._element);
this._isAppended = true;
}
_positionDiv() {
const map = this.getMap();
if (map instanceof google.maps.StreetViewPanorama) {
// TODO: Render in StreetView
return;
} else {
const projection = this.getProjection();
const point = projection.fromLatLngToDivPixel(this._position);
if (point) {
this._element.style.left = `${point.x - this._offset.left}px`;
this._element.style.top = `${point.y - this._offset.top}px`;
}
}
}
setMap(map: google.maps.Map | google.maps.StreetViewPanorama | null) {
super.setMap(map);
}
draw() {
if (!this._isAppended) {
this._appendDivToOverlay();
}
this._positionDiv();
}
remove(): void {
this._element.parentNode?.removeChild(this._element);
this._isAppended = false;
}
setPosition(position: google.maps.LatLng | google.maps.LatLngLiteral): void {
if (!this._LatLngEquals(this._position, position)) {
this._position = this._createLatLng(position);
}
}
getPosition(): google.maps.LatLng {
return this._position;
}
getDraggable(): boolean {
return false;
}
private _createLatLng(
position: google.maps.LatLng | google.maps.LatLngLiteral,
): google.maps.LatLng {
if (position instanceof google.maps.LatLng) {
return position;
} else {
return new google.maps.LatLng(position);
}
}
private _LatLngEquals(
positionA: google.maps.LatLng | undefined,
positionB: google.maps.LatLng | google.maps.LatLngLiteral,
): boolean {
if (!positionA) {
return false;
}
if (positionB instanceof google.maps.LatLng) {
return positionA.equals(positionB);
} else {
return positionA.lat() == positionB.lat && positionA.lng() == positionB.lng;
}
}
}
example fiddle (compiled TS to ESNext)
Although the documentation says:
Additionally, when creating a map with a default StreetViewPanorama, any markers created on a map are shared automatically with the map's associated Street View panorama, provided that panorama is visible.
That doesn't seem to be true for the HTMLMarker. Setting the map property of the HTMLMarker to the default Street View panorama of the map:
marker.setMap(map.getStreetView());
makes it visible.
proof of concept fiddle
Related question: Drawing polylines on Google Maps Streetview
code snippet:
const map = new google.maps.Map(
document.querySelector('#map-canvas'), {
zoom: 18,
center: new google.maps.LatLng(37.422, -122.084),
mapTypeId: google.maps.MapTypeId.ROADMAP,
},
);
google.maps.event.addListener(map, 'click', function(e) {
console.log(e.latLng.toUrlValue(6));
})
class HTMLMarker extends google.maps.OverlayView {
constructor(options) {
super();
this._isAppended = false;
this._position = this._createLatLng(options.position);
this._element = document.createElement('div');
this._element.style.position = 'absolute';
this._element.appendChild(options.content);
}
_appendDivToOverlay() {
const panes = this.getPanes();
panes.overlayMouseTarget.appendChild(this._element);
this._isAppended = true;
}
_positionDiv() {
const map = this.getMap();
const projection = this.getProjection();
const point = projection.fromLatLngToDivPixel(this._position);
if (point) {
this._element.style.left = point.x + 'px';
this._element.style.top = point.y + 'px';
}
}
setMap(map) {
super.setMap(map);
}
draw() {
if (!this._isAppended) {
this._appendDivToOverlay();
}
this._positionDiv();
}
remove() {
if (this._element.parentNode) {
this._element.parentNode.removeChild(this._element);
}
this._isAppended = false;
}
setPosition(position) {
if (!this._LatLngEquals(this._position, position)) {
this._position = this._createLatLng(position);
}
}
getPosition() {
return this._position;
}
getDraggable() {
return false;
}
_createLatLng(position) {
if (position instanceof google.maps.LatLng) {
return position;
} else {
return new google.maps.LatLng(position);
}
}
_LatLngEquals(positionA, positionB) {
if (!positionA) {
return false;
}
if (positionB instanceof google.maps.LatLng) {
return positionA.equals(positionB);
} else {
return positionA.lat() == positionB.lat && positionA.lng() == positionB.lng;
}
}
}
const marker = new HTMLMarker({
position: new google.maps.LatLng(37.42197, -122.083627),
content: document.querySelector('#marker'),
});
marker.setMap(map);
const marker1 = new google.maps.Marker({
position: new google.maps.LatLng(37.42197, -122.083627),
});
marker1.setMap(map);
// We get the map's default panorama and set up some defaults.
// Note that we don't yet set it visible.
panorama = map.getStreetView();
panorama.setPosition({
lat: 37.421885,
lng: -122.083662
});
panorama.setPov( /** #type {google.maps.StreetViewPov} */ ({
heading: 0,
pitch: 0
}));
panorama.setVisible(true);
panorama.setZoom(1);
marker.setMap(map.getStreetView());
* {
box-sizing: border-box;
}
body {
margin: 0;
}
#map-canvas {
height: 100vh;
width: 100vw;
background-color: #CCC;
}
#marker {
display: flex;
height: 50px;
width: 50px;
background: white;
border: 3px solid black;
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas"></div>
<div id="marker">
ID: 1
</div>
I also had a look at this yesterday and as mentioned by geocodezip, the documentation is misleading (or wrong). It mentions that
if you explicitly set the map's streetView property to a StreetViewPanorama of your own construction, you will override the default panorama and disable automatic overlay sharing
which to me would mean that if you are not using a panorama of your own construction (and therefore the default panorama), overlay sharing should work, unless if by "overlay" they meant Marker.
Here is a proof that a standard Marker is shared between the map and the default panorama without the need to do anything and the custom overlay isn't:
var map;
var panorama;
var htmlMarker;
function initialize() {
function HTMLMarker(lat, lng) {
this.lat = lat;
this.lng = lng;
this.pos = new google.maps.LatLng(lat, lng);
this.divReference = null;
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onRemove = function() {
this.divReference.parentNode.removeChild(this.divReference);
this.divReference = null;
}
HTMLMarker.prototype.onAdd = function() {
div = document.createElement('DIV');
div.className = "html-marker";
div.style.width = '60px';
div.style.height = '50px';
div.innerHTML = 'ABC';
var panes = this.getPanes();
panes.overlayMouseTarget.appendChild(div);
this.divReference = div;
}
HTMLMarker.prototype.draw = function() {
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
var panes = this.getPanes();
panes.overlayMouseTarget.style.left = position.x - 30 + 'px';
panes.overlayMouseTarget.style.top = position.y - 25 + 'px';
}
// Set up the map
var mapOptions = {
center: new google.maps.LatLng(40.729884, -73.990988),
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
panorama = map.getStreetView();
panorama.setPosition(new google.maps.LatLng(40.729884, -73.990988));
panorama.setPov({
heading: 330,
zoom: 1,
pitch: 0
});
htmlMarker = new HTMLMarker(40.729952, -73.991056);
htmlMarker.setMap(map);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(40.729952, -73.991198),
map: map,
draggable: true,
title: 'My marker'
});
}
function toggleStreetView() {
var toggle = panorama.getVisible();
if (toggle == false) {
panorama.setVisible(true);
} else {
panorama.setVisible(false);
}
}
var button = document.getElementsByTagName('input')[0];
button.onclick = function() {
toggleStreetView()
};
#map-canvas {
height: 150px;
}
input {
margin: 10px;
background-color: #4CAF50;
border: none;
color: white;
padding: 4px 8px;
}
.html-marker {
background-color: red;
color: white;
line-height: 50px;
text-align: center;
font-size: 18px;
font-weight: bold;
}
<input type="button" value="Toggle Street View">
<div id="map-canvas"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize" async defer></script>
And here, when changing from map to default panorama, I simply do
htmlMarker.setMap(null);
htmlMarker.setMap(panorama);
and it works.
var map;
var panorama;
var htmlMarker;
function initialize() {
function HTMLMarker(lat, lng) {
this.lat = lat;
this.lng = lng;
this.pos = new google.maps.LatLng(lat, lng);
this.divReference = null;
}
HTMLMarker.prototype = new google.maps.OverlayView();
HTMLMarker.prototype.onRemove = function() {
this.divReference.parentNode.removeChild(this.divReference);
this.divReference = null;
}
HTMLMarker.prototype.onAdd = function() {
div = document.createElement('DIV');
div.className = "html-marker";
div.style.width = '60px';
div.style.height = '50px';
div.innerHTML = 'ABC';
var panes = this.getPanes();
panes.overlayMouseTarget.appendChild(div);
this.divReference = div;
}
HTMLMarker.prototype.draw = function() {
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
var panes = this.getPanes();
panes.overlayMouseTarget.style.left = position.x - 30 + 'px';
panes.overlayMouseTarget.style.top = position.y - 25 + 'px';
}
// Set up the map
var mapOptions = {
center: new google.maps.LatLng(40.729884, -73.990988),
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
panorama = map.getStreetView();
panorama.setPosition(new google.maps.LatLng(40.729884, -73.990988));
panorama.setPov({
heading: 330,
zoom: 1,
pitch: 0
});
htmlMarker = new HTMLMarker(40.729952, -73.991056);
htmlMarker.setMap(map);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(40.729952, -73.991198),
map: map,
draggable: true,
title: 'My marker'
});
}
function toggleStreetView() {
var toggle = panorama.getVisible();
if (toggle == false) {
panorama.setVisible(true);
htmlMarker.setMap(null);
htmlMarker.setMap(panorama);
} else {
panorama.setVisible(false);
htmlMarker.setMap(null);
htmlMarker.setMap(map);
}
}
var button = document.getElementsByTagName('input')[0];
button.onclick = function() {
toggleStreetView()
};
#map-canvas {
height: 150px;
}
input {
margin: 10px;
background-color: #4CAF50;
border: none;
color: white;
padding: 4px 8px;
}
.html-marker {
background-color: red;
color: white;
line-height: 50px;
text-align: center;
font-size: 18px;
font-weight: bold;
}
<input type="button" value="Toggle Street View">
<div id="map-canvas"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize" async defer></script>
I have opened a new issue in the tracker. Let's see if this is a bug in the API, or an issue with the documentation (or both).
Fiddle showing how to do it: http://jsfiddle.net/upsidown/mLa4zvs7/
Fiddle showing that overlay sharing does not work by default: http://jsfiddle.net/upsidown/xsqvm6n0/

Leaflet Markers + clustering terribly slow, jsfiddle demo(200-400 markers)

here is my script, I'm currently having a bad time with leaflet, it is taking substantial amounts of time to load my markers yet I'm only playing with up to 200-500 at a time and can't seem to find the reason why.
Markers are pulled from an API and stored into an array then plotted onto the map upon clicking a section on the map, see for yourself on the live demo, it works fine until loading markers then it starts to lag a lot when zooming
If anybody has a solution for me it would be much appreciated as I intend to have a lot more markers than it is currently pulling.
var postcode;
var police_api_dates = [
"&date=2017-03",
];
var completed_requests = 0;
var police_api_base_url = "https://data.police.uk/api/crimes-street/all-crime?poly=";
var crimes = [];
var count = 0;
var mymap = L.map('map').setView([53.7983587, -1.6191674], 11);
mymap.createPane('labels');
mymap.getPane('labels').style.zIndex = 650;
mymap.getPane('labels').style.pointerEvents = 'none';
var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
attribution: '©OpenStreetMap, ©CartoDB'
}).addTo(mymap);
var positronLabels = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png', {
attribution: '©OpenStreetMap, ©CartoDB',
pane: 'labels'
}).addTo(mymap);
L.tileLayer('https://api.mapbox.com/styles/v1/adam97x/cjavcj1680vgz2sqshn70q5pg/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoiYWRhbTk3eCIsImEiOiJjamF2Y2k1NmswYzhuMnZtazlpNXU2NDExIn0.RifBBI5nelL-4d21mkn7Wg', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'mapbox.streets'
}).addTo(mymap);
// control that shows state info on hover
var info = L.control();
info.onAdd = function (mymap) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (properties) {
this._div.innerHTML = '<h4>Highlighted Postcode</h4>' + (properties ?
'<b> Postcode: ' + properties.Name
: 'Hover over a state');
};
info.addTo(mymap);
function style(feature) {
return {
fillColor: 'grey',
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.5
};
}
L.geoJson(statesdata, {style: style}).addTo(mymap);
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
opacity: 1,
color: '#000',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
info.update(layer.feature.properties);
postcode = layer.feature.properties.Name.substr(2)-1;
console.log(postcode);
}
/*global statesdata*/
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomFeature(e) {
mymap.fitBounds(e.target.getBounds());
var colonString = statesdata
.features[postcode]
.geometry
.coordinates[0]
.map(pair => pair.reverse().join())
.join(':');
for (var a = 0; a < 1; a++){
var request = police_api_base_url + colonString + police_api_dates[a]
get_JSON(request, JSON_callback);
}
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomFeature
});
}
geojson = L.geoJson(statesdata, {
style: style,
onEachFeature: onEachFeature
}).addTo(mymap);
geojson.eachLayer(function (layer) {
layer.bindPopup(layer.feature.properties.Name);
});
function JSON_callback(data){
completed_requests++;
var data_len = data.length;
if (data[0] != undefined){
for (var i = 0; i < data_len; i++){
cat = data[i]["category"];
lat = data[i]["location"]["latitude"];
lng = data[i]["location"]["longitude"];
if (cat in crimes) {
crimes[cat]++;
} else {
crimes[cat] = 1;
}
create_marker(lat, lng);
}
}
if (completed_requests == 1){
console.log("Requests done");
console.log(crimes);
}
}
function create_crime_markers(lat, lng, cat){
show_by_id("num_of_crimes_load_img");
show_by_id("popular_crime_load_img");
completed_requests = 0;
num_of_crimes = 0;
crimes = {};;
for (var a = 0; a < 1; a++){
var request = police_api_base_url + lat + "&lng=" + lng + police_api_dates[a]
get_JSON(request, JSON_callback);
}
}
var current_lat_lng = [];
function create_marker(lat, lng, title){
current_lat_lng.push(lat, lng, cat);
chunksize = 3;
var chunks = [];
current_lat_lng.forEach((item)=>{
if(!chunks.length || chunks[chunks.length-1].length == chunksize)
chunks.push([]);
chunks[chunks.length-1].push(item);
});
var markers = L.markerClusterGroup({
chunkedloading: true,
spiderfyOnMaxZoom: true,
showCoverageOnHover: false,
zoomToBoundsOnClick: true,
spiderfyDistanceMultiplier: 2.4
});
var markerList = [];
for (var f = 0; f < chunks.length; f++) {
var marker = new L.circleMarker([chunks[f][0],chunks[f][1]])
markerList.push(marker);
}
markers.addLayers(markerList);
mymap.addLayer(markers);
}
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
.info { padding: 6px 8px; font: 14px/16px Arial, Helvetica, sans-serif; background: white; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; } .info h4 { margin: 0 0 5px; color: #777; }
<html>
<head>
<meta charset=utf-8 />
<title>KML Data</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster#1.2.0/dist/MarkerCluster.Default.css" />
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet.js"></script>
<script type="text/javascript" src="https://project-adam97.c9users.io/asset/bd.js"></script>
<script src="https://project-adam97.c9users.io/asset/requests.js"></script>
</head>
<body>
<script> src='https://api.mapbox.com/mapbox.js/plugins/leaflet-omnivore/v0.2.0/leaflet-omnivore.min.js'></script>
<script src="https://unpkg.com/leaflet.markercluster#1.2.0/dist/leaflet.markercluster.js"></script>
<div id='map'></div>
</body>
</html>

Google maps listener event acts like a click even though it is a mouseover

I am adding these two google.maps.event.addListener events
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
markerIconAcademicCenter.url = 'MapIcons/Circle32.png'
});
google.maps.event.addListener(markerAcademicCenter, "mouseout", function (e) {
markerIconAcademicCenter.url = 'MapIcons/Circle64.png'
});
below this marker that already has a click event.
google.maps.event.addListener(markerAcademicCenter, "click", function (e) {
$(".campusMapInfoPanel > div").appendTo($(".InfoStorageDiv"));
$(".InfoPanelAcademicCenter").appendTo($(".campusMapInfoPanel"));
this.setZIndex(google.maps.Marker.MAX_ZINDEX + 1);
setZoomWhenMarkerClicked();
CampusMap.setCenter(markerAcademicCenter.getPosition());
});
The markerIconAcademicCenter.url is already set to Circle64 above these events. I expect the page to load with the larger circle — 64x64 — the switch back and forth as I hover and leave the marker area.
I'm having two problems with this
Nothing happens when I mouseover the marker, but it does happen when I click. On the initial click after the page loads, the map zooms and centers on the building and the marker image resizes. If I click on the building again, nothing else happens, but:
if I click on a menu link that triggers the click event, function buildingFocus(markerName) {google.maps.event.trigger(markerName, "click");} that function resets the icon as if it were the mouseout event.
To test this unexpected behavior further, I commented out each event one at a time. To clarify that something was actually happening, I first changed the initial image to clear.png.
When I took out the mouseover event, the image did not change when I clicked either the building event or the menu link as my first click after the page loaded. Before I removed the mouseover event, clicking on the menu as my second click after page load changed the icon to the mouseout image, but now clicking on the building causes this.
When I took out the mouseout event, clicking on the building as the first click made the icon change to the mouseover image, and clicking again on either area did nothing further. If I clicked on the menu link as the first or future clicks the image didn't change, but it did as soon as I clicked on the building.
When I took the click event out, the image never changed. By itself, the click event works as expected with both locations.
The icon of a marker is not an MVCObject, the API will not observe changes of the icon-properties.
You must modify the url of the icon and then call setIcon to apply the changes:
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
var icon = this.getIcon();
icon.url = 'url/to/icon';
this.setIcon(icon);
});
But I wouldn't suggest it, when you use the icon for multiple markers changing the url(or other properties) will affect the original icon markerIconAcademicCenter (markers use a reference to the original object). You better create a copy with a modified url:
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
var icon = this.getIcon(),copy={};
for(var k in icon){
copy[k]=icon[k];
}
copy.url= 'url/to/icon';
this.setIcon(copy);
});
Try using this :
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
markerIconAcademicCenter.setIcon('url to icon');
});
instead of code below :
google.maps.event.addListener(markerAcademicCenter, "mouseover", function (e) {
markerIconAcademicCenter.url = 'MapIcons/Circle32.png'
});
This will sort out your problem of icon size change on mouseover and mouseout problem.
You can check the code below, so that you will be clear what I mean to say :
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Map Simple</title>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=places"></script>
<script type="text/javascript">
var map, places, iw;
var markers = [];
var autocomplete;
var options = {
//types: ['(cities)'],
//componentRestrictions: {country: 'us'}
};
var geocoder = new google.maps.Geocoder();
function initialize() {
var myLatlng = new google.maps.LatLng(37.783259, -122.402708);
var myOptions = {
zoom: 12,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
places = new google.maps.places.PlacesService(map);
google.maps.event.addListener(map, 'tilesloaded', tilesLoaded);
autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'), options);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
showSelectedPlace();
});
}
function tilesLoaded() {
google.maps.event.clearListeners(map, 'tilesloaded');
google.maps.event.addListener(map, 'zoom_changed', search);
google.maps.event.addListener(map, 'dragend', search);
search();
}
function showSelectedPlace() {
clearResults();
clearMarkers();
var place = autocomplete.getPlace();
map.panTo(place.geometry.location);
markers[0] = new google.maps.Marker({
position: place.geometry.location,
map: map
});
iw = new google.maps.InfoWindow({
content: getIWContent(place)
});
iw.open(map, markers[0]);
search();
}
function search() {
var type;
for (var i = 0; i < document.controls.type.length; i++) {
if (document.controls.type[i].checked) {
type = document.controls.type[i].value;
}
}
autocomplete.setBounds(map.getBounds());
var search = {
bounds: map.getBounds()
};
if (type != 'establishment') {
search.types = [ type ];
}
places.search(search, function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
clearResults();
clearMarkers();
for (var i = 0; i < 9; i++) {
markers[i] = new google.maps.Marker({
position: results[i].geometry.location,
animation: google.maps.Animation.DROP
});
google.maps.event.addListener(markers[i], 'mouseover', animate(i));
google.maps.event.addListener(markers[i], 'mouseout', reanimate(i));
google.maps.event.addListener(markers[i], 'click', getDetails(results[i], i));
setTimeout(dropMarker(i), i * 100);
//addResult(results[i], i);
mygetDetails(results[i], i);
}
}
})
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
if (markers[i]) {
markers[i].setMap(null);
markers[i] == null;
}
}
}
function dropMarker(i) {
return function() {
markers[i].setMap(map);
}
}
//Function to animate markers on there hover
function animate(locationCount){
return function(){
markers[locationCount].setIcon('https://mts.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=2');
$("#addressSpan"+locationCount).css('font-weight', '700');
$("#addressSpan"+locationCount).css('color', '#ff0000');
}
}
//Function to remove animation of markers on there hover
function reanimate(locationCount){
return function(){
markers[locationCount].setIcon('https://mts.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=1');
$("#addressSpan"+locationCount).css('font-weight', '');
$("#addressSpan"+locationCount).css('color', '');
}
}
function addResult(result, i) {
if(i<=9){
var results = document.getElementById("results");
var tr = document.createElement('tr');
tr.style.backgroundColor = (i% 2 == 0 ? '#F0F0F0' : '#FFFFFF');
tr.click = function() {
google.maps.event.trigger(markers[i], 'click');
};
var iconTd = document.createElement('td');
var nameTd = document.createElement('td');
var addressTd = document.createElement('td');
var icon = document.createElement('img');
icon.src = result.icon;
icon.setAttribute("class", "placeIcon");
icon.setAttribute("className", "placeIcon");
var name = document.createTextNode(result.name);
var address = document.createTextNode(result.formatted_address);
iconTd.appendChild(icon);
nameTd.appendChild(name);
addressTd.appendChild(address);
tr.appendChild(iconTd);
tr.appendChild(nameTd);
tr.appendChild(addressTd);
results.appendChild(tr);
}
}
function clearResults() {
var results = document.getElementById("results");
while (results.childNodes[0]) {
results.removeChild(results.childNodes[0]);
}
}
function clearResults1() {
var results = document.getElementById("results1");
while (results.childNodes[0]) {
results.removeChild(results.childNodes[0]);
}
}
function getDetails(result, i) {
return function() {
places.getDetails({
reference: result.reference
}, showInfoWindow(i));
}
}
function mygetDetails(result, i) {
return places.getDetails({
reference: result.reference
}, function(place, status){
if (status == google.maps.places.PlacesServiceStatus.OK) {
addResult(place, i);
}
});
}
function showInfoWindow(i) {
return function(place, status) {
if (iw) {
iw.close();
iw = null;
}
if (status == google.maps.places.PlacesServiceStatus.OK) {
iw = new google.maps.InfoWindow({
content: getIWContent(place)
});
iw.open(map, markers[i]);
}
}
}
function getIWContent(place) {
var content = "";
content += '<table><tr><td>';
content += '<img class="placeIcon" src="' + place.icon + '"/></td>';
content += '<td><b>' + place.name + '</b>';
content += '</td></tr></table>';
return content;
}
$(function(){
$("#autocomplete").keyup(function(){
clearResults1();
geocoder.geocode({"address": $(this).val()}, function(data, status) {
if (status == google.maps.GeocoderStatus.OK) {
$.each(data, function(int_index,value) {
var results = document.getElementById("results1");
var tr = document.createElement('tr');
tr.style.backgroundColor = (int_index% 2 == 0 ? '#F0F0F0' : '#FFFFFF');
var nameTd = document.createElement('td');
var name = document.createTextNode(value.formatted_address);
nameTd.appendChild(name);
tr.appendChild(nameTd);
results.appendChild(tr);
});
}
});
});
});
</script>
<style>
body {
font-family: sans-serif;
}
#map_canvas {
position: absolute;
width: 399px;
height: 399px;
top: 25px;
left: 0px;
border: 1px solid grey;
}
#listing {
position: absolute;
width: 200px;
height: 360px;
overflow: auto;
left: 401px;
top: 65px;
cursor: pointer;
}
#listing1 {
position: absolute;
width: 200px;
height: 360px;
overflow: auto;
left: 601px;
top: 65px;
cursor: pointer;
}
#controls {
width: 200px;
position: absolute;
top: 0px;
left: 400px;
height: 60px;
padding: 5px;
font-size: 12px;
}
.placeIcon {
width: 16px;
height: 16px;
margin: 2px;
}
#resultsTable, #resultsTable1{
font-size: 10px;
border-collapse: collapse;
}
#locationField {
width: 400px;
height: 25px;
top: 0px;
left: 0px;
position: absolute;
}
#autocomplete {
width: 400px;
}
</style>
</head>
<body style="margin:0px; padding:0px;" onLoad="initialize()">
<div id="locationField">
<input id="autocomplete" type="text" />
</div>
<div id="controls">
<form name="controls">
<input type="radio" name="type" value="establishment" onClick="search()" checked="checked"/>All<br/>
<input type="radio" name="type" value="restaurant" onClick="search()" />Restaurants<br/>
<input type="radio" name="type" value="lodging" onClick="search()" />Lodging
</form>
</div>
<div id="map_canvas"></div>
<div id="listing"><table id="resultsTable"><tr><td><h3>Suggested<br>Locations</h3></td></tr><tbody id="results"></tbody></table></div>
<div id="listing1"><table id="resultsTable1"><tr><td><h3>Suggested<br>Address</h3></td></tr><tbody id="results1"></tbody></table></div>
</body>
</html>
This is a working example.

issue with click event in nokia maps api

i try this code
for(i=0; i<num ;i++)
{
points.push([lats[i], lngs[i]]);
if(i==0) str = 'S';
else if(i==num-1) str = 'E';
else str = '';
var marker = new nokia.maps.map.Marker(
[lats[i], lngs[i]],
{
title: str,
visibility: true,
icon: img,
anchor: new nokia.maps.util.Point(5, 5)
});
marker.addListener('click', function(evt){
$('.loc').html(times[i]);
});
map.objects.add(marker);
}
but it just does not fire click event. is anything wrong with code?
lats and lngs and times are defined and points is to be used later.
Edit:
Problem solved. See comment for answer below.
It looks like the problem is with the line:
$('.loc').html(times[i]);
Within the marker listener. The event hasn't got access to the array element when it is fired and therefore fails. I think you need to add an attribute to the marker and access it as shown:
var marker = new nokia.maps.map.Marker(
[lats[i], lngs[i]],
{
title: str,
visibility: true,
icon: img,
anchor: new nokia.maps.util.Point(29, 71),
$html : times[i]
});
marker.addListener('click', function(evt){
//$('.loc').html(times[i]);
alert (evt.target.$html);
});
Try the following (with your own App Id and token of course):
<!DOCTYPE HTML SYSTEM>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9" />
<script type="text/javascript" charset="UTF-8" src="http://api.maps.nokia.com/2.2.3/jsl.js"></script>
<style type="text/css">
html {
overflow:hidden;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
width: 100%;
height: 100%;
position: absolute;
}
#mapContainer {
width:100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
}
</style>
</head>
<body>
<div id="mapContainer"></div>
<script type="text/javascript">
nokia.Settings.set( "appId", "YOUR APP ID GOES HERE");
nokia.Settings.set( "authenticationToken", "YOUR AUTHENTICATION TOKEN GOES HERE");
var mapContainer = document.getElementById("mapContainer");
var DefaultLatitude = 52.516237;
var DefaultLongitude = 13.377686;
var defaultZoomLevel = 16;
var mapOptions =
{
baseMapType: nokia.maps.map.Display.NORMAL,
center: new nokia.maps.geo.Coordinate(DefaultLatitude, DefaultLongitude),
zoomLevel: defaultZoomLevel,
components: [
new nokia.maps.map.component.ZoomBar(),
new nokia.maps.map.component.Behavior(),
new nokia.maps.map.component.Overview(),
new nokia.maps.map.component.ScaleBar(),
new nokia.maps.map.component.ContextMenu()
]
};
var map = new nokia.maps.map.Display(mapContainer, mapOptions);
var str ="";
var img = "http://api.maps.nokia.com/en/playground/examples/maps/res/markerHouse.png";
var points= new Array();
var lats = new Array();
var lngs = new Array();
var times = new Array();
var num;
lats[0] = 52.516237;
lngs[0] = 13.377686;
times[0] = "brandenburg gate";
num = 1;
for(var i=0; i<num ;i++)
{
points.push([lats[i], lngs[i]]);
if(i==0) str = 'S';
else if(i==num-1) str = 'E';
else str = '';
var marker = new nokia.maps.map.Marker(
[lats[i], lngs[i]],
{
title: str,
visibility: true,
icon: img,
anchor: new nokia.maps.util.Point(29, 71),
$html : times[i]
});
marker.addListener('click', function(evt){
//$('.loc').html(times[i]);
alert (evt.target.$html);
});
map.objects.add(marker);
}
</script>
</body>
</html>

Openlayers - display pacific markers popup using marker id and onclick event

I have the following code which addes 3 markers to the map along with there popup boxes what I want to do is have a list of location at bottom of page and using the id of the marker when click a place in the list it just make that places popup appear on the map.
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Open Street Map</title>
<style type="text/css">
body { font: normal 10pt Helvetica, Arial; }
#map { width: 100%; height: 100%; border: 0px; padding: 0px; }
</style>
<script src="lib/OpenLayers.js" type="text/javascript"></script>
<script type="text/javascript">
var iconSize = new OpenLayers.Size(21, 25);
var iconOffset = new OpenLayers.Pixel(-(iconSize.w / 2), -iconSize.h);
var icon = new OpenLayers.Icon("img/fourmarker.png",
iconSize, iconOffset);
var zoom, center, currentPopup, map, lyrMarkers;
var popupClass = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {
"autoSize": true,
"minSize": new OpenLayers.Size(300, 50),
"maxSize": new OpenLayers.Size(500, 300),
"keepInMap": true
});
var bounds = new OpenLayers.Bounds();
function addMarker(id, lng, lat, info) {
var pt = new OpenLayers.LonLat(lng, lat)
.transform(new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject());
bounds.extend(pt);
var feature = new OpenLayers.Feature(lyrMarkers, pt);
feature.closeBox = true;
feature.popupClass = popupClass;
feature.data.popupContentHTML = info ;
feature.data.overflow = "auto";
var marker = new OpenLayers.Marker(pt, icon.clone());
var markerClick = function(evt) {
if (currentPopup != null && currentPopup.visible()) {
currentPopup.hide();
}
if (this.popup == null) {
this.popup = this.createPopup(this.closeBox);
map.addPopup(this.popup);
this.popup.show();
} else {
this.popup.toggle();
}
currentPopup = this.popup;
OpenLayers.Event.stop(evt);
};
marker.events.register("mousedown", feature, markerClick);
lyrMarkers.addMarker(marker);
}
function initMap() {
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
numZoomLevels: 19,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-0.13011, -0.13011, 51.51039, 51.51039)
};
map = new OpenLayers.Map("map", options);
map.addControl(new OpenLayers.Control.DragPan());
var lyrOsm = new OpenLayers.Layer.OSM();
map.addLayer(lyrOsm);
lyrMarkers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(lyrMarkers);
//add marker on given coordinates
addMarker('1',-0.12519,51.51112 , '<b>Tescos</b><br/>Covent garden');
addMarker('2',-0.13264,51.50918 , '<b>Spar</b><br/>Leicester Square');
addMarker('3', -0.12498,51.50807 , '<b>M & S</b><br/>Embankment');
center = bounds.getCenterLonLat();
map.setCenter(center, map.getZoomForExtent(bounds) - 1);
zoom = map.getZoom();
}
</script>
</head>
<body onload="initMap()" style="margin:0; border:0; padding:0; width:1000px; height:500px;">
<div id="map"></div>
</body>
</html>
EXTRA INFORMATION
I am going to add a list to bottom of map like so:
<ul>
<li>location1</li>
<li>location2</li>
<li>location3</li>
</ul>
What i want to get working is when the user clicks so location1 alink then that relevent popup box will show and the other will be removed.
How would this be done.
This very fast example (modify addMarker function):
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Open Street Map</title>
<style type="text/css">
body { font: normal 10pt Helvetica, Arial; }
#map { width: 100%; height: 100%; border: 0px; padding: 0px; }
#list > div { background-color: #aaa; margin-top: 10px; }
</style>
<script src="http://openlayers.org/api/OpenLayers.js" type="text/javascript"> </script>
</head>
<body onload="initMap()" style="margin:0; border:0; padding:0; width:1000px; height:500px;">
<div id="map"></div>
<div id="list" style="width:100%; height: 100%"></div>
</body>
<script type="text/javascript">
var iconSize = new OpenLayers.Size(21, 25);
var iconOffset = new OpenLayers.Pixel(-(iconSize.w / 2), -iconSize.h);
var icon = new OpenLayers.Icon("img/fourmarker.png",
iconSize, iconOffset);
var list = document.getElementById('list');
var zoom, center, currentPopup, map, lyrMarkers;
var popupClass = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {
"autoSize": true,
"minSize": new OpenLayers.Size(300, 50),
"maxSize": new OpenLayers.Size(500, 300),
"keepInMap": true
});
var bounds = new OpenLayers.Bounds();
function addMarker(id, lng, lat, info) {
var pt = new OpenLayers.LonLat(lng, lat)
.transform(new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject());
bounds.extend(pt);
var feature = new OpenLayers.Feature(lyrMarkers, pt);
feature.closeBox = true;
feature.popupClass = popupClass;
feature.data.popupContentHTML = info ;
feature.data.overflow = "auto";
var marker = new OpenLayers.Marker(pt, icon.clone());
var markerClick = function(evt) {
if (currentPopup != null && currentPopup.visible()) {
currentPopup.hide();
}
if (this.popup == null) {
this.popup = this.createPopup(this.closeBox);
map.addPopup(this.popup);
this.popup.show();
} else {
this.popup.toggle();
}
currentPopup = this.popup;
OpenLayers.Event.stop(evt);
};
marker.events.register("mousedown", feature, markerClick);
lyrMarkers.addMarker(marker);
// add items
var listItem = OpenLayers.Util.createDiv(this.id, null, null, null, 'relative', null);
listItem.innerHTML = info;
list.appendChild(listItem);
var callback = function(e) {
marker.events.triggerEvent('mousedown');
console.log(marker);
OpenLayers.Event.stop(e);
};
OpenLayers.Event.observe(listItem, "touchend", OpenLayers.Function.bindAsEventListener(callback, this));
OpenLayers.Event.observe(listItem, "click", OpenLayers.Function.bindAsEventListener(callback, this));
}
function initMap() {
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
numZoomLevels: 19,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-0.13011, -0.13011, 51.51039, 51.51039)
};
map = new OpenLayers.Map("map", options);
map.addControl(new OpenLayers.Control.DragPan());
var lyrOsm = new OpenLayers.Layer.OSM();
map.addLayer(lyrOsm);
lyrMarkers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(lyrMarkers);
//add marker on given coordinates
addMarker('1',-0.12519,51.51112 , '<b>Tescos</b><br/>Covent garden');
addMarker('2',-0.13264,51.50918 , '<b>Spar</b><br/>Leicester Square');
addMarker('3', -0.12498,51.50807 , '<b>M & S</b><br/>Embankment');
center = bounds.getCenterLonLat();
map.setCenter(center, map.getZoomForExtent(bounds) - 1);
zoom = map.getZoom();
}
</script>
</html>

Categories

Resources