Google Map not centering properly when in a scaling circle - javascript

I have been trying to get my head around this issue for hours now - no result so far, so I am turning to you now.
I have embedded a google map in my website. Then I gave the div a border-radius of 100% in order to make the map appear circular. So far, so good.
But when I wanted to make the circle scalable/responsive, I tried to use the old padding-bottom css-hack which I found ages ago here on stack overflow. Thanks to this trick, the circular map scales perfectly well now.
However, this also seems to set the map off center and I cannot figure out why or come to a fix. I am really looking forward to any solution here ...
Best regards,
Jan
I have a fiddle demonstrating the issue here (With complete HTML/JS/CSS) CSS below:
.cms-map-wrapper.circular {
width: 50%;
margin: auto;
background-color:red;
}
.cms-map {
border: solid 5px blue;
border-radius: 100%;
padding-bottom: 100%;
margin-bottom: 20px;
}

It is a timing problem. One option to fix it is to delay, then trigger the resize event and reset the center of the map.
setTimeout(function () {
google.maps.event.trigger(map, 'resize');
map.setCenter(position);
}, 100);
proof of concept fiddle
working code snippet:
function showMapWithAddress(mapElementId, address) {
geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
position = results[0].geometry.location;
var mapProp = {
center: position,
zoom: 14
};
var map = new google.maps.Map(document.getElementById(mapElementId), mapProp);
google.maps.event.addDomListener(window, 'resize', function() {
google.maps.event.trigger(map, 'resize');
map.setCenter(position);
});
var marker = new google.maps.Marker({
position: position,
title: address,
flat: true,
clickable: false
});
marker.setMap(map);
setTimeout(function() {
google.maps.event.trigger(map, 'resize');
map.setCenter(position);
}, 100);
} else {
console.log('Geocode was not successful for the following reason: ' + status);
}
});
}
showMapWithAddress('googleMap', 'Josef-Bautz-Strasse 14, 63457 Hanau, Germany');
.cms-map-wrapper.circular {
width: 50%;
margin: auto;
background-color: red;
}
.cms-map {
border: solid 5px blue;
border-radius: 100%;
padding-bottom: 100%;
margin-bottom: 20px;
}
<script src="http://maps.googleapis.com/maps/api/js"></script>
<div class="cms-map-wrapper circular">
<div id="googleMap" class="cms-map"></div>
</div>

Related

Geocoder failed due to: REQUEST_DENIED google maps

There I have had this error when using Geocode I know there is a lot of the same question but I wasn't able to understand it so if you guys have a solution please give me your version of my code with your code inside of it
here is my code
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: 'Roboto','sans-serif';
line-height: 30px;
padding-left: 10px;
}
#floating-panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
width: 350px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
#latlng {
width: 225px;
}
</style>
</head>
<body>
<div id="floating-panel">
<input id="latlng" type="text" value="40.714224,-73.961452">
<input id="submit" type="button" value="Reverse Geocode">
</div>
<div id="map"></div>
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 8,
center: {lat: 40.731, lng: -73.997}
});
var geocoder = new google.maps.Geocoder;
var infowindow = new google.maps.InfoWindow;
document.getElementById('submit').addEventListener('click', function() {
geocodeLatLng(geocoder, map, infowindow);
});
}
function geocodeLatLng(geocoder, map, infowindow) {
var input = document.getElementById('latlng').value;
var latlngStr = input.split(',', 2);
var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
if (results[0]) {
map.setZoom(11);
var marker = new google.maps.Marker({
position: latlng,
map: map
});
infowindow.setContent(results[0].formatted_address);
infowindow.open(map, marker);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY" async defer></script>
Thank you I hope someone could help been having this problem alot
This error indicates on a missing Google Maps API key.
https://developers.google.com/maps/documentation/javascript/get-api-key
Click the button below, to get an API key using the Google Cloud Platform Console. You will be asked to (1) pick one or more products, (2) select or create a project, and (3) set up a billing account. Once your API key is created you will be prompted to restrict the key's usage. For more information, see Restricting an API key.
(Button is present in the link)
When loading the Maps JavaScript API, substitute YOUR_API_KEY in the
code below with the API key you got from the previous step.
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" type="text/javascript"></script>
If you follow the steps beyond the link, that should fix the error you're getting.

google map API before / after function (like ajax)

I want to put a loading icon before finding or I need catch find location start/end function (like ajax before/success function)
I could not find any resources related to this .I want to do; When you click on the "Find current location" button, you will see a small icon. Hide the icon when the process is finished
I use javascript without jquery
using Geocoding service code, I added <div id="loader"></div> inside <div id="floating-panel"></div>.In this I have added image tag when geocodeAddress(geocoder, resultsMap) is called. You can change with desired icon
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 8,
center: {
lat: -34.397,
lng: 150.644
}
});
var geocoder = new google.maps.Geocoder();
document.getElementById('submit').addEventListener('click', function() {
geocodeAddress(geocoder, map);
});
}
function geocodeAddress(geocoder, resultsMap) {
document.getElementById('loader').innerHTML = "<img src='https://media.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif'>"
var address = document.getElementById('address').value;
geocoder.geocode({
'address': address
}, function(results, status) {
if (status === 'OK') {
document.getElementById('loader').innerHTML = ""
resultsMap.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location
});
} else {
document.getElementById('loader').innerHTML = ""
alert('Geocode was not successful for the following reason: ' + status);
}
});
/*google.maps.event.addListenerOnce(map, 'idle', function(){
alert()
});*/
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: 'Roboto', 'sans-serif';
line-height: 30px;
padding-left: 10px;
}
<div id="floating-panel">
<input id="address" type="textbox" value="Sydney, NSW">
<input id="submit" type="button" value="Geocode">
<div id="loader">
</div>
</div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>

