如何以索引方式有效存储所有 OpenStreetMap 数据?

发布于 2025-01-02 21:09:49 字数 3644 浏览 3 评论 0 原文

注意:虽然我的目标是 Windows Phone 7,但除了大小限制之外,它没有引入任何内容。

在尝试为 Windows Phone 7 编写 GPS/路由/地图应用程序时,我尝试使用 OpenStreetMap< /a> 为此,我希望将数据存储在 SQL Server 中精简版数据库在我的 Windows Phone 7 上。这给我带来了很多麻烦,所以我不知道正确的方法是什么...

这是我的进度:

  1. 我已经下载了Belgium.osm.pbf,其中包含 PBF 格式

    请注意,比利时并不是那么大,这是我居住的国家,所以这似乎是一个好的开始。

    如果我的数据库接近该 PBF 文件的大小,那就太好了,因为它只有 80 MB...

  2. 使用 Marc Gravell 的 protobuf-net,我现在已经编写了一个解析器,它为我提供了所有 OSM 数据。

  3. 第一次尝试时,我尝试将其全部加载到内存中,但这对于我的 Windows Phone 7 来说似乎太大了,因为它导致大小 > 512 MB。然后我的想法是,我需要一个数据库来存储这些信息,因此将其存储在 SQL Server Compact Edition sdf 文件中似乎是合乎逻辑的。

  4. 因此,我在 LINQ to SQL 中创建了以下 DataContext 和表:

    公共类 RoutingContext : DataContext
    {
        公共路由上下文()
    #如果WINDOWS_PHONE
            : base("数据源 = 'isostore:/RoutingDB.sdf'; 最大数据库大小 = 1024; 最大缓冲区大小 = 65536")
    #别的
            : base("数据源 = './RoutingDB.sdf'; 最大数据库大小 = 1024; 最大缓冲区大小 = 65536")
    #endif
        {
    
        }
    
        公共表<节点>节点;
        公共表<路>道路;
        公共表道路节点;
        公共表节点属性;
        公共表道路地产;
        公共表弦乐;
    }
    
    [桌子]
    公共类节点
    {
        [列(IsPrimaryKey = true)]
        公共 int Id { 得到;放; }
    
        [柱子()]
        公共 int Lon { 得到;放; }
    
        [柱子()]
        公共 int 纬度 { 得到;放; }
    }
    
    [桌子]
    公共类 NodeProperty
    {
        [柱子()]
        公共 int NodeId { 获取;放; }
    
        [列(DbType = "NVarChar(255) NOT NULL")]
        公共 int 密钥 { 获取;放; }
    
        [列(DbType = "NVarChar(255) NOT NULL")]
        公共 int 值 { 获取;放; }
    }
    
    [桌子]
    公共类道路财产
    {
        [柱子()]
        公共 int RoadId { 获取;放; }
    
        [列(DbType = "NVarChar(255) NOT NULL")]
        公共 int 密钥 { 获取;放; }
    
        [列(DbType = "NVarChar(255) NOT NULL")]
        公共 int 值 { 获取;放; }
    }
    
    [桌子]
    公共课路
    {
        [列(IsPrimaryKey = true)]
        公共 int Id { 得到;放; }
    }
    
    [桌子]
    公开课RoadNode
    {
        [柱子()]
        公共 int RoadId { 获取;放; }
    
        [柱子()]
        公共 int NodeId { 获取;放; }
    }
    
    [桌子]
    公共类 StringData
    {
        [列(IsPrimaryKey = true)]
        公共 int Id { 得到;放; }
    
        [列(DbType = "NVarChar(255) NOT NULL")]
        公共字符串字符串{获取;放; }
    }
    
  5. 首先,我使用 SubmitChanges() 执行 InsertOnSubmitTour() code> 时不时地,但这显然是很慢的,因为 SubmitChanges() 逐行插入。然后我尝试了 SqlBulkCopy ,它显然不适用于 SQL Server Compact Edition,这让我最终得到 SqlCeBulkCopy 看起来更快,但仍然很慢。

我使用此解决方案时遇到两个问题:

  1. 它仍然很慢。

  2. 生成的大小要大很多倍。请注意,Belgium.osm.pbf 只有约 80 MB。然而,.sdf 似乎约为 592 MB,对此我能做些什么吗?

所以,这是我的问题:

  1. 我哪里完全错了?我该怎么办?

    我觉得很奇怪,正确处理 80 MB 的文件是如此困难。另请注意,我目前正在计算机上进行所有这些计算,一旦在计算机上运行正常,我将在 Windows Phone 7 上尝试。

  2. 如果确实没有方便的 LINQ 解决方案,生成索引 PBF 有意义吗?

    ,这需要我重新发明数据库已经可以提供给我的东西。

  3. 增加计算机的大小(本质上是编写一个转换器,然后将 ~592 MB .sdf 数据库文件发送到我的手机)是否有意义?

    这似乎是选项 1 和 2 之间的最后手段,但这并不能让应用程序上传到 MarketPlace,因为必须提前在计算机上进行转换,然后以某种方式将其上传到 MarketPlace,这非常令人讨厌。

请注意,我专注于问题 1,其他问题只是解决方案(如果这被证明是不可能的),我只是错过了一些可以让这个问题变得流畅的东西,但我不知道。 。

Note: While I target Windows Phone 7, it doesn't introduce anything besides a size restriction.

