Arquivo da categoria: programação

programar é viver. not.

Inserindo registros geoespaciais: ArcSDE e SQL Server

Inserir registros diretamente através de comandos SQL é bem simples. Note que estou usando como tipo de dado geoespacial o GEOMETRY, nativo do SQL Server 2008.

Primeiro  é necessário criar uma tabela no SQL Server e registrá-la junto ao ArcSDE. Isto é bem simples de se realizar utilizando o ArcCatalog (note que também dá para se criar a tabela via SQL e registrá-la no ArcSDE via linha de comando).  Basta entrar no ArcCatalog, conectar-se com sua instância do ArcSDE e clicar com o botão direito no ícone do banco de dados. Depois é só escolher o Feature Class:

Feature Class

Criando um Feature Class

É apresentada então uma caixa de diálogo para criar sua tabela que conterá sua feição. Criei uma tabela chamada MeuFeatureClass. As colunas OBJECTID e SHAPE são criadas por padrão. Adicionei um campo1 e um campo2 também. E escolhi o tipo da geometria como POINT.

Criada a tabela é bem simples de se inserir um registro através de comando SQL:

INSERT INTO
MeuBD.sde.MeuFeatureClass
(OBJECTID, campo1, campo2, shape)
VALUES
(1, valor1, valor2, geometry::STGeomFromText('POINT (-46.616667 -23.533333)', 4674))

O comando acima insere um registro na tabela contendo um ponto localizado no município de São Paulo – SP, usando o SRID 4674 (SIRGAS 2000).

Note que não usamos uma função típica do T-SQL  para transformar o texto dado em uma coordenada válida pro sistema.  Isto me deixou confuso no início, pois eu não encontrava funções geoespaciais no banco de dados. Liste as funções existentes no banco de dados do ArcSDE que oê não encontrará nada relacionado ao sistema geo.

Estas funções ficam disponíveis como métodos da classe e objetos  geometry.  No caso acima, o STGeomFromText é um método estático da classe geometry. Os mundos da Orientação a Objetos e do SQL se mesclam cada vez mais…

Carregando bibliotecas Javascript abertas

Ext, jQuery, prototype, MooTools, Dojo, scrip.taculo.us, YUI. São algumas das feras que um desenvolvedor web tem de enfrentar, no caminho para matar o Dragão.

Algo que pode ajudar nesta tarefa é usar a própria API Google para carregar estas outras APIs:

http://code.google.com/apis/ajaxlibs/

O código, retirado direto do site, é o seguinte:

// Load Google JS API
<script src="http://www.google.com/jsapi"></script>
<script>
// Load jQuery
google.load("jquery", "1");
</script>

Você simplesmente:

  • carrega a API javascript do Google;
  • utiliza a API do Google para carregar as outras APIs, podendo escolher a versão, inclusive.

A opção de escolher a versão do script ajuda bastante a manter seus sistemas atualizados de forma bem simples.

O problema é apenas não poder guardar as APIs no servidor. Em uma rede local sem acesso à internet, por exemplo, isto já não serve.

SIRGAS 2000

Antes Sistema de Referencia Geocéntrico para America del Sur e agora Sistema de Referencia Geocéntrico para las Américas, o SIRGAS é o sistema de referenciamento espacial padrão do Brasil, definido pelo IBGE.

Seu SRID, num sistema geográfico, é  EPSG:  4674:

GEOGCS["SIRGAS 2000",
    DATUM["Sistema_de_Referencia_Geocentrico_para_America_del_Sur_2000",
        SPHEROID["GRS 1980",6378137,298.257222101,
            AUTHORITY["EPSG","7019"]],
        TOWGS84[0,0,0,0,0,0,0],
        AUTHORITY["EPSG","6674"]],
    PRIMEM["Greenwich",0,
        AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.01745329251994328,
        AUTHORITY["EPSG","9122"]],
    AUTHORITY["EPSG","4674"]]

Na prática o SIRGAS utiliza o mesmo elipsóde de referência do WGS84 – GRS 1980. Veja mais no site da UFRGS. O mesmo ocorre com o posicionamento do elipsóide, com seus centros situando-se bem próximos um do outro.

Isto significa que as medidas dados pelo SIRGAS são quase iguais aos dados pelo WGS84,  onde uma diferença entre as medidas pode ser menor que o erro aproximado de seu instrumento GPS, pois esta diferença está na ordem de centímetros.

Assim, se seu equipamento for antigo é bem provável que ocorram duas coisas:

  • ele não tenha uma precisão tão boa a ponto de se distinguir entre WGS84 e SIRGAS 2000;
  • ele não possua o SIRGAS 2000 em seu rol de referências.

Então use o WGS84 e seja feliz.

Sistema de Referenciamento Espacial

Spatial Reference System,  ou Sistema de Referenciamento Espacial, define como descrever uma posição, uma localização no espaço.

Para determinarmos essa posição precisamos de duas coisas: um ponto de referência e um sistema de coordenadas.

Datum

Para descrever esta localização temos de levar em conta algumas coisas. Primeiro, a Terra não é plana. Verdade. E nem uma bola.  Mas podemos aproximar sua superfície à algumas formas geométricas.  A primeira que vem à mente é a esfera. É boa para se montar globos escolares e pintar os continentes em  bolas de  praia. Mas, como aprendemos na escolinha, a Terra é achatada nos pólos. Mas a aproximação com a esfera serve para qualquer coisa que conte com uma escala pequena.

Globo terrestre

Segue então uma segunda aproximação: um elipsóide ou esferóide. Ou uma esfera achatada.  Esta forma geométrica é bastante utilizada para descrever a superfície do planeta,  parte por facilitar bastante os cálculos envolvidos e parte por se adequar razoavelmente à superfície verdadeira da Terra. Para obter um grau maior de aproximação modificamos os tamanhos dos eixos do elipsóide e também deslocamos seu centro, ajeitando-o com relação à Terra.

Ou seja, se a Terra fosse um esferóide perfeito, todos os pontos de sua superfície iriam tocar nos pontos do esferóide de referência.  Como isso não ocorre, a gente ajeita o esferóide, definindo em que pontos o esferóide toca a superfície do planeta.  Note que definição de pontos tem data de validade, ou pelo menos data de referência, visto que a posição relativa entre os continentes muda com o tempo. Digamos que nosso esferóide toca a superfície do planeta em um ponto específico de Pindamonhangaba e em outro em Paris. Infelizmente estes pontos não corresponderão exatamente ao mesmo local no dia seguinte. Por isso temos nomes como WGS84, SAD69. Os números se referem ao ano .

Esferóide

Uma outra forma é a geóide. A geóide se trata de uma figura geométrica cuja superfície possui sempre a mesma força gravitacional, correspondendo mais ou menos ao nível médio do mar. Uma esfera não rolaria para lado nenhum em cima da superfície de uma geóide. Os cálculos sobre esta figura são mais complicados, mas é uma aproximação bastante útil para analisar a construção de canais, rodovias extensas e redes de água e esgoto.

Geóide

A escolha da figura geométrica, a definição de suas dimensões e o posicionamento desta figura com relação à Terra nos dá o datum (nota: só estou considerando sistema geocêntricos, deixando os topocêntricos de lado).

Espermatozóide

Sistema Geográfico de Coordenadas

Temos um datum. Mas isto não basta. Precisamos de um sistema de coordenadas para localizar o que quer que seja. Para isto temos um Sistema Geográfico de Coordenadas (geographic coordinate system ou GCS), também conhecido como sistema esférico de coordenadas,  que inclui uma unidade de medida angular, um meridiano principal e um datum.

Latitude (φ) e Longitude (λ)

Com o datum, o equador e o meridiano principal, geralmente o de Greenwich, conseguimos um ponto de referência,  onde φ = 0° e λ = 0°,  e o centro do esferóide, a partir do qual todas as medidas são baseadas. Só para constar, a cidade de São Paulo se encontra em 23°33′0″ S, 46°38′0″ W, ou seja, latitude  -23°33′0″ e longitude -46°38′0″.

Sistema de Coordenadas Projetadas

O GCS ajuda a localizar algum ponto. Mas para visualizar o mapa no papel, ou na tela do computador, precisamos levar tudo que está em um objeto 3D em pontos correspondentes em um plano 2D. Isto se chama projeção. A mesma projeção que se ensina nas aulas de matemática da escolinha, mas aplicada em nossos mapas.

Pensando na superfície da Terra, podemos pensar em algumas características:

  • Área
  • Forma
  • Direção
  • Posicionamento relativo
  • Distância
  • Escala

Quando projetamos esta superfície em um plano, podemos preservar algumas delas. Mas não todas. Por isto existem vários tipos de projeção. Cada uma prioriza alguma das propriedades descritas. A mais famosa é a Projeção de Mercator, que privilegia direção e posicionamento relativo.

Projeção de Mercator

A projeção de Mercator é do tipo cilíndrica. Pense em uma bola de tênis enfiada em uma lata de batatas Pringles.  O problema dela é que deforma bastante a área conforme nos afastamos da linha do Equador. É só reparar no tamanho da Ántártica, que não é nem o dobro da do Brasil.

O cilindro em que é projetado o mapa tem seu eixo na mesma direção do eixo de rotação da Terra,  ou seja, o cilindro toca a Terra ao longo da linha do Equador.

Projeção cilíndrica

Isto nos leva à outra projeção importante: o Sistema Universal Transverso de Mercator (UTM). Ele é bastante semelhante à projeção de Mercator tradicional.

As diferenças são que o eixo do cilindro faz 90° com o eixo de rotação da Terra e o próprio cilindro é rotacionado  para obtermos projeções  mais precisas em cada fatia em que o cilindro toca a Terra.

Universal Transverse of Mercator

Estas fatias são então quadriculadas em uma grade. Cada quadrado desta grade forma então um sistema de coordenadas cartesianas, onde a unidade de medida é o metro.

Sistema de Referenciamento Espacial (Spatial Reference System)

E por fim temos o sistema de referencimento espacial, que nada mais é que a descrição de um conjunto que tem tudo que esta aí em cima. Um exemplo:

GEOGCS["SAD69",
    DATUM["South_American_Datum_1969",
        SPHEROID["GRS 1967 (SAD69)",6378160,298.25,
            AUTHORITY["EPSG","7050"]],
        AUTHORITY["EPSG","6618"]],
    PRIMEM["Greenwich",0,
        AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.01745329251994328,
        AUTHORITY["EPSG","9122"]],
    AUTHORITY["EPSG","4618"]]

O que é descrito acima, num formato conhecido como Well Known Text (WKT),  é o sistema SAD 69. Note é descrito o sistema geográfico de coordenadas (GEOGCS) com o datum utilizado,  o meridiano principal – Greenwich e a unidade de medida – degree,  assim como outras informações.  É comum utilizar apenas um número para nos referir a esta referência espacial. Este número, o SRID,  pode ser visto na última linha: EPSG 4618. Muito mais exemplos em SpatialReference.org.

Outro exemplo:

PROJCS["SIRGAS 2000 / UTM zone 23S",
    GEOGCS["SIRGAS 2000",
        DATUM["Sistema_de_Referencia_Geocentrico_para_America_del_Sur_2000",
            SPHEROID["GRS 1980",6378137,298.257222101,
                AUTHORITY["EPSG","7019"]],
            TOWGS84[0,0,0,0,0,0,0],
            AUTHORITY["EPSG","6674"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.01745329251994328,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4674"]],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",-45],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",10000000],
    AUTHORITY["EPSG","31983"],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH]]

Neste caso é descrito um sistema de coordenadas projetadas (PROJCS), o que requer, além das informações previstas para o GEOGCS, qual o tipo de projeção – Transverse Mercator – e localização do ponto de referência  que determina o origem do sistema de medidas, no caso  em metros.  O srid é 31983.

Ao invés de passar toda estas informações para alguém, basta informar o SRID.  Finalmente sabemos de onde vem o tal SRID que popula nossos banco de dados geográficos, e que devemos passar como parâmetro para as APIs Geo deste  mundão esferóide afora.

O Menu Asp.NET e o Chrome (e Safari)

Existe um problema no controle Menu no Asp.NET WebForms que faz com que ele não seja renderizado corretamente no Safari e no Google Chrome. O que acontece é que o servidor detecta o user-agent do navegador do cliente e monta a página de acordo.  Mas o  Asp.NET não reconhece o Safari e o Chrome como navegadores capazes, e por isso não conseguem renderizar um Menu em toda sua glória infestada de table’s, tr’s e td’s. Então lhes é servido um menu mais pobre, feio e maltratado .

O jeito é então alertar o Asp.NET  da existência destes navegadores.  E para isto basta criar uma pasta e um arquivo.

Se já não existir, crie em seu projeto uma pasta App_Browsers. E dentro dela crie um arquivo chamado safari.browser, que deve conter o seguinte:

<browsers>
    <browser refID="Safari1Plus">
        <controlAdapters>
            <adapter controlType="System.Web.UI.WebControls.Menu" adapterType="" />
        </controlAdapters>
    </browser>
</browsers>

E pronto! Tanto Safari quanto Chrome agora poderão mostrar seus lindos menus tablefull.

Programar é arte

O tema é recorrente.  Desde o monumental The Art of Computer Programming ao, hmm…, pragmático  The Pragmatic Programmer existe a noção de que programar não é uma ciência exata. Não é produção, tampouco engenharia. Programar é uma atividade que requer criatividade, visão, trabalho e destreza. É arte.

Vem daí a dificuldade de se estabelecer prazos. De gerar metodologias. De ser produtivo, ter qualidade e criar soluções. Como apressar, controlar e gerenciar algo tão pessoal quanto a produção de código? Talvez tornando-o impessoal e automático. Mas não seria isto remover as características que diferenciam um software bom de um ótimo?

Pode-se criar arte em massa. Pode-se criar obra únicas. Pode-se apreciar ou não uma obra-prima. Não é tão diferente no mundo do código fonte. Quem já não vislumbrou, modificando um programa qualquer, uma obra de arte barroca? Cheia de meandros, voltas, incertezas e becos sem saída. Um labirinto a provocar emoções: fúria, alegria,  raiva, medo, alívio (bom, este só quando o código compila e/ou passa nos testes). Estou divergindo…

E quem programa pode ser entendido como um artesão. Alguém que martela teclas para produzir, vez ou outra, um pouco de arte. E podemos encontrar, procurando bastante, entre estes artesãos, um verdadeiro artista.

Why?

É o caso de Why the Luck Stiff, ou simplesmente _why. Seu trabalho mais conhecido é seu livro: Why’s (poignant) Guide to Ruby. Mesmo que você não programe, mesmo que você não entenda nem mesmo HTML, dê uma olhada.  O livro é excelente. Se parece com algo saído de uma viagem  de LSD, misturado com Alice no País das Maravilhas e lições de Ruby. E existe até uma trilha sonora para acompanhá-la!

Mas, onde encontro este livro? O site do _why saiu do ar. Assim como muitos outros projetos pertencentes a ele. Até a conta no twitter, @_why, sumiu. _why desapareceu. Ninguém sabe ninguém viu.

Where´s why?

É um feito notável para alguém que alcançou certa notoriedade online, e com uma presença forte na internet. Participou de palestras e eventos, mas sempre se identificando por seu pseudônimo.  Ainda existe o anonimato, afinal (há quem diga que _why apenas está dando um tempo e retornará como _because).

Mas dá para apreciar sua obra em alguns mirrors.  E já tratei de guardar a trilha sonora para ouvir enquanto programo. Quem sabe não tenho uma epifania (ou uma síncope, dependendo do código a editar). E tem até tradução para o português, que até onde vi está ótima.

As raposas de _why

So long _why, and thanks for all the chunky bacon.

ArcGIS Javascript, Dojo e o método require

Ando investigando a API Javascript ArcGIS. Esta API é escrita em cima do framework Dojo, que provê um monte de funções úteis, além de um biblioteca bacana de widgets.

Tentando criar um código JS mais organizado, encontrei o método dojo.require, que, em conjunto dos métodos dojo.declare e dojo.provide, devolvem um pouco de sanidade ao programandor.  Ele funciona da seguinte maneira.  Você inventa um namespace/pacote,  e depois associa um caminho à ele:

dojo.registerModulePath( "pacote", "http://localhost/scripts/")

E depois pode incluir ou importar pacotes assim:

dojo.require("pacote.MinhaClasse");

A mágica é que o arquivo http://localhost/scripts/MinhaClasse.js é carregado automaticamente. Legal! Parecido com Java, C# e um monte de outras linguagens. Agora vou criar arquivos correspondentes às classes que criarei, e organizar a macarronada Javascript.

Mas não. A API Javascript ArcGIS, por alguma razão, procura pelo arquivo http://localhost/scripts/MinhaClasse.xd.js !!! De onde saiu este xd? E mesmo criando o arquivo que ele espera, seu conteúdo não é processado da forma correta.

Elaborando alguns testes eu susbtitui a referência:

<script type=”text/javascript” src=”http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.4″></script>

pela:

<script type=”text/javascript” src=”http://dojotoolkit.org/sites/all/modules/dojo/dtk_build/dojo/dojo.js”></script>

E funcionou ok. Parece que a versão do dojo entregue pela ESRI no ArcGIS não permite o uso do dojo.require. Para que isto seja possível, é necessário compilar o dojo de forma a permiti-lo carregar arquivos de domínios distintos, ou cross domain. Mas na API da ESRI não dá. Pena.

Encontrei como resolver o problema:

        djConfig = {
            parseOnLoad: true,
            baseUrl: "./scripts",
            modulePaths: {
                "minhasClasses": "./minhasClasses",
                "meusDijits": "./BLA"
            },
           isDebug: true
        }

Isto me ensina a aprender direito antes de escrever! =)

