Geocoding and Routing

TatukGIS Internet Server Samples


From: 
To: 

  Preference/Cost Level
Main roads
Local roads

Source code

This TatukGIS Internet Server sample shows how to programmatically create a web-based geocoding and routing solution. This sample demonstrates in particular:

  • using the TGIS_Geocoding class
  • using the TGIS_ShortestPath class
  • street address querying
  • optimal routing using StartPos and StopPos features
  • cost based routing

Cost based routing is of particular interest, because it allows the on-line user to specify a cost (or preference) factor for each road type. (This particular TIGER sample contains only two road types, one representing local streets and one representing main roads.) For instance, if the speed limit is higher on the main roads than on the local streets, the major roads can be assigned a lower cost (higher preference) factor than the local streets. The result is that the "optimal route" is calculated taking this preference into consideration, not simply the shortest route.

To use this sample, first identify the starting position by entering one of the following in the "From:" field: a street name, street name and number, or the names of two streets which intersect at some point. To just query for the map location of this place, click on the "Find Address" button.

Use the same method to specify a second location in the "To:" field and then click on the "Find Route" button to calculate the optimal route between the two map locations which reflects on the preference (cost) settings. The starting location is presented on the map by the green point, the destination location is presented by the red point, and the route between the two locations is presented by the red line.

Just entering the first few letters of a street name generally works fine. When entering only a street name with no address number, the query will return the first segment of the specified street contained in the database. (This is because each street segment in a raw TIGER dataset is a separate record.) When entering the names of two intersecting streets in one field to specify a location, use " & ” to separate the names. An example would be "Lafayette & Illinois".

The pending release version of the Internet Server includes address parsing functionality which is not featured in this sample.


geocoding.aspx    Top

                        
                        
