Google 地图 API v3 地理编码

发布于 2024-10-22 05:08:29 字数 3829 浏览 7 评论 0原文

我们将非常感谢您对以下内容的帮助。我使用下面的 JS 代码来显示 Google 地图,其中带有可调整大小的圆圈叠加层,以输出中心点坐标、半径和边界框:

function DistanceWidget(map) {
this.set('map', map);
this.set('position', map.getCenter());
var marker = new google.maps.Marker({
draggable: true,
title: 'Drag to set centre',
icon: 'images/mapicon3.png'
});
marker.bindTo('map', this);
marker.bindTo('position', this);
var radiusWidget = new RadiusWidget();
radiusWidget.bindTo('map', this);
radiusWidget.bindTo('center', this, 'position');
this.bindTo('distance', radiusWidget);
this.bindTo('bounds', radiusWidget);
}
DistanceWidget.prototype = new google.maps.MVCObject();
function RadiusWidget() {
var circle = new google.maps.Circle({
fillColor: '#efefef',
fillOpacity: 0.5,
strokeColor: '#000',
strokeOpacity: 1.0,
strokeWeight: 2
});
this.set('distance', 5);
this.bindTo('bounds', circle);
circle.bindTo('center', this);
circle.bindTo('map', this);
circle.bindTo('radius', this);
this.addSizer_();
}
RadiusWidget.prototype = new google.maps.MVCObject();
RadiusWidget.prototype.distance_changed = function() {
this.set('radius', this.get('distance') * 1000);
};
RadiusWidget.prototype.addSizer_ = function() {
var sizer = new google.maps.Marker({
draggable: true,
title: 'Drag to expand search area',
icon: 'images/mapicon2.png'
});
sizer.bindTo('map', this);
sizer.bindTo('position', this, 'sizer_position');
var me = this;
google.maps.event.addListener(sizer, 'drag', function() {
me.setDistance();
});
};
RadiusWidget.prototype.center_changed = function() {
var bounds = this.get('bounds');
if (bounds) {
var lng = bounds.getNorthEast().lng();
var position = new google.maps.LatLng(this.get('center').lat(), lng);
this.set('sizer_position', position);
}
};
RadiusWidget.prototype.distanceBetweenPoints_ = function(p1, p2) {
if (!p1 || !p2) {
return 0;
}
var R = 6371;
var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
RadiusWidget.prototype.setDistance = function() {
var pos = this.get('sizer_position');
var center = this.get('center');
var distance = this.distanceBetweenPoints_(center, pos);
var distance = Math.round(distance*100)/100
this.set('distance', distance);
};
function init() {
var mapDiv = document.getElementById('map-canvas');
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(geoip_latitude(), geoip_longitude()), zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var distanceWidget = new DistanceWidget(map);
google.maps.event.addListener(distanceWidget, 'distance_changed', function() {
displayInfo(distanceWidget);
});
google.maps.event.addListener(distanceWidget, 'position_changed', function() {
displayInfo(distanceWidget);
});
mapDiv.style.width = (viewportwidth)+"px";
mapDiv.style.height = (viewportheight)+"px";
}
function displayInfo(widget) {
var info = document.getElementById('info');
info.innerHTML = '<form action="/search" method="post"><input type="hidden" name="position" value="' + widget.get('position') + '" /><input type="hidden" name="distance" value="' + widget.get('distance') + '" /><input type="hidden" name="bounds" value="' + widget.get('bounds') + '" /><input type="submit" value="Submit" /></form>';
}
google.maps.event.addDomListener(window, 'load', init);

这很好用,但我不知道如何添加地理编码为此,可以输入地名(通过表单发布),使用 Google Maps API 进行地理编码并在上述脚本中设置为中心点,而不会破坏当前功能。

根据要求,此处有一个 jsFiddle。您将看到用户可以拖动标记来输出位置、距离和边界;然而,我想添加的是在表单中输入位置的能力,该位置在提交时进行地理编码,并使用生成的坐标来重新定位中心标记。

非常感谢任何帮助,谢谢。

your help would be much appreciated with the following. I am using the JS code below to display a Google Map with a re-sizable circle overlay to output a centre point co-ordinate, radius and bounding box:

function DistanceWidget(map) {
this.set('map', map);
this.set('position', map.getCenter());
var marker = new google.maps.Marker({
draggable: true,
title: 'Drag to set centre',
icon: 'images/mapicon3.png'
});
marker.bindTo('map', this);
marker.bindTo('position', this);
var radiusWidget = new RadiusWidget();
radiusWidget.bindTo('map', this);
radiusWidget.bindTo('center', this, 'position');
this.bindTo('distance', radiusWidget);
this.bindTo('bounds', radiusWidget);
}
DistanceWidget.prototype = new google.maps.MVCObject();
function RadiusWidget() {
var circle = new google.maps.Circle({
fillColor: '#efefef',
fillOpacity: 0.5,
strokeColor: '#000',
strokeOpacity: 1.0,
strokeWeight: 2
});
this.set('distance', 5);
this.bindTo('bounds', circle);
circle.bindTo('center', this);
circle.bindTo('map', this);
circle.bindTo('radius', this);
this.addSizer_();
}
RadiusWidget.prototype = new google.maps.MVCObject();
RadiusWidget.prototype.distance_changed = function() {
this.set('radius', this.get('distance') * 1000);
};
RadiusWidget.prototype.addSizer_ = function() {
var sizer = new google.maps.Marker({
draggable: true,
title: 'Drag to expand search area',
icon: 'images/mapicon2.png'
});
sizer.bindTo('map', this);
sizer.bindTo('position', this, 'sizer_position');
var me = this;
google.maps.event.addListener(sizer, 'drag', function() {
me.setDistance();
});
};
RadiusWidget.prototype.center_changed = function() {
var bounds = this.get('bounds');
if (bounds) {
var lng = bounds.getNorthEast().lng();
var position = new google.maps.LatLng(this.get('center').lat(), lng);
this.set('sizer_position', position);
}
};
RadiusWidget.prototype.distanceBetweenPoints_ = function(p1, p2) {
if (!p1 || !p2) {
return 0;
}
var R = 6371;
var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
RadiusWidget.prototype.setDistance = function() {
var pos = this.get('sizer_position');
var center = this.get('center');
var distance = this.distanceBetweenPoints_(center, pos);
var distance = Math.round(distance*100)/100
this.set('distance', distance);
};
function init() {
var mapDiv = document.getElementById('map-canvas');
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(geoip_latitude(), geoip_longitude()), zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var distanceWidget = new DistanceWidget(map);
google.maps.event.addListener(distanceWidget, 'distance_changed', function() {
displayInfo(distanceWidget);
});
google.maps.event.addListener(distanceWidget, 'position_changed', function() {
displayInfo(distanceWidget);
});
mapDiv.style.width = (viewportwidth)+"px";
mapDiv.style.height = (viewportheight)+"px";
}
function displayInfo(widget) {
var info = document.getElementById('info');
info.innerHTML = '<form action="/search" method="post"><input type="hidden" name="position" value="' + widget.get('position') + '" /><input type="hidden" name="distance" value="' + widget.get('distance') + '" /><input type="hidden" name="bounds" value="' + widget.get('bounds') + '" /><input type="submit" value="Submit" /></form>';
}
google.maps.event.addDomListener(window, 'load', init);

This works great, but what I can't figure out is how to add geocoding to this, so that a place name could be entered (POSTed via a form), geocoded using Google Maps API and set as the centre point in the above script, without breaking the current functionality.

As requested, there is a jsFiddle for the above here. You will see that the user can drag the markers to output position, distance and bounds; however what I want to add is the ability to enter a location in the form, which on submit is geocoded, with the resulting co-ordinates being used to reposition the centre marker.

Any help much appreciated, thanks.

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

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

发布评论

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

评论(3

思念绕指尖 2024-10-29 05:08:29

这是 JSFiddle 演示: 并输入邮政编码 (30084) 进行测试:

这是初始标记HTML 的:

    <div id="map-canvas"></div>
    <div id="info">
    </div>
    <div id='geocode'>
         <input name="q" type="text" id="q" /><br />
         <input type="submit" value="Submit" id="geosubmit" />
    </div>

以下是如何根据输入获取地理编码信息,并且在地理编码的回调函数中,您可以设置 DistanceWidget 的中心。 responseResult 将通过调用 responses[0].geometry.location.lat() 为您提供 lat,并通过 responses[0].geometry.location.lng() 为您提供 lng:

function init() {
    var mapDiv = document.getElementById('map-canvas');
    var geocoder = new google.maps.Geocoder();
    var map = new google.maps.Map(mapDiv, {
        center: new google.maps.LatLng(51.5001524, -0.1262362),
        zoom: 11,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    var distanceWidget = new DistanceWidget(map);

    //Geocoder input section and logic
    var mySubmit = document.getElementById('geosubmit');
    var myGeoInfo = document.getElementById('q');
    mySubmit.onclick = function() {
        geocoder.geocode({
            address: myGeoInfo.value
        }, function(responses) {
            if (responses && responses.length > 0) {
                var newMarkerPos = new google.maps.LatLng(responses[0].geometry.location.lat(), responses[0].geometry.location.lng());
                distanceWidget.set('position', newMarkerPos); //sets the new position of marker
                distanceWidget.map.setCenter(newMarkerPos); //sets map's center
            } else {
                //response failed output error message
                alert('error getting geocode');
            }
        });
    }

    google.maps.event.addListener(distanceWidget, 'distance_changed', function() {
        displayInfo(distanceWidget);
    });
    google.maps.event.addListener(distanceWidget, 'position_changed', function() {
        displayInfo(distanceWidget);
    });

    mapDiv.style.width = "500px";
    mapDiv.style.height = "300px";
}

更新。请检查 JSFiddle 演示并输入邮政编码 (30084) 进行测试:

要设置当前的 RadiusWidget 和 google 地图标记,这里是修改后的代码。您不需要修改当前小部件的原型以使事情变得复杂。您只需调用 MVCObject 的 set 选项并使用实例化的 distancewidget 访问地图即可:

geocoder.geocode({
    address: myGeoInfo.value
}, function(responses) {
    if (responses && responses.length > 0) {
        var newMarkerPos = new google.maps.LatLng(responses[0].geometry.location.lat(), responses[0].geometry.location.lng());
        distanceWidget.set('position', newMarkerPos); //sets the new position of marker
        distanceWidget.map.setCenter(newMarkerPos); //sets map's center
    } else {
        //response failed output error message
        alert('error getting geocode');
    }
});

Here is the JSFiddle Demo: and type in zipcode (30084) to test it:

Here is the initial markup of the HTML:

    <div id="map-canvas"></div>
    <div id="info">
    </div>
    <div id='geocode'>
         <input name="q" type="text" id="q" /><br />
         <input type="submit" value="Submit" id="geosubmit" />
    </div>

Here is how you can get the Geocode information based on the input, and within the callback function of your geocode you can set the center of your DistanceWidget. The responseResult would give you lat by calling responses[0].geometry.location.lat() and lng by responses[0].geometry.location.lng():

function init() {
    var mapDiv = document.getElementById('map-canvas');
    var geocoder = new google.maps.Geocoder();
    var map = new google.maps.Map(mapDiv, {
        center: new google.maps.LatLng(51.5001524, -0.1262362),
        zoom: 11,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    var distanceWidget = new DistanceWidget(map);

    //Geocoder input section and logic
    var mySubmit = document.getElementById('geosubmit');
    var myGeoInfo = document.getElementById('q');
    mySubmit.onclick = function() {
        geocoder.geocode({
            address: myGeoInfo.value
        }, function(responses) {
            if (responses && responses.length > 0) {
                var newMarkerPos = new google.maps.LatLng(responses[0].geometry.location.lat(), responses[0].geometry.location.lng());
                distanceWidget.set('position', newMarkerPos); //sets the new position of marker
                distanceWidget.map.setCenter(newMarkerPos); //sets map's center
            } else {
                //response failed output error message
                alert('error getting geocode');
            }
        });
    }

    google.maps.event.addListener(distanceWidget, 'distance_changed', function() {
        displayInfo(distanceWidget);
    });
    google.maps.event.addListener(distanceWidget, 'position_changed', function() {
        displayInfo(distanceWidget);
    });

    mapDiv.style.width = "500px";
    mapDiv.style.height = "300px";
}

Update. Please check the JSFiddle demo and type in zipcode (30084) to test it:

To set your current RadiusWidget and google map marker here is the modified code. You don't need to modify the prototype of your current widget to complicate things. You can just call the MVCObject's set option and access the map by using the instantiated distancewidget:

geocoder.geocode({
    address: myGeoInfo.value
}, function(responses) {
    if (responses && responses.length > 0) {
        var newMarkerPos = new google.maps.LatLng(responses[0].geometry.location.lat(), responses[0].geometry.location.lng());
        distanceWidget.set('position', newMarkerPos); //sets the new position of marker
        distanceWidget.map.setCenter(newMarkerPos); //sets map's center
    } else {
        //response failed output error message
        alert('error getting geocode');
    }
});
甲如呢乙后呢 2024-10-29 05:08:29

如果您将 DistanceWidget 中的标记更改为实例变量,并创建一个对该标记进行操作的 setPosition() 方法,我认为您应该能够执行您想要的操作;

function DistanceWidget(map) {
    this.set('map', map);
    this.set('position', map.getCenter());

    this.marker = new google.maps.Marker({
        draggable: true,
        title: 'Drag to set centre',
        icon: 'images/mapicon3.png'
    });
    this.marker.bindTo('map', this);
    this.marker.bindTo('position', this);

    var radiusWidget = new RadiusWidget();
    radiusWidget.bindTo('map', this);
    radiusWidget.bindTo('center', this, 'position');
    this.bindTo('distance', radiusWidget);
    this.bindTo('bounds', radiusWidget);
}
DistanceWidget.prototype = new google.maps.MVCObject();
/* Add the `setMarkerPosition` method to this class */
DistanceWidget.prototype.setMarkerPosition = function(position) {
    this.marker.setPosition(position);
}

你的 init() 函数就变成了;

function init() {
    var mapDiv = document.getElementById('map-canvas');
    var map = new google.maps.Map(mapDiv, {
        center: new google.maps.LatLng(geoip_latitude(), geoip_longitude()), zoom: 11,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    var distanceWidget = new DistanceWidget(map);

    /* Set up geo-functionality */
    var geo = new google.maps.Geocoder();
    geo.geocode({address: 'Piccadilly Circus, London'}, function(results, status) {
        if (status === google.maps.GeocoderStatus.OK) {
            distanceWidget.setMarkerPosition(results[0].geometry.location);
            map.setCenter(results[0].geometry.location);
        }
    });
    ...

免责声明:这只是我的想法,未经测试,而且我从未使用过这些课程。

If you change your marker in DistanceWidget to be a instance variable instead, and create a setPosition() method operating on that marker I think you should be able to do what you want;

function DistanceWidget(map) {
    this.set('map', map);
    this.set('position', map.getCenter());

    this.marker = new google.maps.Marker({
        draggable: true,
        title: 'Drag to set centre',
        icon: 'images/mapicon3.png'
    });
    this.marker.bindTo('map', this);
    this.marker.bindTo('position', this);

    var radiusWidget = new RadiusWidget();
    radiusWidget.bindTo('map', this);
    radiusWidget.bindTo('center', this, 'position');
    this.bindTo('distance', radiusWidget);
    this.bindTo('bounds', radiusWidget);
}
DistanceWidget.prototype = new google.maps.MVCObject();
/* Add the `setMarkerPosition` method to this class */
DistanceWidget.prototype.setMarkerPosition = function(position) {
    this.marker.setPosition(position);
}

And your init()-function becomes;

function init() {
    var mapDiv = document.getElementById('map-canvas');
    var map = new google.maps.Map(mapDiv, {
        center: new google.maps.LatLng(geoip_latitude(), geoip_longitude()), zoom: 11,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    var distanceWidget = new DistanceWidget(map);

    /* Set up geo-functionality */
    var geo = new google.maps.Geocoder();
    geo.geocode({address: 'Piccadilly Circus, London'}, function(results, status) {
        if (status === google.maps.GeocoderStatus.OK) {
            distanceWidget.setMarkerPosition(results[0].geometry.location);
            map.setCenter(results[0].geometry.location);
        }
    });
    ...

DISCLAIMER: This is just from the top of my head, not tested plus I've never worked with these classes.

岁月静好 2024-10-29 05:08:29

此处有一个教程,展示了如何获取地理编码和使用 Google Maps v3 和 Jquery 进行反向地理编码

There is a tutorial here that shows how to get geocoding and reverse geocoding working with Google Maps v3 and Jquery

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