I need multiple MKTileOverlay
s with multiple blendModes
. Apparently using an overlay with a different blend causes the layer under to use the same blend mode. For the example below, using a normal blend mode on top of a soft light blend mode causes a normal blend mode to be used instead of soft light. The soft light layer is rendered as expected until the normal layer is displayed starting at zoom level 15.
First, I've subclassed MKTileOverlay
to add an overlay type so that the correct renderer is assured.
enum OverlayType {
case softLight,
normal
}
class TileOverlay: MKTileOverlay {
var type: OverlayType = .normal
}
Then setup layers and renderers in the typical fashion:
var softLightRenderer: MKTileOverlayRenderer!
var normalRenderer: MKTileOverlayRenderer!
private func setupSoftlightRenderer() {
let overlay = TileOverlay(urlTemplate: "http://localhost/softlight/{z}/{x}/{y}")
overlay.type = .softLight
overlay.canReplaceMapContent = false
overlay.minimumZ = 9
overlay.maximumZ = 20
mapView.addOverlay(overlay, level: .aboveLabels)
softLightRenderer = MKTileOverlayRenderer(tileOverlay: overlay)
tileRenderer.blendMode = .softLight
}
private func setupNormalRenderer() {
let overlay = TileOverlay(urlTemplate: "http://localhost/normal/{z}/{x}/{y}")
overlay.type = .normal
overlay.canReplaceMapContent = false
overlay.minimumZ = 15
overlay.maximumZ = 20
mapView.addOverlay(overlay, level: .aboveLabels)
normalRenderer = MKTileOverlayRenderer(tileOverlay: overlay)
normalRenderer.blendMode = .normal
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let overlay = overlay as? TileOverlay {
switch overlay.type {
case .softLight:
return softLightRenderer
case .normal:
return normalRenderer
}
}
print("Warning: using unhandled overlay renderer")
return blankRenderer
}
override func viewDidLoad() {
...
setupSoftlightRenderer()
setupNormalRenderer()
}
Interestingly, if I put the overlays at two different levels, one .aboveLabels
and another .aboveRoads
it works as expected. The problem is that limits me to two different overlay blend modes. I really could use more than two. I tried every possible variation of inserting the layers at different indexes and methods, but the only two that seem to work are the .aboveLabels
and .aboveRoads
.
How can I use more than two different blend modes?
EDIT:
When using any vector overlays (MKPolygonRenderer
, MKPolylineRenderer
, etc), my hack of using .aboveLabels
and .aboveRoads
doesn't work. When a raster layer uses .aboveRoads
and the vector uses .aboveLabels
, the vectors are not drawn properly. Since I need at least one vector layer with normal blending, it means I effectively have zero blend modes other than normal for raster overlays.
I created a minimal reproducible project. Clicking the button will add a MKPolygonRenderer
with normal blending that breaks the raster overlay that uses .softLight
blending.
Note that I have tried overriding the draw functions for the overlays and setting the blend modes there - even tried with transparency layers, but I have not found a work-around.