Как эффективно хранить все данные OpenStreetMap в индексированном виде? - PullRequest
5 голосов
/ 06 февраля 2012

Примечание: Хотя я нацелился на Windows Phone 7, он не вводит ничего, кроме ограничения по размеру.

В попытке написать приложение GPS / Маршрутизация / Карта для WindowsТелефон 7, я пытаюсь использовать для этого OpenStreetMap и хочу сохранить свои данные в базе данных SQL Server Compact Edition на моей Windows Phone 7 .Это доставляет мне много хлопот, поэтому я не понимаю, каков правильный путь ...

Вот мой прогресс:

  1. Я скачал Belgium.osm.pbf, который содержит все данные OSM Бельгии в формате PBF .

    Обратите внимание, что Бельгия не такая большая, это страна, в которой я живу, так что кажетсякак хорошее начало.

    Было бы неплохо, если бы моя база данных была размером с этот файл PBF, потому что она всего 80 МБ ...

  2. Использование Marc protobuf-net от Gravell, теперь я написал парсер, который дает мне все данные OSM.

  3. С первой попытки я попытался просто загрузить все это впамяти, но она кажется слишком большой для моего Windows Phone 7, так как ее размер превышает 512 МБ.Тогда идея состояла в том, что мне нужна база данных для хранения этой информации, поэтому логично хранить ее в файле SQL Server Compact Edition sdf.

  4. Следовательно, я создалследующие DataContext и таблицы в 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. Сначала я время от времени использовал InsertOnSubmitTour() с SubmitChanges(), но это, очевидно, способ замедлитьSubmitChanges() вставляет строку за строкой.Затем я попробовал SqlBulkCopy, который, по-видимому, не работает для SQL Server Compact Edition, в результате я получил SqlCeBulkCopy , который кажется более быстрым, но все еще медленным.

С этим решением я сталкиваюсь с двумя проблемами:

  1. Это все еще довольно медленно.

  2. Полученный размер во много раз больше. Обратите внимание, что Belgium.osm.pbf составляет всего ~ 80 МБ.Тем не менее, .sdf составляет ~ 592 МБ. Могу ли я что-нибудь с этим сделать?

Итак, вот мои вопросы:

  1. Где я полностью ошибся?Что мне делать вместо этого?

    Мне действительно странно, что так сложно правильно обработать файл размером 80 МБ.Также обратите внимание, что в данный момент я выполняю все эти вычисления на своем компьютере, и как только он будет работать на компьютере, я попробую его на Windows Phone 7.

  2. Если на самом деле нет удобного решения LINQ, имеет ли смысл производить индексированную PBF?

    Однако для этого необходимо заново изобрести то, что база данных уже может предоставить мне.

  3. Имеет ли смысл увеличить размер моего компьютера, по сути сделать запись конвертера, а затем отправить файл базы данных ~ 592 МБ .sdf на мой телефон?

    Кажется, это последнее средство, которое находится между вариантами 1 и 2, но это не делает возможным загрузку приложения в MarketPlace, так как довольно неприятно заранее конвертировать на компьютере, а затем каким-то образом передавать его нател.

Обратите внимание, что Я сосредоточен на вопросе 1 , и что другие вопросы являются просто решениями, если это невозможно, я просто что-то упускаюэто сделало бы это беглым, но я понятия не имею ...

1 Ответ

1 голос
/ 06 февраля 2012

Для этого имеет смысл использовать базу данных.Размер может быть из-за компактности файла pbf, также имейте в виду, что все данные в SQL CE являются UnicodeВаш вопрос неясен - что медленно?Кроме того, вы можете попробовать сжать файл базы данных после импорта, это может немного уменьшить файл.В зависимости от полученного размера ваш .xap может быть достаточно маленьким для MarketPlace.(Поскольку .xap также архивирует файл sdf)

...