Show/Hide Overlays

1,363 views
Skip to first unread message

Kesuke

unread,
Jul 21, 2010, 6:31:46 AM7/21/10
to Google Maps JavaScript API v3
I'm moving a project from V2 to V3 and am having some trouble showing
and hiding custom overlays (added using overlayMapTypes).

In V2 it was a pretty straightforward job of using the show() and
hide() methods that were part of the GLayer class. But in V3 i'm not
sure how to go about the same thing as this has changed quite a bit.
I've checked the V3 reference and search but am still a little
confussed.

Examples are online at:

V2: http://anatomy.study-medicine.co.uk/testn6.html
V3: http://anatomy.study-medicine.co.uk/testg3t2.html

On the V2 example, if you go to the 'trunk' tab under the navigation
button you will see two selectable layers. These can be shown and
hidden. I would like to achieve the same effect using V3.

Radek Šimko

unread,
Jul 21, 2010, 7:59:58 AM7/21/10
to google-map...@googlegroups.com
What about this?
--
Radek


--
You received this message because you are subscribed to the Google Groups "Google Maps JavaScript API v3" group.
To post to this group, send email to google-map...@googlegroups.com.
To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-maps-js-api-v3?hl=en.


Radek Šimko

unread,
Jul 21, 2010, 8:16:06 AM7/21/10
to google-map...@googlegroups.com
Oh, sorry, I missed the fact, that it's not actually custom Overlays, but custom Map Types.

So
instead of 
pecMajorTilesType.show();
you'll call
anatomy.overlayMapTypes.removeAt(2);

etc.
--
Radek.

2010/7/21 Radek Šimko <radek...@gmail.com>

Kesuke

unread,
Jul 21, 2010, 8:47:47 AM7/21/10
to Google Maps JavaScript API v3
Thanks for the suggestions, however I'm having two major problems with
this approach;

1.) It works the first time its clicked, but I think its trying to
insertAt or removeAt where objects have already been removed. I'm
wondering if when an element is 'removeAt', everything moves down the
MCV array. e.g. index 3 becomes 2.

2.) Because this involves multiple transparent layers being stacked
ontop of each other, it leads to unusual z-index issues where layers
end up in the wrong order. You can see this on the example below when
you click Pectoralis major twice (to hide, then again to show). It
will appear behind the intercostal layer.

I've setup a test to show the strange behaviour of this approach at
http://anatomy.study-medicine.co.uk/testg3t3.html (you can see the
code changes on line 298)

Jason Sanford

unread,
Jul 21, 2010, 2:23:12 PM7/21/10
to google-map...@googlegroups.com
I had a similar problem and posted about how I dealt with it here: http://geojason.info/2010/05/overlay-map-management-with-google-maps-api-v3/

Basically what I'm doing is inserting a null value for every overlay I plan on adding to the map into the map.overlayMapTypes array and then creating a new imageMapType when a check box is clicked.

Probably not the most elegant solution, but it seems to work.



--

Kesuke

unread,
Jul 21, 2010, 8:28:57 PM7/21/10
to Google Maps JavaScript API v3
Thanks Jason, that works for some situations. But I have a problem;

There are some specific situations where toggling a single checkbox
needs to show/hide more than one layer (because there are a few
situations where an individual object like a muscle actually has to be
made from two layers so that a third layer can travel between them to
make it look diagramatically correct).

Any ideas how I might apply this?

It would be so great if a show() hide() feature were added. I realise
keeping the API lightweight is a major consideration in V3, but I
suspect at the level this would be implemented, any developer would be
well aware of the need to keep things light and tidy.



