Get the ID of a marker on click in Mapbox - javascript

I have an angular view in which I bring data from some points from an api, I use a method to place the markers depending on the coordinates that the api gives me. In addition to the coordinates, the data has an ID.
I need that when I click on the marker in addition to showing me the information to take the ID in some way and save it in a variable to be able to perform functions with that specific point. So far I have this.
map: Mapboxgl.Map; // THE MAP
marker: Mapboxgl.Marker; // THE MARKER
// THE METHOD TO CREATE THE MARKERS ON THE MAP
creteGeoJSON(data) {
data.forEach((element) => {
const el: HTMLElement = document.createElement('div');
el.className = 'marker';
el.style.backgroundImage = 'url(../../../../assets/img/icon.png)';
el.style.width = '30px';
el.style.height = '30px';
el.style.cursor = 'pointer';
el.style.backgroundSize = 'cover';
this.marker = new Mapboxgl.Marker(el)
.setLngLat(
element.coor
.split(',')
.reverse()
.map((x) => +x)
)
.setPopup(
new Mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML(
`<h2>ID: ${element.id} </h2>`
)
)
.addTo(this.map);
this.currentMarkers.push(this.marker);
});
}
// THE FUNCTION TO GET THE LAT AND LONG
getCoords(e) {
this.map.getCanvas().style.cursor = 'pointer';
this.map.on('click', (e) => {
const lat = e.lngLat.lat;
const lng = e.lngLat.lng;
// GET SOME ID
});
}

If you want to do something when the user clicks on a marker, you should add the click event to the marker, not to the map.
A marker contains an HTML element, so you can just do:
marker = new Mapboxgl.Marker(el)
//...
.addTo(map);
el.addEventListener('click', () => {
// in here you have access to the `element` object that contains your data
});

Related

How to add a click event to any of my markers which i have stored in an array

I'm working with leaflet js and I have an array in which i store my markers which are automatically added to the map after the location of the user has been obtained.
problem is that i want to add an onclick listener so that any marker that is clicked will run a function.
please help me out cuz i'm stuck right now.
//objects for markers
var allMarkers=[];
var AllMarkers = L.layerGroup(allMarkers);
var Allpoints=[{
"latitudes":9.4258946,"longitudes":-0.8842213, "names":"first", "eastings":556568, "northings":446445, "description": "aijaskj jnrkajra skjanjanek ", "elevations": 5668
},
{
"latitudes":9.4254946,"longitudes":-0.8812213, "names":"second"},
{
"latitudes":9.4054946,"longitudes":-0.8802213, "names":"third"},
{
"latitudes":9.4754946,"longitudes":-0.8712213, "names":"fourth"},
];
//automatically plot all previous markers
var point = L.point(9.2754946, -0.8912213);
q = 0;
while(q< Allpoints.length){
//create Marker here
_newMarker = L.marker(
[Allpoints[q].latitudes, Allpoints[q].longitudes],
{title: Allpoints[q].names,
riseOnHover: true,
} ).addTo(mymap);
allMarkers.push(_newMarker);
q++
}
//function to send back the details of the clicked marker to a paragraph in my index.htm
//PROBLEM
L.marker('click', markers, showMarkerDetails) //however the code immediately above does not work
function showMarkerDetails(){
$("#returnControlName").html(controlName);
$("#returnControlLocation").html(`${controlLat.toFixed(4)} , ${controlLong.toFixed(4)} `);
$("#returnControlEastings").html(controlEastings);
$("#returnControlName").html(controlNorthings);
$("#returnControlName").html(controlElevation);
$("#returnControlName").html(controlDescription);
}
With L.marker() you add new markers / points to the map, you can't add events like that to them. (L.marker('click', markers, showMarkerDetails) )
Change your code to:
//automatically plot all previous markers
var point = L.point(9.2754946, -0.8912213);
q = 0;
while(q< Allpoints.length){
//create Marker here
_newMarker = L.marker([Allpoints[q].latitudes, Allpoints[q].longitudes],
{title: Allpoints[q].names,
riseOnHover: true,
}).addTo(mymap);
_newMarker.informations = Allpoints[q]; // save the data to the marker to read it later out
_newMarker.on('click',showMarkerDetails); // add click event to the markers
allMarkers.push(_newMarker);
q++
}
function showMarkerDetails(e){
var layer = e.target // get the clicked marker
var infos = layer.informations;
console.log(infos.description);
$("#returnControlName").html(controlName);
$("#returnControlLocation").html(`${controlLat.toFixed(4)} , ${controlLong.toFixed(4)} `);
$("#returnControlEastings").html(controlEastings);
$("#returnControlName").html(controlNorthings);
$("#returnControlName").html(controlElevation);
$("#returnControlName").html(controlDescription);
}

