How to prevent full-screen embedded Google Maps from capturing scroll first - javascript

I have an embedded Google Maps V3, and gestureHandling defaults to "cooperative", which is great, because an infobox appears when clicking on a location cluster and it often needs scrolling. However, when the map view goes to full-screen, it returns to regular un-modified scrolling, capturing it before the infobox, rendering the infobox useless as I can't scroll in it anymore.
Is there any way to require cooperative scrolling in full-screen view, or re-capture the scrolling in the infobox first?
--- EDIT ---
Here's what's happening so far, simplified (it's across multiple model instances):
const theMap = new google.maps.Map($("#calendarMap"), {
zoom: 4,
center: {
lat: 39.82,
lng: -98.57
},
gestureHandling: "cooperative"
});
I'm trying to figure out the infoboxes, I'm not the best at reading through typescript, especially when it's a massive cluster of modules and models my seniors wrote.
I verified through console that the map is indeed in "cooperative" mode when in full-screen, I'm trying to mess with the infobox settings now.

Solved in a much better way. Code executes on creating the infobox, from the infobox model:
// this.div is the jQuery node that is this infobox
google.maps.event.addDomListener(this.div, "wheel", (e) => {
e.cancelBubble = true;
if (e.stopPropagation) {
e.stopPropagation();
}
});

Related

How can I dismiss a HERE Maps context menu programmatically?

I have a HERE Maps map displayed on a simple webpage with a multiselect dropdown and a couple of buttons. I'm using the contextmenu event to show a context menu on right-click, like so:
var map = new H.Map(
document.getElementById('mapContainer'),
maptypes.raster.normal.map,
{
zoom: 12,
center: { lat: -33.81, lng: 150.78 },
pixelRatio: window.devicePixelRatio || 1,
engineType: H.map.render.RenderEngine.EngineType.P2D
}
);
...
// an H.map.Polygon object we prepared earlier
polygonObject.addEventListener("contextmenu", handleContextMenu)
...
function handleContextMenu(evt) {
// Don't do anything if the map itself is right-clicked/long-pressed
if (evt.target === map) {
return;
}
if (evt.target instanceof H.map.Polygon) {
// Polygon-specific context menu items
evt.items.push(new H.util.ContextItem({ label: "ABC123" }));
evt.items.push(H.util.ContextItem.SEPARATOR);
evt.items.push(new H.util.ContextItem({ label: "Do something", callback: function () { doSomething(evt) } }));
}
}
This works fine, displays a context menu when a polygon object is right-clicked, and dismisses itself if somewhere else on the map is tapped. However, the context menu doesn't dismiss if the user clicks or interacts with another element on the page outside the map.
I wasn't able to find any documentation on how to achieve this behaviour, and the example that HERE Maps uses also doesn't dismiss the context menu if somewhere outside the map is clicked. Is there any way to dismiss the context menu on a map, either programmatically or automatically if another page element is interacted with?
It's a little bit hacky, but you can manually remove the context menu from the DOM by finding a div with the h_context_menu class in the page, and removing it. This may have some unintended side effects with the UI class, but seems to work OK from my brief testing.
Using JQuery:
$("div.h_context_menu").remove()
Using ES6:
document.querySelector("div.h_context_menu").remove()
Using vanilla JavaScript (compatible with Internet Explorer):
var el = document.querySelector("div.h_context_menu");
el.parentNode.removeChild(el);

How do I display a popup showing feature attributes from a Geoserver WMS layer in a leaflet map?

I'm pretty new to Leaflet and I'm trying to get some pretty basic (or so I thought) functionality on my webmap. In short, I have many (179) WMS layers hosted on Geoserver and I would like the user to be able to click any feature and display a popup showing information about the feature.
I have 179 layers each representing the polygon footprints of paper map sheets for the map library I work for. Each of the layers represents one "series" of maps in the collection. The attribute fields for each layer are identical. Some of the features are stacked on top of one another (multiple records for different editions of the same map). To give you an idea of what I'm interested in creating, here is a link to my pilot application (showing just 3 of the layers) I made in ArcGIS online. Forgive the elementary HTML, it was just an example to show what I needed to do.
I have created a leaflet map displaying two of the layers and I would like to add the other layers once I figure out this functionality.
Is it possible to make a popup that can show information from multiple features from multiple layers?
Can I control the attributes which are displayed in the popup?
Would it be easier to do some kind of "info window" rather than popups?
Really, any suggestions to keep me from giving up on this project would be much appreciated.
var map;
function mapinitialize() {
var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
});
map = new L.Map('map',
{
center: new L.LatLng(46, -90),
zoom: 6,
layers: [osm],
zoomControl: true
});
//This is all for the layer control:
var f0999 = new L.TileLayer.WMS(GEOSERVERBASE + "/geoserver/Geodex/wms",
{
layers: "Geodex:f0999",
format: 'image/png',
styles: 'F0999',
transparent: true,
attribution: ""
});
var f0177 = new L.TileLayer.WMS(GEOSERVERBASE + "/geoserver/Geodex/wms",
{
layers: "Geodex:f0177",
format: 'image/png',
styles: 'F0177',
transparent: true,
attribution: ""
});
var baseMaps = {
"osm": osm
};
var overlayMaps = {
"f0999 Messing Around Layer": f0999,
"f0177 Nautical Charts": f0177
};
L.control.layers(baseMaps, overlayMaps).addTo(map);
//End layer control
The current popup:
map.on('click', function(e){
var popupContent = "You have clicked the map at " + e.latlng.lat + ", " + e.latlng.lng;
var marker = new L.marker(e.latlng).addTo(map)
.bindPopup(popupContent)
.openPopup();
});
}
All the references to popups in leaflet I can find are assigned to markers, and as you can see in the code, I have been able to assign a popup to a marker.
Ideally, I would like to place a marker where the user clicks and display attributes for the features underneath. The intention is that a user can use this application to query what maps we have for a specific area.
If you are using the 7.X version of leaflet, there isn't direct support for this in the box. Luckily for all of us, the library supports customization through plugins and object extension well.
Personally, I've adapted this example for a similar need. It wouldn't accommodate showing details for multiple layers, but with some additional customization that could be accomplished. You'd definitely be able to control what attributes are shown.It extends the framework provided WMS tile layer adding the ability to do a WMS GetFeatureInfo request which is at the heart of what you need.
It seems like GeoServer's OpenLayers backed layer preview feature does do this, but the results are loaded in another div, not a popup. OpenLayers might support this more in-the-box if you prefer not to get your hands too dirty.
Also, if using a WFS layer is an option you would have a much easier time attaching an onclick event using that layer's onEachFeature event. If the number of features were small, you could bind popups to the data you want to show -- with an onclick listener to show the popup when clicked. I can provide some examples of this if it's interesting.

