sábado, maio 10, 2014

Aplicações WebGIS com o Laravel

Quem programa em PHP já deve conhecer ou ter ouvido falar sobre o Laravel. Uma coisa interessante neste framework é que é possível trabalhar com dados espaciais de forma muito prática.

O código abaixo exemplifica a implementação da classe Obra, que no PostGIS é uma tabela espacial do tipo POINT.

Primeiro criamos a migration:

<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateobrasTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
Schema::create('obras', function($table){
$table->increments('id');
$table->string('nome_obra');
$table->timestamps();
});
// Adicionando a coluna que armazenará as geometrias do tipo ponto:
DB::unprepared("ALTER TABLE obras ADD COLUMN geom GEOMETRY(POINT, 4326)");
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
Schema::drop('obras');
}
}
Após rodarmos a migration, criamos o model Obras.php

<?php
class Obra extends Eloquent {
protected $fillable = array('nome_obra', 'geom');
public static $rules = array(
'nome_obra'=>'required|min:3',
/* OBS: os campos abaixo servem para validação da coluna geom
e não existem na tabela Obra */
'longitude'=>'numeric|required',
'latitude'=>'numeric|required'
);
}
view raw Obras.php hosted with ❤ by GitHub
No controller ObrasConrtoller.php, temos o método postCreate(), que recebe os dados de uma view onde são informadas as coordenadas x e y através de um formulário (ou de alguma aplicação Webmapping como mostra a Figura 1). Tais coordenadas são checadas através do método estático checkCoords($x, $y) do model Municipios.php. Este método faz a verificação das coordenadas informadas, que devem estar dentro dos limites do estado:

<?php
class ObrasController extends BaseController {
public function getIndex() {
$obras = DB::table('obras')
->select(DB::raw('ST_X(geom) as lng, ST_Y(geom) AS lat, nome_obra'))
->get();
return View::make('obras.index')
->with('title', 'Mapa das Obras')
->with('obras', $obras);
}
public function getCreate() {
return View::make('obras.create')
->with('title', 'Nova Obra');
}
public function postCreate() {
$validator = Validator::make(Input::all(), Obra::$rules);
if(!$validator->passes()) {
return Redirect::to('obras/create')
->with('message', 'Ocorreu um erro, tente novamente')
->withErrors($validator)
->withInput();
} else {
$x = Input::get('longitude');
$y = Input::get('latitude');
$check = Municipio::checkCoords($x, $y);
if($check == false) {
return Redirect::to('obras/create')
->with('message', 'Coordenadas Inválidas');
}
$obra = new Obra;
$obra->nome_obra = Input::get('nome_obra');
$obra->geom = DB::raw("ST_GeomFromText('POINT({$x} {$y})', 4326)");
$obra->save();
return Redirect::to('obras/index')
->with('message', 'Obra cadastrada com sucesso');
}
}
}
 
Figura 1 - Exemplo de View.

<?php
class Municipio extends Eloquent {
public static function checkCoords($x, $y) {
$query = Municipio::whereRaw(
"ST_Contains(geom, ST_GeomFromText('POINT($x $y)', 4326))"
)->first();
if($query) {
return $query;
}
return false;
}
}
view raw Municipio.php hosted with ❤ by GitHub
Embora o código aqui esteja bastante resumido, acredito que dá para se ter uma ideia do fluxo de trabalho neste framework, envolvendo dados espaciais. Qualquer dúvida ou melhoria no código serão bem vindas.

Um abraço e até a próxima o/

Nenhum comentário: