I'm using the Java API for KML to create a KML file with several Placemarks, each with a description popup. Within the popup, I'd like to link to my REST API that I have running on localhost.
I've tried using a simple href
that calls the API directly, but that opens a new window upon click, which I don't want to happen.
Then, I tried changing the link to a button
that should trigger a callAPI
JavaScript function to call the API without opening a new window. Here is my Java code:
final Kml kml = new Kml();
Document doc = kml.createAndSetDocument()
.withName("My KML File")
.withOpen(true);
BalloonStyle bstyle = doc.createAndAddStyle()
.withId("balloonstyle")
.createAndSetBalloonStyle()
.withId("ID")
.withText("<font face='Courier' size='3'>$[description]</font><br/>");
Folder folder = doc.createAndAddFolder().withName("Placemark Points").withOpen(true);
Placemark placemark = folder.createAndAddPlacemark()
.withName("My Placemark")
.withVisibility(true)
.withOpen(true)
.withStyleUrl("#balloonstyle");
placemark.createAndSetPoint()
.withExtrude(false)
.withAltitudeMode(AltitudeMode.CLAMP_TO_GROUND)
.addToCoordinates(0.0, 0.0); // Using 0,0 as placeholder
placemark.setDescription(
"<button type=\"button\" onclick=\"callAPI()\"/>Call API</button>" +
"<script type=\"text/javascript\"> " +
"function callAPI() { " +
"var xhttp = new XMLHttpRequest(); " +
"xhttp.open('GET', '" + apiUrl + "', true); " + // apiURL = url to my REST API
"xhttp.send(); }" +
"</script>"
);
Sidenote: I've seen JAK examples that involve including the <![CDATA[...]]>
tags around the description, but this caused some formatting issues and didn't seem necessary (when I import the resulting KML file into Google Earth, the HTML in the description works without the tags/the tags themselves seem to appear automatically). I tried putting the tags back in as well, and it didn't fix the problem.
Here is a sample KML file that results from running my code (I've replaced my URL with the fake API URL https://jsonplaceholder.typicode.com/todos/1 as a placeholder):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:kml xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:ns2="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
<ns2:Document>
<ns2:name>My KML File</ns2:name>
<ns2:open>1</ns2:open>
<ns2:Style id="balloonstyle">
<ns2:BalloonStyle id="ID">
<ns2:text><font face='Courier' size='3'>$[description]</font></ns2:text>
</ns2:BalloonStyle>
</ns2:Style>
<ns2:Folder>
<ns2:name>Placemark -- Points</ns2:name>
<ns2:open>1</ns2:open>
<ns2:Placemark>
<ns2:name>My Placemark</ns2:name>
<ns2:visibility>1</ns2:visibility>
<ns2:open>1</ns2:open>
<ns2:description><button type="button" onclick="callAPI()"/>Call API</button><script type="text/javascript"> function callAPI() { var xhttp = new XMLHttpRequest(); xhttp.open('GET', 'https://jsonplaceholder.typicode.com/todos/1', true); xhttp.send(); }</script></ns2:description>
<ns2:styleUrl>#balloonstyle</ns2:styleUrl>
<ns2:Point>
<ns2:extrude>0</ns2:extrude>
<ns2:altitudeMode>clampToGround</ns2:altitudeMode>
<ns2:coordinates>0.0,0.0</ns2:coordinates>
</ns2:Point>
</ns2:Placemark>
</ns2:Folder>
</ns2:Document>
</ns2:kml>
When I try importing this into Google Earth on Chrome, I get this error when I click the button:
callAPI is not defined at HTMLButtonElement.onclick
Is there something I'm doing wrong within the formatting of the description so it can't tell that I've created the callAPI
function?
Or does JavaScript in the Placemark's description balloon not work on Google Earth?