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

时间:2012-02-05 20:58:13

标签: linq-to-sql sql-server-ce openstreetmap sqlbulkcopy

注意:虽然我定位的是Windows Phone 7,但除了尺寸限制外,它不会引入任何内容。

在尝试为Windows Phone 7编写GPS /路由/地图应用程序时,我尝试使用OpenStreetMap进行此操作,并希望将我的数据存储在{{3}中我SQL Server Compact Edition上的数据库。这给了我很多麻烦所以我无法理解正确的方法......

这是我的进步:

  1. 我已下载Windows Phone 7,其中包含Belgium.osm.pbf中所有比利时OSM数据。

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

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

  2. 使用Marc Gravell的PBF format,我现在编写了一个解析器,它给了我所有的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(),但是当SubmitChanges()插入每行时,显然会慢下来。然后我去尝试SqlBulkCopy,这显然不适用于SQL Server Compact Edition,这让我最终得到protobuf-net,这似乎更快但仍然很慢。

  6. 我遇到这个问题时遇到两个问题:

    1. 现在还很慢。

    2. 结果大小要大很多倍。请注意Belgium.osm.pbf只有大约80 MB。然而.sdf似乎是~592 MB,我能做些什么吗?

    3. 所以,这是我的问题:

      1. 我哪里完全出错了?我该怎么做呢?

        我发现很难正确处理80 MB文件真的很奇怪。另请注意,我现在正在计算机上进行所有这些计算,一旦在计算机上运行公平,我将在Windows Phone 7上进行尝试。

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

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

      3. 增加计算机的大小是否有意义,主要是编写转换器,然后将~592 MB .sdf数据库文件发送到手机? < / p>

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

      4. 请注意我专注于问题1 ,其他问题仅仅是解决方案,如果这显示是不可能的,我只是错过了一些可以使这个流畅但我没有想法...

1 个答案:

答案 0 :(得分:1)

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