<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
    <title>Civilized Development</title>
    
    
    <link rel="alternate" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/" />
    <id>tag:typepad.com,2003:weblog-92290523942524683</id>
    <updated>2012-05-25T08:57:16-07:00</updated>
    <subtitle>Diving into Civil 3D programming the polite way.</subtitle>
    <generator uri="http://www.typepad.com/">TypePad</generator>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/CivilizedDevelopment" /><feedburner:info uri="civilizeddevelopment" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://hubbub.api.typepad.com/" /><entry>
        <title>21WOJP  Week 6: Fun Renumbering Points</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/DHt3nvGTYIA/21wojp-week-6-fun-renumbering-points.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2012/05/21wojp-week-6-fun-renumbering-points.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b0168ebc92f8c970c</id>
        <published>2012-05-25T08:57:16-07:00</published>
        <updated>2012-05-25T08:57:16-07:00</updated>
        <summary>Last week we talked about bulk operations for COGO Points. One of those operations is “point renumbering”. Like all bulk operations, there is an interface defined directly in the ‘CogoPoint’ object, but there is a more efficient way to do it through the bulk operation defined in the ‘CogoPointCollection’. So,...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2013" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Points" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Last week we talked about <a href="http://civilizeddevelopment.typepad.com/civilized-development/2012/05/week-6-cogo-points-bulk-operations.html">bulk operations</a> for COGO Points. One of those operations is “point renumbering”. Like all bulk operations, there is an interface defined directly in the ‘CogoPoint’ object, but there is a more efficient way to do it through the bulk operation defined in the ‘CogoPointCollection’.</p>  <p>So, why talk about renumbering points if it is just another bulk operation? The quick answer is that renumbering points can get you into trouble very quickly. In an ideal world, you will create points and let Civil 3D do its stuff. Unfortunately, the world is less than ideal sometimes, so you have to plan how to work with the points you add.</p>  <p><strong>Define Requirements for Point Numbers</strong></p>  <p>In <a href="http://civilizeddevelopment.typepad.com/civilized-development/2012/05/21wojp-week-5-cogo-point-basics.html">COGO Point Basics</a>, I created a command “CDS_CreateRandomPoints”, which uses all the different ways in which you can create COGO Points. Let’s say that you run that command. The points the command creates should look similar to this:</p>  <p><a href="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ebc92f1c970c-pi"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="RandomPoints" border="0" alt="RandomPoints" src="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b016766c7d3ee970b-pi" width="469" height="372" /></a></p>  <p>As you can in the next screenshot, the points are assigned numbers sequentially.</p>  <p><a href="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b016305d3c577970d-pi"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="PointDetails" border="0" alt="PointDetails" src="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ebc92f31970c-pi" width="465" height="430" /></a></p>  <p>The problem is Civil 3D customers do not work this way with points. Some customers use point numbers to inject special meanings. You may have requirements about what the point number should be depending on what the point represents, or you may have the requirement that a point added should have a specific number because it was the number assigned by the surveyor that initially measured the point. Bottom line, there will be instances when you will need to renumber a point, and when that happens, you to plan in advance.</p>  <p>Let’s say we implement a “naïve” command to renumber a point. The command “CDS_NaiveRenumberPoint” shows what most people will try to do.</p>  <p><strong>C#</strong></p>  <div id="codeSnippetWrapper">   <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">[CommandMethod(<span style="color: #006080">"CDS_NaiveRenumberPoint"</span>)]<br /><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CDS_NaiveRenumberPoint()<br />{<br />  PromptIntegerResult result = _editor.GetInteger(<br />    <span style="color: #006080">"\nEnter point to renumber:"</span>);<br />  <span style="color: #0000ff">if</span> (result.Status != PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">return</span>;<br />  }<br />  <span style="color: #0000ff">uint</span> currentPointNumber = (<span style="color: #0000ff">uint</span>)result.Value;<br /><br />  result = _editor.GetInteger(<span style="color: #006080">"\nEnter new point number:"</span>);<br />  <span style="color: #0000ff">if</span> (result.Status != PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">return</span>;<br />  }<br />  <span style="color: #0000ff">uint</span> newPointNumber = (<span style="color: #0000ff">uint</span>)result.Value;<br /><br />  CogoPointCollection points = _civildoc.CogoPoints;<br />  ObjectId pointId = points.GetPointByPointNumber(currentPointNumber);<br />  points.SetPointNumber(pointId, newPointNumber);<br />}</pre>

  <br /></div>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">&lt;CommandMethod(<span style="color: #006080">"CDS_NaiveRenumberPoint"</span>)&gt; _<br /><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Sub</span> CDS_NaiveRenumberPoint()<br />  <span style="color: #0000ff">Dim</span> result <span style="color: #0000ff">As</span> PromptIntegerResult = _editor.GetInteger(<br />    vbLf &amp; <span style="color: #006080">"Enter point to renumber:"</span>)<br />  <span style="color: #0000ff">If</span> result.Status &lt;&gt; PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Return</span><br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />  <span style="color: #0000ff">Dim</span> currentPointNumber <span style="color: #0000ff">As</span> UInteger = CUInt(result.Value)<br /><br />  result = _editor.GetInteger(vbLf &amp; <span style="color: #006080">"Enter new point number:"</span>)<br />  <span style="color: #0000ff">If</span> result.Status &lt;&gt; PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Return</span><br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />  <span style="color: #0000ff">Dim</span> newPointNumber <span style="color: #0000ff">As</span> UInteger = CUInt(result.Value)<br /><br />  <span style="color: #0000ff">Dim</span> points <span style="color: #0000ff">As</span> CogoPointCollection = _civildoc.CogoPoints<br />  <span style="color: #0000ff">Dim</span> pointId <span style="color: #0000ff">As</span> ObjectId = points.GetPointByPointNumber(<br />    currentPointNumber)<br />  points.SetPointNumber(pointId, newPointNumber)<br /><span style="color: #0000ff">End</span> Sub</pre>

  <br /></div>

<p>This code works as long as the point number entered by the user is not assigned yet. But run the command and assign a number that already exists. You will get the following dialog:</p>

<p><a href="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ebc92f3c970c-pi"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="RenumberOptions" border="0" alt="RenumberOptions" src="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ebc92f4e970c-pi" width="279" height="343" /></a></p>

<p>Before you start the celebrations because you just inherited a Civil 3D feature without writing a single line of code to make it work, think about the problem. If your application is UI based and all you are doing is renumbering the point, I guess is OK to let the dialog pop. But if your application’s intention is to automate some task and there should not be any user interaction, you are in trouble. (Note: To be honest, this is a bug, and we are working very hard to deliver a fix for this problem).</p>

<p>It is impossible for me to decide which course of action you should follow without knowing your requirements, but I will rewrite the command as “CDS_RenumberPoint” making the assumption that if the specified number is in use, we can use it as a hint and assign the next available point number. First, let’s take a look at the command changes:</p>

<p><strong>C#</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>[CommandMethod(<span style="color: #006080">"CDS_RenumberPoint"</span>)]<br /><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CDS_RenumberPoint()<br />{<br />  PromptIntegerResult result = _editor.GetInteger(<br />    <span style="color: #006080">"\nEnter point to renumber:"</span>);<br />  <span style="color: #0000ff">if</span> (result.Status != PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">return</span>;<br />  }<br />  <span style="color: #0000ff">uint</span> currentPointNumber = (<span style="color: #0000ff">uint</span>)result.Value;<br /><br />  result = _editor.GetInteger(<span style="color: #006080">"\nEnter new point number (hint):"</span>);<br />  <span style="color: #0000ff">if</span> (result.Status != PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">return</span>;<br />  }<br />  <span style="color: #0000ff">uint</span> pointNumberHint = (<span style="color: #0000ff">uint</span>)result.Value;<br /><br />  <span style="color: #0000ff">try</span><br />  {<br />    CogoPointCollection points = _civildoc.CogoPoints;<br />    ObjectId pointId = <br />      points.GetPointByPointNumber(currentPointNumber);<br />    points.SetPointNumber(pointId, getNextPointNumberAvailable(</p><p>      pointNumberHint));<br />  }<br />  <span style="color: #0000ff">catch</span> (ArgumentException ex)<br />  {<br />    _editor.WriteMessage(ex.Message);<br />  }           <br />}</p></pre>

  <br /></div>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">&lt;CommandMethod(<span style="color: #006080">"CDS_RenumberPoint"</span>)&gt; _<br /><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Sub</span> CDS_RenumberPoint()<br />  <span style="color: #0000ff">Dim</span> result <span style="color: #0000ff">As</span> PromptIntegerResult = _editor.GetInteger(<br />    vbLf &amp; <span style="color: #006080">"Enter point to renumber:"</span>)<br />  <span style="color: #0000ff">If</span> result.Status &lt;&gt; PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Return</span><br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />  <span style="color: #0000ff">Dim</span> currentPointNumber <span style="color: #0000ff">As</span> UInteger = CUInt(result.Value)<br /><br />  result = _editor.GetInteger(vbLf &amp; <span style="color: #006080">"Enter new point number (hint):"</span>)<br />  <span style="color: #0000ff">If</span> result.Status &lt;&gt; PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Return</span><br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />  <span style="color: #0000ff">Dim</span> pointNumberHint <span style="color: #0000ff">As</span> UInteger = CUInt(result.Value)<br /><br />  <span style="color: #0000ff">Try</span><br />    <span style="color: #0000ff">Dim</span> points <span style="color: #0000ff">As</span> CogoPointCollection = _civildoc.CogoPoints<br />    <span style="color: #0000ff">Dim</span> pointId <span style="color: #0000ff">As</span> ObjectId =<br />      points.GetPointByPointNumber(currentPointNumber)<br />    points.SetPointNumber(pointId,<br />      getNextPointNumberAvailable(pointNumberHint))<br />  <span style="color: #0000ff">Catch</span> ex <span style="color: #0000ff">As</span> ArgumentException<br />    _editor.WriteMessage(ex.Message)<br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">Try</span><br /><span style="color: #0000ff">End</span> Sub</pre>

  <br /></div>

<p>The new implementation is similar. The main difference is that instead of specifying the number entered by the user, we call ‘getNextPointNumberAvailable’ to get the new point number using the value entered by the user as a hint. We surround the calls in a try/catch block because, as we will see in the implementation of ‘getNextPointNumberAvailable’ there might be times when we could not provide a new point. Let’s look at the implementation of that function.</p>

<p><strong>C#</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">private</span> <span style="color: #0000ff">uint</span> getNextPointNumberAvailable(<span style="color: #0000ff">uint</span> hint)<br />{<br />  <span style="color: #0000ff">uint</span> suggested = hint;<br />  CogoPointCollection points = _civildoc.CogoPoints;<br />  <span style="color: #0000ff">while</span> (points.Contains(suggested) &amp;&amp; suggested &lt; _maxPointNumber)<br />  {<br />    suggested++;<br />  }<br /><br />  <span style="color: #0000ff">if</span> (suggested == _maxPointNumber)<br />  {<br />    <span style="color: #0000ff">string</span> msg = String.Format(<br />      <span style="color: #006080">"No available point number at {0} or greater value."</span>, <br />      hint);<br />    <span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> ArgumentException(msg);<br />  }<br /><br />  <span style="color: #0000ff">return</span> suggested;<br />}</pre>

  <br /></div>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <div id="codeSnippetWrapper">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">Private</span> <span style="color: #0000ff">Function</span> getNextPointNumberAvailable(hint <span style="color: #0000ff">As</span> UInteger) _ <br />    <span style="color: #0000ff">As</span> UInteger<br />  <span style="color: #0000ff">Dim</span> suggested <span style="color: #0000ff">As</span> UInteger = hint<br />  <span style="color: #0000ff">Dim</span> points <span style="color: #0000ff">As</span> CogoPointCollection = _civildoc.CogoPoints<br />  <span style="color: #0000ff">While</span> points.Contains(suggested) <span style="color: #0000ff">AndAlso</span> suggested &lt; _maxPointNumber<br />    suggested += 1<br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">While</span><br /><br />  <span style="color: #0000ff">If</span> suggested = _maxPointNumber <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Dim</span> msg <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span> = [<span style="color: #0000ff">String</span>].Format(<br />      <span style="color: #006080">"No available point number at {0} or greater value."</span>, hint)<br />    <span style="color: #0000ff">Throw</span> <span style="color: #0000ff">New</span> ArgumentException(msg)<br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br /><br />  <span style="color: #0000ff">Return</span> suggested<br /><span style="color: #0000ff">End</span> Function</pre>
  </div>
</div>

<p>The number passed to the function is used as a hint. If the point number is in use, we increment its value until we find an available point number. Once in a while, hell will break loose, and there would not be any more point numbers available starting at the value passed, in which case, we will hit the value of _maxPointNumber (this is really the same value as UInt32.MaxValue). When this happens, we will throw an exception. Otherwise, we will return the next available point number.</p>

<p><strong>Renumber Points as Close to Creation as Possible</strong></p>

<p>If your application embeds meaning into a COGO Point number, update/renumber the point as close to where is created as possible. Avoid implementing applications that manipulate point numbers after the fact because you most certainly will run into problems; worse yet, your customers will run into problems.</p>

<p>Even when you plan for a strategy to renumber points, there might be instances where things will not work the way you intended. These are more likely to happen when you allow users to specify parameters involved with point renumbering. Let’s implement a command that allows a user to specify the number of points created and a base number for the point number values assigned. The command looks something like this.</p>

<p><strong>C#</strong></p>

