Updating an existing NetworkLink - kml

I have a system set up where a simple NetworkLink is installed in many user systems.
I then periodically (every week or so) update the kml/z file that it links to and users can refresh to see the latest version.
It would have been nice had I made it automatically refresh but when I created it I did not think too hard.
So is there a way of installing a updating process in the already distributed networklink, or can this link work through a second networklink to get the large kml file in a 'mostrecentversion' mode.
It would also be nice to make the links a little more invisible.
The link is currently:
The kml has the usual header and contains this one object
<NetworkLink>
<name>etc</name>
<Snippet maxLines="0"/>
<visibility>1</visibility><open>1</open>
<refreshVisibility>0</refreshVisibility>
<flyToView>1</flyToView>
<Link>
<href>http://dl.dropbox.com etc TrapLinesData.kmz</href>
</Link>
</NetworkLink>
But I did not put any refreshModes etc.
Any thoughts on this bootstrapping need will be appreciated as trying to show the less skilled user how to Refresh is becoming a problem.
Bob J.'

By having a NetworkLink in your KML makes all Google Earth clients load the latest KML that is referenced each and every time they start up. Google Earth will not store the contents of the NetworkLink (only NetworkLink reference itself) -- that content is fetched each time upon startup.
If you only update your target KML once a week and not every hour then you should not have a problem with the KML as it currently exists in clients. The only clients that won't get the update are those Google Earth clients that stay up and running for weeks at a time which is not that common.
If you want to force a refresh even for a week interval then you could define NetworkLink as the following:
<NetworkLink>
<Link>
<href>...</href>
<refreshMode>onInterval</refreshMode>
<refreshInterval>604800</refreshInterval>
</Link>
</NetworkLink>
If your KML is only for a particular region then you may want to define a Region in your NetworkLink and change <viewRefreshMode> to onRegion so it only loads when that Region is in view. No need to fetch your KML if the region is not in view -- KML best practice. Your KML would then look like this:
<NetworkLink>
<Region>
...
</Region>
<Link>
<href>...</href>
<refreshMode>onInterval</refreshMode>
<refreshInterval>604800</refreshInterval>
<viewRefreshMode>onRegion</viewRefreshMode>
</Link>
</NetworkLink>

Related

Google earth sequential placemarks on a time delay

