É possível escrever texto personalizado na API v3 do Google Maps?
é possível escrever texto personalizado na API v3 do Google Maps, ao lado do marcador? ou posso usar apenas a janela de informação para fazer isso?
5 answers
Para mostrar o texto personalizado, precisa de criar uma sobreposição personalizada. Abaixo está um exemplo adaptado da documentação oficial do Google. Você também poderia usar Esta biblioteca para mais janelas de informação "elegantes"
<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false">
</script>
<script>
//adapded from this example http://code.google.com/apis/maps/documentation/javascript/overlays.html#CustomOverlays
//text overlays
function TxtOverlay(pos, txt, cls, map) {
// Now initialize all properties.
this.pos = pos;
this.txt_ = txt;
this.cls_ = cls;
this.map_ = map;
// We define a property to hold the image's
// div. We'll actually create this div
// upon receipt of the add() method so we'll
// leave it null for now.
this.div_ = null;
// Explicitly call setMap() on this overlay
this.setMap(map);
}
TxtOverlay.prototype = new google.maps.OverlayView();
TxtOverlay.prototype.onAdd = function() {
// Note: an overlay's receipt of onAdd() indicates that
// the map's panes are now available for attaching
// the overlay to the map via the DOM.
// Create the DIV and set some basic attributes.
var div = document.createElement('DIV');
div.className = this.cls_;
div.innerHTML = this.txt_;
// Set the overlay's div_ property to this DIV
this.div_ = div;
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
div.style.left = position.x + 'px';
div.style.top = position.y + 'px';
// We add an overlay to a map via one of the map's panes.
var panes = this.getPanes();
panes.floatPane.appendChild(div);
}
TxtOverlay.prototype.draw = function() {
var overlayProjection = this.getProjection();
// Retrieve the southwest and northeast coordinates of this overlay
// in latlngs and convert them to pixels coordinates.
// We'll use these coordinates to resize the DIV.
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
var div = this.div_;
div.style.left = position.x + 'px';
div.style.top = position.y + 'px';
}
//Optional: helper methods for removing and toggling the text overlay.
TxtOverlay.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
TxtOverlay.prototype.hide = function() {
if (this.div_) {
this.div_.style.visibility = "hidden";
}
}
TxtOverlay.prototype.show = function() {
if (this.div_) {
this.div_.style.visibility = "visible";
}
}
TxtOverlay.prototype.toggle = function() {
if (this.div_) {
if (this.div_.style.visibility == "hidden") {
this.show();
} else {
this.hide();
}
}
}
TxtOverlay.prototype.toggleDOM = function() {
if (this.getMap()) {
this.setMap(null);
} else {
this.setMap(this.map_);
}
}
var map;
function init() {
var latlng = new google.maps.LatLng(37.9069, -122.0792);
var myOptions = {
zoom: 4,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: "Hello World!"
});
customTxt = "<div>Blah blah sdfsddddddddddddddd ddddddddddddddddddddd<ul><li>Blah 1<li>blah 2 </ul></div>"
txt = new TxtOverlay(latlng, customTxt, "customBox", map)
}
</script>
<style>
.customBox {
background: yellow;
border: 1px solid black;
position: absolute;
}
</style>
</head>
<body onload="init()">
<div id="map" style="width: 600px; height: 600px;">
</div>
</body>
</html>
, de longe, a maneira mais fácil de adicionar uma Sobreposição de Texto é usar o MapLabel
classe de https://github.com/googlemaps/js-map-label
var mapLabel = new MapLabel({
text: 'Test',
position: new google.maps.LatLng(50,50),
map: map,
fontSize: 20,
align: 'right'
});
Se o texto for estático, pode usar um marcador e uma imagem:
var label = new google.maps.Marker({
position: new google.maps.LatLng(50,50),
map: map,
icon: "/images/mytextasanimage.png"
});
A última API (v3) recomenda a utilização de {[[2]} e uma chamada de resposta quando a API Maps é carregada.
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
Para fazer isto funcionar, é necessário definir a classe de sobreposição a partir de dentro (ou depois) da inicialização quando a classe google
tiver sido definida. Caso contrário, obterá erros google not defined
.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 40, lng: -30 },
zoom: 3
});
TxtOverlay.prototype = new google.maps.OverlayView();
var overlay = new TxtOverlay(new google.maps.LatLng(0, 0),
"<div>Have a wonderful overlay day</div>",
"customCSSClass",
map);
}
...
//adapded from answer above
function TxtOverlay(pos, txt, cls, map) {
// Now initialize all properties.
this.pos = pos;
this.txt_ = txt;
this.cls_ = cls;
this.map_ = map;
// We define a property to hold the image's
// div. We'll actually create this div
// upon receipt of the add() method so we'll
// leave it null for now.
this.div_ = null;
this.onAdd = function() {
// Note: an overlay's receipt of onAdd() indicates that
// the map's panes are now available for attaching
// the overlay to the map via the DOM.
// Create the DIV and set some basic attributes.
var div = document.createElement('DIV');
div.className = this.cls_;
div.innerHTML = this.txt_;
// Set the overlay's div_ property to this DIV
this.div_ = div;
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
div.style.left = position.x + 'px';
div.style.top = position.y + 'px';
// We add an overlay to a map via one of the map's panes.
var panes = this.getPanes();
panes.floatPane.appendChild(div);
}
this.draw = function() {
var overlayProjection = this.getProjection();
// Retrieve the southwest and northeast coordinates of this overlay
// in latlngs and convert them to pixels coordinates.
// We'll use these coordinates to resize the DIV.
var position = overlayProjection.fromLatLngToDivPixel(this.pos);
var div = this.div_;
div.style.left = position.x + 'px';
div.style.top = position.y + 'px';
}
this.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
this.hide = function() {
if (this.div_) {
this.div_.style.visibility = "hidden";
}
}
this.show = function() {
if (this.div_) {
this.div_.style.visibility = "visible";
}
}
this.toggle = function() {
if (this.div_) {
if (this.div_.style.visibility == "hidden") {
this.show();
} else {
this.hide();
}
}
}
this.toggleDOM = function() {
if (this.getMap()) {
this.setMap(null);
} else {
this.setMap(this.map_);
}
}
// Explicitly call setMap() on this overlay
this.setMap(map);
}
**HERE IS THE CODE WHICH IS WORKING & YOU CAN ALSO CHANGE SOURCE AND DESTINATION AND SEE THE MAGIC OF MAP MOVING**
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
#map {
height: 500px;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div id="content">
<div id="map"></div>
<div class="centered">
<h1>Text Over Maps</h1>
</div>
<script type="text/javascript">
const path = "kzoyC{ylyNhDjJlAnGnAnCLjBS|IdAvPLdC^v@hDvExRxUdKtKxP|NbRrMpQhL~AfBzDrGtFrK`Zvs@vO~b@tJ~ZbAdCfDvH|B|HjDlNvAhFhBpDtCjInHjXbHbPzHnQ~ExJR|Ar@`ItB`ErAlDt@zFTzFg@hGaAnFDfCbHba@dGl_@rFn_@p@fIJzAl@fAd@R[fBq@rEu@jEwAxKYrJP`Nj@fIlCnV|D|[hF|XfMp}@D|HsA~ToCpm@cCte@iArMmBbKkZziAeVh~@_HpYsDzRcE~]oMnkAqAzWkBho@h@zPxBhPnHdWfJdXnLzXfRhe@~Qzf@`BrGtD~SnE`Y|CnWfHng@hIjp@fEfRpBxHZvCzAtY@vX~@lI|Ux~@vPrj@t@hGDvGMtSVz^jAzZ~@dLhD~XzD|T^zJ|@pGxM`f@hAjFhAhPB`Ho@zJoEpd@_@zK{@`LyKnn@qH|[u@zHGtH~@`Sk@rG}Jt[cFzUwB`Qw@vKGhLl@la@SdGaCzTgHxq@iF~i@wGvy@qDhl@iA`VHzT~@he@`AfPx@zGZhHRzPfFnf@p@|NL|ZWrPs@`N_D`b@kCxWcIjp@sGhb@aIdZ{J|\\kN~f@iExPuCxPsFj[}E`UuLfj@uObu@eAtEcCfG{JpVoBxMmSnq@cZr`AiMje@sDrg@qEtf@cFvUeE|VwCnPmEjRaKhe@mChLkFvL}`@b|@aKnTaDvJgCvPk@jN}CpaA}Al[}G~[sInb@oo@bvBgShm@aL|]uG|TqAzI_Bl\\O~Sl@|HBbIa@xXiAjPsDp\\oPxg@qPb`@yNd[wWrh@sC~GaB`HqFj_@{AnOqClRuKla@oR~q@yKr]gCdViGtx@[|L}AnL{A|Jy@xKk@~[aAxSgHx{@iA~GuKjV}BjF[jGbAdEhEbGnBnDd@tD_@xE{ErKyBdEkBtFqFj_@uFj[u@fL?pK_@vHsFtp@iEbg@@`LIfHeCdQqLjx@qM~n@oEtQoHvPwHjPeHtQuRhl@uIbWcCjDwPdLkMhKuAnBgBdFuNln@y@dA_A^wAhC}_@riAee@llAki@xdBmGhTuHv`@mLj}@qFng@oExo@k@pTF`KrB`h@bBbdAbB|u@h@bc@aBpNeMze@gBzJa@z@WZ}BrK[hIj@nGhBvJpDlMbBjKGlKaChMaMhi@eDtNc@tKCtKi@|D}CvLo^ltAc[|kAkIr\\_@rD?lCbAfJfIfWtBpHvBxLA@A@AB?BFB@R~@vFvB|IdCjOhAhK~AfIzE|Xl@pE"
let flightPlanCoordinates = []
function initMap() {
flightPlanCoordinates = [].concat(google.maps.geometry.encoding.decodePath(path)).reverse()
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 9,
center: flightPlanCoordinates[0],
mapTypeId: 'terrain',
styles: [
{ elementType: 'geometry', stylers: [{ color: '#242f3e' }] },
{ elementType: 'labels.text.stroke', stylers: [{ color: '#242f3e' }] },
{ elementType: 'labels.text.fill', stylers: [{ color: '#746855' }] },
{
featureType: 'administrative.locality',
elementType: 'labels.text.fill',
stylers: [{ color: '#d59563' }]
},
{
featureType: 'poi',
elementType: 'labels.text.fill',
stylers: [{ color: '#d59563' }]
},
{
featureType: 'poi.park',
elementType: 'geometry',
stylers: [{ color: '#263c3f' }]
},
{
featureType: 'poi.park',
elementType: 'labels.text.fill',
stylers: [{ color: '#6b9a76' }]
},
{
featureType: 'road',
elementType: 'geometry',
stylers: [{ color: '#38414e' }]
},
{
featureType: 'road',
elementType: 'geometry.stroke',
stylers: [{ color: '#212a37' }]
},
{
featureType: 'road',
elementType: 'labels.text.fill',
stylers: [{ color: '#9ca5b3' }]
},
{
featureType: 'road.highway',
elementType: 'geometry',
stylers: [{ color: '#746855' }]
},
{
featureType: 'road.highway',
elementType: 'geometry.stroke',
stylers: [{ color: '#1f2835' }]
},
{
featureType: 'road.highway',
elementType: 'labels.text.fill',
stylers: [{ color: '#f3d19c' }]
},
{
featureType: 'transit',
elementType: 'geometry',
stylers: [{ color: '#2f3948' }]
},
{
featureType: 'transit.station',
elementType: 'labels.text.fill',
stylers: [{ color: '#d59563' }]
},
{
featureType: 'water',
elementType: 'geometry',
stylers: [{ color: '#17263c' }]
},
{
featureType: 'water',
elementType: 'labels.text.fill',
stylers: [{ color: '#515c6d' }]
},
{
featureType: 'water',
elementType: 'labels.text.stroke',
stylers: [{ color: '#17263c' }]
}
]
});
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
marker = new google.maps.Marker({
icon: {
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(10, 32)
}, position: flightPlanCoordinates[0], map: map
});
marker.setMap(map);
//setTimeout(() => {
moveBus(map, marker);
//}, 1000)
function moveBus(map, marker) {
let j = 0;
//marker.setPosition( flightPlanCoordinates[200] );
//console.log(flightPlanCoordinates[0])
flightPlanCoordinates.forEach((i) => {
setTimeout(() => {
marker.setPosition(i);
//map.panTo( i );
}, j * 18)
j += 1
})
};
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCMhew4vf8sG2yizZwy4T6O5L3T98h-6U8&libraries=geometry&callback=initMap"></script>
</div>
</body>
</html>