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

Tam*_*man 5 sqlbulkcopy openstreetmap sql-server-ce linq-to-sql

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

为了尝试为Windows Phone 7编写GPS /路由/地图应用程序,我正在尝试使用OpenStreetMap,我希望将我的数据存储在Windows Phone 7上的SQL Server Compact Edition数据库中.这给我带来了很多麻烦,所以我正在弄清楚正确的方法是什么......

这是我的进步:

  1. 我已下载Belgium.osm.pbf,其中包含PBF格式的所有比利时OSM数据.

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

    如果我的数据库接近该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和Tables:

    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; }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 首先,我不时地继续InsertOnSubmitTour()使用它SubmitChanges(),但显然是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,因为它必须提前在计算机上进行转换然后以某种方式将其打到手机上是非常讨厌的.

请注意,我专注于问题1,其他问题仅仅是解决方案,如果这显示是不可能的,我只是错过了一些可以使它流利但我不知道......

Eri*_*kEJ 1

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