0

我正在尝试编写一个简单地在地图上绘制圆圈的函数。我基本上遵循这里给出的代码。这是我的实际代码:

using attempt2.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Device.Location;
using System.Windows;
using Windows.Foundation;
using Windows.UI.Xaml.Controls.Maps;
using Windows.Devices.Geolocation;
using Windows.Services.Maps;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Shapes;
using System.Device.Location;

namespace attempt2
{
    class MapsClass
{

    //computes a point on the perimeter given an arbitrary point and distance

    public GeoCoordinate getDistanceBearing(this GeoCoordinate point, double distance, double bearing = 180)
    {
        double radius = Convert.ToDouble(this.Set.container.Values["Radius"]);

        const double degreestoRadian = Math.PI / 180;
        const double radiantoDegrees = 180 / Math.PI;
        const double earthRadius = 6378137.0;

        var latA = point.Latitude * degreestoRadian;
        var longA = point.Longitude * degreestoRadian;
        var angularDistance = distance / earthRadius;
        var trueCourse = bearing * degreestoRadian;

        var lat = Math.Asin(Math.Sin(latA) * Math.Cos(angularDistance) + Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));

        var dlon = Math.Atan2(Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
            Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));

        var lon = ((longA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

        var result = new GeoCoordinate(lat * radiantoDegrees, lon * radiantoDegrees);

        return result;
    }

    //adds up a series of those points to create a circle

    public static IList<GeoCoordinate> GetCirclePoints(this GeoCoordinate center,
                               double radius, int nrOfPoints = 50)
    {
        var angle = 360.0 / nrOfPoints;
        var locations = new List<GeoCoordinate>();
        for (var i = 0; i <= nrOfPoints; i++)
        {
            locations.Add(center.getDistanceBearing(radius, angle * i));
        }
        return locations;
    }

    //draws the circle on the map

    private void MainPageLoaded()
    {
        if (this.Data.CurrentOrNot == false)     //searched location
        {
            var location = this.Data.SearchedLocation;
            Map.Center = location;
            Map.ZoomLevel = 16;

            var fill = Windows.UI.Color.FromArgb(50, 100, 0, 100);
            var stroke = Windows.UI.Color.FromArgb(150, 250, 0, 0);
            fill.A = 80;
            stroke.A = 80;
            var circle = new MapPolygon
            {
                StrokeThickness = 2,
                FillColor = fill,
                StrokeColor = stroke,
                StrokeDashed = false,
            };

            foreach (var p in location.GetCirclePoints(150))
            {
                circle.Path.Add(p);
            }

            Map.MapElements.Add(circle);


        } else
        {
            var location = this.Data.CurrentLocation;
            Map.Center = location;
            Map.ZoomLevel = 16;

            var fill = Windows.UI.Color.FromArgb(50, 100, 0, 100);
            var stroke = Windows.UI.Color.FromArgb(150, 250, 0, 0);
            fill.A = 80;
            stroke.A = 80;
            var circle = new MapPolygon
            {
                StrokeThickness = 2,
                FillColor = fill,
                StrokeColor = stroke,
                StrokeDashed = false,
            };

            foreach (var p in location.GetCirclePoints(150))
            {
                circle.Path.Add(p);
            }

            Map.MapElements.Add(circle);

        }         

    }

我得到的唯一错误是在我调用其中一种方法时的行locations.Add(center.getDistanceBearing(radius, angle * i));中,特别是 line 和foreach (var p in location.GetCirclePoints(150)). Visual Studio 给了我错误

'System.Device.Location.GeoCoordinate' 不包含'getDistanceBearing' 的定义,并且找不到接受'System.Device.Location.GeoCoordinate' 类型的第一个参数的扩展方法'getDistanceBearing'(您是否缺少使用指令还是汇编参考?)

当我引用 GetCirclePoints 时出现完全相同类型的错误。但是,当我已经定义了方法时,为什么它会给我这些错误呢?为什么在我提供的示例中基本上相同的代码显然有效?

4

2 回答 2

0

扩展方法应该是类中static的方法static

MapsClass并且getDistanceBearing不是静态的

您可以将您的方法用作常用方法

于 2015-03-14T19:53:59.483 回答
0

您没有遵循扩展方法的规则。这些类和方法也必须标记为静态。一个简单的例子:

public static class Extension
{
    const string _DefaultBasePath = @"C:\Users\stuyckp\Documents\Visual Studio 2013\Projects\WPF\Interstone";
    private static string _BasePath = null;
    public static string getFullPath(this string relativePath)
    {
        if (relativePath == null) return null;
        string path = BasePath;
        if (!path.EndsWith("\\") && !relativePath.StartsWith("\\")) path += "\\";
        return path + relativePath;
    }

    static private string BasePath
    {
        get
        {
            if (_BasePath != null) return _BasePath;

            try
            {
                Configuration cs = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                ConfigurationSectionGroup g = cs.SectionGroups["applicationSettings"];
                ClientSettingsSection s
                    = (from ConfigurationSection section in g.Sections
                        where section is ClientSettingsSection
                        select section).FirstOrDefault() as ClientSettingsSection;
                _BasePath = s.Settings.Get("BasePath").Value.ValueXml.InnerText;
            }
            catch
            {
                _BasePath = _DefaultBasePath;
            }

            return _BasePath;
        }
    }
}

不要组合任何东西,仅将这些静态类用于扩展方法本身所需的代码。这有效地使类中的几乎所有内容都成为静态:私有变量,辅助方法,...

所以你需要这样的东西:

public static class MapsClass{
//computes a point on the perimeter given an arbitrary point and distance

public static GeoCoordinate getDistanceBearing(this GeoCoordinate point, double distance, double bearing = 180)
{
    double radius = Convert.ToDouble(this.Set.container.Values["Radius"]);

    const double degreestoRadian = Math.PI / 180;
    const double radiantoDegrees = 180 / Math.PI;
    const double earthRadius = 6378137.0;

    var latA = point.Latitude * degreestoRadian;
    var longA = point.Longitude * degreestoRadian;
    var angularDistance = distance / earthRadius;
    var trueCourse = bearing * degreestoRadian;

    var lat = Math.Asin(Math.Sin(latA) * Math.Cos(angularDistance) + Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));

    var dlon = Math.Atan2(Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
        Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));

    var lon = ((longA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

    var result = new GeoCoordinate(lat * radiantoDegrees, lon * radiantoDegrees);

    return result;
}

//adds up a series of those points to create a circle

public static IList<GeoCoordinate> GetCirclePoints(this GeoCoordinate center,
                           double radius, int nrOfPoints = 50)
{
    var angle = 360.0 / nrOfPoints;
    var locations = new List<GeoCoordinate>();
    for (var i = 0; i <= nrOfPoints; i++)
    {
        locations.Add(center.getDistanceBearing(radius, angle * i));
    }
    return locations;
}
于 2015-03-14T19:54:13.200 回答