当前页面: 开发资料首页 → J2EE 专题 → 基于Servlet的Google Earth之旅
摘要: Google Earth是一个奇妙的客户端,它在众多市场领域引人瞩目并对如何可视化位置信息以及与地理相关的搜索结果产生影响。本文介绍了如何使用XML与一个基本的servlet来创建Google Earth旅程。在本文给出的示例基础上做进一步挖掘就可以开发出许多真正富有成效的服务
Hello World [127.0.0.1]
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("application/keyhole");
PrintWriter out = response.getWriter();
String message =""; Hello World ["
+ request.getRemoteAddr()+ "]
out.println(message);
}
<?xml version="1.0" encoding="UTF-8"?>
Refresh me
Random City
1
1
1
1
http://location
<%response.setContentType("application/keyhole");%>
London
London, UK
root://styleMaps#default+nicon=0x304+hicon=0x314
-0.1261969953775406,51.50019836425783,50
manager.KMLRenderOfRandomPlacement();
package test.google.earth.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.servlet.ServletConfig;
import test.google.earth.manager.Manager;
public class QuizServlet extends HttpServlet
{
private Manager manager;
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.manager= new Manager();
manager.init();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("application/keyhole");
PrintWriter out = response.getWriter();
out.println(manager.KMLRenderOfRandomPlacement());
}
}
package test.google.earth.manager;
import java.util.Random;
import test.google.earth.bean.PlacementBean;
import test.google.earth.bean.PointBean;
public class Manager {
private PlacementBean[] cityArray;
private String styleURL;
private String open;
private Random generator;
private int idx;
public Manager(){}
public void init(){
this.styleURL="root://styleMaps#default+nicon=0x304+hicon=0x314";
this.open="1";
this.generator = new Random();
String[] coords = {"-0.1261969953775406,51.50019836425783,50",
"12.5,41.889999,50","4.889999,52.369998,0"};
String[] name = {"London","Italy","Amsterdam"};
String[] address={"London, UK","Rome, Italy","Amsterdam, Netherlands"};
String[] description={
"London",
"Rome",
"University of Amsterdam"};
this.idx=coords.length;
cityArray= new PlacementBean[coords.length];
//Init the array of placements
for (int i =0; iplacementBean placementBean = new PlacementBean();
placementBean.setAddress(address[i]);
placementBean.setDescription(description[i]);
placementBean.setName(name[i]);
placementBean.setOpen(open);
placementBean.setStyleURL(styleURL);
pointBean pointBean = new PointBean();
pointBean.setCoordinate(coords[i]);
placementBean.setCoordinates(pointBean);
this.cityArray[i]=placementBean;
}
}
public synchronized PlacementBean nextRandomPlacement(){
return cityArray[ generator.nextInt( this.idx )];
}
public synchronized String KMLRenderOfRandomPlacement(){
return renderKMLPlacement(nextRandomPlacement());
}
private String renderKMLPlacement(PlacementBean pBean){
String klmString="\n"+ \n";
"\t"+pBean.getName()+" \n"+
"\t"+
"\t"+pBean.getAddress()+"\n"+
"\t"+pBean.getStyleURL()+" \n"+
"\t\n"+ \n"+
"\t\t"+pBean.getCoordinates().getCoordinate()+" \n"+
"\t
"
return klmString;
}
}
<?xml version="1.0" encoding="UTF-8"?>
Examples of bi directional flow of information
Network Links
1
1
Lets send coordinates once in a while
Message Pushing
1
1
1
0
http://localhost:8081/Tour/message
2
onStop
1
Location: -0.134539,51.497,-0.117855,51.5034
IP address: 127.0.0.1
Updated: Fri Oct 21 11:42:45 CEST 2005
<?xml version="1.0" encoding="UTF-8"?>
Alan Berg]]> \
Fri Oct 21 11:42:45 CEST 2005]]>
4.889999,52.369998,0
package test.google.earth.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import test.google.earth.bean.LastLocationBean;
import test.google.earth.bean.LastMessageBean;
import java.util.Date;
public class MessageServlet extends HttpServlet
{
private static LastMessageBean lastMessage=new LastMessageBean();
private static LastLocationBean lastLocation= new LastLocationBean();
public void init(ServletConfig config) throws ServletException {
super.init(config);
lastMessage.setMessage("No message Yet");
lastMessage.setName("System");
lastMessage.setUpdated(new Date());
lastLocation.setCoords("No contact with a client yet");
lastLocation.setIpAddress("");
lastLocation.setUpdated(new Date());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String coords = request.getParameter("BBOX");
if (coords==null){
return;
}
String message;
String name;
Date lastDate;
String ipAddress = request.getRemoteAddr();
synchronized(this) {
lastLocation.setCoords(coords);
lastLocation.setIpAddress(ipAddress);
lastLocation.setUpdated(new Date());
message=lastMessage.getMessage();
name=lastMessage.getName();
lastDate=lastMessage.getUpdated();
}
response.setContentType("application/keyhole");
PrintWriter out = response.getWriter();
String[] coParts= coords.split(",");
float userlon;
float userlat;
try{
userlon = ((Float.parseFloat(coParts[2]) - Float.parseFloat(coParts[0]))/2)+
Float.parseFloat(coParts[0]);
userlat = ((Float.parseFloat(coParts[3]) - Float.parseFloat(coParts[1]))/2) +
Float.parseFloat(coParts[1]);
}catch(NumberFormatException e){
return;
}
String klmString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "\n" \n";
+ "\n" \n"
+ ""+name+"]]> \n"
+""+lastDate+"]]> \n"
+ "\n" \n"
+ ""+userlon+","+userlat+",0 \n"
+ "
+ "
+ "
out.println(klmString);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String name = request.getParameter("name");
if (name==null){
return;
}
String message;
PrintWriter out;
synchronized(this) {
lastMessage.setMessage(request.getParameter("message"));
lastMessage.setName(name);
lastMessage.setUpdated(new Date());
message="\nLocation: "+lastLocation.getCoords()+
"\nIP address: "+lastLocation.getIpAddress()+
"\nUpdated: "+lastLocation.getUpdated();
}
response.setContentType("text/html");
out = response.getWriter();
out.println(message);
}
}
来自浏览器的消息保存在静态成员LastMessageBean中,坐标保存在LastLocationBean中,且每个bean都只有一个实例。此外,在执行getting或setting操作时对所有的静态bean都进行同步。我们用单个实例来达到简化的目的,有助于限制要编写的代码数量。然而,更有实用价值的示例应具备跟踪IP地址的会话管理功能并生成相应的处理结果。
有一个不起眼的错误,在placement实体的名字标签里使用HTML标签会导致显示问题:整个标签在Google Earth客户端的“places”菜单区按HTML显示,但在View窗口里却按文本显示。我认为这种不一致是个bug。
在本示例中Google Earth客户端推送坐标,servlet返回KML代码段。既然知道能用坐标推送上下文关联信息,我们可以强制通过段中的链接来进行交互,必要的话还可以让浏览器成为宿主。本文展示了如何控制Google Earth客户端,至此你已拥有了一个创建自己互动旅程的概念性工具箱。
结束语
我在本文中只探讨了初步的互动技术以及KML概貌,你可以在KML中添加更多的功能:通过extrude标签显示3D物体,用snippet添加相关信息,以叠加的方式显示名画,让用户感到仿佛在跟随拿破仑从莫斯科撤退。只需要一点儿想像力和扎实的Java编程技能,你就可以用Google Earth客户端创建互动Web应用。我期待着看到你的努力结出硕果。
关于作者
Alan Berg在阿姆斯特丹大学的中心计算机所作为主要开发人员已有七年。他在闲暇时间撰写计算机方面的文章。他拥有学士学位、两个硕士学位和教师资格。此前他的身份是技术作家、Internet/Linux课程作者和理科教师。他热衷于创建和整合系统。他在与子女们玩计算机游戏时依然身手敏捷,不幸的是他总是落败。
资源
下载本文的源代码:http://www.javaworld.com/javaworld/jw-11-2005/google/jw-1114-google.zip
柱面投影:http://mathworld.wolfram.com/CylindricalProjection.html
Google Earth API: http://code.google.com/apis.html#earth
Google Earth社区:http://bbs.keyhole.com/ubb/ubbthreads.php/Cat/0
Google Earth下载:http://earth.google.com/download-earth.html
Google Earth主页:http://earth.google.com/
Hibernate框架:http://www.hibernate.org/
iBATIS framework框架:http://ibatis.apache.org/index.html
Jamon框架:http://www.jamon.org/Features.html
Microsoft Virtual Earth项目:http://virtualearth.msn.com/
Nasa World Wind项目:http://worldwind.arc.nasa.gov/
Google Earth KML教程,你可以从中找到对中算法:http://www.keyhole.com/kml/kml_tut.html#tracking_point
↑返回目录
前一篇: 使用Annotations设计一个MVC框架
后一篇: 解析 Hibernate Validator