How to show Google Map API only after it has completely loaded?

I'm trying to use the Places search functionality of Google Maps API.
My problem is, the search box shifts and the height of the API container changes after the map is completely loaded.
I've made a demonstration of the problem. Try refreshing the page and you'll observe the above mentioned behaviour.
I found similar questions and the suggestions were --
google.maps.event.addListenerOnce(map, 'idle', function() {
google.maps.event.trigger(map, 'resize');
});
or
window.onload = map_initialize;
However, neither of them seem to solve this shift behaviour.
One option would be to set the input to display:none, add it to the map on the idle event, then display it.
function initAutocomplete() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -33.8688,
lng: 151.2195
},
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
google.maps.event.addListenerOnce(map, 'idle', function() {
input.style.display = "block";
});
proof of concept fiddle
code snippet:
// This example adds a search box to a map, using the Google Place Autocomplete
// feature. People can enter geographical searches. The search box will return a
// pick list containing a mix of places and predicted search terms.
function initAutocomplete() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -33.8688,
lng: 151.2195
},
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
google.maps.event.addListenerOnce(map, 'idle', function() {
input.style.display = "block";
});
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
var icon = {
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)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
google.maps.event.addDomListener(window, 'load', initAutocomplete);
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
#target {
width: 345px;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<input id="pac-input" class="controls" type="text" placeholder="Search Box" style="display:none">
<div id="map"></div>
You can simply use the defer attribute for your <script> tag where you loading the google maps JS api, and a callback function to initialize your map.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Google map demo</title>
<style type="text/css">
html,
body,
#map_canvas {
width: 100%;
height: 700px;
margin: 0;
padding: 0;
}
.infowindow * {
font-size: 90%;
margin: 0
}
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?callback=initialize" defer></script>
</head>
<body>
<div id="map_canvas"></div>
</body>
<script type="text/javascript">
function initialize() {
alert("map api loaded");
// initialize map
var myOptions = {
zoom: 2,
center: new google.maps.LatLng(37.422104808, -122.0838851)
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
</script>
</html>

Draggable Icons on a Google Map V3 - Set to Draggable=True, but can not drag it

I have everything working on this Google map V3 on how I would like it except for one last thing. Right now, If you load up the map, the map is able to search for a place and drag an icon from outside the map into the Google map. However, once the icon is inside the map, I am not able to drag it. I've search endlessly on where I went wrong on my code.
Below are a few examples of many that I read on:
Link1,
Link2, Link3, Link4 (Link 4 is what i need but could not connect the code after further inspection)
I feel I am very close but I believe I am just not declaring the right variables or not connecting them right. Below is the code and here is a FIddle that can give you a picture of my problem. (Try dragging the icon once and then dragging it again inside the map)
<!DOCTYPE html>
<html>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html {
height: 100%;
}
body {
height: 97%;
}
#map-canvas {
width: 70%;
height: 100%;
}
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -30%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
#shelf {
position: absolute;
margin-right: 5px;
top: 25px;
left: 70%;
height: 98%;
width: 30%;
float: right;
}
#draggable {z-index:1000000000;}
#draggable2 {z-index:1000000000;}
#draggable3 {z-index:1000000000;}
.ecostation {
margin-left: auto;
margin-right: auto;
border: 1.0px solid #F0F0F0;
border-radius: 5.0px 5.0px 5.0px 5.0px;
width: 85%;
text-align: center;
}
#wrapper {
display: table-row;
border: 1.0px solid rgb(204,204,204);
border-radius: 5.0px 5.0px 5.0px 5.0px;
}
#wrapper div {
display: table-cell;
border-radius: 10.0px 10.0px 10.0px 10.0px;
width: 12.5%;
}
#wrapper div img {
display: block;
padding: 5.0px;
margin: 5.0px auto;
text-align: center;
}
#wrapper div h5, #wrapper div p {
text-align: center;
font-size: 11px;
margin-top: -10px;
font-weight: 800;
}
.title {
margin-left: 7%;
color: #F0F0F0;
font-weight: 600;
}
#target {
width: 345px;
}
</style>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#draggable").draggable({helper: 'clone',
stop: function(e) {
var point=new google.maps.Point(e.pageX,e.pageY);
var ll=overlay.getProjection().fromContainerPixelToLatLng(point);
var icon = $(this).attr('src');
placeMarker(ll, icon);
}
});
$("#draggable2").draggable({helper: 'clone',
stop: function(e) {
var point=new google.maps.Point(e.pageX,e.pageY);
var ll=overlay.getProjection().fromContainerPixelToLatLng(point);
var icon = $(this).attr('src');
placeMarker(ll, icon);
}
});
});
</script>
<script>
// This example adds a search box to a map, using the
// Google Places autocomplete feature. People can enter geographical searches.
// The search box will return a pick list containing
// a mix of places and predicted search terms.
function initialize() {
var markers = [];
var map = new google.maps.Map(document.getElementById('map-canvas'), {
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-33.8902, 151.1759),
new google.maps.LatLng(-33.8474, 151.2631));
map.fitBounds(defaultBounds);
// Create the search box and link it to the UI element.
var input = document.getElementById('target');
var searchBox = new google.maps.places.SearchBox(input);
// [START region_getplaces]
// Listen for the event fired when the user selects an item from the
// pick list. Retrieve the matching places for that item.
google.maps.event.addListener(searchBox, 'places_changed', function() {
var places = searchBox.getPlaces();
for (var i = 0, marker; marker = markers[i]; i++) {
marker.setMap(null);
}
// For each plce, get the icon, place name, and location.
markers = [];
var bounds = new google.maps.LatLngBounds();
for (var i = 0, place; place = places[i]; i++) {
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)
};
// Create a marker for each place.
var marker = new google.maps.Marker({
map: map,
icon: image,
title: place.name,
position: place.geometry.location
});
markers.push(marker);
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
});
// [END region_getplaces]
// Bias the SearchBox results towards places that are within the bounds of the
// current map's viewport.
google.maps.event.addListener(map, 'bounds_changed', function() {
var bounds = map.getBounds();
searchBox.setBounds(bounds);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
function placeMarker(location, icon) {
var marker = new google.maps.Marker({
position: location,
map: map,
draggable:true,
icon: icon
});
}
</script>
</head>
<body>
<div id="map-canvas"></div>
<div id="panel">
<input id="target" type="text" placeholder="Search Box">
</div>
<div id='shelf'>
<div class="ecostation">
<div id="wrapper">
<div>
<img src="https://cdn1.iconfinder.com/data/icons/mobile-development-icons/30/Map_marker.png" id="draggable" title="Estation Trash/Compost" alt="Estation Trash and Compost"/>
<p>Trash/Compost</p>
</div>
<div>
<img src="https://cdn1.iconfinder.com/data/icons/large-tab-bar-icons/30/Start_flag.png" id="draggable2" title="Estation Trash" alt="Estation Trash"/>
<p>Trash</p>
</div>
<div>
<img src="http://i1288.photobucket.com/albums/b489/Wallace_Adams/bth_facebook-icon-30x30_zpsb49e1af3.jpg" id="draggable3" title="Estation Recycling" alt="Estation Recycling"/>
<p>Recycle</p>
</div>
</div>
</div>
</div>
</html>
end of code
If you guys can let me know that would be great! Also, i noticed that marker is declared twice. Is that one of the problems? I tried declaring something else but had no luck.
I also came accross this code but not sure if it is helpful in this situation
var overlay;
overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
Possibly thinking it has to do something with this piece of code below?
function placeMarker(location, icon) {
var marker = new google.maps.Marker({
position: location,
map: map,
draggable:true,
icon: icon
});
}
But then again, couldn't figure what was wrong with, am I connecting the variables correctly?
Help would be greatly appreciated, I am very close to finishing what I want to accomplish on this map
Check to make sure you are not using svg images for the icon. They seem to work on FireFox and Chrome, but not IE

Fusion Table layer InfoWindow showing all vertices in geometry field

this is my first post here so I apologize if I make a newbie faux pas.
I've got a Google Fusion Table layer that I have on top of a map. I created it by importing a KML file. Everything works great, but last week I realized that the InfoWindow is now displaying all of the vertices of the relevant polygon in the geometry field.
The strange thing is that these vertices do not display in the actual Fusion Table but only on the layer on top of the map. I suspect something might be going on with the JavaScript code, which I am very new to, or perhaps the new API for the Fusion Tables.
I removed the body section to get around some formatting issues on this page, but here is the code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>Georgia Areas</title>
<link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100%; weight: 100% }
#search-panel {
position: absolute;
` top: 10px;
left: 50%;
margin-left: -180px;
width: 350px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
#address {
width: 345px;
}
#instruction {
position: fixed;
float: right;
bottom: 10px;
right: 20px;
width: 375px;
z-index: 4;
background-color: #fff;
padding: 7px;
border: 1px solid #999;
font-family:"Arial";
}
p.small {font-size: small}
</style>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyARy6zbLmjvq3uaPjI--s45afA0LA-ynnA&sensor=false">
</script>
<script type="text/javascript">
var infoWindow = new google.maps.InfoWindow();
var input = document.getElementById('address');
var geocoder;
var gaCentroid;
var gaBounds;
var myMap;
function myclick(num) {
google.maps.event.trigger(markers[num], "click");
}
function initialize() {
geocoder = new google.maps.Geocoder();
gaCentroid = new google.maps.LatLng(32.900000, -83.22671);
gaBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(30.34,-85.652),
new google.maps.LatLng(35.01,-80.85)
);
var mapOptions = {
center: gaCentroid,
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
myMap = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
var lyr = new google.maps.FusionTablesLayer({
query: {
select: 'geometry',
from: '1Bgo94POIxKwQOOltuFbaAW6CpjQqPvYLVSqXuLk'
},
styles: [{
polygonOptions: {
fillColor: '0xDEEBF7',
fillOpacity: 0.1
}
}]
});
lyr.setMap(myMap);
}
function codeAddress() {
var address = document.getElementById('address').value;
geocoder.geocode({'address':address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
myMap.setCenter(results[0].geometry.location);
myMap.fitBounds(results[0].geometry.viewport)
var marker = new google.maps.Marker({
map: myMap,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
function reCenter() {
var currentCenter = myMap.getCenter();
google.maps.event.trigger(myMap, 'resize');
myMap.setCenter(currentCenter);
}
</script>
</head>
</html>
Can anyone shed some light on this?
Thanks,
Ryan
You can configure the content shown in the infowindow.
See this page in the Fusion Tables Help
You must define the templateId to have the same content for the infoWindow.
Add this to the options passed to the layer:
templateId:2
I ended up changing the code to reference another Fusion Tables Layer. All I changed was the ID. This seems to work with the new layer, but I still do not know what happened to display the geometry in the InfoWindow.
If it happens again, I will most likley attempt Dr.Molle's suggestion.

Categories