UPDATE (September 6, 2009):
Updated to work with the latest Papervision3D library and added interactivity to the markers.
Updated to work with the latest Papervision3D library and added interactivity to the markers.
The latest issue of Adobe Edge, with my article on using Flex and Papervision3D to geocode, just went live.
Thanks for a great article on Geocoding/PPV3d. I’m so inspired by your article and I will definitely build something fun based on your sample app. I didn’t know mapping coordinates on a PPV3D Sphere was that easy. 🙂
Mercator is the wrong projection. A Mercator projection in its 2D form already has tremendous distortion built into it and wrapping it on a globe doesn’t change that. It’s often the case that Mercator projections are cut off above 81° N&S latitude because the distortion is so great (USGS states that the poles cannot be shown it’s so extreme). You should use a Lat/Long (aka Platte CarrĂ©e or Equidistant cylindrical) projection. In these projections, the width of the 2D map is 2x the height, just like an “unfolded” sphere. There is distortion as well on this type of projection (most extreme at the poles) but when the map is wrapped onto a sphere the distortion is eliminated by the compression of the pixels.
Yes, I am a cartographer. Visit my small custom mapping site at http://www.the-m-factory.com
Hey Justin,
That’s very interesting.
I definitely don’t claim to be a cartographer, but the biggest point of the article was accurately plotting latitude and longitude points on a globe.
From my investigation, most of the major online mapping services use the Mercator projection for their 2D maps.
The easiest way to plot the latitude and longitude points on a globe was to take the Mercator projection and map it over the sphere as well.
While it might be a bit distorted, it does allow for very accurate lat/long plotting. From my digging, Microsoft takes its Mercator 2D map tiles from Virtual Earth and places them over their Local.Live 3D globe as well.
Another thing to keep in mind about using the Mercator projection is that in theory you could view the map in 2D and then have that same map wrap around a 3D globe, retaining all latitude and longitude coordinates.
Mark: really, really great job. Thank you so much for putting this out there.
The last post regarding the proper projection is way to critical for what you are actually providing.
Justin: Why make yourself look like an ass? thank the guy… it’s been about 6 months since someone figured out how to geocode a sphere in PV3D and they didn’t release the code. The how to do it questions are still on the PV3D list.. with no answer until now.
if your going to talk about projection distortion resulting from projecting the globe/sphere on to a 2d surface; do not then say the projection is not removed when re-projected back on to a sphere!
Is it perfect, no, but close enough if you look at the scale and the precision in the code. Yes, there is need for some generalization… as a cartographer you should understand this.
Vu: nothing easy about coming up with the code. it’s good it appears easy… but that’s the magic.
I was really frustrated trying to figure out where the origin would be in PV3D and then what scale I should be working at. I made about 10 different scaled globes then settled on one that was 65.78 meters radius. Easy to wrap a texture around it, and I was all proud of myself… where is the origin in PV3D.
Again, thanks Mark for helping us dim ones out.
regards,
Harley
Thanks for the kind words Harley and Vu! 🙂
Great work I’m playing around a bit and try to get some Xtra interaction. You know if it’s possible to make de markers interactive? Keep up the good work!
Thanks for a really great article. I’ve been wanting to do this for a long time. I’ve been trying to implement it in CS3 as I don’t have Flex but i’m getting the below error message:
TypeError: Error #1007: Instantiation attempted on a non-constructor.
at com.digitalflipbook.geoglobe::Globe()
at com.digitalflipbook.geoglobe::GlobeView/init()
at com.digitalflipbook.geoglobe::GlobeView()
at Main()
Is there any reason why you need flex to use your custom classes?
Many thanks
Andy
Fantastic article. Thank-you very much. I was able to get it working, but one of the more recent updates to Papervision3D removed the FreeCamera3D object, so your example code no longer works. Do you plan on updating the code?
I’ve been able to replace the FreeCamera3D with Camera3D after some hacking around, but I’m having trouble getting the Globe back to the same size as in your example (probably something to do with camera focus and zoom or FOV).
Perhaps an update to your Globe code in your blog would help those of us who want to get your example working, but don’t follow all the nuances of Papervision updates?
Thanks for an excellent article, Mark. After about two days of adjusting code, I was able to get the files to compile decently in Flash without Flex. (I nixed the geocoding functions in favor of an array of fixed locations) One thing I keep banging my head on is making the marker cubes interactive. No matter what I try with the markers, the InteractiveScene3DEvent just won’t fire. And setting the GlobeView interactive to true just slows the animation to a halt. Any ideas?
Andy, I think that particular error is caused by the way the bitmap material is embedded with Flex. The main thing in Globe.as that I removed to make the code work in CS3 was the lines:
[Embed( source=”assets/earthmap1k.jpg” )]
protected var EarthImage:Class;
And I changed the “var earthMaterial” line to:
var earthMaterial:BitmapAssetMaterial = new BitmapAssetMaterial(“WorldMap”);
Where “WorldMap” is the linkage identifier for a bitmap in my library.
There’s quite a bit more to adapt for CS3, but that’s one of the main things.
Hi Mark,
Its really a great example on flex and PV3D. Can you please update the code for positioning of the globe. As Bill Brown has written the new Camera3D is not working properly with your configs. Finding it really hard to position. I know you must be very hard pressed. See if you can give some time and repost the code.
Thanks a lot Mark…keep up the good work.
Cheers,
Bhuvnesh
I couldn’t find the papervision swc, so I added the papervision source instead. Same with tweener.
It worked fine after I adjusted the camera in the GlobeView.as file.
//Reposition the camera away from the globe and null object.
//camera.moveBackward( 360 );
camera.moveBackward( 1200 );
One problem though. When I run the project it’s fine in firefox but IE asks me do I want to install an activeX. After I choose yes it works fine.
I am new to flash and wondered if I am doing something wrong. I have created other flex and AS3 projects and never get this warning. Any ideas?
Thanks mate,
Garold
As Andy, I’m trying to implement this in Flash CS3, but I’m getting a different error with the Tweener library
Error:
1046: Type was not found or was not a compile-time constant: TweenListObj.
Source:
private static function handleError(pTweening : TweenListObj, pError : Error, pCallBackName : String) : void{
If anyone out there have succesfully port this to Flash CS3, it will be great to take a look.
Thanks Mark for your work! It’s the first example I’ve found incl. sc that is explained very well.
I had the same issue as Garold though.. had to move the camera a lot more backwards. Also the 2D map doesn’t seem to wrap perfectly around the globe.. I see more of the southern part than the north. Moving the camera up doesnt solve it. Is it a version issue of the two libraries or is the sourcecode not exactly the same as the compiled example?
@Carlos: I imported it in FB3, but yours is a reference error – how did you include the Tweener lib?
Thanks, Daniel
Hey again,
So it works well now! For some reason the rotation was working inverse, meaning it rotated the other way as my mouse moved. Also, when I performed a rotationX and clicked again, it performed a rotation in the opposite direction. Don’t know why, but this fixed it for me:
[in mouseDownHandler:]
globeMouseDiffX = -mouseX + cameraTarget.rotationY;
globeMouseDiffY = mouseY – cameraTarget.rotationX;
[in onRenderTick:]
var rotationY:Number = -( -mouseX – globeMouseDiffX );
var rotationX:Number = ( mouseY – globeMouseDiffY );
Cheers,
Daniel
So I downloader the Tweeer swc and the Papaervision sxc from Google code and just put them in the libs folder of the project and then removed the references to the external projects, the project built.
I implemented Garold’s fix:
//Reposition the camera away from the globe and null object.
//camera.moveBackward( 360 );
camera.moveBackward( 1200 );
and that made the perspective right. By the way Garold, you’ve probably found this out by now, but if you run the file locally in IE – through the filesystem rather than via http (as in localhost or from a server) you will get those errors.
Last, I tried Daniel’s fix, but I have a problem that I am working on trying to sort out. When I click the globe, it immediately flips over, then I can interact with it normally. Also, the markers’ latitude seems wrong. I’ve only been messing with it for an hour, so I’ll post any fixes I can find, but has anyone else already solved these issues?
John,
I believe this has something to do with how the yaw method works in the new release of pv3d.
To fix this delete or comment out this code:
//Rotate the camera target to have the camera face America.
cameraTarget.yaw( 180 );
replace it with this:
//Rotate the camera target to have the camera face America.
Tweener.addTween( cameraTarget, { rotationX:30, rotationY:180, time:0 } );
You can change the parameters to make the globe start at anyplace you want.
Mark,
This is a really nice application–thank you for sharing it. I am glad I found it before I started building something like it from scratch.
I haven’t been able to fix the coordinate system, but if I do I will be sure to post the fix here.
I know its not a good / proper fix for the coordinate problem but…in GlobeView.as in the fuction translateGeoCoords
right below this line:
longitude -= ( longitudeDegreeOffset * ( Math.PI/180 ) ); // offset longitude by n degrees (in radians).
add in this:
longitude += .265;
This gets the markers where they should be, or at least close enough for me.
Nick,
I actually got it working acceptably and just hadn’t had time to update this page. (truth be told I got caught up in playing with changing markers etc.)
Here are the changes I had to make to get the code working; first I just added the current swc’s for tweener and papervision3d to my project.
(tweener 1_31_74; Papervision3D_2.0.869)
next in GlobeView.as I did the following (thanks to anyone who posted code above; I made some slight corrections, but these were all the changes that were necessary to amke this work the same or very very close):
**changed a protected class variable
// protected var longitudeDegreeOffset:Number = 15;
protected var longitudeDegreeOffset:Number = 0;
**changed function onRenderTick
//Set the target rotation properties for the camera based on the mouse position.
// var rotationY:Number = -( -mouseX – globeMouseDiffX );
//var rotationX:Number = -( mouseY – globeMouseDiffY );
var rotationY:Number = ( -mouseX – globeMouseDiffX );
var rotationX:Number = ( mouseY – globeMouseDiffY );
//Set a maximum amount that the camera can rotate around the x-axis.
// rotationX = rotationX > 10 ? 10 : rotationX 225 ? 225 : rotationX < 140 ? 140 : rotationX;
//Reposition the camera away from the globe and null object.
// camera.moveBackward( 360 );
camera.moveBackward( 1200 );
**changed function mousedownhandler
//Track the amount the mouse has moved.
// globeMouseDiffX = -mouseX + cameraTarget.rotationY;
//globeMouseDiffY = mouseY + cameraTarget.rotationX;
globeMouseDiffX = -(mouseX + cameraTarget.rotationY);
globeMouseDiffY = mouseY – cameraTarget.rotationX;
Oh and also thank you to Mark; this really is a nice, straightforward example of doing this and the fact that you shared it is just great. Would you like me to send you my updated GlobeView.as as it seems at this time to work fine with the newest Tweener and Papervision libraries?
Alternately I could post it, but I’m not looking to take any traffic from here.
Hey Mark,
thanks for this great tutorial. Have you any idea, how I can rotate the camera to a marker? That would be nice to know.
Hey guys,
Thanks for all the feedback!
I’m about to post an update using the latest PV3D library that includes support for marker interaction.
But until then, I went back and found out the revision number of PV3D that I used with this article.
It’s revision 586 on the branches directory ( http://papervision3d.googlecode.com/svn/trunk/branches ).
Great article mark , saved me a lot of time.
Thanks, Shigil