[YandexMaps2] Собственный конструктор карт, работа с mFilter2


Новая версия полностью переработана несколько раз, написан конструктор карт с нуля, продумана работа с mFilter2.

Преимущества перед подобными компонентами

  • Новая версия API карт, которая поддерживается командой Яндекса
  • Работа с mFilter2 из коробки при небольшой настройке компонента в 3 шага
  • Конструктор карты в бекенде отображается в ресурсах, товарах, тикетах, пользователях
  • Принцип работы похож на UserFiles, что позволяет внедрить конструктор карт в любое место админки, с небольшими знаниями ExtJS. Так, к примеру, я прицепил UserFiles к своему кастомному объекту, без правки исходника.

Конструктор карт

Так выглядит конструктор карты в бекенде при редактировании ресурса:


Вся основная работа компонента заключена в конструкторе карт. Любая карта начинается отсюда.
Конструктор поддерживает 4 типа объектов:
  1. Точки, метки
  2. Ломаные линии
  3. Многоугольники
  4. Круги
Важной особенностью использования конструктора карт в бекенде при редактировании ресурсов/пользователей является то, что после всех изменений, необходимо сохранить объект ресурса/пользователя. Иначе изменения на карте применены не будут!

Библиотека конструктора для Яндекс Карт писалась мной с нуля и, вскоре, есть планы выложить ее в открытый доступ для общего пользования разработчиками.

Работа с mFilter2

Работа фильтрации объектов на карте при помощи mFilter2 продумана из коробки и реализуется в три шага:

Шаг 1

В нужном месте страницы вызываем mFilter2 со следующими параметрами:
{'!mFilter2' | snippet : [
    'parents' => $_modx->resource['id'],
    'limit' => 0,
    'outputSeparator' => ',',
    'filters' => '
        tv|symbol,
    ',
]}
Конечно, параметр &filters у вас должен быть свой, со своими полями.

Шаг 2

Чанк tpl.mFilter2.outer будет выглядеть примерно так:
<div class="row msearch2" id="mse2_mfilter">
    <div class="span3 col-md-3">
        <form action="[[~[[*id]]]]" method="post" id="mse2_filters">
            <div>
                [[+filters]]
            </div>
            [[+filters:isnot=``:then=`
                <button type="reset" class="btn btn-default hidden">[[%mse2_reset]]</button>
                <button type="submit" class="btn btn-success pull-right hidden">[[%mse2_submit]]</button>
                <div class="clearfix"></div>
            `]]
        </form>
    </div>

    <div class="span9 col-md-9">
        {'!YandexMaps2' | snippet : [
            'objects' => $results,
            'mode' => 'mfilter2',
        ]}
    </div>
</div>

Шаг 3

Чанк tpl.mSearch2.row должен выглядеть так:
{'!YandexMaps2' | snippet : [
    'parent' => $id,
    'scripts' => false,
    'tpl' => '@INLINE {($objects | toJSON) | replace : "[" : "[ "}',
]}


Сниппет YandexMaps2

Основной сниппет компонента, который реализует вывод карты на фронте.

Параметры














НазваниеПо умолчанию Описание
parent 0Идентификатор родителя. class Класс объекта. listdefaultИмя списка. К нему будет привязана карта. mapym2mapID блока с картой. center[55.72, 37.64]Центральные координаты карты. zoom10Приближение карты. objects Массив объектов карты. Если указан, выборка объектов из базы производиться не будет. modedefaultРежим сниппета. Варианты: default, mfilter2 scripts1Нужно ли подключать скрипты карты. jquery1Нужно ли подключать jQuery. tpltpl.YandexMaps2Чанк вывода карты.

Примеры

Все объекты класса modDocument
{'!YandexMaps2' | snippet : [
    'class' => 'modDocument',
]}

Все объекты класса msProduct
{'!YandexMaps2' | snippet : [
    'class' => 'msProduct',
]}

Все объекты пользователей
{'!YandexMaps2' | snippet : [
    'class' => 'modUser',
    'map' => 'ym2map-users',
]}


Планы на будущее

В следующих версиях компонента планируется реализовать:
— Вывод конструктора карт на фронте,
— Поддержка кастомных иконок для меток.

Демо сайт

Компонент в Modstore

Павел Гвоздь
21 ноября 2017, 19:02
modx.pro
6
4 500
+13
Поблагодарить автора Отправить деньги

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

Евгений Шеронов
22 ноября 2017, 09:37
0
Павел, а чисто теоретически, с компонентом реализуем такой функционал?
1) Есть объекты в городе, у каждого своя точка;
2) Человек на карте выбирает произвольную область;
3) Через mFilter2 показываем удовлетворяющие этой области объекты.

В целом это вопрос наверно по библиотеке, есть ли там функционал определения вхождения точек в произвольную область?
    Павел Гвоздь
    22 ноября 2017, 10:10
    0
    Теоретически — да. На практике надо смотреть, чего не хватает и допиливать.

    2) Человек на карте выбирает произвольную область;
    Как будет происходить выбор области — не понятно.

    В целом это вопрос наверно по библиотеке, есть ли там функционал определения вхождения точек в произвольную область?
    На данный момент нет такого функционала. Однако, дописать такое реально. Другое дело, что необходимо знать, что дописывать и будет ли на это время…
    Алексей Шумаев
    22 ноября 2017, 09:59
    0
    404 по ссылке на магазин
      Павел Гвоздь
      22 ноября 2017, 10:11
      0
      Модерируем… можете пока демку потыкать)
      Stan Ezersky
      22 ноября 2017, 14:56
      0
      А демка работает?
      Что-то ничего не происходит.
        Павел Гвоздь
        22 ноября 2017, 16:06
        0
        У меня работает и происходит.
          Stan Ezersky
          22 ноября 2017, 16:08
          0
          Страница с фильтрами и всё.

            Павел Гвоздь
            22 ноября 2017, 16:11
            0
            Страница с фильтрами, картой и функционалом.
              Stan Ezersky
              22 ноября 2017, 16:14
              0
              Последний Firefox не показывает

              В Chrome увидел
                Павел Гвоздь
                22 ноября 2017, 16:18
                0
                Вот FireFox:
                  Stan Ezersky
                  22 ноября 2017, 16:29
                  0
                  В MacOS у меня тоже показывает, а на виндах не работает



                  Под виндами

                    Павел Гвоздь
                    22 ноября 2017, 16:38
                    0
                    Может все таки это у тебя что-то не так?..
                    Вот FireFox на винде:
                      Stan Ezersky
                      22 ноября 2017, 16:40
                      0
                      Обнови Firefox до последней версии.

                      У товарища тоже не отображается ничего в новом FF
                        Дмитрий Суворов
                        22 ноября 2017, 19:01
                        +1
                        у меня последней версии FF на винде и все работает четко: prntscr.com/hdu76m
                          Дмитрий Суворов
                          22 ноября 2017, 19:03
                          +2
                          может у вас с товарищем что-то бьет какое-нибудь расширение, блокирующее рекламу?
                            Stan Ezersky
                            24 ноября 2017, 12:45
                            0
                            Отключали, результата нет всё-равно.

                            Спасибо, буду знать, что проблема локальная
        Radj
        23 ноября 2017, 11:31
        0
        Компонент не нашел в Modstore, как можно данный компонент установить? prntscr.com/he4hzd
          Anton
          24 ноября 2017, 10:47
          +1
          Выше писали уже, что на модерации еще находится. Т.е через пару дней появится в репозитории.
            Radj
            24 ноября 2017, 12:29
            0
            Не заметил, Спасибо!
              vrm13
              20 декабря 2017, 10:46
              0
              Доброго дня! Подскажите, получиться вывести все объекты ранее добавленные на yandexmaps с использованием yandexmaps2?
              У меня сейчас около 350 ресурсов с координатами, у каждого выводится своя метка и собраны разные общие карты. Очень проблематично будет по новой прописывать метки, но новые возможности будут действительно полезны
                Павел Гвоздь
                20 декабря 2017, 12:09
                0
                Увы, версии не совместимы.
                  vrm13
                  20 декабря 2017, 12:17
                  0
                  спасибо, понял. Пока значит повременим с приобретением компонента, но когда будет время всё-равно перейдём на yandexmaps2, так что спасибо за работу.
                Максим Кузнецов
                08 января 2018, 17:51
                0
                Можно ли отключать/подключать вкладку штатными средствами для конкретных шаблонов?
                UDAV
                28 февраля 2018, 10:34
                -1
                Перестал работать модуль -(… я про первую версию
                  Дмитрий
                  22 мая 2018, 11:59
                  0
                  Всем привет!
                  есть вопрос по yandexmaps2, Есть n-количество объектов, с метками и полигонами, возможно ли вывести на отельных ресурсах только полигоны и только метки?
                  igor
                  03 сентября 2018, 07:39
                  0
                  покажите плиз вызов сниппета с тем чтобы открывался балун по клику на метке
                  а балуне был текст и изображение из tv
                    Кирилл Киселев
                    30 мая 2019, 19:09
                    0
                    А в компоненте есть функция маршрутизации?
                      Павел Гвоздь
                      30 мая 2019, 20:20
                      0
                      В конструкторе? Нет.
                        Кирилл Киселев
                        31 мая 2019, 18:06
                        0
                        На стороне фронтенда. Чтобы геолокация определяла пользователя и строился маршрут до метки.
                          Павел Гвоздь
                          31 мая 2019, 18:30
                          0
                          На стороне фронтенда
                          Нет, такого нет. Только что-то как-то допиливать.

                          Чтобы геолокация
                          Просто так карты не получат координаты юзера, ему надо будет дать на это разрешение.

                          и строился маршрут до метки
                          До какой метки? Во-первых, маршрут строится не до метки, а от точки А до точки Б. Во-вторых, как на бэке эту точку обозначить? Если меткой, то куда на фронте эту метку девать, когда маршрут будет построен? И как вообще эту метку находить на фронте, если, например их у ресурса будет две или больше?

                          Проще сделать какое-то своё решение для вашей задачи.
                            Кирилл Киселев
                            02 июня 2019, 10:02
                            0
                            Просто так карты не получат координаты юзера, ему надо будет дать на это разрешение.
                            Определять местоположение по айпи.

                            Во-вторых, как на бэке эту точку обозначить?
                            Координатами.

                            Если меткой, то куда на фронте эту метку девать, когда маршрут будет построен?
                            Скрывать и показывать маршрут.

                            И как вообще эту метку находить на фронте, если, например их у ресурса будет две или больше?
                            Ближайшую к пользователю.

                            Проще сделать какое-то своё решение для вашей задачи.
                            Я так и подумал, что придётся изучать апи и делать самому.

                            Было бы неплохо увидеть такой функционал в этом дополнении, если вдруг я Вам дал наводку на реализацию.
                              Павел Гвоздь
                              02 июня 2019, 10:26
                              0
                              Ага, а теперь возле каждого ответа решение пожалуйста… Вот эти «скрывать и показывать», «ближайшую к пользователю» и тд, так и заставляют дать ответ вроде: Бери и делай.
                              Если вам показалось, что я этого не понимаю, этих банальных ответов, то вам показалось. Вопрос здесь не в том, что надо сделать, а как это сделать.

                              И к слову, по айпи вычислить местоположение юзера? Ну-ка ну-ка, по-подробнее и с примерами.
                                Кирилл Киселев
                                02 июня 2019, 11:01
                                0
                                Ага, а теперь возле каждого ответа решение пожалуйста…
                                Если Вам действительно это интересно, я могу сделать отдельную ветку, если есть опенсорс проект, а так это будет бесполезная переписка.
                                  Павел Гвоздь
                                  02 июня 2019, 12:09
                                  0
                                  Интересно, давайте! И не мне одному интересно будет.
                                    Кирилл Киселев
                                    16 июня 2019, 17:29
                                    0
                                    Решение готово. Решил, что если скинетесь в общую сумму 1500р., то выложу решение ;)
                      Denis
                      04 июля 2019, 12:20
                      0
                      Приветствую.
                      А есть ли у компонента ограничение на число объектов на карте?
                      в mFilter2 выводятся около 500 объектов, YandexMaps2 же выводит на карту только примерно 100 объектов.
                      И как включить кластеризацию? Не нашел такой параметр в настройках.
                        Павел Гвоздь
                        04 июля 2019, 18:39
                        0
                        А есть ли у компонента ограничение на число объектов на карте?
                        Нет, ограничений нет. На всякий указал лимит явно, обновляйтесь.

                        И как включить кластеризацию? Не нашел такой параметр в настройках.
                        Нет такого. Можете в коде default.js добавить самостоятельно.

                        P.S. Вопросы по приобретённому компоненту задавайте в техподдержку Modstore.
                          Павел Романов
                          17 июля 2019, 13:55
                          0
                          Аналогичная история с limit.
                          Сайт: sportbook.su/
                          mFilter2 выводит 678 объектов, но при открытии страницы их на карте явно меньше.
                          Причем, если выбрать фильтр, к примеру, sportbook.su/?city=Балашиха, то пропавшие выводятся.
                          При сбросе фильтров снова выводится примерно 100.
                          С limit экспериментировал — не помогает.
                            Павел Романов
                            17 июля 2019, 16:30
                            +1
                            Сам себе отвечу — у одного объекта не были указаны координаты ).
                            Сделал проверку при выводе mFilter2 на наличие значений в geometry, теперь все ОК.
                        Sergey
                        27 января 2021, 03:00
                        0
                        Здравствуйте, скажите пожалуйста, можно ли как то получить координаты точки на карте для документа? Видно что в бд записывается json часть кода
                        "geometry":[48.54047113739968,39.260353189639424]
                        чтобы попробовать относительно этой точки вывести ближайших несколько точек(документов) или есть может другие варианты?
                          Algirdas
                          21 августа 2021, 23:39
                          0
                          Ребята, кто купил компонент, техподдержка отвечает? А то что-то в этом треде давно автора не было. Перед покупкой хотелось бы пару вопросов задать, а то сейчас тестирую и пара вещей не работает, хотя должна вроде как.
                            Павел Гвоздь
                            22 августа 2021, 04:39
                            +1
                            Что не работает?
                              Algirdas
                              22 августа 2021, 11:49
                              0
                              Развернул тестовый стенд на modhost. Из шаблона вызываю вот так:
                              {'!mFilter2' | snippet : [
                                  'parents' => 5,
                                  'limit' => 0,
                                  'tplOuter' => 'tpl.mFilter2.outer.Map',
                                  'tpl' => 'tpl.mSearch2.row.Map'
                                  'filters' => '
                                      tv|system,
                                  ',
                                  'tplFilter.outer.tv|system' => 'tpl.mFilter2.filter.select',
                                  'tplFilter.row.tv|system' => 'tpl.mFilter2.filter.option',
                              ]}
                              tpl.mFilter2.outer.Map

                              <div class="row msearch2" id="mse2_mfilter">
                                  <div class="span3 col-md-4">
                                      <form action="[[~[[*id]]]]" method="post" id="mse2_filters">
                                          <div>
                                              [[+filters]]
                                          </div>
                                          [[+filters:isnot=``:then=`
                                              {*<button type="reset" class="btn btn-default hidden">[[%mse2_reset]]</button> *}
                                              <button type="submit" class="btn btn-success pull-right hidden">[[%mse2_submit]]</button>
                                              <div class="clearfix"></div>
                                          `]]
                                      </form>
                                  </div>
                              
                                  <div class="span9 col-md-12">
                                      {'!YandexMaps2' | snippet : [
                                          'mode' => 'mfilter2',
                                          'class' => 'modDocument',
                                          'objectsInScope' => 1,
                                          'defaultBalloonContent' => '<div><b>pagetitle</b>: {$data.current | resource : "pagetitle"}</div>
                                                                      <div><b>tv</b>: {$data.current | resource : "system"}</div>
                                          ',
                                          'defaultIconContent' => 'test'
                                      ]}
                                      <div id="mse2_results">
                                          {$results}
                                      </div>
                                  </div>
                              </div>
                              tpl.mSearch2.row.Map

                              <div class="mse2-row">
                                  [[+idx]]. <a href="[[+uri]]">[[+pagetitle]]</a>[[+weight]]
                                  [[+intro]]
                              </div>
                              
                              <div class="js-ym2-mse2-objects" style="display:none">{'!YandexMaps2' | snippet : [
                                  'parent' => $id,
                                  'scripts' => false,
                                  'tpl' => '@INLINE {(($objects | toJSON: 9) | replace: "{": "{ ") | replace: "[": "[ "}',
                              ]}</div>
                              
                              <!--msearch2_weight  ([[%mse2_weight]]: [[+weight]])-->
                              <!--msearch2_intro <p>[[+intro]]</p>-->
                              Почему-то не вылазят баллуны, вообще никак. То есть при клике на метку ничего не происходит. Еще не получилось в баллун встроить название ресурса и ссылку на него, как это работает в yandexMaps первой версии. Есть ощущение что в документации отражено далеко не всё, что может компонент. А больше и посмотреть негде (( Очень мало инфы по нему.

                              Еще не понял куда подключать этот код:
                              $(document).ready(function() {
                                  $(document).on('ymOnLoadMap', function(e, ym2, map) {
                                      map.controls
                                          .remove('fullscreenControl') // полный экран
                                          .remove('geolocationControl') // моя геопозиция
                                          .remove('rulerControl') // линейка
                                          .remove('trafficControl') // пробки
                                          .remove('searchControl') // поиск
                                          .remove('typeSelector') // слои
                                          .remove('zoomControl') // масштаб
                                      ;
                                  });
                              });
                              Куда бы я его не подключал, где по моим представлениям он может быть, нигде не сработало. Я не программист, поэтому может откровенную фигню творил ))

                              Пока не включил friendlyURL, ссылки под картой указывали на главную страницу, хотя у вас на демо странице оно вроде как работает и без этого.

                              Вообще меня почти полностью устраивал yandexMaps :)) Только фильтрацию нужную не смог там настроить и с выводом фильтров разобраться )
                                Algirdas
                                22 августа 2021, 12:47
                                0
                                Если просто выводить карту, без фильтров, то всё отлично выводится

                                <div>
                                    {'!YandexMaps2' | snippet : [
                                        'parents' => 5,
                                        'class' => 'modDocument',
                                        'objectsInScope' => 1,
                                        'defaultBalloonContent' => '<div><strong>{$data.parent | resource : "pagetitle"}</strong></div>
                                                                    <div><p><a href="{$data.parent | resource : "uri"}">Подробнее</a></p></div>
                                        ',
                                    ]}
                                </div>
                                С выводом ссылок разобрался, в прошлый раз видимо что-то не то написал там. Но баллуны выводятся только если вызываешь сниппет без фильтров
                                  Algirdas
                                  22 августа 2021, 13:04
                                  0


                                  Вот такие баллуны можно вывести, как в первой версии компонента? Чтобы не по клику, а сразу названия были
                                    Algirdas
                                    22 августа 2021, 13:17
                                    0
                                    С помощью
                                    'defaultIconCaption' => '{$data.parent | resource : "pagetitle"}'
                                    вывел, но можно ли настроить вид, как в первой версии?
                                    Algirdas
                                    22 августа 2021, 13:29
                                    0
                                    Пробовал вставить
                                    <script>
                                    $(document).ready(function() {
                                        $(document).on('ymOnLoadMap', function(e, ym2, map) {
                                            // console.log('ym2', ym2);
                                            // console.log('map', map);
                                            
                                            map.controls
                                                .remove('fullscreenControl')
                                                .remove('geolocationControl')
                                                .remove('rulerControl')
                                                .remove('trafficControl')
                                                .remove('searchControl')
                                                .remove('typeSelector')
                                                .remove('zoomControl')
                                            ;
                                        });
                                    });
                                    </script>
                                    в шаблон, сразу после вызова карты. Но это никак не подействовало, кроме того что стала появляться ошибка в консоли

                                    (index):131 Uncaught ReferenceError: $ is not defined at (index):131 (anonymous) @ (index):131
                                    Algirdas
                                    23 августа 2021, 21:27
                                    0
                                    Павел, можете помочь?
                                      Павел Гвоздь
                                      24 августа 2021, 04:27
                                      0
                                      jQuery подключите. Остальные вопросы в ТП на Модстор, пожалуйста.
                                  Algirdas
                                  05 сентября 2021, 13:42
                                  0
                                  ребят, а кто знает, как вывести один объект на карте с определенным зумом?
                                  Если используешь параметр objectsInScope то параметр zoom не работает, в настройках ym2_zoom тоже нет реакции. Если убираешь objectsInScope то нужно прописывать zoom и center, но как взять координаты центра, кроме как руками прописывать? вызов сниппета с указанием пустого шаблона, чтобы посмотреть плейсхолдеры не прокатывает, всё равно карта выводится.
                                    Павел Гвоздь
                                    06 сентября 2021, 14:26
                                    0
                                    Документацию читайте. joxi.ru/YmEXd3OHB9MEOr
                                      Algirdas
                                      06 сентября 2021, 15:02
                                      0
                                      Да вот читаю. Мне нужно вывести ОДИН объект на карте, на странице (ресурсе) этого объекта.
                                      Согласно документации я могу использовать ЛИБО 1. objectsInScope ЛИБО 2 zoom+center.
                                      1. Если использую objectsInScope, тогда zoom не работает, а мне нужно чтобы он был меньше, сейчас зум на максимуме, здание на весь экран и я не могу это изменить. Системные настройки инициализации карты на него тоже не влияют как я понял.
                                      2. Если использовать zoom + center, то в zoom я могу прописать нужную цифру. А вот как в center прокинуть нужные координаты — этого я не знаю. Объектов много, писать их каждому ручками вообще не вариант.
                                        Algirdas
                                        10 сентября 2021, 08:23
                                        0
                                        Я так понимаю нет такой возможности?
                                          Павел Гвоздь
                                          10 сентября 2021, 08:42
                                          0
                                          Нет.
                                          Остальные вопросы в ТП на Модстор, пожалуйста.
                                      Dmitry
                                      15 ноября 2021, 21:33
                                      0
                                      Павел, подскажите, пожалуйста, по одной части компонента, я возможно не до конца понял. Я хочу его приобрести под сайт недвижимости, но обратил внимание, на обязательный параметр limit => 0 в вызове mfilter2. Я правильно понимаю, что это принципиальный параметр, чтобы данные меток отображались сразу все на странице, и если использовать свои параметры с пагинацией, то на карте будет выводиться только текущая страница? Или все же есть обход, потому что я пока не понял как быть, когда ресурсов будет более 50-100 на одной странице
                                        Павел Гвоздь
                                        16 ноября 2021, 05:34
                                        0
                                        Только текущая страница.
                                          Dmitry
                                          16 ноября 2021, 08:10
                                          0
                                          Спасибо за ответ. Попробую покопаться в другом направлении)
                                        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                                        61