经纬度数据收集自 维北有斗-天文爱好者的乐园
编写这篇博文有几个目的:
首先认识了两个单词

latitude [lat·i·tude || ’lætɪtuːd /-tjuːd] n. 纬度; 回旋余地, 自由; 纬度地区

longitude [lon·gi·tude || ’lɑndʒɪtuːd /’lɒndʒɪtjuːd] n. 经度; 经线

1.学习dom4j的简单用法
2.做一个方便使用的全国城市经纬度数据库
3.利用google天气api做一个全面的天气预报服务
4.学习用python编写webservice

内容:
1.学习dom4j的简单用法
收集了的经纬度都是按照城市分开的单独的htm文件,我已经处理过为符合html4.0标准的html文件了,即所有的标识都是成对的,这里可以下载这些文件(点击下载经纬度html包)
(1)如何使用dom4j读入xml文档

使用dom4j读入xml文档代码片段
1 File file = new File(“G:\\workspace\\test.xml”);
2 SAXReader reader = new SAXReader();
3 //根据实际情况设置编码
4 reader.setEncoding(“GBK”);
5 Document doc = reader.read(files);
6
7 //获得xml文档的根节点
8 Element root = doc.getRootElement();

(2)如何遍历xml文档的所有结点
这样就读入了这个xml文档,并获得了这个xml文档对象的根结点,由于xml文档是一个树形结构,这样就很容易遍历它所有的结点了。
这里根据自己的需要,测试使用了两种遍历方法,一种是根据树的结构编写递归程序,一种就是直接使用循环,还有都dom4j自带的visitor模式访问也很好用,这里有篇参考文档,可以看看(查看)

使用递归遍历

public  void visitAll(Element root, Element child){
// 枚举所有子节点
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element element = (Element) i.next();
System.out.println(stringTrim(element.getText()));
if(this.stringTrim(element.getTextTrim()).equals("")){
return;
} 
else {
Element tmp = child.addElement("city");
visitAll(element, tmp);
}
}
}

这里提供的xml文档层数为2,直接循环即可

直接循环遍历

public  void visitAll(Element root, Element child){
// 枚举所有子节点
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element element = (Element) i.next();      
Iterator j = element.elementIterator();
Element tmpElement = (Element)j.next();
if(!(stringTrim(tmpElement.getTextTrim()).equals("城市名")))
{
Element tmp = child.addElement("city");
tmp.addAttribute("name", 
stringTrim(tmpElement.getTextTrim()).trim());
tmpElement = (Element)j.next();
tmp.addAttribute("longitude", 
stringTrim(tmpElement.getTextTrim()).trim());
tmpElement = (Element)j.next();
tmp.addAttribute("latitude", 
stringTrim(tmpElement.getTextTrim()).trim());
}
}
}

关于visitor模式的使用,请参看上面给出的参考文档

(3)创建新的xml文档

创建xml文档

