Answers:
好的,本,这是我的假设:
1)您已经有了数据(我在shapefile中有一些地址点,并且下载了密苏里州的人口普查区和人口普查区shapefile)。
2)您已经对地址点进行了地理编码,并且可以轻松投影数据。
3)您对OGR / PostGIS解决方案感到满意(均为免费)。
如果没有这些软件,请参见以下安装注意事项:如何使用PostGIS支持安装PostGREs。(通过BostonGIS。请不要冒犯他们的标题,我只是认为这是那里最好的方法。)此外,这是一个,两个和三个站点,它们描述了如何使用Python绑定安装GDAL / OGR。
注意:在进行实际分析(即ST_Contains
下面的内容)之前,应确保所有图层都在同一投影中!如果您有shapefile,则可以使用 Quantum GIS(QGIS)或OGR(如果有的话,也可以使用ArcGIS)将投影从一个投影转换为另一投影很容易。或者,您可以使用PostGIS函数在数据库中执行投影转换。基本上选择您的毒药,或者让我们知道这是否是绊脚石。
有了这些给定的条件,这就是我使用PostGIS在某些地址点数据上附加道和块属性的方式:
首先,我曾经ogr2ogr
将三个shapefile导入PostGIS:
使用ogr2ogr导入地址:
ogr2ogr -f "PostGreSQL" PG:"host=127.0.0.1 user=youruser dbname=yourdb password=yourpass" "E:\path_to\addresses.shp" -nln mcdon_addresses -nlt geometry
进口普查小区使用ogr2ogr(密苏里州)的spMoWest
后缀意味着我已经翻译我的数据,密苏里州西部平面脚。
ogr2ogr -f "PostGreSQL" PG:"host=127.0.0.1 user=youruser dbname=yourdb password=yourpass" "E:\path_to\st_tract10_spMoWest.shp" -nln mo_tracts_2010 -nlt geometry
导入块数据(密苏里州): 这花费了一段时间。实际上,我的计算机一直崩溃,我不得不在上面放风扇!哦,ogr2ogr
也不会给出任何反馈,所以请不要大惊小怪;请确保等待它,直到最终完成。
ogr2ogr -f "PostGreSQL" PG:"host=127.0.0.1 user=youruser dbname=yourdb password=yourpass" "E:\path_to\st_block10_spMoWest.shp" -nln mo_blocks_2010 -nlt geometry
数据导入完成后,启动PgAdmin III(PostGREs GUI),浏览到数据库并抛出一些快速维护命令,以便PostGREsql使用这些新数据可以更快地运行:
vacuum mcdon_addresses;
vacuum mo_tracts_2010;
vacuum mo_blocks_2010;
接下来,我很好奇我导入了多少个原始地址点,所以我做了一个快速介绍COUNT(*)
。我通常会在这样的任务开始时进行一次计数,以便以后为我进行“健全性检查”奠定基础。
SELECT COUNT(*) FROM mcdon_addresses;
-- 11979
在下一阶段,我创建了两个新表,将tracts属性,然后再将blocks属性逐渐添加到我的原始地址点表中。如您所见,PostGIS ST_Contains
函数完成了繁重的工作,在每种情况下都创建了一个新的点表,每个表都获得了它们所在的区域和块多边形的属性。
注意!为简便起见,我仅从每个表中提取几个字段。您可能会想要几乎所有东西。我之所以这样说,几乎是因为您需要ogr_fid
从要合并的表中忽略该字段(甚至其他字段?),否则PostGREs会抱怨这两个字段具有相同的名称。
(PS我在弄清楚此内容的同时在这里进行了一些窥探:http : //postgis.net/docs/manual-1.4/ch04.html)
创建一个具有tracts属性的新地址表: 注意,我在每个输出列的前面添加了一个提示,提示它开始于哪个表(我将在下面解释原因)。
CREATE TABLE mcdon_addresses_wtract AS
SELECT
a.wkb_geometry,
a.route AS addr_route,
a.box AS addr_box,
a.new_add AS addr_new_add,
a.prefix AS addr_prefix,
a.rdname AS addr_rdname,
a.road_name AS addr_road_name,
a.city AS addr_city,
a.state AS addr_state,
a.zip AS addr_zip,
t.statefp10 AS tr_statefp10,
t.countyfp10 AS tr_countyfp10,
t.tractce10 AS tr_tractce10,
t.name10 AS tr_name10,
t.pop90 AS tr_pop90,
t.white90 AS tr_white90,
t.black90 AS tr_black90,
t.asian90 AS tr_asian90,
t.amind90 AS tr_amind90,
t.other90 AS tr_other90,
t.hisp90 AS tr_hisp90
FROM
mcdon_addresses AS a,
mo_tracts_2010 AS t
WHERE
ST_Contains(t.wkb_geometry, a.wkb_geometry);
维护该表,以便PostGREs继续平稳运行:
vacuum mcdon_addresses_wtract;
现在我有两个问题。
ST_Contains实际起作用了吗?..and .. 考虑到我使用的数据输入,返回的地址数量是否有意义?
我能够使用相同的查询回答这两个问题:
select count(*) from mcdon_addresses_wtract;
-- returns 11848
快速了解损失:首先,我在ArcGIS中进行了检查(您也可以在QGIS中进行此检查),并且返回的计数相同。那么,为什么会有所不同呢?首先,有些地址不在密苏里州范围内,而我仅将它与密苏里州的一个区域相比较。其次,仔细分析,似乎在地址数据中存在一些数字化不良的示例。具体来说,许多未被捕获的点的ST_Contains
属性字段为空,这是在数字化过程中出现错误的好兆头。这也意味着它们无论如何都不可用。在这一点上,我对这些差异感到满意,因为我可以合理地返回并改善数据,从而进行更清晰的分析。
继续,下一步是在地址/段表中附加来自块数据的属性。同样,我通过创建一个新表来做到这一点,再次在每个输出字段之前添加前缀以指示该表来自哪个表(前缀将非常重要,您将看到):
CREATE TABLE mcdon_addr_trct_and_blk AS
SELECT
a.*,
b.pop90 AS blk_pop90,
b.white90 AS blk_white90,
b.black90 AS blk_black90,
b.asian90 AS blk_asian90,
b.amind90 AS blk_amind90,
b.other90 AS blk_other90,
b.hisp90 AS blk_hisp90
FROM
mcdon_addresses_wtract AS a,
mo_blocks_2010 AS b
WHERE
ST_Contains(b.wkb_geometry, a.wkb_geometry);
当然,维护表:
vacuum mcdon_addr_trct_and_blk;
我为每个输出字段加上前缀的原因是,如果没有,则某些字段将具有相同的名称,并且在最终产品中将它们彼此区分开是不可能的。但自从我重命名以来,我没有给它机会。例如,考虑上面两个步骤中的以下两个字段。您可以看到为什么我重命名了它们。
t.pop90 AS tr_pop90 -- would have been simply pop90
b.pop90 AS blk_pop90 -- also would have been pop90 !
现在我们有了一个包含区域数据集的地址,dwe仍然具有相同数量的点?
select count(*) from mcdon_addr_trct_and_blk;
-- 11848 (thumbs up!)
是的,我们做到了!如果需要,可以继续删除我们创建的第一个表mcdon_addresses_wtract
。我们不再需要它来进行分析。
作为最后的动作,您可能希望将数据从PostGREs导出到ESRI shapefile中,以便可以使用其他程序(例如ArcGIS)进行查看(注意,QGIS可以毫无问题地读取PostGIS数据)。如果您有兴趣,可以使用以下方法使用ogr2ogr进行转换:
ogr2ogr -f "ESRI Shapefile" "E:\path_to\addr_trct_blk.shp" PG:"host=127.0.0.1 user=youruser dbname=yourdb password=yourpass" "mcdon_addr_trct_and_blk"
最后,当您运行此命令时,您可能会收到类似以下的警告:
警告6:规范/清洗的字段名称:从'tr_statefp10'到'tr_statefp'
这仅意味着OGR必须缩短该字段名称,因为shapefile中的字段名称只能这么长。
当然,这只是完成这项工作的许多方式之一。