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

StackOverflow https://stackoverflow.com/questions/7249565

  •  16-01-2021
  •  | 
  •  

Pergunta

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!

Foi útil?

Solução

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.

Outras dicas

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 :

  1. prepare a RestFul service to generate KML file from DB (KML sample as inside above link)

  2. 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)

  3. Jsp web page allow user to download KMZ file.

  4. When Google Earth open KMZ file, Google Earth will auto refresh to get new data from that Restful service

  5. 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>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top