<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.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>Discussions on SQL Server Manageability and Development.</title><link>http://blogs.msdn.com/b/oliviermeyer/</link><description /><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>My last MSDN blog post, for a little while...</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2010/09/24/my-last-msdn-blog-post-for-a-little-while.aspx</link><pubDate>Thu, 23 Sep 2010 23:37:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10067086</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=10067086</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2010/09/24/my-last-msdn-blog-post-for-a-little-while.aspx#comments</comments><description>&lt;p&gt;I will be transitioning to a role outside Microsoft starting in October but intend to keep blogging in the future about topics of interest around software&amp;nbsp;development, SQL Server spatial and other technology and entrepreneurship topics.&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;My new blog site will be: &lt;a href="http://oliviersmeyer.wordpress.com"&gt;http://oliviersmeyer.wordpress.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the meantime, for those interested in SQL Server Spatial topics, please check out Ed's blog at: &lt;a href="http://blogs.msdn.com/b/edkatibah/"&gt;http://blogs.msdn.com/b/edkatibah/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please keep in touch.&lt;/p&gt;
&lt;p&gt;Sincerely,&lt;/p&gt;
&lt;p&gt;Olivier&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10067086" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Goodbye/">Goodbye</category></item><item><title>Cloud Computing and GeoSpatial forces unite in DC...</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2010/06/09/cloud-computing-and-geospatial-forces-unite-in-dc.aspx</link><pubDate>Wed, 09 Jun 2010 17:23:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10022446</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=10022446</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2010/06/09/cloud-computing-and-geospatial-forces-unite-in-dc.aspx#comments</comments><description>&lt;p&gt;I will be attending the &lt;a href="http://www.com-geo.org"&gt;www.com-geo.org&lt;/a&gt; conference in Washington DC in a couple weeks and it promises to be a pretty interesting conference, bringing together many of the major players in GeoSpatial (Public and Private Sector, ISVs, Academia).&amp;nbsp;&amp;nbsp;&amp;nbsp; I'm attending to learn more about the state of cloud computing adoption in this space and also to hear about some pretty interesting uses of computing and spatial towards public policy problems.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;If you will be in DC during that time and would like to discuss your own experiences and thoughts on cloud computing, please reach out and stop by,&amp;nbsp;&amp;nbsp;your time and feedback will be sincerely appreciated.&amp;nbsp; You can also share your thoughts on Cloud Computing&amp;nbsp;&lt;a target="_blank" href="http://www.surveymonkey.com/s/HFYBMSV" title="Com-Geo Conference Survey"&gt;here&lt;/a&gt; if you will not be able to attend the conference.&lt;/p&gt;
&lt;p&gt;Thank you,&lt;/p&gt;
&lt;p&gt;Olivier&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10022446" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Spatial/">Spatial</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Washington+DC/">Washington DC</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Conference/">Conference</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Cloud+Computing/">Cloud Computing</category></item><item><title>Calling all web and application developers: We need your help to make SQL Server better for developers.</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2010/03/30/calling-all-web-and-application-developers-we-need-your-help-to-make-sql-server-better-for-developers.aspx</link><pubDate>Tue, 30 Mar 2010 19:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9987644</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=9987644</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2010/03/30/calling-all-web-and-application-developers-we-need-your-help-to-make-sql-server-better-for-developers.aspx#comments</comments><description>&lt;P&gt;Good afternoon,&lt;/P&gt;
&lt;P&gt;The SQL Server team is currently undertaking a short survey to learn more about the information you need from a database development and administration tool about your databases once they are "up and running".&lt;/P&gt;
&lt;P&gt;Please take a few minutes to fill out the survey &lt;A title="Web-based Database Development and Administration" href="http://www.surveymonkey.com/s/9VPPCZQ" target=_blank mce_href="http://www.surveymonkey.com/s/9VPPCZQ"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Thank you for your help, your time and feedback will truly help make SQL Server a better product for web and application developers.&lt;/P&gt;
&lt;P&gt;Sincerely,&lt;/P&gt;
&lt;P&gt;Olivier&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9987644" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/management/">management</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/SQL+Server/">SQL Server</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/development/">development</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/administration/">administration</category></item><item><title>The Excel Spatial Spreadsheet (Part Deux)</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2009/12/29/the-excel-spatial-spreadsheet-part-deux.aspx</link><pubDate>Tue, 29 Dec 2009 21:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9942072</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=9942072</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2009/12/29/the-excel-spatial-spreadsheet-part-deux.aspx#comments</comments><description>&lt;P&gt;I hope everyone had a great holiday and that Santa was good to you.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;My kids made out like troopers this year with the grandparents buying them a Wii.&amp;nbsp; Yes I know I work for Microsoft -- but we already have an XBOX 360 – actually we have 2 of them but that’s another story.&amp;nbsp; I probably should feel more guilty about having a Wii but I didn’t buy it myself… and… ok and its pretty fun to play… I mean show the kids how to use it.&amp;nbsp;&amp;nbsp; I just hope my friend Richard in the XBOX team is not reading my blog.&lt;/P&gt;
&lt;P&gt;As for me, got some sweaters, some books and some gift cards which I used to buy the complete Rocky DVD collection and the complete Indiana Jones DVD collection.&lt;/P&gt;
&lt;H4&gt;All I want for Christmas is Part Deux of Excel Spatial&lt;/H4&gt;
&lt;P&gt;With the year quickly coming to a close, I realized I had limited time to blog a couple more times before 2010 started and that I owed everyone a follow up to my &lt;A href="http://blogs.msdn.com/oliviermeyer/archive/2009/11/17/introducing-the-excel-spatial-spreadsheet-building-an-excel-add-in-for-doing-spatial-analysis-and-spatial-operations-in-net.aspx" mce_href="http://blogs.msdn.com/oliviermeyer/archive/2009/11/17/introducing-the-excel-spatial-spreadsheet-building-an-excel-add-in-for-doing-spatial-analysis-and-spatial-operations-in-net.aspx"&gt;previous blog article&lt;/A&gt; on building Excel Add-Ins to turn Excel into a Spatial Spreadsheet.&lt;/P&gt;
&lt;P&gt;In this somewhat lengthy follow on blog article I will revise and extend the COM automation add-in that was introduced in the previous article.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In the 3rd article I will introduce a second Excel add-in which will provide functionality for doing visualization of spatial data within the Excel spreadsheet.&lt;/P&gt;
&lt;H4&gt;When we last left our spatial add-in…&lt;/H4&gt;
&lt;P&gt;In the &lt;A href="http://blogs.msdn.com/oliviermeyer/archive/2009/11/17/introducing-the-excel-spatial-spreadsheet-building-an-excel-add-in-for-doing-spatial-analysis-and-spatial-operations-in-net.aspx" mce_href="http://blogs.msdn.com/oliviermeyer/archive/2009/11/17/introducing-the-excel-spatial-spreadsheet-building-an-excel-add-in-for-doing-spatial-analysis-and-spatial-operations-in-net.aspx"&gt;last article&lt;/A&gt; I mentioned that there were some annoying side effects to using the automated COM automation support from .NET.&amp;nbsp; The main side effect was the exposure to COM automation of some of the inherited public methods from the Object base class (Equals, GetType, ToString).&amp;nbsp;&amp;nbsp; While this is not a catastrophic problem, it does introduce confusion for end users, since these methods have nothing to do with spatial analysis.&lt;/P&gt;
&lt;H4&gt;Refactoring the MySpatialFunctions Class&lt;/H4&gt;
&lt;P&gt;In order to hide from Excel the inherited methods from the Object base class we want to have finer control over what .NET will expose as the COM/Automation interface for our automation add-in.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;H5&gt;(1) Define a new Interface&lt;/H5&gt;
&lt;P&gt;The first step to achieving finer grained control over the exposure of our spatial functions is to refactor the current MySpatialFunctions class into a a class that is derived from an Interface, let us call it IExcelSpatialFunctions.&lt;/P&gt;
&lt;DIV id=codeSnippetWrapper&gt;
&lt;DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum1&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt; ExcelSpatial&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum2&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum3&gt;   3:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;interface&lt;/SPAN&gt; IExcelSpatialFunctions&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum4&gt;   4:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum5&gt;   5:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; INTERSECTS(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; Shape1, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; Shape2);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum6&gt;   6:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum7&gt;   7:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #008000"&gt;// All other methods to be exposed to Excel&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum8&gt;   8:&lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum9&gt;   9:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;H5&gt;(2) Decorate it with COM Attributes&lt;/H5&gt;
&lt;P&gt;Now we can decorate the IExcelSpatialFunction interface with some attributes from the System.Runtime.InteropServices and System.ComponentModel namespaces.&amp;nbsp; These attributes will control how the interface will be exposed as a COM Automation interface for Excel.&lt;/P&gt;
&lt;P&gt;The &lt;STRONG&gt;[ComVisible(True)]&lt;/STRONG&gt; attribute is used to expose the IExcelSpatialFunctions interface as a COM interface and the &lt;STRONG&gt;[Guid()]&lt;/STRONG&gt; attribute is used to specify a unique ID for this interface.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Note: The &lt;STRONG&gt;[Description()]&lt;/STRONG&gt; attribute is used to provide additional help about the exposed functions and appears in the resulting type library for the COM component.&amp;nbsp;&amp;nbsp; Unfortunately that information will not be displayed by Excel (in the formula picker dialog for example) but I include it for completeness and the description should be visible to developers integrating with the COM automation add-in in VB or other COM enabled hosting development tools.&lt;/P&gt;
&lt;DIV id=codeSnippetWrapper&gt;
&lt;DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum1&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum2&gt;   2:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Collections.Generic;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum3&gt;   3:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Linq;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum4&gt;   4:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Text;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum5&gt;   5:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Runtime.InteropServices;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum6&gt;   6:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.ComponentModel;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum7&gt;   7:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum8&gt;   8:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt; ExcelSpatial&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum9&gt;   9:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum10&gt;  10:&lt;/SPAN&gt;     [ComVisible(&lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum11&gt;  11:&lt;/SPAN&gt;     [Guid(&lt;SPAN style="COLOR: #006080"&gt;"916F9116-1A08-4c09-8492-8E34C6EB9214"&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum12&gt;  12:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;interface&lt;/SPAN&gt; IExcelSpatialFunctions&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum13&gt;  13:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum14&gt;  14:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;P&gt;&lt;SPAN style="COLOR: #606060" id=lnum15&gt;  15:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #008000"&gt;/// Returns True if a geography instance intersects another&lt;/SPAN&gt;&lt;SPAN style="COLOR: #008000"&gt;.&lt;/SPAN&gt;&lt;/P&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum16&gt;  16:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum17&gt;  17:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;param name="wktShape1"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum18&gt;  18:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;param name="wktShape2"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum19&gt;  19:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum20&gt;  20:&lt;/SPAN&gt;         [Description(&lt;SPAN style="COLOR: #006080"&gt;"Returns True if a geography instance …"&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum21&gt;  21:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; INTERSECTS(&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; Shape1, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; Shape2);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum22&gt;  22:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum23&gt;  23:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #008000"&gt;// All other methods we wish to expose to Excel.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum24&gt;  24:&lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum25&gt;  25:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;H5&gt;(3) Update our Spatial Function Class&lt;/H5&gt;
&lt;P&gt;We then update our original MySpatialFunctions class to derive from the interface.&amp;nbsp; I also took the liberty to rename the class to ExcelSpatialFunctions.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The primary change from the previous implementation is to change the &lt;STRONG&gt;[ClassInterface()]&lt;/STRONG&gt; attribute to &lt;FONT color=#0000ff&gt;ClassInterfaceType.None&lt;/FONT&gt; from the original ClassInterfaceType.AutoDual.&amp;nbsp; We are being “explicit” about our exposed client interface with IExcelSpatialInterface as the interface to our class, so we don’t want an auto-generated COM interface for the class.&lt;/P&gt;
&lt;P&gt;We also specify the Guid for the class using the &lt;STRONG&gt;[Guid()]&lt;/STRONG&gt; attribute and the ProgId for the class using the &lt;STRONG&gt;[ProgId()]&lt;/STRONG&gt; attribute.&amp;nbsp; The ProgId is the human-readable string that will be used in Excel when selecting a formula category as well as the the name that will appear in the add automation add-in dialog box in Excel. &lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=rem&gt;// ...&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.ComponentModel;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Runtime.InteropServices;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; Microsoft.SqlServer.Types;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; ExcelSpatial&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;{&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;    [ComVisible(&lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;)]&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;    [Guid(&lt;SPAN class=str&gt;"F743643F-510D-416d-868D-92F5A5771101"&lt;/SPAN&gt;)]&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;    [ProgId(&lt;SPAN class=str&gt;"ExcelSpatial.SpatialFunctions"&lt;/SPAN&gt;)]&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;    [ClassInterface(ClassInterfaceType.None)]&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;    [Description(&lt;SPAN class=str&gt;"Spatial add-in for Excel based on …."&lt;/SPAN&gt;)]&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; SpatialFunctions : &lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;        IExcelSpatialFunctions&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;    {&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;        &lt;SPAN class=preproc&gt;#region&lt;/SPAN&gt; IExcelSpatialFunctions Members&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;/// Returns True if a geography instance intersects another.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;param name="wktShape1"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;param name="wktShape2"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  26:  &lt;/SPAN&gt;        [Description(&lt;SPAN class=str&gt;"Returns True if a geography instance..."&lt;/SPAN&gt;)]&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  27:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;bool&lt;/SPAN&gt; INTERSECTS(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; Shape1, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; Shape2)&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  28:  &lt;/SPAN&gt;        {&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  29:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;bool&lt;/SPAN&gt; bReturnValue = &lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  30:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  31:  &lt;/SPAN&gt;            SqlGeography geoShape1 = Shape1.ToGeography();&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  32:  &lt;/SPAN&gt;            SqlGeography geoShape2 = Shape2.ToGeography();&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  33:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  34:  &lt;/SPAN&gt;            bReturnValue = geoShape1.STIntersects(geoShape2).IsTrue;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  35:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  36:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; bReturnValue;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  37:  &lt;/SPAN&gt;        }&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  38:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  39:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// All the other methods to expose to Excel&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  40:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  41:  &lt;/SPAN&gt;        &lt;SPAN class=preproc&gt;#endregion&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  42:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  43:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// Other supporting code for the add-in&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT color=#000000&gt;&lt;SPAN class=lnum&gt;  44:  &lt;/SPAN&gt;}&lt;/FONT&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Note: For those familiar with the String class and looking at the above code, you may be asking yourself&amp;nbsp; “I don’t remember there being a ToGeography() method on the string class.”&amp;nbsp; Don’t worry, you’re not forgetting things, read on to next section… &lt;/P&gt;
&lt;H5&gt;(4) Updated COM registration methods&lt;/H5&gt;
&lt;P&gt;My &lt;A href="http://blogs.msdn.com/oliviermeyer/archive/2009/11/17/introducing-the-excel-spatial-spreadsheet-building-an-excel-add-in-for-doing-spatial-analysis-and-spatial-operations-in-net.aspx" mce_href="http://blogs.msdn.com/oliviermeyer/archive/2009/11/17/introducing-the-excel-spatial-spreadsheet-building-an-excel-add-in-for-doing-spatial-analysis-and-spatial-operations-in-net.aspx"&gt;previous blog post&lt;/A&gt; had those methods chopped off, so I’ve updated them and reposted them below.&amp;nbsp;&amp;nbsp; The following methods are called by VS (or by regasm.exe) to register your class within the registry to make it visible to COM Automation clients like Excel.&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; SpatialFunctions : &lt;/PRE&gt;&lt;PRE&gt;        IExcelSpatialFunctions,&lt;/PRE&gt;&lt;PRE class=alt&gt;{&lt;/PRE&gt;&lt;PRE&gt;   &lt;SPAN class=rem&gt;// ...&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;   &lt;SPAN class=preproc&gt;#region&lt;/SPAN&gt; COM / Automation Registration Methods&lt;/PRE&gt;&lt;PRE class=alt&gt;   [ComRegisterFunctionAttribute]&lt;/PRE&gt;&lt;PRE&gt;   &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; RegisterFunction(Type type)&lt;/PRE&gt;&lt;PRE class=alt&gt;   {&lt;/PRE&gt;&lt;PRE&gt;      Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, &lt;SPAN class=str&gt;"Programmable"&lt;/SPAN&gt;));&lt;/PRE&gt;&lt;PRE class=alt&gt;      RegistryKey key = Registry.ClassesRoot.OpenSubKey(&lt;/PRE&gt;&lt;PRE&gt;                GetSubKeyName(type, &lt;SPAN class=str&gt;"InprocServer32"&lt;/SPAN&gt;), &lt;/PRE&gt;&lt;PRE class=alt&gt;                &lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;      key.SetValue(&lt;SPAN class=str&gt;""&lt;/SPAN&gt;, &lt;/PRE&gt;&lt;PRE class=alt&gt;           System.Environment.SystemDirectory + &lt;SPAN class=str&gt;@"\mscoree.dll"&lt;/SPAN&gt;, &lt;/PRE&gt;&lt;PRE&gt;           RegistryValueKind.String);&lt;/PRE&gt;&lt;PRE class=alt&gt;   }&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;   [ComUnregisterFunctionAttribute]&lt;/PRE&gt;&lt;PRE&gt;   &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; UnregisterFunction(Type type)&lt;/PRE&gt;&lt;PRE class=alt&gt;   {&lt;/PRE&gt;&lt;PRE&gt;       Registry.ClassesRoot.DeleteSubKey(&lt;/PRE&gt;&lt;PRE class=alt&gt;            GetSubKeyName(type, &lt;SPAN class=str&gt;"Programmable"&lt;/SPAN&gt;), &lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE class=alt&gt;   }&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;   &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; GetSubKeyName(Type type, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; subKeyName)&lt;/PRE&gt;&lt;PRE&gt;   {&lt;/PRE&gt;&lt;PRE class=alt&gt;       System.Text.StringBuilder s = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; System.Text.StringBuilder();&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;       s.Append(&lt;SPAN class=str&gt;@"CLSID\{"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;       s.Append(type.GUID.ToString().ToUpper());&lt;/PRE&gt;&lt;PRE class=alt&gt;       s.Append(@"}\");&lt;/PRE&gt;&lt;PRE&gt;       s.Append(subKeyName);&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;       &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; s.ToString();&lt;/PRE&gt;&lt;PRE class=alt&gt;    }&lt;/PRE&gt;&lt;PRE&gt;    &lt;SPAN class=preproc&gt;#endregion&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/STYLE&gt;

&lt;H3&gt;Cleaning up the plumbing a little bit&lt;/H3&gt;
&lt;H4&gt;Making the string class cooler than it already is.&lt;/H4&gt;
&lt;P&gt;A large part of the Excel add-in is about handling textual representations of spatial data, converting them to SQL spatial types, performing calculations and then returning back an appropriate textual representation of the result.&lt;/P&gt;
&lt;P&gt;It turns out there are several well adopted textual representations for spatial data.&amp;nbsp;&amp;nbsp; SQL Server’s type library supports two of the most common: WKT (well known text) and GML (geographical markup language).&amp;nbsp;&amp;nbsp; A third popular standard is KML which was created by Google (through an acquisition I believe).&amp;nbsp;&amp;nbsp; There are also some newcomers including GeoJSON.&lt;/P&gt;
&lt;P&gt;It would be great if we build some of this “text handling” directly into the spatial types and the string class in an extensible manner.&amp;nbsp;&amp;nbsp;&amp;nbsp; Ideally I would like to be able to do things like:&lt;/P&gt;
&lt;DIV id=codeSnippetWrapper&gt;
&lt;DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum1&gt;   1:&lt;/SPAN&gt; String strSomePoint = &lt;SPAN style="COLOR: #006080"&gt;"POINT(-8.6666 27.666)"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum2&gt;   2:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum3&gt;   3:&lt;/SPAN&gt; SqlGeography geo = strSomePoint.ToGeography();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum4&gt;   4:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum5&gt;   5:&lt;/SPAN&gt; strWKT = geo.ToWKT();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum6&gt;   6:&lt;/SPAN&gt; strGML = geo.ToGML();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum7&gt;   7:&lt;/SPAN&gt; strKML = geo.ToKML();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum8&gt;   8:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #606060" id=lnum9&gt;   9:&lt;/SPAN&gt; SqlGeography geo2 = strGML.ToGeography();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;The SQL Spatial Types are sealed classes and we don’t easily have access to the source code for string to extend it, but that doesn’t mean you can’t extend them.&amp;nbsp; You can use &lt;A href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;.NET Extension Methods&lt;/A&gt; to add new methods to existing classes.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;H5&gt;Creating an .NET Extension Method&lt;/H5&gt;
&lt;P&gt;For those not familiar with creating &lt;A href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;a .NET extension method&lt;/A&gt;, here is the generic pattern for creating one:&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; SomeClass&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; ReturnType methodname(&lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt; Type anInstance, ....)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;    {&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// anInstance is the instance of Type that we can act on&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/STYLE&gt;

&lt;H5&gt;Extending the string and SqlGeography types&lt;/H5&gt;
&lt;P&gt;In this case we are interested in extending the string type and the SqlGeography type.&amp;nbsp; I chose to create a separate project as part of my solution to generate an assembly that hosts a single SpatialTextHandling class which uses .NET Extension methods to extend the String and the SqlGeography classes.&amp;nbsp; This was completely optional, the extension methods could have easily been part of the main project.&lt;/P&gt;
&lt;P&gt;This packaging allows these extension methods to be reused in other projects that leverage the SQL spatial types.&amp;nbsp;&amp;nbsp; In order to “consume” the extensions, you simply include the SpatialExtensions assembly in your project and include its namespace into your code.&lt;/P&gt;
&lt;DIV id=codeSnippetWrapper&gt;
&lt;DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Collections.Generic;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Linq;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Text;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; Microsoft.SqlServer.Types;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Data.SqlTypes;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Text.RegularExpressions;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.Xml.Serialization;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; System.IO;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt; SpatialExtensions&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;{&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; SpatialTextHandling&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; FINGERPRINT_GML = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #006080"&gt;"&amp;lt;?xml version=\"1.0\" encoding=\"utf-8\"?&amp;gt;"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; FINGERPRINT_KML = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #006080"&gt;"&amp;lt;?xml version=\"1.0\" encoding=\"utf-8\"?&amp;gt;&amp;lt;kml "&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; FINGERPRINT_GEOJSON = &lt;SPAN style="COLOR: #006080"&gt;"["&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// Returns a SqlGeography object based on the text representation &lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// contained in the string, attempts to &lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// autodetect the text representation if hint not provided.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;param name="p_strGeographyAsText"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; SqlGeography ToGeography(&lt;SPAN style="COLOR: #0000ff"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; p_strGeographyAsText)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            SqlGeography geoShape = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;       &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #008000"&gt;// Assume WKT as the default and exhaustively try &lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #008000"&gt;// everything else if it fails.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                geoShape = SqlGeography.Parse(p_strGeographyAsText);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #008000"&gt;// Must not have been WKT, fall through and try &lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #008000"&gt;// to check for other text formats&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt; == geoShape)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (p_strGeographyAsText.StartsWith(FINGERPRINT_GEOJSON))&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #008000"&gt;// TODO: Implement JSON Parsing&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentException(&lt;SPAN style="COLOR: #006080"&gt;"JSON not yet implemented."&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (p_strGeographyAsText.StartsWith(FINGERPRINT_KML))&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #008000"&gt;// TODO: Implement KML Parsing&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentException(&lt;SPAN style="COLOR: #006080"&gt;"KML not yet implemented."&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                } &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (p_strGeographyAsText.StartsWith(FINGERPRINT_GML))&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        &lt;SPAN style="COLOR: #008000"&gt;// XML Format, assume it is GML for now, at some point we'll need to support&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        &lt;SPAN style="COLOR: #008000"&gt;// mutliple XML representations.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        System.Xml.XmlTextReader xmlTextReader = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                          &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; System.Xml.XmlTextReader(p_strGeographyAsText, &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                                        System.Xml.XmlNodeType.Document, &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                                        &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        System.Data.SqlTypes.SqlXml xml = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                            &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; System.Data.SqlTypes.SqlXml(xmlTextReader);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        geoShape = SqlGeography.GeomFromGml(xml, 4326);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception xmlException)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        &lt;SPAN style="COLOR: #008000"&gt;// Problem parsing the GML encoding &lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt; == geoShape)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentException(&lt;SPAN style="COLOR: #006080"&gt;"Unsupported text for a shape."&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; geoShape;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// Returns the WKT representation of a geography object.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;param name="p_geography"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; ToWKT(&lt;SPAN style="COLOR: #0000ff"&gt;this&lt;/SPAN&gt; SqlGeography p_geography)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; p_geography.ToString();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// Returns the GML representation of a Geography object.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;param name="p_geography"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; ToGML(&lt;SPAN style="COLOR: #0000ff"&gt;this&lt;/SPAN&gt; SqlGeography p_geography)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; p_geography.AsGml().Value.ToString();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;// Additional methods&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;}&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/STYLE&gt;

&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You’ll notice the main extension method is defined on the string class and is called &lt;STRONG&gt;ToGeography()&lt;/STRONG&gt;.&amp;nbsp;&amp;nbsp; The ToGeography() method attempts to auto-detect the text encoding or representation of the string and turns it into a new instance of a SqlGeography class.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt; &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;bool&lt;/SPAN&gt; INTERSECTS(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; Shape1, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; Shape2)&lt;/PRE&gt;&lt;PRE&gt; {&lt;/PRE&gt;&lt;PRE class=alt&gt;     &lt;SPAN class=kwrd&gt;bool&lt;/SPAN&gt; bReturnValue = &lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;     SqlGeography geoShape1 = Shape1.&lt;STRONG&gt;ToGeography&lt;/STRONG&gt;();&lt;/PRE&gt;&lt;PRE&gt;     SqlGeography geoShape2 = Shape2.&lt;STRONG&gt;ToGeography&lt;/STRONG&gt;();&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;     bReturnValue = geoShape1.STIntersects(geoShape2).IsTrue;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;     &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; bReturnValue;&lt;/PRE&gt;&lt;PRE class=alt&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;So in the INTERSECTS function above we can now pass in a string that is encoded in any of the supported textual representations, in fact Shape1 could be in WKT format while Shape2 is in GML format.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;This becomes pretty powerful when you think about how users work with Excel, often combining data from different sources and copying and pasting data from different web sites and other spreadsheets.&amp;nbsp;&amp;nbsp;&amp;nbsp; The ToGeography() extension method attempts to make it transparent to the end user.&lt;/P&gt;
&lt;P&gt;Please note that this SpatialExtensions class is a work in progress with the current implementation supporting only WKT and GML.&amp;nbsp; My goal is to eventually detect and automatically support KML, GeoJSON and GeoRSS.&lt;/P&gt;
&lt;P&gt;The other methods in this SpatialExtensions class extend SqlGeography with convenience methods to return different text representations and as you’ll see below methods to handle specifying some constraints for the text representation.&lt;/P&gt;
&lt;H5&gt;Sometimes a picture is worth more than 32,767 characters&lt;/H5&gt;
&lt;P&gt;A textual representation is a really convenient representation to achieve interoperability between applications and to provide human-readable formats for end users, but in the case of complex spatial objects (detailed country borders, etc.) it can get quite lengthy.&lt;/P&gt;
&lt;P&gt;Excel 2007 and earlier have a &lt;A href="http://office.microsoft.com/en-us/excel/HP100738491033.aspx?pid=CH101030621033" mce_href="http://office.microsoft.com/en-us/excel/HP100738491033.aspx?pid=CH101030621033"&gt;limitation on the number of characters&lt;/A&gt; that can be stored in an Excel cell and that limit is 32K characters.&amp;nbsp;&amp;nbsp; While this only affects complex shapes with lots of vertices, it would be nice if our add-in could somehow automatically make sure that results it returns are always represent-able as a string less than 32,000 characters long.&lt;/P&gt;
&lt;P&gt;In order to reduce the complexity (# of a vertices) for a spatial object we can turn to the Reduce method on the SqlGeography type.&amp;nbsp;&amp;nbsp; The “trick” is to ensure that all our functions that return a string representation of a SqlGeography call Reduce if they are going to be “longer” than 32,000 characters.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;I added some special versions of the ToWKT() and ToGML() extension methods to the SqlGeography class in the SpatialTextHandling class that allow the specification of a maximum string size.&amp;nbsp; These functions are the same as the original version, but they make a call to a helper method called ReduceForTextRepresentation() to ensure the resulting string will be less than the maximum specified.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Caveat: &lt;U&gt;I make no guarantees about the validity of the approach&lt;/U&gt; I use to “guess” at an appropriate value for the epsilon parameter to Reduce().&amp;nbsp; It seems to work relatively well for those cases I tested, but I’m sure the algorithm could be made more correct and any thought you have on this are appreciated.&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; SpatialExtensions&lt;/PRE&gt;&lt;PRE&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; SpatialTextHandling&lt;/PRE&gt;&lt;PRE&gt;    {&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=rem&gt;// .....&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp; &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; ToWKT(&lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt; SqlGeography p_geography, &lt;/PRE&gt;&lt;PRE class=alt&gt;                    &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; p_nMaxLength)&lt;/PRE&gt;&lt;PRE&gt;        {&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=rem&gt;// Assume all will be well&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; strGeography = p_geography.ToWKT();&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// Check to make sure the string is not too big.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (strGeography.Length &amp;gt; p_nMaxLength)&lt;/PRE&gt;&lt;PRE&gt;            {&lt;/PRE&gt;&lt;PRE class=alt&gt;                &lt;SPAN class=rem&gt;// Reduce the shape as best we can to make it &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;                &lt;SPAN class=rem&gt;// fit in the string length specified.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;                strGeography = ReduceForTextRepresentation(p_geography, &lt;/PRE&gt;&lt;PRE&gt;                   strGeography.Length, &lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p_nMaxLength).ToWKT();&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/PRE&gt;&lt;PRE&gt;            }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// Return the string&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; strGeography;&lt;/PRE&gt;&lt;PRE&gt;        }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;       &lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; SqlGeography &lt;/PRE&gt;&lt;PRE&gt;            ReduceForTextRepresentation(SqlGeography p_geography, &lt;/PRE&gt;&lt;PRE class=alt&gt;                    &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; p_nCurrentStringLength, &lt;/PRE&gt;&lt;PRE&gt;                    &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; p_nStringTargetLength) &lt;/PRE&gt;&lt;PRE class=alt&gt;        {&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// Take a best guess as to the right value for reduce by&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=rem&gt;// looking at the "string length" per point in the shape, &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// estimating what the maximum # of points that is acceptable&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=rem&gt;// should be, and then using the average distance/length per &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// point * the ratio of current points to needed points&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=rem&gt;// as a basis for epsilon in the reduce formula.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; nNumPoints = p_geography.STNumPoints().Value;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; fShapeLengthPerPoint = &lt;/PRE&gt;&lt;PRE&gt;            p_geography.STLength().Value / nNumPoints;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; nStringLengthPerPoint = &lt;/PRE&gt;&lt;PRE class=alt&gt;            p_nCurrentStringLength / nNumPoints;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; nMaxPoints = &lt;/PRE&gt;&lt;PRE&gt;            p_nStringTargetLength / nStringLengthPerPoint;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=rem&gt;// how many new points to each original points must we have?&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; fOverByFactor = &lt;/PRE&gt;&lt;PRE class=alt&gt;            (&lt;SPAN class=kwrd&gt;float&lt;/SPAN&gt;)nNumPoints / (&lt;SPAN class=kwrd&gt;float&lt;/SPAN&gt;)nMaxPoints;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=rem&gt;// Not sure if this is "scientific" but tell the shape to reduce &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// so that we have a tolerance of n * the average length of line &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=rem&gt;// segments in the shape.   It probably over compensates.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; fReduceTolerance = &lt;/PRE&gt;&lt;PRE&gt;            ((fShapeLengthPerPoint / 2) * fOverByFactor);&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// Let's try it&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; (p_geography.Reduce(fReduceTolerance));&lt;/PRE&gt;&lt;PRE&gt;        }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;// Additional methods&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;    }&lt;/PRE&gt;&lt;PRE class=alt&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;H3&gt;Implementing some Spatial Aggregate Functions&lt;/H3&gt;
&lt;P&gt;Up until now the functions I have shown take relative simple parameters, for example the INTERSECTS function takes two strings and returns a string.&amp;nbsp;&amp;nbsp;&amp;nbsp; Sometimes it is useful for a method to act on a list of values or in the case of Excel, on a range of cells.&amp;nbsp; One class of functions that could benefit from knowing how to handle a range of cells as a parameter would be aggregate functions. &lt;/P&gt;
&lt;H4&gt;Making the Add-in aware of Excel&lt;/H4&gt;
&lt;P&gt;To this point our add-in and the spatial methods we have created have been pretty generic and have not had to have any knowledge of Excel or the Excel Object Model.&amp;nbsp;&amp;nbsp; In order to accept parameters that represent ranges of cells and possibly return results that represent a list of values it becomes necessary to include some Excel namespaces and assemblies into our project.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;You will need to add a reference to the &lt;STRONG&gt;Microsoft.Office.Interop.Excel&lt;/STRONG&gt; assembly to your project and include its namespace in the ExcelSpatialFunctions class definition files.&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; Excel = Microsoft.Office.Interop.Excel;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;We can now start defining some functions that accept Excel cell ranges as parameters.&lt;/P&gt;
&lt;P&gt;The example below will accept a range of cells containing various spatial objects (LINES, POINTS, etc.) and will return a GEOMETRYCOLLECTION that represents the UNION of all those shapes.&lt;/P&gt;
&lt;H5&gt;UNIONMANY function&lt;/H5&gt;
&lt;P&gt;First we add a UNIONMANY function declaration in the IExcelSpatialFunctions interface which will take a generic object for the cell range (we will cast that object to an Excel.Range in the implementation).&amp;nbsp; &lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; ExcelSpatial&lt;/PRE&gt;&lt;PRE&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;    [ComVisible(&lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;PRE&gt;    [Guid(&lt;SPAN class=str&gt;"916F9116-1A08-4c09-8492-8E34C6EB9214"&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;PRE class=alt&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;interface&lt;/SPAN&gt; IExcelSpatialFunctions&lt;/PRE&gt;&lt;PRE&gt;    {&lt;/PRE&gt;&lt;PRE class=alt&gt;        ...&lt;/PRE&gt;&lt;PRE&gt;          &lt;/PRE&gt;&lt;PRE class=alt&gt;        [Description(&lt;SPAN class=str&gt;"Returns an object representing the union of….."&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; UNIONMANY(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; Range);&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/STYLE&gt;

&lt;P&gt;The implementation the UNIONMANY function consists of iterating through all the cells specified in the Range and repeatedly calling the union method exposed by the resulting SqlGeography of the previous iteration with the contents of the current cell.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;As you can imagine, creating the UNION of many complex shapes can result in a very complex shape (lots of vertices), one whose textual representation may far exceed Excel’s cell content limit mentioned earlier in the article.&amp;nbsp;&amp;nbsp; We leverage the SpatialExtensions work from above to ensure that that UNIONMANY result will result in a shape that will fit in the 32,767 character limit.&lt;/P&gt;
&lt;STYLE type=text/css&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/STYLE&gt;

&lt;DIV id=codeSnippetWrapper&gt;
&lt;DIV style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px" id=codeSnippet&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;[Description(&lt;SPAN style="COLOR: #006080"&gt;"Returns an object representing the union of two or more geography instances."&lt;/SPAN&gt;)]&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; UNIONMANY(&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt; Range)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;{&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; wktUnionManyShape = &lt;SPAN style="COLOR: #006080"&gt;""&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    SqlGeography geoUnionManyShape = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;// Get reference to the excel range object&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        Excel.Range cellRange = (Excel.Range) Range;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;// How many cells are we dealing with&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; nRows = cellRange.Rows.Count;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; nColumns = cellRange.Columns.Count;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #008000"&gt;// Now go through all the remaining cells and keep "unioning" them.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; nColumn = 0; nColumn &amp;lt; nColumns; nColumn++)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; nRow = 0; nRow &amp;lt; nRows; nRow++)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;try&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #008000"&gt;// Look up the cell in question in Excel&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    Excel.Range currentCell = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                          (Excel.Range) cellRange.Cells[nRow+1, nColumn+1];&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    String wktCurrentShape = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                          currentCell.Value2.ToString();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    SqlGeography geoCurrentShape = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                          wktCurrentShape.ToGeography();&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt; == geoUnionManyShape)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        &lt;SPAN style="COLOR: #008000"&gt;// This is the first shape in the union, &lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        &lt;SPAN style="COLOR: #008000"&gt;// so we just use it as is&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        geoUnionManyShape = geoCurrentShape;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        &lt;SPAN style="COLOR: #008000"&gt;// We need to perform the union of the current shape &lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        &lt;SPAN style="COLOR: #008000"&gt;// with the ongoing union shape&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        SqlGeography geoUnion = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                            geoUnionManyShape.STUnion(geoCurrentShape);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        &lt;SPAN style="COLOR: #008000"&gt;// Update the ongoing union for the next iteration&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                        geoUnionManyShape = geoUnion;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt; (Exception cellEx)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #008000"&gt;// Ignore bad stuff in conversion (union those that&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    &lt;SPAN style="COLOR: #008000"&gt;// are valid, ignore those that are not)&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                    System.Diagnostics.Trace.WriteLine(cellEx.ToString());&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;                }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;            }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;catch&lt;/SPAN&gt;(Exception ex)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    {&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ArgumentException(&lt;SPAN style="COLOR: #006080"&gt;"Expected geographies"&lt;/SPAN&gt;,ex);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    }&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (geoUnionManyShape != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;        wktUnionManyShape = &lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;          geoUnionManyShape.ToWKT(MAXIMUM_WKT_LENGTH);&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;&amp;nbsp;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; wktUnionManyShape;&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;PRE style="BORDER-BOTTOM-STYLE: none; TEXT-ALIGN: left; 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: 'Courier New', courier, monospace; DIRECTION: ltr; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"&gt;}&lt;/PRE&gt;&lt;!--CRLF--&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;H5&gt;Some thoughts on Aggregates&lt;/H5&gt;
&lt;P&gt;There are some additional useful aggregate functions that could be implemented using a same approach (for example a LINESTRING constructor which uses &lt;A href="http://blogs.msdn.com/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx" mce_href="http://blogs.msdn.com/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx"&gt;the builder API&lt;/A&gt; to build a line-string from a set of points).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;One set of functions that I am particularly interested in investigating in the future would be aggregate functions to perform clustering analysis on spatial data.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;For example doing cluster analysis from customer location data to find best potential locations for new business branch offices or doing analysis on web traffic to find potential locations for data center load balancing or caching strategies.&lt;/P&gt;
&lt;H4&gt;Making the Add-in “super aware” of Excel&lt;/H4&gt;
&lt;P&gt;Up to this point Excel has been in the driver’s seat sort of speak.&amp;nbsp; That is Excel “calls into” our add-in and for the most part we read what Excel gives us to perform some calculations. &lt;/P&gt;
&lt;P&gt;It is also possible for our add-in to also take the driver’s seat from time to time and call into Excel itself. There are limited reasons to do this, so my recommendation is to use this carefully.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;While I much prefer to make components know very little about each other, there are some cool things you can do if you know you are being called from Excel.&amp;nbsp; For example populating the spreadsheet, formatting cells or even calling Excel provided functions.&lt;/P&gt;
&lt;H5&gt;Gaining Access to the Excel Application Object&lt;/H5&gt;
&lt;P&gt;When Excel loads an add-in as part of its startup, it will investigate if that add-in implements a special interface called &lt;STRONG&gt;Extensibility.IDTExtensibility2&lt;/STRONG&gt; (from the Extensibility assembly).&amp;nbsp;&amp;nbsp; If our class implements the IDTExtensibility2 interface, then Excel will call its methods upon loading and unloading our add-in.&amp;nbsp;&amp;nbsp; That provides us a great place in time to gain a reference to the Excel application object.&lt;/P&gt;
&lt;P&gt;So we update the ExcelSpatialFunctions class to also derive from the &lt;A href="http://msdn.microsoft.com/en-us/library/extensibility.aspx" mce_href="http://msdn.microsoft.com/en-us/library/extensibility.aspx"&gt;IDTExtensibility2&lt;/A&gt; interface and minimally implement the 5 methods it declares.&amp;nbsp; The only method we are truly interested in is the &lt;STRONG&gt;OnConnection&lt;/STRONG&gt; method which will provide us a reference to the Excel application object.&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; SpatialFunctions : &lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;        IExcelSpatialFunctions,&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;        Extensibility.IDTExtensibility2&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;    {&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; Excel.Application m_excelApplication = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;       . . .&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=preproc&gt;#region&lt;/SPAN&gt; IDTExtensibility2 Members&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Extensibility.IDTExtensibility2.OnConnection(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; Application, &lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;                Extensibility.ext_ConnectMode ConnectMode, &lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;                &lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; AddInInst, &lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;                &lt;SPAN class=kwrd&gt;ref&lt;/SPAN&gt; Array custom)&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;        {&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// Keep a reference to the Application object from Excel&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;            m_excelApplication = (Excel.Application)Application;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;        }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;        . . .&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE&gt;        &lt;SPAN class=preproc&gt;#endregion&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;    }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;H5&gt;Finding out Who’s Calling?&lt;/H5&gt;
&lt;P&gt;One potential idea for leveraging our knowledge of Excel would be to somehow indicate through formatting that a particular cell is hosting a spatial function result.&amp;nbsp;&amp;nbsp; The trick is knowing which cell caused our function to be called since Excel does not pass in a reference to the calling cell (there is no “this” reference to the current cell or cell range).&lt;/P&gt;
&lt;P&gt;It turns out you can in fact get that reference through the Excel application object and its method get_Caller.&amp;nbsp; Once you have a reference to the cell or cell range you are free to do what you please to it.&amp;nbsp; In addition to formatting, in the case of array formulas you can use the reference to infer the size of the return array.&amp;nbsp; I also believe but have not yet tried it that this could be a method for achieving asynchronous calculations.&lt;/P&gt;
&lt;P&gt;The following code is for a helper method to let you get a reference to the cell or cell range that caused the call to a function.&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt; &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; Excel.Range GetCallingCellRange()&lt;/PRE&gt;&lt;PRE&gt; {&lt;/PRE&gt;&lt;PRE class=alt&gt;    Excel.Range rangeCallingCells = &lt;/PRE&gt;&lt;PRE&gt;           (Excel.Range) m_excelApplication.get_Caller(System.Type.Missing);&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; rangeCallingCells;&lt;/PRE&gt;&lt;PRE class=alt&gt; }&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/STYLE&gt;

&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Once you have access to the Excel application object you can navigate to other add-ins and make calls into them, you call built-in Excel functions and also do higher level order functions like printing and other Excel operations.&amp;nbsp;&amp;nbsp; A lot of power… use it wisely since your add-in could affect the user experience the end user expects from Excel. &lt;/P&gt;
&lt;H3&gt;So is spatial data special?&lt;/H3&gt;
&lt;H4&gt;Turns out you already have a lot of it.&lt;/H4&gt;
&lt;P&gt;Most business users don’t start out with some ready made WKT encoded geospatial data sets.&amp;nbsp; They typically start from a list of customers, accounts, sites, web logs or more specifically postal addresses and IP Addresses.&lt;/P&gt;
&lt;P&gt;In order to make these add-ins truly approachable to all information workers we should add some ability to turn standard postal and IP address information into spatial objects, specifically POINTs.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/ParseAndLocate_4.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/ParseAndLocate_4.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=ParseAndLocate border=0 alt=ParseAndLocate src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/ParseAndLocate_thumb_1.png" width=367 height=211 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/ParseAndLocate_thumb_1.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/ParseAndLocate2_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/ParseAndLocate2_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=ParseAndLocate2 border=0 alt=ParseAndLocate2 src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/ParseAndLocate2_thumb.png" width=366 height=211 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/ParseAndLocate2_thumb.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H5&gt;Adding Geocoding to our Add-In&lt;/H5&gt;
&lt;P&gt;Luckily for us there are a variety of geocoding web services out on the “cloud” and Microsoft offers such a service for postal addresses through Bing Maps (the &lt;A href="http://msdn.microsoft.com/en-us/library/dd877971.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd877971.aspx"&gt;MapPoint Web Services and SDK&lt;/A&gt;).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Note: Using MapPoint web service requires a Bing Maps developer account, you can sign up for a developer account &lt;A href="https://www.bingmapsportal.com/" mce_href="https://www.bingmapsportal.com/"&gt;here&lt;/A&gt;.&amp;nbsp;&amp;nbsp; Signing up will provide you with the credentials (username, password) you will need to make calls against the web service.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;I added a &lt;STRONG&gt;PARSEANDLOCATE&lt;/STRONG&gt; function to the IExcelSpatialFunctions interface and to the ExcelSpatialFunctions class that accepts a string and expects that string to contain a postal address or partial postal address and returns a POINT spatial object with the latitude and longitude of the specified address, zip code or region.&lt;/P&gt;
&lt;P&gt;Thankfully the MapPoint Web Service does the heavy lifting here as it can handle different combinations or permutations of addresses relatively well.&lt;/P&gt;
&lt;P&gt;In order to access the web service you will need to sign up for a developer account (see above) and you will need to add a Web Reference to your project to point to the MapPoint web service URL (for example: &lt;A href="http://staging.mappoint.net/standard-30/mappoint.wsdl" mce_href="http://staging.mappoint.net/standard-30/mappoint.wsdl"&gt;http://staging.mappoint.net/standard-30/mappoint.wsdl&lt;/A&gt;) and get a proxy class to the web service.&lt;/P&gt;
&lt;P&gt;The MapPoint Web Service SDK provides a Find service which is the service that provides geocoding, it expects an Address object as its parameter.&amp;nbsp;&amp;nbsp; The same service provides a helper method to turn a string address into an Address object.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; ExcelSpatial.MapPoint;    &lt;SPAN class=rem&gt;// reference to mappoint web service proxy&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; ExcelSpatial&lt;/PRE&gt;&lt;PRE class=alt&gt;{&lt;/PRE&gt;&lt;PRE&gt;    &lt;SPAN class=rem&gt;// ...&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; SpatialFunctions : &lt;/PRE&gt;&lt;PRE class=alt&gt;        IExcelSpatialFunctions&lt;/PRE&gt;&lt;PRE&gt;          &lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=rem&gt;// ...&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;PRE&gt;&lt;SPAN class=rem&gt;&lt;/SPAN&gt;&lt;/PRE&gt;        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; PARSEANDLOCATE(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; FullAddress)&lt;/PRE&gt;&lt;PRE class=alt&gt;        {&lt;/PRE&gt;&lt;PRE&gt;            Address parsedAddress = MapPointParseAddress(FullAddress);&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            SqlGeography geoLocation = MapPointFindLatLon(parsedAddress);&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; geoLocation.ToWKT(MAXIMUM_WKT_LENGTH);&lt;/PRE&gt;&lt;PRE class=alt&gt;        }&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;    &lt;SPAN class=preproc&gt;#region&lt;/SPAN&gt; MapPoint Web Service Helper Methods&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=rem&gt;/// This helper method will return a POINT SqlGeography that &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;/// is the LatLon of the address.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;param name="p_mappointAddress"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; SqlGeography MapPointFindLatLon(Address p_mappointAddress)&lt;/PRE&gt;&lt;PRE class=alt&gt;        {&lt;/PRE&gt;&lt;PRE&gt;            SqlGeography geoPoint = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;            {&lt;/PRE&gt;&lt;PRE&gt;                &lt;SPAN class=rem&gt;// Create instance of the mappoint web service proxy&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;                FindServiceSoap findService = MapPointGetFindService();&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;                &lt;SPAN class=rem&gt;// Create the FindAddressSpecification&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;                FindAddressSpecification findAddressSpec = &lt;/PRE&gt;&lt;PRE class=alt&gt;                    &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; FindAddressSpecification();&lt;/PRE&gt;&lt;PRE&gt;                findAddressSpec.InputAddress = p_mappointAddress;&lt;/PRE&gt;&lt;PRE class=alt&gt;                findAddressSpec.DataSourceName = &lt;SPAN class=str&gt;"MapPoint.NA"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;                &lt;SPAN class=rem&gt;// For any addresses we find -- we want the LatLong returned&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;                FindOptions findOptions = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; FindOptions();&lt;/PRE&gt;&lt;PRE class=alt&gt;                findOptions.ThresholdScore = 0;&lt;/PRE&gt;&lt;PRE&gt;                findOptions.ResultMask = FindResultMask.LatLongFlag;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;                &lt;SPAN class=rem&gt;// Just get the 1st / best match&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;                FindRange findRange = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; FindRange();&lt;/PRE&gt;&lt;PRE&gt;                findRange.StartIndex = 0;&lt;/PRE&gt;&lt;PRE class=alt&gt;                findRange.Count = 1;&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;                findOptions.Range = findRange;&lt;/PRE&gt;&lt;PRE&gt;                findAddressSpec.Options = findOptions;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;                &lt;SPAN class=rem&gt;// Make the call to get any matching addresses (with &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;                FindResults findResults = &lt;/PRE&gt;&lt;PRE&gt;                findService.FindAddress(findAddressSpec);&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;                &lt;SPAN class=rem&gt;// Were there any matches?&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;                &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (findResults.NumberFound &amp;gt; 0)&lt;/PRE&gt;&lt;PRE&gt;                {&lt;/PRE&gt;&lt;PRE class=alt&gt;                    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (findResults.Results.Length &amp;gt; 0)&lt;/PRE&gt;&lt;PRE&gt;                    {&lt;/PRE&gt;&lt;PRE class=alt&gt;                        &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; lat = &lt;/PRE&gt;&lt;PRE&gt;                findResults.Results[0].FoundLocation.LatLong.Latitude;&lt;/PRE&gt;&lt;PRE class=alt&gt;                        &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; lon = &lt;/PRE&gt;&lt;PRE&gt;                findResults.Results[0].FoundLocation.LatLong.Longitude;&lt;/PRE&gt;&lt;PRE class=alt&gt;                        geoPoint = &lt;/PRE&gt;&lt;PRE&gt;                SqlGeography.Point(lat, lon, DEFAULT_SRID);&lt;/PRE&gt;&lt;PRE class=alt&gt;                    }&lt;/PRE&gt;&lt;PRE&gt;                }&lt;/PRE&gt;&lt;PRE class=alt&gt;            }&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)&lt;/PRE&gt;&lt;PRE class=alt&gt;            {&lt;/PRE&gt;&lt;PRE&gt;                &lt;SPAN class=kwrd&gt;throw&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Exception(&lt;SPAN class=str&gt;"There was a problem."&lt;/SPAN&gt;, ex);&lt;/PRE&gt;&lt;PRE class=alt&gt;            }&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; geoPoint;&lt;/PRE&gt;&lt;PRE&gt;        }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=rem&gt;/// Helper method that wraps retrieving instance of web service&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; FindServiceSoap MapPointGetFindService()&lt;/PRE&gt;&lt;PRE class=alt&gt;        {&lt;/PRE&gt;&lt;PRE&gt;            &lt;SPAN class=rem&gt;// Create instance of the mappoint web service proxy&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;            FindServiceSoap findService = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; FindServiceSoap();&lt;/PRE&gt;&lt;PRE&gt;            findService.Credentials = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; NetworkCredential(&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Properties.ExcelSpatialResources.strVEUserName, &lt;/PRE&gt;&lt;PRE&gt;               Properties.ExcelSpatialResources.strVEPassword);&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; findService;&lt;/PRE&gt;&lt;PRE&gt;        }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=rem&gt;/// Helper method that wraps call to the MapPoint web service &lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;param name="p_strFullAddress"&amp;gt;&amp;lt;/param&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=rem&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;        &lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; Address MapPointParseAddress(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; p_strFullAddress)&lt;/PRE&gt;&lt;PRE&gt;        {&lt;/PRE&gt;&lt;PRE class=alt&gt;            FindServiceSoap findService = MapPointGetFindService();&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            Address address = findService.ParseAddress(p_strFullAddress, &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;            &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; address;&lt;/PRE&gt;&lt;PRE&gt;        }&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;        &lt;SPAN class=preproc&gt;#endregion&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	background-color: #ffffff; font-family: consolas, "Courier New", courier, monospace; color: black; font-size: small
}
.csharpcode pre {
	margin: 0em
}
.csharpcode .rem {
	color: #008000
}
.csharpcode .kwrd {
	color: #0000ff
}
.csharpcode .str {
	color: #006080
}
.csharpcode .op {
	color: #0000c0
}
.csharpcode .preproc {
	color: #cc6633
}
.csharpcode .asp {
	background-color: #ffff00
}
.csharpcode .html {
	color: #800000
}
.csharpcode .attr {
	color: #ff0000
}
.csharpcode .alt {
	background-color: #f4f4f4; margin: 0em; width: 100%
}
.csharpcode .lnum {
	color: #606060
}&lt;/STYLE&gt;

&lt;H3&gt;What about that map you teased us with last time?&lt;/H3&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Text is great and as developers we tend to spend most of our day dealing with text in the form of code, but spatial data really lights up when you can visualize and interact with it using a map.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;What would be really awesome (ok I’m a little biased here) would be the ability to embed a mapping control directly into the spreadsheet and to link the map control’s rendering&amp;nbsp; to ranges of cells and formulas in the spreadsheet.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;That would indeed be cool! (again I’m a little biased here), maybe it could look something like this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/Africa_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/Africa_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Africa border=0 alt=Africa src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/Africa_thumb.png" width=517 height=410 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetPartDeux_9C87/Africa_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;In the next set of blog articles we will develop a second Excel add-in that will show one approach for achieving that result.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;I’ll then post a final article in this series about creating an installer to install both add-ins as this can be a particular challenge when combining different types of add-ins into a single installer.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;I am hoping to post the complete code for both Excel add-ins on CodePlex early next year so folks can download and extend the project, but I first need to clean up the code a little bit.&lt;/P&gt;
&lt;P&gt;I look forward to hearing about your own experiments with the SQL Server spatial types and the Excel Spatial Spreadsheet example.&lt;/P&gt;
&lt;P&gt;Sincerely,&lt;/P&gt;
&lt;P&gt;Olivier&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9942072" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/GUI/">GUI</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Spatial/">Spatial</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/PDC/">PDC</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/VSTO/">VSTO</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Excel/">Excel</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/-NET/">.NET</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Add_2D00_In/">Add-In</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Geocoding/">Geocoding</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/COM/">COM</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/-NET+Extension+Methods/">.NET Extension Methods</category></item><item><title>PDC 2009 Session Recording – Building Location-Aware Application with SQL Server Spatial Library is now posted.</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2009/11/20/pdc-2009-session-recording-building-location-aware-application-with-sql-server-spatial-library-is-now-posted.aspx</link><pubDate>Fri, 20 Nov 2009 19:03:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9926380</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=9926380</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2009/11/20/pdc-2009-session-recording-building-location-aware-application-with-sql-server-spatial-library-is-now-posted.aspx#comments</comments><description>&lt;p&gt;You can find a recording of the session Ed, Torsten and I gave at PDC on building location-aware applications using the SQL Server Spatial Library here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVR33"&gt;http://microsoftpdc.com/Sessions/SVR33&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Have a great weekend,&lt;/p&gt;  &lt;p&gt;Olivier&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9926380" width="1" height="1"&gt;</description></item><item><title>Introducing the Excel Spatial Spreadsheet – Building an Excel Add-In for doing Spatial Analysis and Spatial Operations in .NET.</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2009/11/17/introducing-the-excel-spatial-spreadsheet-building-an-excel-add-in-for-doing-spatial-analysis-and-spatial-operations-in-net.aspx</link><pubDate>Tue, 17 Nov 2009 04:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923373</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=9923373</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2009/11/17/introducing-the-excel-spatial-spreadsheet-building-an-excel-add-in-for-doing-spatial-analysis-and-spatial-operations-in-net.aspx#comments</comments><description>&lt;P&gt;Good Evening,&lt;/P&gt;
&lt;P&gt;I sit down to write this blog article on the plane on my way to LA in preparation for tomorrow’s presentation at PDC on the same subject.&amp;nbsp;&amp;nbsp; In my last article I described the ability to leverage the hard work that the SQL Server team put into building a &lt;A href="http://blogs.msdn.com/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx" target=_blank mce_href="http://blogs.msdn.com/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx"&gt;spatial library for your own .NET applications&lt;/A&gt;.&amp;nbsp;&amp;nbsp;&amp;nbsp; In this article I will continue to describe how the SQL Server Spatial Library can be leveraged in many different types of applications, and in this case for use with Microsoft Office, and more specifically Microsoft Excel.&lt;/P&gt;
&lt;P&gt;It will likely take a couple blog articles to cover the entire scope of this project, but this first article will show all the necessary steps to get the base functionality built and we will expand on it over the coming two articles.&lt;/P&gt;
&lt;P&gt;Let’s get started building the ES2 (Excel Spatial Spreadsheet) add-in…&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/ES2-LogoImage_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/ES2-LogoImage_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=ES2-LogoImage border=0 alt=ES2-LogoImage src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/ES2-LogoImage_thumb.png" width=519 height=139 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/ES2-LogoImage_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H2&gt;Pre-Requisites&lt;/H2&gt;
&lt;P&gt;In order to follow along you will need Visual Studio 2008, Microsoft Excel 2007 and you will also need to download the SQL Server Option Pack which contains the SQL Server types assemblies (or Install SQL Server 2008 on your development machine as it also includes the same assemblies).&lt;/P&gt;
&lt;H2&gt;Office Add-In Technologies&lt;/H2&gt;
&lt;P&gt;Microsoft Office offers a wide variety of options for developers to extend the core office suite.&amp;nbsp;&amp;nbsp; There is of course the built in Visual Basic for Applications which allows developers to build applications hosted by Office.&amp;nbsp;&amp;nbsp; You can also build different kinds of add-ins that plug into Office.&amp;nbsp;&amp;nbsp; Some add-ins are more “GUI” oriented, allowing you to add task panes, new ribbons while others focus on providing more “backend” services like new formulas for Excel.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;There are also a few options for building add-ins for office.&amp;nbsp;&amp;nbsp; Visual Studio includes the VSTO project types and you can also go with the more traditional and complex native extensions written in C / C++.&lt;/P&gt;
&lt;H2&gt;What the heck is a Spatial Function for Excel?&lt;/H2&gt;
&lt;P&gt;For this blog article, our focus is to build new spatial operators that can be used within Excel as if they were native Excel functions.&amp;nbsp; We want to enable an Excel User (Information Worker) who wants to find out the area of a state or zip code to type in something like:&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff size=2 face="Courier New"&gt;&lt;STRONG&gt;=AREA(ZipCodeShape)&lt;/STRONG&gt;&lt;/FONT&gt; &lt;/P&gt;
&lt;P&gt;or to find out if a customer is located within a kilometer of a store location:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#0000ff size=2 face="Courier New"&gt;=IF(DISTANCE(CustomerLocation, StoreLocation)&amp;lt;1000,”YES”,”NO”)&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;it would also be nice if an Excel user could easily turn a user’s existing data like addresses&amp;nbsp; into spatial objects for analysis by calling out to web services offered by Bing maps for example:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#0000ff size=2 face="Courier New"&gt;=PARSEANDLOCATE(“One Microsoft Way, Redmond WA”)&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In fact we’d like to enable someone who is not an expert in spatial analysis to just “try and learn” spatial operators quickly and painlessly, which is exactly what Microsoft Excel enables (you can always Undo and try out different scenarios by pasting a new formula in a different cell).&lt;/P&gt;
&lt;P align=center&gt;&lt;STRONG&gt;&lt;FONT size=3&gt;We want “The Power of SQL Spatial with the Simplicity of Excel”&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To achieve that goal I’ll&amp;nbsp; be leveraging a type of add-in called an Automation Add-In.&amp;nbsp;&amp;nbsp; For those who remember the days of COM / DCOM programming (yes I’m that old) and terms like late binding, IDispatch and automation interfaces then you’ll be right at home, for those who were able to skip that time period, don’t stress out, .NET makes it pretty easy to create COM Automation classes.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;H2&gt;Implementing the base Spatial Automation Add-In&lt;/H2&gt;
&lt;P&gt;Start Visual Studio 2008 or 2010 as &lt;U&gt;Administrator&lt;/U&gt; (more on this later) and create a new .NET 3.5 C# Class Library Project and name it something interesting like MySpatialFunctions.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Create-Project_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Create-Project_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Create-Project border=0 alt=Create-Project src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Create-Project_thumb.png" width=539 height=365 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Create-Project_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Once the newly created project is loaded in Visual Studio, right click on the project to bring up the project properties dialog.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Click the [Assembly…] button on the Application Tab of the project properties and make sure the “Make Assembly COM-Visible” is checked.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Assembly-Info_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Assembly-Info_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Assembly-Info border=0 alt=Assembly-Info src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Assembly-Info_thumb.png" width=366 height=363 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Assembly-Info_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;We also need to ensure that the “Register for COM Interop” on the Build tab is checked.&amp;nbsp; This step tells Visual Studio to register any COM components in the project every time the project is rebuilt.&amp;nbsp; The alternative is to manually register the assembly using the regasm.exe .NET utility.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Project-Properties_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Project-Properties_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Project-Properties border=0 alt=Project-Properties src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Project-Properties_thumb.png" width=646 height=472 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Project-Properties_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now rename the default class name to something a little nicer than Class1, for example MySpatialFunctions.&amp;nbsp; Please note that the name you pick for the class will show up in Excel’s drop down list of functions as the Category name for your functions (example shown below):&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/ExcelInsertFunction.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/ExcelInsertFunction.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Excel-InsertFunction border=0 alt=Excel-InsertFunction src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/ExcelInsertFunction_thumb.png" width=420 height=365 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/ExcelInsertFunction_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Following the instructions from the &lt;A href="http://blogs.msdn.com/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx" target=_blank mce_href="http://blogs.msdn.com/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx"&gt;previous article&lt;/A&gt; we need to add a reference to the SQL Server Type library which includes the Spatial data types.&amp;nbsp; Right click on the references folder in your newly created project and add a reference to the SQL Server Type assembly.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/InsertReference.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/InsertReference.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Insert-Reference border=0 alt=Insert-Reference src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/InsertReference_thumb.png" width=454 height=384 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/InsertReference_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;You will also need to add:&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; Microsoft.SqlServer.Types;&lt;/PRE&gt;
&lt;P&gt;
&lt;STYLE type=text/css&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;
to the beginning of your class file to bring in the .NET definitions for the spatial data types.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Now let’s make sure your class can act as a COM object by bringing in the .NET COM interop support and decorating your class with the necessary attributes [ClassInterface(ClassInterfaceType.AutoDual)].&amp;nbsp; Without getting too deep into COM terminology, this tells .NET to expose our class as supporting both COM late-binding (IDispatch / Automation) and early binding clients.&lt;/P&gt;
&lt;P&gt;Your class file should now look something like the following:&amp;nbsp; &lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Collections.Generic;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Linq;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Text;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; Microsoft.SqlServer.Types;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; System.Runtime.InteropServices;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; Microsoft.Win32;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; MySpatialFunctions&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;    [ClassInterface(ClassInterfaceType.AutoDual)]&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; MySpatialFunctions&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;    {&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;        [ComRegisterFunctionAttribute]&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; RegisterFunction(System.Type t)&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;        {&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;            Microsoft.Win32.Registry.ClassesRoot.CreateSubKey&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;                (&lt;SPAN class=str&gt;"CLSID\\{"&lt;/SPAN&gt; + t.GUID.ToString().ToUpper() + &lt;SPAN class=str&gt;"}\\Programmable"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;        }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;        [ComUnregisterFunctionAttribute]&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; UnregisterFunction(System.Type t)&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;        {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  26:  &lt;/SPAN&gt;            Microsoft.Win32.Registry.ClassesRoot.DeleteSubKey&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  27:  &lt;/SPAN&gt;                (&lt;SPAN class=str&gt;"CLSID\\{"&lt;/SPAN&gt; + t.GUID.ToString().ToUpper() + &lt;SPAN class=str&gt;"}\\Programmable"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  28:  &lt;/SPAN&gt;        }&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  29:  &lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  30:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;The above code will expose your C# class as a COM automation class and will expose all public methods as automation callable methods.&amp;nbsp;&amp;nbsp; The RegisterFunction, decorated [ComRegisterFunctionAttribute] is called by Visual Studio as part of building the project.&amp;nbsp; These functions are used register the MySpatialFunctions class with the Windows Registry.&amp;nbsp; You can also use the .NET regasm.exe utility to achieve same result. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa; mso-bidi-font-family: 'Times New Roman'"&gt;Now that the plumbing is in place, let’s implement the SPATIALAREA function which will take in the description of a Geography object in WKT (well known text) format from Excel and return the area of that geographic object.&amp;nbsp;&amp;nbsp; WKT is really just text or a string, so the input parameter to the function will be a String and the COM interop between Excel and our automation add-in will make sure that whatever Excel is passing in will appear to us as a .NET String.&amp;nbsp;&amp;nbsp; We will return the area as a double.&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class=csharpcode&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; MySpatialFunctions&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;{&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;    [ClassInterface(ClassInterfaceType.AutoDual)]&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; MySpatialFunctions&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;    {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; SPATIALAREA(String Shape)&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;        {&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; fReturnValue = -1;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// Convert the String representation of&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// geographic object into a SqlGeography&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;            SqlGeography geo = SqlGeography.Parse(Shape);&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// We now have a valid Geography, let's call&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// it's area function and convert the results&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// from SqlDouble to .NET Double.&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;            fReturnValue = geo.STArea().Value;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// Return the results&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;            &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; fReturnValue;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;        }&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;       &lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// ....&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;    }&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;
&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;




.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;The above code receives a String from Excel and converts the string representation into a SqlGeography object using using the class method Parse() which expects a WKT encoded string.&amp;nbsp;&amp;nbsp; Once the string is successfully parsed, we call the OGC standard STArea() method to return the shape’s area in square meters.&amp;nbsp;&amp;nbsp; The SqlGeography and SqlGeometry objects return SQL types (SqlDouble, etc.), so we use the .Value method to return the underlying double value.&amp;nbsp; The area is then returned to Excel as a double. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;I’ll stop with this one function for now to test that we have all the necessary pieces in place, but you could easily add additional public functions that expose additional methods from the SqlGeography class.&amp;nbsp;&amp;nbsp; For example you could add a SPATIALDISTANCE and a SPATIALINTERSECTS method to return the distance between two spatial objects or to test if two spatial objects intersect.&amp;nbsp;&amp;nbsp;&amp;nbsp; I’ll in fact do that in the next blog article to demonstrate some more advanced Excel methods that operate on ranges of cells.&lt;/SPAN&gt; &lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Now Build the Project (F5).&amp;nbsp; This will compile the class assembly and register it as a COM class library.&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;You need to run Visual Studio as an administrator&lt;/STRONG&gt; in order for Visual Studio to correctly register the library as a COM Class Library.&amp;nbsp;&amp;nbsp; When the add-in is packaged for distribution we can create an installer that will take care of registration, for local development and small distributions, it is very convenient to have VS do the registration.&amp;nbsp;&amp;nbsp; Trust me… COM registration setup programs are an acquired taste and can be painful to get right. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa; mso-bidi-font-family: 'Times New Roman'"&gt;Once the project is built and the assembly registered with Windows we can switch gears and launch Excel to bring in the new automation add-in we just created.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;Manually Enabling the Automation Add-In within Excel 2007&lt;/H2&gt;
&lt;P&gt;Lanch Excel 2007 and click on the Office button (upper left round button):&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Excel border=0 alt=Excel src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel_thumb.png" width=473 height=346 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Select [Excel Options…] on the bottom right of the dialog box and from the Options dialog box, select the [Add-Ins] tab.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-Add-In-Options_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-Add-In-Options_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Excel-Add-In-Options border=0 alt=Excel-Add-In-Options src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-Add-In-Options_thumb.png" width=673 height=551 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-Add-In-Options_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa; mso-bidi-font-family: 'Times New Roman'"&gt;Choose Manage: Excel Add-ins and click [Go…], on the dialog box that follows click [Automation….] and find your class MySpatialFunctions.MySpatialFunctions in the list, select it and click OK.&amp;nbsp; This will register your automation add-in with Excel and make its functions available to Excel user as Formulas.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-Automation-Add-In_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-Automation-Add-In_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Excel-Automation-Add-In border=0 alt=Excel-Automation-Add-In src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-Automation-Add-In_thumb.png" width=433 height=381 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-Automation-Add-In_thumb.png"&gt;&lt;/A&gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Let’s now make sure the method is available within Excel.&amp;nbsp;&amp;nbsp; In Excel, select a cell and click the Formula button (Fx) and in the Category drop down list, find your MySpatialFunctions. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-InsertFunction-2_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-InsertFunction-2_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Excel-InsertFunction-2 border=0 alt=Excel-InsertFunction-2 src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-InsertFunction-2_thumb.png" width=362 height=305 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Excel-InsertFunction-2_thumb.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;You have now completed the basic process for registering a custom automation add-in with Excel.&amp;nbsp;&amp;nbsp; In the next blog article I will show how to automate this process using a setup program for deployment to end-users. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;This is really just a glimpse into what is feasible in terms of spatial analysis now that this plumbing is in place. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa; mso-bidi-font-family: 'Times New Roman'"&gt;The next blog post will include example of functionality to operate over a range of cells.&amp;nbsp; These aggregate functions can act on multiple geographic shapes, and include UNION, INTERSECTION and a function to calculate the CONVEXHULL of a shape, etc.&lt;/SPAN&gt;&amp;nbsp; &lt;/P&gt;
&lt;H2&gt;Testing the base Spatial Add-In&lt;/H2&gt;
&lt;P&gt;So we’ve built an Add-In that currently supports one spatial function, the SPATIALAREA function, which when given a WKT encoded string representing a shape will return its area.&amp;nbsp;&amp;nbsp; So how do you get a set of WKT data to try this out?&amp;nbsp;&amp;nbsp;&amp;nbsp; WKT is a standard format for geospatial data and there are different tools and data sources on the internet that let you convert data to / from WKT.&amp;nbsp; Another such text representation is called GML and it is relatively easy to modify our Add-In to support both formats (and auto-detect what format).&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;For now here is an example WKT object, which represents the country of Morocco, all the pairs of numbers are Latitude and Longitude values which form the vertices of the country’s border:&lt;/P&gt;
&lt;TABLE border=1 cellSpacing=0 cellPadding=2 width=853&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD vAlign=top width=851&gt;
&lt;P&gt;POLYGON ((-8.6666678252256713 27.666664129182578, -8.667222995748233 28.709442230680754, -7.6447228335782063 29.38499825838333, -7.4338894686020938 29.397220532368337, -7.1238890576883476 29.636943787478454, -6.5858335012886569 29.567218718351096, -6.400278105924599 29.804443265276372, -5.5383339200815715 29.902496352581256, -5.2758341886801494 30.055274928261763, -4.9205561051119027 30.508052873828575, -4.396945078096711 30.648330706130608, -4.0169448364146341 30.911109819241169, -3.6266669275411774 30.970554415405132, -3.6022224394530782 31.095554457582143, -3.8261113959581103 31.163887059367184, -3.8183335039199489 31.695552783902336, -3.5116668926113768 31.673332210341314, -2.9994444009703307 31.833331997926884, -2.8538890815261464 32.088333074020561, -2.3311115158732578 32.157493608115495, -1.1805555950618838 32.110549872177238, -1.2958334558623108 32.163055394625928, -1.2497221362066235 32.326942482097934, -1.0102780535866551 32.50833136699751, -1.3827780560041652 32.724441516585529, -1.5424999126467027 32.9394379321343, -1.4802780647792078 33.063049307516593, -1.6680558432224473 33.261108396767547, -1.6002779231388138 33.556938179949341, -1.730555759883178 33.70499415941044, -1.6544443650187513 34.083610597469317, -1.7933334168756687 34.378326347728262, -1.6867106306540376 34.485511790735742, -1.8575001956524209 34.6102751699483, -1.7472224616645127 34.7472152758781, -2.209444613630581 35.085830782093907, -2.6350001107359389 35.099716151314666, -2.8855556899671657 35.242775016942396, -2.7727781165503669 35.12344354594692, -2.8416665727057948 35.126937801752014, -2.9147223394202406 35.273605397275951, -2.946944586102064 35.329162557540613, -2.986111147028685 35.418052595660889, -3.0663889907443789 35.28944394203873, -3.33250047654772 35.191383412856624, -3.6591668811445603 35.2727737647203, -4.3538894581048853 35.146110476744205, -4.6958342727246034 35.208885297255144, -5.25305545748645 35.576942396678376, -5.345833746377215 35.841659555457895, -5.3955573480761734 35.916336164243809, -5.9187442140904558 35.790649477730661, -6.3152781038228216 34.834999113878069, -6.8430557148205375 34.018608010752295, -7.4966669134759023 33.648330689833216, -8.5383338847421175 33.250549332499993, -9.27639013723884 32.558326726694006, -9.2811126007121647 32.175552453361512, -9.6791668736386267 31.708610438323728, -9.8252793032591743 31.3849982174836, -9.8402786969497935 30.628051715409157, -9.611946167924998 30.412777042428619, -9.64166834548642 30.161941508800595, -10.242500183623481 29.302219297167209, -10.606668533428026 28.966110252659604, -11.081111961457841 28.738609209711591, -11.509445127963096 28.304996469296981, -12.065833980717276 28.083053697361194, -12.902500271008393 27.954166414933635, -13.174961157838167 27.666957939188453, -8.6666678252256713 27.666664129182578))&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;H2&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;You can copy the above text into a Cell within a blank Excel Spreadsheet, for example copy the text into cell A1.&amp;nbsp; You can “truncate” the text by putting a space / blank in cell B2.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part1_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part1_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Test-Add-In-Part1 border=0 alt=Test-Add-In-Part1 src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part1_thumb.png" width=556 height=406 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part1_thumb.png"&gt;&lt;/A&gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Now let’s try out our fancy SPATIALAREA function by typing =SPATIALAREA(A1) in cell A2 and pressing Enter.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&amp;nbsp; &lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part2_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part2_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Test-Add-In-Part2 border=0 alt=Test-Add-In-Part2 src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part2_thumb.png" width=559 height=409 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part2_thumb.png"&gt;&lt;/A&gt; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;And we should get the answer in square meters, format the cell to show 2 decimal places (unless you really like scientific notation):&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part3_2.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part3_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Test-Add-In-Part3 border=0 alt=Test-Add-In-Part3 src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part3_thumb.png" width=575 height=420 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Test-Add-In-Part3_thumb.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/H2&gt;
&lt;H2&gt;Achieving A More Perfect Spatial Add-In&lt;/H2&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;One of the issues with using the simple approach (Auto Dual Class Interface) to create and automation add-in is that some of the non-spatial related base Object methods are then exposed to Excel as callable methods and visible in the Function Picker in Excel.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;You can see some of those unintended functions above as “Equals”, “GetType” and “ToString”&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;It would be preferable from a user experience and ease of use perspective if we could hide those methods and only expose spatial methods within Excel.&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;In order to achieve finer control over the exposed methods it is necessary to get a tiny bit more involved with the COM interop support in .NET.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;With some refactoring we can in fact hide those base Object public methods and have finer control over the methods that are exposed to Excel.&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;I will cover this in detail in the next blog article, but here is the approach: &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 39.75pt; mso-list: l0 level1 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Trebuchet MS'; mso-bidi-font-family: 'Trebuchet MS'"&gt;&lt;SPAN style="mso-list: ignore"&gt;1.&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Define an Inteface in C# that represents all the methods to be exposed to Excel by the automation class.&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;OL type=1&gt;
&lt;UL type=circle&gt;
&lt;LI style="LINE-HEIGHT: normal; MARGIN: 0in 0in 10pt; mso-list: l0 level2 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 1.0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;Decorate that interface with [ComVisible(true)] attribute and specify a unique Guid for that interface [Guid(“unique-guid-here”)]. &lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/OL&gt;
&lt;P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 39.75pt; mso-list: l0 level1 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Trebuchet MS'; mso-bidi-font-family: 'Trebuchet MS'"&gt;&lt;SPAN style="mso-list: ignore"&gt;2.&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Modify the MyFunctions class: &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 75.75pt; mso-list: l0 level2 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 1.0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Courier New'; mso-bidi-font-size: 10.5pt"&gt;&lt;SPAN style="mso-list: ignore"&gt;o&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Derive / implements interface from step #1. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 75.75pt; mso-list: l0 level2 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 1.0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Courier New'; mso-bidi-font-size: 10.5pt"&gt;&lt;SPAN style="mso-list: ignore"&gt;o&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Add [ComVisible(true)] decoration to the class &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 75.75pt; mso-list: l0 level2 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 1.0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Courier New'; mso-bidi-font-size: 10.5pt"&gt;&lt;SPAN style="mso-list: ignore"&gt;o&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Add [Guid(“unique-guid-for-the-class”)] decoration to the class. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 75.75pt; mso-list: l0 level2 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 1.0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Courier New'; mso-bidi-font-size: 10.5pt"&gt;&lt;SPAN style="mso-list: ignore"&gt;o&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Add [ProgId(“MySpatialFunctions.MySpatialFunctions”)] &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="LINE-HEIGHT: normal; TEXT-INDENT: -0.25in; MARGIN: 0in 0in 10pt 75.75pt; mso-list: l0 level2 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list 1.0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-fareast-font-family: 'Courier New'; mso-bidi-font-size: 10.5pt"&gt;&lt;SPAN style="mso-list: ignore"&gt;o&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Modify [ClassInterface] Attribute to reflect [ClassInterface(“ClassInterfaceType.None”)] &lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV style="LINE-HEIGHT: normal; MARGIN: 0in 0in 10pt; mso-list: l0 level1 lfo1; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; tab-stops: list .5in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;Modify the RegisterFunction and UnRegisterFunction to reflect both the Interface and the Class. &lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P style="LINE-HEIGHT: normal; MARGIN: 7.5pt 0in" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Trebuchet MS','sans-serif'; FONT-SIZE: 10.5pt; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"&gt;In addition to “cleaning” up some of the unintended methods from above, It would also useful to get a reference to the Excel application to enable more communication back and forth between the add-in and Excel.&amp;nbsp;&amp;nbsp;&amp;nbsp; You can get a reference to the Excel Application object by implementing the Extensibility.IDTExtensibility2 interface as part of your class.&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; Once you have access to the Excel Application object, your add-in can actually start communicating and controlling Excel, automatically formatting cells for example that include a spatial formula. &lt;/P&gt;
&lt;H2&gt;What’s Next?&lt;/H2&gt;
&lt;P&gt;In the next article I will build on this base add-in and expand on the functions it exposes as well as describe the process of building a VSTO add-in to provide a Spatial Ribbon within Excel.&amp;nbsp; I’ll also cover how to build some spatial UI componentry for an Excel spreadsheet to allow the embedding of a visualizing / mapping spatial control within a spreadsheet.&amp;nbsp; Finally I also plan to cover the creation of a setup project to install your add-ins (VSTO and Automation) on end-user workstations.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;So some cool stuff is coming.&amp;nbsp;&amp;nbsp; Here is a small teaser to show you what you can expect:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Poster-2_4.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Poster-2_4.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=Poster-2 border=0 alt=Poster-2 src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Poster-2_thumb_1.png" width=703 height=563 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/ExcelSpatialSpreadsheetBuildinganExcelA_85CA/Poster-2_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Hope to see you at PDC tomorrow and let me know if you find this Excel add-in helpful in learning the SQL Spatial operators and in performing simple spatial analysis without having to leave Excel.&lt;/P&gt;
&lt;P&gt;Sincerely,&lt;/P&gt;
&lt;P&gt;Olivier&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923373" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Automation/">Automation</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Spatial/">Spatial</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/SQL+Server/">SQL Server</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/VSTO/">VSTO</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Excel/">Excel</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Office/">Office</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/-NET/">.NET</category></item><item><title>PDC 2009 is next week - I'll be Building Location Aware Applications with the SQL Server Spatial Library at Session SVR33 - Tuesday</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2009/11/13/pdc-2009-is-next-week-i-ll-be-building-location-aware-applications-with-the-sql-server-spatial-library-at-session-svr33-tuesday.aspx</link><pubDate>Fri, 13 Nov 2009 16:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9922049</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=9922049</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2009/11/13/pdc-2009-is-next-week-i-ll-be-building-location-aware-applications-with-the-sql-server-spatial-library-at-session-svr33-tuesday.aspx#comments</comments><description>&lt;P&gt;I will be presenting at PDC next week with Ed Katibah and Torsten Grabs on uses of the SQL Server Spatial library (SQLTypes).&amp;nbsp;&amp;nbsp; The session will be on Tuesday at 12:30pm.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Title: &lt;BR&gt;Building Location Aware Applications with the SQL Server Spatial Library&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Abstract: &lt;BR&gt;Did you know that the new SQL Server 2008 Spatial Types are available in a redistributable library?&amp;nbsp; This library can be used to build interesting location aware functionality in applications that don’t even connect to a database.&amp;nbsp; See us build an Excel Add-In for spatial analysis and an application that demonstrates how to spatially-enable the new StreamInsight product.&amp;nbsp; Hear about what the Spatial Library delivers today and what is coming in future releases.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The session will largely be demos and code walkthroughs with minimal powerpoint slides.&lt;/P&gt;
&lt;P&gt;Please stop by if you are attending PDC and share your experiences building location-aware applications using SQL Server 2008.&lt;/P&gt;
&lt;P&gt;Olivier&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9922049" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Future/">Future</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Spatial/">Spatial</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/GPS/">GPS</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Design/">Design</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/SQL+Server/">SQL Server</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/PDC/">PDC</category></item><item><title>Watch out for gotcha with missing VC++ runtime dlls when deploying .NET applications that leverage the new SQL Server Spatial Types libraries.</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2009/07/08/watch-out-for-gotcha-with-missing-vc-runtime-dlls-when-deploying-net-applications-that-leverage-the-new-sql-server-spatial-types-libraries.aspx</link><pubDate>Thu, 09 Jul 2009 00:56:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9824924</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=9824924</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2009/07/08/watch-out-for-gotcha-with-missing-vc-runtime-dlls-when-deploying-net-applications-that-leverage-the-new-sql-server-spatial-types-libraries.aspx#comments</comments><description>&lt;p&gt;In my &lt;a href="http://blogs.msdn.com/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx" mce_href="http://blogs.msdn.com/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx"&gt;previous blog post&lt;/a&gt; I discussed the ability to leverage the SQL Server type library in your own .NET applications.&amp;nbsp; The article showed how to create a simple console application that calculates some areas for different shapes and how to create these shapes either from a text representation like WKT or “by hand” using the builder classes in the spatial library.&lt;/p&gt;  &lt;p&gt;I did not spend much time on discussing the details of deploying your spatially-enabled .NET application to other machines (client or server) since I expected it to be like any other .NET application: Just copy the EXE along with any dependent assemblies to the target machine and run, of if motivated, create a simple setup project, or possibly use Publish to create a click-once installer.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;The best laid plans of…&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;It turns out that deployment of a spatially-enabled .NET application onto a “clean” target machine has a potential&lt;b&gt; *gotcha*&lt;/b&gt;.&lt;/p&gt;  &lt;p&gt;Taking the example of the simple .NET console application from the previous blog, there are several expected pre-requisites necessary on the target machine in order for the application to run successfully:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;.NET Framework: that one is pretty obvious given my console application was a .NET application.&lt;/li&gt;    &lt;li&gt;SQL Server Types: Running this &lt;a href="http://go.microsoft.com/fwlink/?LinkId=123721&amp;amp;clcid=0x409" mce_href="http://go.microsoft.com/fwlink/?LinkId=123721&amp;amp;clcid=0x409" target="_blank"&gt;installer&lt;/a&gt; will install and register the SQL Types assembly in the GAC.&amp;nbsp; &lt;i&gt;Alternatively you could place the SQL types assembly as a side-by-side assembly to your application.&lt;/i&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It turns out that you will also need to make sure the Visual C++ 2008 C runtime libraries are also installed on that target machine. &lt;/p&gt;  &lt;p&gt;The spatial data types make use of both managed code (.NET) and native code to speed up spatial calculations and as a result the spatial types make calls to some C runtime library functions.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;If these C runtime libraries are not installed on your target machine you will get the following exception when you run your application:&lt;/p&gt;  &lt;table width="532" border="1" cellpadding="2" cellspacing="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td width="530" valign="top"&gt;Unable to load DLL 'SqlServerSpatial.dll': This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0x800736B1)&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;You can find the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&amp;amp;displaylang=en" title="32 Bit Visual C++ runtime libraries" mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&amp;amp;displaylang=en" target="_blank"&gt;32bit&lt;/a&gt; version of the VC++ redistributables here and the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=BD2A6171-E2D6-4230-B809-9A8D7548C1B6&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=BD2A6171-E2D6-4230-B809-9A8D7548C1B6&amp;amp;displaylang=en" target="_blank"&gt;64bit&lt;/a&gt; version here.&amp;nbsp; Run the appropriate version for your target environment and that should resolve the problem.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&lt;i&gt;Alternatively build an installer for your application that installs the C runtime libraries as part of the installation of your application (note that I did not try this, so let me know if you run into any problems).&lt;/i&gt;&lt;/p&gt;  &lt;p&gt;You can read more about this scenario on the Microsoft support site &lt;a href="http://support.microsoft.com/kb/955850" mce_href="http://support.microsoft.com/kb/955850" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Happy coding.&lt;/p&gt;  &lt;p&gt;Olivier&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9824924" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Spatial/">Spatial</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/SQL+Server/">SQL Server</category></item><item><title>Why I should have paid more attention in geometry class: Embedding the new SQL Server Spatial CLR types and functionality directly into your own .NET applications.</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx</link><pubDate>Mon, 22 Jun 2009 21:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9798143</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=9798143</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2009/06/22/why-i-should-have-paid-more-attention-in-geometry-class-embedding-the-new-sql-server-spatial-clr-types-and-functionality-directly-into-your-own-net-applications.aspx#comments</comments><description>&lt;P&gt;In SQL Server 2008 we introduced the ability to store spatial objects as columns within a database through the Geometry and Geography types as well as the ability to perform efficient query operations against those columns through the use of a new Spatial index.&lt;/P&gt;
&lt;P&gt;These data types were implemented as CLR (.NET) types hosted by SQL Server and a great benefit of this approach is that enabled the SQL team to make these same .NET assemblies are available for download and distribution “outside of SQL Server” for use in any .NET application.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;You can download the SQL CLR Types &lt;A href="http://go.microsoft.com/fwlink/?LinkId=123721&amp;amp;clcid=0x409" target=_blank mce_href="http://go.microsoft.com/fwlink/?LinkId=123721&amp;amp;clcid=0x409"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Once you have downloaded and installed the SQL types on your development machine, you can make them available to your .NET applications by adding a reference to the assembly within Visual Studio your project.&lt;/P&gt;
&lt;P&gt;Let’s try it with a simple “hello world” console application that will create a couple of simple geometric shapes and calculate some simple geometric operations like area and intersections.&lt;/P&gt;
&lt;P&gt;From Visual Studio, select File-&amp;gt;New Project and select the Console Application project type.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_4.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_4.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_1.png" width=517 height=350 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_1.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Once your new project is loaded, you will need to add a reference to the SQL Server types assembly.&amp;nbsp; Right click on the References node in your Solution Explorer and Choose Add New Reference.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_6.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_6.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_2.png" width=206 height=313 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_2.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Find the Microsoft.SqlServer.Types .NET component and add it to your project.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_8.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_8.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_3.png" width=306 height=259 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_3.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now that the project is set up to use the Spatial data types, let’s try out a simple set of spatial operations.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE style="WIDTH: 135.65%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;using&lt;/SPAN&gt; Microsoft.SqlServer.Types;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 135.79%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; Program&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;{&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 136.26%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;    &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Main(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;[] args)&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;    {&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 136.95%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// Build a geometry object from Well Known TextSqlGeometry&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;         a = SqlGeometry.Parse(&lt;SPAN class=str&gt;"POLYGON ((0 0, 10 0, 10 10, 0 0))"&lt;/SPAN&gt;);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 137.27%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// Calculate and display its area&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 137.81%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;        System.Console.WriteLine(&lt;SPAN class=str&gt;"Area of A = "&lt;/SPAN&gt; + a.STArea().Value.ToString());&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 137.54%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// Create a buffered version of the original&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;        SqlGeometry b = a.STBuffer(1);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 138.51%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// Calculate and display its area&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 139.22%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;        System.Console.WriteLine(&lt;SPAN class=str&gt;"Area of B = "&lt;/SPAN&gt; + b.STArea().Value.ToString());&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 139.58%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// Create the shape that represents the difference of the two shapes&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;        SqlGeometry c = b.STDifference(a);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 139.62%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;        &lt;SPAN class=rem&gt;// Show its area&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 140.29%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;        System.Console.WriteLine(&lt;SPAN class=str&gt;"Area of B-A = "&lt;/SPAN&gt; + c.STArea().Value.ToString());Console.ReadLine();&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;    }&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 140.46%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;}&lt;/FONT&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;We start by creating a very simple shape, a triangle (line 8) by converting a text representation of the shape into a SqlGeometry object.&amp;nbsp;&amp;nbsp; The text representation used by the SQL Spatial type library is &lt;A href="http://en.wikipedia.org/wiki/Well-known_text" target=_blank mce_href="http://en.wikipedia.org/wiki/Well-known_text"&gt;WKT&lt;/A&gt; (well known text).&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_10.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_10.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_4.png" width=244 height=242 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_4.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Next we buffer the triangle (line 14) by one unit all around, which means “grow” the shape around its border by one unit.&amp;nbsp; Buffering can be useful when used in conjunction with other operators to find out if shapes border each other or to create more complex shapes that represent shapes with holes.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_12.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_12.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_5.png" width=242 height=244 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_5.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Now we create a more complex shape, by geometrically “subtracting” the original triangle from the buffered triangle (line 20), resulting in a shape that represents the one unit border around the original shape.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_14.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_14.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_6.png" width=243 height=244 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_6.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;We can now verify that these operations resulted in shapes that are in fact complements of each other by calculating the areas of the individual shapes and comparing the area of the complex border shape with the areas of the original triangle and its buffered version (lines 11, 17 and 23). &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_16.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_16.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_7.png" width=389 height=148 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_7.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;A question you may be asking is can one start from a non-textual representation of a shape?&amp;nbsp; Can I build the shapes in code?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Yes you can in fact create shapes “by hand” using builder objects (SqlGeometryBuilder and SqlGeographyBuilder) exposed by both the SqlGeometry and the SqlGeography data types.&lt;/P&gt;
&lt;P&gt;Here is a simple example that builds a triangle by hand:&lt;/P&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE style="WIDTH: 124.38%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   1:  &lt;/SPAN&gt;   &lt;SPAN class=kwrd&gt;class&lt;/SPAN&gt; Program&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   2:  &lt;/SPAN&gt;    {&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 123.81%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   3:  &lt;/SPAN&gt;        &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Main(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;[] args)&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   4:  &lt;/SPAN&gt;        {&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 123.41%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   5:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// Create instance of a geometry builder&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   6:  &lt;/SPAN&gt;            SqlGeometryBuilder geoBuilder = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; SqlGeometryBuilder();&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 122.82%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   7:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   8:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// Spatial objects have a reference ID / reference system&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 122.33%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;   9:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// which identifies the type of projection (or lack of)&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  10:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// used, for example WGS84 - SRID = 4326 &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 121.5%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  11:  &lt;/SPAN&gt;            geoBuilder.SetSrid(4326);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  12:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 121.59%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  13:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// Building a simple polygon&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  14:  &lt;/SPAN&gt;            geoBuilder.BeginGeometry(OpenGisGeometryType.Polygon);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 121.01%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  15:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  16:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// Start the shape at 0,0 and add each line segment for the&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 120.97%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  17:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// triangle (0,0 - 0,10) - (0,10 - 10,10) - (10,10 - 0,0)&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  18:  &lt;/SPAN&gt;            geoBuilder.BeginFigure(0, 0);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 120.61%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  19:  &lt;/SPAN&gt;            geoBuilder.AddLine(0, 10);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  20:  &lt;/SPAN&gt;            geoBuilder.AddLine(10, 10);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 120.55%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  21:  &lt;/SPAN&gt;            geoBuilder.AddLine(0, 0);&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  22:  &lt;/SPAN&gt;            geoBuilder.EndFigure();&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 120.25%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  23:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  24:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// We're done, this polygon has one figure.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 119.54%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  25:  &lt;/SPAN&gt;            geoBuilder.EndGeometry();&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  26:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 119.92%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  27:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// retrieve the constructed geometry&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  28:  &lt;/SPAN&gt;            SqlGeometry geo = geoBuilder.ConstructedGeometry;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 119.35%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  29:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  30:  &lt;/SPAN&gt;            Console.WriteLine(&lt;SPAN class=str&gt;"The new shape's WKT:"&lt;/SPAN&gt; + geo.ToString());&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 118.82%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  31:  &lt;/SPAN&gt;            Console.WriteLine(&lt;SPAN class=str&gt;"and it's area: "&lt;/SPAN&gt; + geo.STArea().Value.ToString());&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  32:  &lt;/SPAN&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 118.82%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  33:  &lt;/SPAN&gt;            &lt;SPAN class=rem&gt;// Wait&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  34:  &lt;/SPAN&gt;            Console.ReadLine();&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE style="WIDTH: 117.53%; HEIGHT: 15px" class=alt&gt;&lt;FONT size=1&gt;&lt;SPAN class=lnum&gt;  35:  &lt;/SPAN&gt;        }&lt;/FONT&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_18.png" mce_href="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_18.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_8.png" width=645 height=327 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/image_thumb_8.png"&gt;&lt;/A&gt;&amp;nbsp;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;You are probably thinking to yourself, that’s neat, it had been a long time since I had thought about geometry, but Olivier how do I use this in my day job?&amp;nbsp;&amp;nbsp; &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Agreed, these were very simple examples intended to show you how to get started.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;You now have at your disposal a &lt;A href="http://msdn.microsoft.com/en-us/library/bb933960.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb933960.aspx"&gt;set of industry standard operations&lt;/A&gt; as well as extension methods that allow for complex calculations and operations against complex geometric shapes and a &lt;A href="http://msdn.microsoft.com/en-us/library/bb933917.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb933917.aspx"&gt;similar set of operations for geographic shapes&lt;/A&gt;.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;So while calculating the area of a triangle seems pretty simple, what if that shape was a state and you were asked to calculate the area of a state, excluding all water areas?&amp;nbsp;&amp;nbsp; Remember that Minnesota is the land of 10,000 lakes.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://geology.com/satellite/minnesota-satellite-image-m.jpg" mce_href="http://geology.com/satellite/minnesota-satellite-image-m.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=minnesota-satellite-image-m[1] border=0 alt=minnesota-satellite-image-m[1] src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/minnesota-satellite-image-m%5B1%5D_3.jpg" width=222 height=244 mce_src="http://blogs.msdn.com/blogfiles/oliviermeyer/WindowsLiveWriter/DidyouknowyoucoulduseSQL.NETapplications_8835/minnesota-satellite-image-m%5B1%5D_3.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The spatial library can handle complex shapes made up of 100’s of 1000’s of vertices, including shapes that have “holes”.&lt;/P&gt;
&lt;P&gt;What if you were collecting the locations for the current instances of the bird flu reported across different regions and wanted to quickly calculate an aggregate shape that encompasses those points for clustering analysis (ConvexHull)?&amp;nbsp; &lt;/P&gt;
&lt;P&gt;What if you wanted to efficiently compare the current location for trucks within your fleet against a known “good” path for a route to better track fuel utilization or compliance (STIntersects)?&lt;/P&gt;
&lt;P&gt;These are some of the types of problems that the SQL Server Spatial types can assist with.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Can I extend the existing SqlGeometry and SqlGeography types?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The classes are sealed, but you can use the new &lt;A href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;.NET extension methods&lt;/A&gt; to make it look like you have extended the existing data types.&lt;/P&gt;
&lt;P&gt;In my next blog posting I’ll show some examples of using this extension mechanism to provide integration with Bing Maps Web Services as well as provide ways to aggregate and disaggregate complex shapes.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;So what can I do with this new knowledge?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;With the basics out of the way there are a series of business problems that you could look to leverage the libraries and SQL Server for:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Location based services like asset tracking and employee tracking.&amp;nbsp; For example having mobile devices or laptops report their location through posts against a .NET web service or Windows Azure Web Service application and using the library to quickly calculate the proximity or relationships between assets and employees.&lt;/LI&gt;
&lt;LI&gt;Combine the SQL CLR types with other Microsoft services like Bing Maps and Mappoint web services to perform Geocoding and analysis within your .NETapplication.&lt;/LI&gt;
&lt;LI&gt;Analysis of real estate opportunities by combining in-house data, commercial data and census or government data.&lt;/LI&gt;
&lt;LI&gt;Building extensions and utilities to make working with spatial data easier and more efficient.&amp;nbsp; &lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;Many of the spatial goodies and tools that have been made available on CodePlex were written using these builder APIs and the .NET types.&amp;nbsp;&amp;nbsp; You can download and try these add-ons from CodePlex &lt;A href="http://sqlspatialtools.codeplex.com/" target=_blank mce_href="http://sqlspatialtools.codeplex.com/"&gt;here&lt;/A&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;Modeling and analysis of floor plans&lt;/LI&gt;
&lt;LI&gt;&lt;FONT color=#0000ff&gt;&amp;lt;Your App Here&amp;gt;&lt;/FONT&gt; – Let me know what unique applications you find for using the new SQL Server Spatial Types in your own application.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Have a great week,&lt;/P&gt;
&lt;P&gt;Olivier&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9798143" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Spatial/">Spatial</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/Virtual+Earth/">Virtual Earth</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/CodePlex/">CodePlex</category><category domain="http://blogs.msdn.com/b/oliviermeyer/archive/tags/SQL+Server/">SQL Server</category></item><item><title>Calling all web developers: The SQL Server Team needs your help.</title><link>http://blogs.msdn.com/b/oliviermeyer/archive/2009/06/11/calling-all-web-developers-the-sql-server-team-needs-your-help.aspx</link><pubDate>Thu, 11 Jun 2009 02:43:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9725334</guid><dc:creator>Olivier Meyer</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/oliviermeyer/rsscomments.aspx?WeblogPostID=9725334</wfw:commentRss><comments>http://blogs.msdn.com/b/oliviermeyer/archive/2009/06/11/calling-all-web-developers-the-sql-server-team-needs-your-help.aspx#comments</comments><description>&lt;p&gt;&lt;span style="font-family: 'Calibri','sans-serif'; color: #1f497d; font-size: 11pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;The Microsoft SQL Server product team is undertaking a short survey to help guide potential new features and capabilities for web developers, please take a few minutes to take the survey and help shape the future of SQL Server.&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-family: 'Calibri','sans-serif'; color: #1f497d; font-size: 11pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;Click this &lt;a href="http://www.surveymonkey.com/s.aspx?sm=9s5sHwoJ97OV0OWt60idJA_3d_3d"&gt;link&lt;/a&gt; to take the survey.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-family: 'Calibri','sans-serif'; color: #1f497d; font-size: 11pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;Thank you for your time and feedback.&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-family: 'Calibri','sans-serif'; color: #1f497d; font-size: 11pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;Olivier&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;span style="font-family: 'Calibri','sans-serif'; color: #1f497d; font-size: 11pt; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin; mso-ansi-language: en-us; mso-fareast-language: en-us; mso-bidi-language: ar-sa"&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9725334" width="1" height="1"&gt;</description></item></channel></rss>