webサービスを使用せずにポイントのタイムゾーン(緯度/経度)を決定する可能性はありますか? Geonames.orgは私が使用するには十分に安定していません:(PHPで動作させるにはこれが必要です。
ありがとう
結果はどの程度正確でなければなりませんか?概算で十分な場合は、オフセットを自分で計算します。
offset = direction * longitude * 24 / 360
ここで、方向は東の場合は1、西の場合は-1、経度は(-180,180)です
別のプロジェクトに取り組んでいるときにこの問題に遭遇し、非常に深く調べました。私は、既存のソリューションのすべてが主要な点で欠けていることを発見しました。
GeoNamesデータをダウンロードし、空間インデックスを使用して最も近いポイントを検索することは間違いなくオプションであり、多くの場合正しい結果が得られますが、クエリポイントが時間の反対側にある場合は簡単に失敗する可能性がありますデータベースの最も近い点からのゾーン境界。
より正確な方法は、タイムゾーンのデジタルマップを使用し、特定のクエリポイントを含むマップ内のポリゴンを検索するコードを記述することです。ありがたいことに、 http://efele.net/maps/tz/world/ (メンテナンスされていません anymore )で利用可能な世界のタイムゾーンの優れたマップがあります。効率的なクエリエンジンを作成するには、次のことが必要です。
これらはそれぞれ、独自のStack Overflowの質問/回答ページに値します。
そこにある既存のソリューションはどれも私のニーズを満たしていないと結論付けた後、私は独自のソリューションを作成し、ここで利用可能にしました
AskGeoはデジタルマップを使用し、高度に最適化された空間インデックスを使用して、1つのスレッドでコンピューター上で毎秒10,000を超えるクエリを実行できます。また、スレッドセーフなので、さらに高いスループットが可能です。これは深刻なコードであり、開発に長い時間がかかったため、商用ライセンスで提供しています。
これはJavaで記述されているため、PHPで使用するには、以下を使用する必要があります。
http://php-Java-bridge.sourceforge.net/doc/how_it_works.php
また、賞金のために移植することもできます。価格の詳細および詳細なドキュメントについては、 http://askgeo.com を参照してください。
これが役に立つことを願っています。確かに、私が取り組んでいたプロジェクトに役立ちました。
私はこれが古いことを知っていますが、私はこの答えを探すのに時間を費やしました。非常に便利なものが見つかりました。 Googleは、ロング/ラテによるタイムゾーンルックアップを行います。 無料利用枠はなくなりました :-/
陸上のエリアには、tz(Olson)データベースのタイムゾーン用に作成されたいくつかの shapefileマップ があります。それらはtzデータベース自体ほど定期的に更新されませんが、それは素晴らしい出発点であり、ほとんどの目的で非常に正確であるようです。
これはどう ?
// ben@jp
function get_nearest_timezone($cur_lat, $cur_long, $country_code = '') {
$timezone_ids = ($country_code) ? DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $country_code)
: DateTimeZone::listIdentifiers();
if($timezone_ids && is_array($timezone_ids) && isset($timezone_ids[0])) {
$time_zone = '';
$tz_distance = 0;
//only one identifier?
if (count($timezone_ids) == 1) {
$time_zone = $timezone_ids[0];
} else {
foreach($timezone_ids as $timezone_id) {
$timezone = new DateTimeZone($timezone_id);
$location = $timezone->getLocation();
$tz_lat = $location['latitude'];
$tz_long = $location['longitude'];
$theta = $cur_long - $tz_long;
$distance = (sin(deg2rad($cur_lat)) * sin(deg2rad($tz_lat)))
+ (cos(deg2rad($cur_lat)) * cos(deg2rad($tz_lat)) * cos(deg2rad($theta)));
$distance = acos($distance);
$distance = abs(rad2deg($distance));
// echo '<br />'.$timezone_id.' '.$distance;
if (!$time_zone || $tz_distance > $distance) {
$time_zone = $timezone_id;
$tz_distance = $distance;
}
}
}
return $time_zone;
}
return 'none?';
}
//timezone for one NY co-ordinate
echo get_nearest_timezone(40.772222,-74.164581) ;
// more faster and accurate if you can pass the country code
echo get_nearest_timezone(40.772222, -74.164581, 'US') ;
これを行うために、小さなJavaクラスを作成しました。PHPに簡単に翻訳できます。データベースはコード自体に埋め込まれています。22kmの精度です。
https://sites.google.com/a/edval.biz/www/mapping-lat-lng-s-to-timezones
コード全体は基本的に次のようなものです。
if (lng < -139.5) {
if (lat < 68.5) {
if (lng < -140.5) {
return 371;
} else {
return 325;
}
...だから、PHPへの翻訳は簡単だと思います。
別の解決策は、タイムゾーンを持つ都市のテーブルをインポートし、Haversine式を使用して、座標に関連するそのテーブル内の最も近い都市を見つけることです。完全な説明をここに投稿しました: http://sylnsr.blogspot.com/2012/12/find-nearest-location-by-latitude-and.html
MySQLにデータをロードする例については、ここに例を示しました(小さなデータダンプをダウンロードするためのソースを使用): http://sylnsr.blogspot.com/2012/12/load-timezone-data -by-city-and-country.html
ルックアップの精度は、ルックアップデータの包括性に基づいていることに注意してください。
クレジットとリファレンス: MySQL Great Circle Distance(Haversine formula)
残念なことに、タイムゾーンは、いくつかの単純な機能に対して十分に規則的ではありません。 Wikipedia-Time Zone の地図をご覧ください
ただし、非常に大まかな近似値を計算できます。1時間の差は、経度15度(360/24)に相当します。
これが役に立つかどうかはわかりませんが、タイムゾーンの形状のデータベースを構築しました(北米のみ)。これは、国境だけでなく夏時間の遵守のために、骨の折れるほど正確で最新のものです。また、非公式の例外にも対応します。したがって、特定の場所の一連の図形を照会すると、その場所に適用される複数の図形が返され、その時期に適切な図形を選択できます。
http://OnTimeZone.com/OnTimeZone_shapes.gif で図形の画像を見ることができます。青い図形は夏時間を監視していないエリアの周りにあり、マゼンタは夏時間を監視しているエリアの周りにあり、ネオングリーンの図形(そのズームレベルで小さくて見づらい)は公式のタイムゾーンからの非公式な偏差があるエリアにあります。 OnTimeZone.comサイトで入手可能な詳細については、詳細をご覧ください。
OnTimeZone.comでダウンロード可能なデータは、非営利目的での使用は無料です。ダウンロードできないシェイプデータは、商用ライセンスで利用できます。
ここで提供されるタイムゾーン境界を使用できます。
5桁の郵便番号をタイムゾーンに一致させるデータと、DSTおよび非DST期間中の各タイムゾーンのUTCオフセットを決定するデータをダウンロードしました。
次に、最初の3桁を共有するすべての郵便番号は非常に近いため、データを単純化して郵便番号の最初の3桁のみを考慮しました。 3桁は一意のメール配信センターを識別します。
結果のJsonファイルでは、現在DSTの対象であるかどうかを判断する必要があり、おそらくあちこちで不正確な部分があります。しかし、非常にコンパクトでクエリが簡単な、非常に優れたローカルソリューションです。
ここにあります: https://Gist.github.com/benjiwheeler/8aced8dac396c2191cf
You can get the timezone based on the location in javascript.
function initAutocomplete() {
// Create the autocomplete object, restricting the search to geographical
// location types.
autocomplete = new google.maps.places.Autocomplete(
/** @type {!HTMLInputElement} */(document.getElementById('Location')),
{types: ['geocode']});
// When the user selects an address from the dropdown, populate the address
// fields in the form.
autocomplete.addListener('place_changed', fillInAddress);
}
function fillInAddress() {
// Get the place details from the autocomplete object.
var place = autocomplete.getPlace();
fnGettimezone($('#Location').serialize());
for (var component in componentForm) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details
// and fill the corresponding field on the form.
for (var i = 0; i < place.address_components.length; i++) {
var addressType = place.address_components[i].types[0];
if (componentForm[addressType]) {
var val = place.address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
}
function fnGettimezone(location) {
$.ajax({
url: "http://maps.googleapis.com/maps/api/geocode/json?address=" + location + "&sensor=false",
dataType: 'json',
success: function (result) {
console.log(result);
// result is already a parsed javascript object that you could manipulate directly here
var myObject = JSON.parse(JSON.stringify(result));
lat = myObject.results[0].geometry.location.lat;
lng = myObject.results[0].geometry.location.lng;
console.log(myObject);
$.ajax({
url: "https://maps.googleapis.com/maps/api/timezone/json?location=" + lat + "," + lng + "×tamp=1331161200&sensor=false",
dataType: 'json',
success: function (result) {
// result is already a parsed javascript object that you could manipulate directly here
var myObject = JSON.parse(JSON.stringify(result));
$('#timezone').val(myObject.timeZoneName);
}
});
}
});
}
このプロジェクト OpenStreetMapのデータからシェープファイルを作成し、それを処理する複数のライブラリにリンクします。 PHPを見ることができます https://github.com/minube/geo-timezone
geocoder.ca を使用します
北アメリカの任意の場所を入力し、jsonまたはjsonpでジオコード、市外局番、タイムゾーンを出力します。
例: http://geocoder.ca/1600%20pennsylvania%20avenue,Washington,DC
市外局番:(202)時間帯:アメリカ/ニューヨーク
ジョンソン:
{"standard":{"staddress":"Pennsylvania Ave","stnumber":"1600","prov":"DC","city":"WASHINGTON","postal":"20011","confidence":"0.8"},"longt":"-76.972948","TimeZone":"America/New_York","AreaCode":"202","latt":"38.874533"}
Google Timezone APIを使用できます。 https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=1331161200&key=YOUR_API_KEY
{
"dstOffset" : 0,
"rawOffset" : -28800,
"status" : "OK",
"timeZoneId" : "America/Los_Angeles",
"timeZoneName" : "Pacific Standard Time"
}