Reputation: 51
I am trying to use kml to implement a heirarchy of regions as describe in KML 2.1 Tutorial
I would like to have a feature(polygon or icon) representing a region and when the region becomes active I would like to display a feature representing each of the regions immediate children but no longer display the icon representing the parent region.
An example would be if I had a region representing Canada and a placemark in the middle of the region. When the Canada region becomes active I want the canada placemark to disappear and want to display placemarks over the provinces of Canada(a region and placemark for BC, Alberta ect.). Then when the BC region became active I would like to replace the bc placemark with placemarks for cities in bc.
Any help would be greatly appreciated. Thank you.
Upvotes: 1
Views: 2840
Reputation: 51
I am trying to do the same thing and came up with a solution that works however it requires many calls to the server.
In your base kml loaded from http://example.com/zones.kml you would have
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document id="base">
<Folder id="1_folder">
//Region responsible for hiding the current (Canada) Placemark when zoomed in and made inactive ALSO responsible for hiding children(BC, Alberta...) Placemarks when active
<Region>
<LatLonAltBox>
<north>74.79903411865234</north>
<south>41.508766174316406</south>
<east>-52.03630065917969</east>
<west>-139.96746826171875</west>
</LatLonAltBox>
<Lod>
<maxLodPixels>
1024
</maxLodPixels>
</Lod>
</Region>
//NetworkLink that hides children Placemarks when zooming out
<NetworkLink>
<refreshVisibility>1</refreshVisibility>
<Link>
<href>http://example.com/1/hide_children.kml</href>
<viewRefreshMode>onRegion</viewRefreshMode>
</Link>
</NetworkLink>
//The Canada Placemark
<Placemark id="1">
<name>Canada</name>
<Point>
<coordinates>-96.00188446044922,58.153900146484375</coordinates>
</Point>
</Placemark>
//Networklink for Loading Children While Zooming in
<NetworkLink>
<refreshVisibility>1</refreshVisibility>
// Same Region as above but with minLodPixels instead of maxLodPixels
<Region>
<LatLonAltBox>
<north>74.79903411865234</north>
<south>41.508766174316406</south>
<east>-52.03630065917969</east>
<west>-139.96746826171875</west>
</LatLonAltBox>
<Lod>
<minLodPixels>1024</minLodPixels>
</Lod>
</Region>
<Link>
<href>http://example.com/zones/1.kml</href>
<viewRefreshMode>onRegion</viewRefreshMode>
</Link>
</NetworkLink>
</Folder>
</Document>
</kml>
This requires two more kml files that are loaded to hide or show the children of a particular placemark.
The kml for hiding the children would be loaded from http://example.com/1/hide_children.kml and contains the networklinkcontrol to hide the children
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<NetworkLinkControl>
<Update>
<targetHref>http://example.com/zones.kml</targetHref>
<Change>
<Folder targetId="1_children"><visibility>0</visibility></Folder>
</Change>
</Update>
</NetworkLinkControl>
</kml>
The kml for showing the children would be loaded from http://example.com/1.kml and contains the networklinkcontrol to show the children the children
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<NetworkLinkControl>
<Update>
<targetHref>http://example.com/zones.kml</targetHref>
<Create>
<Folder targetId="1_folder">
<Folder id='1_children'>
//This folder is the same as the original zone
<Folder id="2_folder">
//Empty region if the zone has no children
<Region></Region>
//No need for networklink to hide children if zone has no children
//Placemark
<Placemark id="2">
<name>BC</name>
<Point>
<coordinates>-122.95623779296875, 50.06098937988281</coordinates>
</Point></Placemark>
</Folder>
//Same for other Provinces
//<Folder id="3_folder"></Folder>
//<Folder id="4_folder"></Folder>
</Folder>
</Folder>
</Create>
</Update>
</NetworkLinkControl>
</kml>
It would be best if you could define 2 different regions one for minLod and one for maxLod so you didn't need to have so many calls to servers and you didn't have to call the server to load children you have already loaded but I have not figured out how to do this yet.
This need to be optimized quite a bit. Please let me know if anyone can help find a more direct way of doing this. Thanks
Upvotes: 0
Reputation: 1229
You are on the right track, Regions are what you want. Check out this page for more info on how to use them
http://code.google.com/apis/kml/documentation/regions.html
In particular, you need to understand the Level of Detail (LOD). The LOD determines the view boundaries that activates and deactivates the region. In the end you need to create Regions in this format.
<Region>
<LatLonAltBox>
<north>50</north>
<south>45</south>
<east>28</east>
<west>22</west>
</LatLonAltBox>
<Lod>
<minLodPixels>128</minLodPixels>
<maxLodPixels>1024</maxLodPixels>
</Lod>
</Region>
You can set -1 so the region is ALWAYS shown, no matter how far someone zooms OUT or if you use the value above (128) that means that the bounding box you set, must take up 128x128 pixels of the viewers screen before it gets activated (seen).
The is what you use to turn the view off as they zoom in. Or leave at -1 so it never turns off no matter how far someone zooms IN.
For your question, you would have a region that contains a placemark in the middle of Canada. That region would have a minlodpixels of -1 and a maxlodpixels that corresponds with the minlodpixels of another region (which shows the placemarks in the provinces) I would make a region for each province seperately.
The trick is working out the boundaries of the - I use a square polygon with four points and then look at its code to extract the etc
Actually, here is a great page to show you how to create regions - make sure you download the kml called 'Screen Overlay Size Guide' - it makes things a LOT easier
http://earth.google.ca/intl/en_ca/outreach/tutorial_region.html
Upvotes: 1