<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>A View Inside My Head</title><link>http://www.jasonfollas.com/blog/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AViewInsideMyHead" /><description>Jason's Random Thoughts of Interest</description><language>en-US</language><managingEditor>noemail@noemail.org (Jason Follas)</managingEditor><generator>BlogEngine.NET 2.6.0.5</generator><blogChannel:blogRoll xmlns:blogChannel="http://backend.userland.com/blogChannelModule">http://www.jasonfollas.com/blog/opml.axd</blogChannel:blogRoll><blogChannel:blink xmlns:blogChannel="http://backend.userland.com/blogChannelModule">http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink><dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">A View Inside My Head</dc:title><geo:lat>0.000000</geo:lat><geo:long>0.000000</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AViewInsideMyHead" /><feedburner:info uri="aviewinsidemyhead" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>41.501902</geo:lat><geo:long>-83.736853</geo:long><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><item><title>Product Evaluation: Aspose.Words</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/mjPeaskE_l0/post.aspx</link><pubDate>Fri, 29 Mar 2013 07:38:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=ca964609-ca81-483e-b28b-d44f53a71da0</guid><description>&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;In 2004, I was approached by a client to help write a web application. &amp;nbsp;A multi-page wizard collected information from the user, and at the end, generated a Word document containing pages of best practices and engineering specifications for installing the company&amp;rsquo;s products. &amp;nbsp;Our solution worked, and hundreds (if not thousands) of documents have been generated for their customers. &amp;nbsp;But, we used Office Automation in ASP.NET in a way that was not supported by Microsoft, at least at that time (since it was executing on the server).&lt;/p&gt;
&lt;p&gt;Fast forward to the present day, and I was invited to evaluate &lt;a href="http://www.aspose.com/.net/word-component.aspx" target="_blank"&gt;Aspose.Words for .NET&lt;/a&gt;. &amp;nbsp;While I personally don&amp;rsquo;t get many requests for Office Automation-type projects these days, as a consultant, it is good to have a go-to library to use should the need ever arise. &amp;nbsp;So, I agreed to take a look at the product.&lt;/p&gt;
&lt;div&gt;
&lt;h1&gt;The Unboxing Experience&lt;/h1&gt;
&lt;p&gt;These days, software typically does not come in a box, so there is no unboxing experience involved to establish that first impression. &amp;nbsp;But, there is a lot to be said about how easy the installation process is for software, as well as how discoverable the documentation is. &amp;nbsp;Aspose.Words can be installed by means of a traditional MSI install wizard, or as a NuGet package. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;The MSI option provides a full experience, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installs the Aspose.Words assemblies (multiple assemblies to support different versions of the .NET Framework)&lt;/li&gt;
&lt;li&gt;Installs the demo projects with source code&lt;/li&gt;
&lt;li&gt;Installs the documentation locally on the developer&amp;rsquo;s machine&lt;/li&gt;
&lt;li&gt;Adds the assembly to the Add Reference dialog box in Visual Studio&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After the installation, the developer must manually add a reference to the assembly. &amp;nbsp;Locally-installed documentation is available by means of Windows HTML Help, which is completely available and searchable while disconnected from the Internet.&lt;/p&gt;
&lt;p&gt;The NuGet option is intended to be a bit more task-oriented. &amp;nbsp;Instead of modifying the developer&amp;rsquo;s machine to support general-purpose development with the Aspose.Words library, it merely copies the .NET 2.0 and .NET 3.5 Client Profile assembly versions to the project&amp;rsquo;s directory, and then adds the necessary reference to the project. &amp;nbsp;The package will need to be added to each project that uses the library.&lt;/p&gt;
&lt;p&gt;There is no help file installed locally with the NuGet option, so the developer is left with the online documentation located at: &lt;a href="http://www.aspose.com/docs/display/wordsnet/Home" target="_blank"&gt;http://www.aspose.com/docs/display/wordsnet/Home&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Hello World&lt;/h1&gt;
&lt;p&gt;One challenge that we had with writing the document generator all those years ago was finding an efficient way to insert formatted text into the document. &amp;nbsp;Specifically, the resulting document contained sections of text, each with paragraphs and special formatting. &amp;nbsp;Because of time constraints, the decision was made to not build a document on-the-fly by inserting text into it, but instead start with a document that had every possible section already in it (nicely formatted by a human), and then just delete sections based on the user&amp;rsquo;s input.&lt;/p&gt;
&lt;p&gt;So, in evaluating Aspose.Words, I wanted to see how easy it would be to just insert whole sections of pre-formatted text, written as HTML, into a document. &amp;nbsp;As it turns out, besides the rich Document object (which is very similar to Microsoft Word&amp;rsquo;s object model), there&amp;rsquo;s also a DocumentBuilder object that abstracts away the layers of nodes that makes up a document, and lets you focus on the task at hand.&lt;/p&gt;
&lt;p&gt;Conveniently, DocumentBuilder has an InsertHTML method that looks like it will do exactly what I want. &amp;nbsp;But, will it handle all aspects of HTML, like images and hyperlinks? &amp;nbsp;Let&amp;rsquo;s find out!&lt;/p&gt;
&lt;pre class="brush: c-sharp;"&gt;var doc = new Aspose.Words.Document(); 
var builder = new Aspose.Words.DocumentBuilder(doc); 
var html = @"&amp;lt;div&amp;gt; 
             &amp;lt;img src='http://thetabletshow.com/dnr_photos/JasonFollas.png'&amp;gt; 
             &amp;lt;a href='http://jasonfollas.com/'&amp;gt;Testing&amp;lt;/a&amp;gt; 
             &amp;lt;/div&amp;gt;"; 
			 
builder.InsertHtml(html); 
doc.Save(filename_or_Stream, Aspose.Words.SaveFormat.Docx);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The result? &amp;nbsp;I was expecting the image not to be included (since that&amp;rsquo;s another fetch that Aspose.Words would have to perform), but it worked flawlessly!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;img src="http://www.jasonfollas.com/blog/image.axd?picture=%2f2013%2f03%2fimage001.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: I received a license, but had not yet applied it when this demo executed. &amp;nbsp;This screenshot shows the default behavior of the evaluation mode where text is inserted into the document.&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;Licensing&lt;/h1&gt;
&lt;p&gt;When not associated with an active license, Aspose.Words will run in an Evaluation Mode that injects red text into the documents that are produced (see the screenshot of my &amp;ldquo;Hello World&amp;rdquo; experiment). &amp;nbsp;Developers evaluating the product can obtain a 30-day license in order to work with the fully unlocked behavior.&lt;/p&gt;
&lt;p&gt;Licenses are distributed as XML files, and applications must set the license before working with the API in order to disable the Evaluation Mode. &amp;nbsp;Though this may sound like an inconvenience, it&amp;rsquo;s actually not that bad. &amp;nbsp;For example, to unlock the product for use by an ASP.NET application, simply place the .lic file into the /bin directory, and add the following to global.asax:&lt;/p&gt;
&lt;pre class="brush: c-sharp;"&gt;protected void Application_Start(object sender, EventArgs e) { 
   Aspose.Words.License license = new Aspose.Words.License(); 
   license.SetLicense("Aspose.Words.Product.Family.lic"); 
}&lt;/pre&gt;
&lt;h1&gt;File Types&lt;/h1&gt;
&lt;p&gt;One very impressive aspect of Aspose.Words is the vast number of document formats that are supported for loading and saving documents. &amp;nbsp;With two lines of code, the library could be used as a format converter to open a Word Document and save it as a PDF:&lt;/p&gt;
&lt;pre class="brush: c-sharp;"&gt;var doc = new Aspose.Words.Document("Document.doc"); 
doc.Save("Document.pdf", Aspose.Words.SaveFormat.Pdf);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Building upon this concept, you could start with a Word Document that was authored by a business person, open it on the web server, insert/modify/delete content within the document, and then send a PDF version to the user.&lt;/p&gt;
&lt;h2&gt;Load Formats&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Microsoft Word 97-2003 document&lt;/li&gt;
&lt;li&gt;Microsoft Word 97-2003 template&lt;/li&gt;
&lt;li&gt;Office Open XML WordprocessingML Macro-Free Document&lt;/li&gt;
&lt;li&gt;Office Open XML WordprocessingML Macro-Enabled Document&lt;/li&gt;
&lt;li&gt;Office Open XML WordprocessingML Macro-Free Template&lt;/li&gt;
&lt;li&gt;Office Open XML WordprocessingML Macro-Enabled Template&lt;/li&gt;
&lt;li&gt;Flat OPC document&lt;/li&gt;
&lt;li&gt;RTF format&lt;/li&gt;
&lt;li&gt;Microsoft Word 2003 WordprocessingML format&lt;/li&gt;
&lt;li&gt;HTML format&lt;/li&gt;
&lt;li&gt;MHTML (Web archive) format&lt;/li&gt;
&lt;li&gt;OpenDocument Text&lt;/li&gt;
&lt;li&gt;OpenDocument Text Template&lt;/li&gt;
&lt;li&gt;MS Word 6 or Word 95 format&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Save Formats&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Doc&lt;/strong&gt;: Microsoft Word 97 - 2007 Document&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dot&lt;/strong&gt;: Microsoft Word 97 - 2007 Template&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docx&lt;/strong&gt;: Office Open XML WordprocessingML Document (macro-free))&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docm&lt;/strong&gt;: Office Open XML WordprocessingML Macro-Enabled Document&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dotx&lt;/strong&gt;: Office Open XML WordprocessingML Template (macro-free)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dotm&lt;/strong&gt;: Office Open XML WordprocessingML Macro-Enabled Template&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FlatOpc&lt;/strong&gt;: Office Open XML WordprocessingML stored in a flat XML file instead of a ZIP package&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FlatOpcMacroEnabled&lt;/strong&gt;: Office Open XML WordprocessingML Macro-Enabled Document stored in a flat XML file instead of a ZIP package&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FlatOpcTemplate&lt;/strong&gt;: Office Open XML WordprocessingML Template (macro-free) stored in a flat XML file instead of a ZIP package&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FlatOpcTemplateMacroEnabled&lt;/strong&gt;: Office Open XML WordprocessingML Macro-Enabled Template stored in a flat XML file instead of a ZIP package&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RTF&lt;/strong&gt;: Rich Text Format&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WordML&lt;/strong&gt;: Microsoft Word 2003 WordprocessingML format)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pdf&lt;/strong&gt;: Adobe Portable Document&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xps&lt;/strong&gt;: XML Paper Specification&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XamlFixed&lt;/strong&gt;: Extensible Application Markup Language (XAML) format as a fixed document&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Swf&lt;/strong&gt;: Adobe Flash Player&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Svg&lt;/strong&gt;: Scalable Vector Graphics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Html&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mhtml&lt;/strong&gt;: Web archive&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Epub&lt;/strong&gt;: IDPF EPUB format&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Odt&lt;/strong&gt;: ODF Text Document&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ott&lt;/strong&gt;: ODF Text Document Template&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Text&lt;/strong&gt;: Plain text format&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XamlFlow&lt;/strong&gt;: Beta. Saves the document in the Extensible Application Markup Language (XAML) format as a flow document&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XamlFlowPack&lt;/strong&gt;: Beta. Saves the document in the Extensible Application Markup Language (XAML) package format as a flow document&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tiff&lt;/strong&gt;: Renders a page or pages of the document and saves them into a single or multipage TIFF file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Png&lt;/strong&gt;: Renders a page of the document and saves it as a PNG file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bmp&lt;/strong&gt;: Renders a page of the document and saves it as a BMP file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Emf&lt;/strong&gt;: Renders a page of the document and saves it as a vector EMF (Enhanced Meta File) file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jpeg&lt;/strong&gt;: Renders a page of the document and saves it as a JPEG file&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;A More Complex Example&lt;/h1&gt;
&lt;p&gt;Since I was being asked to provide an honest evaluation of the product, I wanted to find a way to stress the document generation ability a little bit more. &amp;nbsp;So, after a bit of brainstorming, I came up with the idea of creating a PDF containing a Reddit post (&lt;a href="http://reddit.com" target="_blank"&gt;http://reddit.com&lt;/a&gt;) along with its nested comments. &amp;nbsp;Note: This exercise is mostly academic in nature.&lt;/p&gt;
&lt;p&gt;Reddit provides a RESTful API to permit third-party software access to its content. &amp;nbsp;For .NET languages, there is an open source library called RedditSharp (&lt;a href="https://github.com/SirCmpwn/RedditSharp" target="_blank"&gt;https://github.com/SirCmpwn/RedditSharp&lt;/a&gt;) that abstracts away the details of the networking and transport, and allows the developer to focus on the data.&lt;/p&gt;
&lt;pre class="brush: c-sharp;"&gt;var reddit = new RedditSharp.Reddit();
var iama = reddit.GetSubreddit("/r/IAmA");
var firstPost = iama.GetPosts()[0];
var comments = firstPost.GetComments();&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Comments on Reddit can nest deeply at times, so in order to make the document readable, I made two design decisions: &amp;nbsp;Set the page orientation to Landscape, and use the Left Indent instead of the bullet list so that I could have better control over how much space each indent uses.&lt;/p&gt;
&lt;pre class="brush: c-sharp;"&gt;var doc = new Aspose.Words.Document();
var builder = new Aspose.Words.DocumentBuilder(doc);
builder.PageSetup.Orientation = Aspose.Words.Orientation.Landscape;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The post&amp;rsquo;s title and author are written at the top of the document. &amp;nbsp;The Heading 1 style is applied to the title, while a small italic font is used to display the author:&lt;/p&gt;
&lt;pre class="brush: c-sharp;"&gt;builder.ParagraphFormat.StyleIdentifier = 
	Aspose.Words.StyleIdentifier.Heading1;

builder.Writeln(firstPost.Title);

builder.ParagraphFormat.StyleIdentifier = 
	Aspose.Words.StyleIdentifier.BodyText;

builder.Font.Name = "Arial";
builder.Font.Size = 8;
builder.Font.Italic = true;
builder.Writeln(" - " + firstPost.Author.Name);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next, the comments collection must be crawled. &amp;nbsp;I chose to use a recursive function to output each level of comments, and call itself if a given comment has comments of its own (i.e., nested comments). &amp;nbsp;Each level of comments is indented using the ParagraphFormat.LeftIndent property, setting a value in points.&lt;/p&gt;
&lt;pre class="brush: c-sharp;"&gt;iterate(comments, builder);

...

private void iterate(List&amp;lt;RedditSharp.Comment&amp;gt; comments, 
			   Aspose.Words.DocumentBuilder builder)
{
    indent++;
    builder.ParagraphFormat.LeftIndent = indent * 12;

    foreach (var c in comments)
    {
        if (c.ContentHtml != null)
        {
            builder.ParagraphFormat.Borders.Top.LineStyle = 
			Aspose.Words.LineStyle.Dot;

            builder.ParagraphFormat.Borders.Top.DistanceFromText = 6;

            var html = Server.HtmlDecode(c.ContentHtml)
                             .Replace("&amp;lt;div class=\"md\"&amp;gt;", "")
                             .Replace("&amp;lt;/div&amp;gt;", "")
                             .Replace("&amp;lt;p&amp;gt;", "")
                             .Replace("&amp;lt;/p&amp;gt;", "&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;");

            builder.Font.Name = "Times New Roman";
            builder.Font.Size = 10;
            builder.Font.Italic = false;

            builder.InsertHtml(html);

            builder.Font.Name = "Arial";
            builder.Font.Size = 8;
            builder.Font.Italic = true;

            builder.Writeln(" - " + c.Author);

            if (c.Comments.Count &amp;gt; 0)
                iterate(c.Comments, builder);
        }
    }
    indent--;
}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When I first wrote this function, I tried using RedditSharp&amp;rsquo;s Comment.Content property (instead of .ContentHtml). &amp;nbsp;I had to replace hard returns (\n) in the text with vertical tabs (\v) to keep new paragraphs from being started in the document (otherwise, the indent was lost). &amp;nbsp;Even so, the result looked strange to me, since comments in Reddit are entered in plain text using Markdown (&lt;a href="http://en.wikipedia.org/wiki/Markdown" target="_blank"&gt;http://en.wikipedia.org/wiki/Markdown&lt;/a&gt;), but they are intended to be rendered as rich text. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;The rendered HTML version of the comments is wrapped in a &amp;lt;div&amp;gt; tag, and uses &amp;lt;p&amp;gt; elements for each paragraph. &amp;nbsp;However, similar to the hard return issue with Markdown, the indenting was lost when the DocumentBuilder.InsertHtml() function encountered the &amp;lt;div&amp;gt; and &amp;lt;p&amp;gt; elements, because these were handled as new paragraphs by Aspose.Words. &amp;nbsp;So, the easy solution seemed to be to clean the HTML before inserting it into the document (by removing the &amp;lt;div&amp;gt; and &amp;lt;p&amp;gt; tags, and inserting two &amp;lt;br&amp;gt; elements in place of the closing &amp;lt;/p&amp;gt; tag, etc.).&lt;/p&gt;
&lt;p&gt;Finally, after all of the comments are rendered, it is time to save the results. &amp;nbsp;I wrote my program as part of an ASP.NET web application, so saving the document is really just streaming it to the user&amp;rsquo;s browser. &amp;nbsp;The Document object&amp;rsquo;s save() method has an overload that accepts a HttpResponse object as the first parameter, and makes the task of saving/streaming to the user very straightforward:&lt;/p&gt;
&lt;pre class="brush: c-sharp;"&gt;doc.Save(Response, "iama.pdf", Aspose.Words.ContentDisposition.Inline, null);&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: This method overload is not available in the 3.5 Client Profile assembly, but if you need to use the Client Profile, then chances are that you will just be saving the results to an actual file anyways.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jasonfollas.com/blog/image.axd?picture=%2f2013%2f03%2fimage002.png" alt="" /&gt;&lt;/p&gt;
&lt;h1&gt;Closing Thoughts&lt;/h1&gt;
&lt;p&gt;Overall, I was impressed by the power and ease provided by Aspose.Words. &amp;nbsp;While it didn&amp;rsquo;t always do everything in the way that I thought it should, it is probably due more to my lack of understanding of how the Word document model works rather than a flaw in this library.&lt;/p&gt;
&lt;p&gt;The DocumentBuilder object is the real powerhouse of the library, and the InsertHtml function makes it a breeze for web developers to add entire chunks of content to Word Documents. &amp;nbsp;Though, while this technique may get someone like me to the 80% mark with very little effort, it still remains to be seen how much more effort would be required in the form of code tweaking in order to produce a 100% pixel-perfect document of content.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclosure of Material Connection: I received one or more of the products or services mentioned above for free in the hope that I would mention it on my blog. Regardless, I only recommend products or services I use personally and believe my readers will enjoy. &amp;nbsp;I am disclosing this in accordance with the Federal Trade Commission&amp;rsquo;s 16 CFR, Part 255: &amp;nbsp;&amp;ldquo;&lt;a href="http://ftc.gov/os/2009/10/091005revisedendorsementguides.pdf" target="_blank"&gt;Guides Concerning the Use of Endorsements and Testimonials in Advertising&lt;/a&gt;.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=mjPeaskE_l0:oK0rp4KxbdY:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=mjPeaskE_l0:oK0rp4KxbdY:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=mjPeaskE_l0:oK0rp4KxbdY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=mjPeaskE_l0:oK0rp4KxbdY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=mjPeaskE_l0:oK0rp4KxbdY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/mjPeaskE_l0" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=ca964609-ca81-483e-b28b-d44f53a71da0</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=ca964609-ca81-483e-b28b-d44f53a71da0</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2013/03/29/Product-Evaluation-AsposeWords.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=ca964609-ca81-483e-b28b-d44f53a71da0</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=ca964609-ca81-483e-b28b-d44f53a71da0</feedburner:origLink></item><item><title>Knave 21 (Blackjack): The Fairness of Random Cards</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/nWHOE8ShF80/post.aspx</link><category>JavaScript</category><category>Knave</category><category>Metro</category><pubDate>Mon, 26 Nov 2012 15:46:00 PST</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=3901f652-2367-4fea-8605-0ee90f9378d4</guid><description>&lt;p&gt;Blackjack is one of my favorite games in the casino. &amp;nbsp;I'm a casual player, and certainly not an advantage player by any means. &amp;nbsp;To help me drill basic strategy, especially for things like soft hands and splits, I decided to write a version of Blackjack for Windows 8 and make it a game that &lt;strong&gt;*I*&lt;/strong&gt;&amp;nbsp;would like to play. &amp;nbsp;Since I'm not a high-roller, I also wanted to simulate the bankroll that casual players might use in an actual casino: $500 buy in at a $10 minimum table.&lt;/p&gt;
&lt;p&gt;Thus, Knave 21 (soon to be renamed Knave Blackjack) was born after a couple of hundred hours of work in the evenings and weekends (&lt;a title="Knave Blackjack App" href="http://apps.microsoft.com/webpdp/en-US/app/knave-21/c9a42dca-4a9a-4051-b890-54c11c5028fb" target="_blank"&gt;the version in the Windows Store&lt;/a&gt; represents the third rewrite, and a version currently in development has undergone major refactoring recently as I prepare to add more features in the near future). &amp;nbsp;It's been a labor of love, and I hope that the attention to detail reveals that. &amp;nbsp;I've received a lot of positive feedback, and, recently, some negative feedback as well (which prompted this blog post).&lt;/p&gt;
&lt;p&gt;One thing that every card game author likely struggles with is how to randomize the card selection so that it's fair to the player. &amp;nbsp;Knave 21 has the concept of a shoe, which is 2-6 decks of cards that are shuffled together. &amp;nbsp;It penetrates much deeper than a real casino (the reshuffle automatically occurs when 12 cards remain in the shoe), but the randomness of the deck is very dependent on whatever pseudo-random number generator can be coded in JavaScript.&lt;/p&gt;
&lt;p&gt;Instead of relying on JavaScript's Math.random() function, Knave 21 utilizes the &lt;a title="Better random numbers in JavaScript" href="http://baagoe.org/en/w/index.php/Better_random_numbers_for_javascript" target="_blank"&gt;Alea library by Johannes Baag&amp;oslash;e&lt;/a&gt;&amp;nbsp;to provide a better distribution of random numbers. &amp;nbsp;And, since the shoe is serialized and saved to roaming storage (so you can resume a game on another computer), I didn't want to pre-shuffle the shoe. &amp;nbsp;Instead, a random card is selected and removed from the shoe upon demand. &amp;nbsp;If someone were to view the roaming state data, they could see what cards were left in the shoe, but not what the next card would be. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;More importantly (and in response to some recent negative feedback), the game doesn't care what cards have been played or how much you are betting when determining the next card - it simply picks a random number and that's the card that is drawn. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;I'm very concerned about Knave 21's reputation, especially since I have paying customers now that the app is listed in the Windows Store. &amp;nbsp;In the interest of openness, the code for the shoe implementation follows. &amp;nbsp;Note the "nextCard" function for the RNG implementation.&lt;/p&gt;
&lt;pre class="brush: js;"&gt;Knave.Shoe = (function (Alea, undefined) {

    var shoe = function (decks) {
        this.cards = [];

        for (var d = 0; d &amp;lt; decks; d++) {
            for (var s = 0; s &amp;lt; 4; s++) {
                for (var r = 0; r &amp;lt; 13; r++) {
                    this.cards.push(new Knave.Card("A23456789TJQK".charAt(r), "HDCS".charAt(s), true));
                }
            }
        }
    };

    shoe.prototype = {
        nextCard: function (facedown) {
            var random = new Alea();
            var index = random.uint32() % this.cards.length;
            
            var c = this.cards.splice(index, 1);

            if (c.length === 0)
                return undefined;

            var ret = c[0];

            if (facedown !== undefined)
                ret.facedown(facedown);

            return ret;
        },
        remaining: function () {
            return this.cards.length;
        }
    }

    return shoe;
})(Alea);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=nWHOE8ShF80:1e8L6M1S7dk:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=nWHOE8ShF80:1e8L6M1S7dk:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=nWHOE8ShF80:1e8L6M1S7dk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=nWHOE8ShF80:1e8L6M1S7dk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=nWHOE8ShF80:1e8L6M1S7dk:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/nWHOE8ShF80" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=3901f652-2367-4fea-8605-0ee90f9378d4</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=3901f652-2367-4fea-8605-0ee90f9378d4</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2012/11/26/Knave-21-(Blackjack)-The-Fairness-of-Random-Cards.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=3901f652-2367-4fea-8605-0ee90f9378d4</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=3901f652-2367-4fea-8605-0ee90f9378d4</feedburner:origLink></item><item><title>Metro: Introducing the Local and Web Contexts</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/_jFnWzborPg/post.aspx</link><category>Metro</category><pubDate>Mon, 09 Jul 2012 10:02:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=8552de5c-1dac-4bff-a408-e48ef1835dd0</guid><description>&lt;p&gt;I recently recorded an episode of &lt;a href="http://www.thetabletshow.com/" target="_blank"&gt;The Tablet Show&lt;/a&gt;&amp;nbsp;with &lt;a href="http://twitter.com/carlfranklin" target="_blank"&gt;Carl Franklin&lt;/a&gt; and &lt;a href="http://twitter.com/richcampbell" target="_blank"&gt;Richard Campbell&lt;/a&gt;&amp;nbsp;(it will be published at the end of July 2012) where I&amp;nbsp;&lt;span style="text-decoration: line-through;"&gt;rambled on about&lt;/span&gt;&amp;nbsp;discussed different concepts that are needed to construct a Geospatial Metro-style application. &amp;nbsp;Since I seem to do more web development these days than anything else, I naturally approached this from a HTML/JavaScript developer's point of view.&lt;/p&gt;
&lt;p&gt;The geospatial part is really irrelevant. &amp;nbsp;I included it because I could speak to the subject matter, and it permitted me to establish some constraints around the otherwise huge topic of writing a Metro-style application. &amp;nbsp;From the web developer's point of view, though, there are existing JavaScript-based APIs that the developer will be interested in using while writing the Metro application (i.e., jQuery and OpenLayers comes to mind). &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now, when you write a Metro application using .NET or C++, there's a compilation step that takes place to compile the source code into an executable (EXE and/or DLL). &amp;nbsp;The executable and any dependencies are packaged into an application package (an .appx file), which is really just a renamed .zip file that contains the files, a manifest, and cryptographic information to ensure that the contents were not tampered with. &amp;nbsp;Aside from WinRT libraries, everything that is needed to run the application must be included in the package.&lt;/p&gt;
&lt;p&gt;HTML/JavaScript Metro applications, by contrast, actually run as a web page inside of an Internet Explorer 10 process. &amp;nbsp;The source files are stored within the application package, much as they would be on a web server. &amp;nbsp;But, instead of downloading HTML, JavaScript, CSS, and images from a web server across a network, the resources are retrieved from the .appx file on the user's hard drive (much faster load times, and the application is still accessible when there is no network connectivity).&lt;/p&gt;
&lt;p&gt;Metro-style applications built using HTML/JavaScript still have access to the Windows Runtime and can do just about anything that their compiled-counterparts can. &amp;nbsp;In order to allow such privileged access, however, certain common practices in the web world had to be explicitly prohibited. &amp;nbsp;Specifically, anything that attempts to inject HTML or script into the DOM of a Metro-style application will result in an exception (to prevent third-party script injection attacks). &amp;nbsp;More details can be found here:&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This safe HTML filtering causes a problem with a lot of existing JavaScript libraries. &amp;nbsp;So, how is a developer supposed to use such a library inside of a Metro application? &amp;nbsp;It turns out that in the case of Metro-style applications, Internet Explorer 10 will assume two different personalities: Local context and Web context. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;The application bootstraps into the Local context. &amp;nbsp;This mode is what you'll find most people talking about when they discuss building Metro-style applications using HTML/JavaScript because it has full access to WinJS (and WinRT). Local context URIs start with the "ms-appx" protocol, and the resources must exist in the .appx file.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jasonfollas.com/blog/image.axd?picture=%2f2012%2f07%2fmetro_context_2.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The Web context is totally isolated from the Local context, and cannot access WinRT and a lot of other things that the Local context can. &amp;nbsp;As a result, code running in the Web context behaves pretty much like a normal web application today. &amp;nbsp;This means that developers can continue using those existing JavaScript libraries that don't work in the Local context!&lt;/p&gt;
&lt;p&gt;Web context URIs&amp;nbsp;start with the "ms-appx-web" protocol (if the resource exists in the .appx file), or the "http" protocol (if the resource is to be loaded from a web server). &amp;nbsp;Specific&amp;nbsp;differences between Local and Web contexts is documented here:&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465373.aspx"&gt;http://msdn.microsoft.com/en-us/library/windows/apps/hh465373.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jasonfollas.com/blog/image.axd?picture=%2f2012%2f07%2fmetro_context_3.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;In practice, an IFRAME is used to introduce Web context content into a Metro application. &amp;nbsp;In this way, the outermost web page runs in the Local context, while the IFRAME's content runs in the Web context. &amp;nbsp;It's possible for the IFRAME to be styled to fill the entire screen, if needed (and the outermost web page becomes just a thin hosting shell).&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jasonfollas.com/blog/image.axd?picture=%2f2012%2f07%2fmetro_context_1.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;A common scenario is that data in the Local context will need to be sent to the web context (and vice versa). &amp;nbsp;For instance, code running in the Local context may listen for events fired by the device's Compass sensor. &amp;nbsp;When a new directional heading is established, the Local context code will need to send the new data to the Web context code for further processing.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jasonfollas.com/blog/image.axd?picture=%2f2012%2f07%2fmetro_context_4.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;HTML5 defines a means to do this cross-document communication using the window.postMessage() function. &amp;nbsp;In the case of the new Compass reading, the Local context code would post a message to the IFRAME. &amp;nbsp;The Web context code would need to register an event listener for the window's "message" event.&lt;/p&gt;
&lt;p&gt;The messages themselves are strings, and the developer is left with the task of implementing a data protocol. &amp;nbsp;JavaScript Object Notation (JSON) will often be used to serialize JavaScript object to a string representation for the purpose of transferring across the contexts (the sending side will use JSON.stringify() to serialize the object, while the receiving side will use JSON.parse() to deserialize it).&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.jasonfollas.com/blog/image.axd?picture=%2f2012%2f07%2fmetro_context_5.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The hybrid Local-Web context architecture allows an existing HTML5/JavaScript web application to be converted into a Metro-style application without the need to modify third-party JavaScript libraries.&amp;nbsp; Though, even after such a conversion, there will still likely be some clean-up needed to make the existing application behave more like a Metro-style application, such as implementing the App Bar for commands, and taking advantage of the Search and Sharing contracts. &amp;nbsp;But, the reward for going through this effort is an application that can then be distributed or offered for sale on the Windows Store to an audience of millions of potential users.&lt;/p&gt;
&lt;p&gt;Want to try these things out today before Windows 8 launches this Fall? &amp;nbsp;Release candidates are available for free:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Windows 8 Download: &lt;a href="http://aka.ms/JenWin8" target="_blank"&gt;http://aka.ms/JenWin8&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio 2012 Download: &lt;a href="http://aka.ms/JenVS2012" target="_blank"&gt; http://aka.ms/JenVS2012&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=_jFnWzborPg:MmaFo8doM5g:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=_jFnWzborPg:MmaFo8doM5g:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=_jFnWzborPg:MmaFo8doM5g:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=_jFnWzborPg:MmaFo8doM5g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=_jFnWzborPg:MmaFo8doM5g:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/_jFnWzborPg" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=8552de5c-1dac-4bff-a408-e48ef1835dd0</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=8552de5c-1dac-4bff-a408-e48ef1835dd0</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2012/07/09/Metro-Introducing-the-Local-and-Web-Contexts.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=8552de5c-1dac-4bff-a408-e48ef1835dd0</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=8552de5c-1dac-4bff-a408-e48ef1835dd0</feedburner:origLink></item><item><title>Migrating to BlogEngine.NET</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/rPUQMCVqs2s/post.aspx</link><pubDate>Sat, 07 Jul 2012 16:00:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=2f71e569-f3c2-42da-a3b1-f1465718a6d2</guid><description>&lt;p&gt;I've been wanting to migrate this blog to a different blogging engine for a while now. &amp;nbsp;So, the other day, while recording an episode of &lt;a href="http://www.thetabletshow.com/" target="_blank"&gt;The Tablet Show&lt;/a&gt;, Richard Campbell asked me "Did you know that your blog is down?" &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Well, it seems that a recent security patch broke something about SubText as I had it set up on my hosting provider. This became my opportunity to finally spend some time on this tired site!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=rPUQMCVqs2s:4WlE7I79Mg8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=rPUQMCVqs2s:4WlE7I79Mg8:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=rPUQMCVqs2s:4WlE7I79Mg8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=rPUQMCVqs2s:4WlE7I79Mg8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=rPUQMCVqs2s:4WlE7I79Mg8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/rPUQMCVqs2s" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=2f71e569-f3c2-42da-a3b1-f1465718a6d2</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=2f71e569-f3c2-42da-a3b1-f1465718a6d2</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2012/07/07/Migrating-to-BlogEngineNET.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=2f71e569-f3c2-42da-a3b1-f1465718a6d2</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=2f71e569-f3c2-42da-a3b1-f1465718a6d2</feedburner:origLink></item><item><title>Entity Framework Spatial: A Real World Example</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/dg7C-ZSIW3o/post.aspx</link><category>Entity Framework</category><category>Spatial</category><pubDate>Wed, 27 Jul 2011 11:26:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=271471af-fdaa-4f07-87b9-fadddb273966</guid><description>&lt;p&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;From the Wikipedia article, &lt;a href="http://en.wikipedia.org/wiki/Leadership_in_Energy_and_Environmental_Design"&gt;Leadership in Energy and Environmental Design (LEED)&lt;/a&gt; is described as &amp;ldquo;an internationally recognized green building certification system, providing third-party verification that a building or community was designed and built using strategies intended to improve performance in metrics such as energy savings, water efficiency, CO&lt;sub&gt;2&lt;/sub&gt; emissions reduction, improved indoor environmental quality, and stewardship of resources and sensitivity to their impacts.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;In my own words, LEED is a certification system that awards points for following certain environmentally-friendly practices when constructing a building. In the end, a building can be qualify for one of four different levels of certifications, based on the number of points: Certified, Silver, Gold, Platinum. There are often tax benefits associated with having a LEED certification, and many new government buildings (especially Federal) are required to be LEED certified.&lt;/p&gt;
&lt;p&gt;Two points in particular (out of of 100, or so) from the LEED checklist are related to geospatial data. One point is awarded if at least 20% of the building materials (by cost) used in construction were manufactured within 500 miles of the job site. A second point is awarded if 10% of the raw materials of those building materials were extracted, harvested, or recovered within 500 miles of the job site.&lt;/p&gt;
&lt;p&gt;As a window glass manufacturer, Tempuri Glass is often asked to provide data about its products that are being considered for use in construction. Tempuri Glass may have a certain advantage over its competitors if it can quickly show that its products would count towards these two points for any arbitrary job site.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Data&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Tempuri is a simple organization, making only a single type of product (Soda Lime glass) that is then cut into different sizes per order. Therefore, regardless of how many different sized glass panes are produced by a given facility, the ingredients for that glass is the same. The formulas used will be different between facilities, though, since the raw ingredients will be sourced from different locations, and adjustments may need to be made to the ratios due to environmental factors (things like: elevation, temperature, humidity, etc).&lt;/p&gt;
&lt;p&gt;So, for our data model, we just need to know where each facility is, and then the formula used to make the glass at that facility (including the ingredients of that formula and the location where they were harvested from).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jasonfollas.com/blog/images/jasonfollas_com/blog/Windows-Live-Writer/22ea53fcc227_8DCC/a.EF_Diagram.png"&gt; &lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="a.EF_Diagram" src="http://jasonfollas.com/blog/images/jasonfollas_com/blog/Windows-Live-Writer/22ea53fcc227_8DCC/a.EF_Diagram_thumb.png" alt="a.EF_Diagram" width="642" height="317" border="0" /&gt; &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Within the data store, the [Geocode] columns of the Facility and FormulaComponent tables use the SQL Server &lt;em&gt;geography&lt;/em&gt; type. This is useful for the large-scale/real-world distance calculations that Tempuri Glass needs to perform, since the way that you calculate distance on an sphere or ellipsoid (like the Earth) &lt;a href="http://www.jasonfollas.com/blog/archive/2008/05/16/sql-server-2008-spatial-data-part-7.aspx"&gt;is vastly different than on a flat map&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the Entity Framework model (using the &lt;a href="http://blogs.msdn.com/b/adonet/archive/2011/06/30/announcing-the-microsoft-entity-framework-june-2011-ctp.aspx"&gt;June 2011 CTP&lt;/a&gt;), the SQL Server &lt;em&gt;geography&lt;/em&gt; types are mapped as the new &lt;strong&gt;System.Data.Spatial.DbGeography&lt;/strong&gt; type. This makes the geospatial data a first class citizen of our data model, and not just a &lt;a href="http://www.jasonfollas.com/blog/archive/2010/02/14/spatial-data-and-the-entity-framework.aspx"&gt;castable opaque BLOB&lt;/a&gt;, as was the case in the past.&lt;/p&gt;
&lt;p&gt;Geospatial data can take on many forms, including Points, Line Strings, Polygons, and collections of these shapes. Even though it&amp;rsquo;s not apparent from the data model, our [Geocode] data will contain only Points (i.e., a single Latitude/Longitude pair). Likewise, a job site will be specified as a single Point, though there is no hard requirement for this because distance can still be calculated between a Polygon and a Point with no coding change required.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Facility Sample Data&lt;/strong&gt;&lt;/p&gt;
&lt;table style="width: 711px; height: 226px;" border="1" cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="66"&gt;
&lt;p&gt;&lt;strong&gt;FacilityID&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="119"&gt;
&lt;p&gt;&lt;strong&gt;FacilityName&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="96"&gt;
&lt;p&gt;&lt;strong&gt;City&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="41"&gt;
&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;&lt;strong&gt;Geocode&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="68"&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="119"&gt;
&lt;p&gt;Greenfield, IA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="97"&gt;
&lt;p&gt;Greenfield&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="43"&gt;
&lt;p&gt;IA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-94.4547843933106 41.3151755156904)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="70"&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="118"&gt;
&lt;p&gt;Spring Green, WI&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Spring Green&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="45"&gt;
&lt;p&gt;WI&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-90.053981 43.17431)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="71"&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="118"&gt;
&lt;p&gt;Tomah, WI&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Tomah&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="47"&gt;
&lt;p&gt;WI&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-90.477058 43.989319)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="72"&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Fremont, IN&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Fremont&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="48"&gt;
&lt;p&gt;IN&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-84.9314403533936 41.7186070559443)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="73"&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Fargo, ND&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Fargo&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="49"&gt;
&lt;p&gt;ND&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-96.8667125701904 46.8985894795683)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="74"&gt;
&lt;p&gt;6&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Waxahachie, TX&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Waxahachie&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="50"&gt;
&lt;p&gt;TX&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-96.8427014350891 32.4424403136322)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="74"&gt;
&lt;p&gt;7&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Hood River, OR&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Hood River&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="51"&gt;
&lt;p&gt;OR&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-121.51526927948 45.630620334868)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="74"&gt;
&lt;p&gt;8&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Vinton, VA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Vinton&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="51"&gt;
&lt;p&gt;VA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-79.863876 37.263329)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="74"&gt;
&lt;p&gt;9&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Casa Grande, AZ&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Casa Grande&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="51"&gt;
&lt;p&gt;AZ&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-111.78155422210693 32.882073958767954)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="74"&gt;
&lt;p&gt;10&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Mountain Top, PA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Mountain Top&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="51"&gt;
&lt;p&gt;PA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-75.896477 41.141327)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="74"&gt;
&lt;p&gt;11&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Winlock, WA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Winlock&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="51"&gt;
&lt;p&gt;WA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-122.926218509674 46.5449155194259)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="74"&gt;
&lt;p&gt;12&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Durant, OK&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Durant&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="51"&gt;
&lt;p&gt;OK&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-96.4133548736572 34.0001619910696)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="74"&gt;
&lt;p&gt;13&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="117"&gt;
&lt;p&gt;Mooresville, NC&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="98"&gt;
&lt;p&gt;Mooresville&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="51"&gt;
&lt;p&gt;NC&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="357"&gt;
&lt;p&gt;POINT (-80.7865476608277 35.6316281732984)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FormulaComponent Sample Data&lt;/strong&gt;&lt;/p&gt;
&lt;table border="1" cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="148"&gt;
&lt;p&gt;&lt;strong&gt;FormulaComponentID&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="93"&gt;
&lt;p&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="80"&gt;
&lt;p&gt;&lt;strong&gt;Percentage&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="132"&gt;
&lt;p&gt;&lt;strong&gt;SourceLocation&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;&lt;strong&gt;Geocode&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="150"&gt;
&lt;p&gt;14&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="94"&gt;
&lt;p&gt;Limestone&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="82"&gt;
&lt;p&gt;13&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="131"&gt;
&lt;p&gt;Genola, UT&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-111.808204650879 40.0098667779887)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="152"&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="94"&gt;
&lt;p&gt;Silica Sand&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="84"&gt;
&lt;p&gt;75&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="131"&gt;
&lt;p&gt;Houck, AZ&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-109.241695404053 35.2062151838369)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="153"&gt;
&lt;p&gt;27&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="94"&gt;
&lt;p&gt;Soda Ash&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="86"&gt;
&lt;p&gt;12&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="131"&gt;
&lt;p&gt;Trona, CA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-117.311668395996 35.6955040738332)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="153"&gt;
&lt;p&gt;15&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="94"&gt;
&lt;p&gt;Limestone&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="87"&gt;
&lt;p&gt;13&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="130"&gt;
&lt;p&gt;Genola, UT&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-111.808204650879 40.0098667779887)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="154"&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="93"&gt;
&lt;p&gt;Silica Sand&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="88"&gt;
&lt;p&gt;75&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="130"&gt;
&lt;p&gt;Houck, AZ&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-109.241695404053 35.2062151838369)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="155"&gt;
&lt;p&gt;28&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="93"&gt;
&lt;p&gt;Soda Ash&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="89"&gt;
&lt;p&gt;12&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="130"&gt;
&lt;p&gt;Trona, CA&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-117.311668395996 35.6955040738332)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="155"&gt;
&lt;p&gt;16&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="93"&gt;
&lt;p&gt;Limestone&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="90"&gt;
&lt;p&gt;13&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="130"&gt;
&lt;p&gt;Chicago, IL&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-87.6176834106445 41.5738476278005)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="156"&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="93"&gt;
&lt;p&gt;Silica Sand&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="90"&gt;
&lt;p&gt;75&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="130"&gt;
&lt;p&gt;Overton, NV&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-114.4313621521 36.5146030619859)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="bottom" width="156"&gt;
&lt;p&gt;29&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="93"&gt;
&lt;p&gt;Soda Ash&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="90"&gt;
&lt;p&gt;12&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="130"&gt;
&lt;p&gt;Green River, WY&lt;/p&gt;
&lt;/td&gt;
&lt;td valign="bottom" width="345"&gt;
&lt;p&gt;POINT (-109.448783397675 41.5090754257687)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Spatial Querying Algorithm&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Input: Job Site Latitude/Longitude&lt;/p&gt;
&lt;p&gt;Steps:&lt;/p&gt;
&lt;p&gt;A. Query for closest facility to Job Site within 500 miles:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Calculate the distance between the job site and each facility.&lt;/li&gt;
&lt;li&gt;Filter the list of facilities to just those where distance &amp;lt; 500 miles.&lt;/li&gt;
&lt;li&gt;Order the list of facilities by distance in ascending order.&lt;/li&gt;
&lt;li&gt;The first element (if any) will be the closest facility, and also signifies that the product qualifies as being manufactured within 500 miles&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;B. If there is a facility within 500 miles, then sum the percentage of formula components that were sourced from within 500 miles of the Job Site:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Calculate the distance between the job site and each of the facility&amp;rsquo;s formula components&lt;/li&gt;
&lt;li&gt;Filter the list of formula components to just those where distance &amp;lt; 500 miles&lt;/li&gt;
&lt;li&gt;Sum the Percentages&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Output: Boolean of whether the product qualifies; Percentage of the product&amp;rsquo;s ingredients that qualifies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Before we can calculate distance using an &lt;a href="http://www.jasonfollas.com/blog/archive/2011/07/21/entity-framework-spatial-dbgeography-members.aspx"&gt;instance method of the DbGeography type&lt;/a&gt;, we need to actually create an instance to represent the Job Site. &lt;strong&gt;DbGeography&lt;/strong&gt; is immutable and does not have a constructor, so instead, a static method must be called to create a new object. There are a number of these factory methods available to create specific kinds of shapes (Point, Line String, Polygon, etc) given different kinds of input (text, byte arrays).&lt;/p&gt;
&lt;p&gt;For simplicity, let&amp;rsquo;s use the .Parse() method, which accepts Well-Known Text (WKT) as input, and assumes a Spatial Reference ID of 4326 (the same coordinate system that GPS and internet mapping sites use).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: WKT uses a (Longitude, Latitude) ordering for points, which adheres to the same concept as (X, Y) ordering for Cartesian coordinates.&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;div class="code"&gt;&lt;p&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="type"&gt;DbGeography&lt;/span&gt; CreatePoint(&lt;span class="kwrd"&gt;double&lt;/span&gt; latitude, &lt;span class="kwrd"&gt;double&lt;/span&gt; longitude)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="type"&gt;DbGeography&lt;/span&gt;.Parse(&lt;span class="type"&gt;String&lt;/span&gt;.Format(&lt;span class="str"&gt;"POINT({1} {0})"&lt;/span&gt;, latitude, longitude));&lt;br /&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;The first spatial query, written as a LINQ expression, finds the closest qualifying facility. Since SRID 4326 uses meters as the unit of measure, we need to convert 500 miles into meters within the predicate:&lt;/p&gt;
&lt;pre&gt;&lt;div class="code"&gt;&lt;p&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="type"&gt;Facility&lt;/span&gt; GetNearestFacilityToJobsite(&lt;span class="type"&gt;DbGeography&lt;/span&gt; jobsite)&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; q1 = from f &lt;span class="kwrd"&gt;in&lt;/span&gt; context.Facilities&lt;br /&gt;             let distance = f.&lt;span class="type"&gt;Geocode&lt;/span&gt;.Distance(jobsite)&lt;br /&gt;             &lt;span class="kwrd"&gt;where&lt;/span&gt; distance &amp;lt; 500 * 1609.344&lt;br /&gt;             orderby distance&lt;br /&gt;             select f;&lt;br /&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; q1.FirstOrDefault();&lt;br /&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Assuming that a facility was returned, a second LINQ expression can be used to find the sum of Percentage from qualifying Formula Components:&lt;/p&gt;
&lt;pre&gt;&lt;div class="code"&gt;&lt;p&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;decimal&lt;/span&gt; SumQualifyingPercentages(&lt;span class="type"&gt;Facility&lt;/span&gt; nearestFacility, &lt;span class="type"&gt;DbGeography&lt;/span&gt; jobsite)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="kwrd"&gt;var&lt;/span&gt; q2 = from fc &lt;span class="kwrd"&gt;in&lt;/span&gt; nearestFacility.&lt;span class="type"&gt;Formula&lt;/span&gt;.FormulaComponents&lt;br /&gt;            &lt;span class="kwrd"&gt;where&lt;/span&gt; fc.&lt;span class="type"&gt;Geocode&lt;/span&gt;.Distance(jobsite) &amp;lt; 500 * 1609.344&lt;br /&gt;            select fc;&lt;br /&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;return&lt;/span&gt; q2.Sum(c =&amp;gt; c.&lt;span class="type"&gt;Percentage&lt;/span&gt;.GetValueOrDefault(0));&lt;br /&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Finally, putting all of the parts together (using a Tuple&amp;lt;&amp;gt; for the output):&lt;/p&gt;
&lt;pre&gt;&lt;div class="code"&gt;&lt;p&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="type"&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;, &lt;span class="kwrd"&gt;decimal&lt;/span&gt;&amp;gt; GetResults(&lt;span class="kwrd"&gt;double&lt;/span&gt; latitude, &lt;span class="kwrd"&gt;double&lt;/span&gt; longitude)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="type"&gt;DbGeography&lt;/span&gt; jobsite = CreatePoint(latitude, longitude);&lt;br /&gt;   &lt;span class="type"&gt;Facility&lt;/span&gt; nearestFacility = GetNearestFacilityToJobsite(jobsite);&lt;br /&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;if&lt;/span&gt; (nearestFacility != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;   {&lt;br /&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="type"&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;,&lt;span class="kwrd"&gt;decimal&lt;/span&gt;&amp;gt;(&lt;span class="kwrd"&gt;true&lt;/span&gt;, SumQualifyingPercentages(nearestFacility, jobsite));&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="type"&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span class="kwrd"&gt;bool&lt;/span&gt;, &lt;span class="kwrd"&gt;decimal&lt;/span&gt;&amp;gt;(&lt;span class="kwrd"&gt;false&lt;/span&gt;, 0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PerformQuery()&lt;br /&gt;{&lt;br /&gt;   &lt;span class="kwrd"&gt;double&lt;/span&gt; latitude = 47.63752;&lt;br /&gt;   &lt;span class="kwrd"&gt;double&lt;/span&gt; longitude = -122.13343;&lt;br /&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;var&lt;/span&gt; results = GetResults(latitude, longitude);&lt;br /&gt;}&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=dg7C-ZSIW3o:zL5wMF1dVTg:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=dg7C-ZSIW3o:zL5wMF1dVTg:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=dg7C-ZSIW3o:zL5wMF1dVTg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=dg7C-ZSIW3o:zL5wMF1dVTg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=dg7C-ZSIW3o:zL5wMF1dVTg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/dg7C-ZSIW3o" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=271471af-fdaa-4f07-87b9-fadddb273966</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=271471af-fdaa-4f07-87b9-fadddb273966</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2011/07/27/entity-framework-spatial-a-real-world-example.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=271471af-fdaa-4f07-87b9-fadddb273966</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=271471af-fdaa-4f07-87b9-fadddb273966</feedburner:origLink></item><item><title>Entity Framework Spatial: DbGeography and DbGeometry Members</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/CmrSktSp-tM/post.aspx</link><category>Entity Framework</category><category>Spatial</category><pubDate>Thu, 21 Jul 2011 11:21:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=3fd3811d-3c89-462c-b12b-452089a81be9</guid><description>&lt;table border="0" cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap" height="20"&gt;DbGeography Static Property&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;Return Type&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;DbGeometry Static Property&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;Return Type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.DefaultSrid&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.DefaultSrid&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap" height="20"&gt;DbGeography Static Method&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;Return Type&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;DbGeometry Static Method&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;Return Type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.FromBinary(byte[] geographyBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.FromBinary(byte[] geometryBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.FromGml(string geographyMarkup, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.FromGml(string geometryMarkup, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.FromText(string geographyText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.FromText(string geometryText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.GeographyCollectionFromBinary(byte[] geographyBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.GeometryCollectionFromBinary(byte[] geometryBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.GeographyCollectionFromText(string geographyText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.GeometryCollectionFromText(string geometryText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.LineFromBinary(byte[] geographyBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.LineFromBinary(byte[] geometryBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.LineFromText(string geographyText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.LineFromText(string geometryText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.MultilineFromBinary(byte[] geographyBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.MultilineFromBinary(byte[] geometryBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.MultilineFromText(string geographyText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.MultilineFromText(string geometryText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.MultipointFromBinary(byte[] geographyBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.MultipointFromBinary(byte[] geometryBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.MultipointFromText(string geographyText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.MultipointFromText(string geometryText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.MultipolygonFromBinary(byte[] geographyBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.MultipolygonFromBinary(byte[] geometryBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.MultipolygonFromText(string geographyText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.MultipolygonFromText(string geometryText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.Parse(string geographyText)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.Parse(string geometryText)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.PointFromBinary(byte[] geographyBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.PointFromBinary(byte[] geometryBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.PointFromText(string geographyText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.PointFromText(string geometryText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.PolygonFromBinary(byte[] geographyBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.PolygonFromBinary(byte[] geometryBinary, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;DbGeography.PolygonFromText(string geographyText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry.PolygonFromText(string geometryText, int srid)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap" height="20"&gt;DbGeography Instance Property&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;Return Type&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;DbGeometry Instance Property&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;Return Type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Area&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Area&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Boundary&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Centroid&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.ConvexHull&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Dimension&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Dimension&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.EndPoint&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.EndPoint&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Envelope&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.ExteriorRing&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.GeometryType&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;string&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.GeometryType&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.IsClosed&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.IsClosed&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.IsEmpty&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.IsEmpty&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.IsRing&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.IsSimple&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.IsValid&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Latitude&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Length&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Length&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Longitude&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.M&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.M&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.NumGeometries&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.NumGeometries&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.NumInteriorRing&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.NumPoints&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.NumPoints&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.PointOnSurface&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.ProviderValue&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;object&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.ProviderValue&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Srid&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Srid&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.StartPoint&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.StartPoint&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.WellKnownValue WellKnownValue&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeographyWellKnownValue&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.WellKnownValue&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometryWellKnownValue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.WellKnownValue.Srid&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.WellKnownValue.Srid&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;int&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.WellKnownValue.WellKnownBinary&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;byte[]&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.WellKnownValue.WellKnownBinary&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;byte[]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.WellKnownValue.WellKnownText&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;string&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.WellKnownValue.WellKnownText&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.X&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Y&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Z&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Z&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap" height="20"&gt;DbGeography Instance Method&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;Return Type&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;DbGeometry Instance Method&lt;/td&gt;
&lt;td style="background-color: blue; color: white;" nowrap="nowrap"&gt;Return Type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.AsBinary()&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;byte[]&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.AsBinary()&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;byte[]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.AsGml()&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;string&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.AsGml()&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.AsText()&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;string&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.AsText()&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Buffer(double distance)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Buffer(double distance)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Contains(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Crosses(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Difference(DbGeography other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Difference(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Disjoint(DbGeography other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Disjoint(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Distance(DbGeography other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.DistanceDbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;double&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.GeometryN(int index) DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.GeometryN(int index)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.InteriorRingN(int index)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Intersection(DbGeography other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Intersection(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Intersects(DbGeography other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Intersects(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Overlaps(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.PointN(int index)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.PointN(int index)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Relate(DbGeometry other, string matrix)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.SpatialEquals(DbGeography other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.SpatialEquals(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.SymmetricDifference(DbGeography other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.SymmetricDifference(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Touches(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;g.Union(DbGeography other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeography&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Union(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;DbGeometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td nowrap="nowrap" height="20"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;&amp;nbsp;&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;g.Within(DbGeometry other)&lt;/td&gt;
&lt;td nowrap="nowrap"&gt;bool&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=CmrSktSp-tM:0W4P1EB5pHU:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=CmrSktSp-tM:0W4P1EB5pHU:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=CmrSktSp-tM:0W4P1EB5pHU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=CmrSktSp-tM:0W4P1EB5pHU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=CmrSktSp-tM:0W4P1EB5pHU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/CmrSktSp-tM" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=3fd3811d-3c89-462c-b12b-452089a81be9</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=3fd3811d-3c89-462c-b12b-452089a81be9</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2011/07/21/entity-framework-spatial-dbgeography-members.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=3fd3811d-3c89-462c-b12b-452089a81be9</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=3fd3811d-3c89-462c-b12b-452089a81be9</feedburner:origLink></item><item><title>Entity Framework Spatial: First Look</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/OaKXuqTaf0c/post.aspx</link><category>Entity Framework</category><category>Spatial</category><pubDate>Wed, 20 Jul 2011 11:19:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=40511c87-4cc6-499c-ae72-7f3fd431d6b9</guid><description>&lt;p&gt;Today, I began to look into the &lt;a href="http://blogs.msdn.com/b/adonet/archive/2011/06/30/announcing-the-microsoft-entity-framework-june-2011-ctp.aspx"&gt;Entity Framework June 2011 CTP&lt;/a&gt; which includes first class support for Spatial data types.&amp;nbsp; The ADO.NET team created an abstraction layer, based on the OGC simple features specification, with a goal being to support spatial implementations from multiple vendors.&amp;nbsp; As you would expect, SQL Server 2008 Spatial is supported out of the box.&lt;br /&gt;&lt;br /&gt; For some reason, I was expecting a lot of work to be done on the client-side within their abstraction data type.&amp;nbsp; I was pleasantly surprised to see EF pass the heavy lifting to the underlying data store as part of the query.&lt;br /&gt;&lt;br /&gt; For instance, I have a table in my database called Facility with a Geography column named [Geocode].&amp;nbsp; This field contains a point (single latitude/longitude pair) identifying the location of the Facility.&amp;nbsp; Even though this would normally be represented in client-side code as a SqlGeography type, EF wraps it in the new DbGeography type (i.e., the abstraction data type for ellipsoidal data).&lt;br /&gt;&lt;br /&gt; My first query was a LINQ expression to return a list of all facilities that are within 500 miles of a given location:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;div class="code"&gt;&lt;p&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; q = from f &lt;span class="kwrd"&gt;in&lt;/span&gt; context.Facilities &lt;br /&gt;        let p = &lt;span class="type"&gt;DbGeography&lt;/span&gt;.Parse(&lt;span class="str"&gt;"POINT(-83 45)"&lt;/span&gt;) &lt;br /&gt;        &lt;span class="kwrd"&gt;where&lt;/span&gt; f.&lt;span class="type"&gt;Geocode&lt;/span&gt;.Distance(p) &amp;lt; 500 * 1609.344 &lt;br /&gt;        select &lt;span class="kwrd"&gt;new&lt;/span&gt; { f.FacilityID, wkt=f.&lt;span class="type"&gt;Geocode&lt;/span&gt;.AsText() };&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; A couple things about this query:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The default SRID of 4326 is used.&amp;nbsp; This spatial reference system uses meters for distance, so my predicate needs to convert the 500 miles into meters.&amp;nbsp; Like the SqlGeography.Parse() method, DbGeography.Parse() will default to 4326.&lt;/li&gt;
&lt;li&gt;The return type is an anonymous type.&amp;nbsp; I wanted to see how the DbGeography type's .AsText() method was executed (i.e., would it be expressed in the resulting query, or would it be handled client side, etc).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When executed, the LINQ expression above generates the following TSQL:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;div class="code"&gt;&lt;p&gt;SELECT  [Extent1].[FacilityID] AS [FacilityID],&lt;br /&gt;        [Extent1].[Geocode].STAsText() AS [C1] &lt;br /&gt;FROM    [dbo].[Facility] AS [Extent1] &lt;br /&gt;WHERE   ([Extent1].[Geocode].STDistance(geography::Parse(N'POINT(-83 45)'))) &lt; cast(804672 as float(53))&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt; As you can see, the DbGeography.AsText() was translated into the STAsText() method in the query.&amp;nbsp; And, as you might expect, the predicate's DbGeography.Distance() was properly translated into STDistance() in the TSQL WHERE clause.&lt;br /&gt;&lt;br /&gt; The other thing that I was worried about was not having access to the actual SqlGeography type returned from the database.&amp;nbsp; I was surprised to see that EF's DbGeography has a property called ProviderValue that returns the native type that the provider supports!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OaKXuqTaf0c:IIXH1wHSUlE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OaKXuqTaf0c:IIXH1wHSUlE:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OaKXuqTaf0c:IIXH1wHSUlE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OaKXuqTaf0c:IIXH1wHSUlE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OaKXuqTaf0c:IIXH1wHSUlE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/OaKXuqTaf0c" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=40511c87-4cc6-499c-ae72-7f3fd431d6b9</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=40511c87-4cc6-499c-ae72-7f3fd431d6b9</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2011/07/20/entity-framework-spatial-first-look.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=40511c87-4cc6-499c-ae72-7f3fd431d6b9</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=40511c87-4cc6-499c-ae72-7f3fd431d6b9</feedburner:origLink></item><item><title>CodeRush: Anonymous Method Refactoring Fun</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/80sXHCcAjeI/post.aspx</link><category>Blog</category><pubDate>Wed, 14 Jul 2010 11:34:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=cf06a011-0b42-4161-8d30-ba554380f9ae</guid><description>&lt;p&gt;I recently had to work with some code that I wrote a few years ago, and stumbled upon this:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://a.imageshack.us/img84/7176/anonmethod1.png" alt="Code showing an anonymous method being used as an Action delegate in Array.ForEach" /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;(Not that it's relevant to the rest of this blog post, but this code was responsible for deleting a Role in a custom membership provider, but due to foreign key relationships without cascading deletes, all of the User/Role assignments had to be deleted first)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; Now, in all fairness to myself, there's really nothing wrong with this code.&amp;nbsp; Array.ForEach&amp;lt;T&amp;gt; requires an Action&amp;lt;T&amp;gt; delegate, and this anonymous method certainly qualifies as one.&lt;br /&gt;&lt;br /&gt; However, since the time that I wrote this particular piece of code, I started using Lambda expressions more often.&amp;nbsp; To be consistent with the rest of the project's code, I should change this anonymous method into a Lambda expression.&lt;br /&gt;&lt;br /&gt; Fortunately, CodeRush makes this a breeze!&amp;nbsp; Simply put your cursor within with anonymous method itself, and then hit your &lt;a href="http://www.jasonfollas.com/blog/archive/2010/07/09/coderush-the-refactor-key.aspx" target="_blank"&gt;Refactor Key&lt;/a&gt; and choose the "Compress to Lambda Expression" refactoring:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://a.imageshack.us/img444/4954/anonmethod3.png" alt="Compress to Lambda Expression refactoring" /&gt;&lt;br /&gt; As simple as that, the wordy "delegate" syntax of the anonymous method is compressed into the terse "=&amp;gt;" syntax of a Lambda expression:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://a.imageshack.us/img191/4695/anonmethod2.png" alt="Array.ForEach with a Lambda Expression as the Action&amp;lt;T&amp;gt; delegate" /&gt;&lt;br /&gt; But, suppose that you are just learning Lambda expressions, and come across one in code that you don't fully understand.&amp;nbsp; CodeRush allows you to go the other way, too, and expand a Lambda expression into an anonymous method, which may be easier to understand.&amp;nbsp; Similar to above, put your cursor on the Lambda expression, hit the Refactor Key, and then choose "Expand Lambda Expression":&lt;br /&gt;&lt;br /&gt;&lt;img src="http://a.imageshack.us/img696/4858/anonmethod4.png" alt="Expand Lambda Expression refactoring" /&gt;&lt;br /&gt; Anonymous methods were introduced as a way to inline functionality that otherwise had to exist in its own named method.&amp;nbsp; This is really only good if that functionality is used one time.&amp;nbsp; But, what if you discover that the functionality is needed in multiple places?&lt;br /&gt;&lt;br /&gt; CodeRush provides a refactoring for anonymous methods called "Name Anonymous Method" that will extract the logic into a named method that can then be called from other code:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://a.imageshack.us/img693/6535/anonmethod5.png" alt="Name Anonymous Method refactoring" /&gt;&lt;br /&gt; Activating this refactoring will first display the Target Picker (red arrow and line) so that you can select where to add the new method.&amp;nbsp; Then, the new method's name can be set by editing the text in the green box that will appear.&lt;br /&gt;&lt;br /&gt; Finally, suppose that the opposite is true: you have a named method that is only used in one place, and would prefer to just inline that code.&amp;nbsp; Or, perhaps you would like to create a one-off modification to an existing method, and don't need the new functionality to be in its own named method.&lt;br /&gt;&lt;br /&gt; CodeRush has a refactoring called "Inline Delegate" that replaces a delegate referring to a named method with an anonymous method.&amp;nbsp; If there is only a single reference to that named method, then this refactoring will also delete the named method altogether.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://a.imageshack.us/img293/8895/anonmethod6.png" alt="Inline Delegate refactoring" /&gt;&lt;br /&gt;&lt;br /&gt; Since I was already familiar with the anonymous method syntax, CodeRush played an instrumental part in my learning Lambda expressions because I could write an anonymous method and then have it transformed into an equivalent Lambda for me.&amp;nbsp; But, once I knew Lambdas, I found that I wanted to update my older code in order to replace anonymous methods with the newer syntax, and CodeRush made it a trivial task to do this.&lt;br /&gt;&lt;br /&gt; Happy Coding!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=80sXHCcAjeI:FIffQaE2lic:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=80sXHCcAjeI:FIffQaE2lic:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=80sXHCcAjeI:FIffQaE2lic:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=80sXHCcAjeI:FIffQaE2lic:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=80sXHCcAjeI:FIffQaE2lic:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/80sXHCcAjeI" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=cf06a011-0b42-4161-8d30-ba554380f9ae</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=cf06a011-0b42-4161-8d30-ba554380f9ae</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2010/07/14/coderush-anonymous-method-refactoring-fun.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=cf06a011-0b42-4161-8d30-ba554380f9ae</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=cf06a011-0b42-4161-8d30-ba554380f9ae</feedburner:origLink></item><item><title>CodeRush: Markers</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/OQ8YGt0uJx4/post.aspx</link><category>Blog</category><pubDate>Tue, 13 Jul 2010 11:33:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=45585bdd-1240-425c-983c-870f0d83bf26</guid><description>Have you ever become distracted while scrolling through code, or switched to another tab and then forgot what you were working on?  It happens all the time when we try to multitask while coding.  If only there was a call stack for our brains that we could just unwind to find our way back to where we started....&lt;br /&gt;&lt;br /&gt;
Turns out, there is!&lt;br /&gt;&lt;br /&gt;
CodeRush includes a feature called "Markers".  These are little placeholders, or breadcrumbs, for your cursor location that can be created just before your focus changes to another part of code.  When you're done with whatever task distracted you, simply hit ESC (or ALT+End) to collect the most recent marker and your cursor will be returned to exactly where it was when the marker was created.&lt;br /&gt;&lt;br /&gt;
Sometimes, CodeRush will automatically create markers for you during refactoring and template expansions.  These appear as small blue triangles within the newly created code:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://img249.imageshack.us/img249/7552/marker1.png" alt="Refactored code showing a marker" /&gt;&lt;br /&gt;
When you collect a marker, your cursor will be returned to that location, and an animated Locator Beacon will display on top of the cursor to draw your attention to that spot:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://img215.imageshack.us/img215/6969/marker2.png" alt="Animated bullseye showing the marker collection" /&gt;&lt;br /&gt;&lt;br /&gt;
But, you can manually drop your own markers, too, by using ALT+Home.  The manually created markers will be red in color:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://img197.imageshack.us/img197/6854/marker3r.png" alt="Red triangle signifies a manually-created marker" /&gt;&lt;br /&gt;&lt;br /&gt;
Some tricks that you can do with markers:&lt;br /&gt;&lt;br /&gt;
SHIFT+ALT+Home: Drops a marker at the current cursor location and collects the most recent marker (so you can swap between the locations) &lt;span style="font-style: italic;"&gt;Thanks Jay Wren for the clarification.&lt;/span&gt;&lt;br /&gt;
SHIFT+ALT+PgUp: Select text between the current cursor location and the most recently created marker&lt;br /&gt;
SHIFT+ESC: Collect the most recent marker and also paste whatever is in the clipboard at that location&lt;br /&gt;&lt;br /&gt;
Happy Coding!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OQ8YGt0uJx4:ID0okD5HNZ4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OQ8YGt0uJx4:ID0okD5HNZ4:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OQ8YGt0uJx4:ID0okD5HNZ4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OQ8YGt0uJx4:ID0okD5HNZ4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=OQ8YGt0uJx4:ID0okD5HNZ4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/OQ8YGt0uJx4" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=45585bdd-1240-425c-983c-870f0d83bf26</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=45585bdd-1240-425c-983c-870f0d83bf26</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2010/07/13/coderush-markers.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=45585bdd-1240-425c-983c-870f0d83bf26</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=45585bdd-1240-425c-983c-870f0d83bf26</feedburner:origLink></item><item><title>CodeRush: CodeRush Tool Window</title><link>http://feedproxy.google.com/~r/AViewInsideMyHead/~3/FZvIsyBSsSo/post.aspx</link><category>Blog</category><pubDate>Fri, 09 Jul 2010 11:31:00 PDT</pubDate><guid isPermaLink="false">http://www.jasonfollas.com/blog/post.aspx?id=d89e629e-cd4d-4395-a1d4-c44bd8dd9d86</guid><description>CodeRush is full of templates.  Thousands of them, when you combine the basic templates with the various types that are supported by each.  How does someone start to learn all of the required mnemonics in order to use CodeRush effectively?&lt;br /&gt;&lt;br /&gt;
The answer to that is a brilliant feature known as the CodeRush Tool Window:&lt;br /&gt;&lt;br /&gt;&lt;img alt="DevExpress, Tool Windows, CodeRush" src="http://img805.imageshack.us/img805/3508/coderushwindow1.png" /&gt;&lt;br /&gt;&lt;br /&gt;
(DevExpress menu in Visual Studio, Tool Windows -&amp;gt; CodeRush)&lt;br /&gt;&lt;br /&gt;
The CodeRush Tool Window provides a context-sensitive list of "next characters" in CodeRush templates that are valid at the cursor's current location.  As you start to work with CodeRush, leave this window open (perhaps on a second monitor) so that you can train yourself.&lt;br /&gt;&lt;br /&gt;&lt;img alt="CodeRush Tool Window docked on the left" src="http://img16.imageshack.us/img16/5494/coderushwindow2.png" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;
In the screenshot above, I have the CodeRush Tool Window docked on the left side of my IDE.  Depending on where my cursor is located, the contents of the window will change.&lt;br /&gt;&lt;br /&gt;
For example, I can create a new Auto-Implemented Property at the cursor's current location (line 49 in the screenshot).  In the CodeRush Tool Window, I see that mnemonics for Auto-Implemented Properties start with "a", so I can type that character.  But, after typing "a", the contents of the CodeRush window will change:&lt;br /&gt;&lt;br /&gt;&lt;img alt="CodeRush Tool Window after starting a mnemonic" src="http://img695.imageshack.us/img695/5676/coderushwindow3.png" /&gt;&lt;br /&gt;&lt;br /&gt;
The letter "a" by itself is a valid mnemonic for a CodeRush Template, as indicated by the the green "expansion" frame at the top of the CodeRush Tool Window.  If I were to hit the spacebar here, I'd get code for a new abstract class (a preview of this code appears in the expansion frame).  This is not what I want, so I can look in the list to see if typing more characters results in an appropriate mnemonic.  &lt;span style="font-style: italic;"&gt;Note: If you do accidentally expand a wrong template, just perform an Undo (Ctrl-Z) to return to the pre-expansion state of your code.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;
Suppose that I was trying to create an Auto-Implemented Property of type Boolean.  From the contents of the window, I see that "ab" is listed as "bool", and so I only need to type the second character ("b") and then hit the space bar.&lt;br /&gt;&lt;br /&gt;
Play around by moving your cursor to various places in your code, and observing how the contents of the CodeRush Tool Window changes.  Try out some of the template mnemonics that are listed to see how they work.  Remember that Undo (Ctrl-Z) will get you back to where you started.&lt;br /&gt;&lt;br /&gt;
Happy Coding!&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=FZvIsyBSsSo:8sjEwSmma0Y:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=FZvIsyBSsSo:8sjEwSmma0Y:2mJPEYqXBVI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=2mJPEYqXBVI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=FZvIsyBSsSo:8sjEwSmma0Y:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=FZvIsyBSsSo:8sjEwSmma0Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/AViewInsideMyHead?a=FZvIsyBSsSo:8sjEwSmma0Y:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/AViewInsideMyHead?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AViewInsideMyHead/~4/FZvIsyBSsSo" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Jason</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.jasonfollas.com/blog/post.aspx?id=d89e629e-cd4d-4395-a1d4-c44bd8dd9d86</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.jasonfollas.com/blog/trackback.axd?id=d89e629e-cd4d-4395-a1d4-c44bd8dd9d86</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/post/2010/07/09/coderush-coderush-tool-window.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.jasonfollas.com/blog/syndication.axd?post=d89e629e-cd4d-4395-a1d4-c44bd8dd9d86</wfw:commentRss><feedburner:origLink>http://www.jasonfollas.com/blog/post.aspx?id=d89e629e-cd4d-4395-a1d4-c44bd8dd9d86</feedburner:origLink></item></channel></rss>
