<?php
/**
* Draw Polygons in Google Maps and Determine whether an Address is in Polygons
*
* This sample source code uses Google Maps Javascript API V3 to draw polygons in Google Maps.
* (Refer https://google-developers.appspot.com/maps/documentation/javascript/examples/drawing-tools)
*
* The address auto-complete uses Google Places Javascript library.
* (Refer https://developers.google.com/maps/documentation/javascript/places#places_autocomplete)
*
* The server-side code will retrieve address' latitude and longitude using Google Gecoding API.
* (Refer https://developers.google.com/maps/documentation/geocoding/)
*
* Using "Point-In-Polygon" Algorithm, the server-side code will determine whether address' coordinate is inside of polygons or outside.
* (Refer http://alienryderflex.com/polygon/)
*
* ===== How To Use =====
*
* First, draw polygons
* Second, search address and click "Check Inside/Outside Polygons" submit button
*
* ===== For Your Information =====
* If you need client-side Javascript to determine whether an address is in/out polygons,
* you can use google.maps.geometry.poly.containsLocation function in Google Maps API.
* (Refer https://developers.google.com/maps/documentation/javascript/reference#poly)
*
* The address auto-complete (Google Places Library) returns address information including coordinate.
*
* @author Chris LEE
*
*/
// Set up default polygon
$polygons = array();
$polygon = array(
array(-37.813310, 144.951553)
, array(-37.820836, 144.954901)
, array(-37.815209, 144.974728)
, array(-37.807750,144.971209)
, array(-37.813039,144.951468)
);
// If received coordinates, then store into arrays
$got_coordinates = isset($_GET['coordinates']) ? $_GET['coordinates'] : array();
if(!empty($got_coordinates))
{
foreach($got_coordinates as $coordinates)
{
if(!empty($coordinates))
{
$new_box = array();
foreach($coordinates as $coordinate)
{
$coordinate = explode("|", $coordinate);
$new_box[] = array($coordinate[0], $coordinate[1]);
}
$polygons[] = $new_box;
unset($new_box);
}
}
}
else
{
$polygons[] = $polygon;
}
unset($polygon);
unset($got_coordinates);
// Set up default address
$got_this_address = isset($_GET['address']) ? $_GET['address'] : "140 Elizabeth Street, Melbourne, Victoria, Australia";
// Get address coordinate from Google Maps API
$address = json_decode(get_address_coordinate($got_this_address));
if(!empty($address->results))
{
$address = $address->results[0];
}
$address_x = $address->geometry->location->lat;
$address_y = $address->geometry->location->lng;
$result = "";
if(!empty($polygons))
{
foreach($polygons as $polygon)
{
$no_of_polygons = sizeof($polygon);
$polygons_x = array();
$polygons_y = array();
foreach($polygon as $poly)
{
$polygons_x[] = $poly[0];
$polygons_y[] = $poly[1];
}
if (determine_in_polygon($no_of_polygons, $polygons_x, $polygons_y, $address_x, $address_y))
{
$result = "The Address '".$got_this_address."' (". $address_x.", ".$address_y.") is in polygons!";
break;
}
}
}
if($result == "")
{
$result = "The Address '".$got_this_address."' (". $address_x.", ".$address_y.") is not in polygons!";
}
function determine_in_polygon($no_of_polygons, $polygons_x, $polygons_y, $address_x, $address_y) {
$j = $no_of_polygons - 1;
$odd_nodes = 0;
for ($i = 0; $i < $no_of_polygons; $i++)
{
if ($polygons_y[$i] < $address_y && $polygons_y[$j] >= $address_y || $polygons_y[$j] < $address_y && $polygons_y[$i] >= $address_y)
{
if ($polygons_x[$i] + ($address_y - $polygons_y[$i]) / ($polygons_y[$j] - $polygons_y[$i]) * ($polygons_x[$j] - $polygons_x[$i]) < $address_x)
{
$odd_nodes = !$odd_nodes;
}
}
$j = $i;
}
return $odd_nodes;
}
function get_address_coordinate($address)
{
$url = "http://maps.googleapis.com/maps/api/geocode/json?address=".urlencode($address)."&sensor=false";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
?><!DOCTYPE html>
<html>
<head>
<title>Draw Polygons in Google Maps and Determine whether an Address is in Polygons</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset="utf-8">
<style>
#map {
padding: 0;
margin: 0;
width: 65%;
height: 65%;
position: absolute;
}
#panel {
width: 65%;
font-family: Arial, sans-serif;
font-size: 13px;
margin: 10px;
}
</style>
<script src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry,places,drawing"></script>
<script>
var map, drawing_manager, selected_shape, overlays = [];
function clear_selection()
{
if (selected_shape)
{
selected_shape.setEditable(false);
selected_shape = null;
}
}
function set_selection(shape)
{
clear_selection();
selected_shape = shape;
shape.setEditable(false);
}
function delete_selected_shape()
{
if (selected_shape) {
if(overlays)
{
$.each(overlays, function(i, overlay){
if(overlay == selected_shape)
{
overlays[i] = null;
}
});
}
selected_shape.setMap(null);
reset_coordinates();
}
}
function reset_coordinates()
{
$("#coordinates").html("");
var index = 0;
if(overlays)
{
$.each(overlays, function(i, overlay){
if(overlay)
{
$.each(overlay.getPath().getArray(), function (j, coordinate){
$("#coordinates").append('<input type="hidden" name="coordinates['+index+'][]" value="' + coordinate.lat() + "|" + coordinate.lng() + '" />');
});
index++;
}
});
}
}
function initialize()
{
// Set up Address Autocomplete
var input = $("#address")[0];
var autocomplete = new google.maps.places.Autocomplete(input);
// Set up Google Map
map = new google.maps.Map($("#map")[0], {
zoom: 15,
center: new google.maps.LatLng(<?php echo $address_x;?>, <?php echo $address_y;?>),
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true,
zoomControl: true
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(<?php echo $address_x;?>, <?php echo $address_y;?>),
map: map,
title: "<?php echo $got_this_address;?>"
});
// Configure drawingManager options
var polygon_options = {
editable: true,
strokeColor : "#0000FF",
strokeOpacity : 0.8,
strokeWeight : 2,
fillColor : "#0000FF",
fillOpacity : 0.4
};
// Set up drawing manager
drawing_manager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.POLYGON,
]
},
markerOptions: {
draggable: true
},
polylineOptions: {
editable: true
},
polygonOptions: polygon_options,
map: map
});
google.maps.event.addListener(drawing_manager, "overlaycomplete", function(e) {
if (e.type != google.maps.drawing.OverlayType.MARKER)
{
drawing_manager.setDrawingMode(null);
var new_shape = e.overlay;
new_shape.type = e.type;
google.maps.event.addListener(new_shape, "click", function() {
set_selection(new_shape);
});
set_selection(new_shape);
overlays.push(new_shape);
reset_coordinates();
}
});
google.maps.event.addListener(drawing_manager, "drawingmode_changed", clear_selection);
google.maps.event.addListener(map, "click", clear_selection);
google.maps.event.addDomListener($("#delete-button")[0], "click", delete_selected_shape);
// Set up polygons
<?php
if(!empty($polygons))
{
foreach($polygons as $key => $polygon)
{
?>
var poly<?php echo $key;?>, box<?php echo $key;?>;
box<?php echo $key;?> = [
<?php
foreach($polygon as $polygon_key => $co)
{
if($polygon_key != 0)
{
echo ", ";
}
?>
new google.maps.LatLng(<?php echo $co[0];?>, <?php echo $co[1];?>)
<?php
}
?>
];
poly<?php echo $key;?> = new google.maps.Polygon({
paths : box<?php echo $key;?>,
strokeColor : "#0000FF",
strokeOpacity : 0.8,
strokeWeight : 2,
fillColor : "#0000FF",
fillOpacity : 0.4
});
poly<?php echo $key;?>.setMap(map);
google.maps.event.addListener(poly<?php echo $key;?>, "click", function() {
set_selection(poly<?php echo $key;?>);
});
set_selection(poly<?php echo $key;?>);
overlays.push(poly<?php echo $key;?>);
<?php
}
}
?>
}
google.maps.event.addDomListener(window, "load", initialize);
</script>
</head>
<body>
<h1>Draw Polygons in Google Maps and Determine whether an Address is in Polygons</h1>
<pre>/**
* Draw Polygons in Google Maps and Determine whether an Address is in Polygons
*
* This sample source code uses Google Maps Javascript API V3 to draw polygons in Google Maps.
* (Refer https://google-developers.appspot.com/maps/documentation/javascript/examples/drawing-tools)
*
* The address auto-complete uses Google Places Javascript library.
* (Refer https://developers.google.com/maps/documentation/javascript/places#places_autocomplete)
*
* The server-side code will retrieve address' latitude and longitude using Google Gecoding API.
* (Refer https://developers.google.com/maps/documentation/geocoding/)
*
* Using "Point-In-Polygon" Algorithm, the server-side code will determine whether address' coordinate is inside of polygons or outside.
* (Refer http://alienryderflex.com/polygon/)
*
* ===== How To Use =====
*
* First, draw polygons
* Second, search address and click "Check Inside/Outside Polygons" submit button
*
* ===== For Your Information =====
* If you need client-side Javascript to determine whether an address is in/out polygons,
* you can use google.maps.geometry.poly.containsLocation function in Google Maps API.
* (Refer https://developers.google.com/maps/documentation/javascript/reference#poly)
*
* The address auto-complete (Google Places Library) returns address information including coordinate.
*
* @author Chris LEE
*
*/</pre>
<div id="panel">
<form method="get">
Search Address: <input type="text" id="address" name="address" value="<?php echo $got_this_address;?>" style="width:50%;"/>
<input type="submit" value="Check Inside/Outside Polygons" />
<div id="coordinates" style="display:none;">
<?php
if(!empty($polygons))
{
foreach($polygons as $key => $polygon)
{
if(!empty($polygon))
{
foreach($polygon as $b)
{
?>
<input type="hidden" name="coordinates[<?php echo $key;?>][]" value="<?php echo $b[0];?>|<?php echo $b[1];?>" />
<?php
}
}
}
}
?>
</div>
</form>
<br />
<strong><?php echo $result;?></strong>
<br /><br />
<button id="delete-button">Delete Selected Polygon</button>
</div>
<div id="map"></div>
<br /><br />
<br /><br />
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-1581881-5']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>