I have a KML file with a few different placemarks all around the globe. I would like to flyto the first placemark and display it's balloon, wait a minute or two, then flyto the next placemark, and repeat this process until all of the placemarks have been shown.
I think I might be able to achieve this by putting all the placemarks into a tour but this doesn't seem like the right approach. I'm going to be refreshing the KML from a server and I'm not sure how a tour would react to that (e.g., I think you have to always click play before starting a tour).
If this isn't possible I may have to place just a single placemark in the KML file and then keep refreshing the file with a different placemark. I think that approach might be bad though because it will be refreshing a lot more.
I ended up putting one placemark per KML file. I wrote a program in Java that uses the Saxon processor and an XSLT stylesheet to create multiple KML files with just a single placemark per file then using this tutorial I was able to cycle through the KML files one-by-one.
When doing this locally on my machine I created two folders. Folder A housed all the KML files. Folder B would house only one KML file which would be the file expected from the KML NetworkLink tag. In the Java program I had a timer thread that sequentially deletes the single file in Folder B, cuts a file out of Folder A, moves it into Folder B, then renames the newly placed file the common name which the KML NetworkLink tag expects. I hope this helps and the link will help this to make more sense.
(Base KML file which is loaded into Google Earth - Basically tells Google Earth to look for the file called every10.kml every 10 seconds. If we swap that file out, say, every 9 seconds, then once it's refreshed by Google Earth it will be a new KML file thus showing the new placemark)
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<NetworkLink>
<Link>
<href>every10.kml</href>
<refreshMode>onInterval</refreshMode>
<refreshInterval>10</refreshInterval>
</Link>
</NetworkLink>
</Document>
</kml>

kml document auto refresh in google earth

I have an app that over time writes Placemarks to a kml file, slowly building up a route over time.
When I open the file in Google Earth, I can see the Placemarks already in the file, but any new ones added to the doc aren't shown on the map, until I reopen the document again.
Is there any way of getting the document to auto refresh in Google earth?
I've tried putting a NetworkLink into the document whose href points itself (the file) with a refreshMode of onChange, and that works, but the whole document is reloaded on each change and each point is displayed again, which is messy.
NOTE: I can't change the apps code, to generate single Placemark updates, which I believe is the proper way of using NetworkLinks.
The only way to perform incremental updates in KML is using the NetworkLinkControl element in conjunction with a NetworkLink.
NetworkLinkControl controls the behavior of files fetched by a <NetworkLink> in which you can change, add, or delete elements that you already fetched.
<NetworkLinkControl>
<cookie>cookie=sometext</cookie>
<linkName>link name</linkName>
<Update>
<targetHref>same-targethref-for-networklink</targetHref>
<Create>
<Document targetId="targetdoc">
<Placemark>
<name>Created place1</name>
</Placemark>
<Placemark>
<name>Created place2</name>
</Placemark>
</Document>
</Create>
...
</Update>
</NetworkLinkControl>
The NetworkLinkControl is tricky to get working such as the URLs in the NetworkLink and NetworkLinkControl must match exactly.
You can find a tutorial with an example to get started.
https://developers.google.com/kml/documentation/updates
So I guess you can't. I thought there might be some kind of structure within kml to achieve this, nut it would appear not.

Google Earth KML - Weird GE behavior when using balloon links to fragment URLs when doc loaded via NetworkLink

KML newb here. First post.
Using GE client application, v7.12. Have fairly simple KML doc containing placemarks to several GPS time-based breadcrumb points. Wrote a simple C# app to generate the kml doc. Expect to have several more like files for additional tracked entities. I get this working and decide to fancy up the placemark balloons via HTML. Ultimately decide I'd like to have links in the balloon to move to the previous or next placemark. Find advice on this site and make it happen.
Since my app may update(by rewriting) the doc at times it would be nice to not have to manually reload it. Plus there will ultimately be other docs for other tracked entities, all controlled/updated by my app. OK - NetworkLink to the rescue. Cool feature and gives me the option of dynamically modifying the networklinks file to only include the entity doc files that have changed. Plus big bonus -- turning 'flyToView' off so that when networklinks file is reloaded or refresh fires, I'm not pulled away from whatever I'm currently viewing by the default 'LookAt' that normally seems to happen when a doc is loaded directly (anyone know a way around this?)
Very happy, until I discover that when I click one of my balloon links to move to the next or previous point, GE decides to create a new copy of the entire containing document under Temporary Places and now I have two entire sets of points displayed, one hiding the other. On the surface, my next/prev links appear to be working, but they are actually only working with the newly created doc. To test, I alter the original doc with an entirely different set of locations. Reload the networklinks doc to bring in the new point-laden doc and see the new set of points. But when I use any balloon links on the new, they jump to points on the older doc that GE had created on its own. Delete the GE-created version, click balloon and viola, GE creates a new copy of it and were back where we started. Frustrating.
As placemark IDs, I'm using strings like "TPn", where n increments. In my balloon links, I'm linking to the fragment URLs such as href="#TPn-1" and href="TPn+1", ie TP2 links to TP1 and TP3, etc, and I account for both placemarks on the end so they don't have bad links to non-existent IDs. BTW, I've found when you do activate a link to a non-existent fragment URL, GE also decides to create a copy of the file, even if the file was loaded directly and not via a networklink, so you again have one point set laying on top of the other. However, I'm confident I have no bad links in this case.
Any light that can be shed would be appreciated. Or alternate ways of achieving my goals. I'm a KML newb after all and maybe there's something I'm doing wrong.
I suppose if I have to, I will sacrifice the balloon links. Being able to reload only one networklinks document for a collection of files + timed refresh + turning off flyToView are too desirable to lose now.
Thanks!
EDIT: Additional info - The duplicate document is created only when using balloon links. Clicking a link in the treeview under the placemark does not cause this anomaly. (In the code sample, remove the null Snippet element for each Placemark to see this effect.) Furthermore, it appears that a balloon link to ANY fragment URL causes the anomaly, such as a link back to a containing folder or document.
EDIT: Added 2 code samples. These are pared down to my essential needs, but still demonstrate the problem. Interesting to note the difference in the GE tree view when the data file 'document' element has an 'id' defined vs not, but it has no bearing on the problem. I prefer the look when the id is omitted.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- File is: C:\myTwoDataPoints.kml -->
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="myDoc">
<name>Two Points Doc Name Here</name>
<description>Doc Description Here</description>
<visibility>0</visibility>
<Snippet>Contains Two Data Points</Snippet>
<Style id="myStyle">
<BalloonStyle >
<text><![CDATA[Link To: $[description] ]]></text>
</BalloonStyle>
</Style>
<Folder>
<name>Points Folder</name>
<open>1</open>
<Placemark id="TP1">
<name>Miami, FL, USA</name>
<Snippet />
<description><![CDATA[New York]]></description>
<styleUrl>#myStyle</styleUrl>
<Point>
<coordinates>-80.226439,25.788969,0</coordinates>
</Point>
</Placemark>
<Placemark id="TP2">
<name>New York, NY, USA</name>
<Snippet />
<description><![CDATA[Miami]]></description>
<styleUrl>#myStyle</styleUrl>
<Point>
<coordinates>-74.005973,40.714353,0</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
and...
<?xml version="1.0" encoding="UTF-8"?>
<!-- File is: C:\myNetworkLink.kml -->
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>NetworkLink Document Name Here</name>
<visibility>0</visibility>
<open>1</open>
<NetworkLink>
<name>NetworkLink Name Here</name>
<refreshVisibility>1</refreshVisibility>
<flyToView>0</flyToView>
<Link><href>file:///C:/myTwoDataPoints.kml</href></Link>
</NetworkLink>
</Document>
</kml>

How to force network links to refresh, even after they encounter a file error?

I have a program that is constantly writing/updating a KML file, and I have a network link that points to this file. Under heavy load, if the Network Link attempts to access the KML file at the same time as my program is writing to the KML file, Google Earth stops any further auto-refreshing of that Network Link, assuming it to be broken. At this point, I then have to right-click the network link in the Places pane of Google Earth, and hit refresh, for the auto-updating to begin again.
My question is, is there any way to force Google Earth to keep reading from network links, even after a "no file detected" error? Because it is a real hassle having to manually hit refresh for the network link to become active again, when it seems that task could be easily automated.
I have made countless optimizations on my program's part to minimize the time period it spends writing to the KML file, however I have reached a practical limit, and must now figure out a way to fix this network link issue from within Google Earth.
Any replies, comments, or discussions would be greatly appreciated!
We had a similar problem a while ago. In searching the google-earth kml developers forums, a few people recommended using a network-link to a network-link approach like so:
KML file 1 that links to the updating kml file:
<Document>
<NetworkLink>
<Link> my_URL_to_the_updating_kml
<refreshMode>onInterval</refreshMode>
<refreshInterval>my_Inteval</refreshInterval>
</Link>
<name>My_Name</name>
<visibility>1</visibility>
</NetworkLink>
</Document>
KML file 2 that links to the network link file above:
<Document>
<NetworkLink>
<Link>
my_URL_to_the_first_network_link_file
<refreshMode>onInterval</refreshMode>
<refreshInterval>3600</refreshInterval>
</Link>
<name>My_Name</name>
<visibility>1</visibility>
</NetworkLink>
</Document>
If you're writing to a file on the server a simple trick is write to a temp file then swap with the target file like this:
write temp file temp.kml
delete target.kml
rename temp.kml target.kml
The renaming of the files will be nearly instantenous so very unlikely the Google Earth client will fetch it the momemt it's being swapped out. Depending on the OS of the server you could also use symbolic links to change the file reference in one operation.
UPDATE: in whatever is writing the file can you set the filename in a shared variable and serve that file via a "servlet" that opens a stream to the current file. The networklink can point to the servlet rather than the static KML file.

How to properly update Google Earth KML using NetworkLinkControl and the Java API for KML (JAK)?

I'm building an application that serves up data to a standalone Google Earth client. I want to send over an initial set of data, then update it dynamically using <NetworkLinkControl> and <Update><cookie> tags as things change on the server. I'm generating the KML using the Java API for KML (JAK) library. Unfortunately, while I can confirm that GE is refreshing my NetworkLink and pulling down the Updates I'm sending, none of my updates are showing up in GE. After lots of reading, it seems like it might be that the Update's <targetHref> might be the issue, but I'm 99.9% sure I'm sending over the same string.
Part of what has me confused is that I've seen conflicting info on whether or not the <cookie> element's value needs to be appended to <targetHref>. I did actually see one early prototype updating when I was serving up hand-written test KML files from a static server URL, so I suspect it's not. Actually, that's what's frustrating at the moment: I've seen updating work on my own machine, but can't get it working now with what looks like valid and correct KML.
The current setup looks like this (extraneous XML namespaces stripped for clarity; "$CLIENT_ID" is a GUID-like string):
Root KML file served from http://server/kml/${CLIENT_ID}:
<kml xmlns="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><NetworkLink>
<Link>
<href>http://server/kmlupdates/${CLIENT_ID}</href>
<refreshMode>onInterval</refreshMode>
<refreshInterval>1.0</refreshInterval>
<viewRefreshTime>0.0</viewRefreshTime>
<viewBoundScale>0.0</viewBoundScale>
</Link>
</NetworkLink></kml>
Initial content KML served from http://server/kmlupdates/${CLIENT_ID}:
<kml><NetworkLinkControl>
<minRefreshPeriod>0.0</minRefreshPeriod>
<maxSessionLength>-1.0</maxSessionLength>
<cookie>cookie=0|kmlRequestType=updates|projectID=6|lastUpdateSeenIndex=-1</cookie>
</NetworkLinkControl>
<Document id="myProject">
<name>My ProjectProject</name>
<Placemark id="pm1"><name>point1</name>
<Point><coordinates>-117.0,35.0</coordinates></Point>
</Placemark>
</Document></kml>
Later update KML served from http://server/kmlupdates/${CLIENT_ID}:
<kml><NetworkLinkControl>
<minRefreshPeriod>0.0</minRefreshPeriod>
<maxSessionLength>-1.0</maxSessionLength>
<cookie>cookie=0|kmlRequestType=updates|projectID=6|lastUpdateSeenIndex=0</cookie>
<Update>
<targetHref>http://server/kmlupdates/${CLIENT_ID}</targetHref>
<Change>
<Placemark targetId="pm1">
<name>Name changed by Update Change</name>
</Placemark>
</Change>
</Update>
</NetworkLinkControl></kml>
If anyone has any suggestions on what I'm missing here, I'd greatly appreciate it. Thanks!
My original version of the question left out two facts that turned out to be relevant: 1) I'm using the Java API for KML to generate this, and 2) the XML namespaces inside <kml>. I finally figured this out after reading this Google KML Group post for the umpteenth time.
The problem is the last XML namespace, "xmlns:xal". For some reason, removing that from the KML allows the <Update> tags to actually change the items in Google Earth. JAK doesn't let you change the namespaces, but you can strip it manually from the marshaled string.
Absolutely bizarre, but at least I found a solution.
As per https://developers.google.com/kml/documentation/kmlreference:
<xal:AddressDetails> is used by KML for geocoding in Google Maps only.
Currently, Google Earth does not use this element; use <address> instead.
I have some sample using different approach to do something else here maybe related to yours (as your purpose "send over an initial set of data, then update it dynamically using tags") :
https://sites.google.com/site/canadadennischen888/home/kml/auto-refresh-3d-tracking
Approach is that all changes are from server Restful service. Hope it helps. Details as :
How to make a dynamic Auto refresh 3D Tracking :
prepare a RestFul service to generate KML file from DB (KML sample as inside above link)
My other jsp code will generate a KMZ file which has a link to my Restful service. KMZ file has onInterval ( as in the bottom)
Jsp web page allow user to download KMZ file.
When Google Earth open KMZ file, Google Earth will auto refresh to get new data from that Restful service
Everytime refreshing, server will send the latest update KML data with new data to GE.
KMZ sample:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2"
xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<NetworkLink>
<name>Dennis_Chen_Canada#Hotmail.com</name>
<open>1</open>
<Link>
<href>http://localhost:9080/google-earth-project/rest/kml/10001/20002</href>
<refreshMode>onInterval</refreshMode>
</Link>
</NetworkLink>
</kml>

Resources