Dieser Artikel wurde maschinell übersetzt.

SQL Server und MapPoint

Zusammenspiel von MapPoint 2010 und SQL Server Spatial

Eric Frost

Downloaden des Codebeispiels

Nach Bing-Karten sind zwei der offensichtlichsten Geospatial Technologien von Microsoft Microsoft MapPoint 2010 und die räumliche Funktionalität in SQL Server 2008 R2. Allerdings ist, obwohl SQL Server eine ideale Speicher für Geospatial Daten ist und MapPoint einen guten Geospatial Viewer stellt, Kommunikation zwischen den beiden nicht annähernd so einfach, wie es sein könnte.

Dieser Artikel zeigt Ihnen, wie Punkt und Polygon-Objekte von SQL Server gelesen und in MapPoint zu rendern. Wir müssen auch wie Punkte und Vielecke zurück zu SQL Server mithilfe des Entity Framework 4.0 im Lieferumfang von Visual Studio 2010 schreiben werden.

Aus Gründen der Abbildung verwenden wir “ A 's Beef ” Chicago-basierten des Unternehmens Restaurant Speicherorte und hypothetische Handel Bereiche. Im Einzelhandel Analyse und Modellierung Bereichen Handel mit verschiedenen Parametern definiert werden können und für verschiedene Ziele verwendet werden können. Sie haben in der Regel definiert als der kleinste Bereich, um einen Informationsspeicher, der Bereiche enthält, die einen bestimmten Schwellenwert – beispielsweise, wo 50 Prozent oder 75 Prozent der Kunden Leben oder arbeiten. Allen in diesem Artikel verwendeten Bereichen Handel wurden generiert mithilfe der Funktion MapPoint erstellen Drivetime Zonen so, dass Sie einen hypothetischen Handel Bereich basierend auf der Fahrt Zeiten darstellen.

Als eine Kette mit weniger als ein paar Dutzend Lagerorten AL Beef ist ein relativ kleines Unternehmen, aber die Konzepte und Techniken zum großen Einzelhändler mit Tausenden von Speicherorten und in anderen Branchen und Anwendungen angewendet werden.

Der Beispielcode, und das Dataset “ A 's Beef ” (als SQL-Skript) sind unter code.msdn.microsoft.com/mag201009Spatial-heruntergeladen.

Obwohl dies nicht allzu technische Artikel arcane Aspekte der neuesten Technologie oder Sprache verdeckt ist, dient er als eine praktische Anleitungen für eine nützliche Hochzeit allgemeine Microsoft-Technologien. Ein paar Hürden gehören die Unfähigkeit des Entity Framework direkt Geography-Objekte und die Anforderung an SQL Server räumliche gegen den Uhrzeigersinn werden Polygone verstehen, MapPoint ist nicht erforderlich. Es bleibt zu hoffen, hilft in diesem Artikel selbst erfahrene Entwickler, die möglicherweise so wechseln Sie in den Bereich Geospatial für fehlendem der früheren Erfahrungen zögern, und gleichzeitig zeigen MapPoint-Entwickler, wie SQL Server 2008 R2 erfolgreich zu nutzen.

Einrichten der Datenbank

Für die Codebeispiele in diesem Dokument folgen, downloaden Sie das SQL-Skript, und führen Sie Sie mit SQL Server die Datenbank und die Objekte einrichten. Die Daten in einer SQL Server-Datenbank namens “ Unternehmen ” gespeichert und enthält eine Tabelle, eine Ansicht und eine gespeicherte Prozedur. AL Beef Speicherorten werden in einer Tabelle mit dem Namen “ Locations ” gespeichert (siehe Abbildung 1 ).

image: The Table and View Included in the Sample Database

Abbildung 1 in der Beispieldatenbank enthalten sind die Table und View

Dies umfasst die Informationsspeicher Adressen, Attribute (z. B. ist es ein Drive-in?) und einen Speicherort Punkt Geography-Datentyp. Die hypothetische Handel Bereich Polygone werden ebenfalls in der Tabelle ein Feld namens mit den Geography-Datentyp TradeArea “ Locations ” gespeichert.

Die Ansicht vLocations macht die Point- and -Polygon Geography-Felder in Datentypen, die verstanden und Entity Framework eingelesen werden können.

Das Punkt Geography-Feld ist in Breiten- und Längengrad Felder zerlegt und zurück an den Client als Varbinary Feld übergeben. Dies liegt daran Entity Framework kann nicht direkt mit dem Datentyp der Geografie befassen, aber es kann Varbinary Felder verarbeiten. Die Anwendung kann diese Back später in Geography-Objekte konvertieren.

