sexta-feira, 27 de fevereiro de 2009

Verificar se um ponto está dentro de um polígono no Google Maps

Dica rápida para quem está usando Google Maps e javascript (se bem que é quase impossível usar o google maps sem javascript).

Estes códigos permitem verificar se determinado ponto está ou não dentro de um objeto GPolygon(polígono).

Primeiro código:




// // === A method for testing if a point is inside a polygon
// === Returns true if poly contains point
// === Algorithm shamelessly stolen from http://alienryderflex.com/polygon/
GPolygon.prototype.Contains = function(point) {
var j=0;
var oddNodes = false;
var x = point.lng();
var y = point.lat();
for (var i=0; i < this.getVertexCount(); i++) {
j++;
if (j == this.getVertexCount()) {j = 0;}
if (((this.getVertex(i).lat() < y) && (this.getVertex(j).lat() >= y))
|| ((this.getVertex(j).lat() < y) && (this.getVertex(i).lat() >= y))) {
if ( this.getVertex(i).lng() + (y - this.getVertex(i).lat())
/ (this.getVertex(j).lat()-this.getVertex(i).lat())
* (this.getVertex(j).lng() - this.getVertex(i).lng()) oddNodes = !oddNodes
}
}
}
return oddNodes;
}

Ele adiciona a funcao Contains(point) no objeto GPolygon. Eu a retirei do seguinte endereço:http://econym.org.uk/gmap/inside.htm.

Aliás nesta página tem um excelente tutorial sobre o Google Maps. Para usá-la você faria o seguinte:

var polygon = new GPolygon(points);

polygon.Contains(algumPonto);



O outro código é este:


// Create polygon method for collision detection
GPolygon.prototype.containsLatLng = function(latLng) {
// Do simple calculation so we don't do more CPU-intensive calcs for obvious misses
var bounds = this.getBounds();

if(!bounds.containsLatLng(latLng)) {
return false;
}

var numPoints = this.getVertexCount();
var inPoly = false;
var i;
var j = numPoints-1;

for(var i=0; i < numPoints; i++) {
var vertex1 = this.getVertex(i);
var vertex2 = this.getVertex(j);

if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) {
if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) {
inPoly = !inPoly;
}
}

j = i;
}

return inPoly;
};



Ele basicamente faz a mesma coisa, adiciona a função containsLatLng() no objeto GPolygon. Esta eu peguei em: http://dawsdesign.com/drupal/google_maps_point_in_polygon.

O uso é o mesmo também:

var polygon = new GPolygon(points);

polygon.containsLatLng(algumPonto);



Ambas as funções retornam true ou false.



A primeira não estava identificando corretamente alguns pontos em um polígono com quatro lados de tamanhos irregulares, equanto a segunda

funcionou neste caso. A primeira função funcionou corretamente em um polígono com a forma de um círculo.



Espero que elas ajudem vocês como me ajudaram.

PS.:Me desculpem pelo código, é melhor vocês olharem nos links, ainda não sei o que fazer para publicar código decentemente.

Um comentário:

  1. Cara tu conseguiu fazer ele verificar se um ponto esta ou não esta dentro dos poligonos?

    ResponderExcluir