I am new in Javascript and google map api and I have been follow this link to remove a marker but some how I cannot make it work.
Basically I want to use a button to generate the marker when user enter an address and click on the button. When the user enter a new address and click on the button again, the old marker will be removed and the new marker pin on the new address. The marker also draggable.
Here is my js code:
$('#geocode').live('click',function() {
codeAddress();
return false;
});
function codeAddress() {
var address = document.getElementById('location').value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
if (marker) marker.setMap(null);
if (marker) delete marker;
var marker = new google.maps.Marker({
draggable:true,
map: map,
position: results[0].geometry.location
});
var newlat = results[0].geometry.location.lat();
var newlng = results[0].geometry.location.lng();
document.getElementById('mwqsflatlng').value = (newlat+' , '+newlng);
draggeablemarker(marker);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
Update
When I check on the inspect element, it gave me this error:
Uncaught TypeError: Cannot call method 'setMap' of undefined
You need to have a reference to your marker object to be able to access it at a later time. If you want to restrict the map to one marker showing at a time you can update the markers Position property instead of deleting and recreating it.
Here is a function that can change the markers position or create a new marker if one does not exist on the map. The location parameter is a Google LatLng object which is the same as the object returned by the Geocoder results[0].geometry.location.
Notice the marker variable is defined outside of the function scope. This is what allows you to refer to the marker at a later time.
var marker;
function placeMarker(location) {
if (marker) {
//if marker already was created change positon
marker.setPosition(location);
} else {
//create a marker
marker = new google.maps.Marker({
position: location,
map: map,
draggable: true
});
}
}
So for your geocode success function you should only have to pass the result to this function.
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
placeMarker(results[0].geometry.location);
}
...
Here is a fiddle of of the concept. You can click on the map and the marker will move to the desired location.
Related
I currently enabled user to put the address into text-boxes and display the address on Google map, but I want to do the opposite now and get nearest matching address to the text-boxes (which are on a separate region, same page) from a draggable marker. I heard that I should use JSON with PHP or PL/JSON to get the data from the map to the text-boxes. However, I do not have any knowledge about JSON and I think Google map API provide this sort of geocoding methods inside the JavaScript. I am not sure how to fully apply it, and if it is possible to get both methods in one page (or maybe I should use some procedure with JavaScript and call it on the page, not sure). Here is my code so far in the HTML Header of the page:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script type="text/javascript">
var uniLatLng = new google.maps.LatLng (51.887496, -2.088788);
var geocoder = new google.maps.Geocoder();
var map;
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
},
function(responses) {
if (responses && responses.length > 0) {
updateMarkerAddress(responses[0].formatted_address);
}
else {
updateMarkerAddress('Cannot determine address at this location.');
}
});
}
function updateMarkerStatus(str) {
document.getElementById('P15_ADDRESS').value;
}
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: 16,
center: uniLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
};
var marker = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
flat: false,
position: new google.maps.LatLng(59.327383, 18.06747)
})
function map_canvas() {
var address = "&P15_ADDRESS.";
geocoder.geocode( { 'address': address, 'region': "GB"}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
draggable: true,
animation: google.maps.Animation.DROP,
flat: false,
position: results[0].geometry.location
});
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
</script>
Page HTML Body Attribute - onload="initialize(), map_canvas()"
Any suggestions how can I achieve this?
I think this example does what you want on the Reverse Geocoding part. https://developers.google.com/maps/documentation/javascript/examples/geocoding-reverse
the only thing you need to add to this is a draggable marker with a listener for on dragged, which would update the position and call the same methods as it is in the Reverse Geocode button.
This question might be answered in other posts, but I haven't found the specific answer and I'm having trouble discerning how to logically think through this. I have a site where each post has an address. On each post page I've used the Google Maps API to translate the address into a map location and to show a map with a pin at that address. Works great.
What I need to do now is to show a map at the top of my archive/category/etc pages (pages with a list of posts generated by a query and a loop) and to list a pin for every post that shows up in that particular query. I also need the map to automatically resize to show all of the pins, and not show extraneous map outside of the pins boundaries.
The way it seems that this would happen is that I could create the markers with a script that's inside the loop, so that each time the loop runs, it would generate a new marker and add it to the map.
Another possible method that seems like it has potential would be to add the location to an array for each turn of the loop, and then show the array of pins when the loop is done.
Can anyone give me some advice on how to accomplish this? At this point I'm using the following code which gives me a map and the location of the last post in the list generated by the loop. This code is outside of the loop. I need to know which part I should move inside the loop, and how to adjust it so that I won't simply rewrite the marker during every iteration of the loop.
<script type="text/javascript">
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: 3,
}
var myAddress = document.getElementById('theAddress');
var address = myAddress.textContent;
geocoder.geocode({
'address': address
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
You need to add markers in a loop. this was taken from a project i was working.
var locations = ["Denver, CO, United States"];
var markers = [];
var iterator = 0;
for (var i = 0; i < locations.length; i++) {
setTimeout(function() {
geocoder.geocode({'address': locations[iterator]}, function(results, status){
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
animation: google.maps.Animation.DROP
});
bounds.extend(marker.getPosition());
map.fitBounds(bounds);
} else {
log('Geocode was not successful for the following reason: ' + status);
}
});
iterator++;
}, i * 250);
}
I am trying to use the google maps javascript API to map an address based on this example.
https://google-developers.appspot.com/maps/documentation/javascript/examples/geocoding-simple
The documentation recommends the clientside javascript approach as the best way to deal with quotas on requests. So far so good. My problem is in moving from this example to my specific case. My addresses are already in a database so I don't need the user to enter one. Also I do not want the map to load with the page. Instead, I want the map for the address to load when the user clicks a link.
I have a script working that loads the map in a div using initialize (). But my problem is getting initialize to work with geocode. The geocode in the example depends on initialize loading with bodyonload which I do not want.
Here is code. Would appreciate any suggestions:
javascript
var map;
var geocoder;
function codeAddress() {
var address = document.getElementById('address').value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(40.7562008,-73.9903784);
var myOptions = {
zoom: 18,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
html
<input id="address" type="hidden" value="Palo Alto CA">
View map without geocoding
<div id="map_canvas" style="width:300px; height:300px;"></div>
View map of geocoded address
The only issue I had with your script was the following line in the initialize() function:
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
By declaring var map, your script is just declaring a local variable named map, as opposed to using the global map variable declared at the top of your script.
By removing var, the script uses the global variable and runs fine:
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
Finally, to get the geocoded map to load on the link click, change onclick for your geocoded address to onclick="initialize();codeAddress();".
Added:
Try combining your initialize() and codeAddress() methods into the following:
function initialize() {
geocoder = new google.maps.Geocoder();
var address = document.getElementById('address').value;
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var myOptions = {
zoom: 18,
center: results[0].geometry.location,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
And then just call initialize() from your link.
Basically, what we're doing is taking the call to geocoder.geocode() that codeAddress() was performing and inside the resulting delegate, we're using results[0].geometry.location to initialize the map. This way, the temporary latlong doesn't need to be displayed.
I'm implementing geocoder using google map api v3 (javascript). I'm putting mutiple markers and when i click on marker i want the corresponding address to come in the info-window. But when i click on the marker, initially the default value of address(As per code Geo-Address Unavailable!) is coming and when i click the second marker it is having the address of the previously clicked marker. I'm attaching the piece of code.
var addr=" Geo-Address Unavailable!";
var geocoder = new google.maps.Geocoder();
for(var i = 0; i < latLngs.length-1; i++){ //latLngs is the array of latlongs
marker = new google.maps.Marker({
position: latlng,
id:markerId,
icon: image,
map: map,
animation : google.maps.Animation.DROP,
});
}
markers[markerId] = marker;
var infowindow = new google.maps.InfoWindow({
content: "loading..."
});
google.maps.event.addListener(marker, "click", function () {
geocoder.geocode({'latLng': this.getPosition()}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
addr = results[0].formatted_address;
}
});
infowindow.setContent(addr);
infowindow.open(map, this);
});
Geocoding is asynchronous. You have to use the returned value inside the callback from the geocoder.
What is happening:
you send off a request to the geocoder.
you display the response
the response comes back from the geocoder
you send off another request to the geocoder
you display the response to the first request
the response comes back from the geocoder to the second request
This questions relating to infowindow in the google maps API v3..
Currently I loop this function and place markers..
function addPostCode(zip, html)
{
geocoder.geocode( { 'address': zip}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
name: zip
});
});
Now I would like to add an info windows with unique HTML, however I would like the following behaviour..
When an infowindow is opened by an event, any current infowindows will close leaving only the new one present..
Is this possible and how would I go about it? Finding documentation on this issue is proving difficult..
Create a single infowindow in your initialization. In your event/listener where you want to open the infowindow, you'd set the content and open the infowindow on the marker/location on the map.
// Initialize infowindow
var infowindow = new google.maps.InfoWindow({content: ''});
function add_marker(point, name, content)
{
var marker = new google.maps.Marker({
map: map,
position: point,
dragable: false,
clickable: true,
name: name
});
marker.content = content;
google.maps.event.addListener(marker, 'click', function()
{
infowindow.content = marker.content;
infowindow.open(map, marker);
});
return marker;
};
function addPostCode(zip, html)
{
geocoder.geocode( { 'address': zip}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
map.setCenter(results[0].geometry.location);
var marker = add_marker(results[0].geometry.location, zip, html)
});
});
This question and answer helped me out quite a bit with the single or multiple Info Window issue:
Google Maps API v3 adding an InfoWindow to each marker
var currentInfoWindow = ''; //Global variable
google.maps.event.addListener(marker, 'click', function()
{
if(currentInfoWindow != '')
{
currentInfoWindow.close();
currentInfoWindow = '';
}
var infoWindow = new google.maps.InfoWindow({content: 'COntent'});
infowindow.open(map, marker);
currentInfoWindow = infowindow;
});
You are probably better off asking the Google Groups for the Google Maps API v3 about this one, and any other related questions.
I haven't used API v3, but as far as I know, you can only have one info window open at a time, so this would happen automatically.
There are two ways to do this ... the first is to create a single info window and just use the .setOptions method of the info window to update the content.
The second way to do it is to simply set a module-level variable in your code to contain the "active" window ... and then if any infoWindow is open, call it's .close method before you open the new one.