est-il possible de déterminer le fuseau horaire du point (lat/lon) sans utiliser les services Web? Geonames.org n'est pas assez stable pour que je puisse utiliser :( J'ai besoin de ça pour fonctionner en PHP.
Merci
J'ai eu ce problème il y a quelque temps et j'ai fait exactement ce que Adam a suggéré:
IIRC a mis moins de 1 seconde pour peupler le R-Tree et il pouvait ensuite effectuer des milliers de recherches à la seconde (les deux sur un PC âgé de 5 ans).
Quelle est la précision de vos résultats? Si une estimation approximative est suffisante, calculez vous-même le décalage:
offset = direction * longitude * 24 / 360
où direction est 1 pour l'est, -1 pour l'ouest et la longitude est en (-180,180)
J'ai rencontré ce problème alors que je travaillais sur un autre projet et l'ai examiné de manière approfondie. J'ai trouvé que toutes les solutions existantes manquaient de façon majeure.
Télécharger les données GeoNames et utiliser un index spatial pour rechercher le point le plus proche est certainement une option. Le résultat obtenu est souvent correct, mais il peut facilement échouer si un point de requête se trouve du mauvais côté d'une heure. bordure de zone à partir du point le plus proche dans la base de données.
Une méthode plus précise consiste à utiliser une carte numérique des fuseaux horaires et à écrire du code pour trouver le polygone dans cette carte qui contient un point de requête donné. Heureusement, il existe une excellente carte des fuseaux horaires du monde disponible à l’adresse http://efele.net/maps/tz/world/ . Pour écrire un moteur de requête efficace, vous devez:
Chacun de ceux-ci est digne de sa propre page de questions/réponses Stack Overflow.
Après avoir conclu qu'aucune des solutions existantes ne répondait à mes besoins, j'ai écrit ma propre solution et l'ai mise à disposition ici:
AskGeo utilise une carte numérique et dispose d'un index spatial hautement optimisé qui permet d'exécuter plus de 10 000 requêtes par seconde sur mon ordinateur en un seul fil. Et comme il est thread-safe, un débit encore plus élevé est certainement possible. Il s’agit d’un code sérieux dont le développement a pris beaucoup de temps. Nous l’offrons donc sous licence commerciale.
Il est écrit en Java, son utilisation dans PHP impliquerait donc:
http://php-Java-bridge.sourceforge.net/doc/how_it_works.php
Nous sommes également disposés à le porter contre une prime. Pour plus de détails sur les prix et pour une documentation détaillée, voir http://askgeo.com .
J'espère que c'est utile. Cela a certainement été utile pour le projet sur lequel je travaillais.
Je sais que c'est vieux, mais j'ai passé du temps à chercher cette réponse. Trouvé quelque chose de très utile. Google fait des recherches de fuseau horaire par long/lat. Limite de 2 500 par jour (ou 100 000 pour les utilisateurs professionnels).
Vous devriez pouvoir, si vous connaissez le polygone du fuseau horaire, voir si un lat/lon donné se trouve à l'intérieur.
Pour les zones terrestres, il existe des cartes de fichier de formes qui ont été créées pour les fuseaux horaires de la base de données tz (Olson). Elles ne sont pas mises à jour aussi régulièrement que la base de données tz elle-même, mais c'est un excellent point de départ et semble être très précis dans la plupart des cas.
Que dis-tu de ça ?
// 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') ;
J'ai écrit une petite classe Java pour le faire. Il pourrait être facilement traduit en PHP. La base de données est intégrée au code même. C'est précis à 22 km.
https://sites.google.com/a/edval.biz/www/mapping-lat-lng-s-to-timezones
Le code entier est fondamentalement comme ça:
if (lng < -139.5) {
if (lat < 68.5) {
if (lng < -140.5) {
return 371;
} else {
return 325;
}
... donc je suppose qu'une traduction en PHP serait facile.
Une autre solution consiste à importer un tableau des villes avec des fuseaux horaires, puis à utiliser la formule de Haversine pour trouver la ville la plus proche dans ce tableau, en fonction de vos coordonnées ..__ J'ai posté une description complète ici: http: // sylnsr .blogspot.com/2012/12/trouver-le-lieu-le-plus-proche-par-latitude-et.html
Pour un exemple de chargement des données dans MySQL, j'ai posté un exemple ici (avec les sources permettant de télécharger un petit vidage de données): http://sylnsr.blogspot.com/2012/12/load-timezone-data-by -city-and-country.html
Notez que l'exactitude de la recherche dépendra de la précision de vos données de recherche.
Crédits et références: MySQL Great Circle Distance (formule de Haversine)
Malheureusement, les fuseaux horaires ne sont pas assez réguliers pour une fonction simple. Voir la carte dans Wikipedia - Fuseau horaire
Cependant, une approximation très grossière peut être calculée: une différence d'une heure correspond à une longitude de 15 degrés (360/24).
Je ne suis pas sûr que cela soit utile ou non, mais j'ai construit une base de données de formes de fuseaux horaires (pour l'Amérique du Nord uniquement), extrêmement précise et à jour, non seulement pour les frontières, mais également pour l'observation de l'heure avancée. Formes également pour les exceptions non officielles. Ainsi, vous pouvez interroger l'ensemble des formes pour un emplacement donné, puis renvoyer plusieurs formes s'appliquant à cet emplacement et choisir celle qui convient pour la période de l'année.
Vous pouvez voir une image des formes sur http://OnTimeZone.com/OnTimeZone_shapes.gif . Les formes bleues entourent les zones qui n'observent pas l'heure d'été, celles de Magenta, celles respectant l'heure d'été, et les formes vertes fluo (petites et difficiles à voir à ce niveau de zoom), pour les zones non conformes à l'heure officielle. Beaucoup plus de détails sur ceux disponibles sur le site OnTimeZone.com.
Les données disponibles au téléchargement sur OnTimeZone.com sont gratuites pour un usage non commercial. Les données de forme, qui ne sont pas disponibles pour le téléchargement, sont disponibles pour une licence commerciale.
Vous pouvez utiliser les limites de fuseau horaire, fournies ici:
J'ai téléchargé des données qui correspondent à des codes postaux à 5 chiffres dans des fuseaux horaires et des données qui déterminent le décalage UTC pour chaque fuseau horaire pendant les périodes d'heure d'été et les heures d'été.
Ensuite, j'ai simplifié les données pour ne prendre en compte que les trois premiers chiffres du code postal, car tous les codes géographiques qui partagent les trois premiers chiffres sont très proches les uns des autres. les trois chiffres identifient un centre de distribution de courrier unique.
Le fichier Json résultant vous oblige à décider si vous êtes ou non soumis à l'heure d'été, et il comporte probablement une certaine imprécision ici et là. Mais c’est une très bonne solution locale, très compacte et simple à interroger.
Le voici: https://Gist.github.com/benjiwheeler/8aced8dac396c2191cf0
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);
}
});
}
});
}
Ce projet crée un fichier de formes à partir de données provenant d'OpenStreetMap et est lié à plusieurs bibliothèques qui le gèrent. Pour PHP, vous pouvez consulter https://github.com/minube/geo-timezone
J'utilise geocoder.ca
Entrez n'importe quel emplacement en Amérique du Nord, géocodes en sortie, codes de zone et fuseau horaire dans json ou jsonp.
Par exemple: http://geocoder.ca/1600%20pennsylvania%20avenue,Washington,DC
Indicatif régional: (202) Fuseau horaire: America/New_York
Json:
{"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"}
Vous pouvez utiliser 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"
}