在谷歌地图上绘制一个点的半径

我正在使用谷歌地图 API 并添加了标记。现在我要在每个标记周围增加10英里的半径,这意味着一个圆在缩放时表现得恰当。我不知道如何做到这一点,似乎这不是一件普通的事情。

我发现了一个看起来不错的例子,你也可以看看谷歌纬度。在那里,他们使用一个半径标记,就像我想要他们。

更新: Google Latitude 使用了可缩放的 一幅画面,这将如何工作? < sub > < sup > (功能已弃用)

280080 次浏览

It seems that the most common method of achieving this is to draw a GPolygon with enough points to simulate a circle. The example you referenced uses this method. This page has a good example - look for the function drawCircle in the source code.

In spherical geometry shapes are defined by points, lines and angles between those lines. You have only those rudimentary values to work with.

Therefore a circle (in terms of a a shape projected onto a sphere) is something that must be approximated using points. The more points, the more it'll look like a circle.

Having said that, realize that google maps is projecting the earth onto a flat surface (think "unrolling" the earth and stretching+flattening until it looks "square"). And if you have a flat coordinate system you can draw 2D objects on it all you want.

In other words you can draw a scaled vector circle on a google map. The catch is, google maps doesn't give it to you out of the box (they want to stay as close to GIS values as is pragmatically possible). They only give you GPolygon which they want you to use to approximate a circle. However, this guy did it using vml for IE and svg for other browsers (see "SCALED CIRCLES" section).

Now, going back to your question about Google Latitude using a scaled circle image (and this is probably the most useful to you): if you know the radius of your circle will never change (eg it's always 10 miles around some point), then the easiest solution would be to use a GGroundOverlay, which is just an image url + the GLatLngBounds the image represents. The only work you need to do then is cacluate the GLatLngBounds representing your 10 mile radius. Once you have that, the google maps api handles scaling your image as the user zooms in and out.

I've had this problem in the past, so I bookmarked this discussion.

To summarize it, you can:

  1. Take a look at this circle filter's source code and figure out how to incorporate it into your project.
  2. Draw a GPolygon with enough points to simulate a circle.
  3. Generate a KML file by modifying http://www.nearby.org.uk/google/circle.kml.php?radius=30miles&lat=40.173&long=-105.1024 and then importing it. In Google Maps, you can just paste the URI in the search box and it will display on the map. I'm not sure how you might do it using the API though.

I have just written a blog article that addresses exactly this, which you may find useful: http://seewah.blogspot.com/2009/10/circle-overlay-on-google-map.html

Basically, you need to create a GGroundOverlay with the correct GLatLngBounds. The tricky bit is in working out the southwest corner coordinate and the northeast corner coordinate of this imaginery square (the GLatLngBounds) bounding this circle, based on the desired radius. The math is quite complicated, but you can just refer to getDestLatLng function in the blog. The rest should be pretty straightforward.

For a API v3 solution, refer to:

http://blog.enbake.com/draw-circle-with-google-maps-api-v3

It creates circle around points and then show markers within and out of the range with different colors. They also calculate dynamic radius but in your case radius is fixed so may be less work.

Using the Google Maps API V3, create a Circle object, then use bindTo() to tie it to the position of your Marker (since they are both google.maps.MVCObject instances).

// Create marker
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(53, -2.5),
title: 'Some location'
});


// Add circle overlay and bind to marker
var circle = new google.maps.Circle({
map: map,
radius: 16093,    // 10 miles in metres
fillColor: '#AA0000'
});
circle.bindTo('center', marker, 'position');

You can make it look just like the Google Latitude circle by changing the fillColor, strokeColor, strokeWeight etc (full API).

See more source code and example screenshots.