Reputation: 4582
I'm using an overlay on Google Maps to plot an alternate image on the map, and it's working fine. I'm using OverlayView()
, and I'm able to create some designs on the Overlay too via the drawing API, which is great.
The issue is I want to add an additional overlay in between the two to create some opacity (a slight screening effect) on the underlying map.
Do I use two different overlay methods on the same map?
Here's where it's at.
I have this.maps
set to be the GMaps library, and this.map
set to be the map instance itself.
createOverlay() {
MyOverlay.prototype = new this.maps.OverlayView()
/* Constructor for the OverlayView() class */
function MyOverlay(bounds, image, map) {
/* Set up local properties */
this.bounds_ = bounds
this.image_ = image
this.map_ = map
/* Set up property to hold the overlay, which is added in onAdd() */
this.div_ = null
/* Explicitly attach this overlay. */
this.setMap(map)
}
/**
* onAdd() - called when the map's panes are ready and the overlay is added
*/
MyOverlay.prototype.onAdd = function () {
/* Create the element to hold the overlay */
const evDiv = document.createElement('div')
evDiv.style.borderStyle = 'none'
evDiv.style.borderWidth = '0px'
evDiv.style.position = 'absolute'
/* Create the image element for the overlay and attach it */
const evImg = document.createElement('img')
evImg.src = this.image_
evImg.style.width = '100%'
evImg.style.height = '100%'
evImg.style.position = 'absolute'
evDiv.appendChild(evImg)
this.div_ = evDiv
/* Attach the elements to the map */
const panes = this.getPanes()
panes.overlayLayer.appendChild(evDiv)
}
/**
* draw() - called whenever the map's tiles are touched to adjust the overlay
* - uses sw and ne coords of the overlay to set its size and peg it to
* the correct position and size.
*/
MyOverlay.prototype.draw = function () {
/* Retrieve the projection from the overlay */
const overlayProjection = this.getProjection()
/* Convert the coords to pixels and resize the div */
const sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest())
const ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast())
const div = this.div_
div.style.left = sw.x + 'px'
div.style.top = ne.y + 'px'
div.style.width = (ne.x - sw.x) + 'px'
div.style.height = (sw.y - ne.y) + 'px'
}
/* onRemove() - Called if we remove the overlay via setting it to 'null' - Not needed yet */
MyOverlay.prototype.onRemove = function () {
this.div_.parentNode.removeChild(this.div_)
this.div_ = null
}
const { src, latMax, lngMax, latMin, lngMin } = this.state.Imagery
const boundaries = new this.maps.LatLngBounds(
new this.maps.LatLng(latMin, lngMin),
new this.maps.LatLng(latMax, lngMax),
)
this.mapOverlay = new MyOverlay(boundaries, src, this.map)
}
The overlay is working fine and loading. I need to add another overlay in between this overlay and the underlying map.
Upvotes: 0
Views: 2708
Reputation: 4582
Use panes
to layer overlay elements on the map.
This won't work in every scenario, but if you need some type of extra DOM layer between the map base layer and the overlay of the image, it works well. This solution works perfectly for the situation I was in, where I wanted a screen of opacity on top of the underlying map.
You don't create two entirely separate OverlayView
s over the same map.
Instead, to do this, assuming you've followed the Custom Overlays Documentation to set up your primary overlay, you add code to the configuration of your OverlayView to make another layer.
In the constructor, you add a holding div for your additional layer, which we'll call layer
:
/* Set up properties to hold the overlay, which is added in onAdd() */
this.layer_ = null
this.div_ = null
Then when initiating the Overlay with the onAdd()
, you set up your additional div. The crucial part here is properly using the available panes
that google maps exposes as MapPanes for your use:
MyOverlay.prototype.onAdd = function () {
/* Create a layer in between google and overlay tiles */
const layerDiv = document.createElement('div')
layerDiv.style.backgroundColor = 'white'
layerDiv.style.opacity = '0.5'
layerDiv.style.position = 'absolute'
/* Any other properties here for your additional layer element */
this.layer_ = layerDiv
/* Attach the elements to the proper pane layers of the map */
const panes = this.getPanes()
panes.mapPane.appendChild(layerDiv)
panes.overlayLayer.appendChild(div)
You don't have to touch the draw()
function, but in the onRemove()
you need to remove your additional overlay pane:
MyOverlay.prototype.onRemove = function () {
this.layer_.parentNode.removeChild(this.mask_)
this.layer_ = null
this.div_.parentNode.removeChild(this.div_)
this.div_ = null
}
That's it, you should now have an additional overlay appearing between your primary overlay and the underlying map.
Upvotes: 1