Google Maps API v3地理编码

时间:2011-03-17 15:07:29

标签: javascript google-maps google-maps-api-3 google-geocoder

以下是您的帮助。我正在使用下面的JS代码来显示带有可调整大小的圆形叠加层的Google Map,以输出中心点坐标,半径和边界框:

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进行地理编码并设置为中心点上面的脚本,没有打破当前的功能。

根据要求,上面有here的jsFiddle。您将看到用户可以将标记拖动到输出位置,距离和边界;但是我要添加的是能够在表单中输入一个位置,在提交时进行地理编码,生成的坐标用于重新定位中心标记。

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

3 个答案:

答案 0 :(得分:2)

以下是JSFiddle Demo:并输入邮政编码(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()和lng 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";
}

<强>更新。请检查JSFiddle演示并输入zipcode(30084)进行测试:

要在此设置当前的RadiusWidget和谷歌地图标记是修改后的代码。您无需修改​​当前窗口小部件的原型以使事情复杂化。你可以调用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');
    }
});

答案 1 :(得分:1)

如果你将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);
        }
    });
    ...

免责声明:这只是我的头脑,没有经过测试,我从未使用过这些课程。

答案 2 :(得分:-1)

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