给定纬度和经度的多边形以及一组点,确定哪些点位于内部

时间:2013-11-30 02:03:13

标签: geometry geospatial

给定一组构成多边形的latlon点和一组latlon点,我如何确定哪些点位于内部。多边形可以跨越100km并且误差可以是几百米(即,内部或外部的点可能失败或者在边缘处被错误地包括在内)。多边形和点不会靠近极点。我可以将latlon点视为2d,还是需要将它们转换为某种投影?圆圈很容易,但我想知道对于100km宽的多边形,误差是否太大了?

我打算用C ++做这个,但语言并不重要。

2 个答案:

答案 0 :(得分:1)

以下是Openlayers的(javascript)代码来执行此操作

/**
 * Method: containsPoint
 * Test if a point is inside a polygon.  Points on a polygon edge are
 *     considered inside.
 *
 * Parameters:
 * point - {<OpenLayers.Geometry.Point>}
 *
 * Returns:
 * {Boolean | Number} The point is inside the polygon.  Returns 1 if the
 *     point is on an edge.  Returns boolean otherwise.
 */
containsPoint: function(point) {
    var numRings = this.components.length;
    var contained = false;
    if(numRings > 0) {
        // check exterior ring - 1 means on edge, boolean otherwise
        contained = this.components[0].containsPoint(point);
        if(contained !== 1) {
            if(contained && numRings > 1) {
                // check interior rings
                var hole;
                for(var i=1; i<numRings; ++i) {
                    hole = this.components[i].containsPoint(point);
                    if(hole) {
                        if(hole === 1) {
                            // on edge
                            contained = 1;
                        } else {
                            // in hole
                            contained = false;
                        }                            
                        break;
                    }
                }
            }
        }
    }
    return contained;
}

可在Openlayers at Github找到完整档案 要了解this.components背后的想法,请查看Collection.js

<强>更新

在OpenLayers中,多边形是线性环的集合。可以在LinearRing.js

找到此containsPoint功能

答案 1 :(得分:1)

您可以查看实际演示here

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>How to Check If Point Exist in a Polygon - Google Maps API v3</title>
    <script type="text/javascript" src="http://www.the-di-lab.com/polygon/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
    <script type="text/javascript">
        var map;
        var boundaryPolygon;
        function initialize() {

            var mapProp = {
                center: new google.maps.LatLng(26.038586842564317, 75.06787185438634),
                zoom: 6,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };

            map = new google.maps.Map(document.getElementById("map-canvas"), mapProp);

            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);
                }
            };


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

                if (boundaryPolygon != null && boundaryPolygon.Contains(event.latLng)) {
                    alert("in")
                    document.getElementById("spnMsg").innerText = "This location is " + event.latLng + " inside the polygon.";
                } else {
                    alert("out")
                    document.getElementById("spnMsg").innerText = "This location is " + event.latLng + " 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) {
                document.getElementById("spnMsg").innerText = '';
                if (boundaryPolygon.Contains(event.latLng)) {
                    document.getElementById("spnMsg").innerText = "This location is " + event.latLng + " inside the polygon.";
                } else {
                    document.getElementById("spnMsg").innerText = "This location is " + event.latLng + " outside the polygon.";
                }

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

        }

    </script>
</head>
<body onload="initialize();drawPolygon();">
    <form id="form1" runat="server">
        <h3>Check If Point Exist in a Polygon</h3>
        <h3>click on the polygon and out side the polygon for testing</h3>
        <span id="spnMsg" style="font-family: Arial; text-align: center; font-size: 14px; color: red;">this is message</span>
        <br />
        <br />
        <div id="map-canvas" style="width: auto; height: 500px;">
        </div>

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

您可以在此处查看更多可能对您使用的演示 http://codeace.in/download/gmap/

您可以下载所有演示版 点击文件

&#34; googlemap.zip&#34;在索引中给出