How to center the infobubble when marker is clicked? - javascript

im using the infobubble from googlemaps api V3.
I have an event which is on my markers and each time it gets clicked I get a bubble.
I used infobox and infowindow before and they always positioned themselves in the center of the map when i clicked on the marker, if my knowledge of them both is correct then this was accomplished by the pixelOffset property.
Infobubble however does not give me the same effect, i get this:
My code:
google.maps.event.addListener(marker, 'click', function() {
$.ajax({
url: '/templates/GoogleMapsMarkerInfo.aspx?id=' + page + '&epslanguage=<%=CurrentPage.LanguageBranch %>',
dataType: "html",
success: function(data){
var myOptions = {
content: data,
maxWidth: 300,
shadowStyle: 1,
padding: 0,
backgroundColor: '#fff',
borderRadius: 15,
arrowSize: 7,
borderWidth: 1,
borderColor: 'blue',
disableAutoPan: true,
hideCloseButton: false,
arrowPosition: 25,
backgroundClassName: 'phoney',
arrowStyle: 2
};
if(infoBubble.getContent()!="")
infoBubble.close()
infoBubble.setOptions(myOptions)
infoBubble.open(map, marker);
}
});
To clarify:
I wan't the bubble to get centerd on the map so that the entire information is shown, I don't want to be forced to drag on the map to see the entire bubble.
If more info is needed ask and i will do my best to provide it.

Only set disableAutoPan to False.

Related

(Closed) Leaflet.js: How I can Do Editing Geometry On Specific Object I Select Only?

I am very excited and lot of fun playing with Leaflet.JS on gis mapping stuff. I am newbie. I also very appreciate with bro #Grzegorz T. with the kindness and helping me on introduction me to Leaflet.JS.
Now, I am plan to do Editing geometry on specific object I select only. I already think how the flow and the result but the process???(hahahaa..). I also already know regarding DrawItems function on Leaflet.JS but I will use.
Let me describe simple flow before I do it...
A. I just using jsfiddle1 #Grzegorz T.
B. I add DrawItems
...
{ 'DrawLayer': drawnItems }, { position: 'topleft', collapsed: false }).addTo(map);
...
//Add Draw Control//
map.addControl(new L.Control.Draw({
edit: {
featureGroup: drawnItems,
poly: {
allowIntersection: false
}
},
draw: {
polygon: {
allowIntersection: false,
showArea: true
}
}
}));
//Draw Objects//
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
//Get Leaflet Object ID
drawnItems.on('click', function(event) {
console.log("from drawnItems: " + event.layer._leaflet_id);
});
//Get Geometry from Layer & ID
//Edit Only This Objects
//Save This Editing Back to Original Layer & ID
on this part I saw a Problem is:
1. I don't know how to copy original geometry I selected from layer to DrawLayer.
2. Hide only this geometry(id) on original layer until end of editing or cancel. (maybe change opacity to invisible)
3. After finish editing and while saving How I can save back to original layer and show the result to map.
I hope whos hardcore and whos already found the easy way on Leaflet.JS can help me for this dirty work....
Update 3/3/2022
I found how to restyle the object(geometry) I selecting and this was cover for:
2. Hide only this geometry(id) on original layer until end of editing or cancel. (maybe change opacity to invisible)
Code like below:-
onEachFeature: function (feature, layer) {
//restyle the geom when display
layer.setStyle({
fillColor: "white",
weight: 2,
color: "#eb4034",
fillOpacity: 0.7,
});
layer.on("mouseover", function (e) {
// style
this.setStyle({
fillColor: "#eb4034",
weight: 2,
color: "#eb4034",
fillOpacity: 0.7,
});
});
layer.on("mouseout", function () {
// style
this.setStyle({
fillColor: "#3388ff",
weight: 2,
color: "#3388ff",
fillOpacity: 0.1,
});
});
layer.on("click", function () {
this.setStyle({
fillColor: "transparent",
weight: 0,
color: "transparent",
fillOpacity: 0,
});
});
},
Update 4/3/2022
Anyone can help me how to passing geometry to drawnitems programmatically with editing mode? Let say I have whatever geometry like this below:-
......
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[16.3716,54.4414],[16.3946,54.4477],[16.4315,54.487],[16.4797,54.5164],[16.4968,54.5231],[16.5299,54.5407],[16.6145,54.5598],[16.6887,54.5696],[16.6991,54.5692],[16.7126,54.5542],[16.7392,54.5384],[16.7481,54.5276],[16.7392,54.5177],[16.7566,54.4946],[16.764,54.4861],[16.7933,54.4874],[16.8275,54.4648],[16.8211,54.4563],......
........
,"properties":{"id":4,"nazwa":"zachodniopomorskie"},"id":3}
How I can pass this polygon (geometry) into drawnItems layer programmatically?
Please help me and thanks you on advance for read this message.
After struggling a few days finally I found solutions to accomplish my task. It's not pretty but at least I fill ok and all I need are there.
I using
layer.on("click", function(e) {
to get the geometry and id from original layer. The original geometry I pass to drawnItems by using
geojsonLayer = L.geoJson(oriGeom);
geojsonLayer.getLayers()[0].addTo(drawnItems);
to draw back on drawing layer to do editing. On mean while I adjust the style on original geometry to invisible. The editable geometry only can see on this stage where user 'think' this is original geometry he/she do editing right now.
onEachFeature: function (feature, layer) {
//restyle the geom when display
layer.setStyle({
fillColor: "white",
weight: 2,
color: "#eb4034",
fillOpacity: 0.7,
});
layer.on("mouseover", function (e) {
// style
this.setStyle({
fillColor: "#eb4034",
weight: 2,
color: "#eb4034",
fillOpacity: 0.7,
});
});
layer.on("mouseout", function () {
// style
this.setStyle({
fillColor: "#3388ff",
weight: 2,
color: "#3388ff",
fillOpacity: 0.1,
});
});
layer.on("click", function () {
this.setStyle({
fillColor: "transparent",
weight: 0,
color: "transparent",
fillOpacity: 0,
});
After finish the editing I save back to original layer by using Python class by search ID and replace the original coordinates to new coordinates (editGeom) only. :)
Then I delete all object inside drawnItems layer by this trick
document.querySelector(".leaflet-draw-edit-remove").click(); //fake click Delete
document.querySelector("ul li:last-child a").click(); //fake click Save All
That's all.

leaflet pane style.pointerEvents = none

I tried the Interactive Choropleth Map Example form https://leafletjs.com/examples/choropleth/
added a geocoder that places a circle.
But the circle overlays my geojson layer and therefore clicking and hover dosen't work anymore in this area.
I checked out panes tutorial an try to adapt to it. But still not clickable.
Here is a jsfriddle for demonstration https://jsfiddle.net/fhepqrnz/1/
Use the search (right corner) to search for NewYork. Then the circle is drawn. But the state in this area is not anymore highlighted.
// Search
map.createPane('searchradius');
map.getPane('searchradius').style.zIndex = 650;
map.getPane('searchradius').style.pointerEvents = 'none';
var geocoder = L.Control.geocoder({
defaultMarkGeocode: false
})
.on('markgeocode', function(e) {
console.log(e.geocode);
var center = e.geocode.center;
var circle = L.circle(center, {
color: 'red',
fillColor: '#f03',
fillOpacity: 0,
radius: 15000,
pane: 'searchradius'
}).addTo(map);
map.fitBounds(circle.getBounds());
})
.addTo(map);
Glad if someone have the answer for this.
Tanks to the hint of #IvanSanchez i figured it out.
The interactive: flase is the key
.on('markgeocode', function(e) {
console.log(e.geocode);
var center = e.geocode.center;
var circle = L.circle(center, {
color: 'red',
fillColor: '#f03',
fillOpacity: 0,
radius: 15000,
pane: 'searchradius',
interactive: false
}).addTo(map);
map.fitBounds(circle.getBounds());
})

layered markers don't allow click-through when using 'poly' shape

I am having an issue with layered markers in the Google Maps API when trying to open an InfoWindow on mouseover. I have created a sample fiddle using Google's Complex Items documentation example.
The beachflag marker is a complex shape and uses a 'poly' element to define the area for the mouseover. This allows the mouseover to only appear when the cursor is on the upper half of the img where the flag part actually is.
var map_marker = new google.maps.Marker({
position: new google.maps.LatLng(-33.890542, 151.274856),
map: map,
shape: {
coords: [1, 1, 1, 20, 18, 20, 18, 1],
type: 'poly'
},
zIndex: 101,
optimized: false,
icon: "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png"
});
The circle marker is situated behind the flag and is intended to be overlapped by the flag.
var map_marker = new google.maps.Marker({
position: new google.maps.LatLng(-33.890542, 151.274856),
map: map,
zIndex: 100,
optimized: false,
icon: {
path: google.maps.SymbolPath.CIRCLE,
fillColor: "#0FF",
fillOpacity: 1,
strokeWeight: 1.5,
scale: 40
}
});
I have a mouseover event displaying an InfoWindow for both markers but the problem lies in the small area underneath the flag marker polygon, there is a void where the circle InfoWindow is expected to be show, but doesn't.
One possible resolution to this is to turn the circle marker into a straight Circle, however I need my circle to be a fixed size and not scale with my zoom level.
How can I see the lower-level marker through the upper-level marker's "empty space" outside of its defined poly shape, and correctly display the mouseover InfoWindow?

google maps addListener not working properly

i have a separate code for google maps v3. Just for show infowindow infobox in my google fusion kml layer when i click on it. Yesterday my code is work fine. i didn't make any change. but today my addListner not working. when i copy my back up project, same as code. it work again but tomorrow that happens again. My addListener not work.
here's my code
infoBubble = new InfoBubble({
map: map,
shadowStyle: 1,
padding: 5,
borderRadius: 4,
arrowSize: 20,
borderWidth: 1,
borderColor: '#2c2c2c',
disableAutoPan: true,
hideCloseButton: false,
backgroundClassName: 'phoney',
arrowStyle: 2,
});
function get_details(mode,id,lati,lng)
{
$('#loading').show();
if (xhr != null)
{
xhr.abort();
}
xhr = $.ajax({
type: "GET",
url: "realisasi2.php?id="+id,
data: "m="+mode+"&id="+id,
success: function(ret){
ajaxres = JSON.parse(ret);
iconpos = new google.maps.LatLng(lati,lng);
psbchurndata = ajaxres.detail;
var html = psbchurndata+"<i><a class='ajax' href='#' onclick=layer22("+id+","+lati+","+lng+") style='font-family: Arial;font-size: 12px; color:#00CC29;'>Lihat Datel </a></i>";
infoBubble.setContent('<div class="infowindow"><br />'+html+'</div>');
infoBubble.setPosition(iconpos);
infoBubble.close();
infoBubble.open(map);
$('#loading').hide();
}
});
}
layer.setMap(map);
google.maps.event.addListener(layer, 'click', function(e) {
alert(JSON.stringify(e, null, 4)); //UNDIFINED not Working
var lati = e.latLng['mb'];
var lng = e.latLng['nb'];
var x = e.row['id_witel'].value;
get_details('w',e.row['id_witel'].value,lati,lng);
});
}
thank's for any help
There are no "official" properties mb and nb for a google.maps.LatLng(that's what e.latLng is) . These properties will be used internally by the API, the names of these properties may change the next moment, hour or day.
To retrieve latitude and longitude use the methods lat() and lng() of e.latLng

google maps api v3 infoBubble array not working

I have a map that uses infoBubble.js.
In this map there is an array of locations that I iterate through.
The infoBubble should pop up when the custom icon is clicked but for some reason it only ever opens up the first data item.
Does anyone have an idea as to why that may happen?
I have developed the code for it here;
var arrMarkers = [
['Santiago de Cuba', 20.040450354169483, -75.8331298828125],
['Las Tunas', 20.97682772467435, -76.9482421875],
['Camaguey', 21.39681937408218, -77.9205322265625],
['Playa Santa Lucia', 21.555284406923192, -77.0526123046875],
['Santa Clara', 22.421184710331854, -79.9639892578125],
['Cienfuegos', 22.161970614367977, -80.4473876953125],
['Havana', 23.12520549860231, -82.3919677734375],
['San Cristobel', 22.730590425493833, -83.045654296875],
['Pinar del Rio', 22.43641760076311, -83.69384765625]
];
var arrInfoWindowsCuba = [];
var arrInfoWindows = [];
arrMarkers[i] = marker;
function init() {
var mapCenter = new google.maps.LatLng(21.616579336740603, -78.892822265625);
map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 7,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.TERRAIN
});
var image = '/wp-content/themes/Shootcuba/images/map-icon.png';
for (i = 0; i < arrMarkers.length; i++) {
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(arrMarkers[i][1], arrMarkers[i][2]),
icon: image
});
var infoBubble = new InfoBubble({
content: '<div class="phoneytext">' + arrMarkers[i][0] + '<div class="left-col2"></div></div>',
boxClass: 'info-box',
alignBottom: true,
pixelOffset: new google.maps.Size(-150, -40),
maxWidth: 300,
padding: 0,
closeBoxMargin: '0px',
borderColor: '#ffffff',
borderRadius: '0',
maxWidth: 535,
disableAutoPan: false,
hideCloseButton: false,
backgroundClassName: 'phoney'
});
google.maps.event.addListener(marker, 'click', function () {
infoBubble.open(map, marker, i);
console.log(arrMarkers);
});
arrMarkers[i] = marker;
arrInfoWindowsCuba[i] = infoBubble;
}
}
Here's a working example. I took out a few of the arrays you had (I wasn't entirely sure what they were all for, and they were causing errors in just the snippet you posted), but otherwise is pretty true to what you were doing. The big difference is that I made a separate function for creating the markers. This was mainly done to keep the scope of the click events separate from one another, since the click event always triggering the last event indicates to me that the scopes aren't properly separate.
In particular, what I believe was happening is that the event function you kept overriding values to marker and infoBubble, and the event listener would refer to the current values of those variables, not the values when you first attach the listener. Making a separate function call to maintain the scope for the events strikes me as the cleanest solution.

Categories

Resources