public void createXMLFile(String filename) throws Exception{
//使用辅助方法创建文档对象
Document res = DocumentHelper.createDocument();
//添加文档跟结点country
Element rootElement = res.addElement("country");
//给根节点添加属性name,值为"中国"
rootElement.addAttribute("name", "中国");
//打开目录
File file = new File("G:\\workspace\\jwd\\jwd");
//打开目录下所有的xml文档
File[] files = file.listFiles();
//依次操作每个xml文档
for(int i = 0; i < files.length; i ++){
//获取文件名,去掉文件扩展名
String[] name = files[i].getName().split("\\.");
//在根结点下添加子节点province
Element childElement = rootElement.addElement("province");
//添加属性name,值为文件名
childElement.addAttribute("name", name[0].trim());
//创建reader
SAXReader reader = new SAXReader();
//根据实际情况设置编码
reader.setEncoding("GBK");
Document doc = reader.read(files[i]);
//获得xml文档的根节点
Element root = doc.getRootElement();
//遍历所有的结点
this.visitAll(root, childElement);
}
//格式化即将输出的xml,让它看起来整齐点
OutputFormat format = OutputFormat.createPrettyPrint();
/*将document中的内容写入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format);
writer.write(res);
writer.close(); 
}

整个合并所有html页为一个xml的代码如下

完整的代码

import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
 * @author canvas
 *
 */
public class GIS {
public void createXMLFile(String filename) throws Exception{
//使用辅助方法创建文档对象
Document res = DocumentHelper.createDocument();
//添加文档跟结点country
Element rootElement = res.addElement("country");
//给根节点添加属性name,值为"中国"
rootElement.addAttribute("name", "中国");
//打开目录
File file = new File("G:\\workspace\\jwd\\jwd");
//打开目录下所有的xml文档
File[] files = file.listFiles();
//依次操作每个xml文档
for(int i = 0; i < files.length; i ++){
//获取文件名,去掉文件扩展名
String[] name = files[i].getName().split("\\.");
//在根结点下添加子节点province
Element childElement = rootElement.addElement("province");
//添加属性name,值为文件名
childElement.addAttribute("name", name[0].trim());
//创建reader
SAXReader reader = new SAXReader();
//根据实际情况设置编码
reader.setEncoding("GBK");
Document doc = reader.read(files[i]);
//获得xml文档的根节点
Element root = doc.getRootElement();
//遍历所有的结点
this.visitAll(root, childElement);
}
//格式化即将输出的xml,让它看起来整齐点
OutputFormat format = OutputFormat.createPrettyPrint();
/*将document中的内容写入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format);
writer.write(res);
writer.close(); 
}
public  void visitAll(Element root, Element child){
// 枚举所有子节点
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element element = (Element) i.next();
//System.out.println(stringTrim(element.getText()));
/*if(this.stringTrim(element.getTextTrim()).equals("")){
               return;
           } 
           else {
                Element tmp = child.addElement("city");
                visitAll(element, tmp);
           }*/
Iterator j = element.elementIterator();
Element tmpElement = (Element)j.next();
if(!(stringTrim(tmpElement.getTextTrim()).equals("城市名")))
{
Element tmp = child.addElement("city");
tmp.addAttribute("name", 
stringTrim(tmpElement.getTextTrim()).trim());
tmpElement = (Element)j.next();
tmp.addAttribute("longitude", 
stringTrim(tmpElement.getTextTrim()).trim());
tmpElement = (Element)j.next();
tmp.addAttribute("latitude", 
stringTrim(tmpElement.getTextTrim()).trim());
}
}
}
public String stringTrim(String str){
//去掉空格和全角空格
String[] tmp = str.split("\\s| ");
StringBuffer sb = new StringBuffer();
for(int i = 0; i < tmp.length; i ++){
sb.append(tmp[i].trim());
}
return sb.toString();
}
/**
     * @param args
     */
public static void main(String[] args) {
try {
new GIS().createXMLFile("d:\\GI-China.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
}

2.做一个方便使用的全国城市经纬度数据库
经过上面的操作,一个完整的全国城市经纬度数据库就做好了,只不过它是xml格式的,看起来还不错,[下载这个数据库](/Files/canvas/GI- China.zip “下载这个数据库”)

生成的xml展示

<?xml version="1.0" encoding="UTF-8"?>
<country name="中国">
  <province name="上海">
    <city name="上海" longitude="121.48" latitude="31.22"/>
    <city name="嘉定" longitude="121.24" latitude="31.4"/>
    <city name="宝山" longitude="121.48" latitude="31.41"/>
    <city name="川沙" longitude="121.7" latitude="31.19"/>
    <city name="南汇" longitude="121.76" latitude="31.05"/>
    <city name="奉贤" longitude="121.46" latitude="30.92"/>
    <city name="松江" longitude="121.24" latitude="31"/>
    <city name="金山" longitude="121.16" latitude="30.89"/>
    <city name="青浦" longitude="121.1" latitude="31.15"/>
    <city name="崇明" longitude="121.4" latitude="31.73"/>
  </province>
  <province name="云南">
    <city name="昆明" longitude="102.73" latitude="25.04"/>
    <city name="富民" longitude="102.48" latitude="25.21"/>
    <city name="晋宁" longitude="102.58" latitude="24.68"/>
    <city name="呈贡" longitude="102.79" latitude="24.9"/>
    <city name="安宁" longitude="102.44" latitude="24.95"/>
    <city name="昭通" longitude="103.7" latitude="29.32"/>
    <city name="永善" longitude="103.63" latitude="28.22"/>
    <city name="大关" longitude="103.91" latitude="27.74"/>
    <city name="彝良" longitude="104.06" latitude="27.61"/>
    <city name="鲁甸" longitude="103.54" latitude="27.21"/>
    <city name="绥江" longitude="103.97" latitude="28.58"/>

3.利用google天气api做一个全面的天气预报服务
google提供的天气api可以有两种方式访问,
一种是
[ http://www.google.com/ig/api?hl=zh- cn&weather=,,,30670000,104019996](http://www.google.com/ig/api?hl=zh- cn&weather=,,,30670000,104019996)
30670000为纬度,104019996为经度,这个是把上面的xml中的经纬度乘以了10^6(10的六次方),这个方法有个好处,就是可以根据经纬度获得天气预报,自然预报地区也可变得精确些
另一种是
http://www.google.com/ig/api?weather=Beijing
这个链接比较简单,但是支持的城市比较少,所以还是使用第一种方式比较好,于是才整理好了所有城市的经纬度

访问上面的链接,google返回的xml内容看起来是这样的

google返回的xml
1
2 <xml_api_reply version=“1”><forecast_information><postal_code data=""/><latitude_e6 data=“30670000”/><longitude_e6 data=“104019996”/><forecast_date data=“2009-03-05”/><current_date_time data=“2009-03-05 19:00:00 +0000”/><unit_system data=“SI”/></forecast_information><current_conditions><temp_f data=“61”/><temp_c data=“16”/><wind_condition data=“风向: 北、风速:6 (公里/小时)”/></current_conditions><forecast_conditions><day_of_week data=“周四”/></forecast_conditions><forecast_conditions><day_of_week data=“周五”/></forecast_conditions><forecast_conditions><day_of_week data=“周六”/></forecast_conditions><forecast_conditions><day_of_week data=“周日”/></forecast_conditions></xml_api_reply>

对于返回的xml中的,可以这样构造链接获取google提供的图片
取其中的cn_cloudy.gif,然后放在http://www.google.cn/ig/images/weather/之后,生成的链接是
http://www.google.cn/ig/images/weather/cn_cloudy.png
这样这个天气api就基本构思好了

4.学习用python编写webservice(待续……)
将这个服务编写为一个webservice,决定使用python去写,所以要学习一下python了