首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Google Maps API v3 自定義 Marker 實現文字標註:LabelMarker 完整原始碼與使用教學

     編輯:Java 相關知識

Google Maps 預設 google.maps.Marker 僅支援圖片圖示,無法直接顯示文字。透過繼承 OverlayView (或 v3 中擴展 Marker) 實作 LabelMarker,即可在地圖上直接繪製文字標籤 (如地名、編號),無需產生圖片。

LabelMarker 完整實作 (Google Maps API v3)

google.maps.LabelMarker = function(latlng, options) {
    this.latlng = latlng;
    this.labelText = options.labelText || '';
    this.labelClass = options.labelClass || 'map-label'; // CSS 類別
    this.labelOffset = options.labelOffset || new google.maps.Size(8, -33);
    options.icon = options.icon || this.getTransparentIcon(); // 透明圖示佔位
    google.maps.Marker.apply(this, arguments);
};

// 繼承 Marker
google.maps.LabelMarker.prototype = new google.maps.Marker(new google.maps.LatLng(0, 0));

// 建立 1x1 透明圖示避免預設圖示干擾
google.maps.LabelMarker.prototype.getTransparentIcon = function() {
    var icon = {
        url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==',
        size: new google.maps.Size(1, 1),
        anchor: new google.maps.Point(0, 1)
    };
    return icon;
};

// 初始化:建立 DOM 標籤元素
google.maps.LabelMarker.prototype.setMap = function(map) {
    google.maps.Marker.prototype.setMap.call(this, map);
    if (this.labelDiv) return; // 已初始化

    this.labelDiv = document.createElement('div');
    this.labelDiv.className = this.labelClass;
    this.labelDiv.innerHTML = this.labelText;
    this.labelDiv.style.position = 'absolute';
    this.labelDiv.style.whiteSpace = 'nowrap';
    this.labelDiv.style.pointerEvents = 'none'; // 穿透點擊

    // 加入 MAP_MARKER_PANE (v3 對應 overlayMouseTarget 或 overlayLayer)
    var panes = this.getPanes();
    if (panes) panes.overlayLayer.appendChild(this.labelDiv);
};

// 重繪:依投影座標更新標籤位置
google.maps.LabelMarker.prototype.draw = function() {
    if (!this.labelDiv) return;
    var projection = this.getProjection();
    if (!projection) return;

    var pixel = projection.fromLatLngToDivPixel(this.latlng);
    if (!pixel) return;

    this.labelDiv.style.left = (pixel.x + this.labelOffset.width) + 'px';
    this.labelDiv.style.top = (pixel.y + this.labelOffset.height) + 'px';
    this.labelDiv.style.zIndex = Math.round(this.latlng.lat() * -100000) + 1; // 緯度越高 zIndex 越大
};

// 移除:清理 DOM
google.maps.LabelMarker.prototype.onRemove = function() {
    if (this.labelDiv && this.labelDiv.parentNode) {
        this.labelDiv.parentNode.removeChild(this.labelDiv);
    }
    this.labelDiv = null;
};

CSS 樣式範例

.map-label {
    font-family: 'Microsoft JhengHei', Arial, sans-serif;
    font-size: 12px;
    font-weight: bold;
    color: #333;
    background: rgba(255,255,255,0.9);
    padding: 2px 6px;
    border-radius: 3px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
    border: 1px solid #ccc;
}

使用範例

function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: 25.033, lng: 121.565},
        zoom: 12
    });

    var marker = new google.maps.LabelMarker(map.getCenter(), {
        labelText: '我在這裡',
        labelClass: 'map-label',
        labelOffset: new google.maps.Size(10, -35)
    });
    marker.setMap(map);
}

進階應用技巧

  • 動態更新文字:marker.labelDiv.innerHTML = '新文字';
  • 事件穿透:pointerEvents: 'none' 讓點擊事件傳給底層 Marker/地圖
  • 碰撞避讓:結合 MarkerClusterer 或自行演算法調整 labelOffset
  • 支援 HTML:innerHTML 可放入任意 HTML (圖示+文字、超連結等)

版本差異提醒

特性API v2 (舊)API v3 (現行)
基底類別GMarker / GOverlaygoogle.maps.Marker / OverlayView
投影轉換map.fromLatLngToDivPixel()projection.fromLatLngToDivPixel()
Pane 常數G_MAP_MARKER_PANEoverlayLayer / overlayMouseTarget
初始化鉤子initialize(map)setMap(map)
繪製鉤子redraw(force)draw()

本文代碼為 **API v3** 版本,v2 專案請參考原始碼調整對應方法名與常數。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved