This project is read-only.

Setting opacity on a layer

Jan 2, 2009 at 8:05 PM
I've been looking into how I could set the opacity for an entire layer (GeometryLayer or some tile layer source).

It seems as if the opacity property of the layer itself is not used due to the way that the tiles are aggregated for all layers into the MultiScaleImage in the Map class. I can of course set the opacity on each individual Pushpin object in a GeometryLayer, for example, but that seems a pretty brute force method and would require removing/adding objects again if the opacity were changed on a layer.

What I'm looking for is the ability to dynamically set the opacity of a single layer, such that with custom raster imagery (or filled polygons) can be transparent, allowing the road network to show through from the base imagery.

Am I missing something and this is actually possible?

Along the same lines, it would be nice to be able to set the z-index on a layer dynamically in order to control the order in which layers are rendered.

Cheers,
Richard
Jan 6, 2009 at 1:19 AM
The GeometryLayer isn't really the actual canvas layer.  Maybe it should be, but it isn't right now. In the mean time, I've changed the real canvases to public so that you can do something like this:   MapInstance.CanvasPoint.Opacity = .5;
Jan 6, 2009 at 8:07 PM
Edited Jan 6, 2009 at 8:08 PM
I second this!  It would be great to be able to change the z-index and/or set the opacity for a layer.
Jan 7, 2009 at 12:38 AM
Give it a try in the latest codebase.  Let me know if it works as expected.
Jan 7, 2009 at 3:23 PM
The GeometryLayer opacity now works. Thanks!

Any reason why the opacity doesn't work for a tile layer? We are using our own WMS tile source class inherited from BaseLayer, but the opacity work.
Jan 7, 2009 at 5:01 PM
Both work for DeepPoint items, but Polygon & LineString layers are not displaying on the map.  I have opened a work item...
Jan 7, 2009 at 5:28 PM
abssd.  See the note: Important Note for GeometryLayer....  Let me know if this isn't the problem.

So why doesn't opacity work for an TileSource.  My guess is this is because your TileSource is used as datasource and is not a true visual element.  Kind of like asking why can't I change the opacity of the DBMS.  The visual element for the baselayer is the MultiScaleImage (MSI).  Haven't tried it, but perhaps we can change the opacity of the MSI. If this does work, I'll add a public property to the map so you can control it.
Jan 7, 2009 at 5:36 PM
The Important Note for GeometryLayer fixed my problem.  Thanks!
Jan 8, 2009 at 3:32 AM
RoadWarrior: I think I understand better what is happening with the MSI. It is a little confusing to have TileLayer inherit from BaseLayer inherit from Canvas, but the Canvas isn't the visual element. But I'm over that now :)

Your guess that adjusting the opacity of the MSI was correct, but doesn't help in my situation. In many cases, our clients wish to have base imagery (at full opacity) at the bottom, with their own raster and/or vector imagery (rendered as a png via WMS) overlaid, often slightly transparent to allow the road network and other features from the base layer to be visible. It seems that by using a single MSI for all layers, this won't be possible, since the only data passed to the MSI via the TileSource are URIs.

Is there a way around this or would it be possible to manage multiple MSIs in the Map class, so that the opacity of each could be controlled independently?
Jan 8, 2009 at 4:08 AM
If it were me, I would create my own Layer which implements ITileLayer.  When calls to GetTile are made, convert the Tile values to your own format and simply query own service for data. 
Jan 8, 2009 at 5:09 AM
Road Warrior: "If it were me, I would create my own Layer which implements ITileLayer.  When calls to GetTile are made, convert the Tile values to your own format and simply query own service for data."

???  I didn't understand this advice.  Are you saying that any child layer just needs to expose an ITileLayer interface and this interface will get called automatically in sync with the base layer???

I think what the discussion thusfar has pointed out is the requirement to have multiple MSI layers with independently settable Opacity values, allowing multiple maps or maps and images to be overlaid with partial transparency.  I've tried to do this by creating mulitple DeepEarth:Map objects on a single page, and they display properly, but only the topmost DeepEarth:Map receives the scroll/zoom mouse actions.  Is there an easy way to have multiple DeepEarth:Map's scroll and zoom in a coordinated fashion?
Jan 8, 2009 at 5:27 AM
Edited Jan 8, 2009 at 5:28 AM
I don't think your approach is possible with the current version of the MSI.  If you get it to work, please share your wisdom with the rest of us.

Don't mean to blow your mind, but yes, that is exactly what I am suggesting.   If you add a Layer that implements ITileLayer, GetTile will be invoked on your object.   So for example, you can create a GeometryLayer, add ITileLayer and BOOM, it now has everything it needs to know what tiles have been called up.  What you do with that information is another story.  As a matter of fact, I use this very approach on my demo at sales.roadwarriorllc.com to query a data service for location pushpins.
Jan 8, 2009 at 6:05 AM
OK.  But this approach does nothing to resolve the multiple layers, each having a different opacity requirement, correct?

Related question: Since each Layer already has Canvas as it's base, why doesn't layer-specific Opacity work in the existing codebase?
Jan 8, 2009 at 6:17 AM
i think you will have the ability to set the Opacity on the GeometryLayer

so i assume you make a class that inherits "GeometryLayer" & implements the "ITileLayer" interface and the you get a TileLayer which has the ability to set it's "Opacity"
Jan 8, 2009 at 7:28 AM
I tried dotnetnoobie's approach of deriving a class which inherits from "GeometryLayer" and implements "ITileLayer" and the results are exactly the same as before.  Setting the Opacity at either initialization time or later has no effect on the overlay tiles.
Jan 8, 2009 at 8:44 AM
Edited Jan 8, 2009 at 8:55 AM

So it is possible to synchronize multiple MultiScaleImage controls.  I have this working on a codebase not derived from DeepEarth, and have spent a few days now trying without success to duplicate this functionality within DeepEarth. 

To see it in action, visit www.deepzoom.com.  Zoom in near Seattle.  Move the top horizontal slider to change the relative opacity of the layers.

It's basically as simple as keeping a list of all MSI's and whatever command you send to the topmost MSI, send the same commands down the stack to the lower MSIs.

I'm guessing the difficulty with making Opacity work with tile layers in DeepEarth is somehow related to the child/parent relationship of the layers and controls, but I don't understand what's broken.  See http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/d454868b-7b9f-4680-99ee-0b93bb7d5b5a/ for a possible hint?

Jan 8, 2009 at 4:06 PM
I hope this can be worked out.

It is possible to stack layers from WMS sources with '&transparency=true', but that will only work with linear and point features. Area polygonal features will still need to have an opacity capability in the client, something like jaybo_nomad shows in his enc example. 

Opacity control is needed for area features like these:
http://ocs-spatial.ncd.noaa.gov/wmsconnector/com.esri.wms.Esrimap/encdirect?Service=WMS&Version=1.1.1&Request=GetMap&Layers=HARBOR%20FACILITY_POLYGON(HRBFAC),DEPTH%20AREA(DEPARE),SEA%20AREA(SEAARE),LAND%20AREA(LNDARE)&format=image/png&transparent=true&SRS=EPSG:4326&BBOX=-122.5,37.75,-122.25,38.0&width=1000&height=1000

I'd like to be able to select individual layers from a tree control populated with a variety of WMS sources and have them all stack into overlaying msi(s). I'm thinking ideally a spinner control beside each layer in the source tree control would give users opacity adjustment for individual layers. That way DeepEarth would be a really useful OWS viewer, especially with the ability to choose a high resolution base like VE, OSM, or Yahoo.
Jan 10, 2009 at 10:16 PM
Edited Jan 10, 2009 at 10:19 PM
I think this thread has a couple of Issue Layers which is making the ability to understand the issues opaque.  So let's sort this out.

On Tuesday, the 17856 Code check-in converted the Layer class to a Canvas.  This means that Opacity or other properties can be applied to the layer and all child elements.  Try the "Add Geometry" button on the Prototype to see this in action.  The example set the GeometryLayer at .5 Opacity.  Keep in mind this update does not apply to the BaseLayer.  BaseLayer is really misnamed and should probably not really derive from Layer at all.  It really is a DataSource, but also has important properites that are utilized by the MSI and the Map to determine the overall boundaries and dimensions.  The MSI is the real visual element for the BaseLayer.  I plan to do some rework of the BaseLayer for the 1.5 release.  As part of this I'll keep in mind and consider what can be done for MSI layering.

If you find that Layer.Opacity is not working as advertised, please add an issue so it can be tracked and fixed.  Regarding MSI layering, DeepEarth was not originally designed for this.  Your welcome to add this as a feature request to the "Issue Tracker" so the team will decide whether to implement.