Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Google map API v.3查找多段线上一点到另一点的最近点_Javascript_Google Maps_Google Maps Api 3 - Fatal编程技术网

Javascript Google map API v.3查找多段线上一点到另一点的最近点

Javascript Google map API v.3查找多段线上一点到另一点的最近点,javascript,google-maps,google-maps-api-3,Javascript,Google Maps,Google Maps Api 3,我有一张带折线的地图。服务器将在地图上用一个LatLng点来响应我。我需要检查服务器上的点是否位于多段线边缘上。如果没有,我需要找到多段线上最近的点,并在多段线上最近的点上放置一个标记。例如,如果服务器用点a响应我,我需要在点B上放置一个标记 我发现一个很好的库,但是这个库是为GoogleAPI版本设计的。2,我使用的是谷歌API版本。3.谷歌API版本还有其他选择吗。3.谢谢。谷歌地图Javascript API有一个 几何图形库有一个isLocationOnEdge函数。看 要确定点是否落

我有一张带折线的地图。服务器将在地图上用一个LatLng点来响应我。我需要检查服务器上的点是否位于多段线边缘上。如果没有,我需要找到多段线上最近的点,并在多段线上最近的点上放置一个标记。例如,如果服务器用点a响应我,我需要在点B上放置一个标记


我发现一个很好的库,但是这个库是为GoogleAPI版本设计的。2,我使用的是谷歌API版本。3.谷歌API版本还有其他选择吗。3.谢谢。

谷歌地图Javascript API有一个

几何图形库有一个
isLocationOnEdge
函数。看

要确定点是否落在多段线上或附近,或落在多边形边缘上或附近,请将点、多段线/多边形以及可选的公差值(以度为单位)传递到
google.maps.geometry.poly.isLocationOnEdge()
。如果点与直线或边上最近点之间的距离在指定公差范围内,则函数返回true。默认公差值为10-9度

必须以以下方式包含库:

<script type="text/javascript"
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">
</script>

如果您需要多个库,例如:

<script type="text/javascript"
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry,places">
</script>

提供完整的文档


如果需要查找多段线上的点,可以使用您在问题中提到的移植到v3版本的库:

var mapRoute;

var rtPoints;
var centerMAP = new google.maps.LatLng(-7.402438, 110.446957);

function gLatLngFromEN(e, n) {
    var ogbLL = NEtoLL(e, n);
    var pc = OGBToWGS84(ogbLL.lat, ogbLL.lon, 0);
    return new google.maps.LatLng(pc.lat, pc.lon);
}

function routeMap() {

    mapRoute = new google.maps.Map(document.getElementById('mapRoute'), {
        center: centerMAP,
        zoom: 14,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    });
    mapRoute.setCenter(gLatLngFromEN(469000, 169000), 13);

    var rtPoints = new Array();
    rtPoints.push(gLatLngFromEN(468000, 168000));
    rtPoints.push(gLatLngFromEN(468000, 170000));
    rtPoints.push(gLatLngFromEN(470000, 170000));
    rtPoints.push(gLatLngFromEN(470000, 168000));
    var rtPoly = new google.maps.Polyline({
        path: rtPoints,
        strokeColor: "#0000FF",
        strokeWeight: 3,
        map: mapRoute
    });
    var container = document.createElement("div");
    container.style.fontFamily = 'Arial';
    container.style.fontSize = 'XX-Small';

    var ptr = document.createElement("INPUT");
    ptr.style.width = "100px";
    ptr.type = "Text";
    ptr.readOnly = true;
    ptr.id = "distPtr";
    container.appendChild(ptr);

    document.getElementById("control").appendChild(container);


    google.maps.event.addListener(mapRoute, 'mousemove', function (point) {
        document.getElementById('distPtr').value = Math.round(bdccGeoDistanceToPolyMtrs(rtPoly, point.latLng));
    });

}

google.maps.event.addDomListener(window, 'load', routeMap);


