PageSourceSearch

https://atlanticmanagement.com/wp-content/plugins/wp-google-maps/j…/google-map.js?ver=10.1.08+pro-10.0.07

js atlanticmanagement.com collected 2026-10-07 00:19:16 UTC 18,544 bytes, 775 lines download raw bytes

1/**
2 * @namespace WPGMZA
3 * @module GoogleMap
4 * @requires WPGMZA.Map
5 * @pro-requires WPGMZA.ProMap
6 */
7jQuery(function($) {
8	var Parent;
9	
10	/**
11	 * Constructor
12	 * @param element to contain the map
13	 */
14	WPGMZA.GoogleMap = function(element, options)
15	{
16		var self = this;
17		
18		Parent.call(this, element, options);
19		
20		this.loadGoogleMap();
21		
22		if(options){
23			this.setOptions(options, true);
24		} else {
25			this.setOptions({}, true);
26		}
27
28		google.maps.event.addListener(this.googleMap, "click", function(event) {
29			var wpgmzaEvent = new WPGMZA.Event("click");
30			wpgmzaEvent.latLng = {
31				lat: event.latLng.lat(),
32				lng: event.latLng.lng()
33			};
34			self.dispatchEvent(wpgmzaEvent);
35		});
36		
37		google.maps.event.addListener(this.googleMap, "rightclick", function(event) {
38			var wpgmzaEvent = new WPGMZA.Event("rightclick");
39			wpgmzaEvent.latLng = {
40				lat: event.latLng.lat(),
41				lng: event.latLng.lng()
42			};
43			self.dispatchEvent(wpgmzaEvent);
44		});
45		
46		google.maps.event.addListener(this.googleMap, "dragend", function(event) {
47			self.dispatchEvent("dragend");
48		});
49		
50		google.maps.event.addListener(this.googleMap, "zoom_changed", function(event) {
51			self.dispatchEvent("zoom_changed");
52			self.dispatchEvent("zoomchanged");
53		});
54		
55		// Idle event
56		google.maps.event.addListener(this.googleMap, "idle", function(event) {
57			self.onIdle(event);
58		});
59
60		if(this.googleMap.getStreetView()){
61			// Bind streetview events
62			google.maps.event.addListener(this.googleMap.getStreetView(), "visible_changed", function(){
63				var wpgmzaEvent = new WPGMZA.Event("streetview_visible_changed");
64
65				wpgmzaEvent.visible = this.getVisible();
66
67				self.dispatchEvent(wpgmzaEvent);
68			});
69
70			google.maps.event.addListener(this.googleMap.getStreetView(), "position_changed", function(){
71				var wpgmzaEvent = new WPGMZA.Event("streetview_position_changed");
72
73				const position = this.getPosition();
74				if(position){
75					wpgmzaEvent.latLng = {
76						lat: position.lat(),
77						lng: position.lng()
78					};
79				}	
80
81				wpgmzaEvent.visible = this.getVisible();
82
83				self.dispatchEvent(wpgmzaEvent);
84			});
85
86			google.maps.event.addListener(this.googleMap.getStreetView(), "pov_changed", function(){
87				var wpgmzaEvent = new WPGMZA.Event("streetview_pov_changed");
88
89				const pov = this.getPov();
90				if(pov){
91					wpgmzaEvent.pov = {
92						heading: pov.heading,
93						pitch: pov.pitch
94					};
95				}	
96
97				wpgmzaEvent.visible = this.getVisible();
98
99				self.dispatchEvent(wpgmzaEvent);
100			});
101		}
102		
103		// Dispatch event
104		if(!WPGMZA.isProVersion())
105		{
106			this.trigger("init");
107			
108			this.dispatchEvent("created");
109			WPGMZA.events.dispatchEvent({type: "mapcreated", map: this});
110			
111			// Legacy event
112			$(this.element).trigger("wpgooglemaps_loaded");
113		}
114	}
115	
116	// If we're running the Pro version, inherit from ProMap, otherwise, inherit from Map
117	if(WPGMZA.isProVersion())
118	{
119		Parent = WPGMZA.ProMap;
120		WPGMZA.GoogleMap.prototype = Object.create(WPGMZA.ProMap.prototype);
121	}
122	else
123	{
124		Parent = WPGMZA.Map;
125		WPGMZA.GoogleMap.prototype = Object.create(WPGMZA.Map.prototype);
126	}
127	WPGMZA.GoogleMap.prototype.constructor = WPGMZA.GoogleMap;
128	
129	WPGMZA.GoogleMap.parseThemeData = function(raw)
130	{
131		var json;
132		
133		try{
134			json = JSON.parse(raw);	// Try to parse strict JSON
135		}catch(e) {
136			var str = raw;
137			
138			str = str.replace(/\\'/g, '\'');
139			str = str.replace(/\\"/g, '"');
140			str = str.replace(/\\0/g, '\0');
141			str = str.replace(/\\\\/g, '\\');
142			
143			try{
144				json = JSON.parse(str);
145			}catch(e) {
146				console.warn("Couldn't parse theme data");
147				return [];
148			}
149		}
150
151		/* As of 2023-04-28 Google Maps themes must contain array with each item being a defined object. This means older theme definitions
152		 * will cause initialization issues as they may contain only keyname like ["visibility", "weight"] 
153		 * 
154		 * We will attempt to catch these and return the default theme instead of breaking the map 
155		*/
156		if(json instanceof Array){
157			try{
158				for(let data of json){
159					if(!(data instanceof Object)){
160						/* This key is not an object, it's safe to assume the theme has been corrupted */
161						return [];
162					}
163				}
164			} catch (ex){
165				/* Loop failed, for validation, return default */
166				return [];
167			}
168		} else {
169			/* Not array, something failed, default */
170			return [];
171		}
172		
173		return json;
174	}
175	
176	/**
177	 * Creates the Google Maps map
178	 * @return void
179	 */
180	WPGMZA.GoogleMap.prototype.loadGoogleMap = function()
181	{
182		var self = this;
183		var options = this.settings.toGoogleMapsOptions();
184		
185		options = this.extendNativeConfig(options);
186		
187		this.googleMap = new google.maps.Map(this.engineElement, options);
188		
189		google.maps.event.addListener(this.googleMap, "bounds_changed", function() { 
190			self.onBoundsChanged();
191		});
192
193		if(this.settings.bicycle == 1){
194			this.enableBicycleLayer(true);
195		}
196
197		if(this.settings.traffic == 1){
198			this.enableTrafficLayer(true);
199		}
200
201		if(this.settings.transport_layer){
202			this.enablePublicTransportLayer(true);
203		}
204
205		if(this.settings.enable_scale_control){
206			this.enableScaleControl(true);
207		}
208
209		this.showPointsOfInterest(this.settings.wpgmza_show_point_of_interest);
210		
211		// Move the loading wheel into the map element (it has to live outside in the HTML file because it'll be overwritten by Google otherwise)
212		$(this.engineElement).append($(this.element).find(".wpgmza-loader"));
213	}
214	
215	WPGMZA.GoogleMap.prototype.setOptions = function(options, initializing)
216	{
217		Parent.prototype.setOptions.call(this, options);
218		
219		if(options.scrollwheel)
220			delete options.scrollwheel;	// NB: Delete this when true, scrollwheel: true breaks gesture handling
221		
222		if(!initializing)
223		{
224			this.googleMap.setOptions(options);
225			return;
226		}
227		
228		var converted = $.extend(options, this.settings.toGoogleMapsOptions());
229		
230		var clone = $.extend({}, converted);
231		if(!clone.center instanceof google.maps.LatLng && (clone.center instanceof WPGMZA.LatLng || typeof clone.center == "object"))
232			clone.center = {
233				lat: parseFloat(clone.center.lat),
234				lng: parseFloat(clone.center.lng)
235			};
236		
237		if(this.settings.hide_point_of_interest){
238			var noPoi = {
239				featureType: "poi",
240				elementType: "labels",
241				stylers: [
242					{
243						visibility: "off"
244					}
245				]
246			};
247			
248			if(!clone.styles)
249				clone.styles = [];
250			
251			clone.styles.push(noPoi);
252		}
253
254		if(WPGMZA.settings && WPGMZA.settings.googleMarkerMode && WPGMZA.settings.googleMarkerMode === WPGMZA.GoogleMarker.MARKER_MODE_ADVANCED){
255			/* Advanced Marker Module - Disable local styles */
256			if(clone.styles){
257				delete clone.styles;
258			}
259		}
260		
261		this.googleMap.setOptions(clone);
262	}
263	
264	/**
265	 * Adds the specified marker to this map
266	 * @return void
267	 */
268	WPGMZA.GoogleMap.prototype.addMarker = function(marker)
269	{
270		marker.googleMarker.setMap(this.googleMap);
271		
272		Parent.prototype.addMarker.call(this, marker);
273	}
274	
275	/**
276	 * Removes the specified marker from this map
277	 * @return void
278	 */
279	WPGMZA.GoogleMap.prototype.removeMarker = function(marker)
280	{
281		marker.googleMarker.setMap(null);
282		
283		Parent.prototype.removeMarker.call(this, marker);
284	}
285	
286	/**
287	 * Adds the specified polygon to this map
288	 * @return void
289	 */
290	WPGMZA.GoogleMap.prototype.addPolygon = function(polygon)
291	{
292		polygon.googlePolygon.setMap(this.googleMap);
293		
294		Parent.prototype.addPolygon.call(this, polygon);
295	}
296	
297	/**
298	 * Removes the specified polygon from this map
299	 * @return void
300	 */
301	WPGMZA.GoogleMap.prototype.removePolygon = function(polygon)
302	{
303		polygon.googlePolygon.setMap(null);
304		
305		Parent.prototype.removePolygon.call(this, polygon);
306	}
307	
308	/**
309	 * Adds the specified polyline to this map
310	 * @return void
311	 */
312	WPGMZA.GoogleMap.prototype.addPolyline = function(polyline)
313	{
314		polyline.googlePolyline.setMap(this.googleMap);
315		
316		Parent.prototype.addPolyline.call(this, polyline);
317	}
318	
319	/**
320	 * Removes the specified polygon from this map
321	 * @return void
322	 */
323	WPGMZA.GoogleMap.prototype.removePolyline = function(polyline)
324	{
325		polyline.googlePolyline.setMap(null);
326		
327		Parent.prototype.removePolyline.call(this, polyline);
328	}
329	
330	WPGMZA.GoogleMap.prototype.addCircle = function(circle)
331	{
332		circle.googleCircle.setMap(this.googleMap);
333		
334		Parent.prototype.addCircle.call(this, circle);
335	}
336	
337	WPGMZA.GoogleMap.prototype.removeCircle = function(circle)
338	{
339		circle.googleCircle.setMap(null);
340		
341		Parent.prototype.removeCircle.call(this, circle);
342	}
343	
344	WPGMZA.GoogleMap.prototype.addRectangle = function(rectangle)
345	{
346		rectangle.googleRectangle.setMap(this.googleMap);
347		
348		Parent.prototype.addRectangle.call(this, rectangle);
349	}
350	
351	WPGMZA.GoogleMap.prototype.removeRectangle = function(rectangle)
352	{
353		rectangle.googleRectangle.setMap(null);
354		
355		Parent.prototype.removeRectangle.call(this, rectangle);
356	}
357	
358	/**
359	 * Delegate for google maps getCenter
360	 * @return void
361	 */
362	WPGMZA.GoogleMap.prototype.getCenter = function()
363	{
364		var latLng = this.googleMap.getCenter();
365		
366		return {
367			lat: latLng.lat(),
368			lng: latLng.lng()
369		};
370	}
371	
372	/**
373	 * Delegate for google maps setCenter
374	 * @return void
375	 */
376	WPGMZA.GoogleMap.prototype.setCenter = function(latLng)
377	{
378		WPGMZA.Map.prototype.setCenter.call(this, latLng);
379		
380		if(latLng instanceof WPGMZA.LatLng)
381			this.googleMap.setCenter({
382				lat: latLng.lat,
383				lng: latLng.lng
384			});
385		else
386			this.googleMap.setCenter(latLng);
387	}
388	
389	/**
390	 * Delegate for google maps setPan
391	 * @return void
392	 */
393	WPGMZA.GoogleMap.prototype.panTo = function(latLng)
394	{
395		if(latLng instanceof WPGMZA.LatLng)
396			this.googleMap.panTo({
397				lat: latLng.lat,
398				lng: latLng.lng
399			});
400		else
401			this.googleMap.panTo(latLng);
402	}
403	
404	/**
405	 * Delegate for google maps getCenter
406	 * @return void
407	 */
408	WPGMZA.GoogleMap.prototype.getZoom = function()
409	{
410		return this.googleMap.getZoom();
411	}
412	
413	/**
414	 * Delegate for google maps getZoom
415	 * @return void
416	 */
417	WPGMZA.GoogleMap.prototype.setZoom = function(value)
418	{
419		if(isNaN(value))
420			throw new Error("Value must not be NaN");
421		
422		return this.googleMap.setZoom(parseInt(value));
423	}
424	
425	/**
426	 * Gets the bounds
427	 * @return object
428	 */
429	WPGMZA.GoogleMap.prototype.getBounds = function() {
430		
431		var nativeBounds = new WPGMZA.LatLngBounds({});
432
433		try{
434			var bounds = this.googleMap.getBounds();
435			var northEast = bounds.getNorthEast();
436			var southWest = bounds.getSouthWest();
437			
438			
439			nativeBounds.north = northEast.lat();
440			nativeBounds.south = southWest.lat();
441			nativeBounds.west = southWest.lng();
442			nativeBounds.east = northEast.lng();
443			
444			// Backward compatibility
445			nativeBounds.topLeft = {
446				lat: northEast.lat(),
447				lng: southWest.lng()
448			};
449			
450			nativeBounds.bottomRight = {
451				lat: southWest.lat(),
452				lng: northEast.lng()
453			};
454		} catch (ex){
455			/* Just return a default, instead of throwing an error */
456		}
457		
458		return nativeBounds;
459	}
460	
461	/**
462	 * Fit to given boundaries
463	 * @return void
464	 */
465	WPGMZA.GoogleMap.prototype.fitBounds = function(southWest, northEast)
466	{
467		if(southWest instanceof WPGMZA.LatLng)
468			southWest = {lat: southWest.lat, lng: southWest.lng};
469		if(northEast instanceof WPGMZA.LatLng)
470			northEast = {lat: northEast.lat, lng: northEast.lng};
471		else if(southWest instanceof WPGMZA.LatLngBounds)
472		{
473			var bounds = southWest;
474			
475			southWest = {
476				lat: bounds.south,
477				lng: bounds.west
478			};
479			
480			northEast = {
481				lat: bounds.north,
482				lng: bounds.east
483			};
484		}
485		
486		var nativeBounds = new google.maps.LatLngBounds(southWest, northEast);
487		this.googleMap.fitBounds(nativeBounds);
488	}
489	
490	/**
491	 * Fit the map boundaries to visible markers
492	 * @return void
493	 */
494	WPGMZA.GoogleMap.prototype.fitBoundsToVisibleMarkers = function()
495	{
496		var bounds = new google.maps.LatLngBounds();
497		for(var i = 0; i < this.markers.length; i++)
498		{
499			if(markers[i].getVisible())
500				bounds.extend(markers[i].getPosition());
501		}
502		this.googleMap.fitBounds(bounds);
503	}
504	
505	/**
506	 * Enables / disables the bicycle layer
507	 * @param enable boolean, enable or not
508	 * @return void
509	 */
510	WPGMZA.GoogleMap.prototype.enableBicycleLayer = function(enable)
511	{
512		if(!this.bicycleLayer)
513			this.bicycleLayer = new google.maps.BicyclingLayer();
514		
515		this.bicycleLayer.setMap(
516			enable ? this.googleMap : null
517		);
518	}
519	
520	/**
521	 * Enables / disables the bicycle layer
522	 * @param enable boolean, enable or not
523	 * @return void
524	 */
525	WPGMZA.GoogleMap.prototype.enableTrafficLayer = function(enable)
526	{
527		if(!this.trafficLayer)
528			this.trafficLayer = new google.maps.TrafficLayer();
529		
530		this.trafficLayer.setMap(
531			enable ? this.googleMap : null
532		);
533	}
534	
535	/**
536	 * Enables / disables the bicycle layer
537	 * @param enable boolean, enable or not
538	 * @return void
539	 */
540	WPGMZA.GoogleMap.prototype.enablePublicTransportLayer = function(enable)
541	{		
542		if(!this.publicTransportLayer)
543			this.publicTransportLayer = new google.maps.TransitLayer();
544				
545		this.publicTransportLayer.setMap(
546			enable ? this.googleMap : null
547		);
548	}
549	
550	/**
551	 * Enables / disables the scale control bar
552	 * @param enable boolean, enable or not
553	 * @return void
554	 */
555	WPGMZA.GoogleMap.prototype.enableScaleControl = function(enable)
556	{
557		const units = (this.settings.store_locator_distance == WPGMZA.Distance.MILES)
558			? google.maps.ScaleControlStyle.IMPERIAL
559			: google.maps.ScaleControlStyle.METRIC;
560
561		this.googleMap.setOptions({
562			scaleControl: enable,
563			scaleControlOptions: {
564				style: units,
565				position: google.maps.ControlPosition.BOTTOM_LEFT
566			}
567		});
568	}
569
570	/**
571	 * Shows / hides points of interest
572	 * @param show boolean, enable or not
573	 * @return void
574	 */
575	WPGMZA.GoogleMap.prototype.showPointsOfInterest = function(show)
576	{
577		// TODO: This will bug the front end because there is no textarea with theme data
578		var text = $("textarea[name='theme_data']").val();
579		
580		if(!text)
581			return;
582		
583		var styles = JSON.parse(text);
584		
585		styles.push({
586			featureType: "poi",
587			stylers: [
588				{
589					visibility: (show ? "on" : "off")
590				}
591			]
592		});
593		
594		this.googleMap.setOptions({styles: styles});
595	}
596	
597	/**
598	 * Gets the min zoom of the map
599	 * @return int
600	 */
601	WPGMZA.GoogleMap.prototype.getMinZoom = function()
602	{
603		return parseInt(this.settings.min_zoom);
604	}
605	
606	/**
607	 * Sets the min zoom of the map
608	 * @return void
609	 */
610	WPGMZA.GoogleMap.prototype.setMinZoom = function(value)
611	{
612		this.googleMap.setOptions({
613			minZoom: value,
614			maxZoom: this.getMaxZoom()
615		});
616	}
617	
618	/**
619	 * Gets the min zoom of the map
620	 * @return int
621	 */
622	WPGMZA.GoogleMap.prototype.getMaxZoom = function()
623	{
624		return parseInt(this.settings.max_zoom);
625	}
626	
627	/**
628	 * Sets the min zoom of the map
629	 * @return void
630	 */
631	WPGMZA.GoogleMap.prototype.setMaxZoom = function(value)
632	{
633		this.googleMap.setOptions({
634			minZoom: this.getMinZoom(),
635			maxZoom: value
636		});
637	}
638	
639	WPGMZA.GoogleMap.prototype.latLngToPixels = function(latLng)
640	{
641		var map = this.googleMap;
642		var nativeLatLng = new google.maps.LatLng({
643			lat: parseFloat(latLng.lat),
644			lng: parseFloat(latLng.lng)
645		});
646		var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
647		var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
648		var scale = Math.pow(2, map.getZoom());
649		var worldPoint = map.getProjection().fromLatLngToPoint(nativeLatLng);
650		return {
651			x: (worldPoint.x - bottomLeft.x) * scale, 
652			y: (worldPoint.y - topRight.y) * scale
653		};
654	}
655	
656	WPGMZA.GoogleMap.prototype.pixelsToLatLng = function(x, y)
657	{
658		if(y == undefined)
659		{
660			if("x" in x && "y" in x)
661			{
662				y = x.y;
663				x = x.x;
664			}
665			else
666				console.warn("Y coordinate undefined in pixelsToLatLng (did you mean to pass 2 arguments?)");
667		}
668		
669		var map = this.googleMap;
670		var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
671		var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest
671());
672		var scale = Math.pow(2, map.getZoom());
673		var worldPoint = new google.maps.Point(x / scale + bottomLeft.x, y / scale + topRight.y);
674		var latLng = map.getProjection().fromPointToLatLng(worldPoint);
675		return {
676			lat: latLng.lat(),
677			lng: latLng.lng()
678		};
679	}
680	
681	/**
682	 * Handle the map element resizing
683	 * @return void
684	 */
685	WPGMZA.GoogleMap.prototype.onElementResized = function(event)
686	{
687		if(!this.googleMap)
688			return;
689		google.maps.event.trigger(this.googleMap, "resize");
690	}
691
692	WPGMZA.GoogleMap.prototype.enableAllInteractions = function()
693	{	
694		var options = {};
695
696		options.scrollwheel				= true;
697		options.draggable				= true;
698		options.disableDoubleClickZoom	= false;
699		
700		this.googleMap.setOptions(options);
701	}
702
703	WPGMZA.GoogleMap.prototype.openStreetView = function(options){
704		if(this.googleMap.getStreetView()){
705			if(options){
706				if(options.position && options.position instanceof WPGMZA.LatLng){
707					this.googleMap.getStreetView().setPosition(options.position.toGoogleLatLng());
708				}
709
710				if(options.heading || options.pitch){
711					const pov = {};
712					if(options.heading){
713						pov.heading = parseFloat(options.heading);
714					}
715
716					if(options.pitch){
717						pov.pitch = parseFloat(options.pitch);
718					}
719
720					this.googleMap.getStreetView().setPov(pov);
721				}
722			}
723			this.googleMap.getStreetView().setVisible(true);
724		}
725	}
726	
727	WPGMZA.GoogleMap.prototype.closeStreetView = function(){
728		if(this.googleMap.getStreetView()){
729			this.googleMap.getStreetView().setVisible(false);
730		}
731	}
732
733	/**
734	 * Override default map isFullScreen method for Google Maps
735	 * 
736	 * This allows us to check the first child div's height, instead of the container.
737	 * 
738	 * OpenLayers sets the container to fullscreen, Google sets their nested div instead
739	 * 
740	 * @returns bool
741	 */
742	WPGMZA.GoogleMap.prototype.isFullScreen = function(){
743		let fullscreen = WPGMZA.Map.prototype.isFullScreen.call(this);
744
745		if(!fullscreen && WPGMZA.isFullScreen()){
746			if(parseInt(window.screen.height) === parseInt(this.element.firstChild.offsetHeight)){
747				return true;
748			}
749		}
750		return false;
751	}
752
753	/**
754	 * Override the map on Fullscreen change method, this allows us to move embedded `stacks` into the main map div to allow them to be visible 
755	 * as part of the fullscreen display 
756	 * 
757	 * @param bool fullscreen Is this map fullscreen 
758	 * 
759	 * @return void
760	 */
761	WPGMZA.GoogleMap.prototype.onFullScreenChange = function(fullscreen){
762		Parent.prototype.onFullScreenChange.call(this, fullscreen);
763		
764		if(fullscreen && !this._stackedComponentsMoved){
765			if(this.element.firstChild){
766				const innerContainer = this.element.firstChild;
767				$(this.element).find('.wpgmza-inner-stack').each(function(index, element){
768					$(element).appendTo(innerContainer);
769				});
770			
771				this._stackedComponentsMoved = true;
772			}
773		}
774	}
775});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.