Google maps event - get parent of clicked element

I have function with which I'm making new object 'claster'. In every claster is marker from google maps API. I want to click on this marker and get access to claster.icons[]. I'm binding click event in my function declaration. How to do it?
CODE
function newClaster(_center){
this.centerIco = _center;
this.center = this.centerIco.getPosition();
this.icons = [];
this.icons.push(this.centerIco);
this.addIcon = function(_icon){this.icons.push(_icon)};
this.marker = new google.maps.Marker({
position : this.center,
icon : {
url : 'map/circle.png',
scaledSize : new google.maps.Size(40,40),
size : new google.maps.Size(40,40),
},
map:map,
});
this.setCenter = function(ctr){
this.centerIco = ctr;
this.center = ctr.getPosition();
}
this.findCenter = function(){
this.centerIco = this.icons[parseInt((this.icons.length)%2)];
this.center = this.centerIco.getPosition();
}
google.maps.event.addListener(this.marker, 'click', function(){
this.icons
});
}
I'm binding click on marker.
add a function and send the marker to it on click, then you can get the icons by accessing the marker object:
google.maps.event.addListener(this.marker, 'click', getIcons(this));
function getIcons(marker){
console.log(marker.icons);
}

refresh leaflet map: map container is already initialized

I have a page where given a select to the user he can switch the leaflet map I show.
After a initial leaflet map load, my problem is when i want to refresh the map.
I always get "Map container is already initialized":
The problem line is:
var map = L.map('mapa').setView([lat, lon], 15);
Initially it loads well, but when I select another parameter in the form and want to display the map another time it crashes.
btw, I've tried to destroy and recreate $('#mapa') with jQuery before the second setView() but it shows the same error.
Try map.remove(); before you try to reload the map. This removes the previous map element using Leaflet's library (instead of jquery's).
the best way
map.off();
map.remove();
You should add map.off(), it also works faster, and does not cause problems with the events
Html:
<div id="weathermap"></div>
JavaScript:
function buildMap(lat,lon) {
document.getElementById('weathermap').innerHTML = "<div id='map' style='width: 100%; height: 100%;'></div>";
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttribution = 'Map data © OpenStreetMap contributors,' +
' CC-BY-SA',
osmLayer = new L.TileLayer(osmUrl, {maxZoom: 18, attribution: osmAttribution});
var map = new L.Map('map');
map.setView(new L.LatLng(lat,lon), 9 );
map.addLayer(osmLayer);
var validatorsLayer = new OsmJs.Weather.LeafletLayer({lang: 'en'});
map.addLayer(validatorsLayer);
}
I use this:
document.getElementById('weathermap').innerHTML = "<div id='map' style='width: 100%; height: 100%;'></div>";
to reload content of div where render map.
Before initializing map check for is the map is already initiated or not
var container = L.DomUtil.get('map');
if(container != null){
container._leaflet_id = null;
}
Only use this
map.invalidateSize();
https://github.com/Leaflet/Leaflet/issues/690
well, after much seeking i realized it's well documented at http://leafletjs.com/examples/layers-control.html
i've ended not repainting the map, but print it once and repaint the points on each new ajax call, so the problem was how to clean up the old points and print only the new ones. i've ended doing this:
var point = L.marker([new_marker[0], new_marker[1]]).addTo(map).bindPopup('blah blah');
points.push(point);
//points is a temporary array where i store the points for removing them afterwards
so, at each new ajax call, before painting the new points, i do the following:
for (i=0;i<points.length;i++) {
map.removeLayer(points[i]);
}
points=[];
so far, so good :-)
When you just remove a map, it destroys the div id reference, so, after remove() you need to build again the div where the map will be displayed, in order to avoid the "Uncaught Error: Map container not found".
if(map != undefined || map != null){
map.remove();
$("#map").html("");
$("#preMap").empty();
$( "<div id=\"map\" style=\"height: 500px;\"></div>" ).appendTo("#preMap");
}
What you can try is to remove the map before initialising it or when you leave the page:
if(this.map) {
this.map.remove();
}
I had the same problem on angular when switching page. I had to add this code before leaving the page to make it works:
$scope.$on('$locationChangeStart', function( event ) {
if(map != undefined)
{
map.remove();
map = undefined
document.getElementById('mapLayer').innerHTML = "";
}
});
Without document.getElementById('mapLayer').innerHTML = "" the map was not displayed on the next page.
if you want update map view, for example change map center, you don’t have to delete and then recreate the map, you can just update coordinate
const mapInit = () => {
let map.current = w.L.map('map');
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map.current);
}
const setCoordinate = (gps_lat, gps_long) => {
map.setView([gps_lat, gps_long], 13);
}
initMap();
setCoordinate(50.403723 30.623538);
setTimeout(() => {
setCoordinate(51.505, -0.09);
}, 3000);
You should try to unmount the function in react js to remove the existing map.
const Map = () => {
const mapContainer = useRef();
const [map, setMap] = useState({});
useEffect(()=>{
const map = L.map(mapContainer.current, {attributionControl: false}).setView([51.505, -0.09], 13);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map',
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1
}).addTo(map);
// unmount map function
return () => map.remove();
}, []);
return (
<div style={{padding: 0, margin: 0, width: "100%", height: "100vh",}}
ref={el => mapContainer.current = el}>
</div>
);
}
I had same problem.then i set globally map variable e.g var map= null and then for display map i check
if(map==null)then map=new L.Map('idopenstreet').setView();
By this solution your map will be initialize only first time after that map will be fill by L.Map then it will not be null. so no error will be there like map container already initialize.
For refreshing map in same page you can use below code to create a map on the page
if (!map) {
this.map = new L.map("mapDiv", {
center: [24.7136, 46.6753],
zoom: 5,
renderer: L.canvas(),
attributionControl: true,
});
}
then use below line to refresh the map, but make sure to use same latitude, longitude and zoom options
map.setView([24.7136, 46.6753], 5);
Also, I had the same issue when switching between tabs in the same page using angular 2+, and I was able to fix it by adding below code in Component constructor
var container = L.DomUtil.get('mapDiv');
if (container != null) {
container.outerHTML = ""; // Clear map generated HTML
// container._leaflet_id = null; << didn't work for me
}
use the redrawAll() function rather than renderAll().
We facing this issue today and we solved it. what we do ?
leaflet map load div is below.
<div id="map_container">
<div id="listing_map" class="right_listing"></div>
</div>
When form input change or submit we follow this step below. after leaflet map container removed in my page and create new again.
$( '#map_container' ).html( ' ' ).append( '<div id="listing_map" class="right_listing"></div>' );
After this code my leaflet map is working fine with form filter to reload again.
Thank you.
If you don't globally store your map object reference, I recommend
if (L.DomUtil.get('map-canvas') !== undefined) {
L.DomUtil.get('map-canvas')._leaflet_id = null;
}
where <div id="map-canvas"></div> is the object the map has been drawn into.
This way you avoid recreating the html element, which would happen, were you to remove() it.
For refresh leaflet map you can use this code:
this.map.fitBounds(this.map.getBounds());
I had the same problem on react I solved it by initialized at the top in useEffect
Here is my React Code.
const mapContainerRef = useRef(null);
useEffect( async () => {
const res =await Axios.get(BASE_PATH + 'fetchProperty')
const container = L.DomUtil.get(mapContainerRef.current); if(container != null){ container._leaflet_id = null; }
if(container) {
const mapView = L.map( mapContainerRef.current, {
zoom: 13,
center: [19.059984, 72.889999]
// maxZoom: 13
// minZoom: 15
});
// const canvas = mapView.getCanvasContainer();
mapView.zoomControl.setPosition("bottomright");
mapView.attributionControl.addAttribution(
"<a href='https://mascots.pro'>Mascots. pro</a>"
);
L.tileLayer(
// "https://api.mapbox.com/styles/v1/mapbox/dark-v9/tiles/{z}/{x}/{y}?access_token=" + https://api.mapbox.com/styles/v1/anonymousmw/cko1eb1r20mdu18qqtps8i03p/tiles/{z}/{x}/{y}?access_token=
"https://api.mapbox.com/styles/v1/mapbox/dark-v9/tiles/{z}/{x}/{y}?access_token=" +
access_token,
{
attribution: 'Mascots'
}
).addTo(mapView);
const mask = L.tileLayer.mask(
"https://api.mapbox.com/styles/v1/anonymousmw/cko1eb1r20mdu18qqtps8i03p/tiles/{z}/{x}/{y}?access_token=" +
access_token,
{
attribution: 'Mascots pro',
maskSize: 300
// maxZoom: 18,
// maxNativeZoom: 16
// tms: true
}
)
.addTo(mapView);
mapView.on("mousemove", function (e) {
mask.setCenter(e.containerPoint);
});
res.data.map((marker) => {
const innerHtmlContent = `<div id='popup-container' class='popup-container'> <h3> Property Details</h3>
<div class='popup-label'>Building Name :<p>${marker.Building}</p></div>
<div class='popup-address-label'> Address : <p>${marker.Landmark}, ${marker.Location}</p></div>
<div class='popup-rent-label'>Monthly Rent : <p> ₹ ${marker.Price}</p></div>
</div>`;
const divElement = document.createElement("div");
const assignBtn = document.createElement("div");
assignBtn.className = "map-link";
assignBtn.innerHTML = `<button class="view-btn">View Property</button>`;
divElement.innerHTML = innerHtmlContent;
divElement.appendChild(assignBtn);
assignBtn.addEventListener("click", (e) => {
console.log("dsvsdvb");
});
var iconOptions = {
iconUrl: "/images/location_pin2.svg",
iconSize: [25, 25]
};
var customIcon = L.icon(iconOptions);
// create popup contents
var customPopup = divElement;
// specify popup options
var customOptions = {
maxWidth: "500",
className: "custom"
};
const markerOptions = {
// title: "MyLocation",
// draggable: true
clickable: true,
icon: customIcon
};
const mark = L.marker([marker.Latitude,marker.Longitude], markerOptions);
mark.bindPopup(customPopup, customOptions);
mark.addTo(mapView);
// return mapView.off();
});
return () => mapView.remove();
}
}, [])
return (
<div className="map-box">
<div className="map-container" ref={mapContainerRef}></div>
</div>
);
I went through the same problem, so I created a method inside the map instance to reload it.
var map = L.map('mapa').setView([lat, lon], 15);
map.reload = function(){
map.remove();
map = L.map('mapa').setView([lat, lon], 15);
}
....
map.reload();
I did this in reactjs
// Create map (dev = reuse existing map)
let myMap = L.DomUtil.get('map');
if(myMap == null){
myMap = L.map('mapid').setView(currentLocation, zoom);
}
Html:
<div id='leaflet-map' #leafletMap></div>
JavaScript:
#ViewChild('leafletMap')
private mapElement: ElementRef;
private initMap(): void {
this.map = leaflet.map(this.mapElement.nativeElement, {
center: [39.01860177826393, 35.30274319309024],
zoom: 4,
});
leaflet
.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '',
maxZoom: 18,
})
.addTo(this.map);
}
My hacky implementation to refresh the map was to use:
// Hack to refresh the map by panning by zero
public refreshMap() {
this.map.panBy([0,0]);
}
In case you're working with NextJs and typescrypt, what worked for me was
container._leaflet_id = null;
as someone proposed, but had some typing erros so my approach is
const L = await import('leaflet');
const container = L.DomUtil.get('map');
if (!container) return;
if (container.classList.contains('leaflet-container')) return;
const map = L.map('map', {
center: [19.434817, -99.1268643],
zoom: 18,
});
map.invalidateSize();
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
}).addTo(map);
const marker = L.marker([19.434786638353515, -99.1268643025101]).addTo(
map
);
after this code, (all these code needs to be inside a useEffect hook), leaflet just worked fine.
set
var container = L.DomUtil.get('map');
if (container && container['_leaflet_id'] != null) {
container.remove();
}
before var map = L.map('map')
enjoy :)
For web apps, check these things
I've experienced the error "Map container is already initialized" in multiple contexts (e.g. showing/hiding a map, changing map components or triggering hot-reload during development) and ultimately I had to implement multiple solutions to truly clear this error. In general you want to be conservative.
(A) Use a unique ID for the map container
Even if you have only one map instance, use a dynamic unique id anyways. This way you're ensured that every time the component mounts, the DOM element truly is fresh.
For example, in Vue I do this:
<div :id="id"></div>
data() {
return {
id: 'mapLeaflet-'+Date.now()
}
}
And anywhere I refer to the DOM element, I use this.id:
let mapHTMLContainer = document.getElementById(this.id)
(B) Before map init, check existence of map first
Check for DOM element and whether you already have a map instance set in data.
In Vue, I do this:
methods: {
initMap() {
let mapHTMLContainer = document.getElementById(this.id)
if (mapHTMLContainer
&& mapHTMLContainer.hasChildNodes() == false
&& !this.map) {
// DO STUFF
// e.g. initialize leaflet, set tile layer, add markers, etc
}
}
}
(C) On map init, pass the actual HTML element, not just a string
When initiating Leaflet map, pass the actual HTML element instead of just the string id.
Both methods are officially supported, but I cannot find any information talking about the differences. https://leafletjs.com/reference.html#map-l-map
BEFORE
This works in general and is convenient...
this.map = L.map("mymap")
AFTER
... but, instead try to actually get the element, and pass it. I observed a difference doing this.
let myMapElement = document.getElementById(this.id)
this.map = L.map(myMapElement)
(D) On component "dismount", destroy things
If you have a dismount state, use it and destroy stuff related to your map component. Make sure things don't hang-around.
In Vue, I do this:
beforeDestroy() {
// Destroy any listeners
this.$nuxt.$off('refreshMap') // Nuxt is the framework I use
// Clear the map instance in your component
if (this.map) {
// I haven't fully tested these; are they valid?
this.map.off() // Leaflet function
this.map.remove() // Leaflet function
this.map = null // null it for good measure
}
// Clear out the HTML container of any children, just in case
let mapHTMLElement = document.getElementById(this.id)
if (mapHTMLElement) {
mapHTMLElement.outerHTML = ""
}
}

