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

linq-to-sql openstreetmap sqlbulkcopy sql-server-ce

注意:虽然我的目标是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; }
    }
    
  5. 首先我InsertOnSubmitTour()使用SubmitChanges()继续使用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 ,其他问题仅仅是解决方案,如果这显示是不可能的,我只是错过了一些可以使它流利但我不知道......

热门答案

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



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因