經緯度數據收集自
維北有斗-天文愛好者的樂園
編寫這篇博文有幾個目的:
首先認識了兩個單詞
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格式的,看起來還不錯,
下載這個數據庫

生成的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
30670000為緯度,104019996為經度,這個是把上面的xml中的經緯度乘以了10^6(10的六次方),這個方法有個好處,就是可以根據經緯度獲得天氣預報,自然預報地區也可變得精確些
另一種是
http://www.google.com/ig/api?weather=Beijing
這個鏈接比較簡單,但是支持的城市比較少,所以還是使用第一種方式比較好,于是才整理好了所有城市的經緯度
訪問上面的鏈接,google返回的xml內容看起來是這樣的

google返回的xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <xml_api_reply version="1"><weather module_id="0" tab_id="0"><forecast_information><city data=""/><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><condition data="晴"/><temp_f data="61"/><temp_c data="16"/><humidity data="濕度: 45%"/><icon data="/images/weather/sunny.gif"/><wind_condition data="風向: 北、風速:6 (公里/小時)"/></current_conditions><forecast_conditions><day_of_week data="周四"/><low data="7"/><high data="16"/><icon data="/images/weather/mostly_sunny.gif"/><condition data="以晴為主"/></forecast_conditions><forecast_conditions><day_of_week data="周五"/><low data="4"/><high data="9"/><icon data="/images/weather/chance_of_rain.gif"/><condition data="可能有雨"/></forecast_conditions><forecast_conditions><day_of_week data="周六"/><low data="5"/><high data="10"/><icon data="/images/weather/mostly_sunny.gif"/><condition data="以晴為主"/></forecast_conditions><forecast_conditions><day_of_week data="周日"/><low data="3"/><high data="12"/><icon data="/images/weather/chance_of_rain.gif"/><condition data="可能有雨"/></forecast_conditions></weather></xml_api_reply>
對于返回的xml中的<icon data="/images/weather/cn_cloudy.gif"/>,可以這樣構造鏈接獲取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了