14

html5 geolcation apiを介してユーザーのジオロケーションを取得しようとしていますが、次のスニペットを使用しています。

if (navigator.geolocation) {
    var timeoutVal = 10 * 1000 * 1000;
    navigator.geolocation.getCurrentPosition(
      displayPosition, 
      displayError,
      { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
    );
  }
  else {
     // DO SOME STUFF HERE
  }


  function displayPosition(position) {

    // configuration
    var myZoom = 12;
    var myMarkerIsDraggable = true;
    var myCoordsLenght = 6;
    var defaultLat = position.coords.latitude;
    var defaultLng = position.coords.longitude;
    document.getElementById('latitude').value = defaultLat;
    document.getElementById('longitude').value = defaultLng;
    /*
      1. creates the map
      2. zooms
      3. centers the map
      4. sets the map’s type
    */
    var map = new google.maps.Map(document.getElementById('canvas'), {
      zoom: myZoom,
      center: new google.maps.LatLng(defaultLat, defaultLng),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });


    });
    // centers the map on markers coords
    map.setCenter(myMarker.position);
    // adds the marker on the map
    myMarker.setMap(map);
  }

  function displayError(error) {
    var errors = { 
      1: 'Permission denied',
      2: 'Position unavailable',
      3: 'Request timeout'
    };
    alert("Error: " + errors[error.code]);
  }
});

上記のアプローチの問題点は、使用が難しいと感じているユーザーがほとんどいないことです。まれに、 [許可]ではなく[拒否]をクリックして、画面を見つめ続けています。したがって、ユーザビリティの観点から、良いアプローチは次のようになると思います。

  1. 彼らに許可を求めてください。

  2. 3秒間待ちます。[拒否]をクリックするか、応答しない場合は、IPを使用して地図上に地理を表示します。

上記のスニペットの2番目のステップを実行するにはどうすればよいですか。教えてください、ありがとう!ただし、処理するためのより良い方法は何でしょうか

4

8 に答える 8

16

これは、私が少し前に書き、最近更新したスクリプト(geolocator.js )です。

更新:Geolocatorv2がリリースされました。

特徴:

  • HTML5ジオロケーション(ユーザーの許可による)
  • IPによる場所
  • ジオコーディング(住所からの座標)
  • 逆ジオコーディング(座標からの住所検索)
  • 完全な住所情報(通り、町、近所、地域、国、国コード、郵便番号など...)
  • フォールバックメカニズム(HTML5ジオロケーションからIPジオルックアップへ)
  • 地理的位置を見る
  • 距離行列と期間を取得する
  • 2つの地理的ポイント間の距離を計算します
  • タイムゾーン情報を取得する
  • クライアントIPを取得する
  • Googleローダーをサポートします(Googleマップを動的にロードします)
  • Googleマップを動的に作成します(マーカー、情報ウィンドウ、自動調整ズーム付き)
  • ノンブロッキングスクリプトの読み込み(外部ソースはページの読み込みを中断することなくオンザフライで読み込まれます)

ライブデモをご覧ください。APIドキュメント
を参照してください。

Geolocatorの例のスクリーンショット

使用法:

var options = {
    enableHighAccuracy: true,
    timeout: 6000,
    maximumAge: 0,
    desiredAccuracy: 30, // meters
    fallbackToIP: true, // get location by IP if geolocation fails or rejected
    addressLookup: true, // requires Google API key
    timezone: true, // requires Google API key
    map: "my-map" // creates a Google map. requires Google API key
};
geolocator.locate(options, function (err, location) {
    console.log(err || location);
});

出力例:

{
    coords: {
        latitude: 37.4224764,
        longitude: -122.0842499,
        accuracy: 30,
        altitude: null,
        altitudeAccuracy: null,
        heading: null,
        speed: null
    },
    address: {
        commonName: "",
        street: "Amphitheatre Pkwy",
        route: "Amphitheatre Pkwy",
        streetNumber: "1600",
        neighborhood: "",
        town: "",
        city: "Mountain View",
        region: "Santa Clara County",
        state: "California",
        stateCode: "CA",
        postalCode: "94043",
        country: "United States",
        countryCode: "US"
    },
    formattedAddress: "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
    type: "ROOFTOP",
    placeId: "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
    timezone: {
        id: "America/Los_Angeles",
        name: "Pacific Standard Time",
        abbr: "PST",
        dstOffset: 0,
        rawOffset: -28800
    },
    flag: "//cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1/flags/4x3/us.svg",
    map: {
        element: HTMLElement,
        instance: Object, // google.maps.Map
        marker: Object, // google.maps.Marker
        infoWindow: Object, // google.maps.InfoWindow
        options: Object // map options
    },
    timestamp: 1456795956380
}
于 2013-02-11T10:57:24.337 に答える
3

次に、次のようなgeoipapiを使用します。

