Генплан посёлка на основе Яндекс api v2 или как соотнести координаты картинки и карты

Генплан посёлка на основе Яндекс api

Цель нашей работы заключается в:

  • Получить карту с нужными нам отметками (отметки уникальные и могут располагаться в разных местах).
  • При наведение на отметку выдаём информацию о ней (номер дома).
  • При нажатии на отметку показывать дополнительное описание (содержимое) отметки.
  • Карта имеет полноценные возможности масштабирования и навигации.


Иногда требуется организовать навигацию по определенной части карты например по местности. Поэтому нам на помощь приходят Яндекс карты, пользовательские слои, управление своими картами. Во многом может показаться, а зачем всё это описывать если у Яндекса есть на это решение. Сразу отвечаю у Яндекса есть на это функция, а на каждую задачу решений нет.

Для работы я использовал:

  • Яндекс API
  • jQuery — так как он был в основном проекте.
  • ПО от Яндекс «Подготовка слоя тайлов»
  • Картинка от дизайнера, желательно не маленькая (мне предоставили 7987px на 3607px этого вполне хватит)
  • Notepad++ и руки


Сразу вид того что мы получили:

Результат работы. Генплан посёлка на основе Яндекс api

Начнём подготовку тайлов:

Ставим точки в каждый крайний угол, и соответствующие координаторы им (я с этим нашёл не стандартное решение. создал полу прозрачные картинку и подложил на карту). Если точки как-то будут не совпадать по пропорциям картинки есть вероятность искажения изображение т.е. подгонят под карту — нам этого не надо!!!

подготовку тайлов

После мучительных расстановок точек сохраняем наши тайлов. В итоги у вас должно выйти что-то наподобие:

результат подготовки тайлов

маленькие нарезки разрешением 256х256 в соответствующих папках для зуммера. Кол-во папок и их нумерация зависит от кол-во зумирование картинки.

Меняем в генерированном файле подключаемые скрипты на:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://api-maps.yandex.ru/2.0/?load=package.standard,package.geoObjects&lang=ru-RU" type="text/javascript"></script>
    <script src="app.js" type="text/javascript"></script>

В нутри тега body оставляем только:
<div id="YMapsID"></div>
<!--ну и сразу добавим наши точки -->
<map id="ImageMapsCom" name="image-maps">
    <a href="/catalog/projects/aleksandrovskij_21186_kvm3/"
       alt="Татьянинский"
       title="ул. Домбасова 1a"
       data-maps="2042,239,2137,331"
       class="hause_items_shows"
       data-info="1310">
        <div class="show-items-info">
            <img src="/images/cms/data/catalog/12.jpg" alt=""><div class="description-house">
            <p class="status"><span>Сотояния:</span><span color="1716">Продан</span></p><p class="plowad"><span>Площадь: </span>5,05</p><p class="stoimost"><span>Стоимость: </span></p></div></div>
    </a>
    <a href="/catalog/projects/aleksandrovskij_21186_kvm3/"
       alt="Татьянинский 265,29 кв.м."
       title="МАГАЗ"
       data-maps="1319,1237,1441,1339"
       class="hause_items_shows"
       data-info="1310">
        <div class="show-items-info">
            <img src="http://adveks.gowhiterabbit.ru/images/cms/data/content/minimarket.png">
        </div>
    </a>
<!--и дальше . . . . -->
</map>


Немножко с индивидуальным стилем карты, подключим наш стиль:
#YMapsID {
 width: 100%;
 height: 100%;
 min-height: 600px;
}
#YMapsID > ymaps {
 background: url("bg.png") repeat scroll 0 0 rgba(0, 0, 0, 0);
}
#YMapsID .ymaps-copyrights-pane,
#YMapsID .ymaps-controls-rightbottom {
 display: none;
}
#YMapsID.hause_items_shows{
 display: none;
}
#YMapsID.show-items-info {
 background: none repeat scroll 0 0 rgba(253, 250, 243, 0.8);
 left: 0;
 padding: 15px;
 top: 0;
 width: 250px;
 z-index: 19;
}


Настройки карты:
var options = {
    tileUrlTemplate: "./%z/tile-%x-%y.png",
    controls: {
        typeControl: true,
        miniMap: false,
        toolBar: true,
        scaleLine: true
    },
    scrollZoomEnabled: true,
    mapCenter: new YMaps.GeoPoint( Долгота , Широта ),
    backgroundMapType: YMaps.MapType.NONE,
    mapZoom: 17,
    isTransparent: true,
    smoothZooming: false,
    layerKey: "my#layer",
    mapType: {
        name: "Генплан",
        textColor: "#000000"
    },
    copyright: "",
    layerMinZoom: 16,
    layerMaxZoom: 20
};


