terça-feira, 30 de março de 2010

Termo de Utilização: OpenLayers e Google Maps

Têm-me perguntado frequentemente o porquê da utilização da API do Google Maps preterindo a API do OpenLayers.

A resposta é que sempre que pretendo utilizar dados de base do Google Maps (e pretendo muitas vezes), prefiro utilizar directamente a sua API que ir recorrer ao OpenLayers adicionando uma OpenLayers.Layer.Google .

Ou seja, quando utilizo OpenLayers e adiciono uma Layer de Google Maps, não deixo de estar sujeito aos Termos de Utilização da API do Google Maps. Isto parece-me trivial.

De qualquer forma, as restrições de utilização da API do Google Maps não são nada de transcendente, basta ver em http://code.google.com/intl/pt-PT/apis/maps/

"The Maps API is a free service, available for any web site that is free to consumers"

"To use the Maps API on an intranet or in a non-publicly accessible application, please check out Google Maps API Premier"




quarta-feira, 24 de março de 2010

Altitudes do Brasil

Clicar no mapa para saber a altitude





Altitudes em metros. Coordenadas Geográficas referentes ao sistema WGS84.
Especificação dos dados:
- Resolução dos dados: 30 * 30 metros.
- Exactidão vertical: 20 metros (nível de confiança de 95%).
- Exactidão horizontal: 30 metros (nível de confiança de 95%).

Fonte dos dados: Geonames

terça-feira, 23 de março de 2010

Raster Query com a GDAL

Problema: saber o valor do pixel de uma imagem georeferenciada para um determinado par de coordenadas e uma determinada banda.

Solução utilizando GDAL Python bindings:

Nota: no código que se segue substituir underscore(_) por espaço em branco.

import struct
import gdal
from gdalconst import *

filename = "image.tif"
dataset = gdal.Open( filename, GA_ReadOnly )

def CellValue(dataset, band, x, y):
_band = dataset.GetRasterBand(band)
_if (band.GetNoDataValue() == None):
___band.SetNoDataValue(-9999)
_ndv = band.GetNoDataValue()
_cols = band.XSize
_rows = band.YSize
_geotransform = dataset.GetGeoTransform()
_cellSizeX = geotransform[1]
_cellSizeY = -1 * geotransform[5]
_minx = geotransform[0]
_maxy = geotransform[3]
_maxx = minx + (cols * cellSizeX)
_miny = maxy - (rows * cellSizeY)
_print 'bbox(real-world coords):',minx,',',miny,',',maxx,',',maxy
_if ((x <> maxx) or (y <> maxy)):
___print 'given point does not fall within grid'
___return ndv
_xLoc = (x - minx) / cellSizeX
_xLoc = int(xLoc)
_yLoc = (maxy - y) / cellSizeY
_yLoc = int(yLoc)
_#print 'point (pixels): ',xLoc,',',yLoc
_if ((xLoc <> cols - 0.5)):
___#print 'xcoordinate out of bounds'
___return ndv
_if ((yLoc <> rows - 0.5)):
___#print 'ycoordinate out of bounds'
___return ndv
_strRaster = band.ReadRaster(xLoc, yLoc, 1, 1, 1, 1, band.DataType)
_sDT = gdal.GetDataTypeName(band.DataType)
_if (sDT == 'Int16'):
___dblValue = struct.unpack('h', strRaster)
_elif (sDT == 'Float32'):
___dblValue = struct.unpack('f', strRaster)
_elif (sDT == 'Byte'):
___dblValue = struct.unpack('B', strRaster)
_else:
___print 'unrecognized DataType:', gdal.GetDataTypeName(band.DataType)
___return ndv
_print sDT
_return dblValue[0]

Testar a função:

print CellValue(dataset, 1, 222960.0, 285040.0)


Fonte: thread da mailing-list gdal-dev.


Layer de SQL Server 2008 no MapServer

O MapServer tem a possibilidade de estabelecer conexão (em modo read-only) com uma base de dados espacial residente em Microsoft SQL Server 2008.

No caso do MS4W começar por confirmar a existência do respectivo plugin:

/ms4w/Apache/specialplugins/msplugin_mssql2008.dll

No mapfile, na respectiva layer, é necessário utilizar o parâmetro CONNECTIONTYPE PLUGIN bem como o parâmetro PLUGIN para definir a PATH do mesmo.

Utilizar o parâmetro CONNECTION para definir os parâmetros de ligação que permitem aceder ao SQL Server e o parâmetro DATA para especificar a tabela na qual residem os dados espaciais.
LAYER
...
CONNECTIONTYPE PLUGIN
PLUGIN "C:/ms4w/Apache/specialplugins/msplugin_mssql2008.dll"
CONNECTION "server=localhost/sqlexpress;uid=dbusername;
pwd=dbpassword;database=Districts Database;
Integrated Security=false"
DATA "the_geom from districts"
TYPE POLYGON
STATUS ON
CLASS
...
END
END

terça-feira, 2 de março de 2010

Curvas de nível no MapServer

A representação de curvas de nível no MapServer não oferece problemas de maior. Apenas duas questões requerem um cuidado especial:
  • diferenciação entre curvas de nível mestras e secundárias através de simbologia diferente;
  • colocação de índices (labels) nas curvas de nível mestras.
Consideremos uma representação de curvas de nível com uma equidistância de 25 metros. Segundo as boas práticas de representação cartográfica, as curvas mestras serão representadas de 100 em 100 metros. Assim, teremos 3 curvas secundárias entre cada 2 curvas mestras.

No ficheiro de configuração do MapServer poderemos definir duas classes para a mesma layer obtendo algo do género: