纬度和经度作为多边形算法中适合点的坐标

发布于 2024-09-24 20:33:52 字数 93 浏览 5 评论 0原文

给定表示目标的长/纬度坐标的数据库以及表示表示“区域”的多边形的边界坐标的一系列纬度/经度。使用简单的射线投射算法将纬度/经度视为笛卡尔坐标来确定目标是否在区域内是否安全?

Given a database of long/lat coordinates representing targets and a series of lat/long representing the bounding coordinates of polygons representing "zones". Using a simple ray casting algorithm is it safe to treat the lat/long as cartesian coordinates for determining if the target is within the zone?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

混吃等死 2024-10-01 20:33:52

只要边缘短,它就应该工作得足够好。但它不会是“正确的”。

想象一个三角形,其中两个点 a 和 b 位于赤道上,其中一个点位于北极附近。显然,(几乎)所有经度位于赤道上方 a 和 b 之间的点都在三角形中。但是,如果我们尝试将纬度/经度视为笛卡尔坐标,我们会得到完全不同的东西......

编辑:您需要小心跨越经度 = 最大/最小的区域,甚至更小心那些也包含一根杆子

Provided the edges are short, it should work well enough. It won't be "correct" though.

Imagine a triangle with two points a and b on the equator and one just short of the north pole. Evidently, (almost) all points with a longitude between a and b above the equator are in the triangle. But if we try treating the lats/longs as cartesian coordinates, we get something quite different...

Edit: You'll need to be careful with zones which cross longitude = max/min, and even more careful with the ones that also contain a pole

多像笑话 2024-10-01 20:33:52

您可以尝试一下

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBfaExFhABnh7I3-vTHJjA4TWqtYnMccKE&sensor=false"></script>
    <script type="text/javascript" src="http://www.the-di-lab.com/polygon/jquery-1.4.2.min.js"></script>


