2016-04-14 8 views
0

Ich habe ein WPF-Benutzersteuerelement, mit dem der Benutzer ein Rechteck auf dem Kartenbereich zeichnen kann, um einen Bereich zum Herunterladen von Hintergrundbild-Kacheln von einem Webdienst zu definieren. Die Fliesen sind in Lat lang 1x1 Grad.Herunterladen von sich überschneidenden, aber nicht duplizierenden Karten-Download-Kacheln aus einer Liste von Punkten?

Dies funktioniert, ich gebe einen Punkt als Parameter & herunterladen Sie die Kachel. Jedoch versuche ich nun, eine List<Point> für jede Ecke des benutzerdefinierten Rechtecks ​​& zu übergeben, daher zu bestimmen, welche Kacheln jeden Punkt schneiden. Dies funktioniert in einer Weise verändern jedoch, wenn der Benutzer ein Rechteck vollständig innerhalb einer einzelnen Kachel definiert dann die gleiche Kachel 4 mal heruntergeladen (einmal für jeden Punkt):

ForEach(point in rectanglePointsList) 
{ 
    DownloadTile(point); 
} 

Ich brauche über die Punkte iterieren & festzustellen, ob Lade die folgende Kachel herunter oder nicht. Dieser Code ist dumm zu den Kacheln, ich habe nur die Punktparameter, die ich übergebe. Ein Kollege schlug eine verschachtelte for-Schleife vor, wobei ich die X & Y von jedem Punkt, & max & dann irgendwie feststellen, ob a Die Kachel sollte heruntergeladen werden in dem Wissen, dass die Kacheln immer 1x1 Grad sind. Gibt es einen Algorithmus, um dies zu erreichen? Ich weiß nicht wirklich, wo ich anfangen soll.

List<int>xValuesList = new List<int>(); 
List<int> yValuesList = new List<int>(); 

ForEach(point in RectanglePointsList) 
{ 
    xValuesList.Add(Convert.ToInt32(point.X); 
    yValuesList.Add(Convert.ToInt32(point.Y); 
} 

int maxX = xValuesList.Select(value => value.X).Max(); 
int maxY = yValuesList.Select(value => value.Y).Max(); 

//Lost after here... 
+0

Wie ist die Indexierung Ihrer Kartenkacheln? Fängt es an der oberen linken Ecke an, d.h. die Kachel bei (0,0) ist bei Länge -180 und Breite 90? – Clemens

Antwort

1

Hier ist eine schnelle Probe: D

  • wählt eine Gruppe von Fliesen
  • ihnen oder nicht in dem Cache
  • zeigt fügt die ein unterstützt oder nicht
  • wurden hinzugefügt einzelner Mausklick, keine Notwendigkeit, ein Rechteck zu zeichnen
  • e ncompasses ausgewählte Fliesen, egal wo Sie/Ende beginnen

Hier habe ich auf den ersten Zweier geklickt haben, dieses Mal habe ich ein Rechteck um die Zweier unten umfasst gezeichnet haben, haben sie hinzugefügt zweimal nicht.

enter image description here

XAML:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:WpfApplication1" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     x:Name="Window" 
     Title="MainWindow" 
     Width="525" 
     Height="350" 
     Background="Transparent" 
     SnapsToDevicePixels="True" 
     UseLayoutRounding="True" 
     mc:Ignorable="d"> 
    <Grid /> 
</Window> 

Code:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Windows; 
using System.Windows.Input; 
using System.Windows.Media; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window 
    { 
     private readonly HashSet<Int32Point> _set = new HashSet<Int32Point>(); 
     private readonly int columns = 10; 
     private readonly int rows = 10; 
     private bool _down; 
     private Point _position1; 
     private Point _position2; 
     private Size size = new Size(500, 500); 

     public MainWindow() 
     { 
      InitializeComponent(); 
      MouseDown += MainWindow_MouseDown; 
      MouseMove += MainWindow_MouseMove; 
      MouseUp += MainWindow_MouseUp; 
     } 

     private void MainWindow_MouseUp(object sender, MouseButtonEventArgs e) 
     { 
      _down = false; 
      InvalidateVisual(); 

      // find rects selected 
      var x1 = (int) Math.Floor(_position1.X/(size.Width/columns)); 
      var y1 = (int) Math.Floor(_position1.Y/(size.Height/rows)); 
      var x2 = (int) Math.Ceiling(_position2.X/(size.Width/columns)); 
      var y2 = (int) Math.Ceiling(_position2.Y/(size.Height/rows)); 
      var w = x2 - x1; 
      var h = y2 - y1; 

      var builder = new StringBuilder(); 
      for (var y = 0; y < h; y++) 
      { 
       for (var x = 0; x < w; x++) 
       { 
        var int32Point = new Int32Point(x1 + x, y1 + y); 
        var add = _set.Add(int32Point); 
        if (add) 
        { 
         // download image !!! 
        } 
        else 
        { 
         // image already downloaded, do something ! 
        } 
        builder.AppendLine(string.Format("{0} : {1}", int32Point, (add ? "added" : "ignored"))); 
       } 
      } 
      MessageBox.Show(builder.ToString()); 
     } 

     private void MainWindow_MouseMove(object sender, MouseEventArgs e) 
     { 
      _position2 = e.GetPosition(this); 
      InvalidateVisual(); 
     } 

     private void MainWindow_MouseDown(object sender, MouseButtonEventArgs e) 
     { 
      _position1 = e.GetPosition(this); 
      _down = true; 
     } 

     protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) 
     { 
      InvalidateVisual(); 
     } 

     protected override void OnRender(DrawingContext drawingContext) 
     { 
      // draw a mini-map 
      for (var y = 0; y < rows; y++) 
      { 
       for (var x = 0; x < columns; x++) 
       { 
        var color = Color.FromRgb((byte) ((double) x/columns*255), (byte) ((double) y/rows*255), 255); 
        var brush = new SolidColorBrush(color); 
        var w = size.Width/columns; 
        var h = size.Height/rows; 
        var rect = new Rect(w*x, h*y, w, h); 
        drawingContext.DrawRectangle(brush, null, rect); 
       } 
      } 

      // draw selection rectangle 
      if (_down) 
      { 
       drawingContext.DrawRectangle(null, new Pen(new SolidColorBrush(Colors.White), 2.0), 
        new Rect(_position1, _position2)); 
      } 
     } 

     private struct Int32Point 
     { 
      public readonly int X, Y; 

      public Int32Point(int x, int y) 
      { 
       X = x; 
       Y = y; 
      } 

      public override string ToString() 
      { 
       return $"X: {X}, Y: {Y}"; 
      } 
     } 
    } 
} 

Gehen Sie weiter und verbessern Sie auf der!