gpt4 book ai didi

c# - Bing map 多边形搜索不准确

转载 作者:太空狗 更新时间:2023-10-29 20:20:54 24 4
gpt4 key购买 nike

我在此处找到的 bing map 示例多边形搜索有点问题:

Polygon search is about halfway down this link.

  public bool polygonSearch(LocationCollection points, double lat, double lon)
{
MapPolygon poly = new MapPolygon();

int i = 0;
int j = points.Count - 1;
bool inPoly = false;

for (i = 0; i < points.Count; i++)
{
if (points[i].Longitude < lon && points[j].Longitude >= lon || points[j].Longitude < lon && points[i].Longitude >= lon)
{
if (points[i].Latitude + (lon - points[i].Longitude) / (points[j].Longitude - points[i].Longitude) * (points[j].Latitude - points[i].Latitude) < lat)
{
inPoly = !inPoly;

}
}
j = i;
}

return inPoly;



}

我使用 ViewportPointToLocation 获取鼠标坐标并在鼠标单击时添加一个图钉。

            Point mousePosition = e.GetPosition(myMap);
Microsoft.Maps.MapControl.WPF.Location pinLocation = myMap.ViewportPointToLocation(mousePosition);
// Convert the mouse coordinates to a location on the map


// The pushpin to add to the map.
Pushpin pin = new Pushpin();
pin.Location = pinLocation;
pin.Content = "Cust";
pin.Heading = 0;

// Adds the pushpin to the map
myMap.Children.Add(pin);

这是我使用多边形搜索来查看我是否在多边形内单击的地方。

polygonSearch(polygon.Locations, pin.Location.Latitude, pin.Location.Longitude))

如下图所示,我将标签设置为“配送区域内”或“区域外的客户”,具体取决于天气 polygonSearch 返回 true 或 false。

在处理多边形的边缘时似乎不起作用。有更多经验的人可以告诉我哪里错了吗?

enter image description here

下面是完整的代码示例:

您需要引用 Microsoft.Maps.MapControl.WPF.dll让这个工作。

我只制作了一个演示,其中包含 bing map 控制 map 、一个告诉我们多边形搜索输出的标签,以及一个允许您在多边形内搜索的复选框。

要制作多边形,只需右键单击要绘制的 map ,然后按“Escape”结束绘制多边形。然后您可以单击“通过左键单击搜索地址”复选框并在多边形内搜索。

正如您将看到的,当我们看到我们在刚刚绘制的多边形内单击时,来自 MSDN 的多边形搜索返回区域外!

主窗口.xaml

<Window x:Class="PolygonSearch.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"
Title="MainWindow" Height="350" Width="525" KeyDown="Window_KeyDown">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="100*"/>
</Grid.RowDefinitions>
<StackPanel>
<Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="10,10,0,0" Name="lbl_arearsult" Grid.Row="0" VerticalAlignment="Top" />
<CheckBox Content="Search Address by left click" Height="16" HorizontalAlignment="Left" Margin="10,10,0,0" Name="chk_search" VerticalAlignment="Top" />
</StackPanel>
<m:Map x:Name="myMap" Grid.Row="1" CredentialsProvider="your_bing_map_key" Mode="AerialWithLabels" MouseLeftButtonDown="myMap_MouseDown" MouseRightButtonDown="myMap_MouseRightButtonDown" KeyDown="myMap_KeyDown" />

</Grid>
</Window>

主窗口.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using Microsoft.Maps.MapControl.WPF;

namespace PolygonSearch
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
LocationCollection drawPolyPoints = new LocationCollection();

public MainWindow()
{
InitializeComponent();
}



public bool polygonSearch(LocationCollection points, double lat, double lon)
{
MapPolygon poly = new MapPolygon();

int i = 0;
int j = points.Count - 1;
bool inPoly = false;

for (i = 0; i < points.Count; i++)
{
if (points[i].Longitude < lon && points[j].Longitude >= lon || points[j].Longitude < lon && points[i].Longitude >= lon)
{
if (points[i].Latitude + (lon - points[i].Longitude) / (points[j].Longitude - points[i].Longitude) * (points[j].Latitude - points[i].Latitude) < lat)
{
inPoly = !inPoly;

}
}
j = i;
}

return inPoly;



}

private void myMap_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Escape)
{
MapPolygon polygon = new MapPolygon();
polygon.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Blue);
polygon.Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green);
polygon.StrokeThickness = 5;
polygon.Opacity = 0.7;
polygon.Locations = drawPolyPoints;
polygon.Tag = "1388_q3_polygon_5";
myMap.Children.Add(polygon);
//drawPolyPoints.Clear();

for (int p = 0; p < myMap.Children.Count; p++)
{
object entity = myMap.Children[p];
if (entity is Microsoft.Maps.MapControl.WPF.Pushpin)
{
if (((Microsoft.Maps.MapControl.WPF.Pushpin)entity).Content.ToString() == "Vertice")
myMap.Children.Remove(((Microsoft.Maps.MapControl.WPF.Pushpin)entity));
}


}
}
}

private void myMap_MouseDown(object sender, MouseButtonEventArgs e)
{
if (chk_search.IsChecked == true)
{
Point mousePosition = e.GetPosition(myMap);
Microsoft.Maps.MapControl.WPF.Location pinLocation = myMap.ViewportPointToLocation(mousePosition);
// Convert the mouse coordinates to a location on the map


// The pushpin to add to the map.
Pushpin pin = new Pushpin();
pin.Location = pinLocation;
pin.Content = "Cust";
pin.Heading = 0;

// Adds the pushpin to the map
myMap.Children.Add(pin);

bool inArea = false;
for (int p = 0; p < myMap.Children.Count; p++)
{
object entity = myMap.Children[p];


if (entity is Microsoft.Maps.MapControl.WPF.MapPolygon)
{
if (polygonSearch(((Microsoft.Maps.MapControl.WPF.MapPolygon)entity).Locations, pin.Location.Latitude, pin.Location.Longitude))
{
string[] quadAttributes = ((Microsoft.Maps.MapControl.WPF.MapPolygon)entity).Tag.ToString().Split('_');

lbl_arearsult.Content = "Within delivery area ";

inArea = true;
break;
}
else
{

inArea = false;

}

}
}
if (inArea != true)
lbl_arearsult.Content = "Customer out of area. ";
}

}

private void myMap_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
Point mousePosition = e.GetPosition(myMap);
Microsoft.Maps.MapControl.WPF.Location pinLocation = myMap.ViewportPointToLocation(mousePosition);
// Convert the mouse coordinates to a location on the map

// The pushpin to add to the map.
Pushpin pin = new Pushpin();
pin.Location = pinLocation;
pin.Content = "Vertice";

// Adds the pushpin to the map
myMap.Children.Add(pin);
drawPolyPoints.Add(pin.Location);
}

private void Window_KeyDown(object sender, KeyEventArgs e)
{
myMap_KeyDown(sender, e);
}
}
}

注意:此设计仅适用于创建 1 个多边形进行搜索,但您仍然可以直观地看到我的多边形搜索失败的地方。

编辑:

  • 非常感谢KeyboardP,我们发现如果完全放大,然后绘制多边形,然后搜索,问题就不存在了。但是如果我们绘制它,然后缩放,我们会看到同样的问题出现。

  • 我也已经调试确认LocationCollection多边形在不同的缩放级别是一样的

  • 列表项

最佳答案

我大约 6 年前写了这篇文章。这是基于标准二维几何的多边形算法中的一个简单点,不是地理空间精确算法。它适用于覆盖城市或更小区域的小多边形。大的多边形看起来不太准确。请注意, map 上两点之间的线,即使它看起来是直的,但实际上是弯曲的。一个很好的例子可以在这里找到:http://alastaira.wordpress.com/2011/06/27/geodesics-on-bing-maps-v7/

至于您的问题,如果您想单击多边形,只需使用鼠标事件即可。如果你想检查一个点是否在多边形中,那么你可以使用 WPF 中强大的 SQL 空间库,它将在多边形计算中为你提供地理空间上准确的点。您不需要连接到数据库。您只需要通过 SQL Express 免费获得的 Microsoft.SqlServer.Types.dll。您可以在 .NET 中和 Bing Maps WPF 控件中使用它。这是一个很好的起点:http://ecn.channel9.msdn.com/o9/learn/SQL2008R2TrainingKit/Labs/UsingSpatialDataInManagedCode/Lab.docx

完成此操作后,您可以简单地从多边形创建一个 SQLGeography 对象并检查您的点是否与多边形相交。

关于c# - Bing map 多边形搜索不准确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17371801/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com