// Code to find the distance in metres between a lat/lng point and a polyline of lat/lng points
// All in WGS84. Free for any use.
//
// Bill Chadwick 2007
// updated to Google Maps API v3, Lawrence Ross 2014

    // Construct a bdccGeo from its latitude and longitude in degrees
    function bdccGeo(lat, lon) 
    {
      var theta = (lon * Math.PI / 180.0);
      var rlat = bdccGeoGeocentricLatitude(lat * Math.PI / 180.0);
      var c = Math.cos(rlat);   
      this.x = c * Math.cos(theta);
      this.y = c * Math.sin(theta);
      this.z = Math.sin(rlat);      
    }
    bdccGeo.prototype = new bdccGeo();

    // internal helper functions =========================================

      // Convert from geographic to geocentric latitude (radians).
    function bdccGeoGeocentricLatitude(geographicLatitude) 
    {
      var flattening = 1.0 / 298.257223563;//WGS84
        var f = (1.0 - flattening) * (1.0 - flattening);
      return Math.atan((Math.tan(geographicLatitude) * f));
    }

    // Convert from geocentric to geographic latitude (radians)
    function bdccGeoGeographicLatitude (geocentricLatitude) 
    {
      var flattening = 1.0 / 298.257223563;//WGS84
        var f = (1.0 - flattening) * (1.0 - flattening);
      return Math.atan(Math.tan(geocentricLatitude) / f);
    }

     // Returns the two antipodal points of intersection of two great
     // circles defined by the arcs geo1 to geo2 and
     // geo3 to geo4. Returns a point as a Geo, use .antipode to get the other point
    function bdccGeoGetIntersection( geo1,  geo2,  geo3,  geo4) 
    {
      var geoCross1 = geo1.crossNormalize(geo2);
      var geoCross2 = geo3.crossNormalize(geo4);
      return geoCross1.crossNormalize(geoCross2);
    }

    //from Radians to Meters
    function bdccGeoRadiansToMeters(rad)
    {
      return rad * 6378137.0; // WGS84 Equatorial Radius in Meters
    }

    //from Meters to Radians
    function bdccGeoMetersToRadians(m)
    {
      return m / 6378137.0; // WGS84 Equatorial Radius in Meters
    }

    // properties =================================================


    bdccGeo.prototype.getLatitudeRadians = function() 
    {
      return (bdccGeoGeographicLatitude(Math.atan2(this.z,
        Math.sqrt((this.x * this.x) + (this.y * this.y)))));
    }

    bdccGeo.prototype.getLongitudeRadians = function() 
    {
      return (Math.atan2(this.y, this.x));
    }

    bdccGeo.prototype.getLatitude = function() 
    {
      return this.getLatitudeRadians()  * 180.0 / Math.PI;
    }

    bdccGeo.prototype.getLongitude = function() 
    {
      return this.getLongitudeRadians()  * 180.0 / Math.PI ;
    }

    // Methods =================================================

        //Maths
    bdccGeo.prototype.dot = function( b) 
    {
      return ((this.x * b.x) + (this.y * b.y) + (this.z * b.z));
    }

        //More Maths
    bdccGeo.prototype.crossLength = function( b) 
    {
      var x = (this.y * b.z) - (this.z * b.y);
      var y = (this.z * b.x) - (this.x * b.z);
      var z = (this.x * b.y) - (this.y * b.x);
      return Math.sqrt((x * x) + (y * y) + (z * z));
    }

    //More Maths
    bdccGeo.prototype.scale = function( s) 
    {
        var r = new bdccGeo(0,0);
        r.x = this.x * s;
        r.y = this.y * s;
        r.z = this.z * s;
      return r;
    }

        // More Maths
    bdccGeo.prototype.crossNormalize = function( b) 
    {
      var x = (this.y * b.z) - (this.z * b.y);
      var y = (this.z * b.x) - (this.x * b.z);
      var z = (this.x * b.y) - (this.y * b.x);
      var L = Math.sqrt((x * x) + (y * y) + (z * z));
      var r = new bdccGeo(0,0);
      r.x = x / L;
      r.y = y / L;
      r.z = z / L;
      return r;
    }

    // point on opposite side of the world to this point
    bdccGeo.prototype.antipode = function() 
    {
      return this.scale(-1.0);
    }






        //distance in radians from this point to point v2
    bdccGeo.prototype.distance = function( v2) 
    {
      return Math.atan2(v2.crossLength(this), v2.dot(this));
    }

    //returns in meters the minimum of the perpendicular distance of this point from the line segment geo1-geo2
    //and the distance from this point to the line segment ends in geo1 and geo2 
    bdccGeo.prototype.distanceToLineSegMtrs = function(geo1, geo2)
    {            

      //point on unit sphere above origin and normal to plane of geo1,geo2
      //could be either side of the plane
      var p2 = geo1.crossNormalize(geo2); 

      // intersection of GC normal to geo1/geo2 passing through p with GC geo1/geo2
      var ip = bdccGeoGetIntersection(geo1,geo2,this,p2); 

      //need to check that ip or its antipode is between p1 and p2
      var d = geo1.distance(geo2);
      var d1p = geo1.distance(ip);
      var d2p = geo2.distance(ip);
      //window.status = d + ", " + d1p + ", " + d2p;
      if ((d >= d1p) && (d >= d2p)) 
        return bdccGeoRadiansToMeters(this.distance(ip));
      else
      {
        ip = ip.antipode(); 
        d1p = geo1.distance(ip);
        d2p = geo2.distance(ip);
      }
      if ((d >= d1p) && (d >= d2p)) 
        return bdccGeoRadiansToMeters(this.distance(ip)); 
      else 
        return bdccGeoRadiansToMeters(Math.min(geo1.distance(this),geo2.distance(this))); 
    }

        // distance in meters from GLatLng point to GPolyline or GPolygon poly
        function bdccGeoDistanceToPolyMtrs(poly, point)
        {
            var d = 999999999;
            var i;
            var p = new bdccGeo(point.lat(),point.lng());
            for(i=0; i<(poly.getPath().getLength()-1); i++)
                 {
                    var p1 = poly.getPath().getAt(i);
                    var l1 = new bdccGeo(p1.lat(),p1.lng());
                    var p2 = poly.getPath().getAt(i+1);
                    var l2 = new bdccGeo(p2.lat(),p2.lng());
                    var dp = p.distanceToLineSegMtrs(l1,l2);
                    if(dp < d)
                        d = dp;    
                 }
             return d;
        }

        // get a new GLatLng distanceMeters away on the compass bearing azimuthDegrees
        // from the GLatLng point - accurate to better than 200m in 140km (20m in 14km) in the UK

        function bdccGeoPointAtRangeAndBearing (point, distanceMeters, azimuthDegrees) 
        {
             var latr = point.lat() * Math.PI / 180.0;
             var lonr = point.lng() * Math.PI / 180.0;

             var coslat = Math.cos(latr); 
             var sinlat = Math.sin(latr); 
             var az = azimuthDegrees* Math.PI / 180.0;
             var cosaz = Math.cos(az); 
             var sinaz = Math.sin(az); 
             var dr = distanceMeters / 6378137.0; // distance in radians using WGS84 Equatorial Radius
             var sind = Math.sin(dr); 
             var cosd = Math.cos(dr);

            return new google.maps.LatLng(Math.asin((sinlat * cosd) + (coslat * sind * cosaz)) * 180.0 / Math.PI,
            (Math.atan2((sind * sinaz), (coslat * cosd) - (sinlat * sind * cosaz)) + lonr) * 180.0 / Math.PI); 
        }
var映射路径;
风险价值点;
var centerMAP=new google.maps.LatLng(-7.402438110.446957);
函数gLatLngFromEN(e,n){
var ogbLL=NEtoLL(e,n);
var pc=OGBToWGS84(ogbLL.lat,ogbLL.lon,0);
返回新的google.maps.LatLng(pc.lat,pc.lon);
}
函数routeMap(){
mapRoute=new google.maps.Map(document.getElementById('mapRoute'){
中心:中心地图,
缩放:14,
mapTypeId:google.maps.mapTypeId.SATELLITE
});
地图路线设置中心(gLatLngFromEN(469000,169000),13);
var rtPoints=新数组();
推(格拉特朗弗罗门(468000,168000));
推(格拉特朗弗罗门(468000,170000));
推(格拉特朗弗罗门(470000,170000));
推压(gLatLngFromEN(470000168000));
var rtPoly=new google.maps.Polyline({
路径:rtPoints,
strokeColor:#0000FF“,
冲程重量:3,
地图:地图路线
});
var container=document.createElement(“div”);
container.style.fontFamily='Arial';
container.style.fontSize='XX Small';
var ptr=document.createElement(“输入”);
ptr.style.width=“100px”;
ptr.type=“文本”;
ptr.readOnly=true;
ptr.id=“distPtr”;
子容器(ptr);
document.getElementById(“控件”).appendChild(容器);
google.maps.event.addListener(mapRoute,'mousemove',函数(点){
document.getElementById('distPtr')。value=Math.round(bdccGeoDistanceToPolyMtrs(rtPoly,point.latLng));
});
}
google.maps.event.addDomListener(窗口'load',routeMap);
//用于查找lat/lng点和lat/lng点多段线之间的距离(以米为单位)的代码
//全部在WGS84中。免费使用。
//
//比尔·查德威克2007
//更新至谷歌地图API v3,Lawrence Ross 2014
//根据bdccGeo的纬度和经度(以度为单位)构建bdccGeo
功能bdccGeo(横向、纵向)
{
varθ=(lon*Math.PI/180.0);
var rlat=BDCCGeocentriclatide(纬度*Math.PI/180.0);
var c=数学cos(rlat);
x=c*Math.cos(θ);
y=c*Math.sin(θ);
this.z=Math.sin(rlat);
}
bdccGeo.prototype=新的bdccGeo();
//内部辅助函数=========================================
//从地理纬度转换为地心纬度(弧度)。
功能BDCCGeocentriclatude(地理中心)
{
var展平=1.0/298.257223563;//WGS84
var f=(1.0-展平)*(1.0-展平);
返回Math.atan((Math.tan(地理位置)*f));
}
//从地心坐标转换为地理纬度(弧度)
功能BDCCGeoGeographicalTitute(地球中心论)
{
var展平=1.0/298.257223563;//WGS84
var f=(1.0-展平)*(1.0-展平);
返回Math.atan(Math.tan(地心引力)/f);
}
//返回两个大图的两个对交点
//由圆弧geo1到geo2定义的圆,以及
//geo3至geo4。返回一个点作为地理位置,使用.antipode获取另一个点
功能bdccGeoGetIntersection(geo1、geo2、geo3、geo4)
{
var geoCross1=geo1.crossNormalize(geo2);
var geoCross2=geo3.crossNormalize(geo4);
返回geoCross1.crossNormalize(geoCross2);
}
//从弧度到米
函数BDCCG测地仪(rad)
{
返回rad*6378137.0;//WGS84赤道半径(米)
}
//从米到弧度
函数bdccGeoMetersToRadians(m)
{
返回m/6378137.0;//WGS84赤道半径(米)
}
//性质=================================================
bdccGeo.prototype.getLatitudeRadians=函数()
{
return(bdccgeographicalClatitude)(Math.atan2(this.z,
sqrt((this.x*this.x)+(this.y*this.yщщ));
}
bdccGeo.prototype.getLongitudeRadians=函数()
{
返回(Math.atan2(this.y,this.x));
}
bdccGeo.prototype.getLatitude=函数()
{
返回这个.getLatitudeRadians()*180.0/Math.PI;
}
bdccGeo.prototype.getLongitude=函数()
{
返回这个.getLongituderAdans()*180.0/Math.PI;
}
//方法=================================================
//数学
bdccGeo.prototype.dot=函数(b)
{
返回((this.x*b.x)+(this.y*b.y)+(this.z*b.z));
}
//更多的数学
bdccGeo.prototype.crossLength=函数(b)
{
var x=(this.y*b.z)-(this.z*b.y);
var line = turf.lineString(Your polyline coordinates in GeoJson array);
var pt = turf.point([Marker_Lon, Marker_Lat]);
var snapped = turf.pointOnLine(line, pt);
var pstnOnLine = { lat: snapped.geometry.coordinates[1], lng: snapped.geometry.coordinates[0] };
var distToLine = snapped.properties.dist