开源WebGIS中用Java程序语言进行快速开发是最经常使用的方法。比较普遍的是用OpenLayers技术+GeoTools技术+Geoserver服务器+MySQL数据库(当然也可以是DB2等等。由于要收费,所以我会使用PostSQL/GIS数据库)。
当然,我总是希望找到更为简单的解决问题的途径,最好不牵扯那么多乱七八糟的技术,因此,于比小型Web
GIS项目来说,有个方法可以让我们摆脱GeoTools技术为我们提供的那1000多个API所带来的痛苦。
对于初级Java程序员来说,可以直接用Openlayers+JAXP等几个基本类包来完成工作。然后,把程序运行在Geoserver服务上。你可以用Hibanite来实现数据持久化(因此,它有时会阻碍我的生产率,因此,在大型的项目里面我才用。如果你用在小型项目里面时发现了它的缺点,可以通过其他技术来避免这部分的损失。你必须v头脑灵光,不要为框架而框架,应该是通过合适的技术来提高自己的工作生产率),以便与MySQL数据库通信(MySQL数据库虽然已支持Geometry数据,但是也比较糟糕)。
每个技术的任务是什么:
1、OpenLayers只监听电子地图上的用户请求(电子地图操作很多情况加都要采用Ajax异步交互技术),取出业务需要的数据,并将数据变成一个 XML对象(或者是GML/GEoRSS/KML什么的都行)传到Java程序里后任务就结束了(也有不转换成XML的方法,这里不作为重点);
2、Java中我们使用JAXP和STCAME等类包、方法来解析刚才的XML对象,进行业务处理,加工数据,存放数据(如果不用XML数据格式,就可以不用以上两个类包和方方,这里不作重点);
3、当然Geoserver在整个过程中都是枢纽,他分析用户请求和服务器响应。(当然如果你有时间和兴趣也可以扩展开源Geoserver,我是有心而没时间);
以上不是我叙述的重点,因此不在废话!在数据传输中XML是经常用,同时也是很关键的传送格式,因此我从OpenLayers官方网站上找了个例子,结合自己经验和体会具体说明一些OL技术中提供的XML类,以便大家我们能更好的应用GML、GeoRESS、KML等数据格式。
以下是源代码,应该拷贝到本地就可以用,我是在Geoserver中运行地,如果感觉不爽可以登录http://www.openlayers.org/dev/examples/xml.html。
<!--引入OpenLayers错误控制器,如果你也有这个文件就把他加载进来,在界面上按F12就能看见了。如果没有就去掉这个行,Firebug是一个比较简单的报错控件,类似于初级Eclipse Debug控制台--> <br> <br> <script src="http://www.openlayers.org/dev/lib/Firebug/firebug.js" type="text/javascript"></script> <br><br> <!--引入OpenLayers.js,必须地--><br> <script src="http://www.openlayers.org/dev/lib/OpenLayers.js" type="text/javascript"></script> <br><br><br> <script type="text/javascript"><br/> //声明OpenLayers.Format.XML()对象实例,XML()是Format类的其中一个子类,Fromat类中还包括GML、GeoRSS、KML的其他的数据格式。 var format = new OpenLayers.Format.XML(); //空变量 var doc = null; //自动加载的函数 function init() { //被解析的xml文件,一般这个文件是我们用程序写出来的动态文件,除了数据结构不变以外,里面的标记详细值都是动态的,同时又一个标签用来存放几何数据。 var url = "xml/features.xml"; OpenLayers.loadURL(url, null, null, loadSuccess, loadFailure); } //服务器端成功响应了loadURL()中xml/features.xml文件后,所执行的函数 function loadSuccess(request) { //加载完毕后,调用updateStatus(msg)方法,将ID为"loadStatus"的HTML对象中的,第一个标注内的详细值赋为"XML文件加载完毕,请进行试验!"文本字符串 updateStatus("XML文件加载完毕,请进行试验!"); //如果返回的request对象的元素不是XML对象类型,则按Text对象处理返回类型,并赋值给变量doc if(!request.responseXML.documentElement) { doc = format.read(request.responseText); } else { //否则就按XML对象处理返回类型并赋值给变量doc doc = request.responseXML; } } //服务器端响应了loadURL()中xml/features.xml文件失败后,所执行的函数 function loadFailure(request) { //加载失败后,调用updateStatus(msg)方法,将ID为"loadStatus"的HTML对象中的,第一个标注内的详细值赋为"XML文件加载失败,请查看文件是否存在或者是URL地址!"文本字符串 updateStatus("XML文件加载失败,请查看文件是否存在或者是URL地址!"); } function updateStatus(msg) { //将ID为"loadStatus"的HTML对象中的,第一个标注内的详细值赋为msg文本字符串变量 document.getElementById("loadStatus").firstChild.nodeValue = msg; } //今天就写到这里吧,累了... function updateOutput(text) { document.getElementById("output").firstChild.nodeValue =text; } function write() { var text = format.write(doc); updateOutput(text); } function getElementsByTagNameNS(node, uri, name) { var nodes = format.getElementsByTagNameNS(node, uri, name); var pieces = []; for(var i=0; i<nodes.length; ++i) { pieces.push(format.write(nodes[i])); } updateOutput(pieces.join(' ')); } function hasAttributeNS(node, uri, name) { updateOutput(format.hasAttributeNS(node, uri, name)) } function getAttributeNodeNS(node, uri, name) { var attributeNode = format.getAttributeNodeNS(node, uri,name); updateOutput(attributeNode.nodeName + ' = "' + attributeNode.nodeValue + '"'); } function getAttributeNS(node, uri, name) { var attributeValue = format.getAttributeNS(node, uri, name); updateOutput('"' + attributeValue + '"') } function createElementNS(uri, name) { var node = format.createElementNS(uri, name); doc.documentElement.appendChild(node); write(); } function createTextNode(text) { var node = format.createTextNode(text); doc.documentElement.appendChild(node); write(); } window.onload = init; </script> <p>OpenLayers有一个很简单的XML类,你可以用var name = new OpenLayers.Format.XML();方式来声明。这个类包含可以读取,输出".xml"文件,并允许被实例的对象使用类的方法和属性。</p> <p>这个XML类可以让我们从矢量电子地图(由于我把在电子地图上画的Point、Line、Ploygon等Feature对象放在 Vector层上,或者是经常用Vector型的地图数据来呈图,因此我就这么理解了这句英文,哈哈!)上通过DOM解析器来提取、者输出各种XML格式的数据。但是,千万别认为这个OpenLayers.Format.XML类很强大,它仅能完成对XML数据的基本操作。因此,如果有必要,我们可以用 JavaScript中的“Prototype原型构造法”来扩充OpenLayers.Format.XML()类的方法、属性。</p> <p>当然,你也可以直接修改OpenLayers的核心文件(位置在OpenLayers\lib\OpenLayers\Format\XML.js,由于它继承了Format.js父类,因此我建议你顺便看一下父类)。</p> <p>本例仅用DOM解析器,解析一个XML文件,这个XML文件中包含了电子地图的相关数据。你也可以结合其他的类的方法(以后讲)直接从电子地图上面输出真实的XML电子地图数据文件,然后转到Java中处理。或者,跨越过Java直接用JavaScript+SQL语句进行系统开发(由于不是重点,就不废话了)。</p> <p>需要提醒的是,你得等XML文件全部加载完后,再点击下面的按钮。不然,就会有错误!因此,我建议你做一个"loading..."判断程序,以便序告知自己是否加载XML的状态。</p> <p>上面的内容很多是我加的,不是英文翻译地,因此不能算翻译错误,谢谢!</p> <div id="tags"></div> <div id="docs"> <b>基本方法:</b> <ul> <li> <a href="javascript:void write();">format.write()</a>以文本字符串输出这个XML文件。 </li> <li> <a href="javascript:void getElementsByTagNameNS(doc, 'http://www.opengis.net/gml','MultiPolygon');">format.getElementsByTagNameNS()</a> 输出名称空间为“gml:MultiPolygon”的标签,以及它的详细数据,子标签等等,并返回给一个具备数组类型特征的对象(写的比较难理解,是因为这个对象不一定就是数组类型对象,而是具备数组的特征!) </li> <li> <a href="javascript:void hasAttributeNS(doc.documentElement,'http://www.w3.org/2001/XMLSchema-instance','schemaLocation');">format.hasAttributeNS()</a> 判断XML的文本字符串中“schemaLocation”属性的值是否等于“in the http://www.w3.org/2001/XMLSchema-instance”。返回一个Boolean对象,如果等于就输出“ture”,如果不等于就输出“false”。 </li> <li> <a href="javascript:void getAttributeNodeNS(doc.documentElement,'http://www.w3.org/2001/XMLSchema-instance','schemaLocation');">format.getAttributeNodeNS()</a> 输出XML文本字符串中“schemaLocation”这个完整的空间名称和它的值“in the http://www.w3.org/2001/XMLSchema-instance”。 </li> <li> <a href="javascript:void getAttributeNS(doc.documentElement,'http://www.w3.org/2001/XMLSchema-instance','schemaLocation');">format.getAttributeNS()</a> 仅仅输出XML文本字符串中“schemaLocation”属性的值“in the http://www.w3.org/2001/XMLSchema-instance”。 </li> <li> <a href="javascript:void createElementNS('http://bar.com/foo','foo:TestNode');">format.createElementNS()</a> 创建一个空间名称为“foo:TestNode”的标签,并且把它加在这个已经存在的XML文件中的最后。 </li> <li> <a href="javascript:void createTextNode('test text');">format.createTextNode()</a> 创建具体的数据内容,并加进指定的“foo:TestNode”标签中。 </li> </ul> <br> <b>输出结果:</b><br> <div id="output"> </div> </div>