I have a web working with google-earth API where I use multiple KML layers to show data.
With the interactions of the user it's necessary to modify some properties of the placemark like styles and names in order to change the placemarks display information.
In some cases I would like to modify at the Altitude
of the placemarks, information included in the Point
information of the geometry specified at the KML. Actually it is clampedToGround
and I would like to modify it to any number in order to be in top of other elements.
This is an example of how I modify the placemarks information:
var pm = ge.getElementByUrl(UrlOfLayer#IdOfPlacemark);
pm.setStyleUrl(UrlOfLayer#IdOfStyleMap);
pm.setName(NewName);
This is working perfectly and all changes are applied without any problem. The structure of the KML placemarks is as it follows:
<Placemark id="1">
<name>Name</name>
<visibility>1</visibility>
<open>0</open>
<Point>
<extrude>1</extrude>
<tessellate>1</tessellate>
<altitude>clampedToGround</altitude>
<coordinates>1,1,1</coordinates>
</Point>
<styleUrl>#style</styleUrl>
</Placemark>
With this structure and the Placemark in Javascript got by getElementByUrl
I can access the fields name, visibility, etc just by getName()
, getVisibility()
, etc.
But, this doesn't work with Point information, since that is included inside the Geometry
object of the placemark.
I can access the Geometry information by using pm.getGeometry()
, but after that, the 'Point' can't be accessed because as Google earth documentation sais:
The KmlGeometry object is an abstract object and cannot be used directly. It provides a placeholder object for all derived Geometry objects.
Looking at some examples where the Point information is used, it's only used to create a Point and after that include it at the Geometry, but in my case I can't create the point in Javascript because I can't get the coordinates information and the new point would overwrite it.
So, is there any accessor I haven't been able to find to accomplish this purpose?
The documentation is a bit unclear on that point; it should perhaps say that KmlGeometry
objects cannot be instantiated directly. There are, in fact, several methods on a KmlGeometry
object, which you can see in the documentation if you click through the "List of all members" link (the most relevant ones are inherited from KmlObject
).
All the different geometry types inherit from KmlGeometry
, but since you know that this geometry is a KmlPoint
, you can just treat it as a KmlPoint
(in other languages you might have to explicitly cast the variable, but, for better or worse, Javascript is more forgiving). In your case, you could do
var point = pm.getGeometry();
point.setAltitude(newAltitudeValue);
point.setLatLng(...);
etc. You can use all the normal KmlPoint methods.
Incidentally, if you don't know the specific type of geometry (for instance, if the geometry is returned as the target on a click event and could be anything), you can always ask it with getType
inherited from KmlObject
(in this case, pm.getGeometry().getType()
would return 'KmlPoint'
), which you could then act upon. Not a perfect reflection system, but it works.
Addendum: Your example KML contains the line
<altitude>clampedToGround</altitude>
which is not valid KML. What you probably mean is
<altitudeMode>clampToGround</altitudeMode>
Earth discards the element it doesn't understand (though a validator will show this error), but it doesn't especially matter in this case, since clampToGround
is the default altitudeMode anyway. This is the cause of any altitude changes being dropped, as clampToGround
"indicates to ignore an altitude specification" (per the docs), so the point will be placed at ground level regardless of its altitude value.
To be able to change the altitude, either change the KML you're feeding it, using relativeToGround
or absolute
as the altitudeMode, or use the API to change it, e.g.
pm.getGeometry().setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);
Then any altitude you set via pm.getGeometry().setAltitude(...)
should work.