<script type="text/javascript">
    var map;
    var boundaryPolygon;
    function initialize() {

        google.maps.Polygon.prototype.Contains = function (point) {
            // ray casting alogrithm http://rosettacode.org/wiki/Ray-casting_algorithm
            var crossings = 0,
            path = this.getPath();

            // for each edge
            for (var i = 0; i < path.getLength(); i++) {
                var a = path.getAt(i),
                j = i + 1;
                if (j >= path.getLength()) {
                    j = 0;
                }
                var b = path.getAt(j);
                if (rayCrossesSegment(point, a, b)) {
                    crossings++;
                }
            }

            // odd number of crossings?
            return (crossings % 2 == 1);

            function rayCrossesSegment(point, a, b) {
                var px = point.lng(),
                py = point.lat(),
                ax = a.lng(),
                ay = a.lat(),
                bx = b.lng(),
                by = b.lat();
                if (ay > by) {
                    ax = b.lng();
                    ay = b.lat();
                    bx = a.lng();
                    by = a.lat();
                }
                if (py == ay || py == by) py += 0.00000001;
                if ((py > by || py < ay) || (px > Math.max(ax, bx))) return false;
                if (px < Math.min(ax, bx)) return true;

                var red = (ax != bx) ? ((by - ay) / (bx - ax)) : Infinity;
                var blue = (ax != px) ? ((py - ay) / (px - ax)) : Infinity;
                return (blue >= red);
            }
        };


        var mapProp = {
            center: new google.maps.LatLng(37.684, -122.591),
            zoom: 10,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(document.getElementById("googleMap"), mapProp);



        google.maps.event.addListener(map, 'click', function (event) {
            if (boundaryPolygon!=null && boundaryPolygon.Contains(event.latLng)) {
                alert(event.latLng + " is inside the polygon");
            } else {
                alert(event.latLng + " is outside the polygon");
            }

        });
    }


    function btnCheckPointExistence_onclick() {
        var latitude = document.getElementById('txtLattitude').value;
        var longitude = document.getElementById('txtLongitude').value;
        //alert(latitude);     alert(longitude)
        var myPoint = new google.maps.LatLng(latitude, longitude);

        if (boundaryPolygon == null) {
            alert("No Polygon");
        }
        else {

            if (boundaryPolygon.Contains(myPoint)) {
                alert(myPoint + "is inside the polygon.");
            } else {
                alert(myPoint + "is outside the polygon.");
            }
        }
    }


    function drawPolygon() {

        initialize();
        var boundary = '77.702866 28.987153, 77.699776 28.978594 ,77.735996 28.974164 ,77.719946 28.99346 ,77.713423 28.994361 ,77.711706 28.990382 ';
        var boundarydata = new Array();
        var latlongs = boundary.split(",");

        for (var i = 0; i < latlongs.length; i++) {
            latlong = latlongs[i].trim().split(" ");
            boundarydata[i] = new google.maps.LatLng(latlong[1], latlong[0]);
        }

        boundaryPolygon = new google.maps.Polygon({
            path: boundarydata,
            strokeColor: "#0000FF",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: 'Red',
            fillOpacity: 0.4

        });

        google.maps.event.addListener(boundaryPolygon, 'click', function (event) {

            if (boundaryPolygon.Contains(event.latLng)) {
                alert(event.latLng + "is inside the polygon.");
            } else {
                alert(event.latLng + "is outside the polygon.");
            }

        });

        map.setZoom(14);
        map.setCenter(boundarydata[0]);
        boundaryPolygon.setMap(map);

    }



  </script>
</head>
<body onload="initialize();drawPolygon();">
    <form id="form1" runat="server">

         <input type="text" value="28.982005022927137" name="txtLattitude" id="txtLattitude" placeholder="Enter Latitude">
        <input type="text" value="77.72157669067383" name="txtLongitude" id="txtLongitude" placeholder="Enter Langitude">
        <input type="button" value="Submit" name="submit" id="submit-text" value="submit" onclick="btnCheckPointExistence_onclick();">


        <h3>Check If Point Exist in a Polygon</h3>
        <span id="spnMsg" style="font-family: Arial; text-align: center; font-size: 14px; color: red;">this is message</span>
        <br />
        <br />

        <div id="googleMap" style="width: auto; height: 500px;">
        </div>

    </form>
</body>
</html>

您可以在此处查看演示

You can try this

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBfaExFhABnh7I3-vTHJjA4TWqtYnMccKE&sensor=false"></script>
    <script type="text/javascript" src="http://www.the-di-lab.com/polygon/jquery-1.4.2.min.js"></script>


<script type="text/javascript">
    var map;
    var boundaryPolygon;
    function initialize() {

        google.maps.Polygon.prototype.Contains = function (point) {
            // ray casting alogrithm http://rosettacode.org/wiki/Ray-casting_algorithm
            var crossings = 0,
            path = this.getPath();

            // for each edge
            for (var i = 0; i < path.getLength(); i++) {
                var a = path.getAt(i),
                j = i + 1;
                if (j >= path.getLength()) {
                    j = 0;
                }
                var b = path.getAt(j);
                if (rayCrossesSegment(point, a, b)) {
                    crossings++;
                }
            }

            // odd number of crossings?
            return (crossings % 2 == 1);

            function rayCrossesSegment(point, a, b) {
                var px = point.lng(),
                py = point.lat(),
                ax = a.lng(),
                ay = a.lat(),
                bx = b.lng(),
                by = b.lat();
                if (ay > by) {
                    ax = b.lng();
                    ay = b.lat();
                    bx = a.lng();
                    by = a.lat();
                }
                if (py == ay || py == by) py += 0.00000001;
                if ((py > by || py < ay) || (px > Math.max(ax, bx))) return false;
                if (px < Math.min(ax, bx)) return true;

                var red = (ax != bx) ? ((by - ay) / (bx - ax)) : Infinity;
                var blue = (ax != px) ? ((py - ay) / (px - ax)) : Infinity;
                return (blue >= red);
            }
        };


        var mapProp = {
            center: new google.maps.LatLng(37.684, -122.591),
            zoom: 10,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(document.getElementById("googleMap"), mapProp);



        google.maps.event.addListener(map, 'click', function (event) {
            if (boundaryPolygon!=null && boundaryPolygon.Contains(event.latLng)) {
                alert(event.latLng + " is inside the polygon");
            } else {
                alert(event.latLng + " is outside the polygon");
            }

        });
    }


    function btnCheckPointExistence_onclick() {
        var latitude = document.getElementById('txtLattitude').value;
        var longitude = document.getElementById('txtLongitude').value;
        //alert(latitude);     alert(longitude)
        var myPoint = new google.maps.LatLng(latitude, longitude);

        if (boundaryPolygon == null) {
            alert("No Polygon");
        }
        else {

            if (boundaryPolygon.Contains(myPoint)) {
                alert(myPoint + "is inside the polygon.");
            } else {
                alert(myPoint + "is outside the polygon.");
            }
        }
    }


    function drawPolygon() {

        initialize();
        var boundary = '77.702866 28.987153, 77.699776 28.978594 ,77.735996 28.974164 ,77.719946 28.99346 ,77.713423 28.994361 ,77.711706 28.990382 ';
        var boundarydata = new Array();
        var latlongs = boundary.split(",");

        for (var i = 0; i < latlongs.length; i++) {
            latlong = latlongs[i].trim().split(" ");
            boundarydata[i] = new google.maps.LatLng(latlong[1], latlong[0]);
        }

        boundaryPolygon = new google.maps.Polygon({
            path: boundarydata,
            strokeColor: "#0000FF",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: 'Red',
            fillOpacity: 0.4

        });

        google.maps.event.addListener(boundaryPolygon, 'click', function (event) {

            if (boundaryPolygon.Contains(event.latLng)) {
                alert(event.latLng + "is inside the polygon.");
            } else {
                alert(event.latLng + "is outside the polygon.");
            }

        });

        map.setZoom(14);
        map.setCenter(boundarydata[0]);
        boundaryPolygon.setMap(map);

    }



  </script>
</head>
<body onload="initialize();drawPolygon();">
    <form id="form1" runat="server">

         <input type="text" value="28.982005022927137" name="txtLattitude" id="txtLattitude" placeholder="Enter Latitude">
        <input type="text" value="77.72157669067383" name="txtLongitude" id="txtLongitude" placeholder="Enter Langitude">
        <input type="button" value="Submit" name="submit" id="submit-text" value="submit" onclick="btnCheckPointExistence_onclick();">


        <h3>Check If Point Exist in a Polygon</h3>
        <span id="spnMsg" style="font-family: Arial; text-align: center; font-size: 14px; color: red;">this is message</span>
        <br />
        <br />

        <div id="googleMap" style="width: auto; height: 500px;">
        </div>

    </form>
</body>
</html>

You can view Demo here

玩心态 2024-10-01 20:33:52

不,这样做并不安全。您会在两极周围以及 0 经度区域发现异常情况。

看看 NASA 的世界风代码。它们有地球表面多边形的表示,尽管你必须小心——有些表示会表示这些异常,有些则不会。

http://worldwind.arc.nasa.gov/java/

No, it's not safe to do that. You'll get anomalies around the poles and also at the 0 longitude areas.

Take a look at the NASA world wind code. they have representations for polygons on the surface of the globe although you have to be careful -- some of the representations will represent these anomalies, others will not.

http://worldwind.arc.nasa.gov/java/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文