¿Cómo almaceno eficientemente todos los datos de OpenStreetMap de forma indexada?

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

Pregunta

Nota: Aunque me dirijo a Windows Phone 7, no introduce nada más que una restricción de tamaño.

En un intento por escribir una aplicación de GPS / Enrutamiento / Mapa para Windows Phone 7, estoy tratando de usar OpenStreetMap para esto y quiero que mis datos se almacenen en una base de datos de SQL Server Compact Edition en mi Windows Phone 7 . Esto me está causando muchos problemas, así que no tengo ni idea de cuál es el camino correcto ...

Aquí está mi progreso:

  1. He descargado Belgium.osm.pbf , que contiene todos los datos de OSM de Bélgica en formato PBF .

    Tenga en cuenta que Bélgica no es tan grande, es el país en el que vivo, por lo que parece un buen comienzo.

    Sería bueno si mi base de datos estuviera cerca del tamaño de ese archivo PBF, porque solo tiene 80 MB ...

  2. Usando la protobuf-net de Marc Gravell, ahora he escrito un analizador que me da todos los datos de OSM.

  3. En un primer intento, intenté cargarlo todo en la memoria, pero eso parece ser demasiado grande para mi Windows Phone 7, ya que tiene un tamaño> 512 MB. Entonces, la idea era que necesitaba una base de datos para almacenar esta información, por lo que parece lógico almacenar esto en un archivo sdf SQL Server Compact Edition.

  4. Por lo tanto, creé los siguientes DataContext y Tablas en 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. Primero fui al InsertOnSubmitTour() con un SubmitChanges() vez en cuando, pero aparentemente es una manera de reducir la velocidad cuando SubmitChanges() inserta fila por fila. Entonces fui a probar SqlBulkCopy que aparentemente no funciona para SQL Server Compact Edition, esto me hizo terminar con SqlCeBulkCopy, que parece ser más rápido pero aún es lento.

Hay dos problemas que estoy experimentando con esta solución:

  1. Todavía es bastante lento.

  2. El tamaño resultante es muchas veces más grande. Tenga en cuenta que Belgium.osm.pbf tiene solo ~ 80 MB. .sdf embargo, el .sdf parece ser ~ 592 MB, ¿hay algo que pueda hacer al respecto?

Asi que aqui están mis preguntas:

  1. ¿Dónde me equivoqué completamente? ¿Qué debo hacer en su lugar?

    Me parece realmente extraño que sea tan difícil procesar un archivo de 80 MB correctamente. Tenga en cuenta que estoy haciendo todo este cómputo en mi computadora en este momento y una vez que se ejecute correctamente en la computadora, lo intentaré en Windows Phone 7.

  2. Si realmente no hay una solución LINQ práctica, ¿tendría sentido producir un PBF indexado?

    Sin embargo, esto requiere que reinvente lo que una base de datos ya podría proporcionarme.

  3. ¿Tendría sentido aumentar el tamaño de mi computadora, básicamente hacer un conversor a escritura, y luego enviar el archivo de la base de datos .sdf ~ 592 MB a mi teléfono?

    Este parece ser un último recurso que se encuentra entre las opciones 1 y 2, pero eso no hace que la aplicación se pueda cargar en MarketPlace, ya que es bastante desagradable tener que convertir la computadora por adelantado y luego ponerla en el teléfono.

Tenga en cuenta que me concentro en la pregunta 1 y que las otras preguntas son simplemente soluciones si se demuestra que eso es imposible, solo me falta algo que haría que esto fuera fluido pero no tengo idea ...

Respuesta popular

Tiene sentido usar una base de datos para esto. El tamaño puede deberse a la compacidad del archivo pbf, también tenga en cuenta que todos los datos en SQL CE son Unicode. Tu pregunta no está clara, ¿qué es lento? Además, puede intentar compactar el archivo de base de datos después de la importación, puede reducir el tamaño del archivo un poco. Dependiendo del tamaño resultante, su .xap aún puede ser lo suficientemente pequeño para MarketPlace. (Como el .xap también cierra el archivo sdf)



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué