I am wanting to search a KML file to see if a particular address falls within an overlay. Presently, I have the address converting to a geocode. However, I'm not sure what code is needed to add this functionality.
Here's the present code:
function initialize() {
var infowindow = new google.maps.InfoWindow({
content: '',
suppressMapPan:true
});
var myLatlng = new google.maps.LatLng(35.910200,-84.085100);
var myOptions = {
zoom: 12,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(
document.getElementById("map_canvas"), myOptions);
var d = new Date();
var n = d.getMilliseconds();
var nyLayer = new google.maps.KmlLayer(
'http://www.cspc.net/neighborhoods/groups.kml?rand=' + n,
{ suppressInfoWindows: true, map: map});
google.maps.event.addListener(nyLayer, 'click', function(kmlEvent) {
var url = kmlEvent.featureData.snippet;
var groupName = kmlEvent.featureData.name;
var insideContent = "<div style='width:250px;'><h2>" + groupName +
"</h1><p>We have a neighborhood contact in your area! </p>" +
"<p><a href='" + url + "' target='_blank'>Get connected!</a>" +
" They look forward to hearing from you.</p><p>If you have " +
"any additional questions, please contact our " +
"<a href='http://www.cspc.net/communitylife' target='_blank'>" +
"Community Life</a> staff for more information. Betsy Palk, " +
"the Administrative Assistant, may be reached at:<br/><br/>" +
"<b>Email:</b> <a href='mailto:betsypalk#cspc.net'>" +
"betsypalk#cspc.net</a><br/><b>Phone:</b> 865-291-5268<p></div>";
var clickPos = kmlEvent.latLng;
var posX = new google.maps.LatLng(clickPos.lat(), clickPos.lng());
infowindow.close();
infowindow.setPosition(posX);
infowindow.setContent(insideContent);
infowindow.open(map);
});
eventMapClick = google.maps.event.addListener(map, 'click',
function(event) {
var marker = new google.maps.Marker({ position: event.latLng });
var outsideContent = "<div style='width:250px;'><h2>Oops!</h1>" +
"<p> It seems we don't have a neighborhood contact in your " +
"area.</p><p>Please contact our <a " +
"href='http://www.cspc.net/communitylife' target= '_blank'>" +
"Community Life</a> staff for more information. " +
"Betsy Palk, the Administrative Assistant, may be reached at:" +
"<br/><br/><b>Email: </b> <a href='mailto:betsypalk#cspc.net'>" +
"betsypalk#cspc.net</a><br/><b>Phone:</b> 865-291-5268<p></div>";
infowindow.setContent(outsideContent);
infowindow.open(map, marker);
});
}
var geocoder = new google.maps.Geocoder();
function searchAddress(address) {
geocoder.geocode(
{'address': address},
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var loc = results[0].geometry.location;
// use loc.lat(), loc.lng()
window.alert(loc);
}
else {
window.alert("Not found: " + status);
}
}
);
};
If I understand your question, I believe you want the formula to determine if a point (google.maps.LatLng) falls within one of your KML Placemark definitions (that you give names such as: Neighborhood Group 1). Within each Placemark, you define a Polygon and within each Polygon, you define a set of coordinates, which represent the vertices of the Polygon.
Using the coordinates within the Polygon and the LatLng you retrieve via geocoding, you could start with these formulas and select that one that is the best fit for you:
Fast Winding Number Inclusion of a Point in a Polygon
Point-In-Polygon Algorithm
A very similar question has also been asked here on SO: Determine the lat lngs of markers within a polygon.
Related
I have a map that geocodes locations retrieved from JSON and sticks a marker on the map.
The markers also have an infowindow that shows the markers name and rating.
There's a button inside an infowindow that increments a rating counter when you click a button.
The initial counter is retrieved from JSON.
Annoyingly, when the info window closed and reopen, the counter value resets.
I tried populating an object with all of the marker ratings, updating the object when the button is clicked and then output the rating from the object inside the contentString for the infowindow. This didn't work and the same initial rating counter was shown after re-opening the infowindow.
My code is below, any help would be appreciated.
var map;
var geocoder;
var infowindow;
var rating;
function initMap() {
var mapElement = document.getElementById("map_canvas");
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: new google.maps.LatLng(53.481949, -2.237430),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
infowindow = new google.maps.InfoWindow();
map = new google.maps.Map(mapElement, mapOptions);
}
$(document).on('click', '#been-there', function(event){
var entryID = $(this).data('entry-id');
var rating = $(this).data('rating');
var dataString = 'id='+ entryID;
rating++;
$.ajax({
type: "POST",
url: "db-been-there.php",
data: dataString,
cache: false,
}).success(function(html){
console.log(html);
}).fail(function(html){
console.log(html);
});
$('#rating').html(rating);
});
$.getJSON("db-output.php", function(dbJSON) {
$.each(dbJSON, function(key, data) {
var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + data.lat + "," + data.lng + "&result_type=sublocality|political&key=AIzaSyCsY-LOPL7dGbA1ShBEu7zMO8_GaSBA3Vg";
$.getJSON(url, function(reverseGeo) {
var postal_town = reverseGeo.results[0].formatted_address;
geocoder.geocode( { 'address': postal_town}, function(results, status) {
if (status == 'OK') {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: data.name
});
var contentString = '<div id="content">'+
'<h1>' + data.name + '</h1>' +
'<button id="been-there" data-rating="' + data.rating + '" data-entry-id="' + data.id + '">Seen it</button>' +
'<p><strong>Rating: </strong><span id="rating">' + data.rating + '</span></p>' +
'</div>';
marker.addListener('click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
});
});
});
EDIT: Resolved code and JSFiddle below
Resolved JSFiddle: https://jsfiddle.net/BleepyEvans/3czqmqav/
var locations = [
{
"id": "1",
"name": "Location 1",
"lat": "53.408371",
"lng": "-2.991573",
"rating": "17"
},
{
"id": "2",
"name": "Location 2",
"lat": "53.789528",
"lng": "-2.969411",
"rating": "8"
},
]
var map;
var geocoder;
var infowindow;
var rating;
var markers = [];
function initMap() {
var mapElement = document.getElementById("map_canvas");
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: new google.maps.LatLng(53.481949, -2.237430),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
infowindow = new google.maps.InfoWindow();
map = new google.maps.Map(mapElement, mapOptions);
}
$(document).on('click', '#been-there', function(event){
var entryID = $(this).data('entry-id');
var dataString = 'id='+ entryID;
rating = markers[entryID].rating;
rating++;
markers[entryID].rating = rating;
console.log(markers[entryID].rating);
$('#rating').html(rating);
});
$.each(locations, function(key, data) {
var url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + data.lat + "," + data.lng + "&result_type=sublocality|political&key=AIzaSyCsY-LOPL7dGbA1ShBEu7zMO8_GaSBA3Vg";
$.getJSON(url, function(reverseGeo) {
var postal_town = reverseGeo.results[0].formatted_address;
geocoder.geocode( { 'address': postal_town}, function(results, status) {
if (status == 'OK') {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: data.name,
rating: data.rating
});
markers[data.id] = marker;
console.log(markers[data.id].rating);
marker.addListener('click', function() {
var contentString = '<div id="content">'+
'<h1>' + data.name + '</h1>' +
'<button id="been-there" data-rating="' + data.rating + '" data-entry-id="' + data.id + '">Been There</button>' +
'<p><strong>Rating: </strong><span id="rating">' + markers[data.id].rating + '</span></p>' +
'</div>';
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
});
});
Rather than just create an HTML string which includes the rating data that you assign to your infowindow, I'd add the rating value to the Marker object itself.
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: data.manufacturer_name,
rating: data.rating
});
Save those markers in an object keyed on their ID:
markers[data.id] = marker;
Then when the user clicks the button, update that value:
$(document).on('click', '#been-there', function(event){
var entryID = $(this).data('entry-id');
rating = markers[entryID].rating;
rating++;
And update the value on the Marker:
markers[entryID].rating = rating;
If it doesn't work directly accessing the rating property on the markers, you might need to use:
markers[entryID].get('rating');
markers[entryID].set('rating', rating);
I am looping through some JSON files and using the address from the JSON file for the google maps. I know the address is working properly because I set an alert to show the variable and it's showing what I expect. The call for the map is inside a click function. on one virtual page I have a list of customers and when the user clicks that customer, it redirects to another virtual page to display that customers information, with a map showing their address. When I do this for the first time , it works. If I click back, then select a different customer the map is just grey. Any idea why this is happening?
Here is my click function..
function cHandle(num) {
$("#custSpan" + i).on("click", function () {
window.location.href = "#CustInv";
custName = customer.Customer[num].compName;
$("#CustInvHead").html(custName);
$("#invoiceh2").html(custName + "'s Invoices");
$("#custInfo").empty();
$("#invoice").empty();
$("#map-canvas").empty();
var inc = customer.Customer[num].compId;
$("#custInfo").append("Customer ID: " + customer.Customer[num].compId + "<br /><br />"
+"Customer Name: " + custName + "<br /><br />"
+"Customer Address: " + customer.Customer[num].compAddress + "<br /><br />"
+"Customer Contact: " + customer.Customer[num].compContact + "<br /><br />"
+"Customer Phone: " + customer.Customer[num].compPhone + "<br/ ><br />"
+ "Customer Email: " + customer.Customer[num].compEmail + ""
);
address = customer.Customer[num].compAddress;
//alert(address);
codeAddress();
})
}
cHandle(i);
And here is my maps stuff..
function success(pos) {
lat = pos.coords.latitude;
lng = pos.coords.longitude;
drawMap();
}
function error(err) {
alert("Error " + err.code + " : " + err.message);
}
;
function codeAddress() {
lat = 0;
lng = 0;
//Get the address
//address = "123 Fake St";
if (address == "") {
alert("No Address Entered");
return;
}
//Change address to coordinates to plot on map
else {
geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var myLatLng = results[0].geometry.location;
lat = results[0].geometry.location.lat();
lng = results[0].geometry.location.lng();
drawMap();
}
else {
alert("Geocode was not successful for the following reason: " + status);
return;
}
})
}
}
function drawMap() {
mapCenter = new google.maps.LatLng(lat, lng);
var mapOptions = {
center: mapCenter,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//Display the address
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
//Map Marker
var myLoc = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: mapCenter
});
You call several times the creation of the map as you should call once (Initialize) map and call several times the function of creating the marker.
split the code in drawMap in two
first declare the var map at top (window) level (outside the functions)
and initialize your map
var map
function initialize() {
mapCenter = new google.maps.LatLng(lat, lng);
var mapOptions = {
center: mapCenter,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//Display the address
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
google.maps.event.addDomListener(window, 'load', initialize);
</script>
second in the codeAddress() function call only the create marker function
function createMarker() {
var myLoc = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
position: mapCenter
});
}
I've a problem with pushing array html content into an infowindow:
I whant to try to append a html string for each marker that i customize via javascript into the Map, the code work with a native infowindow, but when i try to append html the infowindow is empty.
Here the code:
function initialize(markerPlaces) {
(function(window, google, maplib){
var mapOptions = maplib.MAP_OPTIONS,
domElement = document.getElementById('map'),
//map declaration
map = new google.maps.Map(domElement, mapOptions);
console.log(markerPlaces);
var contentStringOpen = '<div class="modul1 modalWindow">';
var contentStringMiddle = '<span class="modul1_txt">';
var contentStringClose = '</span></div>';
var infowindow = new google.maps.InfoWindow();
var contArray = new Array();
for(i=0;i<markerPlaces[0].posts.length;i++){
var thumb = markerPlaces[0].posts[i].thumb;
var title = markerPlaces[0].posts[i].title;
contArray.push('' +
'<div id="' + markerPlaces[0].posts[i].postId +
'" class="modul1 modalWindow">' +
markerPlaces[0].posts[i].thumb +
'<span class="modul1_txt">' +
markerPlaces[0].posts[i].title +
'</span></div>');
markers = new google.maps.Marker({
position: {
lat: Number(markerPlaces[0].posts[i].lat),
lng: Number(markerPlaces[0].posts[i].long)
},
map: map,
icon: 'http://tovisit.today/wp-content/themes/turisti/img/poi.png',
title: markerPlaces[0].posts[i].title
})
console.log(contArray[i]);
google.maps.event.addListener(markers, 'click', (function(markers, i) {
return function() {
//switch this for htmlContent
//infowindow.setContent(contArray[i]);
//this work
infowindow.setContent(contentStringMiddle + markerPlaces[0].posts[i].title + contentStringClose + markerPlaces[0].posts[i].thumb);
infowindow.open(map, markers);
$()
}
})(markers, i));
}
}(window, google, window.maplib || (window.maplib = {})));
}
The content string is correct:
but when i ispect the dom the div.modalWindow, and his content, missing
anyone has the same trouble?
i solve the problem, sometime a display:none cause some trouble, i forgot this debug css line, i apologize for loosinrg your time.
The function is correct and work by the way.
Thank U for the -1 have a nice day
For each location I'm adding a png icon.
In my database I have many entries with the same lat and lng. Is there a way I can find the entries with the duplicate lat and lng and apply a different icon?
function displayStores(result){
if (result.length > 0){
for (i=0;i<result.length;i++){
//Append Store Address on Sidebar
var html = getEmbedHTML(i+1,result[i].name,result[i].address,result[i].distance);
$("#divStores").append(html);
//place a marker
var image = 'images/number_' + parseInt(i+1) + '.png';
var latlng = new google.maps.LatLng(result[i].lat,result[i].lng);
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: image
});
var msg = 'Location : ' + result[i].name + '<br/> ';
msg = msg + 'Address : ' + result[i].address + '<br/> ';
attachMessage(marker, msg);
}
} else {
$("#divStores").html('No Stores Found');
}
}
You can sort the points and compute the difference. When it's greater then 0 then you can change the icon.
I have an issue with getting longitude and latitude values geocoded and then display the relevant address in an info window. I have tried multiple ways without success, however I must admit that I am not so familiar with javascript. I am continuously getting back as value : "undefined".
Here is a snippet of my code showing the main components:
var position = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var geocoder = new google.maps.Geocoder();
var address;
if (geocoder) {
geocoder.geocode({ 'latLng': position }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
address = (results[0].formatted_address);
} else {
address = (position.coords.latitude + ', ' + position.coords.longitude);
}
});
}
var info =
('<span class="txt_bld">Location:</span> ' + address + '<br />' +
'<span class="txt_bld">Accuracy:</span> ' + position.coords.accuracy + '<br />' +
'<span class="txt_bld">Time:</span> ' + position.timestamp);
Can anyone tell me how I can translate the lat/lng in position to an address in order to show them in my infowindow?
EDIT
Updated Code:
var position = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
var geocoder = new google.maps.Geocoder();
var infowindow = new google.maps.InfoWindow();
var address;
if (geocoder) {
geocoder.geocode({ 'latLng': position }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
address == (results[0].formatted_address);
} else {
address == (position.coords.latitude + ', ' + position.coords.longitude);
}
var info =
('<span class="txt_bld">Location:</span> ' + address + '<br />' +
'<span class="txt_bld">Accuracy:</span> ' + position.coords.accuracy + '<br />' +
'<span class="txt_bld">Time:</span> ' + position.timestamp);
if(!infowindow){
infowindow = new google.maps.InfoWindow({
content: info
});
}else{
infowindow.setContent(info);
}
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
setTimeout(function () {
infowindow.close();
}, 5000);
});
});
}
if(!marker){
marker = new google.maps.Marker({
position: position,
map: this.map,
icon: markericon,
draggable:false
});
}else{
marker.setPosition(point);
}
The geocoder is asynchronous. You need to use the data it returns in the callback function. Something like this (not tested):
var position = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
var geocoder = new google.maps.Geocoder();
var infowindow = new google.maps.InfoWindow();
var address;
if (geocoder) {
geocoder.geocode({ 'latLng': position }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
address = (results[0].formatted_address);
} else {
address = (position.coords.latitude + ', ' + position.coords.longitude);
}
var info =
('<span class="txt_bld">Location:</span> ' + address
+ '<br />' +
'<span class="txt_bld">Accuracy:</span> ' + position.coords.accuracy
+ '<br />' +
'<span class="txt_bld">Time:</span> ' + position.timestamp);
infowindow.setContent(info);
infowindow.setPosition(position);
infowindow.open(map);
});
}
Working example
We are using geocoder to get Lat long by address, as we don't have Lat long so we need to find Lat long via geocoder. In case if we have Lat long coordinates then we can use direct
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});