根据距离和程度获取经度纬度组合

时间:2012-01-10 08:14:17

标签: php geolocation

我正在尝试获取覆盖某个区域(我的城市)的网格的地理组合。网格为500米* 500米。所以我想输入起始长/纬度组合,距离(500米),度数(90或270)并获得下一个长/纬度组合。

我没有意识到数学公式,很难找到解决方案。我找到了一些在两个长/纬度组合之间返回距离的php函数。

http://www.zipcodeworld.com/samples/distance.php.html http://www.phpro.org/tutorials/Geo-Targetting-With-PHP-And-MySQL.html#3

但是我仍然无法根据我的需要重建这个东西(我真的很讨厌 cos,sin,tan )。如果有人帮助我,我真的很感激。

2 个答案:

答案 0 :(得分:5)

以下是围绕中心点找到四个极值点(纬度,长度)的代码

 <script type="text/javascript">
            function toRad (value) {
                return value * Math.PI / 180;
            }

            function toDeg (value) {
                return value * 180 / Math.PI;
            }
            function computePoint(){                
                var radius = 6371;  //in kms
                var lat1 = checkField(document.getElementById("lat"));
                var lon1 = checkField(document.getElementById("long"));
                var dist = document.getElementById("distance").value;

                dist = typeof(dist)=='number' ? dist : typeof(dist)=='string' && dist.trim()!='' ? +dist : NaN;
                //                alert("Dist "+ dist+" kms");
                var angularDist = dist / radius;
                lat1= toRad(lat1);
                lon1=toRad(lon1);

                var lat2,lon2, angle = 0;

                for(i=1; i<5; i++,angle+=90){                  
                    var brng = toRad(angle);
                    lat2=lon2=0;
                    // second latitude
                    lat2 = Math.asin(Math.sin(lat1) * Math.cos(angularDist) + 
                        Math.cos(lat1) * Math.sin(angularDist) * Math.cos(brng));

                    // second longitude
                    lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(angularDist) *
                        Math.cos(lat1), Math.cos(angularDist) - Math.sin(lat1) * Math.sin(lat2));

                    if (isNaN(lat2) || isNaN(lon2)) alert("Something is null");

                    //                lon2 = (lon2+3*Math.PI) % (2*Math.PI) - Math.PI;  // normalise to -180..+180º
                    lat2 = toDeg(lat2);
                    lon2 = toDeg(lon2);
//                    alert("latitude: "+lat2 +",Longitude "+lon2);
                    document.getElementById("lat"+i).innerHTML=lat2;
                    document.getElementById("long"+i).innerHTML=lon2;
                    document.getElementById("ang"+i).innerHTML=angle;
                }

            }
            function checkField(field){
                var str=field.name
                var latlon1
                latlon=field.value;//parselatlon(field.value)
                if (str.substring(0,3)=="lat") {
                    if (latlon > 90.) {
                        alert ("Latitudes cannot exceed 90 degrees")
                        field.focus()  // Doesn't work!
                        field.select()
                    }
                }
                if (str.substring(0,3)=="long") {
                    if (latlon > 180.) {
                        alert ("Longitudes cannot exceed 180 degrees")
                        field.focus()
                        field.select()      
                    }
                }
                return latlon
            }

            function parselatlon(instr){
                // Parse strings dd.dd dd:mm.mm dd:mm:ss.ss
                var deg,min,sec,colonIndex,degstr,minstr,str
                str=instr
                colonIndex=str.indexOf(":")
                if (colonIndex==-1){ // dd.dd?
                    if (!isPosNumber(str)){
                        badLLFormat(instr)
                        return 0.
                    } else {
                        return parseFloat(str)
                    }
                }
            }
            function isPosNumber(instr){ //integer or float
                str=""+instr // force to string type
                oneDecimal=false
                for (var i=0;i<str.length;i++) {
                    var oneChar=str.charAt(i)
                    if (oneChar=="." && !oneDecimal){
                        oneDecimal=true
                        continue
                    }
                    if (oneChar < "0" || oneChar > "9") {
                        return false
                    }
                }
                return true
            }
            function badLLFormat(str){
                alert(str+ " is an invalid lat/lon format\n"+
                    "Use DD.DD DD:MM.MM or DD:MM:SS.SS")
            }
        </script>

和HTML看起来像......

<body>
        <div>Enter the details </div>
        Latitude  : <input type="text" id="lat" name="lat" value="" /> <br/>
        Longitude : <input type="text" id="long" name="long" value="" /> <br/>
        <!--        Bearing   : <input type="text" id="bearing" name="bearing" value="" placeholder="Enter angle in degrees" /> <br/>-->
        Distance  : <input type="text" id="distance" name="distance" value="" placeholder ="Enter distance in Kms. " /> <br/> 
        <input type="submit" value="Find Points" name="findPts" onclick="computePoint();"/>
        <div><h3><span> <strong>Results Will be displayed here</strong></span></h3></div>            
        <table border="1" style="text-align: center">
            <tr>
                <th>Latitude</th>
                <th>Longitude</th>
                <th>Angle (in degrees) </th>
            </tr>
            <tr>
                <td><label id="lat1" value=""></label> </td>
                <td><label id="long1" value=""></label> </td>
                <td><label id="ang1" value=""></label> </td>
            </tr>
            <tr>
                <td><label id="lat2" value=""></label> </td>
                <td><label id="long2" value=""></label> </td>
                <td><label id="ang2" value=""></label> </td>
            </tr>
            <tr>
                <td><label id="lat3" value=""></label> </td>
                <td><label id="long3" value=""></label> </td>
                <td><label id="ang3" value=""></label> </td>
            </tr>
            <tr>
                <td><label id="lat4" value=""></label> </td>
                <td><label id="long4" value=""></label> </td>
                <td><label id="ang4" value=""></label> </td>
            </tr>
        </table>
    </body>

我在这里通过GPL捐赠我的代码....享受!!

答案 1 :(得分:1)

该网站提供了许多纬度/经度/距离/方位计算的示例代码:

http://www.movable-type.co.uk/scripts/latlong.html

公式为:

lat2 = asin(sin(lat1)* cos(d / R)+ cos(lat1)* sin(d / R)* cos(θ))

lon2 = lon1 + atan2(sin(θ)* sin(d / R)* cos(lat1),cos(d / R)-sin(lat1)* sin(lat2))

θ是轴承(以弧度表示,从北向顺时针方向);

d / R是角距离(以弧度表示),其中d是行进距离,R是地球半径

您感兴趣的相关代码是javascript,但应该很容易转换:

var lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) + 
                      Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng) );
var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1), 
                             Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
相关问题