質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.94%

google mapの地図上の2点の半径を表示させ、点同士の距離が4km以内だった時に、”出店不可”4km以上だった時に”出店可”を返したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,101

yoshoo219

score 31

google map APIを利用して、地図上の2点の半径を表示させ、点同士の距離が4km以内だった時に、”出店不可”4km以上だった時に”出店可”を返したいです。

現状、googleマップで、緯度経度を指定した箇所にピンを置き、半径◯mの円を引く機能まで実現する所までが出来たのですが、

1.2点目以降の地図のピンと半径を置く
2.点同士の距離が4km以内だった時に、”出店不可”4km以上だった時に”出店可”を返す

の2つが出来ておりません。
お知恵をお貸し頂けますと幸いです。
何卒よろしくお願いします。

<body>
    <!-- Map -->
    <p class="bar">
        <input type="text" name="name" size="30" maxlength="20">
    </p>

    <div id="map"></div>

    <!-- Map -->
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

    <!--    <div id="map"></div>-->
    <script type="text/javascript">
        var map;
        console.log(document.getElementById('map'));

        function initMap() {
            var latlng = new google.maps.LatLng(35.681382, 139.766084);
            var marker = new google.maps.Marker({
                position: latlng,
                map: map
            });
            var marker2 = new google.maps.Marker({
                position:  {lat: 35.681382, lng: 139.766084},
                map: map,
                title: 'Hello World!'
            });

            //            map = new Map( elem, obj );

            map = new google.maps.Map(document.getElementById('map'), {
                zoom: 12,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                scaleControl: true,
                scrollwheel: true
            });

                        new google.maps.Circle({
                            center: latlng,
                            fillColor: '#ff0000',
                            fillOpacity: 0.5,
                            map: map,
                            radius: 2000,
                            strokeColor: '#ff0000',
                            strokeOpacity: 1,
                            strokeWeight: 1
                        });
        }
    </script>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB5o9PRJhKBWmTMFb_Ep62sfDWrMPbdGu8&callback=initMap">
    </script>
</body>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

前の回答に引き続き失礼いたします。
なるほど…実は複雑なことをしたかった訳ですね…。
しかしながら、個人的におもしろそうだったので、ちょっとコードを書いてみました。

te2jiさんの回答を受けて、「点同士の距離を測る」方法で作成してみました。
こんな感じでどうでしょうか?

<!-- Map -->
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB5o9PRJhKBWmTMFb_Ep62sfDWrMPbdGu8&callback=initMap"></script>
    <!-- googleMap APIは先に読み込んでおいたほうが良いかと -->
    <script type="text/javascript">
// 距離計算関数
function calcDistance(lat_1, lng_1, lat_2, lng_2) {
  // 測地系定数
  // GRS80 ( 世界測地系 ) <- 現在の日本での標準
  var RX = 6378137.000000  // 赤道半径
  var RY = 6356752.314140  // 極半径

  // 2点の経度の差を計算 ( ラジアン )
  var a_x = lng_1 * Math.PI / 180 - lng_2 * Math.PI / 180;
  // 2点の緯度の差を計算 ( ラジアン )
  var a_y = lat_1 * Math.PI / 180 - lat_2 * Math.PI / 180;
  // 2点の緯度の平均を計算
  var p = (lat_1 * Math.PI / 180 + lat_2 * Math.PI / 180) / 2;
  // 離心率を計算
  var e = Math.sqrt((RX * RX - RY * RY) / (RX * RX));
  // 子午線・卯酉線曲率半径の分母Wを計算
  var w = Math.sqrt(1 - e * e * Math.sin(p) * Math.sin(p));
  // 子午線曲率半径を計算
  var m = RX * (1 - e * e) / (w * w * w);
  // 卯酉線曲率半径を計算
  var n = RX / w;
  // 距離を計算
  var d  = Math.pow(a_y * m, 2) + Math.pow(a_x * n * Math.cos(p), 2);
  d = Math.round(Math.sqrt(d)) / 1000;

  return d;
}
function initMap() {
        //マーカーを配置したい座標をオブジェクトで配列にまとめておく
        var latlngArr = [
            { lat: '35.681382' , lng: '139.766084' },
            { lat: '35.695976' , lng: '139.751608' },
            { lat: '35.691771' , lng: '139.698606' }

            //座標を増やしたければ、ここから加えたいだけオブジェクトリテラルで加えていけばOK(末尾の「,」だけ注意)

        ];
        var latlng = new google.maps.LatLng( latlngArr[0].lat , latlngArr[0].lng );//地図の中心位置。今回はとりあえずlatlngArrの一つ目にしておきました
        var optios = {
            zoom: 12,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
        };

        var map = new google.maps.Map(document.getElementById('map') , optios );

        var markers = new Array();
        var circle = new Array();

        for(var i=0;i<latlngArr.length; i++){
            var length = Object.keys(latlngArr[i]).length;

            //距離計算 dはkmで返される
        /* 注意:ここの計算は再考が必要…(2点間の距離を測るだけなら単純なのですが、3点以上になると。。。) */
            if(i === latlngArr.length-1){
                var d = calcDistance(latlngArr[i].lat, latlngArr[i].lng, latlngArr[0].lat, latlngArr[0].lng)
            }else{
                var d = calcDistance(latlngArr[i].lat, latlngArr[i].lng, latlngArr[i+1].lat, latlngArr[i+1].lng)
            }
            /*
            ちなみに2点間の距離を測るだけなら
            if(i < latlngArr.length){
                var d = calcDistance(latlngArr[i].lat, latlngArr[i].lng, latlngArr[0].lat, latlngArr[0].lng)
            }
            のみで
            */

            //マーカーを配置
            markers[i] = new google.maps.Marker({
                position: new google.maps.LatLng( latlngArr[i].lat , latlngArr[i].lng ),
                map: map
            });

            //図形(円)を表示
            circle[i] = new google.maps.Circle({
                center : new google.maps.LatLng( latlngArr[i].lat , latlngArr[i].lng ),
                fillColor: '#ff0000',
                fillOpacity: 0.5,
                map: map,
                radius: 2000,
                strokeColor: '#ff0000',
                strokeOpacity: 1,
                strokeWeight: 1
            });

            //titleだとカーソルオンしてから数秒待たなければ表示されないので「情報ウィンドウ」で表示
            if(d<4){ //距離が4km未満なら
                var infoWindw = new google.maps.InfoWindow({content:'出店不可'})
            }else{
                var infoWindw = new google.maps.InfoWindow({content:'出店可'})
            }
            infoWindw.open(map , markers[i]);
        }
}
    </script>

※数学が苦手なもので、緯度・経度からの距離計算式(※参考:「二地点の緯度・経度からその距離を計算する」(http://yamadarake.jp/trdi/report000001.html)」を見て気持ちが萎えたので、
「Google Maps JavaScript API V3 + 2点間距離計算!」
http://www.mk-mode.com/octopress/2013/07/12/google-maps-api-calc-distance/
から計算用コードを拝借しました。。(※constが使われていた箇所をvar宣言に変えています)

1.2点目以降の地図のピンと半径を置く 

マップに配置したいマーカーの数だけループで処理すればOKですよ。(※下記コード参照)

2.点同士の距離が4km以内だった時に、”出店不可”4km以上だった時に”出店可”を返す

2点だけで大丈夫なら、さほど難しくはないのですが、3点以上になるとかなり複雑な計算が必要になるかと…
(…数学が苦手なもので、公式が分かりません。。苦笑 ここだけだれか別の方のお知恵をお貸しいただけると幸いです。。)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

点の座標がわかっているなら、点同士の距離を測るが普通じゃないかなぁ。簡単だし。
google map api に円の重なりを検出するような仕組みがあるのであれば別だけど。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/20 20:30

    仰る通り、点同士の距離で測るほうが簡単ですね。ご回答ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.94%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • トップ
  • JavaScriptに関する質問
  • google mapの地図上の2点の半径を表示させ、点同士の距離が4km以内だった時に、”出店不可”4km以上だった時に”出店可”を返したい