Google 地图 API v3 地理编码
我们将非常感谢您对以下内容的帮助。我使用下面的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是 JSFiddle 演示: 并输入邮政编码 (30084) 进行测试:
这是初始标记HTML 的:
以下是如何根据输入获取地理编码信息,并且在地理编码的回调函数中,您可以设置 DistanceWidget 的中心。 responseResult 将通过调用
responses[0].geometry.location.lat()
为您提供 lat,并通过responses[0].geometry.location.lng()
为您提供 lng:更新。请检查 JSFiddle 演示并输入邮政编码 (30084) 进行测试:
要设置当前的 RadiusWidget 和 google 地图标记,这里是修改后的代码。您不需要修改当前小部件的原型以使事情变得复杂。您只需调用 MVCObject 的 set 选项并使用实例化的 distancewidget 访问地图即可:
Here is the JSFiddle Demo: and type in zipcode (30084) to test it:
Here is the initial markup of the HTML:
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 byresponses[0].geometry.location.lng()
: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:
如果您将 DistanceWidget 中的标记更改为实例变量,并创建一个对该标记进行操作的 setPosition() 方法,我认为您应该能够执行您想要的操作;
你的 init() 函数就变成了;
免责声明:这只是我的想法,未经测试,而且我从未使用过这些课程。
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;
And your init()-function becomes;
DISCLAIMER: This is just from the top of my head, not tested plus I've never worked with these classes.
此处有一个教程,展示了如何获取地理编码和使用 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