首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >osm-文件(osm.pbf)的处理和过滤在C#中花费的时间太长了。

osm-文件(osm.pbf)的处理和过滤在C#中花费的时间太长了。
EN

Stack Overflow用户
提问于 2020-01-10 11:13:36
回答 1查看 1.1K关注 0票数 2

场景:我想为地址编写自己的Autocomplete,就像谷歌提供的那样。(非常基本的:街道,豪森数,城市,邮政编码,乡村)。它仅供私人使用和培训之用。首先,我想覆盖大约100万个地址。

使用的技术: .Net Framework (非核心)、C#、Visual、OSMSharp、Microsoft、Web 2(尽管我将来可能会切换到ASP.Net Core)。

方法:

Demo-Purposes)

  • Download

  • 设置项目(Web 2或控制台项目,用于从OpenStreetMaps到OpenStreetMaps的相关文件,使用DownloadClient(),在文件中使用OSMSharp,并过滤出相关的Data.

  • Convert过滤数据到DataTable.

  • Use DataTable,以向SQLBulkCopy方法输入数据到数据库。

)

问题:第4步走的太长了。对于osm.pbf格式的"Regierungsbezirk ln“这样的文件,大约为160 GB(未压缩的osm文件大约为2.8GB),其中讨论了4到5个小时。我想优化这个。另一方面,将DataTable大容量复制到数据库(大约100万行)只需要大约5秒。(哇哦。令人惊叹)

最小复制: https://github.com/Cr3pit0/OSM2Database-Minimal-Reproduction

我尝试了什么:

  • 在Server中使用存储过程。这带来了一组完全不同的问题,我没有很好地让它正常工作(主要是因为未压缩的osm.pbf文件超过2GB,Server不喜欢这样),
  • 想出了一种不同的方法来过滤并将数据从文件转换成DataTable (或CSV)。
  • 使用了天桥-API。虽然我在某个地方读到了透视图-API并不适用于超过10,000个条目的DataSets。
  • 向StackOverflow上的绝地大师寻求帮助。(目前正在进行. :D)

代码摘录:

代码语言:javascript
复制
public static DataTable getDataTable_fromOSMFile(string FileDownloadPath)
{

    Console.WriteLine("Finished Downloading. Reading File into Stream...");

    using (var fileStream = new FileInfo(FileDownloadPath).OpenRead())
    {
        PBFOsmStreamSource source = new PBFOsmStreamSource(fileStream);

        if (source.Any() == false)
        {
            return new DataTable();
        }

        Console.WriteLine("Finished Reading File into Stream. Filtering and Formatting RawData to Addresses...");
        Console.WriteLine();

        DataTable dataTable = convertAdressList_toDataTable(
                    source.Where(x => x.Type == OsmGeoType.Way && x.Tags.Count > 0 && x.Tags.ContainsKey("addr:street"))
                    .Select(Address.fromOSMGeo)
                    .Distinct(new AddressComparer())
                );

        return dataTable;
    }
};
代码语言:javascript
复制
private static DataTable convertAdressList_toDataTable(IEnumerable<Address> addresses)
{
    DataTable dataTable = new DataTable();

    if (addresses.Any() == false)
    {
        return dataTable;
    }

    dataTable.Columns.Add("Id");
    dataTable.Columns.Add("Street");
    dataTable.Columns.Add("Housenumber");
    dataTable.Columns.Add("City");
    dataTable.Columns.Add("Postcode");
    dataTable.Columns.Add("Country");

    Int32 counter = 0;

    Console.WriteLine("Finished Filtering and Formatting. Writing Addresses From Stream to a DataTable Class for the Database-SQLBulkCopy-Process ");

    foreach (Address address in addresses)
    {
        dataTable.Rows.Add(counter + 1, address.Street, address.Housenumber, address.City, address.Postcode, address.Country);
        counter++;

        if (counter % 10000 == 0 && counter != 0)
        {
            Console.WriteLine("Wrote " + counter + " Rows From Stream to DataTable.");
        }
    }

    return dataTable;
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-14 16:23:08

好的,我想我明白了。对于文件大小约为600 of的文件和过滤后的310万行数据,Im只需12分钟。

我尝试的第一件事是用FastMember替换填充我的FastMember的逻辑。这是可行的,但并没有实现我所期望的业绩提升(我在3个小时后取消了这个过程.)。经过更多的研究后,我偶然发现了一个名为"osm2mssql“(https://archive.codeplex.com/?p=osm2mssql)的老项目。我使用了代码的一小部分,它直接从osm.pbf文件中读取数据,并将其修改为我的用例(→,用于从方式中提取地址数据)。我确实使用FastMember为Datatable编写了一个IEnumerable<Address>,但是我不需要OSM和它们所拥有的任何额外的依赖项。非常感谢FastMember的建议。我一定会在今后的项目中牢记这一图书馆。

对于那些感兴趣的人,我相应地更新了我的Github (https://github.com/Cr3pit0/OSM2Database-Minimal-Reproduction) (尽管我没有彻底测试它,因为我从test转到了真正的交易,这是一个Web )。

我很确定它可以被进一步优化,但我认为我现在并不在乎。我想,对于一个每月可能会调用一次来更新整个数据库的方法来说,12分钟是可以的。现在,我可以继续操作对Autocomplete的查询。

所以非常感谢谁写了"osm2mssql“。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59680569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档