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.

quarta-feira, 18 de fevereiro de 2009

segunda-feira, 9 de fevereiro de 2009

Tradução -Começando com o CodeIgniter parte 2

Saudações a todos!
* Como o blog está somente começando eu ainda não tenho muito o que escrever. Atualmente estou começando a brincar com o CodeIgniter e achei um tutorial introdutório bem legal sobre ele. Ele foi escrito pelo Mike e está publicado no site dele o Capsize Designs. Ele foi bem gentil e permitiu que eu o traduzisse para o português.

Bem vindos novamente. No último texto nós configuramos e rodamos uma instalação do CodeIgniter e nos familiarizamos com a estrutura e instalação. Agora, nós iremos olhar de perto como o CodeIgniter lida com o MVC, e o que MVC realmente significa.

O MVC é o princípio do CodeIgniter e da maioria dos framewroks de aplicações web (Symfony, Zend, CakePHP e até mesmo o infame Ruby on Rails). É também uma boa forma de se estruturar qualquer tipo de aplicação, e você se sentirá uma pessoa melhor por ter aprendido isso. E também é bom na cama. Continuando...

Curso rápido em PHP Orientado a Objetos
CodIgniter não vai fazer sentido a menos que você se familiarize com os conceitos básicos da programação orientada a objetos. O estilo típico de muitos programadores PHP envolve codificar de uma maneira linear (faça isso e depois faça isso ou isso). Isto serve para projetos pequenos (Digo para projetos bem pequenos), mas conforme uma aplicação cresce, ela fica confusa, feia e muito má.

Contrastando com isso, nós temos a programação orientada a objetos. CI( e MVC em geral, nós veremos isso depois), usa uma versão simplificada da POO. No nível básico, nós temos classes, objetos, e funções e métodos. Classes são o modelo geral ou estrutura de alguma coisa. Um bom exemplo de uma classe é um cão. Um cão possui quatro patas, é peludo, pode latir, etc. Um cão é uma classe.

Por seguinte nós temos objetos. Objetos são instâncias especificas de classes. Por exemplo, se "cão" é uma classe, então meu Cão Pastor Australiano chamado "Tuck" seria um objeto. É um membro especifico da classe.

Finalmente, nós temos métodos e funções. Estas são as coisas que um membro da classe pode fazer. Por exemplo, a classe cão tem uma função latir(), uma função pular(), e uma função estaDormindo(), etc. No mundo da programação, você tem que criar um novo objeto (ou instância de uma classe), geralmente (dependendo da linguagem) usando algo similar a var sparky = new Cao();, e então você pode chamar métodos no nosso cão. Em PHP, chamar funções em um objeto usa a sintaxe de flecha, então para fazer Sparky pular nós usaríamos sparky->jump();.

Esta é uma versão BEM simplificada e a definição da Wikipedia de Programação Orientada a Objetos pode ajudá-lo se você ainda estiver confuso. Contudo, é muito importante ter um entendimento básico sobre isso, porque CI depende disso, como nós veremos.

Modelos, Visualizações, Controladores, Nossa!
CodeIgniter é baseado na testada e verdadeira filosofia MVC. Basicamente, o ponto básico do MVC é que você separa o que o usuário vê(as visualizações) da lógica da aplicação (geralmente os modelos). A lógica da aplicação e a apresentação são conectados pelos controladores.

Agora, não entre em pânico! Isto é bem mais simples do que parece. E quando você tiver começado, eu te prometo que você não vai querer voltar atrás. Esta separação faz tudo mais simples, fácil de entender, e alguns podem dizer que fica mais bonito (embora eu não gostaria de ser tão nerd assim, então não vou ser). Aqui está o básico do papel de cada um destes três componentes.

NOTA: Você vai ver muitas menções sobre convenções de nomes. Convenções de nomes não são absolutamente necessárias no CI (como o são no CakePHP) mas elas são recomendadas pelo fato de que se você sempre segue as mesmas orientações, você não terá que despender tempo tentando lembrar como aquela coisa era chamada. Eu tento seguir as convenções de nomes do EllisLabs, eles desenvolveram o CodeIgniter, embora você possa desenvolver suas próprias e usá-las.

