注意:虽然我的目标是Windows Phone 7,但除了大小限制之外,它没有引入任何内容。
在尝试为Windows Phone 7编写GPS/Routing/Map应用程序时,我正尝试为此使用OpenStreetMap,我想将我的数据存储在Windows Phone 7上的SQL Server Compact Edition数据库中。这给我带来了很多麻烦,所以我不知道什么是正确的方法…
以下是我的进展:
-
我已经下载了
Belgium.osm.pbf
,它包含了PBF格式的所有比利时OSM数据。请注意,比利时并没有那么大,它是我居住的国家,所以这似乎是一个良好的开端。
如果我的数据库接近PBF文件的大小,那就太好了,因为它只有80 MB。。。
-
使用MarcGravell的protobuf-net,我现在已经编写了一个解析器,它为我提供了所有的OSM数据。
-
在第一次尝试时,我试图将其全部加载到内存中,但这对我的Windows Phone 7来说似乎太大了,因为它导致大小>512 MB。当时的想法是,我需要一个数据库来存储这些信息,所以将其存储在SQL Server Compact Edition
sdf
文件中似乎是合乎逻辑的。 -
因此,我在LINQ to SQL中创建了以下DataContext和表:
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; } }
-
首先,我不时地使用
SubmitChanges()
来处理InsertOnSubmitTour()
,但这显然是一种缓慢的方式,因为SubmitChanges()
每行插入一行。所以我尝试了SqlBulkCopy
,它显然不适用于SQL Server Compact Edition,这让我最终使用了SqlCeBulkCopy,它看起来更快,但仍然很慢。
这个解决方案有两个问题:
-
它仍然很慢
-
生成的大小要大很多倍请注意,
Belgium.osm.pbf
只有~80 MB。然而,.sdf
似乎是~592 MB,对此我能做些什么吗?
因此,以下是我的问题:
-
我哪里完全错了?我该怎么办
我觉得很奇怪,很难正确处理一个80 MB的文件。还请注意,我现在正在我的电脑上进行所有这些计算,一旦它在电脑上运行正常,我会在Windows Phone 7上尝试。
-
如果真的没有方便的LINQ解决方案,那么生成索引PBF有意义吗
然而,这需要我重新发明数据库已经可以提供给我的东西
-
增加我电脑的大小,实质上是编写一个转换器,然后将~592 MB的
.sdf
数据库文件发送到我的手机,这有意义吗这似乎是介于选项1和选项2之间的最后手段,但这并不能使应用程序上传到MarketPlace,因为必须提前在计算机上进行转换,然后以某种方式将其上传到手机上,这是非常令人讨厌的。
请注意,我专注于问题1,其他问题只是解决方案,如果这被证明是不可能的,我只是错过了一些可以让它变得流畅的东西,但我不知道。。。
为此使用数据库是有意义的。大小可能是由于pbf文件的紧凑性,还要记住SQL CE中的所有数据都是unicode。你的问题不清楚——什么是慢?此外,您可以尝试在导入后压缩数据库文件,这可能会使文件缩小一点。根据产生的大小,您的.xap可能仍然足够小,适合MarketPlace。(由于.xap也压缩了sdf文件)