In the GE Plugin API GEHelper.cs there is a function FlyToObject. Since I've been unable to get the kml to fly me to a placemark I thought I would use the API call.
The required arguments for FlyToObject are:
"dynamic ge,"
"dynamic feature,"
I'm stuck on what the 'feature' argument is. The description says "the api object". I'm not sure which api object that is referring to or how to create it.
What I'm trying to do is automatically (upon loading the file) "fly to" a placemark in my kml file.
If anyone knows how to do what I'm asking with KML that would be great. Here is the KML file I'm loading that does NOT work. This is one of Google's example files.
<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
<name>300m straight down</name>
<Camera>
<longitude>-122.4783</longitude>
<latitude>37.812</latitude>
<altitude>300</altitude>
<heading>0</heading>
<tilt>0</tilt>
<roll>0</roll>
<altitudeMode>absolute</altitudeMode>
</Camera>
</Placemark>
</kml>
THANKS!
If you are loading Google Earth into your own webpage, you have access to the GE API via javascript. Therefore if you want to set a certain view, use the following code
// Create a new LookAt.
var lookAt = ge.createLookAt('');
// Set the position values.
lookAt.setLatitude(36.584207);
lookAt.setLongitude(-121.754322);
lookAt.setRange(5000.0); //default is 0.0
// Update the view in Google Earth.
ge.getView().setAbstractView(lookAt);
More advanced: If you are loading a custom kml file, with your own Placemarks. Assign them as id as such in your kml file
<Placemark id="uniqueId">
Then, once loaded, use this code
placemark = ge.getElementById(uniqueId);
if (placemark == null) {
return false;
} else if (placemark.getAbstractView()) {
ge.getView().setAbstractView(lastViewLoaded);
}
Related
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.
I am creating a KMZ file as output from my program (using SharpKML). How can I set the initial view so that when this file is opened in Google Earth it centres and zooms around my data?
When I open a KML file in GE this behaviour is by default, but when I open my KMZ the browser just opens to the default whole world view centred on users country. If I double click the main KML within my KMZ file, then I get the correct zoom and centering around my data. How can I make this happen automatically when Google Earth loads the KMZ?
Thanks.
If you add a LookAt or Camera to the first element in your root KML file (first .kml file within your KMZ) Google Earth will start at that location when that file is loaded.
<?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">
<Placemark>
<name>Google office</name>
<LookAt>
<longitude>-122.087387</longitude>
<latitude>37.422130</latitude>
<altitude>0</altitude>
<heading>-0.23</heading>
<tilt>47.81</tilt>
<range>115.5</range>
<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
</LookAt>
<Point>
<coordinates>-122.087461,37.422069</coordinates>
</Point>
</Placemark>
</kml>
If you have multiple features then add the <LookAt> to the root-level Document.
<kml>
<Document>
<LookAt>
...
</LookAt>
<Placemark>
</Placemark>
...
There is also a really easy way to do this in Google Earth/Google Earth pro:
Simply right click and bring up properties of the Folder in Places.
Go to the view tab and click the Snapshot current view.
Then save place as to update the kmz/kml.
This updates the <LookAt> at the level you click on- so for a point at the Placemark level or you can do it at the folder level.
I used to open my kmz files in Javascript and they would center automatically, but now as of a few weeks ago, my maps open up above the north pole. I created the kmz files so long ago I don't want to look at them or edit them. Is there some code I can add so that it works like it did before? I had before my open code
var overlay = new GGeoXml(\"http://www.mysite.com/data/file.kmz" ) ;
map.addOverlay( overlay ) ;
this bogus looking code that does not seem to initialze anything, but worked
var bounds = new GLatLngBounds();
// initialize bounds ??
var SWcorner= new GLatLng(parseFloat(87),parseFloat(-1));
var NEcorner= new GLatLng(parseFloat(89),parseFloat(1));
bounds.extend(SWcorner);
bounds.extend(NEcorner);
map.setCenter(new GLatLng(88.0, 0), map.getBoundsZoomLevel(bounds),
G_PHYSICAL_MAP);
If I double Click on my KML file it does what it should and start GE and does as expected. When I put it in to my HTML file it will not work. I then put it into http://earth-api-samples.googlecode.com/svn/trunk/examples/kml-fetch-interactive.html and it doesn't work from there either. This is the link to the KLM https://dl.dropbox.com/u/61240296/myPoints.Kml. It is bascially a direct copy of a Google Sample. Are KML files dependent on other KML files? One thing I have notice is there are no roads so it appears as though non of the KML files are open or active.
<?xml version="1.0" encoding="UTF-8"?>
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">
<Camera>
<longitude>-93.2539393007755</longitude>
<latitude>45.5456585437059</latitude>
<altitude>139.629438</altitude>
<heading>-70.0</heading>
<tilt>75</tilt>
</Camera>
<Placemark>
<name>Placemark from KML file</name>
<Point>
<coordinates>-93.2539393007755, 45.5456585437059</coordinates>
</Point>
</Placemark>
</Document>
</kml>
Your KML file is fine. It also works perfectly in the example page you link to. The problem is the sample page does not change the view after loading your kml file. It doesn't even try to.
Edit this function
function finishFetchKml(kmlObject) {
// check if the KML was fetched properly
if (kmlObject) {
// add the fetched KML to Earth
currentKmlObject = kmlObject;
ge.getFeatures().appendChild(currentKmlObject);
} else {
// wrap alerts in API callbacks and event handlers
// in a setTimeout to prevent deadlock in some browsers
setTimeout(function() {
alert('Bad or null KML.');
}, 0);
}
}
to look like this
function finishFetchKml(kmlObject) {
// check if the KML was fetched properly
if (kmlObject) {
// add the fetched KML to Earth
currentKmlObject = kmlObject;
ge.getFeatures().appendChild(currentKmlObject);
///////////////////////////////////////////////
// this is what you need to add
var myView = currentKmlObject.getAbstractView();
ge.getView().setAbstractView(myView);
//////////////////////////////////////////////
} else {
// wrap alerts in API callbacks and event handlers
// in a setTimeout to prevent deadlock in some browsers
setTimeout(function() {
alert('Bad or null KML.');
}, 0);
}
}
Then you need to decide if you want to assign that <Camera> view to the <Placemark> or the <Document>
and in case you didn't realise, your <Camera> view does NOT look at the <Placemark> it looks at the horizon from a spot directly above the <Placemark>
If you are trying to load a well formed KML file and the file doesn't load properly you should see the headers of the web server using the developer tools of chrome, firebug or similar.
If you are using apache as your webserver you should add to your httpd.conf:
AddType application/vnd.google-earth.kml+xml .kml
AddType application/vnd.google-earth.kmz .kmz
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>
I am new to the KML format and try to figure out how to display a boat (a png), moving from a place to another along a path (a simple line drawn composed of several lines).
I can see how to display a Placemark, even with an icon, and a Path, separately.
What I would like to see when I click on the KML file is :
the boat appearing at the departure point;
the path drawing itself until the arrival;
the boat icon moving at a comfortable speed (bonus point it I can set a ration time / progress, extra bonus if I can click on start, pause or rewind) from departure to arrival along the path.
Is that even possible ? I know it is with Google Map, but you can program it with Javascript, which eases things a lot.
This is an old question, and there is now a better way to move a placemark (or even better a model) along a pre-determined linestring. Look into using this feature:
http://code.google.com/apis/kml/documentation/kmlreference.html#gxtrack
Sample code:
<?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">
<Folder>
<Placemark>
<gx:Track>
<when>2010-05-28T02:02:09Z</when>
<when>2010-05-28T02:02:35Z</when>
<when>2010-05-28T02:02:44Z</when>
<when>2010-05-28T02:02:53Z</when>
<when>2010-05-28T02:02:54Z</when>
<when>2010-05-28T02:02:55Z</when>
<when>2010-05-28T02:02:56Z</when>
<gx:coord>-122.207881 37.371915 156.000000</gx:coord>
<gx:coord>-122.205712 37.373288 152.000000</gx:coord>
<gx:coord>-122.204678 37.373939 147.000000</gx:coord>
<gx:coord>-122.203572 37.374630 142.199997</gx:coord>
<gx:coord>-122.203451 37.374706 141.800003</gx:coord>
<gx:coord>-122.203329 37.374780 141.199997</gx:coord>
<gx:coord>-122.203207 37.374857 140.199997</gx:coord>
</gx:Track>
</Placemark>
</Folder>
</kml>
The only way I've been able to make this work in static KML is to interpolate between the start and stop points and add placemarks for each frame I want to animate. So, from t=0 to t=1, draw a placemark at the start point. From t=1 to t=2, draw a placemark at the next point, etc.
This gives you the temporal player bar in Google Earth and you can rewind or advance the animation. However it is a little annoying because you wind up with every interpolation point in your placemark tree. Putting the placemarks in their own folder keeps them out of the way, but there's no way to hide them from the user.
Take a look at http://code.google.com/apis/kml/documentation/time.html#animating
The whale shark example does more or less what you want for the placemark. (The URL for the marker icon is broken). Animating the progress along the track can be done using the same trick.
If you want to try something much more difficult, you can try serving dynamic KML. Have Google Earth load a network link to your initial data. Then load another network link with an that sends an update for your placemark at every time tick.
http://code.google.com/apis/kml/documentation/kmlreference.html#link
http://code.google.com/apis/kml/documentation/updates.html
This approach has some serious disadvantages because it requires an external program to drive Google Earth and it does not give the user access to the built-in Google Earth temporal player bar. It also requires that all the data be loaded over a network link -- KML data from a file cannot be updated. That means your driver program needs to act as a http server. Also, in this model it is very hard to know exactly when Google Earth has finished loading and drawing the update. Really I don't recommend doing this; you can make it work using the Google Earth COM API, but it will always be a fragile solution.
There's a browser plug-in that lets you embed Google Earth into a browser page. From there you can use JavaScript to animate your placemark, change your paths, etc. Check out the Google Earth API Developer's Guide.
If you are going to display a boat on Google Earth, a 3D model would be a better approach then an image, since the users can change the viewing angle.
You might want to look into tours: http://code.google.com/apis/kml/documentation/touring.html
I've seen something like this done using a combination of (a number of) <gx:AnimatedUpdate> tags to move a previously created placemark representing your boat and <gx:FlyTo> tags to move the view (I think) all within a <gx:Playlist>.
Hope this helps.
I'm presuming this functionality did not exist when originally answered, but you can achieve the effect using a tour. The following shows a placemark moving in this fashion.
<?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">
<Document>
<Placemark id="boat">
<Point>
<coordinates>0,0</coordinates>
</Point>
</Placemark>
<gx:Tour>
<name>Play me!</name>
<gx:Playlist>
<gx:FlyTo>
<gx:duration>5.0</gx:duration>
<LookAt>
<longitude>0</longitude>
<latitude>0</latitude>
<altitude>0</altitude>
<heading>-95</heading>
<tilt>65</tilt>
<range>250000</range>
<altitudeMode>relativeToGround</altitudeMode>
</LookAt>
</gx:FlyTo>
<gx:AnimatedUpdate>
<gx:duration>5.0</gx:duration>
<Update>
<targetHref/>
<Change>
<Placemark targetId="boat">
<Point>
<coordinates>1,1</coordinates>
</Point>
</Placemark>
</Change>
</Update>
</gx:AnimatedUpdate>
<gx:Wait>
<gx:duration>6.0</gx:duration>
</gx:Wait>
</gx:Playlist>
</gx:Tour>
</Document>
</kml>
The path could be marked with points whose visibility is altered by the tour at the appropriate time.
I have following sample in Google site. Hope this help.
(details inside : https://sites.google.com/site/canadadennischen888/home/kml/auto-refresh-3d-tracking)
prepare a RestFul service to generate KML file from DB
(sample as in https://sites.google.com/site/canadadennischen888/home/kml/3d-tracking)
My other code will generate a KMZ file which has a link to my Restful service
(sample as in this page)
KMZ file has onInterval
Web page allow user to download KMZ file which has URL that link to my Restful service
When Google Earth open KMZ file, Google Earth will auto refresh to get new data from that Restful service
Just google for "kml time animation"
KML: Time and Animation
KML: Animation
Animation and Dynamic Updates with KML