In an attempt to write a GPS / Routing / Map application for the Windows Phone 7, I'm trying to attempt to use OpenStreetMap for this and I want to get my data stored in a SQL Server Compact Edition database on my Windows Phone 7. This is giving me a lot of trouble so I'm getting clueless what the right way is...

Here is my progress:

  1. I've downloaded Belgium.osm.pbf, which contains all the Belgium OSM data in PBF format.

    Note that Belgium isn't that large, it's the country I live in so it seems as a good start.

    It would be nice if my database were near the size of that PBF file, because it is only 80 MB...

  2. Using Marc Gravell's protobuf-net, I now have written a parser which is giving me all the OSM data.

  3. On a first attempt I tried to just load it all in memory but that seems to be too big for my Windows Phone 7, as it results in a size > 512 MB. Then the idea was that I needed a database to store this information in, so it seems logic to store this in a SQL Server Compact Edition sdf file.

  4. Hence, I created the following DataContext and Tables in LINQ to SQL:

    public class RoutingContext : DataContext
    {
        public RoutingContext()
    #if WINDOWS_PHONE
            : base("Data Source = 'isostore:/RoutingDB.sdf'; Max Database Size = 1024; Max Buffer Size = 65536")
    #else
            : base("Data Source = './RoutingDB.sdf'; Max Database Size = 1024; Max Buffer Size = 65536")
    #endif
        {
    
        }
    
        public Table<Node> Nodes;
        public Table<Road> Roads;
        public Table<RoadNode> RoadNodes;
        public Table<NodeProperty> NodeProperties;
        public Table<RoadProperty> RoadProperties;
        public Table<StringData> Strings;
    }
    
    [Table]
    public class Node
    {
        [Column(IsPrimaryKey = true)]
        public int Id { get; set; }
    
        [Column()]
        public int Lon { get; set; }
    
        [Column()]
        public int Lat { get; set; }
    }
    
    [Table]
    public class NodeProperty
    {
        [Column()]
        public int NodeId { get; set; }
    
        [Column(DbType = "NVarChar(255) NOT NULL")]
        public int Key { get; set; }
    
        [Column(DbType = "NVarChar(255) NOT NULL")]
        public int Value { get; set; }
    }
    
    [Table]
    public class RoadProperty
    {
        [Column()]
        public int RoadId { get; set; }
    
        [Column(DbType = "NVarChar(255) NOT NULL")]
        public int Key { get; set; }
    
        [Column(DbType = "NVarChar(255) NOT NULL")]
        public int Value { get; set; }
    }
    
    [Table]
    public class Road
    {
        [Column(IsPrimaryKey = true)]
        public int Id { get; set; }
    }
    
    [Table]
    public class RoadNode
    {
        [Column()]
        public int RoadId { get; set; }
    
        [Column()]
        public int NodeId { get; set; }
    }
    
    [Table]
    public class StringData
    {
        [Column(IsPrimaryKey = true)]
        public int Id { get; set; }
    
        [Column(DbType = "NVarChar(255) NOT NULL")]
        public String String { get; set; }
    }
    
  5. First I went on the InsertOnSubmitTour() with a SubmitChanges() every now and then, but that apparently is way to slow as SubmitChanges() inserts row-per-row. So then I went to try SqlBulkCopy which apparently doesn't work for SQL Server Compact Edition, this made me end up with SqlCeBulkCopy which seems to be faster but still is slow.

There are two problems that I am experiencing with this solution:

  1. It is still pretty slow.

  2. The resulting size is many times bigger. Please note that Belgium.osm.pbf is only ~80 MB. The .sdf however appears to be ~592 MB, is there anything I can do about this?

So, here are my questions:

  1. Where did I completely go wrong? What should I do instead?

    I find it really weird that it's so hard to process a 80 MB file properly. Please also note that I'm doing all this computing on my computer at the moment and once it runs fair on the computer I'll try it on the Windows Phone 7.

  2. If there really is no handy LINQ solution, would it make sense to produce an indexed PBF?

    This however requires me to reinvent what a database could already provide to me.

  3. Would it make sense to increase the size on my computer, essentially making a writing a converter, then sent the ~592 MB .sdf database file to my phone?

    This seems to be a last resort that's in between option 1 and 2, but that doesn't make the application upload-able to MarketPlace as it's quite nasty to have to convert on the computer in advance and then somehow get it onto the phone.

Please note that I focus on question 1 and that the other questions are merely solutions if that is shown to be impossible, I'm just missing something that would make this go fluent but I have no idea...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

葮薆情 2025-01-09 21:09:50

为此使用数据库是有意义的。大小可能是由于 pbf 文件的紧凑性所致,同时请记住 SQL CE 中的所有数据都是 unicode。你的问题不清楚——什么是慢?另外,您可以尝试在导入后压缩数据库文件,它可能会稍微缩小文件。根据最终的大小,您的 .xap 对于 MarketPlace 来说可能仍然足够小。 (因为 .xap 也压缩 sdf 文件)

It makes sense to use a database for this. The size may be due to the compactness of the pbf file, also keep in mind that all data in SQL CE is unicode. Your question is unclear - what is slow? Also, you can try to Compact the database file after the import, it may shrink the file a bit. Depending on the resulting size, your .xap may still be small enough for MarketPlace. (As the .xap zips the sdf file as well)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文