<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://footheory.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Foo Theory</title><link>http://footheory.com/blogs/</link><description>Partners in Community - serving up&amp;nbsp;some ice cold Kool-Aid!</description><dc:language>en-US</dc:language><generator>CommunityServer 2007 SP2 (Debug Build: 20611.960)</generator><item><title>Investigating the new Spatial Types in SQL Server 2008 - Part 2</title><link>http://footheory.com/blogs/bennie/archive/2008/10/08/investigating-the-new-spatial-type-in-sql-server-2008-part-2.aspx</link><pubDate>Wed, 08 Oct 2008 19:32:51 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:415</guid><dc:creator>bennie</dc:creator><slash:comments>0</slash:comments><description>&lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;In the &lt;a href="http://footheory.com/blogs/bennie/archive/2008/10/05/investigating-the-new-spatial-types-in-sql-server-2008-part-1.aspx"&gt;previous part&lt;/a&gt; of this series, we talked about the importance of spatial data in our everyday lives. We talked about vector and raster data, and we explained that the current version of SQL Server 2008 focuses on two-dimensional vector data. Next, we introduced the new &lt;strong&gt;geography&lt;/strong&gt; and &lt;strong&gt;geometry&lt;/strong&gt; data types in SQL server 2008, and we took a quick detour into some important object-oriented principles.&lt;/p&gt;  &lt;p&gt;In this article, we start out by taking a look at the class hierarchies for both the geometry and the geography data types in SQL Server 2008. We will focus on the concrete classes in the class diagram which are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;font size="2" face="tahom"&gt;Point.&amp;#160; &lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;font size="2" face="tahom"&gt;LineString &lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;font size="2" face="tahom"&gt;Polygon&lt;/font&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We will also take a look at the collection classes in the object hierarchy, which allow us to store multiple instances of each type.&lt;/p&gt;  &lt;p&gt;Once we have a good grasp on the geometry and geography class hierarchy we will dive into the details of each concrete class. We will start our investigation by looking into the details of the &lt;font size="2" face="Courier New"&gt;Point&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;LineString&lt;/font&gt; class, and we will write a T-SQL script that highlights the most important features. In the process we will take a look at the three different data formats that can be used to represent spatial data:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The Well-Known-Binary&amp;#160; (&lt;a href="http://edndoc.esri.com/arcsde/9.0/general_topics/wkb_representation.htm"&gt;WKB&lt;/a&gt;) format &lt;/li&gt;    &lt;li&gt;The Well-Known-Text (&lt;a href="http://en.wikipedia.org/wiki/Well-known_text"&gt;WKT&lt;/a&gt;) format &lt;/li&gt;    &lt;li&gt;The Geography Markup Language (&lt;a href="http://en.wikipedia.org/wiki/Geography_Markup_Language"&gt;GML&lt;/a&gt;) data format. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;All of these formats are published as a standard by the Open Geospatial Consortium (&lt;a href="http://www.opengeospatial.org/"&gt;OGC&lt;/a&gt;), which is the leading standards body for geospatial and location based services.&lt;/p&gt;  &lt;h3&gt;The Geometry class hierarchy&lt;/h3&gt;  &lt;h4&gt;Overview&lt;/h4&gt;  &lt;p&gt;A class diagram showing the &lt;font size="2" face="Courier New"&gt;Geometry&lt;/font&gt; class and all of its sub-classes is shown below (note that the &lt;font size="2" face="Courier New"&gt;Geography&lt;/font&gt; class diagram is basically identical, with the &lt;font size="2" face="Courier New"&gt;Geography&lt;/font&gt; class at the root of the tree):&lt;/p&gt;  &lt;p&gt;&lt;a title="Geometry Class Diagram" href="http://www.flickr.com/photos/99548241@N00/2918867849/"&gt;&lt;img border="0" alt="Geometry Class Diagram" src="http://static.flickr.com/3202/2918867849_6193d71671.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The darker-blue shaded classes are abstract base classes, so they cannot be directly instantiated in the database engine. The light-blue shaded classes are the concrete classes that we can use directly in our T-SQL code:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;font size="2" face="Courier New"&gt;Point&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2" face="Courier New"&gt;LineString&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2" face="Courier New"&gt;Polygon&lt;/font&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Each of these single-instance classes has a collection equivalent that can contain multiple instances:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;MultiPoint&lt;/font&gt;&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2" face="Courier New"&gt;MultiLineString&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2" face="Courier New"&gt;MultiPolygon&lt;/font&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The &lt;font size="2" face="Courier New"&gt;GeomCollection&lt;/font&gt; class is an additional collection class that can contain a mixture of instances of any type (&lt;font size="2" face="Courier New"&gt;Points&lt;/font&gt;, &lt;font size="2" face="Courier New"&gt;LineStrings&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;Polygons&lt;/font&gt;).&lt;/p&gt;  &lt;h4&gt;Supported Data Formats&lt;/h4&gt;  &lt;p&gt;All of the classes in the &lt;font size="2" face="Courier New"&gt;geometry&lt;/font&gt; and the &lt;font size="2" face="Courier New"&gt;geography&lt;/font&gt; class hierarchy can be represented by three different formats:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;The Well-Known Binary (&lt;a href="http://edndoc.esri.com/arcsde/9.0/general_topics/wkb_representation.htm"&gt;WKB&lt;/a&gt;) format&lt;/strong&gt;. This is a byte-stream (binary) representation for a geography instance. This format is the preferred serialization format for those applications that need to store geospatial information in a compact, self-contained format.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;The Well-Known Text (&lt;a href="http://en.wikipedia.org/wiki/Well-known_text"&gt;WKT&lt;/a&gt;) format.&lt;/strong&gt; This is a compact, easy to read representation. Because of its user-friendly format it is the most commonly used representation for ad-hoc geospatial queries. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;The Geography Markup Language (&lt;a href="http://en.wikipedia.org/wiki/Geography_Markup_Language"&gt;GML&lt;/a&gt;) format&lt;/strong&gt;. This is an XML-based representation, which is best suited for including geospatial information in an XML document. This format is very useful for those applications that need to exchange geospatial information by means of an XML Web service. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;All of the above formats are published as standards by the &lt;a href="http://www.opengeospatial.org/"&gt;OGC&lt;/a&gt;. In the code samples that follow, we will be showing multiple examples of each format.&lt;/p&gt;  &lt;h4&gt;The Point Class&lt;/h4&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h5&gt;Basic Representation&lt;/h5&gt;  &lt;p&gt;A &lt;font size="2" face="Courier New"&gt;Point&lt;/font&gt; is a zero-dimensional object which represents a single, exact location. It always contains an X and Y coordinate, and can optionally can contain a Z (elevation) value, and a M (measure) value. The measure value is an arbitrary floating point measurement value that you can associate with the &lt;font size="2" face="Courier New"&gt;Point &lt;/font&gt;instance.&lt;/p&gt;  &lt;p&gt;The sample &lt;font size="2" face="tah"&gt;T-SQL script (&lt;font face="Courier New"&gt;GeometryPoint.sql)&lt;/font&gt;illustrates some&lt;/font&gt; of the capabilities of the &lt;font size="2" face="Courier New"&gt;Point&lt;/font&gt; class. Throughout all of our demos, we will be working with a very simple table called &lt;font size="2" face="Courier New"&gt;GeometryDemo&lt;/font&gt;, which allows us to associate a Geometry instance with an integer ID: &lt;/p&gt;  &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;   &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; GeometryDemo&lt;/pre&gt;

  &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; (&lt;/pre&gt;

  &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;     ID    &lt;span style="color:#0000ff;"&gt;INT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt; GEOMETRY &lt;span style="color:#0000ff;"&gt;NOT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;NULL&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt; );&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In the following code sample, we insert a &lt;font size="2" face="Courier New"&gt;Point&lt;/font&gt; instance, and then perform a &lt;font size="2" face="Courier New"&gt;select&lt;/font&gt; to retrieve the point instance in a number of formats:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- Insert a simple Point with an&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- X and Y coordinate&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt; INSERT &lt;span style="color:#0000ff;"&gt;INTO&lt;/span&gt; GeometryDemo (ID, &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt;    (1, &lt;span style="color:#006080;"&gt;&amp;#39;POINT(50 65)&amp;#39;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- Get the X and Y coordinates and &lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- the most relevant methods&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; ID, &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.ToString() &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; WKT, &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;            &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.STX &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [X Coordinate],                        &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt;            &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.STY &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [Y Coordinate],&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt;            &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.STAsBinary() &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; [&lt;span style="color:#0000ff;"&gt;Binary&lt;/span&gt; Representation],&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt;            &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.STasText() &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; [Text Representation]&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  13:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; GeometryDemo&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  14:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; ID = 1;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In lines 3 and 4, we use the WKT format to insert a &lt;font size="2" face="Courier New"&gt;Point&lt;/font&gt; with an X coordinate of 50 and a Y coordinate of 65. The WKT format for a &lt;font size="2" face="Courier New"&gt;Point&lt;/font&gt; simply requires you to to specify the X and Y coordinates. Note that you should NOT use a comma separator between the two, which might seem counterintuitive at first.&lt;/p&gt;

&lt;p&gt;In lines 8 through 14 we select the instance that we just inserted. Since &lt;font size="2" face="Courier New"&gt;Value&lt;/font&gt; is a geometry class instance, we need to use the&amp;#160; dot (&amp;quot;.&amp;quot;) notation to access properties and invoke methods on the object:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In line 8 we invoke the &lt;font size="2" face="Courier New"&gt;ToString()&lt;/font&gt; method. This method will return the Well-Known Text (WKT) representation of the instance. &lt;/li&gt;

  &lt;li&gt;In lines 9 and 10 we invoke the &lt;font size="2" face="Courier New"&gt;STX&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;STY&lt;/font&gt; properties to get the X and Y coordinates of our &lt;font size="2" face="Courier New"&gt;Point.&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;In line 11 we invoke the &lt;font size="2" face="Courier New"&gt;STAsBinary()&lt;/font&gt; method to get the binary representation of the &lt;font size="2" face="Courier New"&gt;Point&lt;/font&gt;. &lt;/li&gt;

  &lt;li&gt;Finally, in line 12 we invoke the &lt;font size="2" face="Courier New"&gt;STAsText()&lt;/font&gt; method, which will again return the WKT format of the &lt;font size="2" face="Courier New"&gt;Point.&lt;/font&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One important note: although TSQL by itself is not case sensitive, the CLR methods and properties on the spatial data types are, so make sure that you spell the property and method names correctly! For example if you would spell &amp;quot;&lt;font size="2" face="courier ne"&gt;Value.STAsText()&amp;quot;&lt;/font&gt; as &amp;quot;&lt;font size="2" face="Courier New"&gt;Value.STasText()&amp;quot;&lt;/font&gt; you would get the following error message:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; Msg 6506, &lt;span style="color:#0000ff;"&gt;Level&lt;/span&gt; 16, &lt;span style="color:#0000ff;"&gt;State&lt;/span&gt; 10, Line 34&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; Could &lt;span style="color:#0000ff;"&gt;not&lt;/span&gt; find method &lt;span style="color:#006080;"&gt;&amp;#39;STasText&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; type &lt;span style="color:#006080;"&gt;&amp;#39;Microsoft.SqlServer.Types.SqlGeometry&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; assembly &lt;span style="color:#006080;"&gt;&amp;#39;Microsoft.SqlServer.Types&amp;#39;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
The output of the select query is shown below:&lt;/div&gt;

&lt;p&gt;&lt;a title="OutputSimplePoint" href="http://www.flickr.com/photos/99548241@N00/2919284043/"&gt;&lt;img border="0" alt="OutputSimplePoint" src="http://static.flickr.com/3004/2919284043_bdd89474de.jpg" width="725" height="83" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the above output, we see that the WKT representation for the &lt;font size="2" face="Courier New"&gt;Point &lt;/font&gt;is returned by both the &lt;font size="2" face="Courier New"&gt;ToString()&lt;/font&gt; and the &lt;font size="2" face="Courier New"&gt;STAsText()&lt;/font&gt; methods. We also see the binary WKB representation and the X and Y coordinates of the &lt;font size="2" face="Courier New"&gt;Point &lt;/font&gt;instance.&lt;/p&gt;

&lt;h5&gt;Using the Z and M coordinates&lt;/h5&gt;

&lt;p&gt;As we mentioned earlier, a Point can optionally contain a Z (Elevation) coordinate and a M (Measurement) value. Note that both the Z and M values should be floats. Below is a T-SQL example:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- Insert a Point with an X, Y, Z and&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- M coordinate&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt; INSERT &lt;span style="color:#0000ff;"&gt;INTO&lt;/span&gt; GeometryDemo (ID, &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt; (2, &lt;span style="color:#006080;"&gt;&amp;#39;POINT(55 70 100.2 50)&amp;#39;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; ID, &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.ToString() &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; WKT, &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt;            &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.STX &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [X Coordinate],                        &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt;            &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.STY &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [Y Coordinate],&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;            &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.Z &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [Elevation],&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt;            &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.M &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [Measure]&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; GeometryDemo&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; ID = 2;&lt;/pre&gt;
  &lt;/div&gt;
As you can see, we simply added the Z and M values in the WKT format. The output of the select query is shown below:&lt;/div&gt;

&lt;p&gt;&lt;a title="OutputAdvancedPoint2" href="http://www.flickr.com/photos/99548241@N00/2920160158/"&gt;&lt;img border="0" alt="OutputAdvancedPoint2" src="http://static.flickr.com/3211/2920160158_0e78117127.jpg" width="571" height="85" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;&lt;/h5&gt;

&lt;h5&gt;OGC-compliant methods and Microsoft Extensions&lt;/h5&gt;

&lt;p&gt;The attentive observer probably noticed that some method and properties have an &lt;strong&gt;ST&lt;/strong&gt; prefix (such as &lt;font size="2" face="Courier New"&gt;STX&lt;/font&gt;, &lt;font size="2" face="courier n"&gt;STY&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;STAsText()&lt;/font&gt;), while other properties and methods do NOT have this prefix (for example: &lt;font size="2" face="Courier New"&gt;Z&lt;/font&gt;, &lt;font size="2" face="Courier New"&gt;M&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;ToString()&lt;/font&gt;). All methods and properties that are prefixed with &lt;strong&gt;ST&lt;/strong&gt; are OGC-compliant methods, while the other methods and properties are Microsoft extensions to the OGC standard.&lt;/p&gt;

&lt;p&gt;In the documentation you will notice that the OGC standard methods and the Microsoft extensions are cleanly separated:&lt;/p&gt;

&lt;p&gt;&lt;a title="OGCMethodsAndExtensions" href="http://www.flickr.com/photos/99548241@N00/2941793987/"&gt;&lt;img border="0" alt="OGCMethodsAndExtensions" src="http://static.flickr.com/3156/2941793987_a96dac7eba.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above diagram we also see sections for static methods (both OGC and Microsoft extensions). We will take a look at static methods in a later section of this post.&lt;/p&gt;

&lt;h5&gt;Geography Markup Language (GML)&lt;/h5&gt;

&lt;p&gt;The only format that we have not worked with so far is the Geographic Markup Language (GML), let&amp;#39;s write a query to retrieve both points as GML:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#008000;"&gt;--    Select both Points as GML&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#008000;"&gt;--  Note that we are NOT retrieving the Z and M&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt; &lt;span style="color:#008000;"&gt;--  coordinates of the second point&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt; &lt;span style="color:#008000;"&gt;--  because they are NOT OGC compliant!&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; ID, &lt;span style="color:#0000ff;"&gt;Value&lt;/span&gt;.AsGml() &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; [GML]&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; GeometryDemo;&lt;/pre&gt;
  &lt;/div&gt;
The &lt;font size="2" face="Courier New"&gt;AsGml()&lt;/font&gt; method can be used to retrieve a geometry instance in GML format. &lt;/div&gt;

&lt;p&gt;The output of the query is shown below:&lt;/p&gt;

&lt;p&gt;&lt;a title="OutputPointGML" href="http://www.flickr.com/photos/99548241@N00/2920194036/"&gt;&lt;img border="0" alt="OutputPointGML" src="http://static.flickr.com/3195/2920194036_69a4f0766f.jpg" width="553" height="107" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The standard XML namespace for GML will have the URN: &lt;a href="http://www.opengis.net/gml"&gt;http://www.opengis.net/gml&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;There is also one important note that we can make from the above output: the &lt;font size="2" face="Courier New"&gt;Z&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;M&lt;/font&gt; coordinates that we used for the second point are NOT returned in the GML! That is because they are proprietary Microsoft extensions to the OGC standard.&lt;/p&gt;

&lt;h5&gt;Using the static Point methods&lt;/h5&gt;

&lt;p&gt;The methods and properties we have used so far were invoked on an instance of the Point class, so we used the &amp;quot;dot&amp;quot; (.) notation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;instanceName.Property &lt;/font&gt;&lt;/p&gt;

  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;-or-&lt;/font&gt;&lt;/p&gt;

  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;instanceName.MethodCall(... method arguments here ...)&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instance properties and methods are always tied to a particular object &lt;strong&gt;instance&lt;/strong&gt;, in this case a Point instance. Besides instance methods, the spatial data types in SQL Server 2008 also use static methods and properties. Static methods and properties are tied to the &lt;strong&gt;class&lt;/strong&gt; itself, and can thus be invoked without having an instance around. You use the &amp;quot;::&amp;quot; notation in combination with the class name to invoke a static method or property in T-SQL:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;className::Property&lt;/font&gt;&lt;/p&gt;

  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;-or-&lt;/font&gt;&lt;/p&gt;

  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;className::MethodCall()&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One frequent usage pattern for a static method is the Factory Pattern. The Factory Pattern returns a new instance of the class through a static method. This pattern is used in both geospatial types in SQL Server 2008. Below is a code example from the &lt;font size="2" face="Courier New"&gt;GeometryPoint.sql&lt;/font&gt; T-SQL script:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; /* ========================================================================= &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt;    ======= &lt;span style="color:#0000ff;"&gt;Using&lt;/span&gt; the &lt;span style="color:#0000ff;"&gt;Static&lt;/span&gt; methods &lt;span style="color:#0000ff;"&gt;to&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;create&lt;/span&gt; a Point Instance =============&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt;    ========================================================================= */&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   4:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @Pnt1 Geometry, @Pnt2 Geometry, @Pnt3 Geometry, @Pnt4 Geometry, @Pnt5 Geometry&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   5:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @xmlSnippet xml;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   7:&lt;/span&gt; &lt;span style="color:#008000;"&gt;--    1. Create a Point from an X and Y coordinate and an SRID&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   8:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; @Pnt1 = geometry::Point(30, 20, 0);&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  10:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- 2. Create a Point using the Parse method&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  11:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; @Pnt2 = geometry::Parse(&lt;span style="color:#006080;"&gt;&amp;#39;POINT( 90 23 56000 231)&amp;#39;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  12:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  13:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- 3. Create a Point using the OGC STPointFromText method&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  14:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- Notice the SRID at the end&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  15:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; @Pnt3 = geometry::STPointFromText(&lt;span style="color:#006080;"&gt;&amp;#39;POINT(20 25)&amp;#39;&lt;/span&gt;, 0)&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  16:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  17:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- 4. Create a Point from GML &lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  18:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt; @xmlSnippet = &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  19:&lt;/span&gt;     &lt;span style="color:#006080;"&gt;&amp;#39;&amp;lt;Point xmlns=&amp;quot;http://www.opengis.net/gml&amp;quot;&amp;gt; &amp;lt;pos&amp;gt;34 23&amp;lt;/pos&amp;gt; &amp;lt;/Point&amp;gt;&amp;#39;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  20:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; @Pnt4 = geometry::GeomFromGml(@xmlSnippet, 0);&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  21:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  22:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- 5. Null Point&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  23:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; @Pnt5 = geometry::[&lt;span style="color:#0000ff;"&gt;Null&lt;/span&gt;];&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  24:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  25:&lt;/span&gt; &lt;span style="color:#008000;"&gt;-- Now select all points&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  26:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; @Pnt1.ToString() &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [&lt;span style="color:#0000ff;"&gt;From&lt;/span&gt; Arguments],&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  27:&lt;/span&gt;        @Pnt2.ToString() &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [&lt;span style="color:#0000ff;"&gt;From&lt;/span&gt; Parse],&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  28:&lt;/span&gt;        @Pnt3.ToString() &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; [&lt;span style="color:#0000ff;"&gt;From&lt;/span&gt; STPointFromText],&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  29:&lt;/span&gt;        @Pnt4.ToString() &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [&lt;span style="color:#0000ff;"&gt;From&lt;/span&gt; Xml],&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;  30:&lt;/span&gt;        @Pnt5 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; [&lt;span style="color:#0000ff;"&gt;Null&lt;/span&gt; Point];&lt;/pre&gt;
  &lt;/div&gt;
Following is a discussion of each static method:&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;In line 8, we use the static &lt;font size="2" face="Courier New"&gt;geometry::Point()&lt;/font&gt; method to create a Point instance by passing in the X, Y, Z and M coordinates. &lt;/li&gt;

  &lt;li&gt;In line 11, we use the &lt;font size="2" face="Courier New"&gt;geometry::Parse()&lt;/font&gt; method to create a Point instance from Well-Known Text (WKT). &lt;/li&gt;

  &lt;li&gt;In line 15, we use the &lt;font size="2" face="Courier New"&gt;geometry::STPointFromText()&lt;/font&gt; method to create a Point instance from Well-Known Text. The is the OGC equivalent of the &lt;font size="2" face="Courier New"&gt;geometry::Parse()&lt;/font&gt; method. &lt;/li&gt;

  &lt;li&gt;In line 18, we have an example of how to create a Point instance from a Geographic Markup Language (GML) snippet, using the static &lt;font size="2" face="Courier New"&gt;geometry::GeomFromGml()&lt;/font&gt; method. &lt;/li&gt;

  &lt;li&gt;Finally, in line 23 we create a &lt;font size="2" face="Courier New"&gt;NULL&lt;/font&gt; Point instance with the static &lt;font size="2" face="Courier New"&gt;geometry::[Null]&lt;/font&gt; property. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output of the select statement is shown below:&lt;/p&gt;

&lt;p&gt;&lt;a title="StaticPointMethods" href="http://www.flickr.com/photos/99548241@N00/2941817723/"&gt;&lt;img border="0" alt="StaticPointMethods" src="http://static.flickr.com/3013/2941817723_30bfba9626.jpg" width="544" height="44" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can conclude from the above output, the expected Point instances were created by means of the static methods.&lt;/p&gt;

&lt;h5&gt;The Spatial Reference Identifier&lt;/h5&gt;

&lt;p&gt;In the previous code sample, you might have noticed the &amp;quot;0&amp;quot; after the &lt;font size="2" face="Courier New"&gt;@xmlSnippet&lt;/font&gt; parameter:&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;
    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt; @xmlSnippet = &lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   2:&lt;/span&gt;     &lt;span style="color:#006080;"&gt;&amp;#39;&amp;lt;Point xmlns=&amp;quot;http://www.opengis.net/gml&amp;quot;&amp;gt; &amp;lt;pos&amp;gt;34 23&amp;lt;/pos&amp;gt; &amp;lt;/Point&amp;gt;&amp;#39;&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="border-bottom-style:none;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;"&gt;   3:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;SET&lt;/span&gt; @Pnt4 = geometry::GeomFromGml(@xmlSnippet, 0);&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This argument is the SRID, or the Spatial Reference Identifier. The SRID corresponds to a spatial reference system based upon the specific ellipsoid used for either flat-earth or round-earth mapping. Different projection systems exist, some of you might be familiar with the Mercator Projection that was used to create the maps that were in most classrooms in recent times. A good discussion of map projections can be found at: &lt;a title="http://maps.unomaha.edu/Peterson/gis/notes/MapProjCoord.html" href="http://maps.unomaha.edu/Peterson/gis/notes/MapProjCoord.html"&gt;http://maps.unomaha.edu/Peterson/gis/notes/MapProjCoord.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each projection is uniquely defined by its own SRID. You can use any projection you want, but you need to be aware that when you are comparing spatial instances using any of the methods (such as &lt;font size="2" face="Courier New"&gt;STIntersection()&lt;/font&gt;) you need to make sure that all objects have the &lt;strong&gt;same&lt;/strong&gt; SRID otherwise you will get a run-time error!&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;That concludes part 2 of this series. In part three, we take a look at the LineString and the Polygon class, and we will use some visualization tools such as &lt;a href="http://www.conceptdevelopment.net/Database/Geoquery/"&gt;GeoQuery&lt;/a&gt;, &lt;a href="http://www.codeplex.com/SpatialViewer"&gt;Spatial Viewer&lt;/a&gt;, and SQL Server Management Studio&amp;#39;s very own &amp;quot;Spatial Tab&amp;quot; to get a visual representation of our spatial data!&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=415" width="1" height="1"&gt;</description><category domain="http://footheory.com/blogs/bennie/archive/tags/SQL+Server+2008/default.aspx">SQL Server 2008</category><category domain="http://footheory.com/blogs/bennie/archive/tags/Spatial+Data/default.aspx">Spatial Data</category><category domain="http://footheory.com/blogs/bennie/archive/tags/SQL+Server/default.aspx">SQL Server</category><category domain="http://footheory.com/blogs/bennie/archive/tags/TSQL/default.aspx">TSQL</category></item><item><title>Investigating the new Spatial Types in SQL Server 2008 - Part 1</title><link>http://footheory.com/blogs/bennie/archive/2008/10/05/investigating-the-new-spatial-types-in-sql-server-2008-part-1.aspx</link><pubDate>Sun, 05 Oct 2008 22:32:05 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:414</guid><dc:creator>bennie</dc:creator><slash:comments>1</slash:comments><description>&lt;h2&gt;&lt;/h2&gt;  &lt;h4&gt;Series Abstract&lt;/h4&gt;  &lt;p&gt;In this post we take a look at the new spatial data type support in SQL server 2008. First, I will make a case for why you would want to integrate spatial support in your applications. Next we will take a look at the two core spatial data types in SQL Server:&amp;#160; the &lt;strong&gt;Geometry&lt;/strong&gt; and &lt;strong&gt;Geography&lt;/strong&gt; types. We will explain when to use each type, and we will take a look at the main application domains for the two types.&lt;/p&gt;  &lt;p&gt;The spatial types are implemented as CLR types in the database engine. Since some database folks might be unfamiliar with CLR types, we will make a brief detour into SQL Server and CLR types. We will talk about the differences between static and instance methods, and explain the TSQL calling notation for each.&lt;/p&gt;  &lt;p&gt;Both the Geometry and the Geography types are really just the top-level types of a rich object hierarchy. We will take a detailed look at the different classes in this hierarchy, and we will explore the methods and properties of each class by means of a number of TSQL scripts. A part of this exploration we will take a look at the three data formats that can be used to represent the spatial types: the SQL Server-native&amp;#160; Well-Know-Binary (WKB) format, and the &lt;a href="http://www.opengeospatial.org/"&gt;OGC&lt;/a&gt; standard data types: the Well-Known-Text (WKT) and the Geography Markup Language (&lt;a href="http://en.wikipedia.org/wiki/Geography_Markup_Language"&gt;GML&lt;/a&gt;) . We will use TSQL scripts for each object to illustrate the different notations.&lt;/p&gt;  &lt;p&gt;As always, a picture is worth a thousand words, and nowhere this is more the case as for spatial information. Therefore, I will use both the &amp;quot;Spatial Results&amp;quot; tab in SQL server and a number of third-party rendering tools such as &lt;a href="http://www.codeplex.com/SpatialViewer"&gt;SpatialViewer&lt;/a&gt; and &lt;a href="http://www.conceptdevelopment.net/Database/Geoquery/"&gt;GeoQuery&lt;/a&gt; to present a spatial query result.&lt;/p&gt;  &lt;p&gt;After we have a good understanding of the spatial data types, we will put them to some practical use. We will use Virtual Earth to create applications in which we create mashups of Spatial data with a variety of business data. A large volume of GIS data is available on the public domain (some good sources are the &lt;a href="http://www.census.gov/"&gt;US Census&lt;/a&gt; and &lt;a href="http://www.usgs.gov/"&gt;USGS&lt;/a&gt; Web sites), but the format of this data is typically not compatible with SQL Server. Therefore, as part of this series we will create a library that will enable us to convert the &amp;quot;traditional&amp;quot; formats into a SQL Server 2008-compatible format.&lt;/p&gt;  &lt;p&gt;The above abstract covers a wide variety of formats, therefore I am planing to spread out this article over a number of different posts. This first post will cover the need for spatial support in our applications, the basics of the Geometry and Geography data types and a quick OO primer.&lt;/p&gt;  &lt;h4&gt;Why Spatial Data?&lt;/h4&gt;  &lt;p&gt;These days it is hard to find any data that DOES NOT have a spatial aspect. A number of applications attempt to answer questions like the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Where are my customers located? &lt;/li&gt;    &lt;li&gt;What cities have the highest accident rates? &lt;/li&gt;    &lt;li&gt;What Florida counties have the highest flood risk? (OK, that one&amp;#39;s easy to answer: &amp;quot;All of them&amp;quot;!) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;As GPS devices become more prevalent, more and more data is geo-tagged. For example, a lot of modern mobile phones have both a camera and a GPS chip build in.&lt;/p&gt;  &lt;p&gt;While the above applications use spatial data only as part of their overall data set, there are a number of applications that use mapping and spatial data as their primary output:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Consumer products such as Microsoft&amp;#39;s Virtual Earth or Google maps. &lt;/li&gt;    &lt;li&gt;The government publishes the census results as spatial data. &lt;/li&gt;    &lt;li&gt;Utilities use mapping tools such as ESRI Server to plot the layout of electrical grid lines or underground gas lines. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;While the above examples are pretty self-evident, spatial data also plays an import role in applications that we might not think about right away:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When a warehousing application generates a pallet &amp;quot;pick run&amp;quot;, it will use geospatial information to calculate the most optimal route. &lt;/li&gt;    &lt;li&gt;When an interior architect uses a CAD tool such as AutoDesk to perform modeling of an interior space, he/she is using spatial data quite extensively. &lt;/li&gt;    &lt;li&gt;Computer-aided manufacturing tools use spatial data to layout out parts on a piece of sheet metal. &lt;/li&gt;    &lt;li&gt;The program in a municipal kiosk uses spatial data and geometric algorithms to predict the arrival times of buses and trains. &lt;/li&gt;    &lt;li&gt;A multi-player computer game use spatial coordinates to keep track of the current locations of all game participants. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;From the above discussion it is clear that a large number of application have a need to work with spatial data. Some common requirements for spatial data support are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The ability to store spatial coordinates directly in the database, preferably in the same tables as its associated data. &lt;/li&gt;    &lt;li&gt;The data types used for this spatial data should go beyond simple point coordinates. Most geospatial data consists out of a mixture of points, lines (both single-segment and multi segment), and closed shapes (typically referred to as polygons in the literature). &lt;/li&gt;    &lt;li&gt;The ability to perform a multitude of operations on this geospatial data. For example, a chip design application might want to assure that certain routes on a chip do not cross, other applications will have a need to calculate the area of a complex polygon etc. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In the next section will take a look at how SQL Server 2008 addresses the above requirements.&lt;/p&gt;  &lt;h4&gt;Spatial Data Support in SQL Server 2008&lt;/h4&gt;  &lt;h5&gt;Types of Spatial Data&lt;/h5&gt;  &lt;p&gt;At the highest level, we recognize two major classes of spatial data:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Vector Data&lt;/strong&gt;. Vector data is data expressed by a set of vertices and their relationship to one another. Common spatial features represented by vector data include:       &lt;ul&gt;       &lt;li&gt;Points. &lt;/li&gt;        &lt;li&gt;Lines (where a line can have one or more segments) &lt;/li&gt;        &lt;li&gt;Polygons. Polygons are typically used to represent areas and regions. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Raster Data&lt;/strong&gt;. Raster data is data expressed as a matrix of cells. We typically recognize raster data as images. Within a spatial or GIS context, we see raster data manifested as:       &lt;ul&gt;       &lt;li&gt;Satellite images. &lt;/li&gt;        &lt;li&gt;The Virtual Earth bird&amp;#39;s eye images. &lt;/li&gt;        &lt;li&gt;Google &amp;quot;street level&amp;quot; images. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;An example of each type of spatial data is shown below&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;         &lt;p&gt;&lt;u&gt;&lt;strong&gt;Sample Raster Image &lt;/strong&gt;&lt;/u&gt;&lt;u&gt;&lt;strong&gt;(a sample satellite heat map)&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;&lt;u&gt;&lt;strong&gt;Sample Vector (in this case a simple line vector)&lt;/strong&gt;&lt;/u&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&lt;a title="RasterImageElevation" href="http://www.flickr.com/photos/99548241@N00/2916843892/"&gt;&lt;img border="0" alt="RasterImageElevation" src="http://static.flickr.com/3124/2916843892_0a7042d488.jpg" width="364" height="255" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td&gt;&lt;a title="vectorGeom1" href="http://www.flickr.com/photos/99548241@N00/2916875752/"&gt;&lt;img border="0" alt="vectorGeom1" src="http://static.flickr.com/3276/2916875752_9ea942fe1e.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;SQL Server 2008 does focus exclusively on Spatial Vector data.&lt;/p&gt;  &lt;h5&gt;&lt;/h5&gt;  &lt;h4&gt;The SQL Server 2008 Spatial Data Types&lt;/h4&gt;  &lt;p&gt;SQL Server 2008 introduces two new data types:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Geometry&lt;/strong&gt;. The geometry data type is based on the Cartesian coordinate system,&amp;#160; based upon a &amp;quot;flat earth&amp;quot; representation model. In this model, a point is represented by an X, Y and optionally a Z coordinate. This usage domain of this data type is either:       &lt;ul&gt;       &lt;li&gt;The representation of simple coordinates in a two or three dimensional space. A example is the precise location of a pallet in a warehouse. &lt;/li&gt;        &lt;li&gt;The representation of map coordinates, where distances are limited enough so that they are not affected by the round earth model. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Geography&lt;/strong&gt;. The geography data point can store points, lines, polygon and collections of each of these, using a &amp;quot;round earth&amp;quot; model as opposed to the &amp;quot;flat earth&amp;quot; model used by the Geometry data type. Instead of using X and Y coordinates, the geography data type will use a latitude/longitude combination to represent a single point. Most of the GIS data available on the Web is latitude/longitude based, so the Geography data type is the data type you should used in most of you GIS applications, especially when you are dealing with longer distances where the shape of the earth becomes relevant. &lt;/li&gt; &lt;/ol&gt;  &lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;&lt;u&gt;&lt;strong&gt;Geometry : Cartesian coordinate system, &amp;quot;flat earth&amp;quot; model&lt;/strong&gt;&lt;/u&gt;&lt;/td&gt;        &lt;td&gt;&lt;u&gt;&lt;strong&gt;Geography: Latitude/longitude coordinates, &amp;quot;round earth&amp;quot; model&lt;/strong&gt;&lt;/u&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;&lt;a title="CartesianCoordinateSystem" href="http://www.flickr.com/photos/99548241@N00/2916940482/"&gt;&lt;img border="0" alt="CartesianCoordinateSystem" src="http://static.flickr.com/3210/2916940482_ec175018e3.jpg" width="290" height="290" /&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td&gt;&lt;a title="LATITUDE_LONGITUDE_MERIDIA" href="http://www.flickr.com/photos/99548241@N00/2916940504/"&gt;&lt;img border="0" alt="LATITUDE_LONGITUDE_MERIDIA" src="http://static.flickr.com/3210/2916940504_f94a4bb23d.jpg" width="298" height="386" /&gt;&lt;/a&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;The geometry data type conforms to the &lt;a href="http://www.opengeospatial.org/"&gt;Open Geospatial Consortium&lt;/a&gt; (OGC) &lt;a href="http://www.opengeospatial.org/standards/sfa"&gt;Simple features for SQL specification version 1.1.0&lt;/a&gt;. The OGC is a non-profit, voluntary concensus standards organization which is the leading consortium when it comes to the drafting and ratification of standards for geospatial and location based services. One of the standards published by the OGC is the Well-Know-Text specification (&lt;a href="http://en.wikipedia.org/wiki/Well-known_text"&gt;WKT&lt;/a&gt;) for spatial data types. We will investigate this format in detail in part 2 of the series.&lt;/p&gt;  &lt;h4&gt;CLR Objects in the Database Engine and the Database Developer&lt;/h4&gt;  &lt;p&gt;Both the geometry and geography data types are implemented as user-defined types (UDT&amp;#39;s) in the database engine. These UDT&amp;#39;s are implemented as .NET Common Language Runtime (CLR) types. Before we take a more detailed look how to use these types, it is important that we make sure that the reader is familiar with some basic OO principles. If you are already familiar with object-orientation and .NET types, please feel free to skip ahead to the next part in this series.&lt;/p&gt;  &lt;p&gt;The core abstraction in the object-oriented world is the&lt;strong&gt; &lt;/strong&gt;&lt;em&gt;class&lt;/em&gt;. A class can be seen as the blueprint for a particular type. From this blueprint, a client can create any number of actual &lt;em&gt;object instances&lt;/em&gt;. A class hides away its implementation details behind a set of publicly accessible properties and methods. This principle is called &lt;strong&gt;encapsulation &lt;/strong&gt;or&lt;strong&gt; information hiding. &lt;/strong&gt;For example, a &lt;font size="2" face="Courier New"&gt;Car&lt;/font&gt; class will encapsulate the behavior of an automobile. It might expose methods such as &lt;font face="Courier New"&gt;Start&lt;/font&gt;, &lt;font size="2" face="Courier New"&gt;Stop&lt;/font&gt;, &lt;font size="2" face="Courier New"&gt;SlowDown&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;SpeedUp&lt;/font&gt;, and it might provide properties such as &lt;font size="2" face="Courier New"&gt;CurrentSpeed&lt;/font&gt; and &lt;font size="2" face="Courier New"&gt;DaysTillNextOilChange&lt;/font&gt;. The &lt;font size="2" face="Courier New"&gt;Car&lt;/font&gt; class will hide the details of how it executes these methods and exposes these properties, enabling the client to be &amp;quot;blissfully unaware&amp;quot; of the implementation details of the &lt;font size="2" face="Courier New"&gt;Car&lt;/font&gt; class.&lt;/p&gt;  &lt;p&gt;Classes can be related to one another. At a high-level we can recognize the following types of relationships:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The &amp;quot;has-a&amp;quot; relationship. For example, a &lt;font size="2" face="Courier New"&gt;Car&lt;/font&gt; class might have a &lt;font size="2" face="Courier New"&gt;SteeringWheel&lt;/font&gt; and a &lt;font size="2" face="Courier New"&gt;GasTank&lt;/font&gt;. This type of relationship is sometimes referred to as a &amp;quot;uses&amp;quot; relationship, for example the Car class &amp;quot;uses&amp;quot; the &lt;font size="2" face="Courier New"&gt;SteeringWheel&lt;/font&gt; class and &amp;quot;uses&amp;quot; the &lt;font size="2" face="Courier New"&gt;GasTank&lt;/font&gt; class. &lt;/li&gt;    &lt;li&gt;The &amp;quot;is-a&amp;quot; relationship. To stay with our &lt;font size="2" face="Courier New"&gt;Car&lt;/font&gt; example, a &lt;font size="2" face="Courier New"&gt;SportsCar&lt;/font&gt;&lt;strong&gt; &lt;/strong&gt;is a specialized type of &lt;font size="2" face="Courier New"&gt;Car&lt;/font&gt;,&amp;#160; which is specially equipped. It might have a &lt;font size="2" face="Courier New"&gt;Spoiler&lt;/font&gt;, a &lt;font size="2" face="Courier New"&gt;HighPerformanceEngine&lt;/font&gt; etc.. When classes have such a relationship they will use an OOP concept called &lt;strong&gt;inheritance&lt;/strong&gt; to implement this relationship. In an inheritance implementation, the class from which we inherit is called the &lt;em&gt;base class&lt;/em&gt; and the more specialized class is called the&lt;em&gt; sub class&lt;/em&gt;. The sub class gets all of the functionality of the base class &amp;quot;for free&amp;quot;, so it only needs to worry about implementing it own specialized behavior on top of the functionality of the base class. For example, the &lt;font size="2" face="Courier New"&gt;SportsCar&lt;/font&gt; class only implements the additional functionality that makes it a sports car. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;An example of a &amp;quot;uses&amp;quot; (&amp;quot;has a&amp;quot;) and an inheritance (&amp;quot;is a&amp;quot;) relationship is shown in the figure below:&lt;/p&gt;  &lt;p&gt;&lt;a title="OOLatest" href="http://www.flickr.com/photos/99548241@N00/2919345220/"&gt;&lt;img border="0" alt="OOLatest" src="http://static.flickr.com/3229/2919345220_63ec8c85d7.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Some base classes only define a general abstract concepts or entities. These types of classes cannot be directly instantiated by the client, since they are not &amp;quot;feature complete&amp;quot;. Such a class is called an &lt;em&gt;abstract class&lt;/em&gt; The features defined by an abstract class are implemented by a sub class of the abstract class. Such a sub class that can be instantiated is called a&lt;em&gt; concrete class&lt;/em&gt;. We will see in the next section that the geometry and geography classes are indeed defined as abstract classes in the database engine.&lt;/p&gt;  &lt;p&gt;In the next part of this series, we will take a look at the class diagrams for both the geography and geometry classes, and we&amp;#39;ll start writing some TSQL code!&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=414" width="1" height="1"&gt;</description></item><item><title>An Introduction to LINQ to XML</title><link>http://footheory.com/blogs/bennie/archive/2008/09/17/an-introduction-to-linq-to-xml.aspx</link><pubDate>Wed, 17 Sep 2008 15:35:18 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:412</guid><dc:creator>bennie</dc:creator><slash:comments>0</slash:comments><description>&lt;h3&gt;Note: This post is a work in progress... not yet completed...&lt;/h3&gt; &lt;h3&gt;Overview&lt;/h3&gt; &lt;p&gt;When Visual Studio 2008 and the .NET Framework 3.5 shipped in late 2007, the feature that got by far the most attention was &lt;strong&gt;Language Integrated Query (LINQ).&lt;/strong&gt; This article will provide a quick overview of the LINQ technologies, and will then focus in on&lt;strong&gt; LINQ to XML&lt;/strong&gt;, which is a subset of the LINQ technologies.&lt;/p&gt; &lt;p&gt;This article is structured as follows:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The next section will provide a short overview of LINQ in general. We take a look at what the main drivers were behind the creation of LINQ, and we will start looking at some of the specifics of LINQ to XML.  &lt;li&gt;Once we have established a basic understanding of LINQ to XML, we will take a look at its object model. LINQ to XML introduces an easy to use, flattened object model, especially when compared to the XML DOM object model.  &lt;li&gt;Next, we will take a look at what is in my opinion one of the most important features of LINQ to XML, and that is &lt;strong&gt;Functional Construction&lt;/strong&gt;. Functional construction enables us to create an XML document in a very straightforward way. No longer do we need to use the elaborate XML DOM object model and write 100 lines of complex code, just to create a simple XML document that is just a few lines long.  &lt;li&gt;After we have an understanding of how to create an XML document, we take a look at how we can use the features on the new LINQ to XML object model to query, iterate, manipulate and validate an XML document.  &lt;li&gt;To illustrate how easy it is to leverage the LINQ to XML features in a real-world application, we will take a look at an example that&amp;nbsp; performs two-way binding of a rather complex XML document to a WPF tree control.  &lt;li&gt;To round out our discussion, we will take a look at some practical tips and tricks, which enables us to take full advantage of LINQ to XML, and we will also mentioned some common pitfalls, and inform you how to save time not making the same mistakes as your truly ;-)!&lt;/li&gt;&lt;/ol&gt; &lt;h4&gt;Prerequisites&lt;/h4&gt; &lt;p&gt;If you want to run the code samples that are associated with this article, you will need the following pre-requisites:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Since we will be using LINQ, you obviously need to have a version of Visual Studio 2008 installed. If you install Visual Studio, you will automatically also install .NET 3.5 and the C# 3.0 compiler.  &lt;li&gt;We will be showing how you can use LINQ to SQL to create XML documents, so you will need to have SQL Server 2005 or the SQL Server 2008 beta installed. If you have the express edition installed, I recommend you also download SQL Server Management Studio express.  &lt;li&gt;We will be using the &lt;font face="Courier New" size="2"&gt;AdventureWorks &lt;/font&gt;sample database to illustrate how we can create an XML document from a SQL Server database, so you should have the latest version of the &lt;font face="Courier New" size="2"&gt;AdventureWorks &lt;/font&gt;database installed. If you currently don&amp;#39;t have this database installed, you can navigate to: &lt;a title="http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=4004" href="http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=4004"&gt;http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=4004&lt;/a&gt;, and download the appropriate version of the &lt;font face="Courier New" size="2"&gt;AdventureWorks*.msi&lt;/font&gt; file, and follow the instructions to install the database on your SQL server.&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;LINQ Overview&lt;/h3&gt; &lt;h4&gt;&lt;/h4&gt; &lt;h4&gt;Background - Problem Description&lt;/h4&gt; &lt;p&gt;Most of us write business applications to earn our living. All business&amp;nbsp; applications that I ever worked with deal with some type of data, and quite a number of them involved multiple heterogeneous data sources.&amp;nbsp; &lt;/p&gt; &lt;p&gt;In the early days (1980-1990) all of the data for an application was centralized in one file, and the data access capabilities were directly built into the language (I know that at this point, my friend Pete Miller is thinking back nostalgically about his FoxPro and DBASE days... ;-). The upside of this was that data querying and data manipulation were a core part of the programming experience, but the downside was that every platform (DBASE, FoxPro, FileMaker) would integrate these data access features in a completely different way, tailored to the capabilities of the underlying data access tool. As a result, programmers faced a steep learning curve when moving from one platform to another. Another drawback of these first-generation data access systems was scalability. All platforms were file-based, and therefore had a hard time scaling to multiple users and large data sizes. &lt;/p&gt; &lt;p&gt;In response to this and other issues, (1990s&amp;nbsp; through early 2000s) &lt;u&gt;&lt;em&gt;relational database systems&lt;/em&gt;&lt;/u&gt; (RDBMS) were created. All of these databases used an emerging query and DML language called &lt;em&gt;&lt;u&gt;SQL&lt;/u&gt;&lt;/em&gt; to access the data, and database programs migrated from being strictly tied to a particular data access system dialect, to using industry-standard SQL. The query and data manipulation features became again external to the core programming languages, and were typically made available through a set of external libraries (db-Library anyone?). This process was accelerated by the creation of ODBC, which provides a standard means of accessing any database that provides an ODBC driver.&lt;/p&gt; &lt;p&gt;In recent years, we have seen the emergence of &lt;u&gt;&lt;em&gt;Object-Relational Mapping&lt;/em&gt;&lt;/u&gt; (ORM) tools. The main philosophy behind the ORM movement was the fact that designers and programmers are dealing with objects to represent their data, but each time they have to persist or load these objects from a data store, they have to make a paradigm shift back to SQL and the relational model,&amp;nbsp; and the specific details associated with the database access libraries that are being used. An ORM tool, such as NHibernate takes over the responsibility of persisting and loading objects to the database in a transparent fashion.&lt;/p&gt; &lt;p&gt;While both SQL and their associated data access technologies (such as ADO.NET) and/or the newer ORM tools have simplified things significantly, we still have a number of challenges that remain:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Most real-world applications out there deal with other data types besides relational data. Indeed, in this connected world, we access a variety of XML data sources, we connect to RSS feeds, leverage Web Services using the SOAP or REST protocols, access data in Active Directory or some other LDAP-based data store, and so on. Each of these data sources have their own data access paradigms.  &lt;li&gt;When working with &amp;quot;plain old objects&amp;quot;, we have to use a very different API to&amp;nbsp; sort, filter, group our otherwise manipulate our objects, as compared to relational data. Wouldn&amp;#39;t it be nice if we could have one standard API for these common tasks?  &lt;li&gt;Often we have to perform complex data transformations and/or data shaping. The way in which these transformations are performed is often dependent on the type of the data. For XML we use XSLT, for relational data we use views or complex joins, for objects we use manual code etc. Again, it would be nice to have access to one standard approach for performing transformations.  &lt;li&gt;What if we want to access data from a dynamic language, such as Ruby, IronPython, PowerShell, F# or any of the future DLR-based languages? Will these languages be able to use the same data access tool as the statically-typed .NET languages such as C# or VB.NET?&lt;/li&gt;&lt;/ol&gt; &lt;h4&gt;Microsoft&amp;#39;s Answer: LINQ&lt;/h4&gt; &lt;p&gt;At the core, LINQ is really a set of constructs, built into the language, which allow us to work with any type of data, be it relational, XML or plain old objects. LINQ is supported in both C# 3.0 and VB 9.0, which are compilers that shipped with Visual Studio 2008. In a way, LINQ brings us &amp;quot;back to the future&amp;quot;, making querying and manipulating data&amp;nbsp; a core programming concept again. The main different with the &amp;quot;old school&amp;quot; languages such as FoxPro is that LINQ is fully independent of the type of data that is being accessed (object, relational data, XML, etc.), and the specific implementation of the data source (SQL Server, Oracle etc.).&lt;/p&gt; &lt;p&gt;The LINQ features in the C# 3.0 compiler are built on top of a number of other language enhancements such as:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Anonymous types  &lt;li&gt;Anonymous methods  &lt;li&gt;Type inference  &lt;li&gt;Lambda expressions  &lt;li&gt;Expression trees  &lt;li&gt;Extension methods  &lt;li&gt;Instance and collection initializers  &lt;li&gt;Partial methods&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;A number of these features were addressed in some of my previous posts. Please refer to the blog archives for more information.&lt;/p&gt; &lt;p&gt;The .NET 3.5 Framework also provides LINQ support through a number of types, available in the System.*.LINQ namespaces. These types provide additional support on top of the compiler features.&lt;/p&gt; &lt;p&gt;A graphical overview of LINQ is shown below:&lt;/p&gt; &lt;p&gt;&lt;a title="LINQ Overview" href="http://www.flickr.com/photos/99548241@N00/2178356509/"&gt;&lt;img alt="LINQ Overview" src="http://static.flickr.com/2302/2178356509_493307271e.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;h4&gt;LINQ to XML&lt;/h4&gt; &lt;p&gt;LINQ to XML is portion of LINQ that allows us to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Construct  &lt;li&gt;Traverse  &lt;li&gt;Manipulate  &lt;li&gt;Query  &lt;li&gt;Search&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;XML documents and fragments, using the standard LINQ API. &lt;/p&gt; &lt;p&gt;One of the main goals of LINQ to XML was to address the main shortcomings in the W3C XML DOM API, as implemented in the System.Xml.* .NET 2.0 namespaces, with a focus on the following areas:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Simplify XML tree construction with functional construction.  &lt;li&gt;Eliminate document centricity in favor of element centricity.  &lt;li&gt;Simplify naming by eliminating prefixes from the API.  &lt;li&gt;Simplify Node value extraction.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The above topics have always been a hard area to deal with for any programmer working with XML documents. XML DOM code is unnecessary complex and bloated, and often unintentionally obfuscated. For example, it is not easy to imply the structure of the created XML document, when reading XML DOM document creation code.&lt;/p&gt; &lt;p&gt;Other issues that Microsoft wanted to address with LINQ to XML is to allow a developer to quickly move data extracted from a relational model to an XML representation, or from an object graph to an XML document. This current DOM API does not support constructs such as projections inside a XQuery, LINQ to XML provides an elegant solution to this problem.&lt;/p&gt; &lt;p&gt;In the .NET 3.5 framework, LINQ to XML is implemented in the &lt;font face="Courier New" size="2"&gt;System.Xml.Linq.dll&lt;/font&gt; assembly, and exposed through the &lt;font face="Courier New" size="2"&gt;System.Xml.Linq&lt;/font&gt; namespace.&lt;/p&gt; &lt;p&gt;The dependencies of the &lt;font face="Courier New" size="2"&gt;System.Xml.Linq.dll&lt;/font&gt; assembly is show in the figure below:&lt;/p&gt; &lt;p&gt;&lt;a title="System.XML.Linq.Overview" href="http://www.flickr.com/photos/99548241@N00/2184371268/"&gt;&lt;img alt="System.XML.Linq.Overview" src="http://static.flickr.com/2218/2184371268_915a787b32.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;LINQ to XML Object Model&lt;/h3&gt; &lt;p&gt;LINQ to XML was developed with Language-Integrated Query over XML in mind from the onset. It takes advantage of the standard query operators and adds query extensions specific to XML. Just as significant as the Language-Integrated Query capabilities of LINQ to XML is the fact that LINQ represents a consistent query experience across all LINQ enabled APIs and allows us to combine XML queries from other data sources. So, with one query, you can access data from:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Local objects in memory  &lt;li&gt;An XML Data Source  &lt;li&gt;One or more SQL Server data sources&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The core classes that make up the LINQ to XML object model are listed below:&lt;/p&gt; &lt;p&gt;&lt;a title="LinqToXMLCoreClasses" href="http://www.flickr.com/photos/99548241@N00/2181197474/"&gt;&lt;img alt="LinqToXMLCoreClasses" src="http://static.flickr.com/2342/2181197474_1d2d452b3e.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As you can conclude from the object model above, the number of classes involved has been dramatically reduced, resulting in a reduced learning curve. Actually I think that the biggest challenge in working with LINQ to XML is to unlearn some of the bad practices that we had to burn into our brain to make the W3C XML DOM work for us.&lt;/p&gt; &lt;p&gt;Some key issues regarding this object model are listed below:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt; &lt;ol&gt; &lt;li&gt;You can now work in a &amp;quot;document free mode&amp;quot; if you would like to do so. In some scenarios, you simply want to create or load some XML, manipulate and query it, and save it back. With the W3C DOM, you would be forced to create an XML document. In LINQ to XML, this is no longer the case. To perform the task listed, you could simply:  &lt;ul&gt; &lt;li&gt;Create &lt;font face="Courier New" size="3"&gt;XElements&lt;/font&gt; directly (without having an &lt;font face="Courier New" size="3"&gt;XDocument&lt;/font&gt; involved at all)  &lt;li&gt;Manipulate the &lt;font face="Courier New" size="3"&gt;XElements&lt;/font&gt; or &lt;font face="Courier New" size="3"&gt;XAttributes&lt;/font&gt; directly.  &lt;li&gt;Save the resulting XML tree directly to a writer.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;XML names have been greatly simplified. LINQ to XML goes out of its way to make XML names as straightforward as possible. One can say that the complexity of XML names does not originate in namespaces, but from XML prefixes. XML prefixes can be used for reducing the keystrokes required when inputting XML or making XML easier to read, however prefixes are just shortcuts for using the full XML namespace. On input LINQ to XML resolves all prefixes to their corresponding XML Namespace and prefixes are&amp;nbsp; not exposed at all in the programming API. In LINQ to XML, a &lt;font face="Courier New" size="3"&gt;XName&lt;/font&gt; represents a full XML name consisting of an &lt;font face="Courier New" size="3"&gt;XNamespace&lt;/font&gt; and the local name. Developers will usually find it more convenient to use the &lt;font face="Courier New" size="3"&gt;XNamespace&lt;/font&gt; rather than the namespace URI string.  &lt;li&gt;An attribute (modeled by means of the &lt;font size="3"&gt;XAttribute&lt;/font&gt; class) is no longer a subclass of the node class). It is now simply a &lt;font face="Courier New" size="3"&gt;XName&lt;/font&gt;-value pair, which is what it always should have been.&lt;/li&gt;&lt;/ol&gt; &lt;h3&gt;Functional Construction&lt;/h3&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Querying&lt;/h3&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;WPF Data Binding&lt;/h3&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;&lt;/h3&gt; &lt;h3&gt;Tips and Tricks&lt;/h3&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Conclusion&lt;/h3&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Notes: Make sure how to construct an XML document from a LINQ database query&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=412" width="1" height="1"&gt;</description></item><item><title>Creating Application Shortcuts  with Google Chrome</title><link>http://footheory.com/blogs/bennie/archive/2008/09/07/creating-application-shortcuts-with-google-chrome.aspx</link><pubDate>Sun, 07 Sep 2008 18:46:44 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:410</guid><dc:creator>bennie</dc:creator><slash:comments>0</slash:comments><description>&lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;Unless you have been living under a rock for the last week, you probably know that Google shipped the first beta-version of it&amp;#39;s new browser, named &amp;quot;&lt;a href="http://tools.google.com/chrome/" target="_blank"&gt;Google Chrome&lt;/a&gt;&amp;quot;. I am not planning to start yet another debate here about why I think Google decided at this point that it needed to get in the Web browser business. You can read plenty of interesting comments on various blog sites, for example Paul Thurrot, from the &lt;a href="http://www.winsupersite.com/" target="_blank"&gt;Windows Supersite&lt;/a&gt; had some very interesting feedback on the subject in his &lt;a href="http://www.winsupersite.com/paul/podcast.asp" target="_blank"&gt;Windows Weekly Podcast&lt;/a&gt; with Leo Laporte.&lt;/p&gt; &lt;p&gt;Most of the&amp;nbsp; features introduced by Chrome have an equivalent in &lt;a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx" target="_blank"&gt;Microsoft&amp;#39;s upcoming IE 8 browser&lt;/a&gt; (beta 2 just shipped a couple of weeks ago). I do want to highlight one interesting feature of Chrome and that is the ability to &lt;strong&gt;create application shortcuts&lt;/strong&gt;.&lt;/p&gt; &lt;h3&gt;What is&amp;nbsp; a Chrome Application Shortcut?&lt;/h3&gt; &lt;p&gt;A Chrome Application Shortcut is basically a quick, streamlined way to access a Web Application&amp;#39;s functionality in it&amp;#39;s own window. You can create a shortcut on either the desktop, the &amp;quot;Start bar&amp;quot;, or the &amp;quot;Quick Launch&amp;quot; toolbar. Once the short cut is created, you can simply double-click the shortcut to launch the application in it&amp;#39;s own window. Using shortcuts is a nice alternative to launching the full browser window, and entering the URL (either manually or through a &amp;quot;favorites&amp;quot; entry).&lt;/p&gt; &lt;p&gt;Also, if you use Google Gears, you optionally have the ability to access the application&amp;#39;s functionality if offline mode (if so desired).&lt;/p&gt; &lt;h3&gt;Walkthrough&lt;/h3&gt; &lt;p&gt;To create a shortcut, first navigate to the URL of the Web Application. Next, click the Page menu next to the address bar, and select the &amp;quot;Create application shortcuts..&amp;quot; menu item, as is shown below:&lt;/p&gt; &lt;p&gt;&lt;a title="CreateChromeShortcut" href="http://www.flickr.com/photos/99548241@N00/2837303820/"&gt;&lt;img alt="CreateChromeShortcut" src="http://static.flickr.com/3174/2837303820_64e88811f8.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In the Google Gears dialog box that comes up, you can select the location(s) for your shortcut. So in my case, I elected to create a shortcut to Gmail, and I opted to have a shortcut on both my desktop and the &amp;quot;Quick Launch&amp;quot; bar.&lt;/p&gt; &lt;p&gt;&lt;a title="ChromeShortcutLocations" href="http://www.flickr.com/photos/99548241@N00/2836468873/"&gt;&lt;img alt="ChromeShortcutLocations" src="http://static.flickr.com/3134/2836468873_650b2d9311.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Note that Chrome will use the appropriate icon for your shortcut.&lt;/p&gt; &lt;p&gt;After creating your shortcut, I can simply double-click the shortcut, to open the selected Web Application as show below:&lt;/p&gt; &lt;p&gt;&lt;a title="ChromeShortcutInQuickLaunch" href="http://www.flickr.com/photos/99548241@N00/2836468821/"&gt;&lt;img alt="ChromeShortcutInQuickLaunch" src="http://static.flickr.com/3029/2836468821_67102fb325.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The application opens up in its own Chrome window, without any toolbar or address bar clutter, as shown below:&lt;/p&gt; &lt;p&gt;&lt;a title="ChromAppInOwnWindow" href="http://www.flickr.com/photos/99548241@N00/2836468951/"&gt;&lt;img alt="ChromAppInOwnWindow" src="http://static.flickr.com/3102/2836468951_07ebdfed39.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=410" width="1" height="1"&gt;</description></item><item><title>Unnecessary Abstractions</title><link>http://footheory.com/blogs/donnfelker/archive/2008/08/27/unnecessary-abstractions.aspx</link><pubDate>Wed, 27 Aug 2008 18:29:24 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:408</guid><dc:creator>donnfelker</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://jasonbock.net" target="_blank"&gt;Jason Bock&lt;/a&gt; had a similar title to this post awhile back … and I found a forehead-slapper today when reviewing some code in a app I’m working on during my free time. I seriously said “What the &amp;lt;ExplativeGoesHere&amp;gt;”. &lt;/p&gt;  &lt;p&gt;Here’s the code: &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://footheory.com/blogs/donnfelker/WindowsLiveWriter/UnnecessaryAbstractions_BDB7/image_4.png"&gt;&lt;img title="image" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="459" alt="image" src="http://footheory.com/blogs/donnfelker/WindowsLiveWriter/UnnecessaryAbstractions_BDB7/image_thumb_1.png" width="543" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;There is absolutely no need to do this. This is exactly WHAT the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.ipaddress.aspx" target="_blank"&gt;IPAddress class&lt;/a&gt; does. The worst part is that the programmer who developed this knew that the IPAddress Class existed.&amp;#160; I’m amazed daily.&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=408" width="1" height="1"&gt;</description><category domain="http://footheory.com/blogs/donnfelker/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Twin Cities Code Camp – Oct 11</title><link>http://footheory.com/blogs/donnfelker/archive/2008/08/27/twin-cities-code-camp-oct-11.aspx</link><pubDate>Wed, 27 Aug 2008 17:47:05 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:407</guid><dc:creator>donnfelker</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;I will be presenting at the 5th &lt;a href="http://www.twincitiescodecamp.com" target="_blank"&gt;Twin Cities Code Camp&lt;/a&gt; on October 11th. &lt;/p&gt;  &lt;p&gt;My session is entitled … &lt;/p&gt;  &lt;h4&gt;&lt;a name="s17"&gt;Smooth Operator: Using the Workflow Rules Engine Within WCF&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a name="s17"&gt;Ever changing business logic requires rule systems that are flexible to business demands. The majority of the time the business requires that these rules systems must be consumable by other applications. Come see how we can utilize the Rules Engine within Windows Workflow Foundation to evaluate our rules and simplify our rules configuration. We will then encompass this functionality within a Windows Communication Foundation Service which will enable consumers to utilize the service. &lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Visit &lt;a href="http://twincitiescodecamp.com" target="_blank"&gt;twincitiescodecamp.com&lt;/a&gt; to sign up! &lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=407" width="1" height="1"&gt;</description><category domain="http://footheory.com/blogs/donnfelker/archive/tags/Events/default.aspx">Events</category></item><item><title>Twin Cities Give Camp Update</title><link>http://footheory.com/blogs/donnfelker/archive/2008/08/23/twin-cities-give-camp-update.aspx</link><pubDate>Sat, 23 Aug 2008 15:56:56 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:406</guid><dc:creator>donnfelker</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;a href="http://twincitiesgivecamp.org" target="_blank"&gt;&lt;img title="image" style="border-right:0px;border-top:0px;margin:0px 10px 0px 0px;border-left:0px;border-bottom:0px;" height="339" alt="image" src="http://footheory.com/blogs/donnfelker/WindowsLiveWriter/TwinCitiesGiveCampUpdate_99F2/image_3.png" width="644" align="left" border="0" /&gt;&lt;/a&gt;The &lt;a href="http://twincitiesgivecamp.org" target="_blank"&gt;Twin Cities Give Camp&lt;/a&gt; site has been updated. &lt;/p&gt;  &lt;p&gt;If you would like to volunteer, you can sign up on the &lt;a href="http://twincitiesgivecamp.org/volunteer/" target="_blank"&gt;volunteer page&lt;/a&gt; and if you or your company would like to sponsor the event, you can sign up on the &lt;a href="http://twincitiesgivecamp.org/sponsors/" target="_blank"&gt;sponsors page&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;If you have any questions, please email us from the &lt;a href="http://twincitiesgivecamp.org/contact-us/" target="_blank"&gt;contact us&lt;/a&gt; page. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Side note: I have been having an intermittent problem with Grafffiti loading properly on the site. At times when you visit you will receive the graffiti cms error page. If you try to access the site again, it will go away. If you get an error, please let me know as I’m trying to sort it out with the host. Thanks!&lt;/em&gt;&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=406" width="1" height="1"&gt;</description><category domain="http://footheory.com/blogs/donnfelker/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://footheory.com/blogs/donnfelker/archive/tags/Exams/default.aspx">Exams</category></item><item><title>Insane Flight Prices</title><link>http://footheory.com/blogs/donnfelker/archive/2008/08/22/insane-flight-prices.aspx</link><pubDate>Fri, 22 Aug 2008 12:11:00 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:405</guid><dc:creator>donnfelker</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;I was on &lt;a href="http://www.sidestep.com" target="_blank"&gt;my favorite travel pricing site&lt;/a&gt; today and I was looking up how much flights were from MPLS to Des Moines. Now I&amp;#39;d probably never-ever fly to Des Moines because I believe its only about 3.5 hours away via car. But with gas prices these days you have to check it out. When I used to live in Phoenix, a group of friends and I would always go to Vegas every year. We drove a couple of times but we eventually found out that flying was actually cheaper (back then - 6-7 years ago). A round trip ticket would cost us 80 dollars. Talk about DEAL!!!!&lt;/p&gt;&lt;p&gt;&amp;nbsp;So, wondering if I could score the same for another short flight such as Des Moines would be awesome.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;YEAH. RIGHT.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;Look at this scree capture:&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://blog.donnfelker.com/content/binary/sidestep.png" title="WTF" alt="WTF" width="554" height="309" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Seriously. Over $700 dollars for a ticket? YOU GOTTA TO BE CRAZY! - or as the New Yorkers in the Bronx where I lived for awhile would say it &amp;quot;Yo dawg, dat price is banana&amp;#39;s!&amp;quot; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Its apparent the airlines no longer have deals (at least in this case). If I do go, I&amp;#39;ll be driving. :) &lt;br /&gt;&lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=405" width="1" height="1"&gt;</description><category domain="http://footheory.com/blogs/donnfelker/archive/tags/Misc/default.aspx">Misc</category></item><item><title>The Twin Cities Give Camp</title><link>http://footheory.com/blogs/donnfelker/archive/2008/08/12/the-twin-cities-give-camp.aspx</link><pubDate>Wed, 13 Aug 2008 03:13:14 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:404</guid><dc:creator>donnfelker</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;a href="http://footheory.com/blogs/donnfelker/WindowsLiveWriter/TheTwinCitiesGiveCamp_1385B/SpoonAndCherry_2.jpg"&gt;&lt;img title="SpoonAndCherry" style="border-right:0px;border-top:0px;margin:0px 15px 15px 0px;border-left:0px;border-bottom:0px;" height="520" alt="SpoonAndCherry" src="http://footheory.com/blogs/donnfelker/WindowsLiveWriter/TheTwinCitiesGiveCamp_1385B/SpoonAndCherry_thumb.jpg" width="395" align="left" border="0" /&gt;&lt;/a&gt; I’ve presented at code camps and given presentations to technical audiences and institutes and I will continue to do so. I have a passion for giving back to the community that has helped me become the what I am today. I’ve decided that I want to give back to the community even further. After doing some research to find someone (or a group) who might already be setting up a Give Camp I’ve come to the conclusion that they don’t exist here in the &lt;a href="http://www.mspmag.com" target="_blank"&gt;Twin Cities&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Therefore, I’ve decided to start up the &lt;a href="http://www.twincitiesgivecamp.org/" target="_blank"&gt;Twin Cities Give Camp&lt;/a&gt; (site not complete). The web site is &lt;a href="http://www.twincitiesgivecamp.org"&gt;www.twincitiesgivecamp.org&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;I’ll be updating the site this week with all relevant info in regards to the Give Camp. No dates have been set, but as soon as we have one the site will be updated. &lt;/p&gt;  &lt;h3&gt;What is a Give Camp?&lt;/h3&gt;  &lt;blockquote&gt;   &lt;p&gt;A Give Camp is a weekend-long event where software developers, designers, and database administrators donate their time to create custom software for non-profit organizations. This custom software could be a new web site for the nonprofit organization, a small data-collection application to keep track of members, or a application for the Red Cross that automatically emails a blood donor three months after they’ve donated blood to remind them that they are now eligible to donate again. The only limitation is that the project should be scoped to be able to be completed in a weekend. &lt;/p&gt;    &lt;p&gt;… &lt;/p&gt;    &lt;p&gt;At the Give Camp, there is an expectation of “What Happens at Give Camp, Stays at Give Camp”. Therefore, all source code must be turned over to the charities at the end of the weekend (developers cannot ask for payment) and the charities are responsible for maintaining the code moving forward (charities cannot expect the developers to maintain the codebase). &lt;/p&gt;    &lt;p&gt;&lt;a href="http://www.annarborgivecamp.org/WhatIsAGiveCamp.aspx" target="_blank"&gt;Source&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;More in depth info can be found here: &lt;a href="http://www.givecamp.org"&gt;www.givecamp.org&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Do you want to be a part of this awesome experience? &lt;/h3&gt;  &lt;p&gt;We are in need of volunteers, developers, designers, DBA’s, volunteers, Project Managers, Charities, Prizes, Giveaways, sponsors and more volunteers. If you would like to participate or sponsor this event, please let me know. I will update this blog as soon as &lt;a href="http://www.twincitiesgivecamp.org"&gt;www.twincitiesgivecamp.org&lt;/a&gt; is updated. I will be in contact with the local &lt;a href="http://www.pmi.org/" target="_blank"&gt;PMI&lt;/a&gt;, &lt;a href="http://www.theiiba.org/" target="_blank"&gt;IIBA&lt;/a&gt;, and &lt;a href="http://www.issa.org/" target="_blank"&gt;ISSA&lt;/a&gt;, &lt;a href="http://www.aitp.org/" target="_blank"&gt;AITP&lt;/a&gt; and local .NET User Groups. &lt;/p&gt;  &lt;p&gt;More info to come soon! &lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=404" width="1" height="1"&gt;</description><category domain="http://footheory.com/blogs/donnfelker/archive/tags/.NET/default.aspx">.NET</category><category domain="http://footheory.com/blogs/donnfelker/archive/tags/Events/default.aspx">Events</category></item><item><title>DiscountASP vs. Me</title><link>http://footheory.com/blogs/donnfelker/archive/2008/08/08/discountasp-vs-me.aspx</link><pubDate>Fri, 08 Aug 2008 13:25:00 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:403</guid><dc:creator>donnfelker</dc:creator><slash:comments>0</slash:comments><description>
&lt;p&gt;DiscountASP just won. Argh! I wrote a long blog post (because I dont have access to Live Writer on this PC) and then clicked Publish and it logged me out. Dont understand what I&amp;#39;m talking about? Read on ..&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
Unfortunately, what DiscountASP.NET does not tell you is that due to Community Server 2007’s large memory footprint (~100 megabytes with little to no activity), DiscountASP.NET has to recycle the application pool frequently, sometimes as often as every 5 minutes. The DiscountASP.NET policy is to recycle an individual website’s entire pool once it reaches a size of 100 megabytes.&lt;br /&gt;

&lt;br /&gt;Here are the consequences of being forced to recycle the application pool on a CS 2007 server:
&lt;br /&gt;
    &lt;br /&gt;* All logged-in users are logged out;
&lt;br /&gt;    * any posts that you may have been writing will be lost if you try to press the submit button;
    &lt;br /&gt;* the entire website is brought to a crawl with slow load times;
    &lt;br /&gt;* and in essence it makes Community Server 2007 unusable.
&lt;br /&gt;
Source - http://www.marketing-ninja.com/hosting/discountaspnet-and-community-server-do-not-mix-despite-what-discountaspnet-advertises/
&lt;/blockquote&gt;

*Shakes fist violently*

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;img src="http://footheory.com/aggbug.aspx?PostID=403" width="1" height="1"&gt;</description><category domain="http://footheory.com/blogs/donnfelker/archive/tags/.NET/default.aspx">.NET</category><category domain="http://footheory.com/blogs/donnfelker/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Is Premature Optimization Really Evil?</title><link>http://footheory.com/blogs/donnfelker/archive/2008/07/23/is-premature-optimization-really-evil.aspx</link><pubDate>Thu, 24 Jul 2008 04:41:31 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:400</guid><dc:creator>donnfelker</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;   &lt;table align="left"&gt;       &lt;tr&gt;         &lt;td&gt;&lt;img title="dominos" style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;margin:10px 10px 10px 0px;border-right-width:0px;" height="361" alt="dominos" src="http://footheory.com/blogs/donnfelker/WindowsLiveWriter/IsPrematureOptimizationReallyEvil_12D7C/dominos_3.jpg" width="504" align="left" border="0" /&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Photo Courtesy of: &lt;a href="http://www.flickr.com/photos/rosendahl/" target="_blank"&gt;rosendahl&lt;/a&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; My first initial answer is … it depends. (Isn’t that the case for everything?) :)&lt;/p&gt;  &lt;p&gt;Today I had conversation with a colleague and we were discussing how application developers don’t plan ahead. &lt;/p&gt;  &lt;p&gt;This eventually brought up the question/topic:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font style="background-color:#ffffff;" color="#00296c"&gt;“Is premature optimization pure evil?”&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;My colleague stated that all optimization should be done up front, while I on the other hand, disagree. In my opinion all development should be done first and then lets figure out where we might have some problems, with some exceptions (which we both agreed upon). &lt;/p&gt;  &lt;h3&gt;So, what did we agree upon? &lt;/h3&gt;  &lt;p&gt;Lets look at a classic example: &lt;/p&gt;  &lt;p&gt;Developer Joe and his team were asked to create an order management system that could handle up to 10,000 orders a day. This doesn’t sound like that big of an issue, and Joe and his team also agreed. It shouldn’t be a big issue. A fast database, a fast web server, and a few third party controls to interact with. No problem! Heck, this is pretty straightforward they thought. In reality, the requirements were very straight forward, no hidden features, no scope creep, nothing like that. Heck, it was a dream project come true. With that said - development ensued, and two months later Joe’s team delivered the product and everyone was excited to see the product run from end to end. (By the way, this was not done &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank"&gt;TDD&lt;/a&gt; or with any &lt;a href="http://en.wikipedia.org/wiki/Agile_software_development" target="_blank"&gt;Agile&lt;/a&gt; Methods – which &lt;a href="http://www.urbandictionary.com/define.php?term=imo" target="_blank"&gt;IMO&lt;/a&gt; would have caught any of our upcoming issues, if the tests were written correctly. But then again “&lt;a href="http://www.urbandictionary.com/define.php?term=if%20if%20was%20a%20fifth" target="_blank"&gt;If ‘if’ was a fifth then we’d all be drunk&lt;/a&gt;”). &lt;/p&gt;  &lt;p&gt;Joe’s team fired up the application for a demo and ran some orders through it and it worked great. They even ran 10 orders through the system in one minute (~14,400 Orders a day). They had gone above and beyond the call of duty (original requirement being 10,000 orders a day)! They were due for a raise! Life couldn&amp;#39;t be better! The system was released and the company started to use it. Orders were flowing through the system without failure and the business was happy. &lt;/p&gt;  &lt;h3&gt;Until the company decided to sell an exclusive hot item two weeks later … &lt;/h3&gt;  &lt;p&gt;Then &lt;a href="http://www.urbandictionary.com/define.php?term=SHTF" target="_blank"&gt;SHTF&lt;/a&gt;… All of a sudden, customers were experiencing time outs,&amp;#160; orders were being duplicated, and the customer service line was being rung off the hook. Essentially, all hell broke loose. After looking into the system, the developers noticed that the system had only accepted 6,000 orders. What gives? This system should handle 14,400 according to their tests. *everyone is scratching their head at this point* &lt;/p&gt;  &lt;h3&gt;Scalability is Relative&lt;/h3&gt;  &lt;p&gt;Scalability in this case, is relative. While looking at the stats, Joe’s team realized that those 6000 orders came in in about 1.5 hours. This was the first 1.5 hours that this product was available. At the end of the day the company eventually sold under 10,000 units, so why did this issue happen? &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Lets take a look at some stats: &lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt;&amp;#160;&lt;/td&gt;        &lt;td&gt;Orders Per Minute&lt;/td&gt;        &lt;td&gt;Time Between Orders (seconds)&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Original Spec (10,000 Per day)&lt;/td&gt;        &lt;td&gt;~7&lt;/td&gt;        &lt;td&gt;8.64&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Current State (6000 in 90 Minutes)&lt;/td&gt;        &lt;td&gt;~67&lt;/td&gt;        &lt;td&gt;0.9&lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Orders Per Minute Equation: Orders / Minutes&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Minutes: (HoursInDay * MinutesInHour)&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Orders Per Second Equation: Seconds / Orders&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Seconds: (HoursInDay * MinutesInHour * SecondsInMinute)&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Do we see the problem here? &lt;/p&gt;  &lt;p&gt;Again, scalability is relative. In this case, analysis and optimization was not done ahead of the time to anticipate the flood of orders at a peak period. The spec was straight forward:&amp;#160; &lt;strong&gt;The system is to be designed to handle an order rate of 10,000 orders a day. &lt;/strong&gt;The system was designed exactly to the spec, and in this case, &lt;u&gt;the system was designed incorrectly&lt;/u&gt;.&lt;/p&gt;  &lt;p&gt;Now, I have a confession… 6 years ago, I was Joe. Yes, I made this very mistake. I was a hero for a couple of weeks, then SHTF. :) Live and learn. Live and learn. &lt;/p&gt;  &lt;h3&gt;When We Agreed&lt;/h3&gt;  &lt;p&gt;My colleague and I both agreed that in certain instances premature optimization should be done, such as this case. The developers should optimize the order process to handle issues at peak times. Perhaps implementing a order service, based on MQ, or implementing a service bus for this type of high-availability process would be the best. In this case, we agree. All of this analysis and optimization should be done up front because this type of thing WILL be a problem at any peak utilization times. We both agree that neglecting to analyze the problem domain can and will lead to performance problems down the road. Plain and simple. &lt;/p&gt;  &lt;h3&gt;When We Disagreed&lt;/h3&gt;  &lt;p&gt;My colleague and I still disagree on the statement of “all code should be optimized up front”. In my opinion this is a &lt;a href="http://en.wikipedia.org/wiki/Big_Design_Up_Front" target="_blank"&gt;BDUF&lt;/a&gt; approach that I tend to shy away from. I don’t necessary mean that no design should happen up front, but I do think it should be limited. In an agile environment things tend to change, and we need to be able to adapt quickly. Wasting months in front of a whiteboard, with of reams of documentation, and endless meetings only slows the process down if something has to change down the road. Re-updating project baselines, and adjusting documentation and so forth is a huge hassle. I would like to state that there is a place for this type of development though. Some companies do require BDUF approaches because of huge regulatory compliance issues, so sometimes there is not much you can do about it. However process driven approaches such as &lt;a href="http://www.google.com/search?q=ITIL+%2B+AGILE&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:en-US:official&amp;amp;client=firefox-a" target="_blank"&gt;ITIL and Agile can work together if done properly&lt;/a&gt;. With that said, I tend to shy away from BDUF approaches because of a simple example that is also exemplified by &lt;a href="http://www.codinghorror.com/blog/archives/000061.html" target="_blank"&gt;Jeff Atwood in a previous post of his&lt;/a&gt; (and I agree with him and the many other experts in the field). Jeff adds a third rule to &lt;a href="http://cisx2.uma.maine.edu/NickTemp/JSP&amp;amp;JSDLec/jsd.html" target="_blank"&gt;M.A. Jacksons Optimization Rules&lt;/a&gt; that I like agree with the most: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;And I would add a third: don&amp;#39;t optimize work that doesn&amp;#39;t have to be done.&amp;#160; - Jeff Atwood&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This can be demonstrated as a sort routine. Lets say you have a menu that will be populated via user selections and the maximum number of values you can have in the menu is 100. You can either implement &lt;a href="http://msdn.microsoft.com/en-us/library/4d7sx9hd.aspx" target="_blank"&gt;IComparable&lt;/a&gt; and utilize the &lt;a href="http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx" target="_blank"&gt;List&amp;lt;T&amp;gt;.Sort() method&lt;/a&gt; to sort the class (which utilizes the &lt;a href="http://en.wikipedia.org/wiki/Quicksort" target="_blank"&gt;Quicksort Algorithm&lt;/a&gt;) which would be SUPER easy but may not be the “Fastest” method of sorting, or you could write an extension method to create your own sort routine to sort the 100 items. At this point we’re splitting hairs. A millisecond, or even 10 milliseconds, wont matter at this point in UI response. We’re only sorting a menu that will never grow beyond 100 items. At this point, pre-mature optimization is evil. There is NO need to rewrite something that that does the job well enough. Can we do it better? Yes! Is there a need to? NO. We wont get any value out of it. The time spend on development is wasted compared to the benefit to the application. &lt;/p&gt;  &lt;p&gt;On the other hand, if the menu had no upper bound limit, then we would want to implement the best sort routine we could because some routines are exponentially faster than others. In this case we would want to optimize early because the possibility of a bottleneck can and might occur in certain situations. &lt;/p&gt;  &lt;h3&gt;It all boils down to: “It Depends”&lt;/h3&gt;  &lt;p&gt;At the end of the day, the true answer to “Is Premature optimization evil?” is “It Depends”. &lt;/p&gt;  &lt;p&gt;It depends on the problem. It depends on the architecture and design. It depends on analysis of the domain. It depends on the factors which “could” come into play. &lt;/p&gt;  &lt;p&gt;Finally, what it really boils down to is: &lt;u&gt;It depends on MONEY&lt;/u&gt;. We can optimize all day and gobs of the companies money in development/optimization costs. This is why deep analysis into the problems need to take place. As architects we need to define the business process that could impact our architecture design and implementation and development of code. At some point we need the business to interject into this analysis and optimization party to say “Listen, I’m willing to deal with X, but I’m not willing to deal with Y”. At that point, our jobs as Architects is to define how much X costs compared to how much Y costs. Only then will the business truly know what should be done juxtaposed with what should not be done. &lt;/p&gt;  &lt;p&gt;To sum it up in my own personal opinion, premature optimization &lt;em&gt;can&lt;/em&gt; be evil. We, as architects and developers need to think about the problem at hand before we write a line of code. As I stated above, there is no need for a full 90 page document on the process, but at least whiteboard with your colleagues. Are you a solo developer and need someone to bounce ideas off of? Join your local user group, join some groups online, visit the MSDN architecture forum and ask questions. &lt;/p&gt;&lt;img src="http://footheory.com/aggbug.aspx?PostID=400" width="1" height="1"&gt;</description><category domain="http://footheory.com/blogs/donnfelker/archive/tags/Agile/default.aspx">Agile</category><category domain="http://footheory.com/blogs/donnfelker/archive/tags/.NET/default.aspx">.NET</category><category domain="http://footheory.com/blogs/donnfelker/archive/tags/Design/default.aspx">Design</category><category domain="http://footheory.com/blogs/donnfelker/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>Mobilizing Your/My Blog - mobile.blog.donnfelker.com</title><link>http://footheory.com/blogs/donnfelker/archive/2008/07/17/mobilizing-your-my-blog-mobile-blog-donnfelker-com.aspx</link><pubDate>Thu, 17 Jul 2008 12:18:51 GMT</pubDate><guid isPermaLink="false">9ce7e6ef-4587-4f0e-939d-3f75f3a8ddfc:399</guid><dc:creator>donnfelker</dc:creator><slash:comments>0</slash:comments><description>&lt;p&