Setting InfoWindow Postion in Google Maps

I am drawing a set of Polygons on to Google Maps and would like to have an InfoWindow pop up at the center of each when I click on it.
function attach_info_window(polygon, centroid, title){
var info_window = new google.maps.InfoWindow({
content: title,
position: { lat: centroid[0], lng: centroid[1] }
});
google.maps.event.addListener(polygon, 'click', function() {
info_window.open(map, this);
});
}
The problem is, the window shows up in the NW corner every time. The 'position' parameter seems to be ignored completely. I also tried setting the position on click with
event.latLng
But that returns undefined, even though the API docs specify it, so that doesn't work either. Curiously, it works just fine if I use a Marker instead of the Polygons.
I solved this by removing the second argument in open()
info_window.open(map)
works great. I was passing "this" in order to bind it to that specific polygon among many. I still don't understand why this works, and neither
info_window.open(map, poly)
nor
info_window.open(map, this)
works
This:
info_window.open(map, this);
Will not work for anything but a google.maps.Marker. The second argument of InfoWindow.open can only be a google.maps.Marker, a Polygon or Polyline won't work there.
from the documentation
"In the core API, the only anchor is the Marker class. However, an anchor can be any MVCObject that exposes a LatLng position property"

Google map js api version 3 infowindow glitch

I am developing an application which uses google maps api v3 to show markers and infowindows.
Well, I have N markers stored within an array and a global infowindow used to show some information.
The infowindow contents are shown simply by clicking a marker, created in this way:
/* global js stuff */
var g_map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var g_current_popup = new google.maps.InfoWindow({ content: "" });
var g_markers = [];
/* create marker function */
function addMarker(p_infowindow_contents)
{
var l_marker = new google.maps.Marker( all the stuff needed );
google.maps.event.addListener(l_marker, 'click', function()
{
g_current_popup.close(); // if already open, it must be closed and reloaded
g_current_popup.setContent(p_infowindow_contents);
g_current_popup.open(g_map, l_marker);
});
g_markers.push(l_marker);
}
Everything works as expected, except for a little graphical glitch: when the infowindow is appearing, I see the infowindow 'tip' positioned at an unknown location for a tenth of a second, then it disappears and I see the correct infowindow.
Look at this screenshot took just before the tip disappears:
Does anyone experienced something like this?
Could it be some CSS issue?
Thanks
It does not look like this is a problem with your code, I think it more likely a browser issue. I was able to validate the same thing looking at the infowindow example that Google provides in Firefox, but not in Chrome:
https://developers.google.com/maps/documentation/javascript/examples/infowindow-simple
it seems to happen more visibly when the map has to scroll to fit the infowindow, but I would say that it is not a requirement for it to do so. It is likely just an artifact with the screen taking a few clock cycles to catch up with the DOM.

Google maps info window: how can I get its offset/clearance?

I have a Google v3 Map with a UI element that overhangs the top of it like so…
And I have an info window attached to multiple markers. The problem I have is that when the infowindow opens and auto-pans to be visible within the map (behaviour I want), it obviously takes no account of the element overhang…
…so the user has to manually pan to see all the info clearly or get at the close box.
I've looked to see if there is a way I can get the offsetTop of the infowindow from its parent map, so I can add an extra panTo nudge when necessary, but I'm stumped.
Attempts such as…
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(this.html);
infowindow.open(map, marker);
var infoTop = infowindow.offsetTop;
console.log(infoTop);
});
…just give me undefined.
What would be great is to be able to set a clearance property on the infowindow, as is possible with the infoBoxClearance property of the InfoBox utility. But I don't want to use InfoBox because there are stylistic aspects of the standard infowindow I prefer.
And I would prefer not to have the map pan more than is necessary by using disableAutoPan and calculating an optimal panTo for each marker.
Any suggestions?
I haven't tried this in Version 3, but in Version 2 the standard solution is to create a custom control on the map. The [v2] infoWindow avoids all controls, including custom controls. Your custom control could simply be an empty space covered by your external UI.
http://code.google.com/apis/maps/documentation/javascript/controls.html#CustomControls

Categories