I have a map, which populates markers based on search. I'm attempting to user the newer google maps feature AdvancedMarkerView so I can fill it with custom HTML - however, as my search updates, I want to flush the old markers and place new ones when it's called for...and I can't for the life of me figure out how to? https://developers.google.com/maps/documentation/javascript/reference/advanced-markers
The following places the custom markers. It works.
const content = document.createElement('div');
content.className = 'marker-title';
content.textContent = item.title;
const marker = new google.maps.marker.AdvancedMarkerView({
map,
position: item.position,
content
});
Normally for markers, as in the old markers, I've removed them with the following code, markers.forEach((marker) => marker.setMap(null)) however this doesn't seem to work for the advanced markers. Since the marker returned when creating the advanced marker points to the element, I also tried doing a marker.remove() thinking the HTML element would be targeted, but no cigar.
I haven't been able to find any concrete examples on the Google API docs, when it comes to advanced markers, and same for others asking the same question.
There is no setMap() or other method to call on the AdvancedMarkerView class to toggle its visibility or remove it from the map.
Although it is not super clear, the documentation says:
To remove a marker from the map, set the markerView.map property to null.
Working example below:
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 37.39094933041195, lng: -122.02503913145092 },
zoom: 14,
mapId: "4504f8b37365c3d0",
});
const draggableMarker = new google.maps.marker.AdvancedMarkerView({
map,
position: { lat: 37.39094933041195, lng: -122.02503913145092 },
draggable: true,
title: "This marker is draggable. Click to remove.",
});
draggableMarker.addListener("click", (event) => {
// Remove AdvancedMarkerView from Map
draggableMarker.map = null;
});
map.addListener("click", (event) => {
// Set AdvancedMarkerView position and add to Map
draggableMarker.position = event.latLng;
draggableMarker.map = map;
});
}
window.initMap = initMap;
#map {
height: 160px;
}
p {
font-family: Arial;
font-size: 0.75em;
margin: 2px 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Draggable Advanced Marker</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<p>Click marker to remove it from map. Click on map to reposition / add marker.</p>
<div id="map"></div>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=marker&v=beta"
defer
></script>
</body>
</html>
Related
I am using the google maps API in angular 10, and I am finding some inconsistencies with toggling a DROP animation.
The JSFiddle on the official documenation has a demo toggling the bounce animation.
However, my use case is having multiple markers on a map, each time a marker is clicked, it will DROP in (not bounce). I've tried altering the JSFiddle to make this work by adding a second marker to the map and using a toggle for both.
I can't find a lot of documentation on the Marker.animation and Marker.animating properties for the different animations. I suspect that when a marker has the DROP animation, these 2 properties are set to null after the animation has completed.
marker.addListener('click', () => marker.setAnimation(google.maps.Animation.DROP))
The above does not work.
To get the marker to drop again, set the map property to null (removing it from the map), then set the animation again, and add the marker to the map.
marker.setMap(null);
marker.setAnimation(google.maps.Animation.DROP);
marker.setMap(map);
proof of concept fiddle
code snippet:
// The following example creates a marker in Stockholm, Sweden using a DROP
// animation. Clicking on the marker will toggle the animation between a BOUNCE
// animation and no animation.
let marker;
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 13,
center: {
lat: 59.325,
lng: 18.07
},
});
marker = new google.maps.Marker({
map,
draggable: true,
animation: google.maps.Animation.DROP,
position: {
lat: 59.327,
lng: 18.067
},
});
marker.addListener("click", function() {
toggleDrop(map);
});
}
function toggleDrop(map) {
marker.setMap(null);
marker.setAnimation(google.maps.Animation.DROP);
marker.setMap(map);
}
/* 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;
}
<!DOCTYPE html>
<html>
<head>
<title>Marker Animations</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="map"></div>
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly" async></script>
</body>
</html>
I'm trying to write a little web app that will map some locations on a map using Google's Maps JavaScript API. Working with the API is going well, but I'm trying to manipulate their example code and I cannot get the array of data to work unless it's declared withing the Map initialization function. I've been digging for what I am not understanding about Javascript variable access, but I can't figure it out. Ideally I would like to put the array of data in a separate <script> tag so I can load it from another file, but I can't even get the data to work if placed right above the function within the same <script> tag.
I here is a simplified version of the code that I cannot get to work. It won't run because I removed my key from the call to the API, but if that's needed to find the problem I can give it out too.
<html>
<head>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
// <script src="...">
// where I really want to load let locations = .... from a file
// </script>
<script>
// where i tried to move let locations = .... without success
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 2.7,
center: new google.maps.LatLng(18,0)
});
let locations = [
{
name: 'MJ Cave',
position: new google.maps.LatLng(47.517869, 19.036026)
}, {
name: 'Protec Tulum',
position: new google.maps.LatLng(20.216557, -87.460052)
}, {
name: 'Giraffe Manor',
position: new google.maps.LatLng(-1.375528, 36.744634)
}
];
function placeMarker( loc ) {
const marker = new google.maps.Marker({
position : loc.position,
map : map
});
}
// ITERATE ALL LOCATIONS. Pass every location to placeMarker
locations.forEach( placeMarker );
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=MYKEY&callback=initMap">
</script>
</body>
</html>
Problem solved.
Taking the new google.maps.latlng() calls out of the initMap() function was the problem because that datatype isn't necessarily defined at the time that code runs apparently. Changed the location position object to be defined by an array of two numbers and then made them into a google.maps.latlng in function. Works as desired now. For postarity here's my changed code:
<script>
let locations = [
{
name: 'MJ Cave',
position: [47.517869, 19.036026]
}, {
name: 'Protec Tulum',
position: [20.216557, -87.460052]
}, {
name: 'Giraffe Manor',
position: [-1.375528, 36.744634]
}
];
</script>
<script type="text/javascript">
function initMap() {
const infowindow = new google.maps.InfoWindow();
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 2.7,
center: new google.maps.LatLng(18,0)
});
function placeMarker( loc ) {
const marker = new google.maps.Marker({
position : { lat: loc.position[0], lng: loc.position[1]},
icon: icons[loc.type].icon,
map : map
});
// ITERATE ALL LOCATIONS. Pass every location to placeMarker
locations.forEach( placeMarker );
}
</script>
I have a KMZ file that i load into my google maps application via link using javascript. The file works perfectly in Google Earth. The problem is in my application when i click in one of the many elements (areas): the returned description data is always from only one of the elements, not displaying the actual clicked, correct, element. This is what i've tried:
Check if the click event in the map is correct by placing a marker in the clicked position, it is correct.
Convert the data into KML using Google Earth, place it into my google drive as public, and using a direct download link from google drive in my application. It displayed the data but the error continued.
Created the most basic/blank application using just the layer to make sure anything else in my other application is interfering. Also didn't work.
The file is in this website: https://www.voanaboa.pt/codigo-drone named as "Regulamento RPA_ver_5.0.kmz”
Here's the only file that creates a basic application using the kmz file, i've removed my API key for privacy.
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<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;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
var kmlLayer = new google.maps.KmlLayer();
var src = 'https://www.voanaboa.pt/Files/downloads/Regulamento-RPA-ver-5.0.kmz';
var kmlLayer = new google.maps.KmlLayer(src, {
//suppressInfoWindows: true,
preserveViewport: false,
map: map
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&libraries=geometry&callback=initMap"
async defer></script>
Most (but not all) of your placemarks have the same ID "ID_00000"). If I change that to be unique, the polygon's descriptions become unique:
example with unique ids
Per the KML reference, that doesn't have to be unique (it is a "stanard XML ID", but I am guessing the rendering code is assuming it is.
code snippet with updated kmz file:
/* 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>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 8
});
var kmlLayer = new google.maps.KmlLayer();
var src = 'http://www.geocodezip.com/geoxml3_test/kmz/Regulamento-RPA-ver-5.0a.kmz';
var kmlLayer = new google.maps.KmlLayer(src, {
//suppressInfoWindows: true,
preserveViewport: false,
map: map
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&callback=initMap" async defer></script>
(I'm very noob with this. I'm learning on my own, I know my code is messy.)
I am working with Google Maps API, and I want the user to click a button (either Restaurant 1 or Restaurant 2) and then have the map pan to the location of that restaurant, using a marker and a InfoWindow above. Simple, right?
Here's my HTML code so far.
<!DOCTYPE html>
<html>
<title>W3.CSS Template</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="estilo.css">
<link rel="stylesheet" href="fuente1.css">
<link rel="stylesheet" href="fuente2.css">
<style>
html,body,h1,h2,h3,h4,h5,h6 {font-family: "Roboto", sans-serif}
</style>
<body class="w3-light-grey">
<!-- Page Container -->
<div class="w3-content w3-margin-top" style="max-width:1400px;">
<!-- The Grid -->
<div class="w3-row-padding">
<!-- Left Column -->
<div class="w3-third">
<div class="w3-white w3-text-grey w3-card-4">
<div class="w3-container">
<img><br>Choose a restaurant<p><br>
<button id="button" style="width:110px;height:30px;cursor:pointer;">Restaurant 1</button>
<button id="button2" style="width:110px;height:30px;cursor:pointer;">Restaurant 2</button>
<!-- End Left Column --> </p>
</div>
</div>
</div>
<!-- Right Column -->
<div class="w3-twothird">
<div class="w3-container w3-card w3-white w3-margin-bottom">
<h2 class="w3-text-grey w3-padding-16"><i class="fa fa-suitcase fa-fw w3-margin-right w3-xxlarge w3-text-blue"></i>
MAP
</h2><div class="w3-container">
<html>
<body>
<div id="map" style="width:555px;height:500px"></div>
<script>
function myMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(31.825948, -116.599869),
zoom: 16
});
}
function addmarker(lat, lon) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lon),
map: map
});
map.panTo(new google.maps.LatLng(lat, lon));
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBQ3QnkneaUIsXaJHZtYwqdWxX9KCMj4CA&callback=myMap">"></script>
</body>
</html>
<br><br>
</div>
</div>
<!-- End Right Column -->
</div>
<!-- End Grid -->
</div>
<!-- End Page Container -->
</div>
</body>
</html>
</body>
</html>
As you can see I have everything set up. The only thing that doesn't work are the buttons.
I have the following Javascript but I have no idea whatsoever on how to implement it in my HTML.
$('#button').click(function() {
addmarker('-22.3157017', '-49.0660877');
});
$('#button2').click(function() {
addmarker('-23.5936152', '-46.5856465');
});
I'll be happy to hear any lectures for this affair and any help will be greatly appreciated.
For reference, I want it to work pretty much like this one. Place marker on google maps api with html button
I did not use your markup - I've created my own.
Upon checking your javascript, everything seems well, except of these two things: missing jQuery library and the code placement of your button event handlers.
It seems you are trying to add Google Maps Javascript API Markers to these locations "-22.3157017,-49.0660877" and "-23.5936152,-46.5856465" by pressing their corresponding triggers (buttons). I would suggest doing a Reverse Geocoding before adding the markers once an event has been fired.
The term geocoding generally refers to translating a human-readable
address into a location on a map. The process of doing the converse,
translating a location on the map into a human-readable address, is
known as reverse geocoding.
You should also add jQuery as an external library to make their events such as ".click()" to work. You can download it here.
For the buttons, you should add these lines $('#button1').click(function()); and $('#button1').click(function()); inside your myMap() function.
It should look something like this:
function myMap() {
var myLatLng = {lat: 31.825948, lng: -116.599869};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
$('#button1').click(function(){
var coord = { lat: parseFloat('-22.3157017'), lng: parseFloat('-49.0660877') };
addMarker( coord, map );
});
$('#button2').click(function(){
var coord = { lat: parseFloat('-23.5936152'), lng: parseFloat('-46.5856465') };
addMarker( coord, map );
});
}
On your addMarker function, add two arguments that accepts the coordinates, and the map object.
function addMarker(params, map) {);
Inside that function, create a variable geocoder and the value is a new instance of google.maps.Geocoder().
var geocoder = new google.maps.Geocoder();
With that, you can now use geocode method. Geocode method accepts two arguments: location and callback. In the location parameter, you need to supply the coordinates you acquired from the addMarker() function.
geocoder.geocode({'location' : params}, function( results, status ) {});
The callback is the part where most of our logic will be implemented. The callback accepts two arguments: results, and status. The results argument returns an array of results if the status is OK. If so, we will now iterate through each array element and then create a new Google Maps Javascript API Markers. On the markers, we'll just supply the coordinates and maps object for its position and map property.
if (status === 'OK') {
var result = results.map( function( value, index ){
map.setCenter(params);
var newMarker = new google.maps.Marker({
position : params,
map : map,
});
});
} else {
alert('Geo not successful: ' + status);
}
This line 'map.setCenter(params);' sets the position displayed by the map.
Whole code below:
<button id="button1">Restaurant 1</button>
<button id="button2">Restaurant 2</button>
<div id="map"></div>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCzjs-bUR6iIl8yGLr60p6-zbdFtRpuXTQ&callback=myMap">
</script>
function myMap() {
var myLatLng = {lat: 31.825948, lng: -116.599869};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
$('#button1').click(function(){
var coord = { lat: parseFloat('-22.3157017'), lng: parseFloat('-49.0660877') };
addMarker( coord, map );
});
$('#button2').click(function(){
var coord = { lat: parseFloat('-23.5936152'), lng: parseFloat('-46.5856465') };
addMarker( coord, map );
});
}
function addMarker(params, map) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'location' : params}, function( results, status ) {
if (status === 'OK') {
var result = results.map( function( value, index ){
map.setCenter(params);
var newMarker = new google.maps.Marker({
position : params,
map : map,
animation: google.maps.Animation.DROP,
});
});
} else {
alert('Geo not successful: ' + status);
}
});
}
Hope it could help and happy coding!
I have answered this before on stackoverflow for how to show icons and infowindow and just updated my fiddle to use https instead. Following are very simple steps you need to take care of.
When you click on that fiddle you will see all HTML, JS and CSS I have used to show icons on map, list of people on car and interactivity to click on them to centre on map.
Using gmap3 library I have inlcuded google map on page
Using List elements I have coded location of items at <li data-gb="car" data-mapid="sc102" data-isactive="0" data-lat="53.538566" data-long="-0.327017199999951">Second Car</li> in data attributes for each item. It can be restuarants, parks etc
Important bits in code are in Javascript and these are
Events and Addmarker actions as well as logic to click on list items.
{ action: 'addMarkers',
marker:{
values:ulmarkerspeople,
options:{
draggable: false,
icon:'http://webricate.com/stackoverflow/mapicons/male-2.png'
},
events:{
mouseover: function(marker, event, context){
var listelement = jQuery("li[data-mapid='"+context.data.id+"']");
jQuery(listelement).attr('style','background-color:#ccc');
jQuery(listelement).attr('data-isactive','1');
var map = $(this).gmap3("get"),
infowindow = $(this).gmap3({get:{name:"infowindow"}});
if (infowindow){
infowindow.open(map, marker);
infowindow.setContent(context.data.ht);
jQuery("#customPopup").html(context.data.ht);
jQuery("#customPopup").show(500);
} else {
$(this).gmap3({
infowindow:{
anchor:marker,
options:{content: context.data.ht}
}
});
jQuery("#customPopup").html(context.data.ht);
jQuery("#customPopup").show(500);
}
},
mouseout: function(marker,event,context){
var listelement = jQuery("li[data-mapid='"+context.data.id+"']");
jQuery(listelement).attr('style','background-color:#fff');
jQuery(listelement).attr('data-isactive','0');
var infowindow = $(this).gmap3({get:{name:"infowindow"}});
if (infowindow){
infowindow.close();
jQuery("#customPopup").hide(500);
jQuery("#customPopup").html("");
}
}
}
}
}
Please read through Javascript comments on fiddle and you will get the gist of it.
I found exactly the same question for Java, but I'd like to do that in JS. So, how to add text above a marker on Google Maps in JS?
As stated in my comment, You can use multiple letters for the map marker label.
If you use the label property when instantiating a new google.maps.Marker class, you pass it an object, with one of the properties text.
var marker = new google.maps.Marker({
position: new google.maps.LatLng(0, 0),
icon: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',
label: { color: '#00aaff', fontWeight: 'bold', fontSize: '14px', text: 'Your text here' }
});
Check the fiddle here.
I think what you're looking for isn't included in the standard library. Google do provide this interesting utility library though so you can make your own markers, labels. The one you want is the MarkerWithLable class. From the link:
This class behaves like google.maps.Marker, but it supports the
association of a label with the marker. If the marker is draggable,
so too will be the label. In addition, a marker with a label responds
to all mouse events in the same manner as a regular marker. It also
fires mouse events and "property changed" events just as a regular
marker would.
Looks like it's used in much the same way a the standard Marker class and there appears to be ample examples of it's use kicking around so good luck and I hope that this was helpful :)
I've attached a quick implementation of the infowindow. Be sure to replace my API_KEY with yours as I've only allowed access to the stack snippets url.
This code snippet creates an infowindow. In the example, the infowindow is called instantly after being created to display it's content above the marker.
<!DOCTYPE html>
<html>
<head>
<style>
#map {
height: 400px;
width: 100%;
}
</style>
</head>
<body>
<h3>My Google Maps Demo</h3>
<div id="map"></div>
<script>
function initMap() {
var uluru = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: uluru
});
var infowindow = new google.maps.InfoWindow({
content: 'Welcome to stackoverflow!'
});
var marker = new google.maps.Marker({
position: uluru,
map: map
});
infowindow.open(map, marker);
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_MAPS_API_KEY&callback=initMap">
</script>
</body>
</html>
To only show the infowindow when the marker is clicked, wrap it inside of a listener:
marker.addListener('click', function() {
infowindow.open(map, marker);
});