sábado, outubro 18, 2014

A Função row_number() em Consultas de Agregação Espacial

Em Banco de Dados, as funções de agregação são utilizadas para agrupar valores de acordo com um ou vários campos, agregando em uma única linha o conteúdo de vários registros. Dessa forma, os detalhes da informação original são postos de lado e as informações são tratadas em conjunto. São exemplos de funções de agregação: count(), sum(), max(), avg(), dentre outras. 

As funções de agregação também são empregradas em dados espaciais, é o caso da função ST_Union(), onde os vértices adjacentes da nova camada são dissolvidos a partir dos valores armazenados em um campo específico. 

Entretanto, para visualizar o resultado desta nova camada em um software de GIS ou de Webmapping, a maioria deles necessita que a camada tenha um campo com valores únicos. E é exatamente aí que a função row_number() se torna útil neste tipo de análise, permitindo gerar um campo “ID” (identificador único) a partir do número da linha dentro da consulta, de acordo com o “order by” informado. 

Para ilustrar o uso função row_number(), vejamos o exemplo a seguir (Figura 1). Utilizando o QGIS e uma camada de um BD Espacial PostGIS é realizada uma agregação dos municípios a partir do campo “meso” (mesorregiões do estado). 

Figura 1 - Consulta no DB Manager do QGIS

Desta forma, o campo id é criado e povoado através da função row_number() e o resultado pode ser visualizado no QGIS (Figura 2).

Figura 2 - Resultado em forma de mapa temático

Existem outras formas de se obter o mesmo resultado do campo id, neste tipo de situação, porém, o emprego da função row_number() é muito simples, como foi demonstrado no exemplo.

domingo, agosto 17, 2014

WMS GetFeatureInfo Utilizando MapServer e Leaflet

No Leaflet existem duas formas bem usuais de se obter os dados tabulares de uma feição através do clique do usuário em uma determinada camada. Uma delas é através do uso de marcadores (Markers), que é mais utilizada para a representação de pontos. A outra  é  o formato GeoJSON, que é uma excelente opção para exibir camadas de polígonos e de linhas neste aplicativo.

Porém, quando uma camada GeoJSON possui muitas feições ou uma grande quantidade de vértices, seu carregamento pode comprometer o desempenho do aplicativo. Uma saída para este problema é utilizar o formato WMS habilitando a requisição GetFeatureInfo como é mostrado no exemplo a seguir.

1 - Configuração do Mapfile como Servidor WMS:


A configuração do servidor WMS é feita através da definição dos itens obrigatórios para o seu funcionamento, a nível de MAP e de LAYER, definidos na documentação do MapServer no item "Setting Up a WMS Server Using MapServer". 

MAP
EXTENT -38.7852 -8.31435 -34.7738 -6.01455
NAME "mapserver_wms"
SIZE 800 600
UNITS DD
OUTPUTFORMAT
NAME "png"
MIMETYPE "image/png"
DRIVER "AGG/PNG"
EXTENSION "png"
IMAGEMODE RGB
TRANSPARENT TRUE
END # OUTPUTFORMAT
PROJECTION
"init=epsg:4326"
END # PROJECTION
WEB
METADATA
"ows_enable_request" "*"
"wms_title" "mapserver_wms"
"wms_onlineresource" "http://localhost/cgi-bin/mapserv?map=/var/www/html/mapserver_wms/municipios.map&"
"ows_srs" "EPSG:3857 EPSG:4326 EPSG:4291 EPSG:900913"
"wms_feature_info_mime_type" "text/html"
END # METADATA
END # WEB
LAYER
NAME "municipios"
EXTENT -38.7852 -8.31435 -34.7738 -6.01455
TYPE POLYGON
CONNECTIONTYPE POSTGIS
CONNECTION "dbname='mapserver_wms' host=localhost port=5432 user='marcello' password='<mypass>' sslmode=disable"
DATA 'geom FROM "municipios" USING UNIQUE gid USING srid=4326'
TEMPLATE "template.html"
STATUS ON
METADATA
"ows_title" "municipios"
END # METADATA
PROJECTION
'init=epsg:4326'
END # PROJECTION
CLASS
NAME "Municípios"
STYLE
COLOR 85 255 127
OUTLINECOLOR 0 85 0
WIDTH 1.4
OPACITY 60
END # STYLE
END # CLASS
END # LAYER
END # MAP
view raw gistfile1.rb hosted with ❤ by GitHub


2 - Configuração do Template HTML para a requisição GetFeatureInfo:


Neste arquivo são definidos os dados que serão exibidos na janela de atributos através do GetFeatureInfo WMS Request. 

<!-- Mapserver Template -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Mapserver Template</title>
</head>
<body>
<ul>
<li><strong>Município: </strong>[item name=nome]</li>
<li><strong>Código IBGE: </strong>[item name=geocodigo]</li>
<li><strong>Mesoregião: </strong>[item name=meso]</li>
<li><strong>Microregião: </strong>[item name=micro]</li>
</ul>
</body>
</html>
view raw template.html hosted with ❤ by GitHub

3 - Configuração do Leaflet:


Para habilitar esta funcionalidade  é necessário configurar a camada WMS no Leaflet, como é exibido a seguir:

var host = "http://localhost/cgi-bin/mapserv?";
var mapfile = "map=/var/www/html/mapserver_wms/municipios.map&";
var wms_server = host + mapfile;
var municipios = new L.tileLayer.wms(wms_server, {
layers: 'municipios',
format: 'image/png',
srs:"EPSG:4326",
transparent: true,
pointerCursor: true
}).addTo(map);
view raw gistfile1.js hosted with ❤ by GitHub
Já com a função IDENTIFY abaixo, é possível associar ao clique do mouse uma requisição GetFeatureInfo, através da obtenção das variáveis BBOX, WIDTH, HEIGHT, X e Y. Com elas é definida a variável URL que fará esta requisição ao servidor WMS e trará o resultado de forma assíncrona com método $.ajax do jQuery.

function Identify (e) {
var BBOX = map.getBounds().toBBoxString();
var WIDTH = map.getSize().x;
var HEIGHT = map.getSize().y;
var X = map.layerPointToContainerPoint(e.layerPoint).x;
var Y = map.layerPointToContainerPoint(e.layerPoint).y;
var URL = wms_server + 'SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&LAYERS=municipios&QUERY_LAYERS=municipios&BBOX='+BBOX+'&FEATURE_COUNT=1&HEIGHT='+HEIGHT+'&WIDTH='+WIDTH+'&INFO_FORMAT=text%2Fhtml&SRS=EPSG%3A4326&X='+X+'&Y='+Y;
$.ajax({
url:URL,
datatype: "html",
type: "GET",
success: function(data) {
var popup = new L.popup({
maxWith: 300
});
popup.setContent(data);
popup.setLatLng(e.latlng);
map.openPopup(popup);
}
});
}
view raw gistfile1.js hosted with ❤ by GitHub
A página HTML contendo o Leaflet fica então desta forma:

<!DOCTYPE html>
<html>
<head>
<title>Leaflet Quick Start Guide Example</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/leaflet.css" />
<style>
#map { width: 800px; height: 600px; border: 1px solid #000; cursor: pointer; }
ul>li { font-size: 12px; }
</style>
</head>
<body>
<div id="map"></div>
<script src="js/leaflet.js"></script>
<script src="js/jquery-2.1.1.min.js"></script>
<script>
var map = L.map('map').setView([-7.1826, -36.7382], 8);
L.tileLayer('https://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png', {
maxZoom: 18,
id: 'examples.map-i86knfo3'
}).addTo(map);
var host = "http://localhost/cgi-bin/mapserv?";
var mapfile = "map=/var/www/html/mapserver_wms/municipios.map&";
var wms_server = host + mapfile;
var municipios = new L.tileLayer.wms(wms_server, {
layers: 'municipios',
format: 'image/png',
srs:"EPSG:4326",
transparent: true,
pointerCursor: true
}).addTo(map);
map.addEventListener('click', Identify);
function Identify (e) {
var BBOX = map.getBounds().toBBoxString();
var WIDTH = map.getSize().x;
var HEIGHT = map.getSize().y;
var X = map.layerPointToContainerPoint(e.layerPoint).x;
var Y = map.layerPointToContainerPoint(e.layerPoint).y;
var URL = wms_server + 'SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&LAYERS=municipios&QUERY_LAYERS=municipios&BBOX='+BBOX+'&FEATURE_COUNT=1&HEIGHT='+HEIGHT+'&WIDTH='+WIDTH+'&INFO_FORMAT=text%2Fhtml&SRS=EPSG%3A4326&X='+X+'&Y='+Y;
$.ajax({
url:URL,
datatype: "html",
type: "GET",
success: function(data) {
var popup = new L.popup({
maxWith: 300
});
popup.setContent(data);
popup.setLatLng(e.latlng);
map.openPopup(popup);
}
});
}
</script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub

4 - Resultado:


Ao clicar em um município, é exibido uma janela contendo os atributos, como mostra a figura abaixo:


Você pode baixar os códigos deste exemplo neste link.

Sugestões de Leitura:


sexta-feira, junho 20, 2014

Instalação do i3Geo no Ubuntu 14.04

Estes dez passos te guiarão no processo de instalação do i3geo no Ubuntu 14.04.

1) Instalação do Mapserver

Para este primeiro item, realize os procedimentos descritos no post: Instalação do Mapserver no Ubuntu 14.04 via Terminal

2) Bibliotecas PHP necessárias para o funcionamento do i3geo:

$  sudo apt-get install libapache2-mod-php5 php5-common php5-curl php5-dev php5-gd php5-odbc php5-pgsql php5-ps php5-xmlrpc php5-xsl php5-sqlite php5-imagick php5-json

Em seguida, reinicie  servidor Apache:

$  sudo /etc/init.d/apache2 restart

3) Instalação do do Banco de Dados sqlite:

$  sudo apt-get install sqlite

4) Instalação do software estatístico R (item opcional)

$  sudo apt-get install r-base r-base-core r-cran-maptools r-cran-spatstat

5) Instalação do subversion (SVN)

$  sudo apt-get install subversion

6) Download do i3Geo

Para esta etapa, é necessário que você tenha uma conta no Portal do Software Público Brasileiro. Caso não possua, clique neste link: http://www.softwarepublico.gov.br/Registre-se e crie sua conta, em seguida digite no terminal:

$  svn checkout http://svn.softwarepublico.gov.br/svn/i3geo/i3geo/ /var/www/html/i3geo

e informe o seu email e senha cadastrada.

7) Altere as permissões do arquivo admin.db

$  sudo chmod -R 755 /var/www/html/i3geo/admin/admin.db

8) Crie a pasta ms_tmp dentro de /tmp

$  sudo mkdir /tmp/ms_tmp && sudo chmod -R 755 /tmp/ms_tmp

9) Crie um link simbólico dentro da pasta /var/www/html direcionando para /tmp/ms_tmp

$  sudo ln -s /tmp/ms_tmp /var/www/html/ms_tmp

10) Testanto a instalação:

Digite no browser: http://localhost/i3geo, você deverá ver uma tela semelhante a da figura abaixo. Caso ocorra algum erro, realize um teste de instalação através do link: http://localhost/i3geo/testainstal.php (usuário admin, senha admin).



Referência:

Instalação e Administração do i3Geo - guia do administrador

segunda-feira, junho 16, 2014

Perfil Longitudinal do Rio Principal Utilizando o GRASS e o R

Por definição, o perfil longitudinal de um rio apresenta a relação existente entre a variação altimétrica e o comprimento do mesmo, desde a nascente até a foz ou ponto de confluência.

Neste tutorial daremos continuidade ao post "Caracterização Morfométrica de Bacias Hidrográficas utilizando o GRASS" onde a partir do rio principal, será gerado o gráfico do perfil longitudinal do mesmo, utilizando o GRASS e o R.

Com o GRASS aberto no terminal, digite os comandos a seguir:

# 1) Criação de um camada de pontos, contendo os vértices do rio principal
v.to.points -i -v -t in=out_dem_filled_mainchannel out=mchannel_pts type=line dmax=1000
# 2) Exportação dos vértices para um arquivo txt
v.out.ascii mchannel_pts > coords.txt
# 3) Remoção dos pipes ("|") e da coluna cat do arquivo txt
cat coords.txt | awk -F "|" '{print $1,''$2}' > xy.txt
# 4) Substituição dos espaços por vírgulas
sed -i "s/ /,/g" xy.txt
# 5) Criação do arquivo txt contendo as distâncias e as elevações do perfil
cat xy.txt | r.profile input=dem output=profile.txt
# 6) Início da sessão do R
R
# 7) Importação do arquivo txt
profile <- read.table('profile.txt', header=F, sep=" ",col.names=c('distance','elev'))
# 8) Plotagem do gráfico
plot(profile$distance/1000, profile$elev, axes='true', xlab='Distância (km)',
ylab='Elevações (m)', main='Perfil Longitudinal do Rio Principal', type='l', col='blue')
# 9) Adição do Grid de coordenadas
grid()
view raw gistfile1.sh hosted with ❤ by GitHub
Como resultado, teremos o gráfico abaixo:


Referências:

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/

sábado, abril 19, 2014

Instalação do Mapserver no Ubuntu 14.04 via Terminal


O Ubuntu 14.04 Trusty Tahr foi disponibilizado recentemente pela Canonical. Esta será uma versão LTS (Long Term Support) que terá suporte técnico durante 5 anos.

Neste tutorial demonstrarei como instalar o MapServer 6.4.1 nesta distribuição, utilizando o Terminal:

1 - Instalando o servidor Apache:

$  sudo apt-get install apache2

 

2 - Configurando as permissões do seu usuário na pasta de publicação:


Substitua a palavra "marcello" pelo nome do seu usuário:

$ sudo adduser marcello www-data 
$ sudo chown marcello:www-data -R /var/www 
$ sudo chmod 0755 -R /var/www

 

3 – Instalando o PHP:

$ sudo apt-get install php5

 

4 – Instalando o Mapserver:

$ sudo apt-get install cgi-mapserver mapserver-bin php5-mapscript

 

5 – Habilitando o CGI no Apache:

$ sudo a2enmod cgi && sudo service apache2 restart

 

6 – Verificando a instalação do Mapserver CGI:


Abra o navegador e digite a url: http://localhost/cgi-bin/mapserv?, deverá surgir a seguinte mensagem:

No query information to decode. QUERY_STRING is set, but empty.

 

7 – Verificando a instalação do php-mapscript

$ cd /var/www/html/
$ touch info.php
$ echo '<?php phpinfo(); ?>' >> info.php

Abra o navegador e digite a url: http://localhost/info.php, procure pela seguinte ocorrência:




That's all folks! Um abraço e até a próxima!

sábado, março 01, 2014

Mapas de relevo com a biblioteca GDAL

Elaborei um script utilizando as bibliotecas gdal e imagemagick para criar mapas de relevo com o efeito Hillshade. Para rodá-lo, basta colocá-lo em uma pasta (como mostra a Figura 1) com os arquivos SRTM baixados da site da Embrapa, junto com o shapefile contendo o limite da sua área de interesse e esta palheta de cores. Em seguida, é só digitar ./mosaic.sh

Figura 1 - Pasta contendo os arquivos necessários

Em função das cores definidas para cada cota no arquivo my_classes.ctp, o script cria um novo raster através do comando gdaldem (Figura 2).

# created by: Marcello Benigno
0 102 153 153
1 236 241 230
10 176 242 205
50 180 246 179
100 207 250 177
150 242 252 179
200 220 238 145
250 147 208 93
300 69 179 53
350 21 151 47
400 18 130 63
450 81 144 58
500 132 158 47
550 181 171 35
600 233 181 17
650 235 149 2
700 209 97 2
750 177 54 2
800 148 20 1
850 124 6 1
900 117 21 4
950 113 30 6
1000 109 39 9
1050 106 45 12
1100 117 64 30
1150 133 88 60
1200 149 113 93
1250 162 144 135
1300 173 173 172
1350 190 190 190
1400 210 208 210
1450 227 225 227
view raw my_classes.cpt hosted with ❤ by GitHub

Figura 2 - Imagem SRTM colorida

Em seguida é gerado o arquivo Hillshade (Figura 3).

Figura 3 - Relevo sombreado (Hillshade)

E os arquivos anteriores são unidos, como mostra a Figura 4.

Figura 4 - União do relevo sombreado com a imagem SRTM colorida

Por último, em função do limite do shapefile, o arquivo é "clipado". A Figura 5 mostra o resultado da utilização do script para o estado do Mato Grosso do Sul.

Figura 5 - Resultado da utilização do script para o MS.

Lembrando que para utilizar o script, é necessário lhe dar permissões de execução após baixá-lo, através do comando abaixo:
$ sudo chmod +x mosaic.sh
#!/bin/bash
# Author: Marcello Benigno, Mar/2014; copyright: GPL >= 2
# Purpose: Create a beautiful SRTM Hillshade color Map
# Usage: ./mosaic.sh
## Required programs:
## imagemagick
## gdal >=1.7.0
## my_classes.cpt - download at
## <https://gist.github.com/marcellobenigno/9289976>
echo -n "Enter the shapefile name (or path):"
read _SHP
echo "Unzipping files:"
echo "----------------"
for i in *.zip ; do unzip $i ; done
mkdir zip
mv *.zip zip
ls *.tif *.rrd *.aux > list.txt
files=`cat list.txt`
echo "Creating the mosaic:"
echo "----------------"
gdalwarp *.tif 00.tif
echo "removing unnecessary files:"
echo "----------------"
for i in `echo $files`;do
find . name *$i -exec rm -rf {} \;
done
rm list.txt
SHPFILE=$_SHP
BASE=`basename $SHPFILE .shp`
EXTENT=`ogrinfo -so $SHPFILE $BASE | grep Extent | sed 's/Extent: //g' | sed 's/(//g' | sed 's/)//g' | sed 's/ - /, /g'`
EXTENT=`echo $EXTENT | awk -F ',' '{print $1 " " $4 " " $3 " " $2}'`
echo $EXTENT
echo "Cutting SRTM according to the bounding box:"
echo "----------------"
gdal_translate -projwin $EXTENT -of GTiff -co compress=LZW 00.tif 01.tif
echo "Generating raster with the altimetric classes:"
echo "----------------"
gdaldem color-relief 01.tif -alpha my_classes.cpt 02.tif
echo "Generating hillshade:"
echo "----------------"
gdaldem hillshade -z 5 -s 111120 -co COMPRESS=LZW 01.tif 03.tif
echo "Adjusting Hillshade's contrast (takes a while):"
echo "----------------"
convert -gamma .5 03.tif 04.tif
echo "Merging hillshade with color terrain SRTM (takes a while):"
echo "----------------"
convert 02.tif 04.tif -compose Overlay -composite 05.tif
listgeo -tfw 01.tif
mv 01.tfw 05.tfw
echo "Assigning the original Coordinate System:"
echo "(loose spatial reference after merging with imagemagick)"
echo "----------------"
gdal_translate -of GTiff -co compress=LZW -co tiled=YES 05.tif -a_srs EPSG:4326 06.tif
echo "Cliping the raster to the bounding box of shapefile (takes a while):"
echo "----------------"
gdalwarp -co compress=JPEG -co TILED=YES -of GTiff -cutline $SHPFILE 06.tif dem_hillshade.tif
echo "Removing unnecessary files and ending :)"
echo "----------------"
rm -fr 00* 01* 02* 03* 04* 05* 06* *.tfw
view raw mosaic.sh hosted with ❤ by GitHub

Referências:

quinta-feira, janeiro 16, 2014

Conversão de Tabelas Espaciais para o Formato GeoJSON Utilizando PHP

Neste exemplo irei utilizar o CodeIgniter para realizar a conversão de uma tabela espacial (rodovias) para o formato GeoJSON, utilizando MVC.

Primeiro deve-se criar um Model. Com a função geojson_output(), observem que a geometria da tabela é convertida para GeoJSON e reprojetada para WGS-84:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Rodovias_model extends CI_Model {
private $_table_name = 'rodovias';
public function __construct()
{
parent::__construct();
}
public function geojson_output()
{
$sql = "SELECT nome, codigo, trecho, kminicial, kmfinal, situacao_fisica,
st_asgeojson(st_transform(geom, 4326)) AS geojson
FROM {$this->_table_name}";
$query = $this->db->query($sql);
if($query->num_rows() > 0)
{
return $query->result_array();
}
else
{
return false;
}
}
}
/* End of file rodovias_model.php */
/* Location: ./application/models/rodovias_model.php */

Em seguida o Controller, que vai receber os dados do Model e enviar para a View:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Rodovias extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('rodovias_model', 'model');
}
public function geojson_link()
{
$data['geojson_data'] = $this->model->geojson_output();
$this->load->view('rodovias_geojson', $data);
}
}
/* End of file rodovias.php */
/* Location: ./application/controllers/rodovias.php */
view raw rodovias.php hosted with ❤ by GitHub

Por último a View, que renderiza os dados no formato GeoJSON:

<?php
header('Content-Type: text/javascript; charset=UTF-8');
function escapeJsonString($value)
{
$escapers = array("\\", "/", "\"", "\n", "\r", "\t", "\x08", "\x0c");
$replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t", "\\f", "\\b");
$result = str_replace($escapers, $replacements, $value);
return $result;
}
$output = '';
$rowOutput = '';
foreach ($geojson_data as $row)
{
$rowOutput = (strlen($rowOutput) > 0 ? ',' : '') . '{"type": "Feature", "geometry": ' . $row['geojson'] . ', "properties": {';
$props = '';
$id = '';
foreach ($row as $key => $val)
{
if ($key != "geojson")
{
$props .= (strlen($props) > 0 ? ',' : '') . '"' . $key . '":"' . escapeJsonString($val) . '"';
}
if ($key == "id")
{
$id .= ',"id":"' . escapeJsonString($val) . '"';
}
}
$rowOutput .= $props . '}';
$rowOutput .= $id;
$rowOutput .= '}';
$output .= $rowOutput;
}
$layer = 'var rodovias = ';
$output = $layer . '{ "type": "FeatureCollection", "features": [ ' . $output . ' ]}';
echo $output;

Para ver os dados da tabela neste formato (Figura 1), é necessário acessar a url que contém o "controller/método" utilizado, no meu caso:
http://localhost/sirh/rodovias/geojson_link

Figura 1 - Resultado da conversão







Seguindo a documentação do Leaflet é bastante simples carregar os dados neste formato. O resultado pode ser conferido na Figura 2.

Figura 2 - GeoJson exibido na interface do Leaflet