2012-06-02 40 views
14

Tôi đang cố triển khai thông tin tùy chỉnhBiểu đồ có hộp mở ở bên cạnh điểm đánh dấu thay vì vị trí mặc định ở trên cùng. Điều này đã trở nên khó hơn dự kiến.Google Maps InfoBubble pixelBài viết (Di chuyển từ vị trí mặc định trên điểm đánh dấu)

Sử dụng thông tin thông thườngBạn có thể sử dụng pixelOffset. Xem tại đây để xem documentation

Sử dụng thông tinBằng cách này dường như không đúng. Có anyway sử dụng pixelOffset trong một infoBubble, hoặc một cái gì đó mà sẽ làm điều tương tự?

Tôi đã thấy điều này rất khó khăn để tìm kiếm, như sử dụng một tìm kiếm google như thế này trả về kết quả có liên quan Google Search

Dưới đây là tất cả các nguồn lực của tôi, tôi đã được sử dụng.

  • Ví dụ về infoBubble here.

  • JavaScript của tôi để thiết lập bản đồ và thông tinBiểu đồ here.

Và bây giờ javascript của tôi ở đây chỉ trong trường hợp liên kết jsfiddle bị hỏng.

<script type="text/javascript"> 

    $(document).ready(function() { 
     init(); 
    }); 

    function init() { 

     //Setup the map 
     var googleMapOptions = { 
      center: new google.maps.LatLng(53.5167, -1.1333), 
      zoom: 13, 
      mapTypeId: google.maps.MapTypeId.ROADMAP 
     }; 

     //Start the map 
     var map = new google.maps.Map(document.getElementById("map_canvas"), 
     googleMapOptions); 

     var marker = new google.maps.Marker({ 
      position: new google.maps.LatLng(53.5267, -1.1333), 
      title: "Just a test" 
     }); 

     marker.setMap(map); 

     infoBubble = new InfoBubble({ 
      map: map, 
      content: '<div class="phoneytext">Some label</div>', 
      //position: new google.maps.LatLng(-35, 151), 
      shadowStyle: 1, 
      padding: '10px', 
      //backgroundColor: 'rgb(57,57,57)', 
      borderRadius: 5, 
      minWidth: 200, 
      arrowSize: 10, 
      borderWidth: 1, 
      borderColor: '#2c2c2c', 
      disableAutoPan: true, 
      hideCloseButton: false, 
      arrowPosition: 7, 
      backgroundClassName: 'phoney', 
      pixelOffset: new google.maps.Size(130, 120), 
      arrowStyle: 2 
     }); 
     infoBubble.open(map, marker); 

    } 
</script> 

Cập nhật

Để giúp trả lời câu hỏi này tôi đã đặt cùng một trường hợp thử nghiệm đây . Các dòng quan trọng là các dòng 38 & 39, sẽ chỉ định vị trí đặt nhãn.

Cập nhật 2

Đối với tiền thưởng được trao tôi cần phải nhìn thấy một ví dụ về infoBubble vị trí cách xa vị trí mặc định của nó trên các điểm đánh dấu. Tốt hơn là ở phía bên tay phải của điểm đánh dấu.

Cập nhật 3

Tôi đã gỡ bỏ các testcase từ cập nhật 1 bởi vì nó được lưu trữ trên máy chủ của công ty cũ của tôi.

+0

chỉ động não: nếu bạn biết vị trí của các điểm đánh dấu: (lng, lat), sau đó (lng + X, lat) nên vị trí cho các bong bóng, phải ? – Gavriel

+0

Nghe có vẻ như nó có thể làm việc có – Undefined

Trả lời

9

Dường như thư viện infoBubble mặc định định vị bong bóng phía trên điểm đánh dấu mà nó bị ràng buộc. Hãy xem tập tin mẫu được đưa vào thư viện: http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobubble/examples/example.html. Thông báo cụ thể từ dòng 99 đến dòng 122 và sử dụng hai infobubbles.Cái đầu tiên được gắn với điểm đánh dấu, tuy nhiên cái thứ hai là độc lập và do đó nếu bạn nhìn thấy dòng 106, bạn có thể xác định vị trí cho nó. Bây giờ, dựa trên sự hiểu biết này, tôi đã tạo ra một ví dụ cho bạn trong fiddle http://jsfiddle.net/pDFc3/ này. InfoBubble được đặt ở bên phải của điểm đánh dấu.

