среда, 29 января 2014 г.

работа с openstreetmaps в оффлайне на Windows 7

Итак, не забыть бы чего.
Сначала качаем планету в формате osm.pbf (на данный момент 22Гб), если ссылка недоступна или не вызывает доверия, просто гуглим planet.osm.pbf.


Далее нам понадобится програмка osmosis, я ставил по вот этой инструкции.
Если в кратце, то качаем архив, распаковываем его куда-нибудь (я распаковал на F:\osmosis), создаем bat-файл в папке с osmosis, в котором прописываем запуск другого бат-файла (

"F:\osmosis\bin\osmosis.bat"), создаем ярлык для новосозданного бата, заходим в свойства ярлыка и перед адресом ресурса пишем cmd /k 

(чтобы окно с командной строкой не закрывалось).

Дальше надо настроить, чтобы java могла использовать больше оперативки (да, она должна быть установлена, Jre), для этого в панели управления - категории - прораммы - java надо зайти в настройки и выставить xmx - вот тут подробнее. Я выставил 3/4 всей оперативки ноута (4гб).

Итак, все готово. Теперь надо вытащить из нашего громадного 22-гигового монстра кусок карты. Я вытащил 4 квадратных градуса широты/долготы (2x2) вокруг СПБ. Больших кусков вытаскивать не стоит, а то будет неудобно, даже этих 4-х я бы сказал много для среднестатистического компа, в след раз буду 2-3 вытаскивать - как раз целый город. И лучше брать побольше долготу и поменьше широту - 1 градус широты больно велик получился во всяком случае для питера..

Что делаем, открываем Bat созданный нами и вводим

bin\osmosis.bat --read-pbf file=planet-140122.osm.pbf --log-progress interval=30 --bounding-box clipIncompleteEntities=true top=60.5700 left=29.1900 bottom=58.5700 right=31.1900 --write-pbf file=sanktpeterburg2.osm.pbf

По мере выполнения еще каждые 30 сек будет видно, что прога реально что-то делает. Сначала nodes вытаскивает, потом ways, потом relations, я вообще не гребу что это все, но это не важно. Конечный файл получился 40Мб.

Когда будет готово (у меня заняло чуть больше часа), надо открыть это добро в программе Maperitive - качаем, разархивируем, запускаем. 

В правом нижнем углу там map sources - отрубаем интернет-карты, жмем file-add map content, открываем только что полученный pbf, открывался минуты 3 у меня, при этом в правом нижнем углу показывает уровень загруженности оперативки, у меня загрузилась где-то на 1.5 гб, если верно помню. 

когда откроется приближаем так, чтобы вошло все, что нужно, но не было серых зон (иначе из них тоже будут делаться картинки - пустая трата места), вводим в командной строке maperitive (снизу)

generate-tiles minzoom=1 maxzoom=19

 - будут генерироваться картинки, генерироваться долго (я сначала сгенерировал с 13 по 16 уровень - не очень долго - может минут 10-40, вообще не помню, теперь вот генерирую 17 - так он очень долго генерируется - уже несколько часов), если хоцца быстро, maxzoom надо сделать ниже.

По объему этих картинок получилось меньше гига когда я с 13 по 16 левел извлекал, с 17 где-то 2 гига похоже выйдет.

Далее качаем openLayers (javascript фреймворк) (плюс надо найти, скачать и кинуть в ту же папку что и OpenLayers.js файл OpenStreetMap.js, создаем html-файл следующего содержания:


<html>
<head>
    <title>OSM Local Tiles</title>
    <link rel="stylesheet" href="style.css" type="text/css" />
    <!-- bring in the OpenLayers javascript library
         (here we bring it from the remote site, but you could
         easily serve up this javascript yourself) -->
    <script src="OpenLayers-2.13.1/OpenLayers.js"></script>
 
    <!-- bring in the OpenStreetMap OpenLayers layers.
         Using this hosted file will make sure we are kept up
         to date with any necessary changes -->
    <script src="OpenLayers-2.13.1/OpenStreetMap.js"></script>
 
    <script type="text/javascript">
// Start position for the map (hardcoded here for simplicity)
        var lat=60;
        var lon=30;
        var zoom=14;
 
        var map; //complex object of type OpenLayers.Map
 
        //Initialise the 'map' object
        function init() {
 
            map = new OpenLayers.Map ("map", {
                controls:[
                    new OpenLayers.Control.Navigation(),
                    new OpenLayers.Control.PanZoomBar(),
                    new OpenLayers.Control.Permalink(),
                    new OpenLayers.Control.ScaleLine({geodesic: true}),
                    new OpenLayers.Control.Permalink('permalink'),
                    new OpenLayers.Control.MousePosition(),                    
                    new OpenLayers.Control.Attribution()],
                maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
                maxResolution: 156543.0339,
                numZoomLevels: 19,
                units: 'm',
                projection: new OpenLayers.Projection("EPSG:900913"),
                displayProjection: new OpenLayers.Projection("EPSG:4326")
            } );
 
            layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
            layerMapnik.setOpacity(0.4);
            map.addLayer(layerMapnik); 
 
            layerCycleMap = new OpenLayers.Layer.OSM.CycleMap("CycleMap");
            layerCycleMap.setOpacity(0.4);
            map.addLayer(layerCycleMap);
 
            // This is the layer that uses the locally stored tiles
            var newLayer = new OpenLayers.Layer.OSM("Local Tiles", "Maperitive/Tiles/${z}/${x}/${y}.png", 
{numZoomLevels: 19, alpha: true, isBaseLayer: false});
            map.addLayer(newLayer);
   // This is the end of the layer
 
              var switcherControl = new OpenLayers.Control.LayerSwitcher();
             map.addControl(switcherControl);
             switcherControl.maximizeControl();
 
            if( ! map.getCenter() ){
                var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), 
map.getProjectionObject());
                map.setCenter (lonLat, zoom);
            }
        }
 
    </script>
</head>
 
<!-- body.onload is called once the page is loaded (call the 'init' function) -->
<body onload="init();">
 
    <!-- define a DIV into which the map will appear. Make it take up the whole window -->
    <div style="width:100%; height:100%" id="map"></div>
 
</body>
 
</html>

Надо задать 

  var lat=60;
  var lon=30;
  var zoom=14;

- это изначальные параметры, не перепутать главное ширину и долготу.

потом

numZoomLevels: 19 - это устанавливает, как я понял максимальное приближение для онлайн карт

и ("Local Tiles", "Maperitive/Tiles/${z}/${x}/${y}.png", {numZoomLevels: 19 - это для локальных.

Я онлйн карты отключил в гребеням, отредактировав файлы OpenLayer.js и OpenStreetMap.js - заменил все ссылки на tiles.openstreetmaps... на Maperitive/Tiles/...

Сохраняем, зпускаем, карта города готова. Но никакого поиска и никаких маршрутов. Возможно буду изучать тему дальше. 

Но в кайф, что целая планета на компе, в каких-то жалких 25 гигах умещается, хоть и такой нудный процесс выкачки данных. 

Bytheway, такую систему использовать надо в длительных безинтернетных путешествиях в особенности по России, если не знаешь координаты города, карта которого нужна, можно использовать оффлайн-википедию, в ней для каждого города есть коодинаты, ну и по площади города рассчитать сколько квадратных градусов нужно - это школьный матан

Комментариев нет:

Отправить комментарий