Hier wird die gespeicherte Prozedur UspAddLocation, der wie der Name schon sagt, zum Einfügen von neuer Speicherorten von MapPoint wieder in SQL Server verwendet wird:

CREATE VIEW [dbo].[vLocations]
AS
SELECT LocID,Location.Long As Longitude,
       Location.Lat As Latitude,
       CAST(Location AS VARBINARY(MAX)) AS Location,
       Locations.TradeArea.STAsText() As TradeAreaWKT,
       CAST(TradeArea AS VARBINARY(MAX)) AS TradeArea
FROM Locations

Wir können wieder zu dieser später stammen.

Einrichten der Anwendungs

Unser Projekt ist eine C#-Windows Forms-Anwendung, die dem MapPoint-Steuerelement enthält. Das Steuerelement ist im Lieferumfang von MapPoint 2010 und die Vollversion von MapPoint 2010 muss installiert sein, damit verfügbar sein. Datensätze Sie können mithilfe von Schaltflächen, um durch die Datensätze zu durchlaufen und zum Anzeigen des Informationsspeichers und seinen Bereich Handel navigieren. Speicher können auch durch Klicken auf den Informationsspeicher Pushpinsymbol ausgewählt werden. Das Formular enthält auch ein Kontrollkästchen im Handel Bereich als eine Konvexer Hull und eine Schaltfläche zum Hinzufügen neuer Lagerplätze anzeigen. Standardmäßig zeigt die Anwendung das Polygon, wie er in der Datenbank gespeichert ist (siehe Abbildung 2 ).

image: The Al’s Beef App, Showing the Chicago Heights Store and Territory as Defined in the Database

Abbildung 2 die Al Beef Anwendung, mit der Informationsspeicher für die Höhe in Chicago und Gebiet als in der Datenbank definierte

Wenn das Ansicht Trade Bereich unter Konvexer Rumpf Kontrollkästchen festgelegt ist, wird eine Zeile (Konvexer Hull) umgebrochen, um den Handel Bereich, vergleichbar mit der Umbruchart eines Bandes erst um das Polygon (siehe Abbildung 3 ).

image: The Chicago Heights Store, with a Convex Hull Wrapped Around the Territory Shown in Figure 2

Abbildung 3 Die Chicago Höhe-Speicher mit einem Konvexer Rumpf Wrapped um das Gebiet angezeigt, die in Abbildung 2

Bevor wir die Zuordnung Anzeige implementieren können, müssen wir Entity Data Objects hinzufügen, die auf die Datenbanktabelle und Sicht verweisen. Um das Entity Data Objects herzustellen, mit der rechten Maustaste auf die Anwendung im Projektmappen-Explorer von Visual Studio, und gehen Sie zu hinzufügen | Neues Element | Visual C#-Objekte | ADO.NET Entity Data Model. Klicken Sie auf Hinzufügen und wählen Sie aus der Datenbank generieren. Wählen Sie im Dialogfeld Datenbankobjekte auswählen die Tabelle Adressen und der Ansicht vLocations aus. Nachdem Sie auf "Fertig stellen" klicken, wird der Assistent erstellen Sie die Objekte und den Code zum Verbinden mit der Datenbank generieren.

Mit dem MapPoint-2010-Steuerelement Windows Form hinzufügen, ist es erforderlich, zunächst die MapPoint COM-Steuerelementkomponente der Visual Studio-Toolbox hinzufügen. COM nicht besonders fashionable Technologie, aber es ist ein wichtiger Bestandteil der Windows-Ökosystem weiterhin. Viele Anwendungen, einschließlich MapPoint, nur eine API über eine COM-Schnittstelle implementieren und COM-Unterstützung von Visual Studio ist nicht als Abwesend jederzeit schnell.

Öffnen Sie die Visual Studio-Toolbox und im allgemeinen Bereich mit der rechten Maustaste, und wählen Sie die Elemente auswählen. Wechseln Sie zur Registerkarte COM-Komponenten, und wählen Sie Microsoft MapPoint der 17.0. MapPoint-Control-17.0 bezeichnet MapPoint 2010 (Nordamerika oder Europa). Ältere Versionen von MapPoint (nachfolgend 2002) können auch verwendet werden, jedoch geringfügige Namensänderungen (z. B. die Symbolleiste und das Symbol für Bezeichner) werden benötigt werden.

Sowohl die AxInterop.MapPoint Interop.MapPoint Assemblys einbetten Interop Type-Eigenschaft auf False festgelegt und die lokale Kopie True.The MapPoint-Steuerelement jetzt auf das Formular gezogen und verwendet werden kann innerhalb der Anwendung.

Beim Initialisieren des Forms Map: Laden von MapPoint

Die Form Map deklariert mehrere Membervariablen, einschließlich der Datenbankverbindung Entity Framework, eine Liste der speichern-Informationen und eine parallele Liste von die Speicher geographische Informationen, die aus der Ansicht zu lesen. Variable CurLoc verfolgt die aktuelle Speicher-ID in der Anwendung, und ObjMap verweisen des Steuerelements MapPoint Map-Objekt verwendet, wie hier gezeigt:

namespace AlsBeef
{
 public partial class Map : Form
 {
  CorporateEntities db;
  List<Location> locationList;
  List<vLocation> vlocationList;
  int curLoc = -1;    // <0 indicates 'not set'
  MapPoint.Map objMap;
  MapPoint.Symbol objSymb;
  ...

Wenn das Formular erstellt wird, wird die Methode CreateNewMapObject Map-Steuerelement zu initialisieren, und öffnen eine neue Zuordnung unter Verwendung der Standardvorlage für Nordamerika Zuordnung aufgerufen. Die Symbolleisten sind festgelegt, ObjMap definiert ist und Punkt in dieser Ausgabe aktiviert ist, um als nicht zu überladen die Karte aus (siehe Abbildung 4 ). “ Themen in dieser Ausgabe ” sind MapPoint Orte, Restaurants und Theater, z. B. vordefiniert.

Abbildung 4 Erstellen eines Formulars

public Map()
{
 InitializeComponent();
 CreateNewMapObject();
}
private void CreateNewMapObject()
{
  MPctrl.NewMap(GeoMapRegion.geoMapNorthAmerica);
  object barObj = "advanced";
  MPctrl.Toolbars.get_Item(refbarObj).Visible = true;
  MPctrl.Toolbars.LargeToolbarButtons = false;
  objMap = MPctrl.ActiveMap;
  // Make sure all points of interest are turned off
  objMap.PlaceCategories.Visible = MapPoint.GeoTriState.geoFalse;
}

Load-Methode des Formulars füllt beide Listen von Speicherinformationen. Alle reguläre-geografische Informationen enthält, die LocationList und Vloc ­ AtionList liest die geografische Felder, wie durch die Datenbankansicht transformiert:

private void Map_Load(object sender, EventArgs e)
{
 db = new CorporateEntities();
 locationList = new List<Location>();
 vlocationList = new List<vLocation>();
 ObjectQuery<Location> locationQuery =
  db.Locations;
 ObjectQuery<vLocation> vlocationQuery =
  db.vLocations;
 locationList = locationQuery.ToList();
 vlocationList = vlocationQuery.ToList();
 InitMapSymb();
 InitMapPins();
 SetLocation(0);
}

Die letzten beiden Zeilen starten Sie die Anwendung effektiv durch Initialisierung der Zuordnung. Sie fügen einen PIN für jeden Speicherort (InitMapPins) und positionieren Sie die Karte und Formular-Steuerelemente, die Daten für den ersten Speicherort (SetLocation) auf.

Hinzufügen von Pins auf der Karte

Aktionen werden in der Methode InitMapPins interessanter:

private void InitMapPins()
  {
    MapPoint.Pushpin objPin = null;
    for (int i = 0; i < locationList.Count;
     i++)
    {
     MapPoint.Location objLoc =
      objMap.GetLocation(vlocationList[i].    
      Latitude.Value,
      vlocationList[i].Longitude.Value);
     objPin = objMap.AddPushpin(objLoc,   
      locationList[i].Name);
     objPin.Symbol = 145; // Red fork and knife
                         // (food, restaurant)
   }
  }

Die LocationList Schleifen, Abrufen wir die Breiten- und Längengrad Werte, die berechnet wurden und durch die Ansicht. Diese werden verwendet, um die MapPoint Location-Objekte erstellen, die dann zum Erstellen der Zuordnung Pins (MapPoint-PIN-Objekte) verwendet werden. Der Speichernamen wird für die Eigenschaft PushpinName verwendet, die später suchen, und positionieren Sie die Karte verwendet wird. Die Pins sind mit dem MapPoint integrierten rote Restaurant PIN-Symbol (Symbol # 145) dargestellt. Eine vollständige Liste der integrierten 2010 MapPoint-Symbole kann mapping-tools.com/info/pushpins/pushpins_2010.shtml-gefunden werden. Diese Seite enthält auch Links zu PIN-Auflistungen für frühere Versionen von MapPoint.

Klicken Sie auf Aktueller Datensatz positionieren und Polygone zur Zuordnung hinzufügen

Neue Datensätze ausgewählt sind, und mit die Methoden IncDecLocation und SetLocation angezeigt. IncDecLocation einfach gilt eine Schrittweite (Stk) an die aktuelle Position (CurLoc) und übergibt diese neue Datensatzposition SetLocation:

private void IncDecLocation(int cnt = 0)
{
 // Apply the increment/decrement, wrapping around if necessary
 int newLoc = (curLoc + cnt + locationList.Count) % locationList.Count;
 SetLocation(newLoc);
}

Die Routine SetLocation ist die leistungsfähigste der Anwendung. SetLocation eine neue Datensatzposition auswählt und auf der Karte angezeigt. SetLocation auch die hervorgehobene (falls vorhanden) aus dem vorigen Pin entfernt und löscht alle vorherigen Handel Bereich Polygone aus der Zuordnung (siehe Abbildung 5 ).

Abbildung 5 TheSetLocation Routine ist die leistungsfähigste App

private void SetLocation(int newLoc)
{
  MapPoint.Pushpin objPin = null;
  // Unhighlight previous pushpin
  If (curLoc>= 0)
  {
    objPin = (MapPoint.Pushpin)
     objMap.FindPushpin(locationList[curLoc].Name);
    objPin.Highlight = false;
  }
  // Clear all previous shapes
  while(objMap.Shapes.Count> 0)
  {
    objMap.Shapes[1].Delete();
  }
 
  // Set the new location
  curLoc = Math.Min( Math.Max(newLoc,0), locationList.Count-1);
  objPin = (MapPoint.Pushpin)
   objMap.FindPushpin(locationList[curLoc].Name);
  objMap.Location = objPin.Location;
...

Im nächste Abschnitt wird etwas schwierig sein. Zunächst überprüft die Anwendung den Status des Kontrollkästchens Ansicht Trade Bereich unter Konvexer Rumpf. Wenn Sie nicht festgelegt wurde, dauert die WKT (Known Text)-Zeichenfolge, die das Vieleck definiert und übergibt Sie an die benutzerdefinierte RenderPolygon-Methode analysiert und als ein Polygon auf der Karte dargestellt werden.

Wenn das Kontrollkästchen aktiviert ist, zieht das Gebiet Polygon Varbinary-Objekt und konvertiert ihn in einen Geography-Objekt mithilfe der System.IO.MemoryStream-Klasse und BinaryReader-Methode. STConvexHull ist eine der Methoden, die im Lieferumfang von SQL Server 2008; es können Sie Instanzen des geografischen Standorts oder Geometrie Daten zu ändern. STConvexHull, funktioniert nur vor allem bei Datentypen, die Geometrie. Die Unterschiede zwischen SQL Server-Geometrie und Datentypen Geography wird an anderer Stelle ausführlich behandelt, aber im Moment in Betracht ziehen, dass Daten für die Geometrie in eine flache definiert ist (2D Euclidean) kartesischen Ebene, wohingegen geografischen Daten auf der Oberfläche des spheroidal Erde mit einem sphärischen Koordinatensystem (Datum, Projektion, Nullmeridian und Maßeinheit) projiziert werden.

Der SCM-Bereich ist mit einer Geography-Feldtyp in der Datenbank gespeichert und dann die Ansicht in eine Varbinary umgewandelt. Dies muss in einer Geography-Objekt gelesen werden, die dann in ein Geometrieobjekt konvertiert werden kann, um die STConvexHull-Methode ausgeführt.

Aufgrund der kleine Bereiche abgedeckt wird, STConvexHull für das Geometrieobjekt (Ebenen) durchgeführte Berechnungen sind praktisch identisch geführt hätte hatte Konvexer Hull für das Objekt tatsächlich spheroidal Geographie berechnet.

Im nächsten Teil SetLocation der ursprünglichen Handel Bereich als einer dünnen schwarzen Linie gezeichnet wird und Konvexer Hull als eine dickere rote Linie dargestellt. Dieser Code ist in Abbildung 6 dargestellt.

Abbildung 6 Zeichnen die ursprüngliche Supply Chain Management-Fläche und Konvexer Rumpf

...
 // Draw trade area
if (checkBox1.Checked == false)
{
 RenderPolygon(vlocationList[curLoc].TradeAreaWKT);
}
else
{
  // Need to add C:\Program Files\Microsoft SQL
  // Server\100\SDK\Assemblies\Microsoft.SqlServer.Types.dl
  // to references
  SqlGeographyTradeAreaGeog = new SqlGeography();
  using (var stream = new
   System.IO.MemoryStream(vlocationList[curLoc].TradeArea))
  {
   using (var rdr = new System.IO.BinaryReader(stream))
   {
    TradeAreaGeog.Read(rdr);
   }
  }
  SqlGeometry TAConvexHullGeom = new SqlGeometry();
  TAConvexHullGeom =  
   SqlGeometry.STPolyFromText(TradeAreaGeog.STAsText(), 4326);
  TAConvexHullGeom = TAConvexHullGeom.STConvexHull();
  RenderPolygon(TradeAreaGeom.ToString(), 3355443, 0); // Gray80
  RenderPolygon(TAConvexHullGeog.ToString());
}
...

So wie sieht dieser Zeichenfolge WKT wie, und welche? RenderPolygon mit sich Sie haben bereits gesehen, die Ergebnisse ( Abbildungen 2 -und 3). In die Interna Let’s eintauchen.

WKT ist ein Open Geospatial Consortium (OGC)-Standardformat für Geospatial Vektor-Daten in Form von Text formatieren. WKT Polygon Zeichenfolge sieht folgendermaßen aus (viel abgekürzt):

POLYGON ((-111.918823979795 33.6180476378649, -111.91810682416 33.6096635553986, -111.911686453968 33.6078672297299, -111.907403888181 33.599476357922, -111.907403888181 33.6060674674809, -111.903121406212 33.6060674674809))

Das Wort “ POLYGON ” vorangestellt ist eine Liste von Koordinaten, die von zwei Sätze von runden Klammern umgeben sind. Einzelne Koordinatenpaaren sind durch Kommas getrennt. Wir verwenden die MapPoint AddPolyLine-Methode, um das Polygon auf der Karte zu zeichnen und es MapPoint-Shapes-Auflistung hinzu. Dies nimmt ein Array von MapPoint Location-Objekte als Parameter. Konvertieren der WKT-Zeichenfolge in ein Array von Objekten Speicherort ist ein halbes Dutzende Zeilen Code erforderlich. RenderPolygon führt dies durch Entfernen von “ POLYGON ” Präfix und Klammern vor die Zeichenfolge in das Kommatrennzeichen mit Koordinaten aufteilen. Einzelne Koordinaten werden dann in Paare von Double-Werten (Länge, Breite) analysiert, die zum Erstellen von MapPoint Location-Objekten verwendet werden. Der Speicherort der Objekte das resultierende Array wird dann an AddPolyline, Erstellen von neuen Polygons übergeben.

RenderPolygon hat zusätzliche Parameter für die Linienstärke und die Linienart (siehe Abbildung 7 ).

Abbildung 7 TheRenderPolygon Methode

private void RenderPolygon(string polystring, 
 int forecolor = 128, int weight = 3)
{
  polystring = polystring.Replace("POLYGON ((", "");
  polystring = polystring.Replace("))", "");
  string[] stringList = polystring.Split(',');
  MapPoint.Location[] objLoc = 
   new MapPoint.Location[stringList.Count()];
  for (int i = 0; i <stringList.Count(); i++)
  {
   string[] coords = stringList[i].Trim().Split(' ');
   objLoc[i] = objMap.GetLocation(Convert.ToDouble(coords[1]),  
    Convert.ToDouble(coords[0]), 0);
  }
  MapPoint.Shape objShape;
  objShape = objMap.Shapes.AddPolyline(objLoc);
  objShape.Line.ForeColor = forecolor;
  objShape.Line.Weight = weight;
}

Eine vollständigere RenderPolygon erlangen zusätzliche Parameter für die unabhängig davon, ob die Form ausgefüllt ist, die Farbe, den Namen eines Shapes (interner Zeichenfolge, die Shapes zugeordnet werden können) und die zOrder (in der Form vor oder hinter Straßen und andere Shapes anordnen).

Zeichnung und Anmerkungen können sowohl Benutzer von einem Programm ein MapPoint Map platziert werden. MapPoint unterstützt maximal 40 verschiedene Farben für diese Anmerkung. Obwohl in Wirklichkeit die Standardfarben der 3-Byte-RGB (verschiedene 16.777.216) unterstützen diese Zahlen lediglich eine nützliche Methode zum Angeben der Farbe zu verwenden, bieten die Programmierschnittstelle wird angezeigt. Mapping-tools.com/info/pushpins/colors.shtml-, können die 40 Farben von MapPoint unterstützt betrachtet werden.

In der Vergangenheit diese Einschränkung mit Bild Update Effizienz geholfen, doch heute es in erster Linie hilfreich Klarheit Zuordnung durch, um sicherzustellen, dass Farben unterschiedlich sind.

Wir kommen jetzt in den letzten Teil der SetLocation (siehe Abbildung 8 ).

Abbildung 8 der letzte Teil von SetLocation

...
   // Reset zoom level
   objMap.Altitude = 30;
   objPin.Highlight = true;
   Double distance;
   distance = 
     NearestLocation(curLoc) * 0.000621371192; //convert to miles
   label1.Text = "ID: " + locationList[curLoc].LocID.ToString();
   label2.Text = locationList[curLoc].Name + " - " +  
     locationList[curLoc].Format;
   label3.Text = locationList[curLoc].Address + ", " + 
     locationList[curLoc].City + ", " + locationList[curLoc].State;
   label4.Text = "Distance to next closest store: " + 
     String.Format("{0:#,0.0}", distance) + " miles";
  }
private double NearestLocation(int curLoc)
{
 SqlGeography AllLocations = new SqlGeography();
  SqlGeography CurLocation = new SqlGeography();
  for (int i = 0; i <locationList.Count; i++)
  {
    SqlGeography TempLocation = new SqlGeography();
    using (var stream = new 
     System.IO.MemoryStream(vlocationList[i].Location))
   { 
     using (var rdr = new System.IO.BinaryReader(stream))
     {
       TempLocation.Read(rdr);
     }
   }
   if (i == curLoc)
   {
     CurLocation = TempLocation;
   }
   else
   {
     AllLocations = AllLocations.STUnion(TempLocation);
   }
  }
  return (Double)AllLocations.STDistance(CurLocation); //meters
}

Dies hebt hervor, die neue PIN, legt die Vergrößerungsstufe (mithilfe des Map-Objekts Höhe-Eigenschaft), meldet die Informationsspeicher-Informationen (aus dem Array LocationList) und feststellt, dass den Abstand zur nächsten Speicherort.

Dieser Abstand wird von der NearestLocation berechnet. Dies führt eine Schleife durch die Speicherorte und die räumliche STUnion für SQL Server-Methode verwendet, um Punkte geografischen Standort in eine MultiPoint Geography-Instanz zu kombinieren. Die Ausnahme wird von den aktuellen Speicherort, die übersprungen wird, andernfalls der Abstand immer 0 (null) Meilen werden! Die Anwendung dann verwendet die STDistance-Methode, um die Entfernung in Metern zwischen den aktuellen Speicherort und die MultiPoint Geography-Instanz zu berechnen. STDistance meldet den Abstand um eine MultiPoint dem kürzesten Abstand zu einem beliebigen Punkt Komponente innerhalb der MultiPoint.

Die Schaltfläche, um einen neuen Speicherort für die Website hinzufügen entfernt alle Polygone Handel Bereich aus der Zuordnung und ändert dann einfach den Mauszeiger, in ein Fadenkreuz:

private void button1_Click(object sender, EventArgs e)
{
  // Clear all previous shapes
  while(objMap.Shapes.Count > 0)
  {
    objMap.Shapes[1].Delete();
  }
  MPctrl.MousePointer = MapPoint.GeoPointer.geoPointerCrosshair;
}

Mit MapPoint-Ereignisse behandeln, benötigt das Formular einen Ereignishandler in der Formulardesigner definiert. Die Ereignisse können hinzugefügt werden, mit dem Formular-Designer oder manuell Map.Designer.cs hinzugefügt. Zwei der Ereignisse MapPoint werden Handler hinzugefügt: SelectionChange und BeforeClick, wie in der Abbildung 9 .

Abbildung 9 Hinzufügen von Handlern auf MapPoint-Ereignisse

// 
// MPctrl
// 
this.MPctrl.Enabled = true;
this.MPctrl.Location = new System.Drawing.Point(13, 13);
this.MPctrl.Name = "MPctrl";
this.MPctrl.OcxState = 
  ((System.Windows.Forms.AxHost.State)
  (resources.GetObject("MPctrl.OcxState")));
this.MPctrl.Size = new System.Drawing.Size(674, 389);
this.MPctrl.TabIndex = 0;
this.MPctrl.SelectionChange += 
  new AxMapPoint._IMappointCtrlEvents_SelectionChangeEventHandler
 (this.MPctrl_SelectionChange);
this.MPctrl.BeforeClick += 
  new AxMapPoint._IMappointCtrlEvents_BeforeClickEventHandler
  (this.MPctrl_BeforeClick);

Das SelectionChange-Ereignis zum Erkennen, wenn der Benutzer einen PIN ausgewählt hat. Hiermit wird dann mit dieser PIN-Datensatz den aktuellen Datensatz verschieben. Abbildung 10 zeigt den Ereignishandler-Implementierung.

Abbildung 10 implementieren einen SelectionChange-Ereignishandler

private void MPctrl_SelectionChange(object sender,  
 AxMapPoint._IMappointCtrlEvents_SelectionChangeEvent e)
{
  // Has the user just selected a pushpin?
  if (e.pNewSelection is MapPoint.Pushpin)
  {
    MapPoint.Pushpin ppin = e.pNewSelection as MapPoint.Pushpin;
    // Find the corresponding location object, and select it
    for (int iloc = 0; iloc < locationList.Count; iloc++)
    {
      if (locationList[iloc].Name == ppin.Name)
      { // Found it: select, and move to it
        SetLocation(iloc);
        break;
      } 
    } 
  } 
}

Dadurch wird überprüft, dass das neu ausgewählte Objekt, tatsächlich ein PIN ist. Dann führen wir eine einfache Suche über lokale LocationList für einen übereinstimmenden Datensatz. MapPoint-Pins können doppelte Namen verfügen, damit dieser Code, der alle nimmt Pfaddatensätze (und somit Pins) eindeutige Namen haben. Sie sollten auch vergleichen, geografische Koordinaten für Situationen, in denen dies Bearbeitungsvorgängen werden kann nicht.

Der Karte BeforeClick-Ereignishandler wird die Funktionalität “ Hinzufügen neuer Speicherort ” verwendet. Der Handler überprüft, wenn der Mauszeiger die Form eines Fadenkreuzes ist – d. h., der Benutzer versucht, auf einen neuen Speicherort für die Website einfügen. Behandelt das Click-Ereignis, wenn sich der Zeiger in ein Fadenkreuz ist nicht MapPoint ermöglicht. Wenn der Mauszeiger die Form eines Fadenkreuzes ist, wird das Programm fängt die Klickaktion und einen neuen PIN an der Position des Mauszeigers über das rote Restaurant-Symbol hinzugefügt. Dinge zu vereinfachen, sondern haben Benutzer zeichnen, den Bereich Handel, verwendet die Anwendung an dieser Stelle MapPoint AddDrivetimeZone-Methode zum Generieren eines hypothetischen (Reisen-zeitbasierte) Handel-Bereichs, um den neuen Standort.

Im Interesse von SQL Server diese Form verleitet, ist das Shape zuerst in Vertices, zerlegt, die dann in ein Polygon WKT (Text) Definition umgewandelt werden. Dies wird dann an SQL Server geschrieben werden.

Übergeben Sie den Punkt und die Polygon in SQL Server, und aktualisieren die Geography-Spalten, kann nicht wir die normalen Entity Framework unterstützt gespeicherten Prozeduren verwenden, da es sich bei Geography-Datentyp nicht unterstützt wird. Da die Ausführung von beliebigen gespeicherten Prozeduren jetzt von Entity Framework 4.0 unterstützt wird, sind wir jedoch Importieren der gespeicherten Prozedur und wie eine normale Funktion ausgeführt werden kann.

Dieser Code legt die Parameter und führt dann Usp ­ AddLocation gespeicherte Prozedur:

object[] parameters =
{   
  new SqlParameter("Latitude",objLoc.Latitude),
  new SqlParameter("Longitude",objLoc.Longitude),
  new SqlParameter("PolyWKT",PolyWKT)
};
var retValue = db.uspAddLocation(objLoc.Longitude, 
 objLoc.Latitude, PolyWKT);

Letzter, diese Routine setzt die Karte (CreateNewMapObject), fragt die Liste der Speicherorte aus der Datenbank (InitMapPins) ab und wählt den neuen Informationsspeicher als der aktuelle Datensatz (SetLocation) haben:

// Re-query and re-initialize map
 ObjectQuery<Location> locationQuery = db.Locations;
 ObjectQuery<vLocation> vlocationQuery = db.vLocations;
 locationList = locationQuery.ToList();
 vlocationList = vlocationQuery.ToList();
 objMap.Saved = true;
 CreateNewMapObject();
 InitMapSymb();
 InitMapPins();
 SetLocation( locationList.Count – 1 );
 e.cancel = true;
}

Die Zeile e.cancel=true; verhindert, dass MapPoint weiter verarbeitet das Click-Ereignis. Die gespeicherte Prozedur UspAddLocation folgt (siehe Abbildung 11 ).

Abbildung 11 die UspAddLocation gespeicherte Prozedur

CREATE PROCEDURE [dbo].[uspAddLocation]
@Longitude FLOAT,
@Latitude FLOAT,
@PolyWKT NVARCHAR(MAX)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
DECLARE @NewLocID int = 0
SELECT @NewLocID = MAX(LocID)+1 FROM Locations
DECLARE @NewPoly geography
SET @NewPoly = geography::STPolyFromText(@PolyWKT,4326)
INSERT INTO Locations(LocID,Name,Address,City,State,Format,Location,TradeArea)
VALUES(@NewLocID, 'New Location ' + CAST(@NewLocID As varchar(3)), '123 Main',   
 'Anywhere', 'ST', 'Food', geography::Point(@Latitude,@Longitude,4326), 
 @NewPoly)
SELECT @NewLocID AS NewLocID
END

Sie können einen neuen Geography-Instanz und die Variablen für das Polygon vor der INSERT-Anweisung erstellt wird sehen, während der Point-Speicherort in der INSERT-Methode der Point-Methode erstellt wird. Entweder Ansatz ist gültig.

Ereignisbehandlungscode in Abbildung 12 ist zuständig für die Schaltflächen “ vorherigen ” und “ ”, Konvexer Hull Kontrollkästchen und Formular schließen – die Anwendung ist damit abgeschlossen.

Abbildung 12 Fertigstellen der Anwendung

private void prev_Click(object sender, EventArgs e)
{
  IncDecLocation(-1);
}
private void next_Click(object sender, EventArgs e)
{
  IncDecLocation(1);
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
  IncDecLocation();
}
private void Map_FormClosing(object sender, FormClosingEventArgs e)
{
  db.Dispose();
  MPctrl.ActiveMap.Saved = true;
}

Anzeigen und Bearbeiten von SQL Server-Geospatial Daten visuell

Dieser Artikel behandelt ein Großteil von Grund auf, aber es veranschaulicht eine vollständige End-to-End-Anwendung mit SQL Server, die zum Übergeben von Daten in und out mithilfe von SQL Server räumliche und MapPoint-Methoden zum Anzeigen und Bearbeiten der reale Informationen.

Die hier gezeigten Prinzipien können weitere genommen werden.Eine lokale Kopie der Daten gewährleistet schnellen Karte Updates aber wäre nicht sinnvoll für große Datasets.Für diese Situationen sollte die Daten auf Basis von Datensatz, idealerweise mit einem Mechanismus für das Zwischenspeichern abgerufen werden.

MapPoint ist in der Lage, einige nützliche Geospatial Operationen (z. B. die Zeitzone auf dem Laufwerk Berechnung), aber es fehlen viele der Geospatial Vorgänge von einem vollständigen GIS erwartet.Hier nutzen wir zwei solche Operationen, STConvexHull und STDistance, von SQL Server räumliche Erweiterungen.Andere erweiterten Funktionen die räumlichen Erweiterungen umfassen die Möglichkeit, die Länge und das Ausmaß der geographische Funktionen sowie die Suche nach Vereinigungs- und Schnittmengen von Polygonen messen.So erstellen Sie eine anspruchsvolle Gebiets-Verwaltungsanwendung, konnte diese Funktionen verwendet werden.Dies könnte Gebiete kombinieren oder Überlappungen zu suchen, in denen ein Informationsspeicher eines anderen Unternehmens cannibalizing.

Ebenso könnte Stärken des MapPoint genutzt werden.MapPoint kann offline Geocoding.In unserem Beispiel verwendet vorhandene Coor ­ Dinates, aber die MapPoint Geocoder konnte stattdessen Suchen von Adressen verwendet werden.MapPoint wird außerdem mit einer Reihe von demographischen Datenbanken auf den Kanton, Postleitzahl und Census Tract Ebenen ausgeliefert.Dieser Daten können auf einer Karte Speicher ermöglicht einfache Vergleiche durchgeführt werden sollen gezeichnet werden, z. B. wie Store Sales lokale Auffüllungen und Einnahmen Ebenen vergleichen.

Suchen im voraus, räumliche von SQL Server ist wahrscheinlich einen generationsbasierten Fortschritt in der nächsten Version von SQL Server, MapPoint-Produkt hat eine Renaissance Neuentwicklungen und Features mit den letzten beiden Versionen genießen wurde und dadurch wird festgelegt, um den Vorgang fortzusetzen.Darüber hinaus wird das Entity Framework wahrscheinlich weiter mit Unterstützung für neue Feldtypen, einschließlich räumliche Datentypen, die Kommunikation zwischen SQL Server und MapPoint zu verbessern, sollten.Zusammen genommen bilden diese Technologien eine fortlaufend weiterentwickelte stabile und leistungsfähige Plattform für die Zuordnung der Anwendungsentwicklung.

Eric Frost ist ein Microsoft MVP und Business-Anwendungsentwickler spezialisiert GIS/Zuordnung Anwendungen. Er verwaltet die aktive Microsoft Zuordnung Technologie Forum mapforums.com und eric.frost@mp2kmag.com-erreicht werden kann.

Richard Marsden ist ein Microsoft MVP und freiberuflicher Software-Entwickler. Er eine Reihe von MapPoint-Erweiterungen unter Zuordnung tools.com -verkauft und betreibt die Website GeoWeb Guru geowebguru.com .

Dank an die folgenden technischen Experten für die Überprüfung der in diesem Artikel:Bob Beauchemin,Ed KatibahundAmar Nityananda