Thật kỳ lạ, vì thư viện infoBubble js có chức năng setPosition (http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobubble/src/infobubble.js?r=206) xem Dòng 1027. Nhưng vì lý do nào đó sau khi tôi đợi DOM tải và cố gắng thay đổi vị trí bằng cách đi infoBubble.setPosition(newLatLng); Tôi không làm việc . Ngược lại, khai báo infoBubble.getPosition(); sau khi tải DOM cung cấp cho tôi vị trí hiện tại của điểm đánh dấu mà infoBubble bị ràng buộc. Vì vậy, setPosition() có thể có một lỗi trong thư viện js, bởi vì tôi tin rằng nó vẫn đang được làm việc trên (tôi có thể sai có lẽ nó chỉ là lỗi).


Tôi đã khắc phục jsFiddle tôi để giải quyết vấn đề của bạn cho khi phóng to trong và ngoài, và định vị infoBubble phù hợp (http://jsfiddle.net/pDFc3/). Để tôi giải thích logic trước. Thứ nhất, mức thu phóng tối đa trên Google Maps cho loại bản đồ đường là 21 - giá trị này không phù hợp với hình ảnh vệ tinh nhưng mức thu phóng tối đa mà người dùng có thể đến là 21. Từ 21, mỗi lần bạn thu nhỏ sự khác biệt giữa hai điểm có thể giữ nhất quán "trên màn hình" dựa trên logic sau:

consitent_screen_dist = initial_dist * (2^(21 - zoomlevel)) 

Trong trường hợp của chúng tôi, giá trị hợp lý cho khoảng cách ban đầu là 0,003 độ (giữa điểm đánh dấu và thông tin). Vì vậy, dựa trên logic này tôi đã thêm các mảnh sau đây để tìm khoảng cách theo chiều dọc ban đầu giữa marker và infoBubble:

var newlong = marker.getPosition().lng() + (0.00003 * Math.pow(2, (21 - map.getZoom()))); 

Tương tự như vậy, để đảm bảo khoảng cách vẫn phù hợp trên mỗi sự thay đổi mức độ phóng chúng tôi chỉ đơn giản là khai báo một kinh độ mới như chúng ta nghe cho một sự thay đổi trong mức độ zoom:

google.maps.event.addListener(map, "zoom_changed", function() { 
     newlong = marker.getPosition().lng() + (0.00003 * Math.pow(2, (21 - map.getZoom()))); 
     infoBubble.setPosition(new google.maps.LatLng(marker.getPosition().lat(), newlong));     
    }); 

hãy nhớ bạn có thể làm cho mã này hiệu quả hơn bằng cách tuyên bố biến cho marker.getPosition và các giá trị khác được gọi là thông qua phương pháp. Vì vậy, các cuộc gọi phương thức không lặp lại và làm chậm mã của bạn.

+0

Đó là những gì tôi đang tìm kiếm, một vấn đề là khi phóng to và thu nhỏ di chuyển điểm đánh dấu liên quan đến điểm đánh dấu, đôi khi ẩn nó hoàn toàn. Bạn có nghĩ đây là thứ có thể được giải quyết không? – Undefined

+0

Đó là sự thật, đó là vì chúng tôi đang thiết lập vị trí của infoBubble có liên quan đến điểm đánh dấu ở mức thu phóng cụ thể. Nhưng khi bạn thay đổi mức thu phóng, khoảng cách giữa điểm đánh dấu và thông tin thông tin (sự khác biệt giữa các tọa độ vĩ độ/dài của cả hai) không thay đổi. Vì vậy, khi bạn thu nhỏ, sự khác biệt đó quá nhỏ đến nỗi bạn xem infoBubble phía trên điểm đánh dấu. –

+0

Mặc dù vậy, có một sửa chữa cho vấn đề này, tôi đã phát hiện ra rằng nếu bạn không ràng buộc infoBubble với nhà sản xuất thì bạn thực sự có thể sử dụng phương thức infoBubble.setPosition (latlng). Điều này có nghĩa là chúng ta có thể nghe những thay đổi thu phóng bằng cách sử dụng trình nghe sự kiện bản đồ google 'zoom_changed' và sau đó sử dụng hàm' getZoom() 'để xác định các lớp cho cách định vị thông tin liên quan đến điểm đánh dấu dựa trên các mức thu phóng. Tôi sẽ cập nhật jsfiddle của mình với bản sửa lỗi có thể có này, nhưng cảm thấy tự do để thử nghiệm dựa trên nguyên tắc này. –

1

Rất tiếc, không có tùy chọn nào như pixelOffset trong InfoBubble. Nhưng nếu bạn chỉ muốn di chuyển Bubble lên trên điểm đánh dấu trong ví dụ của mình, bạn không nên đặt thông số bản đồ khi khởi chạy bong bóng. Hãy xem xét các fiddle sau (i cố định nó cho bạn):

http://jsfiddle.net/ssrP9/5/


T.B. Fiddle của bạn không hoạt động vì bạn không thêm tài nguyên đúng cách http://doc.jsfiddle.net/basic/introduction.html#add-resources

+0

Quên đề cập đến. Câu trả lời của tôi dựa trên phân tích nguồn. Vì vậy, nếu bạn thực sự cần đặt bù đắp tùy chỉnh tương ứng với điểm đánh dấu có hai cách: 1. Nhận nguồn của thư viện này và thêm chức năng cần thiết 2. [khá lạ] Đặt điểm đánh dấu vô hình với chênh lệch cần thiết từ bong bóng ban đầu và mở nó. –

+0

Cảm ơn jsfiddle mà tôi sẽ bao gồm trong câu hỏi của tôi. Thật không may tôi đang tìm cách đặt các infoBubble ở một vị trí khác từ trên các điểm đánh dấu – Undefined

1

Tôi vừa gặp chính xác vấn đề tương tự nhưng không thể tìm thấy câu trả lời ở bất kỳ đâu. Thông qua một thử nghiệm nhỏ và lỗi tôi đã làm việc nó ra.

Bạn sẽ sử dụng tệp Google JS cho "infoBubble". Đi vào tệp này và tìm kiếm ...

InfoBubble.prototype.buildDom_ = function() { 

Đối với tôi, đây là dòng 203 (nhưng đó có thể là kết quả của việc xáo trộn và chỉnh sửa trước đó).

Trong chức năng đó, bạn sẽ thấy tuyên bố "tuyệt đối" vị trí. Trên một dòng mới, bạn có thể thêm marginTop, marginRight, marginBottom và marginLeft. Điều này sẽ di chuyển bong bóng từ vị trí mặc định của nó (cũng phụ thuộc vào khai báo vị trí mũi tên trong cấu hình của bạn) ...

Đây là tinh chỉnh mã của tôi trong tệp JS bong bóng vị trí bong bóng trên đỉnh của điểm đánh dấu (do tính năng thiết kế) ...

var bubble = this.bubble_ = document.createElement('DIV'); 
bubble.style['position'] = 'absolute'; 
bubble.style['marginTop'] = this.px(21); 
bubble.style['marginLeft'] = this.px(1); 
bubble.style['zIndex'] = this.baseZIndex_; 

Hy vọng điều đó sẽ hữu ích.

0

Trong chức năng InfoBubble buildDom, thêm:

bubble.className = 'bubble-container'; 

Bây giờ bạn có một lớp CSS cho mỗi InfoBubble, bạn có thể thay đổi nó bằng cách sử lề CSS.

8

Đây là giải pháp của tôi.

Trong InfoBubble thư viện

thay

toàn bộ InfoBubble.prototype.draw phương pháp

với

/* 
* Sets InfoBubble Position 
* */ 
InfoBubble.prototype.setBubbleOffset = function(xOffset, yOffset) { 
    this.bubbleOffsetX = parseInt(xOffset); 
    this.bubbleOffsetY = parseInt(yOffset); 
} 


/* 
* Gets InfoBubble Position 
* */ 
InfoBubble.prototype.getBubbleOffset = function() { 
    return { 
    x: this.bubbleOffsetX || 0, 
    y: this.bubbleOffsetY || 0 
    } 
} 

/** 
* Draw the InfoBubble 
* Implementing the OverlayView interface 
*/ 
InfoBubble.prototype.draw = function() { 
    var projection = this.getProjection(); 

    if (!projection) { 
    // The map projection is not ready yet so do nothing 
    return; 
    } 

    var latLng = /** @type {google.maps.LatLng} */ (this.get('position')); 

    if (!latLng) { 
    this.close(); 
    return; 
    } 

    var tabHeight = 0; 

    if (this.activeTab_) { 
    tabHeight = this.activeTab_.offsetHeight; 
    } 

    var anchorHeight = this.getAnchorHeight_(); 
    var arrowSize = this.getArrowSize_(); 
    var arrowPosition = this.getArrowPosition_(); 

    arrowPosition = arrowPosition/100; 

    var pos = projection.fromLatLngToDivPixel(latLng); 
    var width = this.contentContainer_.offsetWidth; 
    var height = this.bubble_.offsetHeight; 

    if (!width) { 
    return; 
    } 

    // Adjust for the height of the info bubble 
    var top = pos.y - (height + arrowSize) + this.getBubbleOffset().y; 

    if (anchorHeight) { 
    // If there is an anchor then include the height 
    top -= anchorHeight; 
    } 

    var left = pos.x - (width * arrowPosition) + this.getBubbleOffset().x; 

    this.bubble_.style['top'] = this.px(top); 
    this.bubble_.style['left'] = this.px(left); 

    var shadowStyle = parseInt(this.get('shadowStyle'), 10); 

    switch (shadowStyle) { 
    case 1: 
     // Shadow is behind 
     this.bubbleShadow_.style['top'] = this.px(top + tabHeight - 1); 
     this.bubbleShadow_.style['left'] = this.px(left); 
     this.bubbleShadow_.style['width'] = this.px(width); 
     this.bubbleShadow_.style['height'] = 
     this.px(this.contentContainer_.offsetHeight - arrowSize); 
     break; 
    case 2: 
     // Shadow is below 
     width = width * 0.8; 
     if (anchorHeight) { 
     this.bubbleShadow_.style['top'] = this.px(pos.y); 
     } else { 
     this.bubbleShadow_.style['top'] = this.px(pos.y + arrowSize); 
     } 
     this.bubbleShadow_.style['left'] = this.px(pos.x - width * arrowPosition); 

     this.bubbleShadow_.style['width'] = this.px(width); 
     this.bubbleShadow_.style['height'] = this.px(2); 
     break; 
    } 
}; 

và sau đó bạn có thể sử dụng điều này bằng cách

var infoBubble = new InfoBubble({ 
    map: map, 
    content: "My Content", 
    position: new google.maps.LatLng(1, 1), 
    shadowStyle: 1, 
    padding: 0, 
    backgroundColor: 'transparent', 
    borderRadius: 7, 
    arrowSize: 10, 
    borderWidth: 1, 
    borderColor: '#2c2c2c', 
    disableAutoPan: true, 
    hideCloseButton: true, 
    arrowPosition: 50, 
    backgroundClassName: 'infoBubbleBackground', 
    arrowStyle: 2 

}); 

Sau đó, cuối cùng chúng ta phải sử dụng phương pháp này setBubbleOffset(x,y); để thiết lập vị trí InfoBubble

infoBubble.setBubbleOffset(0,-32); 
1

Bạn cũng có thể sử dụng một chiều cao neo được xác định;

var anchorHeight = YOURNUMBER; 

dòng 874 infobubble.js

Các vấn đề liên quan