On Jul 21, 7:23 pm, Jason Sanford <jasonsanf...@gmail.com> wrote:
> I had a similar problem and posted about how I dealt with it here:http://geojason.info/2010/05/overlay-map-management-with-google-maps-...
>
> Basically what I'm doing is inserting a null value for every overlay I plan
> on adding to the map into the map.overlayMapTypes array and then creating a
> new imageMapType when a check box is clicked.
>
> <http://geojason.info/2010/05/overlay-map-management-with-google-maps-...>Probably
> not the most elegant solution, but it seems to work.
>
>
>
> On Wed, Jul 21, 2010 at 8:47 AM, Kesuke <Nick_dai...@hotmail.com> wrote:
> > Thanks for the suggestions, however I'm having two major problems with
> > this approach;
>
> > 1.) It works the first time its clicked, but I think its trying to
> > insertAt or removeAt where objects have already been removed. I'm
> > wondering if when an element is 'removeAt', everything moves down the
> > MCV array. e.g. index 3 becomes 2.
>
> > 2.) Because this involves multiple transparent layers being stacked
> > ontop of each other, it leads to unusual z-index issues where layers
> > end up in the wrong order. You can see this on the example below when
> > you click Pectoralis major twice (to hide, then again to show). It
> > will appear behind the intercostal layer.
>
> > I've setup a test to show the strange behaviour of this approach at
> >http://anatomy.study-medicine.co.uk/testg3t3.html(you can see the
> > code changes on line 298)
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Google Maps JavaScript API v3" group.
> > To post to this group, send email to
> > google-map...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > google-maps-js-a...@googlegroups.com<google-maps-js-api-v3%2B­unsub...@googlegroups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/google-maps-js-api-v3?hl=en.- Hide quoted text -
>
> - Show quoted text -

Jason Sanford

unread,
Jul 21, 2010, 9:49:08 PM7/21/10
to google-map...@googlegroups.com
I threw together some code very quickly so it's likely to be buggy but check out the slightly modified version of the sample I linked to earlier.

http://demos.geojason.info/anatomy.php

What I did was add three additional check boxes that have an id with two (or more) layers instead of one. The ids are separated by commas so that we can split them apart and add/remove the layer as needed. This might help you?

The code might be a little confusing if you're not familiar with jQuery but it's pretty self explanatory. Let me know if I need to explain further.

To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.

Kesuke

unread,
Jul 23, 2010, 4:35:06 PM7/23/10
to Google Maps JavaScript API v3
Thanks for taking the time to create that Jason, it has been very
helpful! I've got it working and now just have two questions;

1.) On your version the overlays are unchecked/not shown by default.
Any ideas about how this could be tweaked to have some layers switched
on at load.

2.) Linking into the first question - are you aware of any V3 code
that could be used to return whether an MCVarray item is null? - if so
that could be used to detect 'if (layer X is not null) do....'
> > > >http://anatomy.study-medicine.co.uk/testg3t3.html(you<http://anatomy.study-medicine.co.uk/testg3t3.html%28you>can see the

William

unread,
Jul 23, 2010, 11:56:44 PM7/23/10
to Google Maps JavaScript API v3
On Jul 22, 10:28 am, Kesuke <Nick_dai...@hotmail.com> wrote:
>
> There are some specific situations where toggling a single checkbox
> needs to show/hide more than one layer (because there are a few
> situations where an individual object like a muscle actually has to be
> made from two layers so that a third layer can travel between them to
> make it look diagramatically correct).
>

could the layers be represented by a hierarchical tree, where you
might want to toggle display at any level of the hierarchy?

Or do the layer categories overlap, for example if the third layer
mentioned above originates from a different category than the two
layers which comprise the muscle?

...

Kesuke

unread,
Jul 24, 2010, 8:56:12 AM7/24/10
to Google Maps JavaScript API v3
The layers have a z-index heirarchy, so the lowest elements (e.g. the
skeleton) do not appear above higher elements (e.g. the skin).

If I have understood your question, you mean could I create a linear
heirarchy where for example everything above a certain point could be
switched off? But there are situations where for example somebody
might want to show all the muscles of the face (elements very high up
the heirarchy) but not show the muscles of the neck (lower elements).

However, if you mean "can every layer be given a static z-index" the
answer is yes absolutely. They are already arranged into a linear
heirarchy in photoshop (all ~150 layers). However, there are subtle
rules which govern their display - for example:

"IF layer X is shown, layer Y must also be shown"
"IF layer X is shown, layer Y must be hidden"
"IF layer X is shown, layer Z must be shown and Y must be hidden" etc.

In V2 controlling the z-index and the rules was much easier, as
show(); and hide(); could be used and you could insert layers at a
specific z-index (a bit like the MCVarray, only the array is dynamic
so if a layer is removed the whole array moves down 1, messing up the
z-index order).

William

unread,
Jul 24, 2010, 10:57:01 PM7/24/10
to Google Maps JavaScript API v3

On Jul 24, 10:56 pm, Kesuke <Nick_dai...@hotmail.com> wrote:
>
> "IF layer X is shown, layer Y must also be shown"
> "IF layer X is shown, layer Y must be hidden"
> "IF layer X is shown, layer Z must be shown and Y must be hidden" etc.
>

I was wondering if these display rules cascade, ie if show(X) triggers
show(Y), then can show(Y) trigger other display rules?

>
> In V2 controlling the z-index and the rules was much easier, as
> show(); and hide(); could be used and you could insert layers at a
> specific z-index (a bit like the MCVarray, only the array is dynamic
> so if a layer is removed the whole array moves down 1, messing up the
> z-index order).

yeah V2 sounds more logical, but V3 more efficient, so we need a data
structure which reflects the relationships between all layers and
their display state, backed by the V3 MVCArray, which only contains
the visible layers in the correct order.

William

unread,
Jul 28, 2010, 10:19:59 PM7/28/10
to Google Maps JavaScript API v3
On Jul 25, 12:57 pm, William <william.g...@gmail.com> wrote:
> yeah V2 sounds more logical, but V3 more efficient, so we need a data
> structure which reflects the relationships between all layers and
> their display state, backed by the V3 MVCArray, which only contains
> the visible layers in the correct order.

I had one idea for this generic data structure, based on the concept
of a SQL query, where the contents of the MVCArray are selected from a
table, based on a where condition, sorted in a particular order.

In this case we want the overlayMapTypes to contain the
"imageMapTypes" where "visible" is true, sorted by "zIndex".

So I made a composite MVCObject that contains mapType, visible and
zIndex properties, and created a generic SQLArray which adapts
MVCArray, with parameters for "select", "where" and "order". Each
layer was given a unique id (primary key) so it is easy for the rest
of the program to retrieve the layers.

so the constructor is as follows:

overlays = new SQLArray(anatomy.overlayMapTypes, {
key: "id",
select: "mapType",
where: "visible",
order: "zIndex"
});

with methods to add() and get() layers.

see the following example:
http://www.william-map.com/20100729/1/overlays.htm

....

Kesuke

unread,
Jul 28, 2010, 10:58:44 PM7/28/10
to Google Maps JavaScript API v3
Thanks William, this is amazingly useful and particularly creative!
I'm very optimistic about your concept as it removes a lot of the
complexity from loading the many layers. In the next few days I plan
to upload tiles for each of the ~30 layers in the head region. This
way I'll have some additional material to 'stress-test' this with a
more complex and numerous set of images.

Two questions; -

1.) How can I adapt this SQLarray idea to allow for multiple layers to
be added/removed at the same time? For example, there are a few
situations where 'if layer A is shown, layer B must also be shown' and
'if layer A is shown, layer B must be hidden'. To give an idea, out of
the ~150 layers, these rules occur with around 15 of them.

2.) Less importantly but never-the-less, I was aiming to include an
opacity control (probably just a simple slider) at least for some
layers (assuming the IE8 opacity problem gets fixed). How could we set
this up so that when the click event occurs, the map grabs the sliders
opacity value for that layer?

William

unread,
Jul 28, 2010, 11:40:29 PM7/28/10
to Google Maps JavaScript API v3
1. At the moment all layers are separate, each with a "visible"
attribute of its own, so we need a composite controller that toggles
the visibility of multiple layers. The checkbox is the physical
control but there needs to be something that sits between the clicks
on that control and the full list of layers. The relationship between
layers would need to be specified in the data. I imagine if you want
to view layer B when layer A is visible, and if parts of B are above A
and parts below A, then A needs to become two layers C and D, to be
displayed in order C,B,D. The user interface would still display a
single layer control for A, and the user would be able to turn it off
independently of layer B. I guess the easiest way to make progress
is to create a simple example and see what data representation works
best.

2. The slider would be the control, and the ImageMapType.opacity is
the property holding the state. I am not sure if ImageMapType is a
MVCObject, and whether changes to opacity are automatically reflected
in the display. To set the opacity of layer "a" to X, it would be
something like

overlays.get("a").get("mapType").setOptions({opacity:X});

...

William

unread,
Jul 29, 2010, 4:56:33 AM7/29/10
to Google Maps JavaScript API v3
On Jul 29, 1:40 pm, William <william.g...@gmail.com> wrote:
> overlays.get("a").get("mapType").setOptions({opacity:X});

this didn't work ... the ImageMapType isn't a MVCObject. So instead I
made a new ImageMapType when there's a change in opacity. SQLArray
now ensures the MVCArray is up to date by listening to changes in the
"select" and "where" attributes of its MVCObjects.

Using jQuery sliders:

$("#slider_" + layers[i].id).slider({
min: 0,
max: 1,
step: 0.1,
value: 1,
change: sliderHandler(layers[i].id)
});

function sliderHandler(id) {
return function(event, ui) {
overlays.get(id).set("mapType", createImageMapType(id, ui.value));
};
}

http://www.william-map.com/20100729/1/opacity.htm

...
Message has been deleted

Kesuke

unread,
Jul 29, 2010, 7:40:13 AM7/29/10
to Google Maps JavaScript API v3
On Jul 29, 4:40 am, William <william.g...@gmail.com> wrote:

> I imagine if you want to view layer B when layer A is visible,
> and if parts of B are above A and parts below A, then A needs
> to become two layers C and D, to be displayed in order C,B,D.

This controller idea sounds perfect, and your absolutely right about
the layer structure - in photoshop where the drawings were made the
layers are already in that sort of order (e.g. A can't be both above
and below B). I'll upload some more layers later that I can use to
demonstrate/test this practically.

These specific 'exceptions' only occur about 15 times so a few lines a
bit like this in the controller will probably do it nicely.

if( id(A).visible == true ){ id(B).visible = true};
if( id(C).visible == true ){ id(D).visible = false};


> this didn't work ... the ImageMapType isn't a MVCObject. So instead I
> made a new ImageMapType when there's a change in opacity. SQLArray
> now ensures the MVCArray is up to date by listening to changes in the
> "select" and "where" attributes of its MVCObjects.

This should work very nicely, and in addition to the opacity handler
opens up potential for other 'live' modifications.

I should have more tiles online by this weekend when I get some free
time, then I can test the idea with a more complex set of images.

Kesuke

unread,
Aug 1, 2010, 5:57:29 PM8/1/10
to Google Maps JavaScript API v3
I've got the new layers I spoke about online to allow for more testing
of the method.

Rather than go into detail here about what I've done, I've created an
explanation here: http://anatomy.study-medicine.co.uk/update.html

And you can see where the map is at so far, here:
http://anatomy.study-medicine.co.uk/testk1.html

So - I have the layers working which is great. Now I need to find a
way of adding rules to control which layers are seen under different
circumstances. My first link goes into more detail about these
different types of rules, and how they apply to the layers I have
uploaded so far.

The bit i'm struggling with at the moment is creating a means to
implement this controller/rule handler.

William

unread,
Aug 1, 2010, 6:51:46 PM8/1/10
to Google Maps JavaScript API v3
as a start you could have additional layer properties to store the
rule definitions.

For the simplest types of rules you could have the properties "rule",
"operation" and "list"

rule: none | shadow | group etc
operation: any | all
list: comma separated list of layer ids

