Skip to content

Instantly share code, notes, and snippets.

@surferxo3
Last active July 26, 2020 13:13
Show Gist options
  • Save surferxo3/cecaaf78a351bf529b02cdbadf67c5ef to your computer and use it in GitHub Desktop.
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.
/* 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();
}
//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