[SP-pm] Mapas

Hernan Lopes hernanlopes at gmail.com
Sat Aug 31 17:04:35 PDT 2013


Blabos,

Preparei o código abaixo para exemplificar, ele faz o seguinte, dado uma
lista de lojas, e uma lista de usuarios magic com CEP, a app abaixo vai:
1. calcular as coordenadas para o CEP e associar ao usuario
2. Calcular a distancia de cada loja para esse usuario
3. Vai executar um sort e associar a distancia de lojas para cada usuario
4. Vai imprimir um markup (HTML) para vc colar no teu browser com o exemplo
de plotagem dos dados que estao contidos na app.

é só copiar e colar o código abaixo e rodar com:
$ perl programinha.pl > lojas.htm
$ firefox lojas.htm

e veja vc mesmo =)
espero que eu não tenha feito o trablho por vc, caso isso aconteca não
esquece das minhas congratulacoes rsrs

abs,

Hernan

Segue a app:



package
Ajudando::O::Blabos::Em::Magic::Addicts::Encontre::A::Loja::Mais::Proxima;

=head2 SYNOPSIS

execute este o código a seguir e salve a saída num arquivo HTML e abra no
firefox.

ex: $ perl este_programa.pl > lojas_mais_proximas.htm
    $ lojas_mais_proximas.htm

=cut

=head2 DESCRIPTION

Objetivo: Ajudar o Blabos

Como: Com um programa que seja útil para pessoas que jogam Magic,
encontrando a loja mais próxima com um baralho fechado de mááágic

Premissas:

- Tenho uma lista com as lojas.

- Tenho uma lista de pessoas que jogam magic e seus CEPs respectivos.

=cut

=head2 AUTOR

Hernan Lopes

=cut

use strict;
use warnings;
use Geo::Coder::Google;
use Data::Printer;
use GIS::Distance;

my $lojas = {
    loja1 => {
        lat => -23.6196,
        lon => -46.6627
    },
    loja2 => {
        lat => -23.668,
        lon => -46.783
    },
    loja3 => {
        lat => -23.616,
        lon => -46.477
    },
    loja4 => {
        lat => -23.519,
        lon => -46.704
    }
};


my $magic_addicts = {
    joe => {
        cep => "04363-000"
    },
    mary => {
        cep => "04362-000"
    },
    gus   => {
        cep => "05443-060"
    },
    gus   => {
        cep => "04106-011"
    },
    pri   => {
        cep => "05423-030"
    },
    tabata => {
        cep => "09710-000"
    }
};

my $geocoder = Geo::Coder::Google->new(apiver => 3);
my $gis      = GIS::Distance->new();
   $gis->formula( 'Haversine' );

foreach my $user ( keys $magic_addicts ) {
    $magic_addicts->{ $user }->{ location } = $geocoder->geocode( location
=> "Brasil, cep ". $magic_addicts->{ $user }->{ cep } )->{geometry}->{
location };
    $magic_addicts->{ $user }->{ lojas_mais_proximas } = [];
    foreach my $loja ( keys $lojas ) {
        my @origem    = ( $magic_addicts->{ $user }->{ location }->{ lat }
,
                          $magic_addicts->{ $user }->{ location }->{ lng }
);

        my @destino   = ( $lojas->{ $loja }->{ lat },
                          $lojas->{ $loja }->{ lon } );
        my $distancia = $gis->distance( @origem => @destino );
        push( @{   $magic_addicts->{ $user }->{ lojas_mais_proximas }   },
          {
              loja      => $loja,
              distancia => $distancia->{ values }->{ kilometre }
          }
        );
    }
    my @sorted =
                      sort{ $a->{distancia} <=> $b->{distancia} }
                      @{ $magic_addicts->{ $user }->{ lojas_mais_proximas }
};
    $magic_addicts->{ $user }->{ lojas_mais_proximas } = \@sorted;

}



print <<HTML;

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Simple markers</title>
    <link href="/maps/documentation/javascript/examples/default.css"
rel="stylesheet">
    <script src="
https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
    <script>
function initialize() {
  var myLatlng = new google.maps.LatLng( $lojas->{ loja1 }->{ lat },
$lojas->{ loja1 }->{ lon } );
  var mapOptions = {
    zoom: 11,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
HTML

foreach my $loja ( keys $lojas ) {
print <<HTML;
  new google.maps.Marker({
      position: new google.maps.LatLng( $lojas->{ $loja }->{ lat },
$lojas->{ $loja }->{ lon } ),
      map: map,
      title: '$loja',
      icon: 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png'
  });
HTML
}

foreach my $user ( keys $magic_addicts ) {
print <<HTML;
  new google.maps.Marker({
      position: new google.maps.LatLng( $magic_addicts->{ $user }->{
location }->{ lat }, $magic_addicts->{ $user }->{ location }->{ lng } ),
      map: map,
      title: '$user',
      icon: 'http://maps.google.com/mapfiles/ms/icons/red-dot.png'
  });
HTML
}

print <<HTML;

}

google.maps.event.addDomListener(window, 'load', initialize);

    </script>
  </head>
  <body>
    <div id="map-canvas" style="width: 400px; height: 400px;"></div>

    <pre>
Dentro do objeto \$magic_addicts estão as distancias calculadas e ordenadas
HTML

print p $magic_addicts;

print <<HTML;
    </pre>

  </body>
</html>


HTML





2013/8/31 Hernan Lopes <hernanlopes at gmail.com>

> Quanto ao CEP, é simples tambem, vc precisa fazer o seguinte para
> descobrir as coordenadas relacionadas a um cep... o myagawa implementou um
> módulo que facilita esse tipo de busca:
>
> abs,
>
> Hernan
>
> # Imprime coordenadas relacionadas a um CEP
> use Geo::Coder::Google;
> use Data::Printer;
> my $cep      = "04363-040" ,
>    $geocoder = Geo::Coder::Google->new(apiver => 3),
>    $location = $geocoder->geocode( location => "Brasil, cep $cep" );
> print "A latutide e longitude para o $cep é: \n";
> print "Latitude: ", $location->{ geometry }->{ location }->{ lat }, "\n";
> print "Longitude: ", $location->{ geometry }->{ location }->{ lng }, "\n";
>
>
>
>
>
>
>
> 2013/8/31 Hernan Lopes <hernanlopes at gmail.com>
>
>> Ahh, e vc pode implementar em qq linguagem, é bem simples, segue
>> implementacao em JS pra vc colar no seu firebug:
>>
>> abs,
>>
>> Hernan
>>
>> var to_radian = function( val ) {
>>
>>     return val * Math.PI / 180;
>> }
>>
>> var cidade = {
>>     new_york : {
>>         lat : 40.697169,
>>         lon : -74.052658
>>     },
>>     sao_paulo : {
>>         lat : -23.548943,
>>         lon : -46.638818
>>
>>
>>     }
>> };
>>
>> var partida = cidade[ "new_york" ];
>> var destino = cidade[ "sao_paulo" ];
>>
>> var raio_da_terra = 6371; // http://pt.wikipedia.org/wiki/Raio_da_Terra
>>
>>
>> var dLat = to_radian(destino["lat"]-partida["lat"]);
>> var dLon = to_radian(destino["lon"]-partida["lon"]);
>> var lat1 = to_radian(partida["lat"]);
>> var lat2 = to_radian(destino["lat"]);
>>
>>
>> var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
>>         Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
>> var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
>> var d = raio_da_terra * c;
>>
>> console.log( "A distância entre Nova York e São Paulo é: " + d + " km ");
>>
>>
>>
>>
>> 2013/8/31 Hernan Lopes <hernanlopes at gmail.com>
>>
>>> Segue um exemplo prático da fórmula de haversine... essa fórmula calcula
>>> a distância entre duas coordenadas com latitude e longitude.
>>>
>>> O exemplo abaixo demonstra o cálculo da distância entre são paulo e nova
>>> york:
>>> Se fizer o mesmo procedimento no google maps, vai ver que o valor é
>>> igual.
>>>
>>> abs,
>>>
>>> Hernan
>>>
>>> use strict;
>>> use warnings;
>>> use GIS::Distance;
>>> use Data::Printer;
>>>
>>> my $gis             = GIS::Distance->new();
>>>    $gis->formula( 'Haversine' );
>>>
>>> my $cidade = {
>>>     new_york => {
>>>         lat => 40.697169,
>>>         lon => -74.052658
>>>     } ,
>>>     sao_paulo => {
>>>         lat => -23.548943 ,
>>>         lon => -46.638818
>>>     }
>>> } ;
>>> my @partida         = ( $cidade->{ new_york }->{ lat }, $cidade->{
>>> new_york }->{ lon } );
>>> my @destino         = ( $cidade->{ sao_paulo }->{ lat }, $cidade->{
>>> sao_paulo }->{ lon } );
>>> my $distance        = $gis->distance( @partida => @destino );
>>> warn "A distância entre Nova york e São Paulo é: " , $distance->{ values
>>> }->{ $distance->{unit} } , " ",  $distance->{unit};
>>>
>>>
>>>
>>>
>>>
>>> 2013/8/31 Hernan Lopes <hernanlopes at gmail.com>
>>>
>>>> De qualquer maneira, dadas duas coordenadas, a fórmula da distância de
>>>> haversine vai te dar a resposta.
>>>>
>>>> É só vc usar este módulo com a opcão "Haversine" e as coordenadas,
>>>> conforme: https://metacpan.org/module/GIS::Distance
>>>>
>>>>
>>>>
>>>>
>>>> 2013/8/31 Blabos de Blebe <blabos at gmail.com>
>>>>
>>>>> Obrigado Stan, vou dar uma olhada.
>>>>>
>>>>> Desculpe se a pergunta é idiota, mas tem binding disso em Perl?
>>>>>
>>>>>
>>>>> 2013/8/31 Stanislaw Pusep <creaktive at gmail.com>
>>>>>
>>>>>> Tem API do Google para isso, o Distance Matrix:
>>>>>>
>>>>>>     var service = new google.maps.DistanceMatrixService();
>>>>>>     service.getDistanceMatrix({
>>>>>>         origins: players,
>>>>>>         destinations: players,
>>>>>>         travelMode: google.maps.TravelMode.WALKING,
>>>>>>     }, function (response, status) {
>>>>>>         if (status == google.maps.DistanceMatrixStatus.OK) {
>>>>>>             var origins = response.originAddresses;
>>>>>>             var destinations = response.destinationAddresses;
>>>>>>             ...
>>>>>>         }
>>>>>>     });
>>>>>>
>>>>>>
>>>>>>
>>>>>> 2013/8/31 Blabos de Blebe <blabos at gmail.com>
>>>>>>
>>>>>>> Fala pessoal,
>>>>>>>
>>>>>>> Eu estou fazendo mais um trabalho final na faculdade ( é, eu sei, é
>>>>>>> o segundo, longa história... ) e vou precisar integrar com uma api de mapas.
>>>>>>>
>>>>>>> O trabalho é um site pra ajudar jogadores de magic, e uma das ajudas
>>>>>>> é encontrar a loja mais próxima.
>>>>>>>
>>>>>>> Eu nunca mexi com mapas antes então gostaria que vocês me apontassem
>>>>>>> documentação, módulos, dicas etc.
>>>>>>>
>>>>>>> Basicamente o que eu preciso é plotar lojas no mapa e calcular
>>>>>>> distâncias entre elas e entre os jogadores, da mesma forma que o locator da
>>>>>>> wizards faz:
>>>>>>>
>>>>>>>
>>>>>>> http://locator.wizards.com/#brand=magic&a=search&p=20550-060&c=-23.7246761476923,-46.57210253923074&massmarket=no
>>>>>>>
>>>>>>> Parto do pressuposto que eu sei pelo menos o CEP de todo mundo.
>>>>>>>
>>>>>>> Qualquer ajuda é bem vinda.
>>>>>>>
>>>>>>> []'s
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> =begin disclaimer
>>>>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>>>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>>> =end disclaimer
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> =begin disclaimer
>>>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>>> =end disclaimer
>>>>>>
>>>>>>
>>>>>
>>>>> =begin disclaimer
>>>>>    Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
>>>>>  SaoPaulo-pm mailing list: SaoPaulo-pm at pm.org
>>>>>  L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
>>>>> =end disclaimer
>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20130831/b15c2770/attachment-0001.html>


More information about the SaoPaulo-pm mailing list