1. the visible property would be determined by a formula if "rule"
wasn't "none"
2. the formula would be conjunction/disjunction over the "visible"
property of a list of layers
3. the formula would be evaluated on the initial state of the layers
4. afterwards a layer would listen to "visible_changed" on the layers
in its list, nd recalculate its own visible property accordingly.

you would need two functions for formula calculation:

function any(list) {
var a = false;
for (var i in list) {
a = a || overlays.get(i).get("visible");
}
return a;
}

function all(list) {
var a = true;
for (var i in list) {
a = a && overlays.get(i).get("visible");
}
return a;
}

...

Kesuke

unread,
Aug 9, 2010, 7:21:47 AM8/9/10
to Google Maps JavaScript API v3
I'm having a bit of trouble getting this working, but its getting
there slowly.

The first problem is that some layers are subject to both ANY and ALL
rules, and have different layer-lists for show and hide - but I think
I can get around that by adding new properties for hide/show as the
concept remains the same.

The second problem is with the actual construction of the controller,
I've got parts of the code together at http://anatomy.study-medicine.co.uk/testk2.html
but haven't been able to find a place where I can put the IF rules.
Any suggestions where this should go?

William

unread,
Aug 9, 2010, 7:50:33 PM8/9/10
to Google Maps JavaScript API v3
On Aug 9, 9:21 pm, Kesuke <Nick_dai...@hotmail.com> wrote:
> haven't been able to find a place where I can put the IF rules.
> Any suggestions where this should go?
>

I've got a few ideas but will try it in code later today and post
something here if it works!

...

William

unread,
Aug 10, 2010, 6:38:52 PM8/10/10
to Google Maps JavaScript API v3
On Aug 9, 9:21 pm, Kesuke <Nick_dai...@hotmail.com> wrote:
>
> The second problem is with the actual construction of the controller,
> I've got parts of the code together athttp://anatomy.study-medicine.co.uk/testk2.html
> but haven't been able to find a place where I can put the IF rules.

I made a start on this, when the checkbox is being constructed:
http://www.william-map.com/20100811/1/rules.htm

if there's no rule, initialize to the value given, otherwise evaluate
the rule and add a listener on each of the layers in the rule to
reevaluate it when the visible property changes:

if (layers[i].rule == "none") {
checkbox.checked = layers[i].visible;
} else {
var ids = layers[i].list.split(',');
evaluateRule(checkbox, layers[i], ids);
for (var j=0; j<ids.length; j++) {
var overlay = overlays.get(ids[j]);
createListener(checkbox, layers[i], ids, overlay);
}
}

function createListener(checkbox, layer, ids, overlay) {
google.maps.event.addListener(overlay, "visible_changed", function()
{
evaluateRule(checkbox, layer, ids);
});
}

function evaluateRule(checkbox, layer, ids) {
checkbox.checked = layer.operation(ids);
overlays.get(layer.id).set("visible", checkbox.checked);
}

...

Nianwei Liu

unread,
Aug 10, 2010, 10:03:44 PM8/10/10
to Google Maps JavaScript API v3
Have you simply try implement a custom map type class that supports
show/hide/opacity? in V3 you get hold on the actual tile element so
all can be done relatively easily.

Kesuke

unread,
Sep 10, 2010, 9:14:45 PM9/10/10
to Google Maps JavaScript API v3
I’ve been tinkering with this over the past few weeks and in many
cases its working very nicely. I’ve figured out ways I can use the
‘any’ and ‘all’ rules to cover almost any situation which is great.

There’s one issue - some layer controls (checkboxes) should not be
seen by the user. E.g. ‘n’ and ‘f’ on the example below. We set it up
to accommodate that originally, with an array property called
‘control: true/false’.

However, the evaluateRule function uses those checkboxes – so if
“control: false”, the rules for that layer are ignored.

Any ideas how I can get around this (so a layer can have its
control:false but its rules still evaluate)?

Example: http://anatomy.study-medicine.co.uk/testk4.html
Reply all
Reply to author
Forward
0 new messages