Last active
July 26, 2020 13:13
-
-
Save surferxo3/cecaaf78a351bf529b02cdbadf67c5ef to your computer and use it in GitHub Desktop.
Perform search on highlighted area by drawing Polygon on Google Maps. Supports actions such as Undo, Redo, and Clear and with Ray Castle Algorithm implementation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global declerations */ | |
var poly, map, path, path_backup, markersArray = []; | |
/* undo all point(s) */ | |
function undo_point() { | |
//enable search button if 3 points on the map | |
if(path.length < 4) { | |
$("#ss").css('visibility', 'hidden'); | |
} | |
if (path.length < 1) { | |
return; | |
} | |
path_backup.push(path.getAt((path.length - 1))); | |
path.removeAt(path.length - 1); | |
} | |
/* redo all point(s) */ | |
function redo_point(){ | |
//enable search button if 3 points on the map | |
if(path.length > 1) { | |
$("#ss").css('visibility', 'visible'); | |
} | |
if (path_backup.length < 1) { | |
return; | |
} | |
path.insertAt(path.length, path_backup.pop()); | |
} | |
/* update map with the polygon drawn */ | |
function insert_poly(){ | |
poly = new google.maps.Polygon({ | |
strokeWeight: 3, | |
fillColor: "#ff9900", | |
strokeColor: "#66AD1C", | |
editable:true | |
}); | |
poly.setPaths(new google.maps.MVCArray([path])); | |
poly.setMap(map); | |
} | |
/* when clicked on the map, add a point on the map */ | |
function addPoint(event) { | |
path.insertAt(path.length, event.latLng); | |
if (path.length > 2) { | |
$("#ss").css('visibility', 'visible'); | |
} | |
} | |
/* clear all the point(s) on the map */ | |
function clear_all() { | |
poly.setMap(null); | |
initialize("24.94200", "67.09044"); | |
$("#ss").css('visibility', 'hidden'); | |
$("#sm").css('visibility', 'hidden'); | |
$("#sr").css('visibility', 'hidden'); | |
$("#fr").css('visibility', 'hidden'); | |
$("#place").attr('value', ''); | |
} | |
/* update map with the markers */ | |
function submit_search() { | |
$("#sm").css('visibility', 'visible'); | |
$("#sr").css('visibility', 'visible'); | |
$("#fr").css('visibility', 'visible'); | |
$.ajax({ | |
type: "POST", | |
url: "fetch-results.php", | |
data: {args:1}, | |
success: function(result){ | |
var myLatLng = result.split(":"); | |
var latLng = new Array(), j=0; | |
//var markerArray = new Array(); | |
for(var i=0; i<myLatLng.length-1; i+=2) { | |
/* ray castle algorithm */ | |
var coordinate = new google.maps.LatLng(myLatLng[i], myLatLng[i+1]); | |
var isWithinPolygon = poly.containsLatLng(coordinate); | |
if(isWithinPolygon) | |
{ | |
latLng[j] = myLatLng[i]; | |
latLng[j+1] = myLatLng[i+1]; | |
j+=2; | |
} | |
} | |
for(var i=0; i<latLng.length-1; i+=2) { | |
$.ajax({ | |
type: "POST", | |
url: "fetch-results.php", | |
data: {lat:latLng[i], lng:latLng[i+1], args:2}, | |
success: function(result){ | |
var data = result.split(":"); | |
contentString ='<div><img src="'+ data[7] +'" width="50%" /></div>'+ | |
'<h3 style="color:#000000">'+ data[1] +'</h3></div>'+ | |
'<div>'+ data[2] +'</div><br />'+ | |
'<div>Purpose: '+ data[3] +'</div>'+ | |
'<div>Price: '+ data[4] +'</div>'+ | |
'<div>Size: '+ data[8] +'</div><br />'+ | |
'<a target="_blank" href="enquire.php?id='+ data[0] +'" class="button">Enquiry</a><br /><br />'; | |
var marker = new google.maps.Marker({ | |
position: new google.maps.LatLng(data[5], data[6]), | |
map: map, | |
animation: google.maps.Animation.DROP, | |
title: "Click to view Property Details!" | |
}); | |
markersArray.push(marker); //pushing markers | |
var infowindow = new google.maps.InfoWindow({ | |
maxWidth: 350 | |
}); | |
bindInfoW(marker, contentString, infowindow); | |
} | |
}); | |
} | |
} | |
}); | |
} | |
/* update map with the filter */ | |
function filter_search(val, field) { | |
$.ajax({ | |
type: "POST", | |
url: "fetch-results.php", | |
data: {args:1}, | |
success: function(result){ | |
var myLatLng = result.split(":"); | |
var latLng = new Array(), j=0; | |
for(var i=0; i<myLatLng.length-1; i+=2) { | |
/* ray castle algorithm */ | |
var coordinate = new google.maps.LatLng(myLatLng[i], myLatLng[i+1]); | |
var isWithinPolygon = poly.containsLatLng(coordinate); | |
if(isWithinPolygon) | |
{ | |
latLng[j] = myLatLng[i]; | |
latLng[j+1] = myLatLng[i+1]; | |
j+=2; | |
} | |
} | |
for(var r=0; r<markersArray.length; r++) | |
{ | |
markersArray[r].setMap(null); | |
} | |
markersArray.length=0; | |
for(var i=0; i<latLng.length-1; i+=2) { | |
$.ajax({ | |
type: "POST", | |
url: "fetch-filter-results.php", | |
data: {lat:latLng[i], lng:latLng[i+1], val:val, field:field}, | |
success: function(result){ | |
var data = result.split(":"); | |
contentString ='<div><img src="'+ data[7] +'" width="50%" /></div>'+ | |
'<h3 style="color:#000000">'+ data[1] +'</h3></div>'+ | |
'<div>'+ data[2] +'</div><br />'+ | |
'<div>Purpose: '+ data[3] +'</div>'+ | |
'<div>Price: '+ data[4] +'</div>'+ | |
'<div>Size: '+ data[8] +'</div><br />'+ | |
'<a target="_blank" href="enquire.php?id='+ data[0] +'" class="button">Enquiry</a><br /><br />'; | |
var marker = new google.maps.Marker({ | |
position: new google.maps.LatLng(data[5], data[6]), | |
map: map, | |
animation: google.maps.Animation.DROP, | |
title: "Click to view Property Details!" | |
}); | |
markersArray.push(marker); //pushing markers | |
var infowindow = new google.maps.InfoWindow({ | |
maxWidth: 350 | |
}); | |
bindInfoW(marker, contentString, infowindow); | |
} | |
}); | |
} | |
} | |
}); | |
} | |
/* bind infowindow to the markers */ | |
function bindInfoW(marker, contentString, infowindow) | |
{ | |
google.maps.event.addListener(marker, 'click', function() { | |
infowindow.setContent(contentString); | |
infowindow.open(map, marker); | |
}); | |
} | |
/* append autocomplete to the google map */ | |
function autocomplete() | |
{ | |
var input = document.getElementById('place'); | |
var autocomplete = new google.maps.places.Autocomplete(input); | |
autocomplete.bindTo('bounds', map); | |
var infowindow = new google.maps.InfoWindow(); | |
var marker = new google.maps.Marker({ | |
map: map | |
}); | |
google.maps.event.addListener(autocomplete, 'place_changed', function() { | |
infowindow.close(); | |
marker.setVisible(false); | |
input.className = ''; | |
var place = autocomplete.getPlace(); | |
if (!place.geometry) { | |
input.className = 'notfound'; | |
return; | |
} | |
if (place.geometry.viewport) { | |
map.fitBounds(place.geometry.viewport); | |
} | |
else { | |
map.setCenter(place.geometry.location); | |
map.setZoom(17); | |
} | |
var image = new google.maps.MarkerImage( | |
place.icon, | |
new google.maps.Size(71, 71), | |
new google.maps.Point(0, 0), | |
new google.maps.Point(17, 34), | |
new google.maps.Size(35, 35)); | |
marker.setIcon(image); | |
marker.setPosition(place.geometry.location); | |
var address = ''; | |
if (place.address_components) { | |
address = [ | |
(place.address_components[0] && place.address_components[0].short_name || ''), | |
(place.address_components[1] && place.address_components[1].short_name || ''), | |
(place.address_components[2] && place.address_components[2].short_name || '') | |
].join(' '); | |
} | |
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address); | |
infowindow.open(map, marker); | |
}); | |
} | |
/* create the settings for the map & add the map to the stage */ | |
function initialize(myLat, myLng) { | |
var latlng = new google.maps.LatLng(myLat, myLng); //set latlng to Karachi | |
var settings = { | |
zoom: 15, | |
center: latlng, | |
mapTypeControl: true, | |
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}, | |
navigationControl: true, | |
navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}, | |
mapTypeId: google.maps.MapTypeId.ROADMAP | |
}; | |
path = new google.maps.MVCArray; | |
path_backup = new Array(); | |
map = new google.maps.Map(document.getElementById("map_canvas"), settings); | |
google.maps.event.addListener(map, 'click', addPoint); | |
insert_poly(); | |
autocomplete(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Ray Castle Algorithm | |
if (!google.maps.Polygon.prototype.getBounds) { | |
google.maps.Polygon.prototype.getBounds = function(latLng) { | |
var bounds = new google.maps.LatLngBounds(); | |
var paths = this.getPaths(); | |
var path; | |
for (var p = 0; p < paths.getLength(); p++) { | |
path = paths.getAt(p); | |
for (var i = 0; i < path.getLength(); i++) { | |
bounds.extend(path.getAt(i)); | |
} | |
} | |
return bounds; | |
} | |
} | |
// Polygon containsLatLng - method to determine if a latLng is within a polygon | |
google.maps.Polygon.prototype.containsLatLng = function(latLng) { | |
// Exclude points outside of bounds as there is no way they are in the poly | |
var lat, lng; | |
//arguments are a pair of lat, lng variables | |
if(arguments.length == 2) { | |
if(typeof arguments[0]=="number" && typeof arguments[1]=="number") { | |
lat = arguments[0]; | |
lng = arguments[1]; | |
} | |
} else if (arguments.length == 1) { | |
var bounds = this.getBounds(); | |
if(bounds != null && !bounds.contains(latLng)) { | |
return false; | |
} | |
lat = latLng.lat(); | |
lng = latLng.lng(); | |
} else { | |
console.log("Wrong number of inputs in google.maps.Polygon.prototype.contains.LatLng"); | |
} | |
// Raycast point in polygon method | |
var inPoly = false; | |
var numPaths = this.getPaths().getLength(); | |
for(var p = 0; p < numPaths; p++) { | |
var path = this.getPaths().getAt(p); | |
var numPoints = path.getLength(); | |
var j = numPoints-1; | |
for(var i=0; i < numPoints; i++) { | |
var vertex1 = path.getAt(i); | |
var vertex2 = path.getAt(j); | |
if (vertex1.lng() < lng && vertex2.lng() >= lng || vertex2.lng() < lng && vertex1.lng() >= lng) { | |
if (vertex1.lat() + (lng - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < lat) { | |
inPoly = !inPoly; | |
} | |
} | |
j = i; | |
} | |
} | |
return inPoly; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment