I have two hidden fields which contain latitude value values and longitude values having id-#latitude_val and #longitude_val.I will set variable chicago with a initial latitude and longitude.If above two fields are null,I will pass the place name (here statically for checking )and locate the marker by the following code.
function initialize() {
chicago = new google.maps.LatLng(51.508742,-0.120850);//default value
if(($("#latitude_val").val().length >3) || ($("#longitude_val").val().length>3))
{
chicago = new google.maps.LatLng($("#latitude_val").val(), $("#longitude_val").val());
}
else
{
geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': 'Abudhabi'}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK)
{
console.log(results[0].geometry.location.lat()+' '+results[0].geometry.location.lng());//if null this should print first
chicago = new google.maps.LatLng(results[0].geometry.location.lat(),results[0].geometry.location.lng());
console.log('__'+chicago);//this should print second
}
else
{
console.log("Geocode was not successful for the following reason: " + status);
}
});
}
console.log('****'+chicago);//this should print third
var mapOptions = { zoom:4, mapTypeId: google.maps.MapTypeId.ROADMAP, center: chicago }
map = new google.maps.Map(document.getElementById("googlemap"), mapOptions);
var marker=new google.maps.Marker({
position:chicago,
map:map,
draggable:true,
animation: google.maps.Animation.DROP
});
marker.setMap(map);
});
}
I have checked the value of chicago in cases.Here the default value is marked by the marker in the map.When I check console,the third one is printing first,the first one in second and second one in third.I didnt understand why this happens.I need to run this based on the order.
The map is showing with values (51.508742,-0.120850) rather than the new values
So, I guess you might populate said inputs from the backend, and provide a fallback in case they are null. Either way, you want to get a location and only then you want to instance your map.
The following should work:
var map;
function initialize() {
var createMapWithLocation=function(myposition) {
var mapOptions = {
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: myposition
},
mymap = new google.maps.Map(document.getElementById("googlemap"), mapOptions),
marker = new google.maps.Marker({
position: myposition,
map: mymap,
draggable: true,
animation: google.maps.Animation.DROP
});
console.log('****' + myposition); //this should print third
return mymap;
};
var chicago = new google.maps.LatLng(51.508742, -0.120850); //default value
if (($("#latitude_val").val().length > 3) || ($("#longitude_val").val().length > 3)) {
chicago = new google.maps.LatLng($("#latitude_val").val(), $("#longitude_val").val());
map = createMapWithLocation(chicago);
} else {
geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': 'Abudhabi'
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results[0].geometry.location.lat() + ' ' + results[0].geometry.location.lng()); //if null this should print first
chicago = new google.maps.LatLng(results[0].geometry.location.lat(), results[0].geometry.location.lng());
console.log('__' + chicago); //this should print second
map = createMapWithLocation(chicago);
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
}
}
You decide when to call createMapWithLocation. It will be synchronous if the inputs are populated, and asynchronous if they aren't. Either way, you don't need to know the position of chicago beforehand.
Please note I've declared map outside of the initialize function, just in case you want to inspect it from the console.
Related
I have a google.maps.Data layer with a polygon feature:
state = new google.maps.Data();
state.loadGeoJson('static/geojson/ga_state.geojson', {
idPropertyName: 'name'
});
state.setStyle({
clickable: false,
visible: false,
});
state.setMap(map);
Within this feature collection is a polygon representing the state of Georgia:
ga = state.getFeatureById('Georgia')
I can get the geometry of this feature:
gaGeom = ga.getGeometry()
But when I pass either of these objects and also the raw array to google.maps.geometry.polygon.containsFeature(), I get an error that the object does not contain the get() fuction:
google.maps.geometry.poly.containsLocation(p.getPosition(), ga)
Uncaught TypeError: b.get is not a function(…)
google.maps.geometry.poly.containsLocation(p.getPosition(), gaGeom)
Uncaught TypeError: b.get is not a function(…)
google.maps.geometry.poly.containsLocation(p.getPosition(), gaGeom.getArray())
Uncaught TypeError: b.get is not a function(…)
How can I get a google.maps.Data.Polygon to either convert to a google.maps.Polygon or to work with this function?
EDIT:
I have found a way to construct a google.maps.Polygon from a google.maps.Data.Polygon as:
//gaGeom is the feature.geometry from the data layer
poly = new google.maps.Polygon({paths:gaGeom.getAt(0).getArray()})
But surely there has to be a cleaner way to construct the google.maps.Polygon?
The google.maps.geometry.poly.containsLocation method takes a point (a google.maps.LatLng) and a polygon (a google.maps.Polygon).
containsLocation(point:LatLng, polygon:Polygon)
Return Value: boolean
Computes whether the given point lies inside the specified polygon.
ga = state.getFeatureById('Georgia') returns a "feature"
gaGeom = ga.getGeometry() returns a "Geometry"
gaGeom.getArray() returns an "Array" of LinearRings
None of which is a google.maps.Polygon. You can make a google.maps.Polygon from the Array (as I see you have discovered while I wrote this).
proof of concept
code:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var state = new google.maps.Data();
var poly;
state.addListener('addfeature', function(evt) {
if (evt.feature.getId() == "Georgia") {
var ga = state.getFeatureById('Georgia');
var gaGeom = ga.getGeometry();
//gaGeom is the feature.geometry from the data layer
poly = new google.maps.Polygon({
paths: gaGeom.getAt(0).getArray(),
map: map,
clickable: false
});
}
});
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(map, 'click', function(evt) {
infoWindow.setPosition(evt.latLng);
if (google.maps.geometry.poly.containsLocation(evt.latLng, poly)) {
infoWindow.setContent("INSIDE POLY<br>" + evt.latLng.toUrlValue(6));
} else {
infoWindow.setContent("OUTSIDE POLY<br>" + evt.latLng.toUrlValue(6));
}
infoWindow.open(map);
});
state.loadGeoJson("http://www.geocodezip.com/GeoJSON/gz_2010_us_040_00_500k.json.txt", {
idPropertyName: 'NAME'
});
state.setStyle({
clickable: false,
visible: false,
});
state.setMap(map);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': "State of Georgia"
}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
map.fitBounds(results[0].geometry.viewport);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, "load", initialize);
I know that similar questions have been posted but I have not found and answer in any of them as it relates to my particular issue.
I have a javascript that uses google maps to place customer zipcodes on a map. The problem I am have is similar to what others have already posted – I get a “over query limit” error.
I have tried different setups using setTimeOut to try to send google the data within the allowable time intervals but I can’t get it to work.
Here is my action:
function initialize()
{
var rowNum = 0 ;
var rowColor = "" ;
var latlng = new google.maps.LatLng(27.91425, -82.842617);
var myOptions =
{
zoom: 7,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
geocoder = new google.maps.Geocoder();
data.forEach(function(mapData,idx)
{
window.setTimeout(function()
{
geocoder.geocode({ 'address': mapData.address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: mapData.title,
icon: getIcon(mapData.type)
});
var contentHtml = "<div style='width:250px;height:90px'><strong>"+mapData.title+"</strong><br />"+mapData.address+"</div>";
var infowindow = new google.maps.InfoWindow({
content: contentHtml
});
google.maps.event.addListener(marker, 'click', function()
{
infowindow.open(map,marker);
});
marker.locid = idx+1;
marker.infowindow = infowindow;
markers[markers.length] = marker;
if (idx%2 == 0)
{
rowColor = 'style="background-color:#00FFFF;"' ;
}
else
{
rowColor = 'style="background-color:#FFFFFF;"' ;
}
var sideHtml = '<div ' + rowColor + ' class="loc" data-locid="'+marker.locid+'"><b>'+mapData.title+'</b><br/>';
sideHtml += mapData.address + '</div>';
$("#locs").append(sideHtml);
//Are we all done? Not 100% sure of this
if(markers.length == data.length) doFilter();
}
else
{
// alert("Geocode was not successful for the following reason: " + status);
}
}, 3000);
});
});
When I run my page using this action, I get back 11 markers even though I have many more than that in my JSON string. The window.setTimeout has absolutely no effect – I’m obviously doing something wrong here.
I would appreciate any help on this matter.
Thanks,
I found the answer to my question. I found the following code on the Web and modified it to my needs.
With it, you can load many markers without getting Over Query Limit from Google.
I have tested it with over 100 markers and it works beautifully. The page does not freeze up at all.
I am certain some of you guys can do something much more elegant and efficient but this is a good starting point.
<script type="text/javascript">
//<![CDATA[
// display ani gif
loadingGMap() ;
// delay between geocode requests - at the time of writing, 100 miliseconds seems to work well
var delay = 100;
// ====== Create map objects ======
var infowindow = new google.maps.InfoWindow();
var latlng = new google.maps.LatLng(27.989551,-82.462235);
var mapOptions =
{
zoom: 7,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var geo = new google.maps.Geocoder();
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var bounds = new google.maps.LatLngBounds();
// ====== Geocoding ======
function getAddress(search, next)
{
geo.geocode({address:search}, function (results,status)
{
// If that was successful
if (status == google.maps.GeocoderStatus.OK)
{
// Lets assume that the first marker is the one we want
var p = results[0].geometry.location;
var lat = p.lat();
var lng = p.lng();
// Output the data
var msg = 'address="' + search + '" lat=' +lat+ ' lng=' +lng+ '(delay='+delay+'ms)<br>';
//document.getElementById("messages").innerHTML += msg;
// Create a marker
createMarker(search,lat,lng);
}
// ====== Decode the error status ======
else
{
// === if we were sending the requests to fast, try this one again and increase the delay
if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT)
{
nextAddress--;
delay++;
}
else
{
var reason = "Code "+status;
var msg = 'address="' + search + '" error=' +reason+ '(delay='+delay+'ms)<br>';
// document.getElementById("messages").innerHTML += msg;
}
}
next();
}
);
}
// ======= Function to create a marker
function createMarker(add,lat,lng)
{
var contentString = add;
if (add=='EOF')
{
stopLoadingGMap() ;
}
var addArray = add.split(' ');
var zipcode = addArray.pop();
var zipcode = add.match(/\d{5}/)[0] ;
var image = 'icons/sm_02.png';
var marker = new MarkerWithLabel(
{
position: new google.maps.LatLng(lat,lng),
map: map,
icon: image,
labelContent: zipcode,
labelAnchor: new google.maps.Point(50, 0),
labelClass: "labels", // the CSS class for the label
labelStyle: {opacity: 0.75},
zIndex: Math.round(latlng.lat()*-100000)<<5
});
google.maps.event.addListener(marker, 'click', function()
{
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
bounds.extend(marker.position);
}
// ======= An array of locations that we want to Geocode ========
// use static or build dynamically
// use as many markers as you need – I’ve test with over 100
var addresses = var data = [
{‘StreetAddress1 City State Zipcode’},
{‘StreetAddress2 City State Zipcode’},
{‘StreetAddress3 City State Zipcode’},
{‘StreetAddress14 City State Zipcode’},
…
{‘EOF’},
];
// ======= Global variable to remind us what to do next
var nextAddress = 0;
// ======= Function to call the next Geocode operation when the reply comes back
function theNext()
{
if (nextAddress < addresses.length)
{
setTimeout('getAddress("'+addresses[nextAddress]+'",theNext)', delay);
nextAddress++;
}
else
{
// We're done. Show map bounds
map.fitBounds(bounds);
}
}
// ======= Call that function for the first time =======
theNext();
// This Javascript is based on code provided by the
// Community Church Javascript Team
// http://www.bisphamchurch.org.uk/
// http://econym.org.uk/gmap/
//]]>
</script>
As i am working on object oriented javascript, i have created one map object and as i need to maintain the all previous routes and markers i am not creating new Map object. My code is as follows
function map() {
this.defaultMapOption = {
center : new google.maps.LatLng(0, 0),
zoom : 1,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
this.map = null;
this.marker = [];
this.directionsDisplay = null;
}
map.prototype.init = function() {
this.map = new google.maps.Map(document.getElementById("map"), this.defaultMapOption);
var map1 = this.map;
var marker1 = this.marker;
var count = 0;
google.maps.event.addListener(this.map, 'click', function(event) {
count++;
$(".tabNavigation li").find("a[href=markers]").trigger('click');
if ( marker1[count] ) {
marker1[count].setPosition(event.latLng);
}
else
{
marker1[count] = new google.maps.Marker({
position: event.latLng,
map: map1,
draggable : true
});
//by clicking double click on marker, marker must be removed.
google.maps.event.addListener(map.marker[count], "dblclick", function() {
console.log(map.marker);
map.marker[count].setMap(null);//this was working previously
map.marker[count].setVisible(false);//added this today
$("#markers ul li[rel='"+count+"']").remove();
});
google.maps.event.addListener(marker1[count], "dragend", function(innerEvent) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': innerEvent.latLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.addMarkerData(results, count);
}
else
{
alert("Geocoder failed due to: " + status);
}
});
});
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': event.latLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.addMarkerData(results, count);
}
else
{
alert("Geocoder failed due to: " + status);
}
});
}
});
}
Only above code works for only one marker. Means first time marker get removed on double click. After that it wont work.
Any ideas that why its stopped working!
Your count value is incrementing with new markers and in addListener(map.marker[count],...) , count will contain the latest value. So only that marker will be deleted.
So you should be decrementing the count value at the end in the addListener function.
You're adding marker[1] but then you try to remove marker[0]. Move your count++; from the beginning to the end of the function.
I'm currently working on an application where various markers are placed with infowindows on a Google Map based on a user's posts. I've also included geocoding so that the user can change their location and view markers/posts in any area.
What I'd like to do is for the user to search through the text info in the infowindows via a form and the map then responds by showing the markers that contain that text window. I've searched through the API and I don't see this ability mentioned, although it seems like it should be achievable.
Any insight or information on how to accomplish this would be much appreciated.
Here's the current code within the application:
function mainGeo()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition( mainMap, error, {maximumAge: 30000, timeout: 10000, enableHighAccuracy: true} );
}
else
{
alert("Sorry, but it looks like your browser does not support geolocation.");
}
}
var stories = {{storyJson|safe}};
var geocoder;
var map;
function loadMarkers(stories){
for (i=0;i<stories.length;i++) {
var story = stories[i];
(function(story) {
var pinColor = "69f2ff";
var pinImage = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=S|" + pinColor,
new google.maps.Size(21, 34),
new google.maps.Point(0,0),
new google.maps.Point(10, 34));
var point = new google.maps.LatLng(story.latitude, story.longitude);
var marker = new google.maps.Marker({position: point, map: map, icon: pinImage});
var infowindow = new google.maps.InfoWindow({
content: '<div >'+
'<div >'+
'</div>'+
'<h2 class="firstHeading">'+story.headline+'</h2>'+
'<div>'+
'<p>'+story.author+'</p>'+
'<p>'+story.city+'</p>'+
'<p>'+story.topic+'</p>'+
'<p>'+story.date+'</p>'+
'<p>'+story.copy+'</p>'+
'<p><a href='+story.url+'>Click to read story</a></p>'+
'</div>'+
'</div>'
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,this);
});
})(story);
}
}
function mainMap(position)
{
geocoder = new google.maps.Geocoder();
// Define the coordinates as a Google Maps LatLng Object
var coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
// Prepare the map options
var mapOptions =
{
zoom: 15,
center: coords,
mapTypeControl: false,
navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Create the map, and place it in the map_canvas div
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// Place the initial marker
var marker = new google.maps.Marker({
position: coords,
map: map,
title: "Your current location!"
});
loadMarkers(stories);
}
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 error() {
alert("You have refused to display your location. You will not be able to submit stories.");
}
mainGeo();
Create three empty arrays (e.g., markers, infowindows, and matches)
As you instantiate the marker, reference the marker via an index in the markers array (e.g., markers[i] = marker)
As you instantiate the infowindow, reference it's content via an index in the infowindows array (e.g., infowindows[i] = htmltext [or whatever variable name you store your content in)
Search for the string in the infowindows array, store the indexes of the items that contain the string in the matches array, and then use a for loop with the matches array to add the markers from the markers array (based on the index values of the matches array).
Goal: Get the TEXT address and then display the street view and map view at the same time
Ref Site:
http://code.google.com/apis/maps/documentation/javascript/examples/streetview-simple.html
My site:
http://www.iamvishal.com/dev/property/P2154 (pls click the map view to see the map)
Problem: I am able to display the map and the address correctly but instreet view does not change. Any idea why ?
My js variable address hold the text address in this case "323235 Balmoral Terrace Heaton Newcastle Upon Tyne"
function initialize()
{
var fenway = new google.maps.LatLng(42.345573,-71.098326);
var mapOptions = {
center: fenway,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(
document.getElementById("map_canvas"), mapOptions);
var panoramaOptions = {
position: fenway,
pov: {
heading: 34,
pitch: 10,
zoom: 1
}
};
var panorama = new google.maps.StreetViewPanorama(document.getElementById("pano"),
panoramaOptions);
map.setStreetView(panorama);
var geocoderTwo = new google.maps.Geocoder();
geocoderTwo.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);
}
}
);
}
Here's how I've created a streetview before:
function createStreetMap(strMapCanvasID, yourLatLng)
{
var panorama;
//once the document is loaded, see if google has a streetview image within 50 meters of the given location, and load that panorama
var sv = new google.maps.StreetViewService();
sv.getPanoramaByLocation(yourLatLng, 50, function(data, status) {
if (status == 'OK') {
//google has a streetview image for this location, so attach it to the streetview div
var panoramaOptions = {
pano: data.location.pano,
addressControl: false,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
}
};
var panorama = new google.maps.StreetViewPanorama(document.getElementById(strMapCanvasID), panoramaOptions);
// lets try and hide the pegman control from the normal map, if we're displaying a seperate streetview map
objCreatedMap.setOptions({
streetViewControl: false
});
}
else{
//no google streetview image for this location, so hide the streetview div
$('#' + strMapCanvasID).parent().hide();
}
});
}
Update: and you could call this function directly from within your existing code (I've amended the function to use a LatLng rather than individual latitude and longitude values:
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
});
createStreetMap('yourStreetViewDiv', results[0].geometry.location);
}
There are a couple issues with your code. Fix them first:
64 Uncaught ReferenceError: berkeley is not defined
Also, you'll need to set a zoom and mapTypeId options on your Map before anything shows.