Sorry in advance if this is a noob question.
All kml files start with roughly the same two lines:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
In the second line there is a reference to a web address which contains the schema for kml.
Am i to understand that this is contacted every time a kml file is
read ?
Secondly, is it possible (and how) to not have to contact
this (and other) addresses ?
The xmlns reference in a KML file only defines the XML namespace which happens to be associated with an XML Schema that defines that namespace.
Google Earth or Google Maps do NOT download the KML schema every time a KML file is accessed. In fact, it won't ever download the XML schema. The namespace just tells GE how to handle the file.
It just so happens that the Namespace URI for KML is a URL that redirects to the appropriate XML Schema.
In fact the complete schema reference for KML would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/kml/2.2
http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd">
...
</kml>
A description of XML namespaces can be found here:
http://www.w3.org/TR/REC-xml-names/#sec-namespaces
On a related note the standard icons you can use for your KML placemarks (e.g. http://maps.google.com/mapfiles/kml/shapes/airports.png) are likewise never downloaded by the Google Earth client. Those images are part of the installed Google Earth application from which Google Earth maps URLs to the local image file.
Related
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 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>
Is it possible to create a KML file without coordinates in it? I have a list of addresses and I don't have the long/lat. I'd like to create a KML file and have Google Earth geocode and determine the long/lat for each placemark. Thanks in advance.
The geometry (e.g. Point, Polygon, etc.) in a KML Placemark is not required.
You can just have an address in your KML placemarks and Google Earth will automatically geodecode it for you if it can. Under the covers Google Earth will perform a lookup on that address and use the first match if any results are returned. Basically, the resolved address will be the same as if you entered an address via search panel in Google Earth or Google Maps.
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
<name>Google place</name>
<address>1600 Amphitheatre Parkway, Mountain View, CA</address>
</Placemark>
</kml>
After that if you save your KML then Google Earth will have inserted the coordinates for you into each Placemark.
<Point>
<coordinates>-122.083954,37.421998,0</coordinates>
</Point>
You can create KML file without coordinates when you have an address in your file. You can input the data from MS Excel for instance, if you are interested a batch operation. See the solution below:
http://www.mkrgeo-blog.com/input-a-multiple-address-list-in-google-maps-and-google-earth-the-quickest-way/
Then Google Earth will geocode your placemarks automatically when save it as a .kml file again.
It only works when you have no additional data in your excel column. If so, then you must import the Excel spreadsheet to the Google Earth directly, as per the explanation below:
https://gis.stackexchange.com/questions/298570/exporting-layer-from-google-my-maps-as-kml-has-no-geometries/332642#332642
I have developed the following network link for dynamic updates :
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<NetworkLink>
<name>Loads TEST.kml</name>
<Link>
<href>/home/desktop/farhan/test.kml</href>
</Link>
</NetworkLink>
</kml>
Test.kml file has two placemarks.
My network link file is getting successfully updated on changes in Test.kml file
Now what I want to do is to place an 'IF' condition so that if a certain thing is true then placemark color is 'Green' Else 'Red'.
What should I do here ?? Is there any Java API I need to follow.
Depends how/where you want to host the KML and what those conditions are.
If the styles and conditions are static then you can generate the KML pre-set with those styles as part of the KML. For example, if you want to generate the KML based on some conditions such as population size > 100K => red, size > 50K => blue, otherwise white where each generated Placemark would have the appropriate shared share or inline style.
One popular Java-API to generate KML is the Java API for KML (or JAK for short).
If the views (based on conditions) are "dynamic" and user-selected then you have a couple of options:
Generate different versions/views of the Placemarks based on different conditions with NetworkLinks and radioFolders to load a particular view. The KML could be statically generated once or dynamically via a web-service, servlet, CGI-script, etc.
For example, the USGS has an earthquake real-time feed with multiple NetworkLinks each with a different view/color/size scheme for the same data (e.g. color by age vs magnitude).
Check out http://earthquake.usgs.gov/earthquakes/feed/earthquakes.kml
Use the Google Earth API to load, create, and modify KML in context of HTML and JavaScript with Google Earth running as a plugin in your web browser. This requires some JavaScript programming.
Use NetworkLinks as shown in your example combined with NetworkLinkControl elements to globally change the shared styles. See NetworkLinkControl tutorial. You can't add NetworkLinkControl elements to your KML directly in Google Earth so you have to author your KML manually or programmatically.
use php , if you are aware of it and generate kml with the help of your table and also you can use various plugins and JAK as told by jason above.
What you can do is :
connect your mysql db ( having latnlong ) through jdbc.
2 .Run a loop i.e while loop which will add placemarks as per the latitude and longitude and add other necessary element of kml like :
Element ristyle = doc.createElement("IconStyle"); // this will create an Icon.
make a new file through :
Result dest = new StreamResult(new File("file location"));
this will create your new kml file
-- place a condition here which will show your condition like a normal loop.
5 Make a network link and refer your kml file in this for manual updation.
I think this should work
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>