Modelos
Modelos fazem qualquer coisa entre conectar-se com um banco de dados e realizarem o CRUD (Create (Criar), Read (Ler), Update (Atualizar), Delete (Excluir)). Eu gosto de ter um modelo para cada tabela do meu banco de dados, geralmente chamado "nomedatabela_model.php". Modelos (e Controladores) contem um construtor, frequentemente com o mesmo nome da página exceto que maiúsculo (se a página é chamada blog_model.php, seu construtor será chamado de Blog_model).

Relembrando nossa explanação de programação orientada a objetos, um modelo seria uma "classe". Cada modelo tem suas próprias funções (lembra disso?) que podem ser chamadas depois de você criar uma instância especifica do modelo. Acalme-se. Aqui está um exemplo.
Vamos dizer que você possui um site de E-Commerce, então você provavelmente possui um banco de dados com tabelas como produtos, usuários, compras, etc. Assim, para construir o modelo para a tabela de produtos, você criaria um arquivo chamado produtos_model.php, e o estruturaria assim:

class Produtos_model extends Model {
function Produtos_model() {
parent::Model();
}
function algumacoisa1()
{
.....faz alguma coisa....
}
function algumacoisa2()
{
.....faz alguma coisa....
}


Então basicamente, você tem um modelo com o mesmo nome da página php, e a primeira função é o construtor, que tem o mesmo nome do modelo. O construtor diz ao CI que o pai da classe é classe genérica de modelo(Model). Depois disso, você coloca algumas funções que relacionam o banco de dados e os produtos. Você pode ter uma função getPreco() ou excluiProduto(). Estas funções criam um mini-biblioteca de coisas que seu controlador pode fazer, mas o controlador em si não tem que se preocupar em como elas são feitas. Nós entusiastas da programação gostamos de chamar isso de "abstração". Ohhhhhhh...

Vale lembra que o CI não OBRIGA você a usar modelos. Você pode colocar toda a interação com o banco de dados no controlador se você quiser. Faça um favor a você mesmo e use os modelos. Conforme sua aplicação cresce, você ficará feliz de ter uma camada extra de separação para mantê-lo são.

Controladores
Controladores são pontes entre a lógica de aplicação e a visualização. No exemplo prévio do E-Commerce, o modelo Produtos_model tinha funções que faziam as operações CRUD para nós, e nosso controlador chamará estas operações para fazer o que tiver para fazer, e retornará o que tiver para ser mostrado na visualização. Na minha opinião, controladores são a beleza de frameworks MVC como o CI. Você tem a parte de banco de dados no modelo, a parte visual nas visualizações, e o meio disso nos controladores. Ele é o atravessador. Isso não faz vocês ficarem entusiasmados? Somente eu? Não minta.

A anatomia de um controlador é muito parecida com um modelo. O nome de seu controlador será todo minúsculo, e deve explicar o que ele está manipulando. Por exemplo, nós provavelmente faríamos um controlador produtos.php comunicar nosso produtos_model.php com as visualizações. Bem chame ele de produtos.php, e ele vai ficar mais ou menos assim:

class Produtos extends Controller {
function Produtos() {
parent::Controller();
}
function index() {
echo 'Olá mundo!'
}
}

NOTA: As funções nos controladores são muito legais no CI. Ao invés de ter uma página php separada para cada página no site, você pode ter um controlador para cada seção, e páginas dentro de cada seção possuem sua própria função no controlador. Isto significa que por padrão, quando você navega para um controlador (como www.seusite.com/index.php/produtos), a função index do controlador produtos será chamada. Contudo, se você quer uma página para mostrar todos os sapatos ou outra coisa, você criaria uma função "sapatos()", e então navegaria para www.seusite.com/index.php/produtos/sapatos para executar a função. Isto é incrível.

Mas este era um controlador bem simples. Frequentemente, um controlador irá criar uma instância de um modelo, chamar algumas funções do modelo, e então passar os resultados para a visualização para mostrá-las no browser. Ficará mais ou menos assim:

class Produtos extends Controller {
function list() {
$this->load->model('Productos_model');
$data['preco'] = $this->Produtos_model->getProdutoPreco(algum_parametro);
$this->load->view('produtos_view', $data);
}
}

Acostume-se BEM com a sintaxe dos comandos load ($this->load->algo). Seu controlador usa este comando para criar uma nova instância do modelo ou para passar dados para a view para serem mostrador no browser. Neste caso, nós estamos dizendo o CI que nós iremos conversar com o Produtos_model usando o comando load. Então, nós chamamos a função getProdutoPreco() do Produtos_model e passamos os resultados em um array associativo chamado $data. Nós vamos chamar nosso resultado 'preco', então nós colocamos isso como $data['preco'].

O array $data é muito importante porque é que usamos para passar informações para nossa visualização.
E falando de visualizações...

Visualizações
Visualizações mostram tudo o que o usuário vê. Existem infinitas maneiras de organizar visualizações. Algumas aplicações podem ser pequenas o bastante para ter somente uma visualização, e esta representar diferentes páginas baseada em diferentes informações que os controladores passam para ela. Você pode também ter uma visualização diferente para cada página. Você escolhe, e isto depende do quão complexas suas páginas serão.
Visualizações obviamente vão dentro da pasta de visualizações, e eu usualmente as nomeio como algumacoisa_view.php. Se sua visualização vai mostrar uma lista de produtos, porque o nome não pode ser produtos_view.php. Note que os modelos são nomeados como algumacoisa_model.php e visualizações como algumacoisa_view.php enquanto controladores são somente algumacoisa.php. Isto é porque o nome do controlador é o que aparece na url, e você quer deixá-la bonita. Sim, eu sei, você pode mudar o que aparece na URL para qualquer coisa que você queira no arquivo routes.php, mas como nós estamos no básico, não vou tentar confundi-lo com isso.

Basicamente, uma visualização é muito parecida com uma página html que vocês estão acostumados, possui um DocType, tags, head e body, etc. De fato, é bem comum ter uma visualização cabeçalho e uma visualização rodapé para carregar antes de depois do conteúdo da visualização que você estiver usando.

A parte legal: A visualização mostra informação passada a ela pelo controlador. Qualquer coisa dentro do array $data (no nosso exemplo do controlador, 'preco') será passado a visualização e nós podemos referenciar isso usando o nome do objeto como variável. Isto não é tão confuso quanto parece! Digamos que passamos $data['preco'] para a visualização. Na visualização, nós podemos referenciar isso usando $preco. Se tivéssemos passsado $data['descricao'], nós poderíamos referenciar isso como $descricao. Isto é a beleza disso tudo. Nós podemos até mesmo passar outros arrays para $data. Digamos que o array $data contenha um array chamado 'produtoinfo'. Na visualização, nós poderíamos fazer algo como $produtoinfo['preco'] ou $produtoinfo['entrega'] ou qualquer outra coisa. Oportunidades ilimitadas! EBAAAA! Você pode não estar excitado como eu estou, mas você ficará depois que entender tudo.

Para demonstrar, aqui está uma visualização bem simples que mostra o preço que passamos:


"O preço é: =$preco *



Legal e simples. Note a sintaxe alternativa PHP. Ao invés de usar um comando echo para mandar o preco, nós usamos...

=algumca_coisa_para_mostrar *

... e o "=" fez isso para você. Somente um atalho. Embora, embora como cheekygeek observou nos comentários abaixo (link para o original no inicio do texto), isto requer que as tags curtas (short tags) estejam habilitadas no php.ini. Se isto não funcionar para você, isto deve ser o motivo. Contudo, em system/application/config.php no final do arquivo, você pode mudar $config['rewrite_short_tags'] = TRUE; e o CodeIgniter vai re-escrever todas elas em tempo de execução, então elas ainda vão funcionar no seu servidor.

Bem é o bastante por agora. Espero que você tenha aprendido algo, e volte para ver a parte três! Feliz codificação!

* Eu não sei porque mas o Blogger não está aceitando as tags php. Vou tentar colocar estes códigos nos comentários.

terça-feira, 3 de fevereiro de 2009

Tradução -Começando com o CodeIgniter parte 1

Saudações a todos!
* Como o blog está somente começando eu ainda não tenho muito o que escrever. Atualmente estou começando a brincar com o CodeIgniter e achei um tutorial introdutório bem legal sobre ele. Ele foi escrito pelo Mike e está publicado no site dele o Capsize Designs. Ele foi bem gentil e permitiu que eu o traduzisse para o português.

CodeIgniter é um "Framework de aplicação web open source que permite você escrever programas PHP que arrebentam." O próprio site diz isso. O CodeIgniter é extravagante. Contudo, sua documentação é muito bom depois que você inicia, mas começar é um pouco difícil. É por isso que estou aqui. Espero que depois deste tutorial, você encontre seu caminho para entender o CodeIgniter e tenha um bom entendimento da arquitetura MVC.

Na parte um nós iremos aprender sobre a instalação e configuração do CI, e também conhecer um pouco sobre a estrutura de diretórios (que sempre parece assustar as pessoas). Então vamos começar.

Um pouco de fundamentos
Para aqueles que não estão familiarizados com frameworks PHP ou o conceito MVC (Modelo, Visualização, Controle) em geral, aqui está uma introdução. MVC é um método testado e genuíno de organizar código fonte e arquivos do programa. Basicamente o MVC separa o código de interface do código da lógica do programa.
O CodeIgniter implementa a arquitetura MVC muito bem, e coloca tudo em toneladas de classes PHP e helpers (arquivos com funções úteis para a aplicação) para ser mais produtivo e rápido. Você tem uma classe de manipulação de imagens na qual você tem acesso a funções para redimensionar, cortar e colocar uma marca d' agua facilmente. Você tem uma classe de captcha que torna bem fácil gerar captchas para formulários web. Você tem até mesmo uma classe de codificação ZIP que torna simples criar pacotes zip dinamicamente no seu site. Eu não ficaria surpreso se o CI 2.0 viesse completo com um uma classe pia_cozinha.php! Ponto final. Isso foi divertido.

Dando uma olhada
Agora vamos uma olhada no CodIgniter para ver com o que estamos lidando. Faça o download da versão mais nova do site do CI e descompacte o arquivo em algum lugar do seu servidor. Abra o diretório no seu gerenciador de arquivos e dê uma olhada.
Você deve ver quatro coisas: A pasta "system" (que contém praticamente TUDO, incluindo o código fonte do CI e as pastas para você colocar seu código), uma pasta user_guide (guia de usuário que você pode excluir porque tem tudo no site do CI), um arquivo license.txt, e um arquivo index.php (o qual roteia cada requisição para qualquer lugar que ela precise ir).

Abra a pasta system. Você vê a pasta "application"? Este é seu lar. Não toque em nenhuma das outras pastas a menos que você esteja querendo saber como as coisas funcionam. Ou melhor, nem mesmo faça isso. Dá medo. Somente abra a pasta application. Você vai ver algumas pastas aí dentro. No começo, as únicas pastas com as quais você vai se preocupar são, config, models, views e controllers. Quando você melhorar no desenvolvimento com o CI, talvez você queira desenvolver suas próprias bibliotecas ou helpers que vão ficar nas suas pastas apropriadas, mas espere um pouco! Paciência é a chave! CHAVE!!!

Configuração e instalação
A primeira pasta que iremos olhar é a config. Especificamente, nós vamos mexer com o config.php, autoload.php, e database.php. Abra o config.php e dê uma olhada. Este é o principal lugar para brincar com as opções que o CI oferece. Antes de tudo, mude o valor de $config['base_url'] para o local que sua instalação do CI está. Se você está rodando no localhost e colocou em uma pasta chamada "ci", por exemplo, você colocará "http://localhost/ci/". Se está em um servidor online, vai ficar mais ou menos assim "http://www.seustie.com/seu_diretorio_ci". Seja lá o que você colocar, TENHA CERTEZA de incluir a barra(/) depois do nome do diretório, e tenha TENHA CERTEZA de incluir o "http://".

Continuando, nós veremos que $config['index_page'] está setado para "index.php". Está ok por agora, porque por padrão o CodeIgniter roteia tudo através da página index.php na rota do documento. Isto significa que suas urls ficarão parecidas com "www.seusite.com/index.php/alguma_pagina". Se você quiser tirar o index.php do endereço (Eu sempre tiro! Fica feio!), você pode mudar a configuração $config['index_page'] para uma string vazia (somente duas aspas sem nada entre elas para aqueles que nunca programaram antes) ao invés de "index.php" e faça um arquivo .htaccess para remover isso da url como o wiki do CI ensina.

Vá para $config['log_threshold'] = 0, e mude para 1. Isso permite que mensagens de erro (como mensagens do PHP ) vão para o log. Qualquer coisa menor do que 1 e você não verá nenhum log, qualquer coisa maior do que 1 e seus arquivos de log vão aumentar sem piedade. Então, fique com 1. É uma boa prática.

ATUALIZAÇÃO: Aparentemente alguns servidores teem problemas setando log_threshold para 1, então se você só ver páginas em branco depois da instalação, mude para 0 e veja se funciona. Se alguém puder explicar isso, por favor me avise.

ATUALIZAÇÃO 2: Graças a cheekygeek (nos comentários do artigo original, link no início do texto), nós temos a resposta
"Uma solução para o problema do log_threshold é permitir a escrita na pasta system/logs. Contudo, deixar pastas na web com permissão de escrita(777) nunca é uma boa ideia... A solução mais segura em um sistema compatível com linux é dar a permissão de grupo dos arquivos de log para o usuário do servidor web. Se você estiver usando o Apache, você verá isso definido no arquivo httpd.conf."

Obrigado pela informação, cheekygeek!

De volta ao principal, vá em frente e mude a chave encriptação ($config['encryption_key']) para uma sequência randômica de 32 caracteres alfa-numéricos. Muitas aplicações que usam autenticação ou trabalham com senhas usam a chave de encriptação colocando ela no final da senha (chamam isso de sal) e então criam um hash disso para segurança. Isso faz o armazenamento de senhas um pouco mais seguro.

Agora vamos sair do config.php e iremos para o database.php, também na pasta config. Se sua aplicação não vai usar um banco de dados, você não precisa mexer neste arquivo. A maioria dos usuários irão somente mudar as primeiras quatro opções das opções de banco de dados (hostname, username, password, database). Se você não estiver usando MySQL, você terá que mudar a opção dbdriver, e se você estiver prefixando todas suas tabelas com algo, você terá que mudar o dbprefix. Todo o resto deve estar correto.

Finalmente, nós vamos abrir o autoload.php. Este arquivo basicamente diz para o CI quais dos helpers e bibliotecas você gostaria de carregar automaticamente. Helpers e bibliotecas podem ser carregados em um controlador pelo próprio controlador, mas se tiver algum que você irá usar a maioria dos controladores, você pode simplesmente auto carregá-lo. Se você está usando um banco de dados, você deveria auto-carregar "database" na seção de bibliotecas. Eu geralmente auto-carrego "url" na seção de helper. Visite o guia de usuário do CodeIgniter para ver o que isto tudo faz. Você provavelmente vai precisar despender algum tempo familiarizando-se com tudo isso para tirar total proveito do CI. NOTA: No topo da página do Guia do usuário, tem um pequeno botão chamado "Conteúdo" que revela um menu de navegação deslizante. Estou falando disso porque fiquei duas semanas martelando minha cabeça até eu achar este menu.

Agora abra seu browser, navegue para onde você instalou o CI com o index.php no final (algo como http://localhost/ci/index.php). NOTA: Se você usou o arquivo .htaccess para retirar o index.php da url, você obviamente não precisará colocá-lo no endereço. Você está vendo a página de bem vindo? Se está, você está dominando o CI! Como é bom esta sensação! SIMMMM! Se não está, coloque um comentário aqui ou mande uma mensagem para os ótimos fóruns do CodeIgniter e não deve ser muito difícil para descobrir o que está errado.

Por padrão, o CI carrega o controlador "welcome.php". Para mudar para sua própria página, abra o "routes.php" na pasta de configuração e mude o controlador padrão. Nós vamos falar mais sobre controladores (e modelos e visualizações também!) na próxima parte, fique ligado.