<%@ Page Language="VB" Debug="True" %>
<%@ Register TagPrefix="ttkGIS" Namespace="TatukGIS.IS" Assembly="TatukGIS.IS" %>
<script runat="server">

    Dim GisUtils As API.XGIS_Utils
    Dim layerSrc As API.XGIS_LayerVector
    Dim layerRoute As API.XGIS_LayerVector
    Dim rtrObj As API.XGIS_ShortestPath
    Dim geoObj As API.XGIS_Geocoding
    
    Private WithEvents EventShortestPath As API.XGIS_ShortestPath
    
    Sub Page_Load(sender As Object, e As EventArgs)
        If not page.IsPostBack then
            edtAddrFrom.Text = "ham 102"
            edtAddrTo.Text = "kev"
            session("btnClick") = 0
            session("setZoom") = FALSE
        end if
    End Sub
    
    Sub GIS_FullExtent_Click(sender As Object, e As ImageClickEventArgs)
        GIS.FullExtent
    End Sub
    
    Sub GIS_ZoomIn_Click(sender As Object, e As ImageClickEventArgs)
        GIS.ZoomIn
    End Sub
    
    Sub GIS_ZoomOut_Click(sender As Object, e As ImageClickEventArgs)
        GIS.ZoomOut
    End Sub
    
    Sub GIS_Smaller_Click(sender As Object, e As ImageClickEventArgs)
        GIS.Width  = Unit.Pixel( GIS.Width.Value  - 54 )
        GIS.Height = Unit.Pixel( GIS.Height.Value - 40 )
    End Sub
    
    Sub GIS_Larger_Click(sender As Object, e As ImageClickEventArgs)
        GIS.Width  = Unit.Pixel( GIS.Width.Value  + 54 )
        GIS.Height = Unit.Pixel( GIS.Height.Value + 40 )
    End Sub
    
    Private Sub EventShortestPath_OnLinkType(ByRef translated As Boolean, ByVal Shape As Object, ByRef Kind As Integer) Handles EventShortestPath.OnLinkType
        translated = True
        If Shape.GetField("CFCC") >= "A4" Then
          'local roads
            Kind = 1
        Else
            Kind = 0
        End If
    End Sub    
    
    Sub GIS_Load(sender As Object, e As EventArgs)
        GisUtils = New API.XGIS_Utils

        GIS.Open(GisUtils.GisSamplesDataDir + "tiger_route.shp")
        GIS.API.Units.Units = API.XGIS_UnitsType.XgisUnitsTypeDegreeDecimal
    
        layerSrc = GIS.API.Items.Item(0)
        If layerSrc Is Nothing Then
            Exit Sub
        End If
        layerSrc.Params.Line.SmartSize = 0
    
        layerRoute = New API.XGIS_LayerVector()
        If layerRoute Is Nothing Then
            Exit Sub
        End If
    
        layerRoute.UseConfig = False
        layerRoute.Params.Line.Color = RGB(255, 0, 0)
        layerRoute.Params.Line.Width = -2
        layerRoute.Params.Marker.OutlineWidth = 1
        layerRoute.Name = "RouteDisplay"
        GIS.API.Add(layerRoute)
    
        geoObj = New API.XGIS_Geocoding
        If geoObj Is Nothing Then
            Exit Sub
        End If
    
        geoObj.Create_(layerSrc)
        geoObj.Offset = 0.0001
        geoObj.RoadName = "FENAME"
        geoObj.LFrom = "FRADDL"
        geoObj.LTo = "TOADDL"
        geoObj.RFrom = "FRADDR"
        geoObj.RTo = "TOADDR"
    
        rtrObj = New API.XGIS_ShortestPath()
        If rtrObj Is Nothing Then
            Exit Sub
        End If
    
        rtrObj.Create_(layerSrc.Viewer)
        EventShortestPath = rtrObj
        rtrObj.LoadTheData(layerSrc)
        rtrObj.RoadName = "FENAME"
        GIS.API.RecalcExtent()
        GIS.FullExtent()
    
    End Sub
    
    Sub GIS_Paint(sender As Object, e As PaintEventArgs)
        Dim i As Short
        Dim shp As API.IXGIS_Shape
        Dim res As Short
        Dim pt_a As API.IXGIS_Point
        Dim pt_b As API.IXGIS_Point
        Dim ang As String
        Dim oldnam, oldang as string
    
   
       'find route
        if session("btnClick") = 1 then
    
            rtrObj.CostModifiers(0) = 1 - ((1 / 11) * RadioButtonList1.SelectedItem.Value)
            rtrObj.CostModifiers(1) = 1 - ((1 / 11) * RadioButtonList2.SelectedItem.Value)
    
            res = geoObj.Parse(edtAddrFrom.Text)
            If res > 0 Then
                edtAddrFrom.Text = geoObj.Query(0)
            Else
                edtAddrFrom.Text = edtAddrFrom.Text & " ???"
            End If
    
            If res <= 0 Then
                Exit Sub
            End If
    
            pt_a = geoObj.Point(0)
    
            res = geoObj.Parse(edtAddrTo.Text)
            If res > 0 Then
                edtAddrTo.Text = geoObj.Query(0)
            Else
                edtAddrTo.Text = edtAddrTo.Text & " ???"
            End If
    
            If res <= 0 Then
                Exit Sub
            End If
    
            pt_b = geoObj.Point(0)
    
            rtrObj.UpdateTheData()
            rtrObj.StartPos(layerRoute.Unproject(pt_a), 5 / GIS.Zoom)
            rtrObj.StopPos(layerRoute.Unproject(pt_b), 5 / GIS.Zoom)
    
            dim routeTable as New System.Data.DataTable
            routeTable.Columns.Add("Desc", GetType(string))
            dim dr as System.Data.DataRow
    
            oldnam = "#$@3eqewe"
            oldang = ""
            For i = 0 To rtrObj.ItemsCount - 1
                If oldnam <> rtrObj.Items(i).Name Then
                    If oldnam <> "#$@3eqewe" then
                        dr = routeTable.NewRow()
                        dr(0) = "" & oldang &"" & oldnam
                        routeTable.Rows.Add(dr)
                    end if
    
                    oldnam = rtrObj.Items(i).Name
                    Select Case rtrObj.Items(i).Compass
                        Case 0 :
                            ang = "FOWARD "
                        Case 1 :
                            ang = "RIGHT "
                        Case 2 :
                            ang = "RIGHT "
                        Case 3 :
                            ang = "RIGHT "
                        Case 4 :
                            ang = "BACK "
                        Case -1 :
                            ang = "LEFT "
                        Case -2 :
                            ang = "LEFT "
                        Case -3 :
                            ang = "LEFT "
                        Case -4 :
                            ang = "BACK "
                    End Select
                    oldang = ang
                end if
            Next i
    
            If oldnam <> "#$@3eqewe" then
                dr = routeTable.NewRow()
                dr(0) = "" & oldang &"" & oldnam
                routeTable.Rows.Add(dr)
            end if
    
            memRoute.Visible = True
            memRoute.DataSource = routeTable.DefaultView
            DataBind()
    
            For i = 0 To rtrObj.ItemsCount - 1
                shp = rtrObj.Items(i).Layer.GetShape(rtrObj.Items(i).Uid)
                If shp Is Nothing Then Exit For
                layerRoute.AddShape(shp)
                If i = 0 Then
                    layerRoute.Extent = shp.Extent
                End If
            Next i
    
            shp = layerRoute.CreateShape(API.XGIS_ShapeType.XgisShapeTypePoint)
            shp.Lock(1)
            shp.AddPart()
            shp.AddPoint(pt_a)
            shp.Params.Marker.Color = Convert.ToUInt32(RGB(0, 255, 0))
            shp.Unlock()
    
            shp = layerRoute.CreateShape(API.XGIS_ShapeType.XgisShapeTypePoint)
            shp.Lock(1)
            shp.AddPart()
            shp.AddPoint(pt_b)
            shp.Unlock()
        end if
    
       'find address
        if session("btnClick") = 2 then
            memRoute.Visible = False
            If geoObj Is Nothing Then
                Exit Sub
            End If
    
            layerRoute.RevertAll()
            geoObj.Clear()
            res = geoObj.Parse(edtAddrFrom.Text) - 1
            If res <= 0 Then
                edtAddrFrom.Text = edtAddrFrom.Text & " ???"
            End If
    
            For i = 0 To res
                edtAddrFrom.Text = geoObj.Query(i)
    
                shp = layerSrc.GetShape(geoObj.Uid(i))
                layerRoute.AddShape(shp)
                If i = 0 Then
                    layerRoute.Extent = shp.Extent
                End If
    
                shp = layerSrc.GetShape(geoObj.UidEx(i))
                If Not shp Is Nothing Then
                    layerRoute.AddShape(shp)
                End If
    
                shp = layerRoute.CreateShape(API.XGIS_ShapeType.XgisShapeTypePoint)
                shp.Lock(1)
                shp.AddPart()
                shp.AddPoint(geoObj.Point(i))
                shp.Params.Marker.Color = Convert.ToUInt32(RGB(0, 255, 0))
                shp.Unlock()
            Next i
        end if
    
        if session("setZoom") = TRUE then
            GIS.API.VisibleExtent = layerRoute.Extent
            GIS.Zoom = 0.7 * GIS.Zoom
            session("setZoom") = FALSE
        end if
        GIS.Draw()
    End Sub
    
    Sub btnRoute_Click(sender As Object, e As EventArgs)
        session("btnClick") = 1
        session("setzoom") = TRUE
    End Sub
    
    Sub btnResolve_Click(sender As Object, e As EventArgs)
        session("btnClick") = 2
        session("setzoom") = TRUE
    End Sub


</script>
<html>
<head>
    <title>TatukGIS IS Sample</title>
    <link href="style.css" type="text/css" rel="stylesheet" />
</head>
<body>
    <a name="top"></a>
    <h1>Geocoding and Routing 
    </h1>
    <h2 class="comment"><a href="../../samplesAPI.htm">TatukGIS Internet Server Samples</a>
    </h2>
    <form runat="server">
        <p>
            <br />
        </p>
        <table style="WIDTH: 237px; HEIGHT: 204px" cellspacing="0" cellpadding="0" border="0">
            <tbody>
                <tr>
                    <td>
                        <asp:ImageButton id="GIS_FullExtent" onclick="GIS_FullExtent_Click" runat="server" ImageUrl="/TatukGIS_IS8/img/fullextent.gif"></asp:ImageButton>
                        <asp:ImageButton id="GIS_ZoomIn" onclick="GIS_ZoomIn_Click" runat="server" ImageUrl="/TatukGIS_IS8/img/zoomin.gif"></asp:ImageButton>
                        <asp:ImageButton id="GIS_ZoomOut" onclick="GIS_ZoomOut_Click" runat="server" ImageUrl="/TatukGIS_IS8/img/zoomout.gif"></asp:ImageButton>
                    </td>
                    <td align="right">
                        <asp:ImageButton id="GIS_Smaller" onclick="GIS_Smaller_Click" runat="server" ImageUrl="/TatukGIS_IS8/img/smaller.gif"></asp:ImageButton>
                        <asp:ImageButton id="GIS_Larger" onclick="GIS_Larger_Click" runat="server" ImageUrl="/TatukGIS_IS8/img/larger.gif"></asp:ImageButton>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <p>
                            <TTKGIS:XGIS_VIEWERIS id="GIS" runat="server" OnPaint="GIS_Paint" BorderWidth="1px" BorderColor="CornflowerBlue" OnLoad="GIS_Load" Width="360px" Height="280px"></TTKGIS:XGIS_VIEWERIS>
                        </p>
                    </td>
                </tr>
            </tbody>
        </table>
        <p>
            <asp:Panel id="Panel1" runat="server" Width="362px" Height="57px" BackColor="LightSteelBlue">
                <p>
                    <table style="WIDTH: 237px; cellspacing: " cellpadding="0" border="0">
                        <tbody>
                            <tr>
                                <td>
                                    From: <asp:TextBox id="edtAddrFrom" runat="server"></asp:TextBox>
                                </td>
                                <td>
                                    <asp:Button id="Button1" onclick="btnResolve_Click" runat="server" Text="Find Address"></asp:Button>
                                </td>
                            </tr>
                            <tr>
                                <td align="right">
                                    To: <asp:TextBox id="edtAddrTo" runat="server"></asp:TextBox>
                                </td>
                                <td align="right">
                                    <asp:Button id="Button2" onclick="btnRoute_Click" runat="server" Text="  Find Route "></asp:Button>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </p>
                <p>
                    <table>
                        <tbody>
                            <tr>
                                <td>
                                     
                                </td>
                                <td>
                                    <asp:Label id="Label1" runat="server" font-bold="True">Preference/Cost Level</asp:Label></td>
                            </tr>
                            <tr>
                                <td>
                                    <asp:Label id="Label2" runat="server" font-bold="True">Main roads</asp:Label></td>
                                <td>
                                    <asp:RadioButtonList id="RadioButtonList1" runat="server" RepeatDirection="Horizontal" AutoPostBack="True">
                                        <asp:ListItem Value="1">low</asp:ListItem>
                                        <asp:ListItem Value="6">middle</asp:ListItem>
                                        <asp:ListItem Value="11" Selected="True">high</asp:ListItem>
                                    </asp:RadioButtonList>
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <asp:Label id="Label3" runat="server" font-bold="True">Local roads</asp:Label></td>
                                <td>
                                    <asp:RadioButtonList id="RadioButtonList2" runat="server" RepeatDirection="Horizontal" AutoPostBack="True">
                                        <asp:ListItem Value="1" Selected="True">low</asp:ListItem>
                                        <asp:ListItem Value="6">middle</asp:ListItem>
                                        <asp:ListItem Value="11">high</asp:ListItem>
                                    </asp:RadioButtonList>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </p>
            </asp:Panel>
        </p>
        <p>
            <asp:Repeater id="memRoute" runat="server">
                <HeaderTemplate>
                    <br />
                    <asp:Label id="Label1" runat="server" cssclass="bold">ROUTE:</asp:Label>
                    <br />
                    <br />
                </HeaderTemplate>
                <ItemTemplate>
                    <font class="smallerfont"><%# Container.DataItem("Desc") %></font>
                    <br />
                </ItemTemplate>
                <FooterTemplate></FooterTemplate>
            </asp:Repeater>
        </p>
    </form>
</body>
</html>