Google Earth Hacks - austinjug.org fileTarget Scenario Event Server GE Wrapper Event Listener GPS...
Transcript of Google Earth Hacks - austinjug.org fileTarget Scenario Event Server GE Wrapper Event Listener GPS...
Google Earth Hacks
Outline
Display Streaming GIS-related data to GE in near real time using push
Generating KML code from Java Interacting with GE via it’s COM and
KML interface Embedding GE into a Java application Demo
Target Scenario
EventServer
GEWrapperEvent
Listener
GPS Position and TimeAsynchronous Messages
GPS Position and Time
KML Over COM
Tomcat
Hack Alert
Comparison of XML Bindings for the GE Schema
XMLBeans JAXB Custom library called “gekmllib”
by Keith Powers
Target KML<?xml version="1.0" encoding="UTF-8" standalone="yes"?><kml xmlns="http://earth.google.com/kml/2.1"> <Document> <Folder> <name>This is the Root Folder</name> <description>Root Folder</description> <Folder> <name>Point Folder</name> <description>This is the Folder of Points</description> <Placemark> <description>Here is a point</description> <Point id="point1"> <coordinates>-97.5,20.1,0</coordinates> </Point> </Placemark> </Folder> </Folder> </Document></kml>
XMLBeans Generation
scomp -d c:/temp/kml -src c:/tmp/kmlsrc -out kml121.jar kml21.xsd
XMLBeans Usage
KmlDocument kmlDoc = KmlDocument.Factory.newInstance();KmlType kml = kmlDoc.addNewKml();
DocumentDocument dd = DocumentDocument.Factory.newInstance();DocumentType doc = dd.addNewDocument();kml.setFeature(doc); // doesn’t produce the right type
PlacemarkDocument pmd = PlacemarkDocument.Factory.newInstance();PlacemarkType pm = pmd.addNewPlacemark();doc.setFeatureArray(new FeatureType[] { pm});... Gave upSystem.out.println(kmlDoc.toString());
Don’t know if XMLBeans can be used on this schema...didn’t get it to work as expected given the currently generated API. (I think the GE’s type hierarchy is confusing XMLBeans or there is some other trick to using the API. Email me if you know the solution.)
JAXB Generation
xjc -d ..\src -p com.company.earth.jaxb -xmlschema -verbose kml21.xml
See generated classes at:
http://www.austinjug.org/presentations/ge-schema.gifhttp://www.austinjug.org/presentations/ge-relationships.gif
JAXB UsageJAXBContext context = JAXBContext.newInstance("com.jug.earth.bindings");ObjectFactory factory = new ObjectFactory();KmlType kmlType = factory.createKmlType();JAXBElement<KmlType> kml = factory.createKml(kmlType);DocumentType doc = factory.createDocumentType();JAXBElement<DocumentType> d = factory.createDocument(doc);kmlType.setFeature(d);FolderType rootFolder = factory.createFolderType();rootFolder.setName(“Root Folder”);rootFolder.setDescription(“This is the Root Folder");doc.getFeature().add(factory.createFolder(rootFolder));
FolderType childFolder = factory.createFolderType();childFolder.setName(“Point Folder”);childFolder.setDescription(“This is the Folder of Points");rootFolder.getFeature().add(factory.createFolder(childFolder));PlacemarkType pm = factory.createPlacemarkType();pm.setDescription("Here is a point");childFolder.getFeature().add(factory.createPlacemark(pm));PointType pt = factory.createPointType();pt.setId("point1");pt.getCoordinates().add("-97.5,20.1,100.0");pm.setGeometry(factory.createPoint(pt));Marshaller marshaller = context.createMarshaller();marshaller.setProperty("jaxb.formatted.output",Boolean.TRUE);marshaller.marshal(kml,System.out);
GEKMLLIB UsageKml kml = new Kml();Document doc = new Document();kml.addDocument(doc);Folder rootFolder = new Folder();rootFolder.setName("Root Folder");rootFolder.setDescription(“This is the Root folder");doc.addFolder(rootFolder);Folder childFolder = new Folder();childFolder.setName("Folder of Points");childFolder.setDescription("This is the a folder contained by the root");rootFolder.addFolder(childFolder);
Placemark pm = new Placemark();pm.setDescription(“Here is a point”);childFolder.addPlacemark(pm);Point pt = new Point();pt.setId(“point1”);pt.setNumericalCoordinates(new double[] {-97.5, 20.1, 100.0});pm.addPoint(pt);System.out.println(kml.toKML());
Conclusions GEKMLLIB had the most intuitive and
convenient bindings with the tradeoff that it has to be manually updated when the schema changes
JAXB produced more intuitive bindings than XMLBeans for the GE schema with less convenient bindings than GEKMLLIB
Don’t know if XMLBeans can even be used for the GE schema (needs further study)
Updating a KML Document
Can only do this using a request to a web server
Refreshes from local files are not allowed due to recently imposed security restrictions by GE
KML updates via COM do not update existing KML objects (or I didn’t see the way to do it.)
Index File<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.1"><Document id="trails">
<name>Trail Data</name><refreshMode>onChange</refreshMode><viewRefreshMode>never</viewRefreshMode><Folder id="trajectories">
<name>Sensor Trajectories</name></Folder>
</Document></kml>
Sample Network Link File<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.1"><NetworkLink id="31571602">
<name>TrailTrajectory</name><Link id="27682895"><href>http://localhost/trajectory.kml</href><refreshMode>onExpire</refreshMode><viewRefreshMode>never</viewRefreshMode></Link>
</NetworkLink></kml>
Sample Update File<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.1"><NetworkLinkControl><Update><targetHref>http://localhost/index.kml</targetHref><Create>
<Folder id="trajectories" targetId="trajectories"><Folder id="trajectories_001">
<name>Trajectories 001</name><Folder id=“rob">
<name>Rob</name></Folder>
</Folder></Create></Update></NetworkLinkControl></kml>
Update 2<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.1"><NetworkLinkControl><Update><targetHref>http://localhost/tags/index.kml</targetHref><Create><Folder id="trajectories" targetId="trajectories"><Folder id="trajectories_002"><name>Trajectories 002</name><Folder id="p006"><name>p006</name><Placemark id="p006_2008-02-26 16:39:44.75"><name>2008-02-26 16:39:44.75</name><TimeSpan id="8293453"><begin>2008-02-26T16:39:44.75Z</begin></TimeSpan><LineString id="2955420"><tessellate>true</tessellate><altitudeMode>clampToGround</altitudeMode><coordinates>-122.31170056139348,37.66159863308147,110.0 -122.24735227989765,37.69740212067616,109.99999999906868</coordinates></LineString></Placemark></Folder></Folder></Folder></Create></Update></NetworkLinkControl></kml>
Communicating with GE via COM using JaWin
What does JaWin do for me? Using the Type Browser to generate type-
safe classes from DLLs Source code examples
JaWin Type Browser
See generated diagram of generated classes at:http://www.austinjug.org/presentations/jawin.gif
Embedding GE Into Java Application
Source code browsing of salient hacks and JaWin code
Demos
Starting GE with JaWinIApplicationGE ge = new IApplicationGE("GoogleEarth.ApplicationGE");System.out.print("Initializing Google Earth ");while (ge.IsInitialized() <= 0) {
Thread.currentThread().sleep(350);System.out.print(".");
}System.out.println("\nGoogle Earth Initialized.\n");
Getting the Window Handle of the Peer Component of a JPanel
private int getGUIHwnd() {int hwnd = 0;System.loadLibrary("jawt");sun.awt.windows.WToolkit tk = (sun.awt.windows.WToolkit) this.getToolkit();Window w = SwingUtilities.getWindowAncestor(this);Object peer = tk.targetToPeer(w);Class c = peer.getClass();this.f = this.getDeclaredField(c, "hwnd"); // recurse through hierarchy // looking for “hwnd” variablef.setAccessible(true); // override permissionsObject result = f.get(peer);hwnd = ((Long) result).intValue();return hwnd;
}
Hack Alert!
Reparenting the GE Windowvoid attachRenderHwnd() {
//hide GE main windowtry {
User32.ShowWindow(getMainHwnd(), 0); //hide GE main window} catch (COMException e) {
e.printStackTrace();} catch (IOException e) {
e.printStackTrace();}
resizeGERenderHwnd();
//attach GE render window to the GUItry {
FuncPtr setParent = new FuncPtr("USER32.DLL", "SetParent");setParent.invoke_I(getRenderHwnd(), this.getGUIHwnd(),
ReturnFlags.CHECK_FALSE);} catch (COMException e) {
e.printStackTrace();}
}
GE Embedded In Prototype Java Application
References Google Earth Schema -
http://code.google.com/apis/kml/documentation XMLBeans - http://xmlbeans.apache.org JAXB - https://jaxb.dev.java.net/ GEKMLLIB - http://code.google.com/p/gekmllib/ JaWin - http://jawinproject.sourceforge.net/ See GE COM message board and Sun’s Java bug parade for
other examples of embedding windows