<div>
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p>[CommandMethod(<span style="color: #006080">"CDS_CreateRandomPointsAtSpecifiedNumber"</span>)]<br /><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CDS_CreateRandomPointsAtSpecifiedNumber()<br />{<br />  PromptIntegerResult result = _editor.GetInteger(<br />    <span style="color: #006080">"\nEnter number of points to generate: "</span>);<br />  <span style="color: #0000ff">if</span> (result.Status != PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">return</span>;<br />  }<br />  <span style="color: #0000ff">int</span> numberOfPoints = result.Value;<br /><br />  result = _editor.GetInteger(<br />    <span style="color: #006080">"\nEnter base number for first point: "</span>);<br />  <span style="color: #0000ff">if</span> (result.Status != PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">return</span>;<br />  }<br />  <span style="color: #0000ff">uint</span> basePoint = (<span style="color: #0000ff">uint</span>)result.Value;<br /><br />  ObjectIdCollection createdIds = createPoints(numberOfPoints);<br />  renumberPoints(createdIds, basePoint);<br />}</p><p> </p></pre>
</div>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p><span style="color: #0000ff">private</span> ObjectIdCollection createPoints(<span style="color: #0000ff">int</span> numberOfPoints)<br />{<br />  RandomCoordinateGenerator generator = <br />    <span style="color: #0000ff">new</span> RandomCoordinateGenerator();<br />  Point3dCollection coordinates = <br />    generator.GetCoordinates(numberOfPoints);<br />  CogoPointCollection points = _civildoc.CogoPoints;<br />  _creationSet++;<br />  <span style="color: #0000ff">string</span> description = String.Format(<span style="color: #006080">"Creation {0}"</span>, _creationSet);<br />            <br />  <span style="color: #0000ff">return</span> points.Add(coordinates, description);<br />}</p><p> </p></pre>

  <div id="codeSnippetWrapper">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> renumberPoints(ObjectIdCollection pointIds, <span style="color: #0000ff">uint</span> basePoint)<br />{<br />  CogoPointCollection points = _civildoc.CogoPoints;<br />  <span style="color: #0000ff">uint</span> suggested = basePoint;<br />  <span style="color: #0000ff">foreach</span> (ObjectId pointId <span style="color: #0000ff">in</span> pointIds)<br />  {<br />    suggested = getNextPointNumberAvailable(suggested);<br />    points.SetPointNumber(pointId, suggested);<br />    suggested++;<br />  }<br />}</pre>
  </div>
</div>

<div><strong /></div>

<div><strong>VB.NET</strong></div>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">&lt;CommandMethod(<span style="color: #006080">"CDS_CreateRandomPointsAtSpecifiedNumber"</span>)&gt; _<br /><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Sub</span> CDS_CreateRandomPointsAtSpecifiedNumber()<br />  <span style="color: #0000ff">Dim</span> result <span style="color: #0000ff">As</span> PromptIntegerResult = _editor.GetInteger(<br />    vbLf &amp; <span style="color: #006080">"Enter number of points to generate: "</span>)<br />  <span style="color: #0000ff">If</span> result.Status &lt;&gt; PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Return</span><br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />  <span style="color: #0000ff">Dim</span> numberOfPoints <span style="color: #0000ff">As</span> <span style="color: #0000ff">Integer</span> = result.Value<br /><br />  result = _editor.GetInteger(<br />    vbLf &amp; <span style="color: #006080">"Enter base number for first point: "</span>)<br />  <span style="color: #0000ff">If</span> result.Status &lt;&gt; PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Return</span><br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />  <span style="color: #0000ff">Dim</span> basePoint <span style="color: #0000ff">As</span> UInteger = CUInt(result.Value)<br /><br />  <span style="color: #0000ff">Dim</span> createdIds <span style="color: #0000ff">As</span> ObjectIdCollection = createPoints(numberOfPoints)<br />  renumberPoints(createdIds, basePoint)<br /><span style="color: #0000ff">End</span> Sub</pre>

  <div id="codeSnippetWrapper">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><p><span style="color: #0000ff">Private</span> <span style="color: #0000ff">Function</span> createPoints(numberOfPoints <span style="color: #0000ff">As</span> <span style="color: #0000ff">Integer</span>) _<br />    <span style="color: #0000ff">As</span> ObjectIdCollection<br />  <span style="color: #0000ff">Dim</span> generator <span style="color: #0000ff">As</span> <span style="color: #0000ff">New</span> RandomCoordinateGenerator()<br />  <span style="color: #0000ff">Dim</span> coordinates <span style="color: #0000ff">As</span> Point3dCollection =<br />    generator.GetCoordinates(numberOfPoints)<br />  <span style="color: #0000ff">Dim</span> points <span style="color: #0000ff">As</span> CogoPointCollection = _civildoc.CogoPoints<br />  _creationSet += 1<br />  <span style="color: #0000ff">Dim</span> description <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span> = [<span style="color: #0000ff">String</span>].Format(<br />    <span style="color: #006080">"Creation {0}"</span>, _creationSet)<br /><br />  <span style="color: #0000ff">Return</span> points.Add(coordinates, description)<br /><span style="color: #0000ff">End</span> Function</p><p> </p></pre>

    <div id="codeSnippetWrapper">
      <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">Private</span> <span style="color: #0000ff">Sub</span> renumberPoints(pointIds <span style="color: #0000ff">As</span> ObjectIdCollection,<br />                               basePoint <span style="color: #0000ff">As</span> UInteger)<br />  <span style="color: #0000ff">Dim</span> points <span style="color: #0000ff">As</span> CogoPointCollection = _civildoc.CogoPoints<br />  <span style="color: #0000ff">Dim</span> suggested <span style="color: #0000ff">As</span> UInteger = basePoint<br />  <span style="color: #0000ff">For</span> <span style="color: #0000ff">Each</span> pointId <span style="color: #0000ff">As</span> ObjectId <span style="color: #0000ff">In</span> pointIds<br />    suggested = getNextPointNumberAvailable(suggested)<br />    points.SetPointNumber(pointId, suggested)<br />    suggested += 1<br />  <span style="color: #0000ff">Next</span><br /><span style="color: #0000ff">End</span> Sub</pre>
    </div>
  </div>
</div>

<p>As you can see, we prompt the user to enter the number of points to create and the base number to use when creating the points. At the end of the command, we see this is a two step operation. We first create the points, and then we renumber them.</p>

<p>Go ahead and run the command. I used ‘100’ for the number of points and ‘5’ for the base number to use.</p>

<p><a href="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ebc92f5d970c-pi"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="CreateAtSpcifiedOutput" border="0" alt="CreateAtSpcifiedOutput" src="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ebc92f6a970c-pi" width="493" height="45" /></a></p>

<p>Is this the result that you expected?</p>

<p><a href="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b016766c7d420970b-pi"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="CreateAtSpecifiedResult" border="0" alt="CreateAtSpecifiedResult" src="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ebc92f80970c-pi" width="494" height="482" /></a></p>

<p>Probably not. The first point gets a number of ‘101’ and the rest follow sequentially. If you look at the implementation of ‘renumberPoints()’, you might be able to determine why. We are first creating the points, in this case 100 of them, and they are being numbered (assuming you started with a clean drawing) from 1 to 100. Therefore, when we renumber them with a base value of ‘5’, the point number is in use; therefore, the next available number ‘101’ is assigned.</p>

<p>Not a solution, but an alternate implementation can use a second overload of the ‘CogoPointCollection.SetPointNumber(). which takes an additive factor. Assuming, you know the number of the first point you added, you can add/subtract a factor to get to the value where you want to renumber. An implementation of this concept can be found in the command ‘CDS_CreateRandomPointsAtSpecifiedNumberByFactor’.</p>

<p><strong>C#</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">[CommandMethod(<span style="color: #006080">"CDS_CreateRandomPointsAtSpecifiedNumberByFactor"</span>)]<br /><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CDS_CreateRandomPointsAtSpecifiedNumberByFactor()<br />{<br />  PromptIntegerResult result = _editor.GetInteger(<br />    <span style="color: #006080">"\nEnter number of points to generate: "</span>);<br />  <span style="color: #0000ff">if</span> (result.Status != PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">return</span>;<br />  }<br />  <span style="color: #0000ff">int</span> numberOfPoints = result.Value;<br /><br />  result = _editor.GetInteger(<br />    <span style="color: #006080">"\nEnter base number for first point: "</span>);<br />  <span style="color: #0000ff">if</span> (result.Status != PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">return</span>;<br />  }<br />  <span style="color: #0000ff">uint</span> basePoint = (<span style="color: #0000ff">uint</span>)result.Value;<br /><br />  ObjectIdCollection createdIds = createPoints(numberOfPoints);<br />  <span style="color: #0000ff">uint</span> firstCreatedPointNumber = getPointNumberFor(createdIds[0]);<br />  <span style="color: #0000ff">int</span> additiveFactor = (<span style="color: #0000ff">int</span>)(basePoint - firstCreatedPointNumber);<br />  CogoPointCollection points = _civildoc.CogoPoints;<br />  points.SetPointNumber(ToEnumerable(createdIds), additiveFactor);<br />}</pre>

  <br /></div>

<p><strong>VB.NET</strong></p>

<div>
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">&lt;CommandMethod(<span style="color: #006080">"CDS_CreateRandomPointsAtSpecifiedNumberByFactor"</span>)&gt; _<br /><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Sub</span> CDS_CreateRandomPointsAtSpecifiedNumberByFactor()<br />  <span style="color: #0000ff">Dim</span> result <span style="color: #0000ff">As</span> PromptIntegerResult = _editor.GetInteger(<br />    vbLf &amp; <span style="color: #006080">"Enter number of points to generate: "</span>)<br />  <span style="color: #0000ff">If</span> result.Status &lt;&gt; PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Return</span><br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />  <span style="color: #0000ff">Dim</span> numberOfPoints <span style="color: #0000ff">As</span> <span style="color: #0000ff">Integer</span> = result.Value<br /><br />  result = _editor.GetInteger(<br />    vbLf &amp; <span style="color: #006080">"Enter base number for first point: "</span>)<br />  <span style="color: #0000ff">If</span> result.Status &lt;&gt; PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Return</span><br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />  <span style="color: #0000ff">Dim</span> basePoint <span style="color: #0000ff">As</span> UInteger = CUInt(result.Value)<br /><br />  <span style="color: #0000ff">Dim</span> createdIds <span style="color: #0000ff">As</span> ObjectIdCollection = createPoints(numberOfPoints)<br />  <span style="color: #0000ff">Dim</span> firstCreatedPointNumber <span style="color: #0000ff">As</span> UInteger =<br />    getPointNumberFor(createdIds(0))<br />  <span style="color: #0000ff">Dim</span> additiveFactor <span style="color: #0000ff">As</span> <span style="color: #0000ff">Integer</span> =<br />    <span style="color: #0000ff">CInt</span>(basePoint - firstCreatedPointNumber)<br />  <span style="color: #0000ff">Dim</span> points <span style="color: #0000ff">As</span> CogoPointCollection = _civildoc.CogoPoints<br />  points.SetPointNumber(ToEnumerable(createdIds), additiveFactor)<br /><span style="color: #0000ff">End</span> Sub</pre>
</div>

<div> </div>

<div>Depending on your requirements this may or may not work for you. You may run into other conflicts and things may not work as you are expecting. A “real world” solution will establish some rules about considering the following guidelines.</div>

<div> </div>

<div><strong>Give yourself some buffer</strong>. If your requirements involve encoding information in the point number, try to define rules that give you some buffer; especially at the beginning and between point types. For example instead of using point numbers starting a ‘1’, give your self some buffer at the beginning and start point numbers at ‘1000’ or ‘10000’. </div>

<div> </div>

<div>If you have points that represent things like trees, think about how many trees are usually represented in a model, and give you a range of numbers for them. If a model usually contains somewhere about 100 and 200 trees define a range big enough for them, for example numbers 1000 to 1500.</div>

<div> </div>

<div><strong>Avoid providing an interface where users explicitly assign numbers</strong>. Even if you defined very strict rules on how points will be renumbered and did a lot of defensive programming to avoid conflicts, users will be confused if the point they are renumbering ends up with a different number than what they entered. Define the rules and program defensively, but abstract the process into operations where the user does not have to deal with the point numbers themselves.</div>

<div> </div>

<div><strong>Let Civil 3D manage the point numbers</strong>. Ultimately if you can avoid dealing with point numbers, the better. Civil 3D provides tools to do the work and most users will know how to use them. Let Civil 3D take care of the numbers and write your applications to complement the functionality instead of replacing it if you can.</div>

<div>
  <br /></div>

<p>As you can see, renumbering points is not a trivial task and you have to be very careful. Define your rules and give you some buffer. Try to abstract the task from your users or let Civil 3D do its thing. Of course, you can always play more with this part of the API, and you can download the complete source code from the <a href="https://bitbucket.org/IsaacRodriguez/civilizeddevelopment">Civilized Development repository</a>.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2012/05/21wojp-week-6-fun-renumbering-points.html</feedburner:origLink></entry>
    <entry>
        <title>Week 6  COGO Points Bulk Operations</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/un1xjLcneY8/week-6-cogo-points-bulk-operations.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2012/05/week-6-cogo-points-bulk-operations.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b0168eb97f04e970c</id>
        <published>2012-05-18T10:08:19-07:00</published>
        <updated>2012-05-18T10:08:19-07:00</updated>
        <summary>The COGO Point object in Civil 3D had some special requirements that influence its design and make it different from other Civil 3D (or AutoCAD) objects. Among its special requirements, there were two of great importance: performance and scalability. This does not mean that other Civil 3D objects have been...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2013" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Points" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>The COGO Point object in Civil 3D had some special requirements that influence its design and make it different from other Civil 3D (or AutoCAD) objects. Among its special requirements, there were two of great importance: performance and scalability. This does not mean that other Civil 3D objects have been implemented with complete disregard for performance and scalability, but COGO Points are different because a drawing may contain thousands if not millions of point.</p>  <p>You won’t find many drawings with thousands of Corridors, Alignments, or Surfaces. As a matter of fact, I assure you, you won’t find any. But you can easily find drawings containing thousands or more COGO Points. The design of other objects if applied to COGO Points will be very inefficient. It will be slow to process points, and it will consume a lot of memory. It will impact the performance, but worse yet, it will make the feature not scalable for industry needs.</p>  <p>In reality, without going to deep into the implementation details, the COGO Point ‘DBObject’ is a very simple object containing no data, other than its graphical representation for display purposes. All the data for the COGO Points in a drawing is stored in what we call internally the “points node”. An abstraction of this node is provided through the API in the form of a ‘CogoPointCollection’ object, which is exposed by the ‘CogoPoints’ property of the ‘CivilDocument’ object.</p>  <p>This design allows the ‘CogoPointCollection’ to expose an interface that makes editing COGO Point properties very efficiently when processing multiple ‘CogoPoint’ objects. Let’s take a look at a quick example.</p>  <p><strong>C#</strong></p>  <div id="codeSnippetWrapper">   <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">[CommandMethod(<span style="color: #006080">"CDS_OffsetPointElevations"</span>)]<br /><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CDS_OffsetPointElevations()<br />{<br />  PromptDoubleResult result = _editor.GetDouble(<br />    <span style="color: #006080">"\nEnter elevation offset: "</span>);<br />  <span style="color: #0000ff">if</span> (result.Status == PromptStatus.OK)<br />  {<br />    <span style="color: #0000ff">double</span> offset = result.Value;<br />    CogoPointCollection points = _civildoc.CogoPoints;<br />    points.SetElevationByOffset(points, offset);<br />  }<br />}</pre>

  <br /></div>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">&lt;CommandMethod(<span style="color: #006080">"CDS_OffsetPointElevations"</span>)&gt; _<br /><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Sub</span> CDS_OffsetPointElevations()<br />  <span style="color: #0000ff">Dim</span> result <span style="color: #0000ff">As</span> PromptDoubleResult = _editor.GetDouble(vbLf _ <br />    &amp; <span style="color: #006080">"Enter elevation offset: "</span>)<br />  <span style="color: #0000ff">If</span> result.Status = PromptStatus.OK <span style="color: #0000ff">Then</span><br />    <span style="color: #0000ff">Dim</span> offset <span style="color: #0000ff">As</span> <span style="color: #0000ff">Double</span> = result.Value<br />    <span style="color: #0000ff">Dim</span> points <span style="color: #0000ff">As</span> CogoPointCollection = _civildoc.CogoPoints<br />    points.SetElevationByOffset(points, offset)<br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br /><span style="color: #0000ff">End</span> Sub</pre>

  <br /></div>

<p>As you probably figured out, the command prompts the users of an offset elevation value, and then modifies the elevation property of all points in the drawing by that offset. You can see how easy it is to do this through the ‘bulk operation’ methods exposed by the ‘CogoPointCollection’ class.</p>

<p>If you dive into the <a href="http://docs.autodesk.com/CIV3D/2013/ENU/API_Reference_Guide/html/edaa16d0-2e48-5617-ccc0-e238b942e69d.htm">‘CogoPointcollection’ methods</a>, you will see that there are several “Set…” methods that allow setting properties of the ‘CogoPoint’ objects contained in the collection. These methods usually have the following overloads:</p>

<ul>
  <li><strong>ObjectId, Value:</strong> When the method takes an ‘ObjectId’ and a ‘Value’, it is setting the property for a single ‘CogoPoint’ object (the ‘CogoPoint’ object to which the ‘ObjectId’ refers). These methods work the same as if you were to open the ‘ObjectId’ for write and set the same property in the ‘CogoPoint’ object. </li>

  <li><strong>IEnumerable&lt;ObjectId&gt;, Value:</strong> A second overload will take an IEnumerable of ‘ObjectId’ and a value. In this case, the same value is being set for all the ‘CogoPoint’ objects represented by the specified object ids. </li>

  <li><strong>IEnumerable&lt;ObjectId&gt;, IEnumerable&lt;”Value”&gt;:</strong> This third overload allows to set the property for each of the specified ‘CogoPoint’ object and specify individual values for each one of them. </li>
</ul>

<p>There are two things to consider when you are using the last overload that takes ‘IEnumerables’ for ‘ObjectId’ and ‘Values’. If the number of items the ‘ObjectId’ enumerable &lt;x&gt; is larger than the number of items in the ‘Values’ enumerable &lt;y&gt;, only &lt;y&gt; number of points are updated. If the number of ‘Values’ &lt;y&gt; is larger than the number of points &lt;x&gt;, all the specified points are updated, but the remaining values are ignored.</p>

<p>Bulk operations for COGO Points are very powerful and efficient. When working with COGO Points, you want to find ways to make edits in bulk better than opening each of the individual objects. The interface exposed through the ‘CogoPointCollection’ class allows you to write efficient code for editing COGO Points and provides great flexibility on how the edits are performed.</p>

<p>As usual, you can download the source code from the <a href="https://bitbucket.org/IsaacRodriguez/civilizeddevelopment">Civilized Development repository</a> at bit bucket.</p>

<p>P.S: I realized that the build process for Colibra (the process that was packaging the code and sample) is not working and the generated ZIP file was empty. So I’ve been posting empty ZIP files to dropbox for a while and I haven’t heard any complaints. This means readers have either downloaded the source from Bit Bucket, synching the repository, or not downloading the source at all. In order to save me some time from now on, I will just post the source and related files to bit bucket. You can still download a ZIP file from the bit bucket interface.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2012/05/week-6-cogo-points-bulk-operations.html</feedburner:origLink></entry>
    <entry>
        <title>21WOJP  Week 5: COGO Point Basics</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/O_JhrrhSy-8/21wojp-week-5-cogo-point-basics.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2012/05/21wojp-week-5-cogo-point-basics.html" thr:count="3" thr:updated="2012-05-10T03:38:32-07:00" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b0167665b2cd9970b</id>
        <published>2012-05-09T10:07:08-07:00</published>
        <updated>2012-05-09T10:07:08-07:00</updated>
        <summary>Most of the API work done in Jay Peak was around providing a full COGO Point .NET API. COGO Points are an important piece in Civil 3D, and from an API perspective they present some challenges because of the way they are implemented in the application. During the following weeks,...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2013" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="Points" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Most of the API work done in Jay Peak was around providing a full COGO Point .NET API. COGO Points are an important piece in Civil 3D, and from an API perspective they present some challenges because of the  way they are implemented in the application. During the following weeks, we will take an in-depth look at the COGO Points .NET API, and I will explain the correct way to work with COGO Point objects.Today, we will take a look at some basic functionality like the different ways to create COGO Points and access their properties.</p>  <p><strong>Creating COGO Points</strong></p>  <p>There are several similar, yet different ways to create new COGO Points using the .NET API. You can create COGO Points one by one, or you can create several at once, which is more efficient when creating a large number of points.</p>  <p>The basics are the same. COGO Points are created through the ‘CogoPointCollection’ object exposed through the ‘’CogoPoints’ property in ‘CivilDocument’. The collection exposes several overloads of the ‘Add()’ method that creates new ‘CogoPoint’ objects and returns their id.</p>  <p>The following command demonstrates the different ways in which you can create COGO Points, as you can see, it will display information from the created objects, but we will look at that more in deep later on. For now, take a look at the implementation of the command.</p>  <p><strong>C#</strong></p>  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">[CommandMethod(<span style="color: #006080">"CDS_CreateRandomPoints"</span>)]<br /><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CDS_CreateRandomPoints()<br />{<br />  RandomCoordinateGenerator generator = <br />    <span style="color: #0000ff">new</span> RandomCoordinateGenerator();<br />  CogoPointCollection points = _civildoc.CogoPoints;<br /><br />  <span style="color: #008000">// From Point3d</span><br />  Point3d coordinate = generator.GetCoordinate();<br />  ObjectId pointId = points.Add(coordinate);<br />  write(<span style="color: #006080">"\nSingle Point from coordinate."</span>);<br />  display(pointId);<br /><br />  coordinate = generator.GetCoordinate();<br />  pointId = points.Add(coordinate, <span style="color: #006080">"Sample description."</span>);<br />  write(<span style="color: #006080">"\nSingle Point from coordinate and description."</span>);<br />  display(pointId);<br /><br />  coordinate = generator.GetCoordinate();<br />  pointId = points.Add(coordinate, <span style="color: #006080">"Sample description"</span>,  <br />    <span style="color: #0000ff">true</span>, <span style="color: #0000ff">false</span>);<br />  write(<span style="color: #006080">"\nSingle Point from coordinate with description, "</span><br />    + <span style="color: #006080">"using description key, and not matching parameters."</span>);<br />  display(pointId);<br /><br />  <span style="color: #008000">// From Point3dCollection</span><br />  Point3dCollection coordinates = generator.GetCoordinates(10);<br />  ObjectIdCollection pointIds = points.Add(coordinates);<br />  write(<span style="color: #006080">"\nPoints from coordinate collection."</span>);<br />  display(pointIds);<br /><br />  coordinates = generator.GetCoordinates(5);<br />  pointIds = points.Add(coordinates, <span style="color: #006080">"Group of 5"</span>);<br />  write(<span style="color: #006080">"\nPoints from coordinate collection with description."</span>);<br />  display(pointIds);<br /><br />  coordinates = generator.GetCoordinates(7);<br />  pointIds = points.Add(coordinates, <span style="color: #006080">"Group of 7"</span>, <span style="color: #0000ff">true</span>, <span style="color: #0000ff">true</span>);<br />  write(<span style="color: #006080">"\nPoints from coordinate collection with description,"</span><br />    + <span style="color: #006080">"using description key, and not matching parameters."</span>);<br />  display(pointIds);<br />}</pre>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">&lt;CommandMethod(<span style="color: #006080">"CDS_CreateRandomPoints"</span>)&gt; _<br /><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Sub</span> CDS_CreateRandomPoints()<br />  <span style="color: #0000ff">Dim</span> generator <span style="color: #0000ff">As</span> <span style="color: #0000ff">New</span> RandomCoordinateGenerator()<br />  <span style="color: #0000ff">Dim</span> points <span style="color: #0000ff">As</span> CogoPointCollection = _civildoc.CogoPoints<br /><br />  <span style="color: #008000">' From Point3d</span><br />  <span style="color: #0000ff">Dim</span> coordinate <span style="color: #0000ff">As</span> Point3d = generator.GetCoordinate()<br />  <span style="color: #0000ff">Dim</span> pointId <span style="color: #0000ff">As</span> ObjectId = points.Add(coordinate)<br />  write(vbLf &amp; <span style="color: #006080">"Single Point from coordinate."</span>)<br />  display(pointId)<br /><br />  coordinate = generator.GetCoordinate()<br />  pointId = points.Add(coordinate, <span style="color: #006080">"Sample description."</span>)<br />  write(vbLf &amp; <span style="color: #006080">"Single Point from coordinate and description."</span>)<br />  display(pointId)<br /><br />  coordinate = generator.GetCoordinate()<br />  pointId = points.Add(coordinate, <span style="color: #006080">"Sample description"</span>, <span style="color: #0000ff">True</span>, <span style="color: #0000ff">False</span>)<br />  write(vbLf &amp; <span style="color: #006080">"Single Point from coordinate with description, "</span> _<br />    &amp; <span style="color: #006080">"using description key, and not matching parameters."</span>)<br />  display(pointId)<br /><br />  <span style="color: #008000">' From Point3dCollection</span><br />  <span style="color: #0000ff">Dim</span> coordinates <span style="color: #0000ff">As</span> Point3dCollection = generator.GetCoordinates(10)<br />  <span style="color: #0000ff">Dim</span> pointIds <span style="color: #0000ff">As</span> ObjectIdCollection = points.Add(coordinates)<br />  write(vbLf &amp; <span style="color: #006080">"Points from coordinate collection."</span>)<br />  display(pointIds)<br /><br />  coordinates = generator.GetCoordinates(5)<br />  pointIds = points.Add(coordinates, <span style="color: #006080">"Group of 5"</span>)<br />  write(vbLf &amp; <span style="color: #006080">"Points from coordinate collection with description."</span>)<br />  display(pointIds)<br /><br />  coordinates = generator.GetCoordinates(7)<br />  pointIds = points.Add(coordinates, <span style="color: #006080">"Group of 7"</span>, <span style="color: #0000ff">True</span>, <span style="color: #0000ff">True</span>)<br />  write(vbLf &amp; <span style="color: #006080">"Points from coordinate collection with description,"</span> _<br />    &amp; <span style="color: #006080">"using description key, and not matching parameters."</span>)<br />  display(pointIds)<br /><span style="color: #0000ff">End</span> Sub</pre>

  <br /></div>

<p>The ‘Add()’ method overloads are categorized in two basic ways: creating a single COGO Point object from a ‘Point3d’ or creating multiple COGO Point objects from a ‘Point3dCollection’. Variations of these two categories allows you specify other parameters for the creation, like the description used for the COGO Points. We will not go too deep into the different parameters, since their explanation requires understanding other concepts that we will look at in a later post.</p>

<p><strong>Accessing COGO Point Properties</strong></p>

<p>Like other Civil 3D objects, COGO Points are assigned an ‘ObjectId’ when created. This allows you to open the object and access its properties. The ‘display()’ methods in the example below shows how to do this.</p>

<p><strong>C#</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> display(ObjectId pointId)<br />{<br />  <span style="color: #0000ff">using</span> (Transaction tr = startTransaction())<br />  {<br />    CogoPoint point = pointId.GetObject(OpenMode.ForRead) <br />      <span style="color: #0000ff">as</span> CogoPoint;<br />    displayPointInfo(point);<br />  }<br />}<br /><br /><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> display(ObjectIdCollection pointIds)<br />{<br />  <span style="color: #0000ff">using</span> (Transaction tr = startTransaction())<br />  {<br />    <span style="color: #0000ff">foreach</span> (ObjectId pointId <span style="color: #0000ff">in</span> pointIds)<br />    {<br />      CogoPoint point = pointId.GetObject(OpenMode.ForRead)<br />        <span style="color: #0000ff">as</span> CogoPoint;<br />      displayPointInfo(point);<br />    }<br />  }<br />}<br /><br /><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> displayPointInfo(CogoPoint point)<br />{<br />  write(<span style="color: #006080">"\nPoint Number: "</span> + point.PointNumber.ToString());<br />  write(<span style="color: #006080">"\n- Location: "</span> + point.Location.ToString());<br />  write(<span style="color: #006080">"\n- - Northing: "</span> + point.Northing.ToString());<br />  write(<span style="color: #006080">"\n- - Easting: "</span> + point.Easting.ToString());<br />  write(<span style="color: #006080">"\n- - Elevation: "</span> + point.Elevation.ToString());<br />  write(<span style="color: #006080">"\n- Description: "</span> + point.FullDescription);<br />  write(<span style="color: #006080">"\n- Raw Description: "</span> + point.RawDescription);<br />}</pre>

  <br /></div>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">Private</span> <span style="color: #0000ff">Sub</span> display(pointId <span style="color: #0000ff">As</span> ObjectId)<br />  Using tr <span style="color: #0000ff">As</span> Transaction = startTransaction()<br />    <span style="color: #0000ff">Dim</span> point <span style="color: #0000ff">As</span> CogoPoint =<br />      <span style="color: #0000ff">TryCast</span>(pointId.GetObject(OpenMode.ForRead), CogoPoint)<br />    displayPointInfo(point)<br />  <span style="color: #0000ff">End</span> Using<br /><span style="color: #0000ff">End</span> <span style="color: #0000ff">Sub</span><br /><br /><span style="color: #0000ff">Private</span> <span style="color: #0000ff">Sub</span> display(pointIds <span style="color: #0000ff">As</span> ObjectIdCollection)<br />  Using tr <span style="color: #0000ff">As</span> Transaction = startTransaction()<br />    <span style="color: #0000ff">For</span> <span style="color: #0000ff">Each</span> pointId <span style="color: #0000ff">As</span> ObjectId <span style="color: #0000ff">In</span> pointIds<br />      <span style="color: #0000ff">Dim</span> point <span style="color: #0000ff">As</span> CogoPoint =<br />        <span style="color: #0000ff">TryCast</span>(pointId.GetObject(OpenMode.ForRead), CogoPoint)<br />      displayPointInfo(point)<br />    <span style="color: #0000ff">Next</span><br />  <span style="color: #0000ff">End</span> Using<br /><span style="color: #0000ff">End</span> <span style="color: #0000ff">Sub</span><br /><br /><span style="color: #0000ff">Private</span> <span style="color: #0000ff">Sub</span> displayPointInfo(point <span style="color: #0000ff">As</span> CogoPoint)<br />  write(vbLf &amp; <span style="color: #006080">"Point Number: "</span> &amp; point.PointNumber.ToString())<br />  write(vbLf &amp; <span style="color: #006080">"- Location: "</span> &amp; point.Location.ToString())<br />  write(vbLf &amp; <span style="color: #006080">"- - Northing: "</span> &amp; point.Northing.ToString())<br />  write(vbLf &amp; <span style="color: #006080">"- - Easting: "</span> &amp; point.Easting.ToString())<br />  write(vbLf &amp; <span style="color: #006080">"- - Elevation: "</span> &amp; point.Elevation.ToString())<br />  write(vbLf &amp; <span style="color: #006080">"- Description: "</span> &amp; _<br />    Convert.ToString(point.FullDescription))<br />  write(vbLf &amp; <span style="color: #006080">"- Raw Description: "</span> &amp; _<br />    Convert.ToString(point.RawDescription))<br /><span style="color: #0000ff">End</span> Sub</pre>

  <br /></div>

<p>The ‘display()’ methods open the ‘CogoPoint’ objects and pass them to ‘displayPointInfo()’, which reads the properties and displays them. In this sample, we are just reading properties from the ‘CogoPoint’ object, so this way of accessing them and getting their properties should be fine. However, COGO Points are implemented different than other Civil 3D objects for performance and scalability issues. In a later post, we will talk about the actual implementation of the COGO Point object and how to work more efficiently when we need to update/write to it.</p>

<p>The ‘CDS_CreateRandomPoints’ command uses a ‘RandomCoordinateGenerator’ object to randomly create new locations/coordinates for the points. The full <a href="https://bitbucket.org/IsaacRodriguez/civilizeddevelopment">source code</a> contains the implementation of this class. Alternatively, you can download the <a href="http://dl.dropbox.com/u/22270286/CogoPoint%20Basics.zip">source files</a> and add them to your own project.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2012/05/21wojp-week-5-cogo-point-basics.html</feedburner:origLink></entry>
    <entry>
        <title>21WOJP  Week 4: Document Management</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/aGlMhRryrHQ/21wojp-week-4-document-management.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2012/05/21wojp-week-4-document-management.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b0168eb089cb2970c</id>
        <published>2012-05-02T10:15:06-07:00</published>
        <updated>2012-05-02T10:15:06-07:00</updated>
        <summary>Last year, I wrote a post on how to implement a DocumentManager for Civil 3D documents. The motivation was to overcome the limitations in the Civil 3D API that made very difficult to work with multiple documents at once. Many of you have pointed out how difficult is to keep...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2013" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="General" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Last year, I wrote a post on <a href="http://civilizeddevelopment.typepad.com/civilized-development/2011/03/implementing-a-documentmanager.html">how to implement a DocumentManager</a> for Civil 3D documents. The motivation was to overcome the limitations in the Civil 3D API that made very difficult to work with multiple documents at once. Many of you have pointed out how difficult is to keep track of the different document and database objects even when the code is well abstracted into an owned 'Document' and 'DocumentManager' classes.</p>  <p>In Jay Peak, we have introduced a new static method 'GetCivilDocument() in the 'CivilDocument' class, which allows you to instantiate a 'CivilDocument' object from an AutoCAD 'Database' object. This new method highly simplifies the process because it allows you to implement all document management through the AutoCAD API; therefore, your 'DocumentManager' abstraction should only depend on the AutoCAD API and its document management functionality. From an AutoCAD 'Document' object, you can access the 'Database' object, which in turn allows you to instantiate a 'CivilDocument', and from these objects you can also access their COM instances.</p>  <p>In this post, I will go through the process of porting the 'Document' and 'DocumentManager' classes in 'Colibra' to make use of the new functionality and remove as many dependencies as possible.</p>  <p><b>Porting ‘Colibra.Document'</b><b>     <br /></b></p>  <p>Looking at last year's implementation, the first thing we notices is that the 'Colibra.Document' class provides an internal constructor that takes both an AutoCAD 'Document' object and an instance of 'CivilDocument'.</p>  <p><strong>C#</strong></p>  <div id="codeSnippetWrapper">   <div id="codeSnippetWrapper">     <div id="codeSnippetWrapper">       <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">internal</span> Document(acadappsvcs.Document acadDoc, <br />  CivilDocument civilDoc)<br />{<br />  m_ThisAcadDocument = acadDoc;<br />  m_ThisCivilDocument = civilDoc;<br />  m_ActiveTransaction = <span style="color: #0000ff">null</span>;<br />}</pre>
    </div>
  </div>
</div>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">Friend</span> <span style="color: #0000ff">Sub</span> <span style="color: #0000ff">New</span>(acadDoc <span style="color: #0000ff">As</span> acadappsvcs.Document, _<br />  civilDoc <span style="color: #0000ff">As</span> CivilDocument)<br />  <br />  m_ThisAcadDocument = acadDoc<br />  m_ThisCivilDocument = civilDoc<br />  m_ActiveTransaction = <span style="color: #0000ff">Nothing</span><br /><span style="color: #0000ff">End</span> Sub</pre>

  <br /></div>

<p>This is no longer necessary because we can access the ‘Database’ object from the AutoCAD ‘Document’, which will allow us to instantiate a ‘CivilDocument’. Therefore, our first change will be to remove the ‘CivilDocument’ parameter from the internal constructor and initialize the member variable using the ‘Database’ object.</p>





<p><strong>C#</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">internal</span> Document(acadappsvcs.Document acadDoc)<br />{<br />  m_ThisAcadDocument = acadDoc;<br />  m_ThisCivilDocument = CivilDocument.GetCivilDocument(<br />    m_ThisAcadDocument.Database);<br />  m_ActiveTransaction = <span style="color: #0000ff">null</span>;<br />}</pre>

  <br /></div>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">Friend</span> <span style="color: #0000ff">Sub</span> <span style="color: #0000ff">New</span>(acadDoc <span style="color: #0000ff">As</span> acadappsvcs.Document)<br />  m_ThisAcadDocument = acadDoc<br />  m_ThisCivilDocument = CivilDocument.GetCivilDocument(<br />    m_ThisAcadDocument.Database)<br />  m_ActiveTransaction = <span style="color: #0000ff">Nothing</span><br /><span style="color: #0000ff">End</span> Sub</pre>

  <br /></div>

<p>At this point, our project will not compile because we have to update every location where we are instantiating a ‘Colibra.Document’ object to remove the ‘CivilDocument’ parameter. Thankfully, our code is well abstracted; therefore, the only class we need to update is the ‘Colibra.DocumentManager’ class.</p>

<p><strong>Porting ‘Colibra.DocumentManager’</strong></p>

<p>‘Colibra.DocumentManager’ had the responsibility to keep in sync the AutoCAD ‘Document’ object with its corresponding ‘CivilDocument’ object. This is no longer necessary, so we can start updating and refactoring the implementation.</p>

<p>There are two public interfaces that instantiate a ‘Colibra.Document’ in ‘Colibra.DocumentManager’: the static property ‘ActiveDocument’ and the static method ‘OpenDocument’. The implementation of both of these public interfaces make use of a private method ‘createNewAndActivateFromAutoCADDocument()’, which was the place we insured both objects were kept in sync.</p>

<p><strong>C#</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> Document ActiveDocument<br />{<br />  <span style="color: #0000ff">get</span><br />  {<br />    <span style="color: #0000ff">if</span> (m_ActiveDocument == null)<br />    {<br />      createNewAndActivateFromAutoCADDocument(<br />        acadappsvcs.Application<br />        .DocumentManager.MdiActiveDocument);<br />    }<br />    <span style="color: #0000ff">return</span> m_ActiveDocument;<br />  }<br />}<br /><br /><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> Document OpenDocument(<span style="color: #0000ff">string</span> fileName)<br />{<br />  acadappsvcs.Document acadDoc = acadappsvcs.Application<br />    .DocumentManager.Open(fileName);<br />  createNewAndActivateFromAutoCADDocument(acadDoc);<br />  <span style="color: #0000ff">return</span> m_ActiveDocument;<br />}<br /><br /><span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> void createNewAndActivateFromAutoCADDocument(<br />   acadappsvcs.Document acadDoc)<br />{<br />  CivilDocument civilDoc = getCivilDocumentAndActivate(acadDoc);<br />  m_ActiveDocument = <span style="color: #0000ff">new</span> Document(acadDoc, civilDoc);<br />}<br /><br /><span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> CivilDocument getCivilDocumentAndActivate(<br />  acadappsvcs.Document acadDoc)<br />{<br />  acadappsvcs.Application.DocumentManager.MdiActiveDocument <br />    = acadDoc;<br />  <span style="color: #0000ff">return</span> CivilApplication.ActiveDocument;<br />}</pre>

  <br /></div>

<p><strong>VB.NET</strong></p>

<div id="codeSnippetWrapper">
  <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Shared</span> <span style="color: #0000ff">ReadOnly</span> <span style="color: #0000ff">Property</span> ActiveDocument() <span style="color: #0000ff">As</span> Document<br />  <span style="color: #0000ff">Get</span><br />    <span style="color: #0000ff">If</span> m_ActiveDocument <span style="color: #0000ff">Is</span> <span style="color: #0000ff">Nothing</span> <span style="color: #0000ff">Then</span><br />      createNewAndActivateFromAutoCADDocument(<br />        acadappsvcs.Application. _<br />        DocumentManager.MdiActiveDocument)<br />    <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />    <span style="color: #0000ff">Return</span> m_ActiveDocument<br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">Get</span><br /><span style="color: #0000ff">End</span> <span style="color: #0000ff">Property</span><br /><br /><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Shared</span> <span style="color: #0000ff">Function</span> OpenDocument(fileName <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Document<br />  <span style="color: #0000ff">Dim</span> manager <span style="color: #0000ff">As</span> DocumentCollection =<br />    acadappsvcs.Application.DocumentManager<br />  <span style="color: #0000ff">Dim</span> acadDoc <span style="color: #0000ff">As</span> acadappsvcs.Document = manager.Open(fileName)<br />  createNewAndActivateFromAutoCADDocument(acadDoc)<br />  <span style="color: #0000ff">Return</span> m_ActiveDocument<br /><span style="color: #0000ff">End</span> <span style="color: #0000ff">Function</span><br /><br /><span style="color: #0000ff">Private</span> <span style="color: #0000ff">Shared</span> <span style="color: #0000ff">Sub</span> createNewAndActivateFromAutoCADDocument(<br />    acadDoc <span style="color: #0000ff">As</span> acadappsvcs.Document)<br />  <span style="color: #0000ff">Dim</span> civilDoc <span style="color: #0000ff">As</span> CivilDocument = getCivilDocumentAndActivate(acadDoc)<br />  m_ActiveDocument = <span style="color: #0000ff">New</span> Document(acadDoc, civilDoc)<br /><span style="color: #0000ff">End</span> <span style="color: #0000ff">Sub</span><br /><br /><span style="color: #0000ff">Private</span> <span style="color: #0000ff">Shared</span> <span style="color: #0000ff">Function</span> getCivilDocumentAndActivate(<br />    acadDoc <span style="color: #0000ff">As</span> acadappsvcs.Document) <span style="color: #0000ff">As</span> CivilDocument<br />  acadappsvcs.Application.DocumentManager.MdiActiveDocument = acadDoc<br />  <span style="color: #0000ff">Return</span> CivilApplication.ActiveDocument<br /><span style="color: #0000ff">End</span> Function</pre>

  <br /></div>

<p>
  <div>With the new API, we do not need to activate a document before accessing the ‘CivilDocument’ instance, so we can remove the implementations of ‘createNewAndActivateFromAutoCADDocument()’ and ‘getCivilDocumentAndActivate()’. To remove these methods, we need to update the implementation of the ‘ActiveDocument’ property and the ‘OpenDocument()’ method, then we can remove them.</div>

  <div> </div>

  <div><strong>C#</strong></div>

  <div id="codeSnippetWrapper">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> Document ActiveDocument<br />{<br />  <span style="color: #0000ff">get</span><br />  {<br />    <span style="color: #0000ff">if</span> (m_ActiveDocument == null)<br />    {<br />      m_ActiveDocument = <span style="color: #0000ff">new</span> Document(acadappsvcs.Application<br />        .DocumentManager.MdiActiveDocument);          <br />    }<br />    <span style="color: #0000ff">return</span> m_ActiveDocument;<br />  }<br />}<br /><br /><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> Document OpenDocument(<span style="color: #0000ff">string</span> fileName)<br />{<br />  acadappsvcs.Document acadDoc = acadappsvcs.Application<br />    .DocumentManager.Open(fileName);<br />  <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> Document(acadDoc);<br />}</pre>
  </div>

  <div> </div>

  <div><strong>VB.NET</strong></div>

  <div id="codeSnippetWrapper">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Shared</span> <span style="color: #0000ff">ReadOnly</span> <span style="color: #0000ff">Property</span> ActiveDocument() <span style="color: #0000ff">As</span> Document<br />  <span style="color: #0000ff">Get</span><br />    <span style="color: #0000ff">If</span> m_ActiveDocument <span style="color: #0000ff">Is</span> <span style="color: #0000ff">Nothing</span> <span style="color: #0000ff">Then</span><br />      m_ActiveDocument = <span style="color: #0000ff">New</span> Document(acadappsvcs.Application. _<br />        DocumentManager.MdiActiveDocument)<br />    <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span><br />    <span style="color: #0000ff">Return</span> m_ActiveDocument<br />  <span style="color: #0000ff">End</span> <span style="color: #0000ff">Get</span><br /><span style="color: #0000ff">End</span> <span style="color: #0000ff">Property</span><br /><br /><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Shared</span> <span style="color: #0000ff">Function</span> OpenDocument(fileName <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>) <span style="color: #0000ff">As</span> Document<br />  <span style="color: #0000ff">Dim</span> manager <span style="color: #0000ff">As</span> DocumentCollection =<br />    acadappsvcs.Application.DocumentManager<br />  <span style="color: #0000ff">Dim</span> acadDoc <span style="color: #0000ff">As</span> acadappsvcs.Document = manager.Open(fileName)<br />  <span style="color: #0000ff">Return</span> <span style="color: #0000ff">New</span> Document(acadDoc)<br /><span style="color: #0000ff">End</span> Function</pre>

    <br /></div>

  <div>Running all the unit tests, we can see that everything passes, so our port was successful. The final implementation of ‘Colibra.DocumentManager’ is much simpler, and the design fits better to extend its interface and provide additional functionality our application may need. The fact that last year we provided the ‘Colibra.Document’ and ‘Colibra.DocumentManager’ abstractions has helped us to make the changes because they were well centralized and our client code was not directly dependent on the AutoCAD and Civil 3D APIs.</div>

  <div> </div>

  <div>You can download the full source for Colibra from this <a href="http://dl.dropbox.com/u/22270286/Colibra_2_0_2_0.zip">link</a>, or download the source repository from <a href="https://bitbucket.org/IsaacRodriguez/civilizeddevelopment">BitBucket</a>. BitBucket will also allow you to download the entire repository as a ZIP file.</div></p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2012/05/21wojp-week-4-document-management.html</feedburner:origLink></entry>
    <entry>
        <title>21WOJP  Week 3 - Getting Help</title>
        <link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CivilizedDevelopment/~3/ylvRA8Aahnc/21wojp-week-3-getting-help.html" />
        <link rel="replies" type="text/html" href="http://civilizeddevelopment.typepad.com/civilized-development/2012/04/21wojp-week-3-getting-help.html" thr:count="0" />
        <id>tag:typepad.com,2003:post-6a0147e1be0df6970b0168ea9a0ae9970c</id>
        <published>2012-04-23T09:56:00-07:00</published>
        <updated>2012-05-05T08:52:58-07:00</updated>
        <summary>Last year, we made the decision to go on-line with the API help and documentation. Despite the initial negative reaction from some of our customers, I still think it was the right decision, and we went the same route this year. Missing documentation is bad, but inaccurate, incomplete documentation can...</summary>
        <author>
            <name>Isaac R</name>
        </author>
        <category scheme="http://www.sixapart.com/ns/types#category" term="C3D2013" />
        <category scheme="http://www.sixapart.com/ns/types#category" term="General" />
        
        
<content type="xhtml" xml:lang="en-US" xml:base="http://civilizeddevelopment.typepad.com/civilized-development/">
<div xmlns="http://www.w3.org/1999/xhtml"><p>Last year, we made the decision to go on-line with the API help and documentation. Despite the initial negative reaction from some of our customers, I still think it was the right decision, and we went the same route this year.</p>  <p>Missing documentation is bad, but inaccurate, incomplete documentation can be even worse. Having the documentation on-line allows us to update it at any point in time and improve it over time. Last year, we were able to add additional articles to the Developer's Guide after the product shipped. We would not have been able to do it if the documentation resided locally on your machine. And in the future, we are planning to have more releases/improvements for the documentation as new articles and samples are written.</p>  <p>But this series is about Jay Peak and what we have done in the new release of Civil 3D, and when it comes to documentation, we have done a lot. Some results will show immediately, others will appear very soon, and like I said, we will deliver more improvements in shorter cycles. Let's take a look at what's new and how you can get some help.</p>  <p><b>Where's the Help?</b><b>      <br /></b></p>  <p>You can access the API documentation from the <a href="http://wikihelp.autodesk.com/AutoCAD_Civil_3D/enu/2013">AutoCAD Civil 3D 2013 WikiHelp site</a>. This site provides access to all the product documentation as well as the API. You can find articles, tutorials, videos, and links to other resources, and it is the first place to find information about Civil 3D in general. You should add that location to your bookmarks and keep it handy.</p>  <p><b>What's New with the Developer's Guide</b><b>      <br /></b></p>  <p>This year, we were able to add several articles to the <a href="http://wikihelp.autodesk.com/AutoCAD_Civil_3D/enu/2013/Help/API_Developer's_Guide">Developer's Guide</a> that cover, not only the functionality in the 2013 release, but also the functionality made available in 2012 for which we didn't have any new content. Because of our ability to update the documentation at any point in time, we added the applicable articles to the <a href="http://wikihelp.autodesk.com/AutoCAD_Civil_3D/enu/2012/Help/API_Developer's_Guide">2012 Developer's Guide</a> to keep things up-to-date.</p>  <p>The new version of the <a href="http://wikihelp.autodesk.com/AutoCAD_Civil_3D/enu/2013/Help/API_Developer's_Guide">Developer's Guide</a> includes articles for the Surfaces .NET API introduced last year, as well as articles for the COGO Points .NET API, which is new to the 2013 release. These articles go deep into the functionality of the API and are a great resource to understand the design and implementation of the features.</p>  <p><b>Introducing the New Reference Guide</b><b>      <br /></b></p>  <p>One of the biggest efforts this year regarding the API documentation has been the brand new <a href="http://docs.autodesk.com/CIV3D/2013/ENU/API_Reference_Guide/index.html">Reference Guide</a>. We spent quite some time researching tools and processes that would allow us to provide a better reference for all the available APIs and make them more valuable to all of our customers. Some improvements you will notice right-away; others will appear over time. This is an ongoing effort, and we are committed to it.</p>  <p>The first change you will notice is the new look and feel of the Reference Guide. We did some research of documentation tools that generate HTML documentation ready to be posted on-line and that can be integrated with our build process. The result a more modern, up-to-date Reference Guide generated every time we build Civil 3D. This allow us to release updates at any time including the latest and greatest information. We can fix any problems we find, and we can make changes according to the feedback we receive (more on that below).</p>  <p>One of the most requested improvements to our documentation is to provide more and better examples. You speak, we listen. The new Reference Guide allows us to embed sample code for each of the classes and members we document. You will notice that some of the new features are already providing small snippets of code that demonstrate their use. Again, we can update this over time, and we will be providing more and more code samples.</p>  <p><a href="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ea9a0abf970c-pi"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Embedded Samples" border="0" alt="Embedded Samples" src="http://civilizeddevelopment.typepad.com/.a/6a0147e1be0df6970b0168ea9a0ad6970c-pi" width="465" height="334" /></a></p>  <p>We created a new documentation review process to insure the quality of the documentation is the highest. You will see that classes, methods, and properties are better documented, and it is likely they will get even better in the near future. Of course, good documentation is kind of subjective, so we will need your help and feedback with that, which leads me to the next improvement.</p>  <p>Feedback links in the Reference Guide have been broken for quite some time. Not any more. Not only do they work, but submitted feedback does not go into a bucket that no one is monitoring anymore. When you submit your feedback it goes directly to me (and other members of the API engineering team). That's right, you submit your feedback, I get an e-mail. I have total confidence in the community to provide us with comments and suggestions on how to improve things even more, and find problems with the documentation where things are not correctly stated or do not work as described. I am also sure all of you will be very respectful to the engineering team when submitting your feedback and that I will not need to ignore/delete your e-mails.</p>  <p>How about getting help right in Visual Studio 2010? Well, you got it. During the process that generates the Reference Guide, an XML file is created that has all the information to point Visual Studio in the right direction. You can download this <a href="http://dl.dropbox.com/u/22270286/AeccDbMgd.zip">ZIP file</a>, extract the XML file into the AutoCAD Civil 3D 2013 installation folder (usually, "C:\Program Files\Autodesk\AutoCAD Civil 3D 2013"), and restart Visual Studio, if needed, and you will get help information for each of the API classes, methods, and properties right in your Visual Studio tool-tips as you type the code. Isn't that a dream come true?</p>  <p><b>What Else is Coming Up?</b><b>      <br /></b></p>  <p>I recognize that for some of you local documentation is important. We are in the process of making the documentation available for download. We are looking at different alternatives because we want to have the same flexibility to update the downloads as we do with the on-line documentation. In the near future, I will update this post to provide links to the hosted files, so you can download, not only the Developer's Guide and Reference Guide, but also all the samples (as working code) included and embedded in the Reference Guide.</p>  <p>As you can see, we did a lot of work to bring you as much help as possible. There is still room for improvements, but we are at a point where changes can be easily propagated, which will allow us to provide a better service in the future. I think we are moving in the right direction, and I hope you participate in the process by telling us what more can we do to help you.</p>  <p><strong>Update: Documentation Available for Download</strong></p>  <p>As promised, we have made the new documentation available for download. You can access it now, and please report any problems with the links below.</p>  <p><a href="http://images.autodesk.com/adsk/files/APIDocs.zip">Reference Guide</a>. The ZIP file contains the entire Reference Guide in HTML format. You can extract the files and create a shortcut to index.html for quick access.</p>  <p><a href="http://images.autodesk.com/adsk/files/AutoCAD_Civil_3D_API_Developer_s_Guide.pdf">Developer's Guide</a>. We have also provided a PDF with all the articles in the Developer’s Guide. We’ve found some formatting issues with certain images caused by the new documentation system in use by the User Experience group. They are investigating the problems, so please have a little patience. Still, the Developer’s Guide is full of great information, and this PDF should allow you to bring it with you everywhere.</p>  <p><a href="http://images.autodesk.com/adsk/files/rgsamples.zip">Reference Guide Samples</a>. All the Reference Guide samples are also available for download. This download contains a Visual Studio 2010 solution and projects with working code written in C# and VB.NET. As more samples become available, we will update this file, so you can download it and play with it.</p>  <p><a href="http://images.autodesk.com/adsk/files/aeccdbmgd.zip">Visual Studio Help Index</a>. This download is a great resource. Extract and copy the included file into your Civil 3D installation directory, and Visual Studio will show you documentation information as tool-tips right from the Reference Guide.</p></div>
</content>



    <feedburner:origLink>http://civilizeddevelopment.typepad.com/civilized-development/2012/04/21wojp-week-3-getting-help.html</feedburner:origLink></entry>
 
</feed><!-- ph=1 -->

