Thursday, July 15, 2010

Tech Mashup Idea: Live Street View for Google Maps

Cell phone cameras are getting much more impressive.  I just saw an 8 megapixel HD camera on an Android  phone.  Neat.  Also about time.  Android also has lots of great apps too (I really need to dig into Java programming a bit more).  After all, it's free to develop apps (eclipse.org, android.com, etc.) for it.  A friend (@alanlupsha) and I were swapping app ideas when it finally hit me: live street view feeds.

Given that phones have:
  • high quality cameras to capture photos and video
  • the ability to record a lat/long position, and a bearing & angle (via compass app/tilt/acceleratometers)
  • the ability to send data and communicate with other devices/computers
then this app can:
  • automatically geotag photos with a lat/long, direction, and angle OR
    automatically geotag frames of a video with locations along a recorded along a path (also see RoboGEO software)
  • upload geotagged media to a server when you return to your home wifi connection, or any other wifi hotspot (@alanlupsha)
  • server geocodes the images (with minimal effort now) and updates an internet mapping application view that can be shared individually as a single view (see Google's Street View @ the 2010 Olympic ski runs)

Monday, July 12, 2010

Browser Spellchecking: Text areas and text boxes


I love Mozilla's dictionary extension/add-on, though I noticed that it only works on text areas (blog entries, facebook comment boxes, etc.) as opposed to other one-line text boxes (blog titles, "Enter your name" type fields).  It turns out that this is a setting that can be changed so all text input boxes can be checked for spelling.  Also, it's not difficult to change either:

Using Mozilla:
  • type about:config into the URL address bar and hit Enter
  • take note of the resulting message, warning users to be careful with any changes and click the, "I'll be careful, I promise!" button to bring up a list of all of the preferences available in the browser
  • type layout.spellcheckDefault into the filter and double click on the matching result to change the setting from 1 to 2
    • 0 = Disable Spellchecker
    • 1 = Enable Spellchecker for multi-line controls (default)
    • 2 = Enable Spellchecker for multi- and single-line controls
  • Click OK to save the parameter
That's it!  Change it back to 1 if you don't like it, though I find it to be pretty useful.

    Thursday, May 27, 2010

    Formatting Spreadsheet Cells with Unit of Measure

    I'm working with data imported from a GPS unit. The Altitude field is reported by a value with the unit of measure tacked on the end (below).



    The extra characters after the numeric value need to be removed if this value is going to be used in a database or a spreadsheet.  As of now it's being stored as a text value and is not as useful for calculations, summarizations, or sorting.

    The general idea is to use only a certain amount of text from the left side of the Altitude values, however there are various lengths of numbers. "11" and "-4" are both composed of two characters, but "2" is made up of one character.

    The best course of action is to remove those last three characters from each value so it can be treated as an integer (or other numeric value).  The best way to do this is to combine two simple and powerful functions into a spreadsheet formula.

    Function SyntaxDescription
    Length =LEN(text) Returns the length of a string including spaces. Text is the text (or cell) whose length is to be determined.
    Left =LEFT(text, number) Returns the first character or characters in a text string. Text is the text (or cell) where the initial partial words are to be determined. Number (optional) is the number of characters for the start text. If this parameter is not defined, one character is returned.


    Length example:
    The length function returns the number of characters that are present in a cell





    Now that we know how many characters are found in each individual record, we can create a formula that will pull just the specific numbers we want using the Left function.

    Combining with the Left function:
    The following formulas return only a certain number of the Left most characters from the Altitude field.  That number is calculated by subtracting 3 (a single space and "ft") from the total length of the Altitude field.





    Sometimes Google Docs treats this text field as a number already, so the formula doesn't need to include the -3 (i.e. simply testing the =LEN(C2) formula returns 2 instead of 5).




    The Right function is very similar to the Left function.  The Mid function, on the other hand, is used to report strings that do not begin on the ends of a cell, but rather when information begins closer to the center or more than one character away from the left most position. Check out the "Decimal Degrees to Degrees, Minutes, Seconds (DD to DMS):" section of my post on Angular Unit Conversion for an example.

    Wednesday, April 28, 2010

    Install Non-Packaged 3rd Party GIS Plugins

    Many third party GIS plugins have been neatly packaged into .dll files or batch files (ET GeoWizards, arcscripts.esri.com/resources.arcgis.com, etc.) that can be installed or imported into ones software interface in one step.  This easy method is not always available.  Below is an example of how to install a non-packaged plugin.  For further explanation on any of these steps, refer to a previous article on GIS Desktop Customization.

    I'll use my Attribution Assistant in the following example - Download the installation package (12 kb)

    What's included:
    • _Attribution_Icon.bmp is a graphic to use as the icon that will be used to launch the tool from the ArcMap interface
    • frmAttribution v2.0.frm is the form that will be imported into ArcMap.  The source code is stored in this file, and can be viewed when opened by a text editor.  Do not change any of these settings via text editor.
    • frmAttribution v2.0.frx a VB binary file that accompanies the .frm file that holds graphics and other information that will be used by the application
    • Installation instructions.txt is a "Readme" text file with information about the plugin

    Install:
    • Open ArcMap
    • Open the Visual Basic Editor from Tools menu under Tools :: Macros :: Visual Basic Editor
    • Locate the Project Explorer (see below).  If you want the tool to be available every time you open ArcMap, you'll import the plugin under the Normal.mxt branch.  Otherwise, installing the application under the Project branch in the Project Explorer will only allow access to the tool when working under a specific ArcMap project (a saved .mxd file).
    Undocked Visual Basic Project Explorer
    • Right click on the Normal branch and choose Import File so the plugin will be available every time ArcMap is opened.  Navigate to where the install package was unzipped, choose frmAttribution v2.0.frm and click Open.  Expand Normal and Forms to view the new form (see below), otherwise close the Visual Basic Editor.
     frmAttribution successfully imported
    • Back in ArcMap open the Customize dialog via Tools :: Customize
    • Navigate to the Commands tab
    • Ensure that the Save in: setting is set to Normal.mxt to ensure that the tool will be available every time ArcMap is opened
    • Scroll to the bottom of the Categories menu and select [ UI Controls ]
    • Click the New UIControl button, choose UIButton Control
    • Slow double click on the new control probably named Normal.UIButtonControl1 in the Commands list and rename it "Attribution_Launch."  When you press enter it will automatically rename itself "Normal.Attribution_Launch"
    •  Drag the new control onto the ArcMap interface
    •  Change the button face icon: With the Customize dialog still opened, right click on the icon that was just dropped onto the ArcMap interface and under the Change Button Image sub-menu, choose Browse
    • Navigate to the directory where the installation package was unzipped, choose _Attribution_Icon.bmp and click Open
    •  With the Customize dialog still open, right click on the new button on the ArcMap interface one more time and choose View Source.  The Visual Basic Editor will open, and will automatically open the ThisDocument code under Normal.mxt, with some code written for you (don't worry if you don't completely understand this part, just follow the directions to get through it)
    • Copy and following line and paste it into the Attribution_Launch_Click subroutine:
      Normal.frmAttribution.Show (vbModeless)
      It should look like the following:
    Private Sub Attribution_Launch_Click() 
        Normal.frmAttribution.Show (vbModeless)
    End Sub

    • Close the Visual Basic Editor when finished and you're good to go!  Click on your new button to launch the newly imported ArcMap plugin!

    Friday, April 23, 2010

    Attribution Assistant: Toolset/Plugin for ArcMap 9.x

    Attribution Assistant icon

    Attribution Assistant interface



    This (free) application is a plugin for ArcMap 9.x that allows a user to rapidly attribute GIS data.  Simply launch the tool from a button on the ArcMap interface to begin (installation instructions below).  Use the two menus to choose an available layer and a field to attribute.  Next, type a value in the text box, select some features, and press the Calculate button to quickly apply the attribution.  It's as simple as that.

    Features:
    Use the Add and Remove buttons to manage up to 16 attribution values.

    Use the check boxes to "disable" a specific field or restrict access to altering the current properties - this prevents the manipulation of information.  The topmost check box enables or disables all other check boxes at once (see graphic below).  Click the button in the top left corner to expand a few extra features (see below).

    A layer and field are set with four attribution values

    Use the Mirror tool to flip the interface for easier access to a particular control (see below).  For instance if you would rather have the Attribution Assistant sit on the left side of the screen, a user can flip the interface so the mouse does not have to travel as far to click the Calculate button.

    The interface is reversed with the Mirror tool

    Minimize the Attribution Assistant application with the Minimize button.  When you launch the tool again from the main icon on the ArcMap interface all settings will be preserved.

    Use the Import button to automatically populate the attribution boxes with (up to 16) unique values that exist in the dataset in decreasing order.

    Uses:
    • Basic attribution - select features on-the-fly with the Select Features Tool and click the calculate button on the Attribution Assistant to apply the custom value to each of the selected features. Add a blank text box that can be used to clear an existing value.
    • In an editing session - use the Attribution Assistant in an editing session to quickly attribute data as it is being digitized.  Rather than clicking inside the Attributes dialog (launched from the Editor toolbar ) or clicking inside a cell in the Attribute Table and typing a (or pasting a copied) value for each new feature, one can simply close the polygon, click a single button to apply attribution, and continue.
    Dynamic Help:
    Click on any label to bring up a small explanation for each feature in the application.  Look for the Help pointer as you hover over a label

    Installation:
    View the installation instructions for this tool in the article titled, "Install Non-Packaged 3rd Party GIS Plugins"


    Refer to a previous article on GIS Desktop Customization to learn about manipulating buttons/tools and toolbars on your GIS interface.

    Thursday, April 22, 2010

    ArcObjects: Clear Selected Features

    The following is the VB code to quickly selected features in ArcMap with ArcObjects. This code will perform the same function as clicking the Clear Selected Features tool on the ArcMap interface.

    There are two parts: the setup (Dim/Set instances), then clear the selection with a partial refresh followed by pMap.ClearSelection (in that order).  This example is a command button that will run the method after a Click event:

    Private Sub cmdClear_Click()
        Dim pMxDocument As IMxDocument
       
    Dim pMap As IMap
       
    Dim pActiveView As IActiveView
        Set pMxDocument = ThisDocument
       
    Set pMap = pMxDocument.FocusMap
       
    Set pActiveView = pMap

        pActiveView.PartialRefresh esriViewGeoSelection, Nothing, Nothing
        pMap.ClearSelection
    End Sub

    Tuesday, April 20, 2010

    GIS Desktop Customization

    I developed and led a training seminar for FDEP's ArcDiscovery Sessions that discusses GIS Desktop customization.  Presented April 15, 2010 to 30 in-house participants and another 20 employees around the state via video conference, this topic is separated into two parts:
    • the configuration of buttons and toolbars on the ArcMap interface
    • an introduction to object-oriented programming for custom GIS tools

    Below are the slides that were presented in the course, however a pdf tutorial accompanies the talk which provides step-by-step instruction on each topic discussed in the seminar.


    Monday, April 5, 2010

    Geometric Field Calculations

    There are a number of common geometric field calculations that I use on a regular basis.  Calculating polygon area & primiter, linear/arc/path distance, or feature centroid coordinates are surprisingly simple to obtain and can prove to be very powerful information.

    If you're working in a geodatabase, many of these will be automatically calculated and updated as features are edited, however these must be re-calculated using the Field Calculator when working with shapefiles.  Here's how:
    • Open a layer's attribute table
    • From the Options menu at the bottom of the attribute table window choose Add Field... if some kind of area/length/etc. field does not already exist.  
    • Name the new field and choose Double for its type.

      Again, if the layer is in a geodatabase, the SHAPE_AREA and SHAPE_LENGTH fields will be available and updated.  These fields will be present in a shapefile format if they were exported from a geodatabase coverage, but you will need to re-calculate the values.  Don't bother adding a new field if this is the case - just update the existing fields using the following steps
    • Right click on the appropriate field (of type Double) and choose Field Calculator
    • Check the Advanced option box
    •  Use the following code snippets to calculate the appropriate type of geometric information for each feature.  I'll calculate polygon Area for this example, however I can also calculate perimeter or centroids, etc.

      Paste the code (see below) in the Pre-Logic VBA Script Code box, and type the object (the variable that is created in the first line: in this case it's dblArea) in bottom most text box.  Click OK when finished
    •  That's it!
    Below are code snippets for various types of geometric calculations.  Be sure to paste the corresponding object created in the first line (dblArea/dblPerimeter/etc.) into the text box at the bottom of the Field Calculator.

    Area
    Dim dblArea as Double
    Dim pArea as IArea
    Set pArea = [shape]
    dblArea = pArea.area



    Perimeter
    Dim dblPerimeter as Double
    Dim pCurve as ICurve
    Set pCurve = [shape]
    dblPerimeter = pCurve.Length



    Length
    Dim dblLength as Double
    Dim pCurve as ICurve
    Set pCurve = [shape]
    dblLength = pCurve.Length



    X-coordinate of a point
    Dim dblX As Double
    Dim pPoint As IPoint
    Set pPoint = [Shape]
    dblX = pPoint.X



    Y-coordinate of a point
    Dim dblY As Double
    Dim pPoint As IPoint
    Set pPoint = [Shape]
    dblY = pPoint.Y



    X-coordinate of a polygon centroid
    Dim dblX As Double
    Dim pArea As IArea
    Set pArea = [Shape]
    dblX = pArea.Centroid.X



    Y-coordinate of a polygon centroid
    Dim dblY As Double
    Dim pArea As IArea
    Set pArea = [Shape]
    dblY = pArea.Centroid.Y


    Read more in these selected ESRI's articles:
     - Making Field Calculations
     - The Field Calculator Unleashed

    Wednesday, March 17, 2010

    Georeferencing / Georectification / Geometric Correction in ArcMap

    I've done some geometric correction using other software packages, but have not yet tried to do it in ArcMap.  It turns out that there's a pretty small learning curve in the world of georeferencing in ArcMap.  I recommend simply turning on the Georeferencing toolbar and playing around with the hand full of tools that it holds.  All of the most useful tools are hidden away in either the Georeferencing menu on the left of the toolbar or in the small menu of three manual alteration tools to the right of drop down menu of selectable layers.  In the hour or so that I have been attempting to georeference a couple images, I already want to pull the tools out of the drop down menus and place them on the main toolbar for faster access.


    A screenshot of the Georeferencing toolbar in ArcMap


    Turn on the Georeferencing toolbar:
    To verify, turn on the Georeferenceing toolbar by either right clicking in empty gray space beside tool bars/file menus at the top of the ArcMap window, or by going to Tools :: Customize and on the Toolbars tab, place a check mark in the box next to the Georeferencing toolbar option (then click Close).  The toolbar (see above) will appear.

    Add imagery:
    Use the Add Data button to add a raw, unreferenced images (.jpg, .png, .bmp, etc.) to an ArcMap project.  Expect to receive an "Unknown Spatial Reference" message that explains that the image cannot be projected.  If there are spatial layers already added to the project, the images will probably be displayed somewhere off in a corner.  Right click on the image layer in the table of contents and select Zoom to Layer to view it.

    Here are a few good resources to consider to obtain imagery:

    Georeferencing:
    I have access to rectified imagery and other reference datasets (transportation networks, hydrography, etc.) so I'll use those to illustrate some techniques (very quickly and roughly).  I'll just be using aerial imagery from 2005-2009 and a coverage of State Routes.
    • Zoom to the area where the image should cover.  This example is looking at an area in Florida around Taylor Creek, just north of Lake Okeechobee:











    • Choose an image to manipulate from the Layer menu on the Georeferencing toolbar

    • Since my .jpg image (in this case) is hiding down at the grid origin, somewhere in the Gulf of Mexico, I will have a hard time matching similar locations in the relation process.  Open the Georeferencing menu on the toolbar and select Fit to Display.  The image will shift into view and be resized to fill your map view.

    • Begin by using the three tools in the menu to the right of the Layer menu to roughly align the image:
      • Primarily, it seems that the images are rotated about 90° clockwise (north is pointing east). Use the Rotate tool to fix this. The original top of the raw JPEG is now facing west:
        (This can also be performed from the Georeferencing menu under Flip or Rotate :: Rotate Left)
    Rotated the image 90° anti-clockwise so north
    (Click to enlarge images)
      • Next, use the Scale tool to shrink the image a bit:
     
    Shrink the image with the scale too
      • Finally, use the shift tool to move the image closer to its correct position:
     Moved the image using the shift tool
    •  Open the Link Table by clicking the button on the far right of the Georeferencing toolbar.  This will keep track of the control points that will be added in the next step.

    • Zoom in to a location that is easily distinguishable in the rectification image as well as any reference data.  Roadways are excellent references, especially when they intersect with each other or with a stream, etc.  A less effective reference feature can be a lake or stream, for example, because the shorelines can change over time.  Roadways often have less variation.  Local knowledge is very beneficial in these situations.

      Below is an example of a roadway intersection that is a decent enough reference point to use.  The red circle indicates where the control points will be placed:
    (Broken GIF: the image should be animated
    to illustrate the two control point locations)
    • Use the Add Control Points tool to add pairs of control points.  The first click will represent the "from" location that will correspond to a point on the image that is being rectified (the black & white image in this case).  The second click will represent the "to" position, where the image will be moved or stretched.  This pair of control points creates a vector that is used to rotate, stretch, and skew the image.

      Add a few of these control points across the extent of the rectification image.  Each time a control point is completed, the information will appear in the Link Table, and the image will move (if the Auto Adjust option is checked in the Georeferencing menu).

      Note the Total RMS Error that is reported in the lower right corner of the Link Table window.  Root Mean Square Error is "a measure of the difference between locations that are known and locations that have been interpolated or digitized" (Heather Kennedy. 2000. ESRI Dictionary of GIS Terminology, ESRI Press, Redlands, CA.). In general, lower values are desirable.  Read more about RMS Error.


    •  It helps to turn layers on and off in the table of contents pane.  Another useful technique is to use the Swipe Layer tool (found on the Effects toolbar).  Make sure that the image/layer/group layer is selected in the Effects toolbar selected layer menu, then select the Swipe Layer tool and click the map view.  Then simply click and drag the tool across a map to reveal lower layers on the map.
    Image rectified with various control points
    * Caution! Changing the selected layer on the
    Georeferencing toolbar will remove any editing
    or work that has been done to an image. Use the
    following methods to preserve your referencing
    Save image referencing:
    •  From the Georeferencing menu, simply choose Update Georeferencing
    This adds two files ( [image name].aux & [image name].JGw ) to the directory where the image is located.  These two files are referenced when the image is added to a project,future

    (Optional) Export image:
    •  From the Georeferencing menu, choose Rectify to bring up the Save As dialog

    • Change the Output Location (choose a folder or workspace), and change the name of the image if necessary.  The remaining parameters can be left with the default settings.  Click Save to continue.

    • Use the Add Data button again to add the new image to the project, or distribute as necessary

    Remove null values:
    After adding the image, you may notice a black box surrounding the image.  This is simply the blank space left when the new image was created from an image that was rotated slightly.  These null values have the value of 0 in the dataset and can be easily removed:
    • Right click on the image layer in the table of contents pane and choose Properties (or double click on the layer)
    • Navigate to the Symbology tab
    • Place a check next to Display Background Value setting.  Ensure that 0 is the denoted value, and that the color selector is set to No Color.  Choose Apply or OK to continue

      Removing null values from the layer

      Several georeferenced images

      One problem remains.  There are still some black outlines on the edges of these images.  Those areas are inherited from the original raw images.  These can be handled in two ways;
      1. The images can be cropped from the original JPEG files before they are georeferenced to remove the outlines.  Be sure to make copies of the original images before any editing is applied.
      2. Manipulate the geographic extent of each layer:
        • Open the layer properties for an image
        • Navigate to the Extent tab
        • Change the "Set the extent to" option to "a custom extent entered below"
        • Increase (Left & Bottom) or decrease (Top & Right) the Visible Extent values by small intervals and click Apply to view the results.

          * Reset the values if necessary by changing the "Set the extent to" option to "the default extent of this layer"

        Several georeferenced images with altered geographic extents

        If this is still not suitable, you may need to pre-process the image with some other graphics software.

        More information:

        Saturday, February 27, 2010

        Loop Through Controls in VB


        A little info about the tool to the left that I'm building then I'll get to the point:

        This Attribution Assistant (screenshot of version 1) allows a user to quickly apply attribution to selected features in ArcMap.  Say you're attributing a huge dataset of streams (my current project) and they need to be designated either a "river," a "stream," or a "canal."  One can open an editing session and type in the values as they're hilighted, or for several at a time (a bit more efficient) a user can right click on the in the attribute table, and use the Field Calculator to do some en-masse attribution, but she or he will still need to change that one value over and over again.  Back and forth... Kill me.

        Instead, select the layer of interest, then select the field that will hold the attribution, and add up to 16 text boxes for possible values (it starts with just one row, but the screenshot is expanded to 16 for the sake of screenshots...).  Then select some features and click the calculator button that corresponds with the proper value.  That's it.  One click attribution.

        The check boxes to the right disables the corresponding text box and delete button so a user doesn't accidentally change/remove values.  Here's the problem though.  For version 2, there will be a "Check All" check box at the top that will let the user - that's right - select/unselect all check boxes at once.  The best way to do this is to loop through each check box control and set its value to False.

        Easier example to begin:
        • All text boxes should be reset when the the dataset is changed or the form is "reset" for other possible reasons.
        Originally, the Reset procedure/subroutine had 16 lines which manually erase each text box:

        ‘Reset all text boxes to null or  “”
        txtValue01.Text = ""
        txtValue02.Text = ""
        txtValue03.Text = ""
        txtValue04.Text = ""
        txtValue05.Text = ""
        txtValue06.Text = ""
        txtValue07.Text = ""
        txtValue08.Text = ""
        txtValue09.Text = ""
        txtValue10.Text = ""
        txtValue11.Text = ""
        txtValue12.Text = ""
        txtValue13.Text = ""
        txtValue14.Text = ""
        txtValue15.Text = ""
        txtValue16.Text = ""

        This works, but it's lame.  Here's a better way, explained below:

        ‘This is faster
        Dim cControl As Control
        For Each cControl In Me.Controls
        ........'Look for text boxes only
        ........If TypeName(cControl) = "TextBox" Then
        ............cControl.Text = ""
        ....End If

        Next cControl
        [Be sure to remove the dots (....) used to format the above code]

        - Start by creating an object named cControl (or whatever) As a Control.
        - Make a For Each loop that will loop/search through all controls (buttons, text boxes, etc. see my VB Cheat Sheet) in the form.
        - Begin to target which specific controls you want to change.  In this case all text boxes in the form should be changed, but if there were more text boxes, you can add more parameters to a query.  For instance, all text boxes with a certain .Tag or .Name.  Use logic operators (like And, Or, etc.) to add to the query.

        A (just slightly) more difficult example:

        I also want to set .Tabstop = False for some of the text boxes so a user can hit the tab key to move the cursor to the next available text box.  The problem is that I don't want the user to tab to a box that is out of view. (I cheated.  When the form initializes, there seems to be only one row of attribution controls, but there are 16.  The form just gets bigger and the next row of controls are initialized.  They're really there the whole time though.)

        So there's some code to take care of turning the .Tabstop property on, but let's just focus on turning that off as well.  I'll also include another parameter in the query to find the exact controls, highlighted below:

        ‘Loop through controls
        Dim cControl As Control
        For Each cControl In Me.Controls
        ........'Look for specific text boxes
        ........If TypeName(cControl) = "TextBox" And _
        ............cControl.Name Like "txtValue*" Then
        ............cControl.Text = ""
        ............cControl.Tabstop = False
        ....End If
        Next cControl
        [Be sure to remove the dots (....) used to format the above code]


          Friday, February 19, 2010

          Gaps in Polyline Coverages / Vector Linear Direction

          I'm editing a large statewide line coverage of streams across the state of Florida based on 24k NHD Flowlines. I have been continually coming across what appear to be small gaps in the coverage, however zooming in (even to 1:1 or further) does not reveal disconnected features.  Setting snapping parameters and repositioning the endpoints in an editing session doesn't help either.

          Here's a screenshot with an enlargement of the gap to the left.  The instances of the gap are subtle, and even more so in screenshot below (click to enlarge):

          A gap between two segments in a polyline coverage with
          an enlargement of the issue to the left

          It turns out that the line segments do in fact intersect and their ends are connected.  The problem is that the vector feature directions may not be aligned properly.  Although it is possible for two stream segments to flow away from each other (via confluence at usually obtuse angles), when the directions of two line segments are converging (see below) a small gap appears between the two features which is usually only one pixel wide.

          There's a bit more to the distance and direction parameters that polyline features preserve in a vector dataset. A tertiary "from-to" designation is included in the bearing, although it's not always apparent at first glance (nor is it always needed, though it's a good idea to consider to avoid future problems).

          Vector Linear Direction:

          As an illustration, two simple line segments are created.  Line 1 is digitized from west to east / left to right, and Line 2 is digitized from east to west, however it isn't immediately apparent:


          By viewing a line's vertices (double click on a line segment using the edit tool in an edit session to expose its sketch) one can view the from-to direction orientation of a line feature.  Initial / first, and intermediate vertices are green, and the final / last vertex is red; which indicate from-to direction:


          The from-to direction of a line can be flipped easily: select a line, expose its sketch (double click using the edit tool), then right click the sketch and choose Flip from the context menu.

          It's easier to visualize flow direction of a linear network by putting arrow heads on the end of each line:


          Arrowhead Symbology:
          • Open the "Symbol Selector" dialog for a line coverage (change the symbol properties):
           
          • Click Properties to open the Symbol Property Editor
          • Change the Type to "Catrographic Line Symbol"
          • Navigate to the Line Properties tab
          • Select the middle, right facing arrow from Line Decorations area and click OK until you're back at your map:

          The default symbology is a bit bulky so play around with different settings and characters to represent arrowheads or other symbols at either or both ends of your line features.

          Linear Network Interactions:

          So the single pixel-wide gap seems to appear only with converging line segments, and not with diverging, or in-line interactions: