Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как вывести метки всех записей на карте гугл? (https://javascript.ru/forum/misc/72504-kak-vyvesti-metki-vsekh-zapisejj-na-karte-gugl.html)

giwuf 02.02.2018 17:07

Как вывести метки всех записей на карте гугл?
 
Всем привет! Есть сайт на wordpress с установленной темой classipress. В теме для каждой записи или объявления можно задавать координаты места положения на гугл карте с помощью заполнения произвольных полей cp_street,cp_city,cp_state,cp_zipcode. А я хочу вывести карту с указанием всех меток с адресами записей - как это сделать?
Код ниже позволяет вывести координату только одной метки записи:
<div id="gmap" class="mapblock">
  <?php
    $make_address = get_post_meta( $post->ID, 'cp_street', true ) . '&nbsp;' . get_post_meta( $post->ID, 'cp_city', true ) . '&nbsp;' . get_post_meta( $post->ID, 'cp_state', true ) . '&nbsp;' . get_post_meta( $post->ID, 'cp_zipcode', true );
    $coordinates = cp_get_geocode( $post->ID );
  ?>
  <script type="text/javascript">var address = "<?php echo esc_js($make_address); ?>";</script>
  <?php cp_google_maps_js( $coordinates ); ?>
  <!-- google map div -->
  <div id="map"></div>
</div>
<?php function cp_google_maps_js( $coordinates ) { ?>
<script type="text/javascript">
    jQuery(document).ready(function($) {
        map_init();
    });
    <?php
    if ( ! empty( $coordinates ) && is_array( $coordinates ) ) {
      echo 'var SavedLatLng = new google.maps.LatLng(' . $coordinates['lat'] . ', ' . $coordinates['lng'] . ');';
      $location_by = "'latLng':SavedLatLng";
      $marker_position = "SavedLatLng";
    } else {
      $location_by = "'address': address";
      $marker_position = "results[0].geometry.location";
    }
    ?>
    var map = null;
    var marker = null;
    var infowindow = null;
    var geocoder = null;
    var fromAdd;
    var toAdd;
    var redFlag = "<?php echo esc_js( appthemes_locate_template_uri( 'images/red-flag.png' ) ); ?>";
    var noLuck = "<?php echo esc_js( appthemes_locate_template_uri( 'images/gmaps-no-result.gif' ) ); ?>";
    var adTitle = "<?php echo esc_js( get_the_title() ); ?>";
    var contentString = '<div id="mcwrap"><span>' + adTitle + '</span><br />' + address + '</div>';

    function map_init() {
      jQuery(document).ready(function($) {
        $('#map').hide();
        load();
        $('#map').fadeIn(1000);
        codeAddress();
      });
    }
    function load() {
        geocoder = new google.maps.Geocoder();
        var newyork = new google.maps.LatLng(40.69847032728747, -73.9514422416687);
        var myOptions = {
            zoom: 14,
            center: newyork,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            mapTypeControlOptions: {
                style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
            }
        }
        map = new google.maps.Map(document.getElementById('map'), myOptions);
    }
    function codeAddress() {
        geocoder.geocode( { <?php echo $location_by; ?> }, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            marker = new google.maps.Marker({
                map: map,
                icon: redFlag,
                animation: google.maps.Animation.DROP,
                position: <?php echo $marker_position; ?>
            });

            map.setCenter(marker.getPosition());

            infowindow = new google.maps.InfoWindow({
                maxWidth: 230,
                content: contentString,
                disableAutoPan: false
            });

            infowindow.open(map, marker);

            google.maps.event.addListener(marker, 'click', function() {
              infowindow.open(map,marker);
            });

          } else {
            (function($) {
                $('#map').html('<div style="height:400px;background: url(' + noLuck + ') no-repeat center center;"><p style="padding:50px 0;text-align:center;"><?php echo esc_js( __( 'Sorry, the address could not be found.', APP_TD ) ); ?></p></div>');
                return false;
            })(jQuery);
          }
        });
      }

    function showAddress(fromAddress, toAddress) {
        calcRoute();
        calcRoute1();
    }
    function calcRoute() {
        var start = document.getElementById("fromAdd").value;
        var end = document.getElementById("toAdd").value;
        var request = {
            origin: start,
            destination: end,
            travelMode: google.maps.DirectionsTravelMode.DRIVING
        };
        directionsService.route(request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                directionsDisplay.setDirections(response);
            }
        });
    }
</script>

<?php
}


Собрал я массив всех значений - а как его дальше в функцию передать и с помощью js разложить на составялющие и разместить на карте метки?
$posts = get_posts(array('post_type' => 'post'));
foreach($posts as $post){ 
  $address = get_post_meta( $post->ID, 'cp_street', true ) . '&nbsp;' . get_post_meta( $post->ID, 'cp_city', true ) . '&nbsp;' . get_post_meta( $post->ID, 'cp_state', true ) . '&nbsp;' . get_post_meta( $post->ID, 'cp_zipcode', true );
}

Nexus 02.02.2018 17:21

Закодируйте массив в json, json вставьте в переменную в JS.
Раскодируйте JSON на клиенте с помощью js, далее в цикле определяйте координаты адреса с помощью геокодера.
В callback'е геокодера добавляйте на карту маркер.
<script type="text/javascript">
    var markerAddresses='<?php echo json_encode($addresses);?>';
    try{
        markerAddresses=JSON.parse(markerAddresses);
    }catch(e){
        alert('Что-то пошло не так');
        markerAddresses=[];
    }

    markerAddresses.forEach(function(address){
        //Тут используете геокодер и добавляете маркер
    });
</script>

laimas 02.02.2018 17:24

Данные маркеров нужно отдать клиенту как объект:

<script>
var locations = <?=json_encode(массив описывающий маркеры)?>
</script>

Далее используя методы API циклом поместить маркеры на карту.

laimas 02.02.2018 17:25

Цитата:

Сообщение от Nexus
Раскодируйте JSON на клиенте с помощью js

Этого не потребуется.

Nexus 02.02.2018 17:27

laimas, я только сейчас понял, что json - корректный JS Object...
Что я делал все эти годы )

laimas 02.02.2018 17:35

Цитата:

Сообщение от Nexus
я только сейчас понял, что json - корректный JS Object...

Не совсем так. JSON - это строковое значение, и будучи переданное как json, например в асинхронном запросе, подлежит обратному преобразованию.

Если же выводить эту строку на страницу непосредственно, то выведено будет только то что заключено в двойные кавычки, что и будет в итоге литерально заданным js-объектом или массивом. :)

Nexus 02.02.2018 17:43

laimas,
Цитата:

Сообщение от laimas
JSON - это строковое значение, и будучи переданное как json, например в асинхронном запросе, подлежит обратному преобразованию.

Это мне, к счастью известно.

Цитата:

Сообщение от laimas
Если же выводить эту строку на страницу непосредственно, то выведено будет только то что заключено в двойные кавычки, что и будет в итоге литерально заданным js-объектом или массивом.

Не совсем понял про двойные кавычки, можете пояснить?

laimas 02.02.2018 18:05

Цитата:

Сообщение от Nexus
Это мне, к счастью известно.

Известно, но тем не менее определяете это неверно. ) Часто в темах пишут "есть json объект ....", что ну никак не может быть. А не понимание этого может быть предпосылкой к ошибкам.

Цитата:

Сообщение от Nexus
Не совсем понял про двойные кавычки, можете пояснить?

Строковые значения обрамляются кавычками, и json будучи строковым значением не является исключением, что и делает функция json_encode. Кодирование в json производится согласно соглашению к данному типу документа. Правда в РНР можно задавать тот или иной формат данных в json, чтобы быть уверенным, что имеем то, что ожидаем.

giwuf 02.02.2018 18:24

Спасибо! Буду пробовать. По результатам отпишусь

Nexus 02.02.2018 22:21

Цитата:

Сообщение от laimas
Строковые значения обрамляются кавычками, и json будучи строковым значением не является исключением

Может я что-то не так понял, но ведь значение переменной json - вполне корректная строка формата JSON, хоть и не обрамлена в двойные кавычки:
var json='{"foo":"bar"}';
console.log(JSON.parse(json));


Цитата:

Сообщение от laimas
Известно, но тем не менее определяете это неверно.

В комментарии №5 я имел ввиду, что если массив на сервере преобразовать к строке json, то после эту строку можно вставить в JS, не как строку, но как корректный объект.

laimas 03.02.2018 05:03

Цитата:

Сообщение от Nexus
значение переменной json - вполне корректная строка формата JSON

Это как понять? :D

В JS нет ассоциативных массивов, но их можно представить как объекты. Именно как объект они пакуются в JSON, по синтаксису литеральной нотации. Поэтому, если на сервере выполнить вывод json-строки в тег script, то клиент получит корректный JS объект. Тоже самое и с массивом. Индексные массивы будут упакованы в json ровно также, как в JS - [...].

Вот почему "хотя не обрамлена ..." выполняется без ругани, так как первый символ в json строке корректный. Но json, это не обязательно массив в него упакованный, в него можно упаковать и строки:

JSON.parse('<p>txt</p>') - ошибка, частый случай при ajax запросах.
JSON.parse('"<p>txt</p>"') - получили требуемое

И это мы, представляя строковые значения можем использовать комбинации двойные в одинарных или наоборот, или экранирование. Но по факту это будут строки с двойными в двойных, это можно даже в отладчике наблюдать.

Но это не так важно, будь определено синтаксисом помещать в косые, пусть помещает, важно что и как json строка представляет и использовать эту строку по полной программе. :)

Nexus 03.02.2018 11:46

Цитата:

Сообщение от laimas
Это как понять?

JSON - текстовый формат обмена данными © wiki
Значит любая строка может как соответствовать формату, так и нет.
Цитата:

Сообщение от Nexus
значение переменной json - вполне корректная строка формата JSON

Т.е. значение переменной json - строка, которая соответствует формату JSON.

Цитата:

Сообщение от laimas
Вот почему "хотя не обрамлена ..." выполняется без ругани, так как первый символ в json строке корректный. Но json, это не обязательно массив в него упакованный, в него можно упаковать и строки

Теперь понял, что вы имели ввиду.
Спасибо :)

laimas 03.02.2018 12:26

Цитата:

Сообщение от Nexus
Значит любая строка может как соответствовать формату, так и нет.

Как все запутано. :) Коли речь идет о json, значит либо этот формат, либо ошибка формата, а не любая строка. Иначе я понял, что речь о json в json.

Ну тогда на закуску - валидным json могут быть integer, float, булевы значения. Например на клиенте вот такое alert(JSON.parse(123)) не является ошибкой и будет исполнено. Но не обязательно все декодеры воспримут такой json как валидный, так как нет однозначной спецификации по данному вопросу.


Часовой пояс GMT +3, время: 11:52.