domingo, 31 de março de 2013

Criando elementos HTML com jQuery

Olá galera,

Outro dia precisei criar um elemento HTML dinamicamente usando jQuery. Como fazer isso?! Basta colocá-lo como objeto jQuery.

    var div = $("<div />");

    $("body").append(div);
  

Agora digamos que você quer criar o elemento já com os atributos.

    var div = $("<div />");

    div.attr({
      id: 'minha_div',
      title: 'estilo'
    });

    $("body").append(div);
  

Esse é o jeito mais tradicional. Vamos ver uma forma mais simplificada.

    var div = $("<div />", {
      id: 'minha_div',
      title: 'estilo'
    });

    $("body").append(div);
  

Mais elegante concorda?! Um dica básica porém muito útil em alguns projetos.

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

sábado, 30 de março de 2013

Padrão de nomenclatura para banco de dados

Olá galera,

Há algum tempo venho adotando um padrão de nomenclatura para tabelas e campos do banco de dados. Esse padrão é utilizado por muitos frameworks como: Ruby on Rails, Laravel, Yii Framework, CakePHP, entre outros.

Se você já usou algum desses frameworks ou pretende usar, vai notar que seguindo essa convenção terá que configurar e codificar menos.

Criei um exemplo de uma modelagem bem simples para demonstrar o padrão.

  1. Nome das tabelas no plural.
  2. Tabela em um relacionamento N:M - O nome das duas tabelas envolvidas no plural, em ordem alfabética e separado por "_"
  3. Chave estrangeira - Nome da tabela no singular com "_id".
  4. Chave primária - Somente "id"

Sintam-se a vontade para adotar ou não esse padrão. Resolvi segui-lo pois a maioria dos frameworks que trabalho usa ele.

Grande abraço a todos e até a próxima.

segunda-feira, 18 de março de 2013

Criando um cluster com Openlayers

Olá galera,

A idéia desse post é criarmos um exemplo de cluster com Openlayers utilizando um GeoJSON. Utilizaremos um GeoJSON com as sedes dos municípios brasileiros por ser uma massa de dados com muitos pontos.

O primeiro passo é criar a estrutura do nosso projeto como abaixo.

Antes de começarmos a escrever código, faça o download do Openlayers. Atualmente, a última versão estável e a que vamos usar no nosso exemplo é a 2.12.

Após descompactar o arquivo baixado, copie o arquivo Openlayers.js que se encontra na raiz para a pasta js. Em seguida copie o arquivo style.css dentro de theme/default para a pasta css.

Faça o download do GeoJSON e salve na pasta js do nosso projeto. Além dele, baixe as imagens que vamos utilizar e salve na pasta img do nosso projeto.

O arquivo index.html deve conter o código abaixo.

    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <title>CodeGeo - Desenvolvimento é diversão</title>
        <link rel="stylesheet" type="text/css" href="css/cluster.css" />
        <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript" src="js/OpenLayers.js" defer></script>
        <script type="text/javascript" src="js/cluster.js" defer></script>
      </head>
      <body>
        <div id="map"></div>
      </body>
    </html>
  

Obs:. Explicarei somente sobre algumas linhas de código do nosso projeto já que as demais são bem comuns para quem desenvolve para web. Ainda assim, caso alguma parte do código não fique clara, terei a maior satisfação em responder sua dúvida.

Na linha 9, carregando a api do Google Maps já que utilizaremos uma camada do Google.

Nas linhas 10 e 11, note que estou usando defer. Este atributo indica que o bloco de script só será carregado após todo o carregamento da página.

Crie o arquivo cluster.css dentro da pasta css do nosso projeto e adicione o código abaixo.

  * {
    margin: 0;
    padding: 0;
  }
  body {
    font: normal 11px arial, sans-serif;
    text-align: justify;
  }
  #map {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
  }
  

Na linha 1, limpando as margens e espaçamentos de todos os elementos.

Na linha 9, setando o nosso mapa para ocupar 100% da páginal.

Para os que estão acompanhando o blog, devem ter notado que os códigos e análises acima são idênticos aos dos últimos posts. A parte que se vai diferenciar é exatamente o código que vem a seguir.

Crie o arquivo cluster.js dentro da pasta js do nosso projeto e adicione o código abaixo.

OpenLayers.ImgPath='img/';

var map = new OpenLayers.Map({
  controls: [
    new OpenLayers.Control.Navigation(),
    new OpenLayers.Control.Zoom(),
    new OpenLayers.Control.MousePosition(),
    new OpenLayers.Control.ScaleLine(),
    new OpenLayers.Control.LayerSwitcher()
  ],
  div: "map",
  projection: "EPSG:4326",
  layers: [
    new OpenLayers.Layer.OSM(null, null, {isBaseLayer: true}),
    new OpenLayers.Layer.Google("Google Streets")
  ],
  theme: 'css/style.css'
});

var renderCluster = function(feature, tipo) {
  var qtd = feature.attributes.count;
  if (qtd > 200) {
    return (tipo == 'img') ? 'img/m3.png' : 64;
  } else if (qtd > 20) {
    return (tipo == 'img') ? 'img/m2.png' : 48;
  } else {
    return (tipo == 'img') ? 'img/m1.png' : 32;
  }
}

var pontoStyle = new OpenLayers.StyleMap({
  'default': new OpenLayers.Style({
    externalGraphic: "${iconImg}",
    graphicWidth: "${iconSize}",
    graphicHeight: "${iconSize}",
    label: "${getName}",
    fontSize: "9px",
    fontFamily: "Trebuchet MS, sans-serif",
    labelAlign: "cm"
  },{
    context: {
      iconImg: function (feature) {
        return renderCluster (feature, 'img');
      },
      iconSize: function (feature) {
        return renderCluster (feature, 'size');
      },
      getName: function (feature) {
        return feature.attributes.count;
      }
    }
  })
});

var points = new OpenLayers.Layer.Vector('Cluster', {
  strategies: [
    new OpenLayers.Strategy.Fixed(),
    new OpenLayers.Strategy.Cluster(),
    new OpenLayers.Strategy.BBOX()
  ],
  visibility: false,
  protocol: new OpenLayers.Protocol.HTTP({
    url: "js/sedes.json",
    format: new OpenLayers.Format.GeoJSON()
  }),
  styleMap: pontoStyle
});

map.addLayer(points);

map.setCenter(
  new OpenLayers.LonLat(-5112108.4510014, -1854056.5578272), 4
);

Na linha 1, alterando a pasta padrão de imagens do Openlayers.

Na linha 3, instanciando nosso mapa.

Na linha 4, adicionando alguns controles como zoom, posição do mouse, escala, navegação e layerswitcher.

Na linha 11, o id da div onde carregaremos o mapa.

Na linha 12, a projeção que estamos utilizando.

Na linha 13, as camadas que usaremos como base layer, no caso Google Maps e OpenStreetMap.

Na linha 17, alterando o caminho e qual o arquivo css padrão do Openlayers.

Na linha 20, criei uma função que vai retornar as imagens e os tamanhos de cada uma delas de acordo com quantidade de pontos.

Na linha 31, instanciando o estilo que vai ser usado nos pontos.

Na linha 55, instanciando uma camada do tipo vector tendo como a fonte de dados o GeoJSON e setando o estilo que criamos na linha 31.

Na linha 69, adicionando a camada ao mapa.

Na linha 71, setando o enquadramento inicial no Brasil.

Como resultado devemos ter um mapa como o abaixo:

O arquivo final pode ser baixado clicando aqui.

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

domingo, 17 de março de 2013

Criando e exibindo um WMS com MapServer, PostGIS e Openlayers - Parte 2

Olá galera,

Dando continuidade ao nosso último post, iremos dar carga no banco de dados e criar o mapfile que será chamado pelo Openlayers.

Primeiro baixe o arquivo de estados em formato SQL. Caso você queira usar seu próprio shapefile, pode transformá-lo usando um comando que eu citei no post Alguns comandos úteis para PostgreSQL.

Caso você ainda não tenha instalado o PostgreSQL com PostGIS, recomendo olhar o post Instalando e configurando o PostgreSQL, PostGIS e pgAdmin no Ubuntu 12.04 antes de prosseguir.

Para gerar o banco e dar carga, usei o pgAdmin mas sinta-se a vontade para utilizar inclusive o terminal. É importante utilizar o template do PostGIS ao gerar o banco.

Agora que o banco de dados está pronto, cria na pasta raiz do projeto o arquivo fonts.list e insira o código abaixo:

    ubuntu /usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf
  

Esse arquivo indica o caminho e nome da font que vamos utilizar no label do mapfile.

Ainda na pasta raiz do projeto, crie o arquivo codegeo.map e insira o código abaixo:

#
# Mapfile - CodeGeo
#

MAP
  NAME 'codegeo_wms'
  IMAGETYPE PNG
  EXTENT -73.9913940429688 -33.7520141601562 -32.3924560546875 5.27179002761841
  UNITS meters
  SIZE 800 600
  FONTSET '/var/www/codegeo/fonts.list'

#
# Definição da projeção do mapa
#
 
  PROJECTION
    "init=epsg:4326"
  END
 
#
# Formato de imagem que utiliza a biblioteca GD
#
 
  OUTPUTFORMAT
    NAME "aggpng"
    DRIVER "AGG/PNG"
    MIMETYPE "image/png"
    IMAGEMODE RGBA
    EXTENSION "png"
  END

#
# Definição WEB
#
 
  WEB
    TEMPLATE void
    IMAGEPATH "/var/www/codegeo"
    IMAGEURL "http://localhost/codegeo"
    METADATA
      "wms_title" "WMS PNG CodeGeo"
      "wms_onlineresource" "http://localhost/cgi-bin/mapserv?map=/var/www/codegeo/codegeo.map"
      "wms_srs" "EPSG:4326 EPSG:900913"
      "wms_abstract" "Serviço WMS PNG CodeGeo."
      "ows_enable_request" "*"
      "wms_feature_info_mime_type" "text/html"
    END
  END

#
# Camada de Estados do Brasil
#
  
  LAYER
    NAME 'estados'
    CONNECTIONTYPE postgis
    CONNECTION "user=postgres password=1234 dbname=codegeo host=localhost"
    DATA "the_geom FROM estados USING UNIQUE id USING SRID=4326"
    TYPE POLYGON
    STATUS default
    TRANSPARENCY 65
    LABELITEM 'nome'
    LABELCACHE ON

    CLASS
      NAME 'bahia'
      EXPRESSION ([codigo] eq 29)
      LABEL
        COLOR 0 0 0
        FONT ubuntu
        TYPE TRUETYPE
        POSITION CC
        PARTIALS FALSE
        SIZE 9
        BUFFER 5
        OUTLINECOLOR 255 255 255
      END
      STYLE
        OUTLINECOLOR 0 0 0
        COLOR 187 117 0
      END
    END

    CLASS
      NAME 'padrao'
      LABEL
        COLOR 0 0 0
        FONT ubuntu
        TYPE TRUETYPE
        POSITION CC
        PARTIALS FALSE
        SIZE 9
        BUFFER 5
        OUTLINECOLOR 255 255 255
      END
      STYLE
        OUTLINECOLOR 0 0 0
        COLOR 155 137 123
      END
    END
  END
 
END

De um forma geral, o mapfile criado vai exibir todos os Estados do Brasil com seus respectivos nomes e com a Bahia em destaque.

Farei um comentário das linhas que possuem uma relevância.

Linha 11 - Caso pretenda utilizar um outra fonte ou esteja usando um sistema operacional diferente, certifique-se de setar o caminho correto para a fonte do seu sistema.

Linha 58 - Certifique-se de fazer as alterações para as configurações da sua máquina.

Linha 63 - Esse é o campo da tabela utilizado para exibir qual o conteúdo estará no label do mapa.

Linha 68 - Nesse trecho, o campo da tabela codigo é igualado ao valor do código da Bahia no banco de dados.

Para finalizar, antes da linha que contém o código map.setCenter( no arquivo project.js, insira o trecho abaixo:

    var estados = new OpenLayers.Layer.WMS("Estados",
      "http://localhost/cgi-bin/mapserv?map=/var/www/codegeo/codegeo.map",
      {
        layers: "estados",  
        transparent: true
      },
      {
        isBaseLayer: false,
        visibility: false,
        singleTile: false
      }
    );

    map.addLayers([estados]);
  

No trecho acima, seto o caminho onde nosso mapfile está e qual layer vamos exibir.

O resultado final deve se parecer com a imagem abaixo:

A versão final do nosso aplicativo pode ser baixado clicando aqui.

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

domingo, 10 de março de 2013

Criando e exibindo um WMS com MapServer, PostGIS e Openlayers - Parte 1

Olá galera,

Conforme prometido, iremos criar um serviço WMS utilizando MapServer e PostGIS. Para visualizar nosso mapa, usaremos o Openlayers.

No post de hoje, vamos criar a estrutura inicial com alguns controles para exibir o nosso mapa. Abaixo segue a estrutura de pastas do nosso projeto.

Antes de começarmos a escrever código, faça o download do Openlayers. Atualmente, a última versão estável e a que vamos usar no nosso exemplo é a 2.12.

Após descompactar o arquivo baixado, copie o arquivo Openlayers.js que se encontra na raiz para a pasta js. Em seguida copie o arquivo style.css dentro de theme/default para a pasta css.

Faça, também, o download do arquivo e descompacte na pasta img do nosso projeto.

O arquivo index.html deve conter o código abaixo.

    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <title>CodeGeo - Desenvolvimento é diversão</title>
        <link rel="stylesheet" type="text/css" href="css/project.css" />
        <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript" src="js/OpenLayers.js" defer></script>
        <script type="text/javascript" src="js/project.js" defer></script>
      </head>
      <body>
        <div id="map"></div>
      </body>
    </html>
  

Obs:. Explicarei somente sobre algumas linhas de código do nosso projeto já que as demais são bem comuns para quem desenvolve para web. Ainda assim, caso alguma parte do código não fique clara, terei a maior satisfação em responder sua dúvida.

Na linha 9, carregando a api do Google Maps já que utilizaremos uma camada do Google.

Nas linhas 10 e 11, note que estou usando defer. Este atributo indica que o bloco de script só será carregado após todo o carregamento da página.

Crie o arquivo project.css dentro da pasta css do nosso projeto e adicione o código abaixo.

  * {
    margin: 0;
    padding: 0;
  }
  body {
    font: normal 11px arial, sans-serif;
    text-align: justify;
  }
  #map {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
  }
  

Na linha 1, limpando as margens e espaçamentos de todos os elementos.

Na linha 9, setando o nosso mapa para ocupar 100% da páginal.

Crie o arquivo project.js dentro da pasta js do nosso projeto e adicione o código abaixo.

   OpenLayers.ImgPath='img/';

   var map = new OpenLayers.Map({
    controls: [
        new OpenLayers.Control.Navigation(),
        new OpenLayers.Control.Zoom(),
        new OpenLayers.Control.MousePosition(),
        new OpenLayers.Control.ScaleLine(),
        new OpenLayers.Control.LayerSwitcher()
    ],
    div: "map",
    projection: "EPSG:900913",
    layers: [
        new OpenLayers.Layer.OSM(null, null, {isBaseLayer: true}),
        new OpenLayers.Layer.Google("Google Streets")
    ],
    theme: 'css/style.css'
   });

   map.setCenter(
      new OpenLayers.LonLat(-5112108.4510014, -1854056.5578272), 4
   );
  

Na linha 1, alterando a pasta padrão de imagens do Openlayers.

Na linha 3, instanciando nosso mapa.

Na linha 4, adicionando alguns controles como zoom, posição do mouse, escala, navegação e layerswitcher.

Na linha 11, o id da div onde carregaremos o mapa.

Na linha 12, a projeção que estamos utilizando.

Na linha 13, as camadas que usaremos como base layer, no caso Google Maps e OpenStreetMap.

Na linha 17, alterando o caminho e qual o arquivo css padrão do Openlayers.

Na linha 20, setando o enquadramento inicial no Brasil.

Como resultado devemos ter um mapa como o abaixo:

No próximo post, vamos dar carga no banco de dados e criar um mapfile com o serviço WMS. Um abraço e até a próxima.

sexta-feira, 1 de março de 2013

Utilizando .htaccess para hospedar uma aplicação Laravel em produção

Olá galera,

Há alguns dias precisei hospedar uma aplicação feita em Laravel em um servidor externo. O problema é que não tinha acesso para criar um Virtual Host que apontaria para o diretório onde está o arquivo index.php. No caso do Laravel, o diretório que contém esse arquivo é o public.

Aí me veio a idéia de utilizar o .htaccess que é um arquivo que permite subescrever configurações de escopo global.

Mãos à obra?! No diretório raiz da aplicação do servidor externo, que normalmente é "public_html" ou "www", crie um arquivo .htaccess com o seguinte conteúdo:

    <IfModule mod_rewrite.c>
      RewriteEngine on
      RewriteCond %{REQUEST_URI} !^public
      RewriteRule ^(.*)$ public/$1 [L]
    </IfModule>
  

Agora quando sua aplicação for acessada, ocorrerá o direcionamento automático para a pasta public. É algo bem simples porém muito útil.

No próximo post vou falar sobre Openlayers e MapServer. Grande abraço e até a próxima.