http://freegeoip.net/static/index.html

于 2013-02-01T14:24:29.843 に答える
2

わかりました。これはコードの答えではなく、ユーザーエクスペリエンスの答えです。

UXの観点から、最初に目立つのは、ブラウザーをトリガーして許可を求める前に、提供している情報が不足していることです。

許可を求められる画面の「場所」を示すスクリーンショット(大きな矢印が付いている)を示す、ある種のオーバーレイボックスを用意することをお勧めします。また、その機会を利用して、許可を拒否したり、たとえば10秒以内に許可を受け入れなかった場合(つまり、プロンプトバーを無視した場合)に何が起こるかを伝えることができます。

IPの場所をデフォルトで表示しないことをお勧めします。これは、基本的に「私がどこにいるかを通知することに同意しない」と言っている可能性があるためです。次に、彼らがどこにいるかの大きな地図を表示します。これは、[拒否]をクリックした数人の人々を驚かせる可能性があります。その上、それは非常に不正確かもしれません。

「許可を求めないで許しを求める」という考えは、Biz devで機能する可能性がありますが、UIでは機能しないため、戻ってこないだけです。

本当に高精度が必要かどうかを自問します。高精度はユーザーのバッテリーを消耗し、時間がかかり、特にそれらがどこにあるかを大まかに見つけるためだけに必要な場合は、それ以上の価値がない可能性があるためです。必要に応じて、後でいつでも電話をかけて、より正確に読むことができます。

[拒否]または[許可]をクリックしない場合にタイムアウトするという概念は、setTimeoutを使用して実現できます。したがって、オーバーレイボックスで[OK、[許可]をクリックする準備ができました]をクリックしたら、タイムアウトを開始し、最終的にタイムアウトになる場合は、上記の手順で行うように指示したことを実行します。

この方法を使用すると、ユーザーに許可または拒否(無視)のいずれかを強制します。どちらの方法でも、制御を法廷に戻し、ユーザーに完全な情報を提供し続けます。

これはコード固有の答えではありませんが、JSからは、「コード実装のヘルプ」が実際にはここでの問題ではないことは明らかです。これがあなたのユーザーエクスペリエンスについてもう少し考えさせてくれることを願っています。

于 2013-02-04T17:37:14.947 に答える
0

これは助けになるかもしれません:http: //jsfiddle.net/sandesh2302/FghFZ/ 私はこれを自分のものに使用しました、それはうまくいきました。

元:

    <!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />    
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=true"></script>    

    <script type="text/javascript">
      function getLocation(){
        navigator.geolocation.getCurrentPosition(handleSuccess,handleError);
      }

      function initiate_watchlocation() {  
        if(watchProcess == null){
          watchProcess = navigator.geolocation.watchPosition(handleSuccess,handleError);
        }
      } 

      function stop_watchlocation() {  
        if(watchProcess != null){
          navigator.geolocation.clearWatch(watchProcess);
        }
      } 

      function handleSuccess(position){
        drawMap(position);
      }

      function handleError(error){
        switch(error.code)
        {
          case error.PERMISSION_DENIED: alert("User did not share geolocation data");break;  
          case error.POSITION_UNAVAILABLE: alert("Could not detect current position");break;  
          case error.TIMEOUT: alert("Retrieving position timed out");break;  
          default: alert("Unknown Error");break;  
        }
      }


      function drawMap(position) {
        var container = $('#map_canvas');
        var myLatLong = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
        var mapOptions = {
          center: myLatLong,
          zoom: 12,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(container[0],mapOptions);
        container.css('display','block');
        var marker = new google.maps.Marker({ 
          position: myLatLong,
          map:map,
          title:"My Position (Accuracy of Position: " + position.coords.accuracy + " Meters), Altitude: " 
            + position.coords.altitude + ' Altitude Accuracy: ' + position.coords.altitudeAccuracy
        });
      }

      function drawStaticMap(position){
        var container = $('#map_canvas');
        var imageUrl = "http://maps.google.com/maps/api/staticmap?sensor=false&center=" + position.coords.latitude + "," +  
                    position.coords.longitude + "&zoom=18&size=640x500&markers=color:blue|label:S|" +  
                    position.coords.latitude + ',' + position.coords.longitude;  

        container.css({
          'display':'block',
          'width' : 640
        });
        $('<img/>',{
          src : imageUrl
        }).appendTo(container);
      } 
    </script>
  </head>
  <body >
    <button id="getLocation">Find My Location</button>
    <div style="text-align:center">
      <button id="initWatch">Put Watch on Your Position</button>
      <button id="stopWatch">Stop Position Watching</button>
    </div>
    <div id="map_canvas" ></div>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>



  </body>
</html>
于 2013-02-04T17:46:55.857 に答える
0

このtutsplusの例を見てくださいhttp://mobile.tutsplus.com/tutorials/mobile-web-apps/html5-geolocation/

于 2013-02-03T11:06:01.283 に答える
0

このオンラインサービスを使用して、latlngを簡単に取得できます。

http://dev.maxmind.com/geoip/javascript

タイムアウトに関しては、ブラウザーのアクセス許可メカニズムを妨害する方法はないと思います(たとえば、一定の秒数後にそのアクセス許可ポップアップを閉じる)-私は喜んで間違っていることが証明されますが。タイマーを設定し、3秒後に、IPベースのジオロケーションを取得してマップを設定する(または、3秒後にページを更新し、HTML5ではなくIPベースのジオをトリガーするCookieを設定する)ことができます。ジオですが、私に言わせれば、それは少し上です)。

次に、許可があれば、HTML5ジオロケーション(はるかに正確なはずです)で地図を更新します。IPジオフォールバックを関数にカプセル化して、HTML5ジオロケーションがない場合や拒否された場合に使用することもできます。

これがフィドルです:http: //jsfiddle.net/mfNCn/1/

これがフィドルからのラフカットです:

<script src="http://j.maxmind.com/app/geoip.js" charset="ISO-8859-1" type="text/javascript"></script>
...
var time_perm = window.setTimeout(get_by_ip, 3000);
...
function get_by_ip() {
    var lat = geoip_latitude();
    var lng = geoip_longitude();
    map_it(lat, lng);
}
...
function map_it(lat,lng) {
    // build your map here
}

(コードチャンク全体がかなり長いため、ここに配置することを躊躇します。残りの部分と完全な実装については、フィドルを確認してください)

于 2013-02-06T21:40:27.997 に答える
0

タイムアウトが発生した場合、またはユーザーがリクエストを拒否した場合は、ニューヨーク州ニューヨーク(40.7142、-74.0064)のようなデフォルトの場所を設定します。ユーザーがリクエストを拒否した場合、ユーザーはあなたが自分の場所を知らないことも期待する必要があるため、わかりやすいデフォルトを選択することが次善の策です。

コードを変更せずにデフォルトを使用するにはdisplayPosition({coords: {latitude: 40.7142, longitude: -74.0064}})、次の2つの場所で呼び出すことで実現できます。

if (navigator.geolocation) {
    var timeoutVal = 10 * 1000 * 1000;
    navigator.geolocation.getCurrentPosition(
        displayPosition, 
        displayError,
        { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
    );
}
else {
    displayPosition({coords: {latitude: 40.7142, longitude: -74.0064}})
}
....
function handleError(error){
    switch(error.code)
    {
        case error.PERMISSION_DENIED: alert("User did not share geolocation data");break;  
        case error.POSITION_UNAVAILABLE: alert("Could not detect current position");break;  
        case error.TIMEOUT: alert("Retrieving position timed out");break;  
        default: alert("Unknown Error");break;  
    }
    displayPosition({coords: {latitude: 40.7142, longitude: -74.0064}});
}

http://nearbytweets.comでは、関数の「キュー」を使用してユーザーの場所を検索し、そのうちの1人が有効な場所を見つけるまでキューをループします。最後の関数はニューヨーク州ニューヨークを返します。これは、他のすべての試行が失敗したことを意味します。少し変更されたコードのサンプルを次に示します。

var position_finders = [                                                                                                                                                                                                              
    function () {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(check_position, check_position);
            return;
        }   
        check_position();
    },  
    function () {
        check_position(JSON.parse(localStorage.getItem('last_location')));
    },  
    function () {
        $.ajax({
            url: 'http://www.google.com/jsapi?key=' + google_api_key,
            dataType: 'script',
            success: check_position
        }); 
    },  
    function () {
        check_position({latitude: 40.7142, longitude: -74.0064}, true);
    }   
],

check_position = function (pos, failed) {
    pos = pos || {}; 
    pos = pos.coords ? 
        pos.coords :
        pos.loader ?
        pos.loader.clientLocation :
        pos;

    if (typeof pos.latitude === 'undefined' || typeof pos.longitude === 'undefined') {
        position_finders.shift()();
        return;
    }   

    localStorage.setItem('last_location', JSON.stringify(pos));

    // using your code, I would call this:
    displayPosition(pos);
};

check_position();

各position_finderの機能は次のとおりです。

  1. navigator.geolocationを試行します。
  2. localStorageから最後の場所をプルしようとします
  3. Googleローダーを使用してIP経由で場所を検索
  4. ニューヨーク州ニューヨークを使用
于 2013-02-08T23:03:20.387 に答える
-1

UIの観点から、私は次の手順に従います。

A)次に何が起こるかを説明する素敵なテキストボックスを表示し(つまり、「ブラウザは許可を与えるように要求します」、「許可をクリックします」など)、ボタンを押して続行するように要求しますB)マップを表示します今

于 2013-02-07T07:58:48.817 に答える