C#XmlReader ChildNodes 30GB文件导入SQL Server

时间:2013-07-23 09:02:11

标签: c# sql xmlreader openstreetmap get-childitem

数据示例:

<?xml version='1.0' encoding='UTF-8'?><osm version="0.6" generator="osmconvert 0.7P" timestamp="2013-07-20T19:00:02Z">
.
   <way id="128725988" version="1" timestamp="2011-09-03T08:06:56Z" changeset="9198624" uid="42429" user="42429">
      <nd ref="1421727256"/>
      <nd ref="1421727264"/>
      <nd ref="1421727238"/>
      <nd ref="1421727237"/>
      <nd ref="1421727256"/>
      <tag k="addr:housenumber" v="43"/>
      <tag k="addr:street" v="Wilhelm-Ahrens-Straße"/>
      <tag k="building" v="yes"/>
   </way>
.
.
   <node id="1964468590" lat="53.068416" lon="8.779039" version="1" timestamp="2012-10-14T12:29:02Z" changeset="13491909" uid="715371" user="cracklinrain"/>
   <node id="1964468593" lat="53.0684177" lon="8.7798644" version="1" timestamp="2012-10-14T12:29:02Z" changeset="13491909" uid="715371" user="cracklinrain">
      <tag k="natural" v="tree"/>
   </node>
.
.
.
   <way id="128725989" version="1" timestamp="2011-09-03T08:06:57Z" changeset="9198624" uid="42429" user="42429">
      <nd ref="1421728028"/>
      <nd ref="1421728023"/>
      <nd ref="1421728016"/>
      <nd ref="1421728024"/>
      <nd ref="1421728028"/>
      <tag k="addr:housenumber" v="44"/>
      <tag k="addr:street" v="Alma-Rogge-Straße"/>
      <tag k="building" v="yes"/>
   </way>
.
.

这是一个Xml文件的示例,里面有30GB的数据。

我想要做的只是获取包含<tag>等特定所需属性的addr:housenumber个元素。

保持连接所需的一件事是来自父元素的id

我的主要问题是如何处理30 GB的文档。如果它大约几百MB,我自己解决它就没问题了。

我已经尝试过:

  1. 的XmlReader

    非常适合获取特定属性,但与父ID的连接将丢失。

  2. 像xDocument,XmlDocument ......

    之类的东西

    问题是数据量。 (30 GB)
    将〜1GB加载到内存后获得OutOfMemoryException 我知道将30GB的内容加载到内存中会很疯狂。

  3. 我已经有一个单独的工作解决方案,通过使用OpenSource库来处理pbf文件(但我想处理干净的数据)并通过遍历每个节点并使用LinqToSql将其添加到数据库来提取所需的数据。 / p>

    最终结果:

    我想将每个街道,住宅号码,邮政编码和城市导入到StreetTableCityTable连接的SQL Server数据库中(我的第一个解决方案运行良好,但经过10 000个处理项目后)它变得非常慢。)

    我希望我想做的事情是可以理解的。

2 个答案:

答案 0 :(得分:0)

我不确定,但这些链接可能有所帮助:

https://wiki.openstreetmap.org/wiki/Osmconvert#Dispose_of_Ways_and_Relations_and_Convert_them_to_Nodes

https://wiki.openstreetmap.org/wiki/Osmconvert#Writing_CSV_Files

也很有用:osmfilter,Osmosis

osmconvert和osmfilter的一些选项需要严格排序的输入文件:首先是所有节点,然后是所有方式,然后是所有关系。在覆盖范围内,数据应按ID排序。

如果使用.o5m(或者.pbf)文件格式,转换和过滤会更快。

答案 1 :(得分:0)

我没有使用C#的经验,但由于XML文件非常庞大,只能读取/访问一次,因此简单的XML SAX解析器就足够了。 C#的XmlReader似乎与SAX解析器类似。因此,您只需要读取<node><way>元素并触发相应的事件,您只需存储id属性即可。每当读取<tag>事件并触发相应的事件时,您将其所有属性分配给以前读取id