Odbc DataSource 32bits no Windows 7

Ando efetuando uns testes com o Postgresql e o Virtual Box, ambos excelentes sistemas. No Virtual Box eu criei uma máquina virtual, nele instalando um Ubuntu Server 64 bits com o Postgresql – e configurando o postgresql.conf e pg_hba.conf como sempre.

A partir de outra máquina virtual, rodando o Ubuntu Jaunty Desktop, consigo normalmente acessar o banco de dados no Ubuntu Server, então tudo ok. Ou quase tudo ok.

Para acessar o banco de dados postgresql a partir de meu sistema hospedeiro – ou seria anfitirião? estalajadeiro?, rodando o indefectível ( até o momento) Windows 7 tive de instalar os controladores ODBC (disponíves no ftp do Postgresql) .

Depois de instalar, navego até o Painel de Controle, depois para Fontes de dados Odbc e, CADÊ? Sumiu, ninguém viu. Só aparecem listados os controladores das fontes de dados do SQL Server. Muito estranho.

Mas eu já havia feito isto. Uma busca em minha memória e me lembrei que era um problema de versão do sistema. O controlador, ou driver , que instalei é de 32 bits. O sistema é de 64 bits. E o Windows não gosta de misturar alhos com bugalhos.

Para acessar finalmente o gerenciador de fontes de dados ODBC 32 bits é necessário executar este safado:

C:\Windows\SysWOW64\odbcad32.exe

Agora sim!

Upgrade no PostGIS

Algumas vezes é necessário um upgrade no banco de dados. E chegou a vez do PostgreSQL, para ir da versão 8.2 para a 8.3.  Aproveitando, fiz um upgrade do PostGIS 1.1.6 para a versão 1.4.  Surpreendentemente não ocorreram grandes problemas. Quer dizer, não até eu migrar os dados.

O próprio PostGIS possui um script para migração de dados. Se trata de um script Perl que recebe um dump do PostgreSQL e mais alguns outros parâmetros, trata-os gerando um novo dump e depois finalmente faz o restore do dump no banco de dados.

Problemas

Parecia tudo ok, até eu tentar fazer um backup do novo banco:

ERROR:  geometry contains non closed rings

Será que os dados se corromperam durante a migração?

O PostGIS 1.4 é um pouco mais restritivo quanto aos dados que armazena. Um multipolygon ou polygon, por exemplo, só podem ser inseridos no sistema se estiverem bem formados, o que significa que devem ser polígonos fechados (hmm,  e existe “polígono aberto”?).

O problema é que a versão 1.1.6 é mais, digamos, liberal. Você consegue gravar “polígonos  abertos”, consegue fazer SELECTs e backups em cima deles. Apenas operações  que envolvam as formas geométricas podem dar problema.

E o processo de migração de dados não realiza nenhuma verificação de validade destas entidades.

Assim, os dados migrados para a nova versão continua com “polígonos abertos”,  impossibilitando, na versão 1.4,  até mesmo um simples select sobre os dados da tabela.

A solução foi encontrar os registros com este problema e removê-los da tabela através da seguinte consulta SQL:

DELETE
FROM <nome_da_tabela>
WHERE isvalid(coords) != 't'

E se você possui muitas tabelas com o problema, boa sorte!

Problema rodando testes MbUnit no VS2008 Test Runner

Importei um projeto para trabalhar em meu Visual Studio 2008. Ao tentar rodar os testes, que utilizam o framework MbUnit, fui contemplado com a seguinte mensagem:

No tests were run because no tests are loaded or the selected tests are disabled

O problema é que o projeto de testes é tratado como uma simples biblioteca de classes, embora seus métodos sejam decorados com atributos [Test] e similares.

E como fazer o VS2008 entender que o projeto em questão é de testes? É necessário abrir o arquivo .csproj correspondente ao projeto e incluir o seguinte:

<ProjectTypeGuids>
{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
</ProjectTypeGuids>

Logo antes do primeiro </PropertyGroup> do arquivo. O VS2008 verifica o tipo do projeto em questão através destes identificadores. E como encontrei estes números? Criei um projeto de testes MSTest pelo VS2008 e abri o .csproj.

E encontrei o significado destes guids:

  • {3AC096D0-A1C2-E12C-1390-A8335801FDAB} identifica um Test Project
  • {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} identifica um Windows Forms C# Project