Wednesday, December 05, 2007

Java and the Google Earth COM API

Using com4J, I managed to utilize the Google Earth COM API from a Java application. Here's how: 1) Using com4J, generate java source from googleearth.exe:
java -jar tlbimp.jar -o ge_code -p com.brant.ge "c:\program files\google\google earth\googleearth.exe"
This command will cause com4j to generate java source in the ge_code directory inside the com.brant.ge package. 2)Now use the generated code in your own code:
import com.brant.ge.ClassFactory;
import com.brant.ge.IApplicationGE;

public class GETest {

    public static void main(String[] args) {

        //Launch Google earth unless it's already open
        IApplicationGE ge = ClassFactory.createApplicationGE();
        
        //Load kml from the network
        ge.openKmlFile("http://localhost:8080/ff.kml", 1);

        //Load kml from the local filesystem
        ge.openKmlFile("c:\\dir\\ff.kml", 1);
    }
}

The Google Earth COM API allows you to load kml data from a file or network location as shown above or as a string with the loadKmlData method. You can also get handles to Features and set the visibility. So far I have not found a way to programmatically refresh network links which is what I was really after, so I'm open to suggestions there. The COM API seems a bit limited in what you can accomplish, but maybe we'll see more in future releases. From the experience I've garnered that com4j is a very easy to use tool, and made interacting with Google Earth a breeze.

25 comments:

Kurt M said...

has anyone been able to successfully implement the IApplicationGE interface? For example i have not been able to do getTemporaryPlaces() or getMyPlaces() etc.

some sample code would be great!

thanks any info would help

Brant Boehmann said...

kurt m, I just tried to get My Places and was successful with the following code:

IApplicationGE ge = ClassFactory.createApplicationGE();


IFeatureGE myPlaces = ge.getMyPlaces();

IFeatureCollectionGE myPlacesColl = myPlaces.getChildren();

int count = myPlacesColl.count();

System.out.printf("My Places has %s items\n", count);

for(int i = 1; i <= count; i++) {
IFeatureGE item = myPlacesColl.item(1);
System.out.println("Feature Name: " + item.name());
}

}
}

Kurt M said...

ok thanks! ... but i am pulling an exception. here is the code

System.out.printf("1 BEGIN GOOGLE CLIENT TEST : My Places \n");
IApplicationGE ge = ClassFactory.createApplicationGE();

ge.openKmlFile("c://googlefiles/sanJoseGoogle.kml", 1);


IFeatureGE myPlaces = ge.getMyPlaces();
System.out.printf("2 GOOGLE CLIENT TEST : My Places \n");
IFeatureCollectionGE myPlacesColl = myPlaces.getChildren();
System.out.printf("3 GOOGLE CLIENT TEST : My Places \n");
int count = myPlacesColl.count();
System.out.printf("My Places has %s items\n", count);
for(int i = 1; i <= count; i++) {
IFeatureGE item = myPlacesColl.item(1);
System.out.println("Feature Name: " + item.name());
}


myPlaces.getChildren() - throws the exception

the google client MYPlaces does have 'places' listed

whats up with that?

Kurt M said...

Brant

i just got the MyPlaces code to work!
my google client was googleEarthPro
when i reinstalled GoogleEarthEC-4.2.205.5730.exe

your code worked.Thanks so much.

is there source code for capturing coordinates from the mouse location or mouse event?

i would really like to iterate the points of a polygon feature.

thanks
Kurt

Brant Boehmann said...

I'm glad you got it working.

>is there source code for capturing >coordinates from the mouse location or >mouse event?

I'd be surprised if the public com api allows this. I've heard rumor of people finding other useful, non-documented, non-public google earth dlls on their machine. I've never tried as it would likely break with each release of Google Earth.

>i would really like to iterate the >points of a polygon feature.
I thought this woul dbe available, but a quick browse through the com api doesn't show any classes or structs for Placmarks or polygons. I thought for sure there be something else extending IFeatureGE, but maybe I'm missing it.

I'd be curious to hear what you're able to accomplish.

kurt said...

what about using event cookies. event registrations would be
a mechanism to receive event objects that contain information

one would have to test for the event object type, once determined can yield mouse (x,y) location, or
placement of a polygon event ?

Event sample from https://com4j.dev.java.net/annotations.html:

Com4jObject comObject = ...; // more likely it's an interface derived from Com4jObject
EventCookie cookie = comObject.advise(_IiTunesEvents.class, new MyEventReceiver());