Функция получения дынных из выгруженных

Здесь реализован переход из системы навигации картинки (по пикселам) в системы навигации карты (градусы) т.е. переводим пиксели в градусы.
формула перевода пикселей в градусы
var contentString = new Array();
function strat_masiv() {
    var clo_in=0;
    $('#ImageMapsCom .hause_items_shows').each(function (_index, _label) {
        var blocks = $(_label);
        contentString[clo_in] = new Array();
        var bjects_alt = $(blocks).attr('alt');
        var example = $(blocks).attr('data-maps').split(',');
        var max_x_dpi = 39.05776, // конечный координаты карты
            max_x_px = 7986, // конечный координаты картинки
            min_x_dpi = 39.048469, // начальные координаты карты
            max_y_dpi = 51.74439, // конечный координаты карты
            max_y_px = 3606, // конечный координаты картинки
            min_y_dpi = 51.747;// начальные координаты карты
        contentString[clo_in][0] = $(blocks).attr('title');
        contentString[clo_in][1] = $(blocks).html();
        //Правый Y
        contentString[clo_in][2] = min_y_dpi+((((parseInt(example[1], 10)*100)/max_y_px)*(max_y_dpi-min_y_dpi))/100);
        //Правый X
        contentString[clo_in][3] = min_x_dpi+((((parseInt(example[0], 10)*100)/max_x_px)*(max_x_dpi-min_x_dpi))/100);
        contentString[clo_in][4] = $(blocks).attr('href');
        contentString[clo_in][5] = '';
        //Левый Y
        contentString[clo_in][6] = min_y_dpi+((((parseInt(example[3], 10)*100)/max_y_px)*(max_y_dpi-min_y_dpi))/100);
        //Правый X
        contentString[clo_in][7] = min_x_dpi+((((parseInt(example[2], 10)*100)/max_x_px)*(max_x_dpi-min_x_dpi))/100);
        clo_in++

    });
    console.log('Y='+contentString[0][6]+' x='+contentString[0][7]);
}
    ymaps.ready(function () {
        strat_masiv();

        // Передаем его в конструктор класса TilerConverter и получаем ссылку на карту.
        var myMap = (new TilerConverter(options)).getMap();
        //создаём точки
        for (var i = 0; i < contentString.length; i++) {
            contentString[i][5] = new ymaps.Rectangle([
                [contentString[i][2],contentString[i][3]],
                [contentString[i][6],contentString[i][7]]
            ], {
                balloonContentHeader: contentString[i][0],
                balloonContent: contentString[i][1],
                balloonContentFooter: "<a href='" + contentString[i][4] + "'>подробней</a>",
                hintContent: contentString[i][0]
            }, {
                fillColor: '#7df9ff33',
                fillOpacity: 0.5,
                strokeColor: '#0000FF',
                strokeOpacity: 0.5,
                strokeWidth: 2,
                borderRadius: 6
            });
            myMap.geoObjects.add(contentString[i][5]);
        };
});


После всех настроек, по вашему желанию, чтобы не видеть эти квадратик вокруг домиков ставим:
 fillOpacity: 0,
 strokeOpacity: 0,


Полный файл скриптов
Ссылка на репозиторий!
  • +38
  • 17,7k
  • 5
Поделиться публикацией

Комментарии 5

    +4
    По-моему вашу большую и красивую формулу можно сократить:

    min_x_dpi + ((((N*100)/max_x_px)*(max_x_dpi-min_x_dpi))/100)
    до
    min_x_dpi + (N/max_x_px)*(max_x_dpi-min_x_dpi)
    или до
    min_x_dpi + N * (max_x_dpi-min_x_dpi) / max_x_px
      0
      спасибо большое. Как-то упустил.
      +3
      Задача, которую Вы описали, называется географической привязкой.
      Легко делается в специализованом софте, например, в открытом QGIS. Там ещё есть разные формулы и разные варианты привязки.

      Останется только как-то выгрузить это всё в TMS.
      • НЛО прилетело и опубликовало эту надпись здесь
          0
          Прикольно, дайте ссылочку на сайт, если он готов (и открыт) ;)

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое