创建按比例缩放的地图圆

发布于 2024-10-09 19:34:11 字数 368 浏览 5 评论 0原文

与此类似的问题已经在这里被问过很多次了,但似乎没有一个能准确地给我我想要的东西。我正在 Windows Phone 上使用 Bing 地图控件,我想添加一个可以随着缩放变化正确缩放的椭圆。这可以使用多段线和多边形来完成,但没有从 MapShapeBase 派生的椭圆类型。我已经尝试了各种方法来做到这一点,但它们需要调整像素大小并伪造数学以使其与地理坐标对齐。我想创建一个具有中心和 x/y 尺寸(以米为单位)的椭圆,并让框架完成其余的工作。看起来很简单。我是不是错过了什么地方?我的另一种方法是在多段线上绘制 365 条线段,但这看起来非常难看,而且由于中心可以移动,我需要绑定每个线段的位置。这看起来分量很重。还有其他想法吗?

[具体来说,我想添加一个“GPS 精度”指示器作为当前位置周围的圆圈。]

Similar questions to this have been asked a number of times here, but none of them seem to give me exactly what I want. I am working with the Bing Map control on Windows Phone and I'd like to add an ellipse that scales properly with zoom changes. This can be done with poly lines and polygons, but there is no ellipse type derived from MapShapeBase. I've tried various ways of doing it, but they require playing around with pixel sizes and fudging the math to make it line up with geo coordinates. I want to create an Ellipse with a center and x/y sizes in meters and have the framework do the rest. It seems so simple. Have I missed it somewhere? My other approach is to draw 365 line segments in a poly line, but that seems horribly ugly, and since the center can move, I'd need to bind the Location of every segment. That seems very heavy-weight. Any other thoughts?

[To be specific, I want to add a "GPS Accuracy" indicator as a circle around the current location.]

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

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

发布评论

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

评论(1

三月梨花 2024-10-16 19:34:11

更新

在Mango中,手机会自动显示这样一个圆圈。

原始帖子

这相当简单。您只需使用图钉控件即可进行绘图。

1) 将 MapLayer 添加到控件中:

<maps:MapLayer>
    <maps:MapPolygon Fill="Gray"
                        IsHitTestVisible="False"
                        Locations="{Binding AccuracyLocationCollection}"
                        Opacity="0.6"
                        Stroke="Black"
                        StrokeThickness="2" />
</maps:MapLayer>

2) 在 ViewModel 中添加 AccuracyLocationCollection 属性

public LocationCollection AccuracyLocationCollection
{
    get;
    set;
}

3) 在 GeoCooperativeWatcher_PositionChanged 事件处理程序中,计算圆的大小,并将值设置为 AccuracyLocationCollection

ViewModel.AccuracyLocationCollection = DrawMapsCircle(e.Position.Location);

4) DrawMapsCircle 的代码如下所示:

private static double ToRadian(双度)
{
返回度数 * (Math.PI / 180);
结果

private static double ToDegrees(double radians)
{
    return radians * (180 / Math.PI);
}

public static LocationCollection DrawMapsCircle(GeoCoordinate location)
{
    double earthRadiusInMeters = 6367.0 * 1000.0;
    var lat = ToRadian(location.Latitude);
    var lng = ToRadian(location.Longitude);
    var d = location.HorizontalAccuracy / earthRadiusInMeters;

    var locations = new LocationCollection();

    for (var x = 0; x <= 360; x++)
    {
        var brng = ToRadian(x);
        var latRadians = Math.Asin(Math.Sin(lat) * Math.Cos(d) + Math.Cos(lat) * Math.Sin(d) * Math.Cos(brng));
        var lngRadians = lng + Math.Atan2(Math.Sin(brng) * Math.Sin(d) * Math.Cos(lat), Math.Cos(d) - Math.Sin(lat) * Math.Sin(latRadians));

        locations.Add(new Location()
        {
            Latitude = ToDegrees(latRadians),
            Longitude = ToDegrees(lngRadians)
        });
    }

    return locations;
}

:(这是我家旁边的,我可以确认灰色圆圈显示的道路之间大约有 3 米)

精度圆

Update

In Mango, the phone automatically shows such a circle.

Orginal Post

It's fairly easy. You just use a Pushpin control to do the drawing with.

1) Add a MapLayer to your control:

<maps:MapLayer>
    <maps:MapPolygon Fill="Gray"
                        IsHitTestVisible="False"
                        Locations="{Binding AccuracyLocationCollection}"
                        Opacity="0.6"
                        Stroke="Black"
                        StrokeThickness="2" />
</maps:MapLayer>

2) Add the AccuracyLocationCollection property in your ViewModel

public LocationCollection AccuracyLocationCollection
{
    get;
    set;
}

3) In the GeoCoordinateWatcher_PositionChanged event handler, calculate the size of the circle, and set the value to the AccuracyLocationCollection

ViewModel.AccuracyLocationCollection = DrawMapsCircle(e.Position.Location);

4) The code for the DrawMapsCircle goes like this:

private static double ToRadian(double degrees)
{
return degrees * (Math.PI / 180);
}

private static double ToDegrees(double radians)
{
    return radians * (180 / Math.PI);
}

public static LocationCollection DrawMapsCircle(GeoCoordinate location)
{
    double earthRadiusInMeters = 6367.0 * 1000.0;
    var lat = ToRadian(location.Latitude);
    var lng = ToRadian(location.Longitude);
    var d = location.HorizontalAccuracy / earthRadiusInMeters;

    var locations = new LocationCollection();

    for (var x = 0; x <= 360; x++)
    {
        var brng = ToRadian(x);
        var latRadians = Math.Asin(Math.Sin(lat) * Math.Cos(d) + Math.Cos(lat) * Math.Sin(d) * Math.Cos(brng));
        var lngRadians = lng + Math.Atan2(Math.Sin(brng) * Math.Sin(d) * Math.Cos(lat), Math.Cos(d) - Math.Sin(lat) * Math.Sin(latRadians));

        locations.Add(new Location()
        {
            Latitude = ToDegrees(latRadians),
            Longitude = ToDegrees(lngRadians)
        });
    }

    return locations;
}

Result: (This is next to my home, I can confirm there's about 3 meters between the roads the grey circle is displaying between)

Accuracy Circle

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