...

cookie.close(); // terminates subscription


thanks again

Anonymous said...

Brant, your demo code got me started, thanks a lot! www.hakenberg.de

tolgatanriverdi said...

how did you imported the source codes?
i have used the command line tool to create source files from googleearth.exe and that worked fine however when i try to load it from netbeans it always says there is no package as com.nps.ge(nps is the name that i gave) I even made it jar file and put under jre\lib\ext it still didnt work how should i import it?
Thanks

Brant Boehmann said...

tolgatanriverdi,
I simply copied the generated source files from com4j into my netbeans project source tree. I also included com4j.jar as a project dependency. Look here for details on running/distributing com4j dependant projects: https://com4j.dev.java.net/deployment.html

James :) said...

Has anybody tried to get a "save map image" back to java using com4j? I have tried, but to no avail so far. Would be great if someone could help.

manetta199 said...

hi brant
i have a problem: when i generate java source, the JVM catch a exception com4j.ComException : 80029c4 LoadTypeLib failed
thanks

suresh said...
This comment has been removed by a blog administrator.
Brant Boehmann said...

Hi Suresh,
I don't think you can retrieve the imagery using the documented Google Earth COM API. There may be some undocumented feature that I am unaware of. However, Google Earth retrieves imagery from a TCP connection (HTTP I assume). You could probably figure out the urls of the imagery without too much work using wireshark or some other packet analysis tool. You could also get this tool. Which will download google earth imagery given a spatial range. I feel obligated to say that it is my understanding that utilizing or downloading the google earth imagery this way is likely a violation of the google terms of use. You may want to consider the google earth forums or contacting google earth and asking permission for research project purposes.

Neeraj Blog said...

Hi Brant,

This is Neeraj, and I am working in java technology and also a fresher.

I am trying to find out the following classes :

com.brant.ge.ClassFactory;
com.brant.ge.IApplicationGE;


can you send me these classes.
Please help me. and my mail id is
neeraj.verma@qesoft.net

Thanks
Neeraj

Brant Boehmann said...

Neeraj,
Those classes are generated using COM4J. Go download COM4J and execute the following command java -jar tlbimp.jar -o ge_code -p com.brant.ge "c:\program files\google\google earth\googleearth.exe"

tlbimp.jar comes with COM4J. The -o option specifies where on the filesytem to generate the code and the -p option specifies the package of the classes to be generated.

Austin said...

Hey, this is pretty cool. Thanks for the tip.

Anonymous said...

Hi,

When I tried this procedure, I got an error as such:
Failed to bind IApplicationGE

What do you think is causing this error?

Thanks a lot.

Martin said...

It's been a while since your post but I'm a bit stuck. Is there no other way to integrate GE into my Java application? I'd like to embed it into a JPanel, JFrame or such.

TIA
Martin

Brant Boehmann said...

Martin,
I'm not aware of anyway to do that with Google Earth. The NASA Workdwind Java components may be a better fit for what you want to do. http://worldwind.arc.nasa.gov/java/

Martin said...

Ok, thanks Brant. I'll look into NASA WW.

Ugo said...

When i perform the command : java -jar tlbimp.jar -o ge_code -p com.brant.ge "c:\program files\google\google earth\googleearth.exe" , i have this exception:
Exception in thread "main" java.lang.UnsupportedClassVersionError: com4j/tlbimp/driver/Main (Unsupported major.minor version 49.0)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:539)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:251)
at java.net.URLClassLoader.access$100(URLClassLoader.java:55)
at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)

what is the problem?
Thanks

nexir said...

Hi,
Actually I want to use google earth in my java application without installing it on my desktop because it is to be used on a server and it does not depend on an browser so I don't think I can use a plugin, then I saw your blog of java and google earth api. So I thought if you could help us in anyways or could you tell us how to use COM4J so that we could use it,any help would be great. Thanx
Regards,
nexir.

Anonymous said...

hello i have try to execute your source code but the import is not recognized by my environment.
Courld you explain me quickly how resolved this problem.

thanks a lot

Sankar lp said...

Thanks for the post, I am techno savvy. I believe you hit the nail right on the head. I am highly impressed with your blog. It is very nicely explained. Your article adds best knowledge to our Java Online Training from India. or learn thru Java Online Training from India Students.

Kanye Co Jamila said...

Great Article
IEEE Final Year Projects for CSE
IEEE Project Centers in Chennai