問題描述

我想”geotag” 我所有的帖子,並顯示在一個 GoogleMap 上。

最佳解決方案

可以做到這一點沒有任何外掛,你只需要 Google Maps API

請注意,如果您計劃在單個頁面上有 20 個或更多的標記,則必須使用座標而不是地址來定位帖子。

要從地址中儲存座標,您可以:

  1. 手動使用服務 (類似於 this)

  2. 在建立或更新帖子時,請致電 WP 管理員的 GoogleMap 地理編碼

如何實現第二個選項與問題並不是完全相關的,我不會考慮我的答案,但是看到這個 Maps API example 可以看到從地址中檢索座標是多麼簡單。

所以我會假設在這個答案中,帖子有自定義欄位’coords’,其中座標儲存為兩個逗號分隔值的字串,類似於:'38.897683,-77.03649'

我也假設有一個頁面模板儲存在檔案’page-google-map.php’ 中。

將以下程式碼放在 functions.php

add_action( 'wp_enqueue_scripts', 'enqueue_gmap' );

function enqueue_gmap() {
    // script goes only in the map page template
    if ( ! is_page_template('page-google-map.php') ) return;

    wp_register_script( 'google-maps-api', '//maps.google.com/maps/api/js?sensor=false', false, false );
    wp_register_script( 'posts_map', get_template_directory_uri().'/js/mygmap.js', false, false, true );
    wp_enqueue_script( 'google-maps-api' );
    wp_enqueue_script( 'posts_map' );

    // use a custom field on the map page to setup the zoom
    global $post;
    $zoom = (int) get_post_meta( $post->ID, 'map_zoom', true );
    if ( ! $zoom ) $zoom = 6;

    $map_data = array(
        'markers' => array(),
        'center'  => array( 41.890262, 12.492310 ),
        'zoom'    => $zoom,
    );
    $lats  = array();
    $longs = array();

    // put here your query args
    $map_query = new WP_Query( array( 'posts_per_page' => -1, ) );

    // Loop
    if ( $map_query->have_posts() ) :
        while( $map_query->have_posts() ) : $map_query->the_post();
            $meta_coords = get_post_meta( get_the_ID(), 'coords', true );
            if ( $meta_coords ) {
                $coords = array_map('floatval', array_map( 'trim', explode( ",", $meta_coords) ) );
                $title = get_the_title();
                $link  = sprintf('<a href="%s">%s</a>', get_permalink(), $title);
                $map_data['markers'][] = array(
                    'latlang' => $coords,
                    'title'   => $title,
                    'desc'    => '<h3 class="marker-title">'.$link.'</h3><div class="marker-desc">'.get_the_excerpt().'</div>',
                );
                $lats[]  = $coords[0];
                $longs[] = $coords[1];
            }
        endwhile;
        // auto calc map center
        if ( ! empty( $lats ) )
            $map_data['center'] = array(
                ( max( $lats ) + min( $lats ) ) /2,
                ( max( $longs ) + min( $longs ) ) /2
            );
    endif; // End Loop

    wp_reset_postdata;
    wp_localize_script( 'posts_map', 'map_data', $map_data );
}

如你所見,在 Map 頁面模板中,我排隊

  • google map api 指令碼

  • 一個名為 mygmap.js 的指令碼位於’js’ 子資料夾的主題

也是迴圈的帖子,我填充一個陣列 $map_data 並使用 wp_localize_script 我透過這個陣列到頁面中的 js 。

現在,mygmap.js 將包含:

function map_initialize() {
    var map_div     = document.getElementById( 'map' );
        map_markers = map_data.markers,
        map_center  = new google.maps.LatLng( map_data.center[0], map_data.center[1] ),
        map_zoom    = Number( map_data.zoom ),
        map         = new google.maps.Map( document.getElementById( 'map' ), {
            zoom      : map_zoom,
            center    : map_center,
            mapTypeId : google.maps.MapTypeId.ROADMAP
        } );

    if ( map_markers.length ) {
        var infowindow = new google.maps.InfoWindow(),
            marker,
            i;
        for ( i = 0; i < map_markers.length; i++ ) {
            marker = new google.maps.Marker( {
                position : new google.maps.LatLng(
                    map_markers[i]['latlang'][0],
                    map_markers[i]['latlang'][1]
                ),
                title    : map_markers[i]['title'],
                map      : map
            } );
            google.maps.event.addListener( marker, 'click', ( function( marker, i ) {
                return function() {
                    infowindow.setContent( map_markers[i]['desc'] );
                    infowindow.open( map, marker );
                }
            } )( marker, i ) );
        }
    }
};
google.maps.event.addDomListener( window, 'load', map_initialize );

javascript 不是 WP 相關的,我把這裡放在這裡只顯示使用 map_data var 。我不是一個 js 開發人員,程式碼或多或少完全取自 here

就這樣。只需建立頁面模板並使用 id ‘map’ 插入一個 div,就像:

<div id="map" style="width:100%; height:100%"></div>

當然,div 可以用 css 來設計,並注意標記的資訊視窗也可以設定樣式:在 css 中使用 h3.marker-title 來設定資訊視窗標題和 div.marker-desc 的樣式。

請注意,自動計算 Map 中心,如果要更改預設縮放,則必須在分配給 Map 頁面模板的頁面中放置自定義欄位’map_zoom’ 。

希望它有幫助。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。