Wprowadzenie
Znacznik wskazuje lokalizację na mapie. Domyślnie znacznik używa a
standardowego obrazu. Znaczniki mogą wyświetlać obrazy niestandardowe, w którym to przypadku są
zwykle nazywane „ikonami”. Znaczniki i ikony to obiekty typu
Marker. Możesz ustawić ikonę niestandardową w konstruktorze znacznika lub wywołując
setIcon() na znaczniku. Więcej informacji o
dostosowywaniu obrazu znacznika.
Ogólnie rzecz biorąc, znaczniki są rodzajem nakładki. Więcej informacji o innych typach nakładek znajdziesz w artykule Rysowanie na mapie.
Znaczniki są interaktywne. Domyślnie odbierają np.
zdarzenia 'click', dzięki czemu możesz dodać detektor zdarzeń, aby
wyświetlać
okno informacyjne
z informacjami niestandardowymi. Możesz zezwolić użytkownikom na przesuwanie znacznika na
mapie, ustawiając właściwość znacznika draggable na
true. Więcej informacji o znacznikach, które można przeciągać, znajdziesz
poniżej.
Dodawanie znacznika
Konstruktor
google.maps.Marker
przyjmuje pojedynczy Marker options literał obiektu, który określa początkowe właściwości znacznika.
Podczas tworzenia znacznika szczególnie ważne są te pola, które są zwykle ustawiane:
-
position(wymagane) określaLatLngidentyfikujący początkową lokalizację znacznika. Jednym ze sposobów pobraniaLatLngjest użycie usługi geokodowania. -
map(opcjonalne) określaMap, na której ma zostać umieszczony znacznik. Jeśli nie określisz mapy podczas tworzenia znacznika, zostanie on utworzony, ale nie będzie do niej dołączony ani na niej wyświetlany. Możesz dodać znacznik później, wywołując metodę znacznikasetMap().
Ten przykład dodaje prosty znacznik do mapy w Uluru w środkowej Australii:
TypeScript
function initMap(): void { const myLatLng = { lat: -25.363, lng: 131.044 }; const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: myLatLng, } ); new google.maps.Marker({ position: myLatLng, map, title: "Hello World!", }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const myLatLng = { lat: -25.363, lng: 131.044 }; const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: myLatLng, }); new google.maps.Marker({ position: myLatLng, map, title: "Hello World!", }); } window.initMap = initMap;
W powyższym przykładzie znacznik jest umieszczany na mapie podczas tworzenia
znacznika za pomocą właściwości map w opcjach znacznika.
Możesz też dodać znacznik do mapy bezpośrednio za pomocą metody znacznika setMap(), jak pokazano w przykładzie poniżej:
var myLatlng = new google.maps.LatLng(-25.363882,131.044922); var mapOptions = { zoom: 4, center: myLatlng } var map = new google.maps.Map(document.getElementById("map"), mapOptions); var marker = new google.maps.Marker({ position: myLatlng, title:"Hello World!" }); // To add the marker to the map, call setMap(); marker.setMap(map);
title znacznika będzie wyświetlany jako etykietka.
Jeśli nie chcesz przekazywać żadnych Marker options w konstruktorze znacznika, przekaż pusty obiekt {} jako ostatni argument konstruktora.
Usuwanie znacznika
Aby usunąć znacznik z mapy, wywołaj metodę setMap(), przekazując null jako argument.
marker.setMap(null);
Pamiętaj, że powyższa metoda nie usuwa znacznika. Usuwa go z mapy. Jeśli chcesz usunąć znacznik, usuń go z mapy, a następnie ustaw sam znacznik na
null.
Jeśli chcesz zarządzać zestawem znaczników, utwórz tablicę, która będzie je przechowywać. Gdy trzeba usunąć znaczniki, możesz wywołać metodę setMap() na
każdym znaczniku w tablicy. Możesz usunąć znaczniki, usuwając je z mapy, a następnie ustawiając length tablicy na 0, co spowoduje usunięcie wszystkich odwołań do znaczników.
Dostosowywanie obrazu znacznika
Możesz dostosować wygląd znaczników, określając plik obrazu lub ikonę wektorową, która ma być wyświetlana zamiast domyślnej ikony pinezki Map Google. Możesz dodać tekst z etykietą znacznika, używać złożonych ikon do definiowania regionów, które można kliknąć, i ustawiać kolejność stosu znaczników.
Znaczniki z ikonami obrazów
W najprostszym przypadku ikona może określać obraz, który ma być używany zamiast
domyślnej ikony pinezki Map Google. Aby określić taką ikonę, ustaw właściwość
znacznika icon na adres URL obrazu. Interfejs Maps JavaScript API automatycznie zmieni rozmiar ikony.
TypeScript
// This example adds a marker to indicate the position of Bondi Beach in Sydney, // Australia. function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: -33, lng: 151 }, } ); const image = "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png"; const beachMarker = new google.maps.Marker({ position: { lat: -33.89, lng: 151.274 }, map, icon: image, }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example adds a marker to indicate the position of Bondi Beach in Sydney, // Australia. function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: -33, lng: 151 }, }); const image = "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png"; const beachMarker = new google.maps.Marker({ position: { lat: -33.89, lng: 151.274 }, map, icon: image, }); } window.initMap = initMap;
Znaczniki z ikonami wektorowymi
Możesz używać niestandardowych ścieżek wektorowych SVG do definiowania wyglądu
znaczników. Aby to zrobić, przekaż literał obiektu Symbol z żądaną ścieżką do właściwości icon znacznika. Możesz zdefiniować a
ścieżkę niestandardową za pomocą
notacji ścieżki SVG lub użyć jednej ze wstępnie zdefiniowanych ścieżek w
google.maps.SymbolPath. Aby znacznik był prawidłowo renderowany po zmianie poziomu powiększenia, wymagana jest właściwość anchor. Więcej informacji o
używaniu symboli do tworzenia ikon wektorowych
dla znaczników (i polilinii).
TypeScript
// This example uses SVG path notation to add a vector-based symbol // as the icon for a marker. The resulting icon is a marker-shaped // symbol with a blue fill and no border. function initMap(): void { const center = new google.maps.LatLng(-33.712451, 150.311823); const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 9, center: center, } ); const svgMarker = { path: "M-1.547 12l6.563-6.609-1.406-1.406-5.156 5.203-2.063-2.109-1.406 1.406zM0 0q2.906 0 4.945 2.039t2.039 4.945q0 1.453-0.727 3.328t-1.758 3.516-2.039 3.070-1.711 2.273l-0.75 0.797q-0.281-0.328-0.75-0.867t-1.688-2.156-2.133-3.141-1.664-3.445-0.75-3.375q0-2.906 2.039-4.945t4.945-2.039z", fillColor: "blue", fillOpacity: 0.6, strokeWeight: 0, rotation: 0, scale: 2, anchor: new google.maps.Point(0, 20), }; new google.maps.Marker({ position: map.getCenter(), icon: svgMarker, map: map, }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example uses SVG path notation to add a vector-based symbol // as the icon for a marker. The resulting icon is a marker-shaped // symbol with a blue fill and no border. function initMap() { const center = new google.maps.LatLng(-33.712451, 150.311823); const map = new google.maps.Map(document.getElementById("map"), { zoom: 9, center: center, }); const svgMarker = { path: "M-1.547 12l6.563-6.609-1.406-1.406-5.156 5.203-2.063-2.109-1.406 1.406zM0 0q2.906 0 4.945 2.039t2.039 4.945q0 1.453-0.727 3.328t-1.758 3.516-2.039 3.070-1.711 2.273l-0.75 0.797q-0.281-0.328-0.75-0.867t-1.688-2.156-2.133-3.141-1.664-3.445-0.75-3.375q0-2.906 2.039-4.945t4.945-2.039z", fillColor: "blue", fillOpacity: 0.6, strokeWeight: 0, rotation: 0, scale: 2, anchor: new google.maps.Point(0, 20), }; new google.maps.Marker({ position: map.getCenter(), icon: svgMarker, map: map, }); } window.initMap = initMap;
Etykiety znaczników
Etykieta znacznika to litera lub cyfra, która pojawia się wewnątrz znacznika. Obraz znacznika w tej sekcji przedstawia etykietę znacznika z literą „B”. Etykietę znacznika możesz określić jako ciąg znaków lub
MarkerLabel
obiekt, który zawiera ciąg znaków i inne właściwości etykiety.
Podczas tworzenia znacznika możesz określić właściwość label w
MarkerOptions
obiekcie. Możesz też wywołać metodę setLabel() na obiekcie
Marker, aby ustawić etykietę na istniejącym znaczniku.
Ten przykład wyświetla oznaczone znaczniki, gdy użytkownik kliknie na mapę:
TypeScript
// In the following example, markers appear when the user clicks on the map. // Each marker is labeled with a single alphabetical character. const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let labelIndex = 0; function initMap(): void { const bangalore = { lat: 12.97, lng: 77.59 }; const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 12, center: bangalore, } ); // This event listener calls addMarker() when the map is clicked. google.maps.event.addListener(map, "click", (event) => { addMarker(event.latLng, map); }); // Add a marker at the center of the map. addMarker(bangalore, map); } // Adds a marker to the map. function addMarker(location: google.maps.LatLngLiteral, map: google.maps.Map) { // Add the marker at the clicked location, and add the next-available label // from the array of alphabetical characters. new google.maps.Marker({ position: location, label: labels[labelIndex++ % labels.length], map: map, }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// In the following example, markers appear when the user clicks on the map. // Each marker is labeled with a single alphabetical character. const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let labelIndex = 0; function initMap() { const bangalore = { lat: 12.97, lng: 77.59 }; const map = new google.maps.Map(document.getElementById("map"), { zoom: 12, center: bangalore, }); // This event listener calls addMarker() when the map is clicked. google.maps.event.addListener(map, "click", (event) => { addMarker(event.latLng, map); }); // Add a marker at the center of the map. addMarker(bangalore, map); } // Adds a marker to the map. function addMarker(location, map) { // Add the marker at the clicked location, and add the next-available label // from the array of alphabetical characters. new google.maps.Marker({ position: location, label: labels[labelIndex++ % labels.length], map: map, }); } window.initMap = initMap;
Złożone ikony
Możesz określić złożone kształty, aby wskazać regiony, które można kliknąć, oraz
określić, jak ikony mają się wyświetlać względem innych nakładek (ich
"kolejność stosu"). Ikony określone w ten sposób powinny mieć ustawione właściwości
icon
na obiekt typu
Icon.
Icon
obiekty definiują obraz. Określają też size ikony, jej origin (jeśli obraz, którego chcesz użyć, jest częścią większego obrazu w sprite, na przykład) oraz anchor, w którym ma się znajdować hotspot ikony (który jest oparty na początku).
Jeśli używasz etykiety ze znacznikiem niestandardowym, możesz ją umieścić za pomocą właściwości labelOrigin w obiekcie Icon.
TypeScript
// The following example creates complex markers to indicate beaches near // Sydney, NSW, Australia. Note that the anchor is set to (0,32) to correspond // to the base of the flagpole. function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 10, center: { lat: -33.9, lng: 151.2 }, } ); setMarkers(map); } // Data for the markers consisting of a name, a LatLng and a zIndex for the // order in which these markers should display on top of each other. const beaches: [string, number, number, number][] = [ ["Bondi Beach", -33.890542, 151.274856, 4], ["Coogee Beach", -33.923036, 151.259052, 5], ["Cronulla Beach", -34.028249, 151.157507, 3], ["Manly Beach", -33.80010128657071, 151.28747820854187, 2], ["Maroubra Beach", -33.950198, 151.259302, 1], ]; function setMarkers(map: google.maps.Map) { // Adds markers to the map. // Marker sizes are expressed as a Size of X,Y where the origin of the image // (0,0) is located in the top left of the image. // Origins, anchor positions and coordinates of the marker increase in the X // direction to the right and in the Y direction down. const image = { url: "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png", // This marker is 20 pixels wide by 32 pixels high. size: new google.maps.Size(20, 32), // The origin for this image is (0, 0). origin: new google.maps.Point(0, 0), // The anchor for this image is the base of the flagpole at (0, 32). anchor: new google.maps.Point(0, 32), }; // Shapes define the clickable region of the icon. The type defines an HTML // <area> element 'poly' which traces out a polygon as a series of X,Y points. // The final coordinate closes the poly by connecting to the first coordinate. const shape = { coords: [1, 1, 1, 20, 18, 20, 18, 1], type: "poly", }; for (let i = 0; i < beaches.length; i++) { const beach = beaches[i]; new google.maps.Marker({ position: { lat: beach[1], lng: beach[2] }, map, icon: image, shape: shape, title: beach[0], zIndex: beach[3], }); } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// The following example creates complex markers to indicate beaches near // Sydney, NSW, Australia. Note that the anchor is set to (0,32) to correspond // to the base of the flagpole. function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 10, center: { lat: -33.9, lng: 151.2 }, }); setMarkers(map); } // Data for the markers consisting of a name, a LatLng and a zIndex for the // order in which these markers should display on top of each other. const beaches = [ ["Bondi Beach", -33.890542, 151.274856, 4], ["Coogee Beach", -33.923036, 151.259052, 5], ["Cronulla Beach", -34.028249, 151.157507, 3], ["Manly Beach", -33.80010128657071, 151.28747820854187, 2], ["Maroubra Beach", -33.950198, 151.259302, 1], ]; function setMarkers(map) { // Adds markers to the map. // Marker sizes are expressed as a Size of X,Y where the origin of the image // (0,0) is located in the top left of the image. // Origins, anchor positions and coordinates of the marker increase in the X // direction to the right and in the Y direction down. const image = { url: "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png", // This marker is 20 pixels wide by 32 pixels high. size: new google.maps.Size(20, 32), // The origin for this image is (0, 0). origin: new google.maps.Point(0, 0), // The anchor for this image is the base of the flagpole at (0, 32). anchor: new google.maps.Point(0, 32), }; // Shapes define the clickable region of the icon. The type defines an HTML // <area> element 'poly' which traces out a polygon as a series of X,Y points. // The final coordinate closes the poly by connecting to the first coordinate. const shape = { coords: [1, 1, 1, 20, 18, 20, 18, 1], type: "poly", }; for (let i = 0; i < beaches.length; i++) { const beach = beaches[i]; new google.maps.Marker({ position: { lat: beach[1], lng: beach[2] }, map, icon: image, shape: shape, title: beach[0], zIndex: beach[3], }); } } window.initMap = initMap;
Konwertowanie obiektów MarkerImage na typ Icon
Do wersji 3.10 interfejsu Maps JavaScript API złożone ikony
były definiowane jako MarkerImage obiekty. Literał obiektu
Icon został dodany w wersji 3.10 i zastępuje
MarkerImage od wersji 3.11.
Literały obiektu Icon obsługują te same parametry co
MarkerImage, co pozwala łatwo przekonwertować MarkerImage na Icon, usuwając
konstruktor, otaczając poprzednie parametry nawiasami {}'s i
dodając nazwy każdego parametru. Na przykład:
var image = new google.maps.MarkerImage( place.icon, new google.maps.Size(71, 71), new google.maps.Point(0, 0), new google.maps.Point(17, 34), new google.maps.Size(25, 25));
zmienia się w
var image = { url: place.icon, size: new google.maps.Size(71, 71), origin: new google.maps.Point(0, 0), anchor: new google.maps.Point(17, 34), scaledSize: new google.maps.Size(25, 25) };
Optymalizowanie znaczników
Optymalizacja zwiększa wydajność, renderując wiele znaczników jako jeden element statyczny. Jest to przydatne w przypadkach, gdy wymagana jest duża liczba znaczników. Domyślnie interfejs Maps JavaScript API decyduje czy znacznik będzie zoptymalizowany. Gdy jest duża liczba znaczników, interfejs Maps JavaScript API próbuje renderować znaczniki z optymalizacją. Nie wszystkie znaczniki można zoptymalizować. W niektórych sytuacjach interfejs Maps JavaScript API może renderować znaczniki bez optymalizacji. Wyłącz zoptymalizowane renderowanie animowanych plików GIF lub PNG albo gdy każdy znacznik musi być renderowany jako osobny element DOM. Ten przykład pokazuje, jak utworzyć zoptymalizowany znacznik:
var marker = new google.maps.Marker({ position: myLatlng, title:"Hello World!", optimized: true });
Udostępnianie znacznika
Aby udostępnić znacznik, dodaj detektor kliknięć i
ustaw optimized na false. Detektor kliknięć sprawia, że znacznik ma semantykę przycisku, do którego można uzyskać dostęp za pomocą nawigacji klawiaturowej, czytników ekranu itp. Użyj opcji
title, aby wyświetlić tekst dostępny dla znacznika.
W tym przykładzie pierwszy znacznik otrzymuje fokus po naciśnięciu klawisza Tab . Następnie możesz użyć klawiszy strzałek, aby przechodzić między znacznikami. Naciśnij ponownie klawisz Tab, aby kontynuować przechodzenie przez pozostałe elementy sterujące mapy. Jeśli znacznik ma okno informacyjne, możesz je otworzyć, klikając znacznik lub naciskając klawisz Enter albo spację, gdy znacznik jest zaznaczony. Po zamknięciu okna informacyjnego fokus powróci do powiązanego znacznika.
TypeScript
// The following example creates five accessible and // focusable markers. function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 12, center: { lat: 34.84555, lng: -111.8035 }, } ); // Set LatLng and title text for the markers. The first marker (Boynton Pass) // receives the initial focus when tab is pressed. Use arrow keys to // move between markers; press tab again to cycle through the map controls. const tourStops: [google.maps.LatLngLiteral, string][] = [ [{ lat: 34.8791806, lng: -111.8265049 }, "Boynton Pass"], [{ lat: 34.8559195, lng: -111.7988186 }, "Airport Mesa"], [{ lat: 34.832149, lng: -111.7695277 }, "Chapel of the Holy Cross"], [{ lat: 34.823736, lng: -111.8001857 }, "Red Rock Crossing"], [{ lat: 34.800326, lng: -111.7665047 }, "Bell Rock"], ]; // Create an info window to share between markers. const infoWindow = new google.maps.InfoWindow(); // Create the markers. tourStops.forEach(([position, title], i) => { const marker = new google.maps.Marker({ position, map, title: `${i + 1}. ${title}`, label: `${i + 1}`, optimized: false, }); // Add a click listener for each marker, and set up the info window. marker.addListener("click", () => { infoWindow.close(); infoWindow.setContent(marker.getTitle()); infoWindow.open(marker.getMap(), marker); }); }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// The following example creates five accessible and // focusable markers. function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 12, center: { lat: 34.84555, lng: -111.8035 }, }); // Set LatLng and title text for the markers. The first marker (Boynton Pass) // receives the initial focus when tab is pressed. Use arrow keys to // move between markers; press tab again to cycle through the map controls. const tourStops = [ [{ lat: 34.8791806, lng: -111.8265049 }, "Boynton Pass"], [{ lat: 34.8559195, lng: -111.7988186 }, "Airport Mesa"], [{ lat: 34.832149, lng: -111.7695277 }, "Chapel of the Holy Cross"], [{ lat: 34.823736, lng: -111.8001857 }, "Red Rock Crossing"], [{ lat: 34.800326, lng: -111.7665047 }, "Bell Rock"], ]; // Create an info window to share between markers. const infoWindow = new google.maps.InfoWindow(); // Create the markers. tourStops.forEach(([position, title], i) => { const marker = new google.maps.Marker({ position, map, title: `${i + 1}. ${title}`, label: `${i + 1}`, optimized: false, }); // Add a click listener for each marker, and set up the info window. marker.addListener("click", () => { infoWindow.close(); infoWindow.setContent(marker.getTitle()); infoWindow.open(marker.getMap(), marker); }); }); } window.initMap = initMap;
Animowanie znacznika
Możesz animować znaczniki, aby w różnych okolicznościach wykazywały dynamiczny ruch. Aby określić sposób animowania znacznika, użyj
właściwości animation znacznika typu
google.maps.Animation. Obsługiwane są te
Animation wartości:
-
DROPoznacza, że po pierwszym umieszczeniu na mapie znacznik powinien spaść z góry mapy do swojej ostatecznej lokalizacji. Animacja ustanie, gdy znacznik się zatrzyma, aanimationpowróci donull. Ten typ animacji jest zwykle określany podczas tworzeniaMarker. -
BOUNCEoznacza, że znacznik powinien się odbijać w miejscu. Odbijający się znacznik będzie się odbijać, dopóki jegoanimationwłaściwość nie zostanie wyraźnie ustawiona nanull.
Możesz rozpocząć animację na istniejącym znaczniku, wywołując
setAnimation() na obiekcie Marker.
TypeScript
// The following example creates a marker in Stockholm, Sweden using a DROP // animation. Clicking on the marker will toggle the animation between a BOUNCE // animation and no animation. let marker: google.maps.Marker; function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 13, center: { lat: 59.325, lng: 18.07 }, } ); marker = new google.maps.Marker({ map, draggable: true, animation: google.maps.Animation.DROP, position: { lat: 59.327, lng: 18.067 }, }); marker.addListener("click", toggleBounce); } function toggleBounce() { if (marker.getAnimation() !== null) { marker.setAnimation(null); } else { marker.setAnimation(google.maps.Animation.BOUNCE); } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// The following example creates a marker in Stockholm, Sweden using a DROP // animation. Clicking on the marker will toggle the animation between a BOUNCE // animation and no animation. let marker; function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 13, center: { lat: 59.325, lng: 18.07 }, }); marker = new google.maps.Marker({ map, draggable: true, animation: google.maps.Animation.DROP, position: { lat: 59.327, lng: 18.067 }, }); marker.addListener("click", toggleBounce); } function toggleBounce() { if (marker.getAnimation() !== null) { marker.setAnimation(null); } else { marker.setAnimation(google.maps.Animation.BOUNCE); } } window.initMap = initMap;
Jeśli masz wiele znaczników, możesz nie chcieć umieszczać ich na mapie jednocześnie. Możesz użyć setTimeout(), aby rozłożyć swoje
znaczniki' animacje za pomocą wzorca podobnego do tego, który pokazujemy poniżej:
function drop() { for (var i =0; i < markerArray.length; i++) { setTimeout(function() { addMarkerMethod(); }, i * 200); } }
Umożliwianie przeciągania znacznika
Aby umożliwić użytkownikom przeciąganie znacznika w inne miejsce na mapie, ustaw
draggable na true w opcjach znacznika.
var myLatlng = new google.maps.LatLng(-25.363882,131.044922); var mapOptions = { zoom: 4, center: myLatlng } var map = new google.maps.Map(document.getElementById("map"), mapOptions); // Place a draggable marker on the map var marker = new google.maps.Marker({ position: myLatlng, map: map, draggable:true, title:"Drag me!" });
Dalsze dostosowywanie znacznika
Więcej informacji o rozszerzeniach klasy Marker, rozwiązaniu do łączenia znaczników w klastry i zarządzaniu nimi oraz dostosowywaniu nakładek znajdziesz w bibliotekach open source.