1 # -*- mode: perl; coding: utf-8 -*-
2 # keitairc/lib/plugins/00location_receiver
4 # $Id: 00location_receiver,v 1.13 2008-12-20 12:46:28 morimoto Exp $
5 # $Source: /home/ishikawa/work/keitairc/tmp/keitairc/lib/plugins/00location_receiver,v $
7 # The line number (1 incremented) and filename below must be
9 # line 10 "keitairc/lib/plugins/00location_receiver"
16 sub get_rgeocode_xml {
18 my $s = Net::HTTP->new(Host => 'refits.cgk.affrc.go.jp') || return;
19 $s->write_request(GET => "/tsrv/jp/rgeocode.php?lat=$lat&lon=$lon");
20 $s->read_response_headers();
24 my $n = $s->read_entity_body($buf, 1024);
25 return unless defined $n;
34 my ($degree, $min, $sec, $secc) = ($dms =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
35 $degree + $min/60 + $sec/3600 + $secc/360000;
40 return ($lat + 0.00010696*$lat - 0.000017467*$lat - 0.0046020,
41 $lon + 0.000046047*$lon + 0.000083049*$lon - 0.010041);
46 return ($lat - 0.00010695*$lat + 0.000017464*$lat + 0.0046017,
47 $lon - 0.000046038*$lon - 0.000083043*$lon + 0.010040);
50 # see http://labs.anoncom.net/others/GoogleMap/NoAjaxInterface.html
52 my ($wx, $wy, $format) = @_;
53 my $gwx = sprintf('%0.6f', $wx);
54 my $gwy = sprintf('%0.6f', $wy);
66 sprintf('http://maps.google.com/mapdata?cc=JP&min_priority=1&w=%d&h=%d&latitude_e6=%d&longitude_e6=%d&zm=%d&Point=b&Point.latitude_e6=%d&Point.longitude_e6=%d&Point.iconid=%d&Point=e&image_format=%d',
68 $gwx, $gwy, $zoom, $gwx, $gwy, $iconid, $format{$format});
72 name => 'location_receiver',
74 action_imprementation => sub {
75 my ($request, $name, $session_id, $param_string) = @_;
76 my ($cid) = ($param_string =~ /^(\d+)/);
77 my $uri = $request->uri();;
80 for my $pair (split(/&/, $uri)){
81 my ($k, $v) = split(/=/, $pair);
85 my $ci = new Keitairc::ClientInfo($request);
86 my $view = new Keitairc::View($::cf, $ci);
88 $p->{session_id} = $session_id;
91 $p->{channel_compact} = $::ib->simple_escape(encode($::cf->web_charset(), $::ib->compact_channel_name($cid)));
94 # 以下の2つの測地系の中から使用している測地系を示す。
95 # wgs84 WGS84系: GPS測量で算出される座標系。数回の改定
96 # により現在ではITRF座標系と実用上の差異はなくなってい
98 # tokyo 日本測地系: 測量法施行令第2条で定められた日本標
100 # 備考: 引数内容としては"tokyo"という表示になるが、実際
101 # の測地系はWGS84系のデータを使用。
102 # from http://www.au.kddi.com/ezfactory/tec/spec/eznavi.html
105 if($ci->is_docomo()){
107 # ACTN=OK&LAT=%2B35.44.27.996&LON=%2B139.35.37.932&GEO=wgs84&XACC=1&POSINFO=2
109 my $posted = $request->content();
111 for my $pair (split(/&/, $posted)){
112 my ($k, $v) = split(/=/, $pair);
115 if(defined $posted{LAT}){
116 $posted{LAT} =~ s/^%2b//i;
117 $posted{LON} =~ s/^%2b//i;
118 ($wx, $wy) = (dms_to_degree($posted{LAT}), dms_to_degree($posted{LON}));
121 # GET /loc.jsp?lat=%2B35.40.53.008&lon=%2B139.45.57.971&geo=WGS84&x-acc=3
122 # see http://www.utilz.jp/wiki/Gps
123 unless(defined $h{lat}){
126 return $view->render('location_receiver.html', $p);
128 $h{lat} =~ s/^%2b//i;
129 $h{lon} =~ s/^%2b//i;
130 ($wx, $wy) = (dms_to_degree($h{lat}), dms_to_degree($h{lon}));
133 my ($tx, $ty) = wgs84_to_tokyo($wx, $wy);
134 my $xml_code = get_rgeocode_xml($wx, $wy);
137 $p->{rgeocode_noresponse} = 1;
138 return $view->render('location_receiver.html', $p);
141 my $xml = XMLin($xml_code);
142 if($xml->{status} ne 'true'){
144 $p->{rgeocode_invalid} = 1;
145 return $view->render('location_receiver.html', $p);
151 $p->{map_image_url} = google_map_image($wx, $wy, 'gif');
152 $p->{address} = $xml->{prefecture}->{pname} .
153 $xml->{municipality}->{mname} .
154 $xml->{local}->{section};
155 Encode::_utf8_off($p->{address}) if Encode::is_utf8($p->{address});
156 Encode::from_to($p->{address}, 'utf8', $::cf->web_charset());
157 return $view->render('location_receiver.html', $p);
161 # HTTPヘッダーのx-jphone-geocodeに位置情報が通知されます。
162 # x-jphone-geocode: 354053%1A1394557%1A(住所がSJISでエ
163 # ンコードされたもの) "%1A"(SUB)で区切られて lat, lon,
164 # 住所(SJISでエンコード)の形式になります。住所はドキュ
165 # メントを見る限りSJISでエスケープしたものとなっていま
166 # すが、正しくデコードできない場合がありました。この情
167 # 報は利用しない方が良いのかも知れません。
168 # see http://www.utilz.jp/wiki/Gps
169 if($ci->is_softbank()){
171 if(defined $request->{_headers}->{'x-jphone-geocode'}){
172 ($lat, $lon) = split(/%1A/, $request->{_headers}->{'x-jphone-geocode'});
174 $lat =~ s/^(\d\d)(\d\d)(\d\d)/$1.$2.$3.00/;
175 $lon =~ s/^(\d\d\d)(\d\d)(\d\d)/$1.$2.$3.00/;
177 # GET /loc.jsp?pos=N35.40.53.00E139.45.57.97&geo=wgs84&x-acr=1
178 ($lat, $lon) = ($h{pos} =~ /^N([\d.]+)E([\d.]+)$/);
180 my ($wx, $wy) = (dms_to_degree($lat), dms_to_degree($lon));
181 my ($tx, $ty) = wgs84_to_tokyo($wx, $wy);
182 my $xml_code = get_rgeocode_xml($wx, $wy);
185 $p->{rgeocode_noresponse} = 1;
186 return $view->render('location_receiver.html', $p);
189 my $xml = XMLin($xml_code);
190 if($xml->{status} ne 'true'){
192 $p->{rgeocode_invalid} = 1;
193 return $view->render('location_receiver.html', $p);
199 $p->{map_image_url} = google_map_image($wx, $wy, 'png');
200 $p->{address} = $xml->{prefecture}->{pname} .
201 $xml->{municipality}->{mname} .
202 $xml->{local}->{section};
203 Encode::_utf8_off($p->{address}) if Encode::is_utf8($p->{address});
204 Encode::from_to($p->{address}, 'utf8', $::cf->web_charset());
205 return $view->render('location_receiver.html', $p);
208 # see KDDI au: 技術情報 > 簡易位置情報
209 # http://www.au.kddi.com/ezfactory/tec/spec/eznavi.html
211 # au W53S location の戻り例
212 # 3/?datum=tokyo&unit=dms&lat=35.44.51.75&lon=139.35.15.0
213 # au W53S gpsone の戻り例
214 # /?ver=1&datum=0&unit=0&lat=%2b35.44.29.09&lon=%2b139.35.38.97&alt=71&time=20080114183222&smaj=116&smin=96&vert=46&majaa=24&fm=2
215 $h{lat} =~ s/^%2b//i; # au GPSOneの場合
216 $h{lon} =~ s/^%2b//i; # au GPSOneの場合
217 my ($wx, $wy) = (dms_to_degree($h{lat}), dms_to_degree($h{lon}));
218 my ($tx, $ty) = wgs84_to_tokyo($wx, $wy);
219 my $xml_code = get_rgeocode_xml($wx, $wy);
222 $p->{rgeocode_noresponse} = 1;
223 return $view->render('location_receiver.html', $p);
226 my $xml = XMLin($xml_code);
227 if($xml->{status} ne 'true'){
229 $p->{rgeocode_invalid} = 1;
230 return $view->render('location_receiver.html', $p);
236 $p->{map_image_url} = google_map_image($wx, $wy, 'png');
237 $p->{address} = $xml->{prefecture}->{pname} .
238 $xml->{municipality}->{mname} .
239 $xml->{local}->{section};
240 Encode::_utf8_off($p->{address}) if Encode::is_utf8($p->{address});
241 Encode::from_to($p->{address}, 'utf8', $::cf->web_charset());
242 return $view->render('location_receiver.html', $p);
245 # http://developer.emnet.ne.jp/browser3-1.html
247 # http://www.emobilemap.net/positioning.cgi?ver=MOPA-001-2001&pos=N35.44.33.156E135.22.33.124&geo=wgs84&x-acy=1
248 if($ci->is_emobile()){
249 unless(defined $h{pos}) {
252 return $view->render('location_receiver.html', $p);
256 if($h{pos} =~ /N([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)E([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/){
257 ($wx, $wy) = ($1, $2);
260 ($wx, $wy) = (dms_to_degree($wx), dms_to_degree($wy));
261 my ($tx, $ty) = wgs84_to_tokyo($wx, $wy);
262 my $xml_code = get_rgeocode_xml($wx, $wy);
265 $p->{rgeocode_noresponse} = 1;
266 return $view->render('location_receiver.html', $p);
269 my $xml = XMLin($xml_code);
270 if($xml->{status} ne 'true'){
272 $p->{rgeocode_invalid} = 1;
273 return $view->render('location_receiver.html', $p);
279 $p->{map_image_url} = google_map_image($wx, $wy, 'gif');
280 $p->{address} = $xml->{prefecture}->{pname} .
281 $xml->{municipality}->{mname} .
282 $xml->{local}->{section};
283 Encode::_utf8_off($p->{address}) if Encode::is_utf8($p->{address});
284 Encode::from_to($p->{address}, 'utf8', $::cf->web_charset());
285 return $view->render('location_receiver.html', $p);
288 return $view->render('location_receiver.html', $p);