Google Maps API v.3 Clearing and adding markers on marker click

I am pulling markers from a MySQL database table of locations, which uses a nested set model for hierarchical categorization.
That part is working well.
I can place all markers on the map, using MarkerManager to show/hide at different zoom levels (using the 'depth' field from my table). That works nicely.
My issue is that if a marker for a country is clicked on, I would like all markers outside that country to be removed. Getting a single country's markers is trivial, I just feed a parent id to the xhr function. But clearing the markers... this is stumping me. I've been working at it for days, and just can't seem to make headway.
Here is the business-end of the JS
var map = new google.maps.Map(document.getElementById('gMap'), mapOptions);
// init the markerManager
var mgr = new MarkerManager(map);
//Associate the styled map with the MapTypeId and set it to display.
map.mapTypes.set('Dark', darkMap);
map.mapTypes.set('Light', lightMap);
map.setMapTypeId('Dark');
// lat lng bounds for center/zoom marker
var bounds = new google.maps.LatLngBounds();
// infowindow (infobox)
// init here, and re-use
var ib = new InfoBox();
var oldDraw = ib.draw;
ib.draw = function() {
oldDraw.apply(this);
jQuery(ib.div_).hide();
jQuery(ib.div_).fadeIn('slow');
}
// init marker list
// for removing 'old' markers and loading new ones
var markersArray= [];
// load markers from database
function loadMarkers(params) {
var params = params || {};
var pid = params.pid || 5;
deleteOverlays(pid,function(){
// alert("deleteOverlays(" + pid + ");")
$.getJSON('/map/xhr_get_descendants', {
pid : pid
}, function(data) {
var bounds = new google.maps.LatLngBounds();
$.each(data, function(key, val) {
if (val.lat_long && val.lat_long != '') {
var name = val.name;
var id = val.id;
var depth = val.depth;
var children = val.children;
var pos = val.lat_long.split(',');
var lat = parseFloat(pos[0]);
var long = parseFloat(pos[1]);
var myLatLng = new google.maps.LatLng(lat, long);
var html = "<b>NAME=>" + name + "\nID=>" + id + "\nDEPTH=>" + depth+"</b>";
var marker = new google.maps.Marker({
position : myLatLng
});
mgr.addMarker(marker, depth);
markersArray.push(marker);
var boxText = document.createElement("div");
google.maps.event.addListener(marker, 'mouseover', function() {
/*
getStats(id);
// */
boxText.innerHTML = html;
var infoBoxOptions = {
content : boxText,
disableAutoPan : true,
maxWidth : 0,
pixelOffset : new google.maps.Size(-140, 0),
zIndex : null,
boxClass : "infoBox",
closeBoxMargin : "2px 2px 2px 2px",
closeBoxURL : "http://www.google.com/intl/en_us/mapfiles/close.gif",
infoBoxClearance : new google.maps.Size(10, 10),
isHidden : false,
pane : "floatPane",
enableEventPropagation : false,
};
ib.setOptions(infoBoxOptions);
ib.open(map, marker);
})
google.maps.event.addListener(marker, 'mouseout', function() {
ib.close();
})
google.maps.event.addListener(marker, 'click', function() {
map.panTo(this.getPosition());
// getLinks(id);
if (children > 0) {
loadMarkers({
pid : id
});
}
})
bounds.extend(myLatLng);
}
});
map.fitBounds(bounds);
});
});
}
// clear markers
function deleteOverlays(pid,callback){
if((markersArray)&&(markersArray.length > 1)) {
for (var x in markersArray) {
markersArray[x].setMap(null);
markersArray[x]=null;
}
markersArray=[];
};
callback(pid);
}
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}
loadMarkers({
pid:5
});
So quickly, you can see that I send a parent id to the loadMarkers() among other things if necessary, and do some stuff, and then I call the deleteMarkers() function, the callback of which creates the markers, adds them to the manager and to the main markersArray[]
for brevity I'm not going to add the full Ajax call to xhr_get_descendants/ because without the Model it would be a bit meaningless.
Anyway, the function returns id, name, depth of each "child" of the parent id provided, as well as how many children each one of those children might have.
I mean... this should work!!! LOL
I've been looking at it wayyyy too long. I'd seriously appreciate any suggestions, or hints, or even a "why the hell are you doing it this way?"
The markers displayed by the MarkerMangager are not the markers you create (and supply as argument to mgr.addMarker() ), the MarkerManager creates new Instances and these Instances will not be deleted when you delete the Markers stored in markersArray(what doesn't have any visual effect, because the markers stored in markersArray are not visible)
You may call mgr.clearMarkers() in deleteOverlays() to delete also the Instances created by the MarkerManager, but the complete approach with the markersArray is unnecessary. You don't need this array at all, simply call mgr.clearMarkers() to remove the visible Markers.

google maps API3 drawing custom map icon based on user selection

Im working on a google maps plugin (there's always room for another right?) and I'm drawing a preview of the map my users will be inserting into their content. Im able to draw everything I set out to, custom content in the info window, setting the location (through places.Autocomplete) etc. The one thing that is escaping me is custom map icon isn't being drawn.
My goal is to have the default icon drawn on first load, and then update it when it changes
Im not getting any 404 or errors in the console, and I've checked my event handlers and they are all working. Can anyone tell me where I've going astray?
Here is what I have so far:
//Initilize the map
google.maps.event.addDomListener(window, 'load', initialize);
function initialize(infowindow) {
var init_center = new google.maps.LatLng(43.703793, -72.326187);
mapOptions = {
center: init_center,
zoom: parseFloat(mapZoomReturn),
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel : false,
};
var input = document.getElementById('mapAddress');
var autocomplete = new google.maps.places.Autocomplete(input);
var infowindow = new google.maps.InfoWindow();
//var marker = new google.maps.Marker({
// position: init_center,
// map: map,
// icon: mapMarkerImageReturn
//});
// Draw the map
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
// marker needs to be set after the map
var marker = new google.maps.Marker({
position: init_center,
map: map,
icon: mapMarkerImageReturn
});
// Set up event listeners
// Info window DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapInfoWindow'),
'change', function() {
mapInfoWindowReturn = escape(jQuery('#mapInfoWindow').val());
// get the extra content from feild, by this time the place_changed even will have fired at least once, so we have these values
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn); // returns formatted markup for info bubble
infowindow.setContent(infowindowPlace);
});
// Marker dropdown selection DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapMarker'), 'change', update_maker);
// Custom marker text field DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapMarkerImage'), 'change', update_maker );
function update_maker(){
//update the marker imge - (not working)
markerImage = get_marker_image(); // returns URL as string
marker.setIcon(markerImage);
marker.setPosition(locPlace.geometry.location);
marker.setMap(map);
}
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn);
infowindow.close();
if (mapMarkerImageReturn !=='' || mapMarkerImageReturn !== false) marker.setVisible(false);
input.className = '';
locPlace = autocomplete.getPlace();
if (!locPlace.geometry) {
// Inform the user that the place was not found and return.
input.className = 'notfound';
return;
}
// If the place has a geometry, then present it on a map.
if (locPlace.geometry.viewport) {
map.fitBounds(locPlace.geometry.viewport);
mapCurrCenter = map.getCenter();
} else {
map.setCenter(locPlace.geometry.location);
map.setZoom(parseFloat(mapZoomReturn));
mapCurrCenter = map.getCenter();
}
// Set the marker image (not working)
markerImage = get_marker_image(); // returns URL as string
marker.setIcon(markerImage);
marker.setPosition(locPlace.geometry.location);
marker.setMap(map);
// get the location values for the info bubble
if (locPlace.address_components) {
//console.log(locPlace.address_components);
// Populate values for info bubble
locName = locPlace.name;
locIcon = locPlace.icon;
locAddress = locPlace.formatted_address;
locPhone = locPlace.formatted_phone_number;
locWeb = locPlace.website;
}
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn);
infowindow.setContent(infowindowPlace);
infowindow.open(map, marker);
});
}

Categories

Resources