ここにあるポリゴン検索の例のビングマップに少し問題があります:
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 を返します。
ポリゴンのエッジ周辺を扱うときはうまくいかないようです。これについてもっと経験のある人は、私が間違っている場所を教えてもらえますか?
以下の完全なコード例:
これを機能させるには、 を参照する必要がありますMicrosoft.Maps.MapControl.WPF.dll
。
bing マップ コントロール マップ、ポリゴン検索出力を示すラベル、およびポリゴン内を検索できるチェックボックスを含むデモを作成しました。
多角形を作成するには、マップを右クリックして描画し、[Esc] を押して多角形の描画を終了します。次に、「左クリックで住所を検索」チェックボックスをクリックして、ポリゴン内を検索できます。
ご覧のとおり、描画したばかりのポリゴン内をクリックしたことがわかると、MSDN からのポリゴン検索が領域外に返されます!
MainWindow.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>
MainWindow.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 ポリゴンが異なるズーム レベルで同じであることをデバッグして確認しました
リスト項目