利用python解析基于GraphML的的社会网络并用GIS展示
好长一个标题… …但是确实是用python来连接SNA(Social Network Analysis)和GIS(Geographic Information System)。脑子里反复想着自己特长是啥,画地图?那大概是5岁以前的事情,后来几个伙计打趣说我谈恋爱很在行,Seriously,这方面我还确实拿不出手。一直不离不弃的,也许就是自己编程的能耐,当学了“君子不器”后,越来越发觉似乎连编程都不能当会事了,但是话说回来,至少这算是个爱好吧。
需求大抵是这样的,客户用igraph进行社会网络分析,然后生成了xml格式的数据文件,但并没有很好的网络展示平台,manager就来找我,希望通过我们研发的WebGIS系统展示。在我们的WebGIS系统中,矢量数据都是保存在PostgreSQL数据库里,一般来说,都是通过shapefile 生成sql files,然后导入数据库。由于没有shapefile,但是分析graphicML文件发现结构还是很简单的,而且对于社会网络的两个node之间的关系(relationship),从几何的角度讲,两个nodes构成的关系就是一条两点直线(edge)。基于此,我希望通过python对graphML进行分析,然后直接生成sql file,导入到postgreSQL里面,此后就能用uDig就能直接转换成为shapefile,我不清楚新版的ArcGIS 9.3有没有相似的功能,好久不用Arctoolbox了。

原始数据片段:
< ?xml version="1.0" encoding="UTF-8"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> <!-- Created by igraph --> <key id="filestub" for="graph" attr.name="filestub" attr.type="string"/> <key id="id" for="node" attr.name="id" attr.type="string"/> <key id="xcoord" for="node" attr.name="xcoord" attr.type="double"/> <key id="ycoord" for="node" attr.name="ycoord" attr.type="double"/> <key id="h_loc" for="edge" attr.name="h_loc" attr.type="string"/> <key id="h_zip" for="edge" attr.name="h_zip" attr.type="string"/> <key id="h_city" for="edge" attr.name="h_city" attr.type="string"/> <key id="t_loc" for="edge" attr.name="t_loc" attr.type="string"/> <key id="t_zip" for="edge" attr.name="t_zip" attr.type="string"/> <key id="t_city" for="edge" attr.name="t_city" attr.type="string"/> <key id="appyear" for="edge" attr.name="appyear" attr.type="string"/> <key id="patent" for="edge" attr.name="patent" attr.type="string"/> <key id="pat_type" for="edge" attr.name="pat_type" attr.type="string"/> <graph id="G" edgedefault="undirected" parse.nodes="1022" parse.edges="9399"> <data key="filestub">/tmp/VDC/DSB/iGraph.322801</data> <node id="n0"> <data key="id">20190035</data> <data key="xcoord">394.439</data> <data key="ycoord">245.759</data> </node> <node id="n1"> <data key="id">21810055</data> <data key="xcoord">452.308</data> <data key="ycoord">-49.6771</data> </node> <edge source="n1020" target="n1021"> <data key="h_loc">MA</data> <data key="h_zip">01532</data> <data key="h_city">NORTHBORO</data> <data key="t_loc">MA</data> <data key="t_zip">01601</data> <data key="t_city">WORCESTER</data> <data key="appyear">2004</data> <data key="patent">7459547</data> <data key="pat_type">U</data> </edge> </graph> </graphml>
通过python对XML进行解析,我还是向大家推荐pyQuery,大概是喜欢Jquery的缘故吧,我觉得pyQuery用起来很方便,很顺手。大家可以到pyquery.org查找帮助和教程。需要注意的是,pyQuery对于命名空间的解析似乎不是很好,我记得以前我写过一篇帖子叫做两个GIS编程技巧,里面提及了用@nodeName=namespace:elementName的方式来对异域命名空间的元素进行解析。但是pyQuery似乎不能进行该操作,所以我在进行解释之前,将根节点的所有命名空间都删除了。
解析本省是一件很简单的事情,随后写入到另一个文件中,其次对每一个node和edge进行分析,按照SQL语法,生成INSERT INTO的语句。
python 代码片段
from pyquery import PyQuery as pq from lxml import etree d = pq(filename="data/rna.xml") file = open('data/output.sql', 'w+') content = '' nodes = d('node') for item in nodes: content += "INSERT INTO sn_node ( the_geom, nid) VALUES ( GeomFromText('POINT(" + item[1].text.__str__() + " " + item[2].text.__str__() +")', 900913), '" + item.attrib['id'] + "');\n" file.write(content) file.close()
从而生成output.sql,如下片段,
INSERT INTO sn_node ( the_geom, nid) VALUES ( GeomFromText('POINT(394.439 245.759)', 900913), 'n0'); INSERT INTO sn_node ( the_geom, nid) VALUES ( GeomFromText('POINT(452.308 -49.6771)', 900913), 'n1'); INSERT INTO sn_node ( the_geom, nid) VALUES ( GeomFromText('POINT(172.295 72.8809)', 900913), 'n2'); INSERT INTO sn_node ( the_geom, nid) VALUES ( GeomFromText('POINT(-217.813 -581.18)', 900913), 'n3'); INSERT INTO sn_edge ( the_geom, snid, tnid, s_zip, t_zip, appyear, patent, pat_type) VALUES ( GeomFromText('LINESTRING(-206.829 790.104,-200.639 791.055)', 900913), 'n121', 'n365', '05403', '05452', '1997', '5902044', 'U'); INSERT INTO sn_edge ( the_geom, snid, tnid, s_zip, t_zip, appyear, patent, pat_type) VALUES ( GeomFromText('LINESTRING(-206.829 790.104,-231.181 757.468)', 900913), 'n121', 'n214', '05403', '05403', '1998', '6134704', 'U');
生成了SQL的INSERT INTO 语句后,然后加上创建数据库和构建索引的语句
CREATE TABLE sn_node ( id serial, nid varchar(6) ); SELECT AddGeometryColumn('', 'sn_node','the_geom',900913,'POINT',2); CREATE INDEX sn_node_index ON sn_node USING GIST ( the_geom );
所有的SQL语句组成了一个SQL文件,如果你有PgAdminIII,导入不是繁琐的事情。不再熬述了。uDig可以直接读取PostgreSQL里面的数据,然后我在uDig里面可以绘制出社会网络的模型,也可uDig输出shapefile,再用ArcGIS读取并展示。如图所示:

Related posts:
About this entry
You’re currently reading “利用python解析基于GraphML的的社会网络并用GIS展示,” an entry on Geoinformatics
- Published:
- 10.31.09 / 3上午
Ajax ArcGIS China Dreams Flex Geography Geoinformatics GeoRSS GIS Google Hardware Harvard Historical Geography History Jquery Life Linux Love Map MapServer NASA Neo-Confucianism OGC OpenGIS OpenSource OSGeo PHP Politics PostGIS PostgreSQL PROJ4 Python R RS Song SVG Ubuntu Web WebGIS Wordpress
WP Cumulus Flash tag cloud by Roy Tanck and Luke Morton requires Flash Player 9 or better.















赵 博 (Bo Zhao),
参与或主持的项目
2 Comments
Jump to comment form | comments rss [?] | trackback uri [?]