Saving Program Settings

March 2, 2009

As I have written of previously, here, I use XML files to save program settings.  The types of settings I am saving are:

  • Default PMF locations (Directories)
  • Field Names

programsettings

The code to save the settings is:

Private Sub cmdSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click
‘Program Defaults
objSettings.blnWriteString(“Program”, “DefaultPath”, (txtDefaultPath.Text))
objSettings.blnWriteString(“Program”, “DefaultMap”, (txtDefaultMap.Text))
objSettings.blnWriteBoolean(“Program”, “DefaultLayers”, CStr(chkDefaultLayers.CheckState))

‘Parcel Query Defaults
objSettings.blnWriteString(“ParcelQuery”, “ParcelFile”, (Me.txtParcelFile).Text)
objSettings.blnWriteString(“ParcelQuery”, “ParcelID”, (Me.txtParcelID).Text)
objSettings.blnWriteString(“ParcelQuery”, “OwnerName”, (Me.txtOwner).Text)
objSettings.blnWriteString(“ParcelQuery”, “HouseNumber”, (Me.txtHouseNum).Text)
objSettings.blnWriteString(“ParcelQuery”, “StreetName”, (Me.txtStreetName).Text)
objSettings.blnWriteString(“ParcelQuery”, “Map”, (Me.txtMap).Text)
objSettings.blnWriteString(“ParcelQuery”, “Group”, (Me.txtGroup).Text)
objSettings.blnWriteString(“ParcelQuery”, “Parcel”, (Me.txtParcel).Text)

‘Street Query Defaults
objSettings.blnWriteString(“StreetQuery”, “StreetField”, (Me.txtStreetField).Text)
objSettings.blnWriteString(“StreetQuery”, “StreetID”, (Me.txtStreetID).Text)
objSettings.blnWriteString(“StreetQuery”, “StreetFile”, (Me.txtStreetFile).Text)

‘destroy the class, this causes the class_finalize
‘event which saves the settings to persist in the
‘disk file
objSettings.blnSaveFile()
‘objSettings = Nothing
Call sGetCurvSettings()
Me.Close()
End Sub

The code to load the settings is:

Private Sub ProgramSettings_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
‘Program Defaults
Me.txtDefaultPath.Text = objSettings.strReadString(“Program”, “DefaultPath”, “”)
Me.txtDefaultMap.Text = objSettings.strReadString(“Program”, “DefaultMap”, “”)
chkDefaultLayers.Checked = objSettings.blnReadBoolean(“Program”, “DefaultLayers”, False)

‘Parcel Query Defaults
Me.txtParcelFile.Text = objSettings.strReadString(“ParcelQuery”, “ParcelFile”, “”)
Me.txtParcelID.Text = objSettings.strReadString(“ParcelQuery”, “ParcelID”, “”)
Me.txtOwner.Text = objSettings.strReadString(“ParcelQuery”, “OwnerName”, “”)
Me.txtHouseNum.Text = objSettings.strReadString(“ParcelQuery”, “HouseNumber”, “”)
Me.txtStreetName.Text = objSettings.strReadString(“ParcelQuery”, “StreetName”, “”)
Me.txtMap.Text = objSettings.strReadString(“ParcelQuery”, “Map”, “”)
Me.txtGroup.Text = objSettings.strReadString(“ParcelQuery”, “Group”, “”)
Me.txtParcel.Text = objSettings.strReadString(“ParcelQuery”, “Parcel”, “”)

‘Street Query Defaults
Me.txtStreetFile.Text = objSettings.strReadString(“StreetQuery”, “StreetFile”, “”)
Me.txtStreetID.Text = objSettings.strReadString(“StreetQuery”, “StreetID”, “”)
Me.txtStreetField.Text = objSettings.strReadString(“StreetQuery”, “StreetField”, “”)
End Sub

I also use the following function to save the Program settings as global varials for use throughout the program:

Public Sub sGetCurvSettings()

‘Program Defaults
gtxtDefaultPath = objSettings.strReadString(“Program”, “DefaultPath”, “”)
gtxtDefaultMap = objSettings.strReadString(“Program”, “DefaultMap”, “”)
gysnDefaultLayers = objSettings.blnReadBoolean(“Program”, “DefaultLayers”, False)

‘Parcel Query Defaults
gtxtParcelFile = objSettings.strReadString(“ParcelQuery”, “ParcelFile”, “”)
gtxtParcelID = objSettings.strReadString(“ParcelQuery”, “ParcelID”, “”)
gtxtOwner = objSettings.strReadString(“ParcelQuery”, “OwnerName”, “”)
gtxtHouseNum = objSettings.strReadString(“ParcelQuery”, “HouseNumber”, “”)
gtxtStreetName = objSettings.strReadString(“ParcelQuery”, “StreetName”, “”)
gtxtMap = objSettings.strReadString(“ParcelQuery”, “Map”, “”)
gtxtGroup = objSettings.strReadString(“ParcelQuery”, “Group”, “”)
gttxtParcel = objSettings.strReadString(“ParcelQuery”, “Parcel”, “”)

‘Street Query Defaults
gtxtStreetFile = objSettings.strReadString(“StreetQuery”, “StreetFile”, “”)
gtxtStreetID = objSettings.strReadString(“StreetQuery”, “StreetID”, “”)
gtxtStreetField = objSettings.strReadString(“StreetQuery”, “StreetField”, “”)
End Sub

Global variables:

Public objSettings As New xmlrw(“CURVSettings.xml”)
‘Program Settings
Public gtxtDefaultPath As String
Public gtxtDefaultMap As String
Public gysnDefaultLayers As Boolean

‘Parcel Search Settings
Public gtxtParcelFile As String
Public gtxtParcelID As String
Public gtxtOwner As String
Public gtxtHouseNum As String
Public gtxtStreetName As String
Public gtxtMap As String
Public gtxtGroup As String
Public gttxtParcel As String

‘Street Query Defaults
Public gtxtStreetFile As String
Public gtxtStreetID As String
Public gtxtStreetField As String

‘Layer Indexes
Public gintGroupIndex As Short
Public gintLayerIndex As Short


Saving Map Settings

March 1, 2009

One of the first things I want to be able to do with my ArcReadercontrol Viewer is be able to save program and map settings.  I have some experience with VB 6 and considered using INI files.  In the course of my research for upgrading to VB.net I became aware the INI files were strongly discouraged (INI Files Will Never Die: How-To in .NET).  With a little digging, I found that the same functionality of INI files could be found by using XML files.

XML Demo

A program that demonstrates how to persist VB.NET application settings using an XML document. This is basically notice the pun an example of how to use an XML file to persist settings in your application. The coding convention is the same as the VB SaveSettings or GetSettings, also the same as the old INI file convention. You use a Section to separate different types of settings then a key=value pair to store individual settings.

The sample from XML Demo works well, but I did need to make 1 change to the code to make it work:

I Changed:

Private Function blnSaveFile() As Boolean
‘private function used by the class to
’save current settings to the file, this
‘function is called on class_finalize, when
‘the object representing the class is destroyed
‘or set to nothing

m_xmld_File.Save(m_str_File_Name)

End Function

To:

Public Function blnSaveFile() As Boolean
‘private function used by the class to
’save current settings to the file, this
‘function is called on class_finalize, when
‘the object representing the class is destroyed
‘or set to nothing

m_xmld_File.Save(m_str_File_Name)

End Function

I created 2 functions that use the sample code from XML Demo.  These function are accessed via Menu items, Save Map Settings and Load Map Settings.

mapsettingsSave Map Settings:

Private Sub SaveMapToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveMapToolStripMenuItem.Click
Dim strFileName As String
Dim saveFileDialog1 As New SaveFileDialog()
saveFileDialog1.Title = “Select Location to Save Map Settings”
saveFileDialog1.Filter = “Curv Files (*.curv)|*.curv”
saveFileDialog1.RestoreDirectory = True

If saveFileDialog1.ShowDialog() = DialogResult.OK Then
strFileName = saveFileDialog1.FileName
Dim objMapSettings As New xmlrw(strFileName)
Dim varLayerInfo() As String
Dim i As Integer
Dim strKey As String
Dim strValue As String
Dim intLayers As Integer
Dim strCoords As String
Dim dXmin As Double, dYmin As Double, dXmax As Double, dYmax As Double
conARMap.ARPageLayout.FocusARMap.GetExtent(dXmin, dYmin, dXmax, dYmax)
strCoords = dXmin & “,” & dYmin & “,” & dXmax & “,” & dYmax
intLayers = fCountLayers()
varLayerInfo = fSetLayerIndexes(intLayers)
objMapSettings.blnWriteString(“Layers”, “SettingsForMap”, cmbMapSelection.Text)
objMapSettings.blnWriteString(“Layers”, “LayerExtents”, strCoords)
objMapSettings.blnWriteString(“Layers”, “Count”, CStr(intLayers))
For i = LBound(varLayerInfo) To UBound(varLayerInfo)
strValue = varLayerInfo(i)
If Len(strValue) > 0 Then
strKey = “Layer” & i
strValue = varLayerInfo(i)
objMapSettings.blnWriteString(“Layers”, strKey, strValue)
Else
i = 1001
End If
Next i
‘destroy the class, this causes the class_finalize
‘event which saves the settings to persist in the
‘disk file
objMapSettings.blnSaveFile()
objMapSettings = Nothing
End If
End Sub

I will try to explain the code:


Dim strFileName As String
Dim saveFileDialog1 As New SaveFileDialog()
saveFileDialog1.Title = “Select Location to Save Map Settings”
saveFileDialog1.Filter = “Curv Files (*.curv)|*.curv”
saveFileDialog1.RestoreDirectory = True

Open a save dialog and select a file to create.

If saveFileDialog1.ShowDialog() = DialogResult.OK Then

If a user selects a file and hits OK in the save dialog, continue.

Dim objMapSettings As New xmlrw(strFileName)

Create the save file via the xml class

Dim dXmin As Double, dYmin As Double, dXmax As Double, dYmax As Double
conARMap.ARPageLayout.FocusARMap.GetExtent(dXmin, dYmin, dXmax, dYmax)
strCoords = dXmin & “,” & dYmin & “,” & dXmax & “,” & dYmax

Get the coords of the map.

intLayers = fCountLayers()

Count the number of layers in the map (See Supporting Subs and Functions below)

varLayerInfo = fSetLayerIndexes(intLayers)

Create an Array of Layer index numbers, used to save layer index as well as visibility, ie on or off. (See Supporting Subs and Functions below)

objMapSettings.blnWriteString(“Layers”, “SettingsForMap”, cmbMapSelection.Text)
objMapSettings.blnWriteString(“Layers”, “LayerExtents”, strCoords)
objMapSettings.blnWriteString(“Layers”, “Count”, CStr(intLayers))
For i = LBound(varLayerInfo) To UBound(varLayerInfo)
strValue = varLayerInfo(i)
If Len(strValue) > 0 Then
strKey = “Layer” & i
strValue = varLayerInfo(i)
objMapSettings.blnWriteString(“Layers”, strKey, strValue)
Else
i = 1001
End If
Next i
‘destroy the class, this causes the class_finalize
‘event which saves the settings to persist in the
‘disk file
objMapSettings.blnSaveFile()
objMapSettings = Nothing
End If
End Sub

Save the settings to a file.

Load Map Settings

Sub sLoadDefaults()

OpenFileDialog1.Title = “Select a Map Settings File”
OpenFileDialog1.Filter = “Curv Files (*.curv)|*.curv”
OpenFileDialog1.ShowDialog()

‘Exit if no map document is selected
Dim sFilePath As String
sFilePath = OpenFileDialog1.FileName
If sFilePath = “” Then Exit Sub
Dim objMapSettings As New xmlrw(sFilePath)
Dim i As Integer
Dim strValue As String
Dim strKey As String
Dim intLayers As Integer
Dim intGroup As Integer
Dim intChild As Integer
Dim ysnLayerOnOff As Boolean
Dim arrString() As String
Dim arrCoords() As String
Dim strMapName As String
Dim strCoords As String
Dim dXmin As Double, dYmin As Double, dXmax As Double, dYmax As Double
strMapName = objMapSettings.strReadString(“Layers”, “SettingsForMap”, “”)
If cmbMapSelection.Text <> strMapName Then
Exit Sub
End If
strCoords = objMapSettings.strReadString(“Layers”, “LayerExtents”, “”)
arrCoords = Split(strCoords, “,”, -1)
dXmin = CDbl(arrCoords(0))
dYmin = CDbl(arrCoords(1))
dXmax = CDbl(arrCoords(2))
dYmax = CDbl(arrCoords(3))
conARMap.ARPageLayout.FocusARMap.SetExtent(dXmin, dYmin, dXmax, dYmax)
intLayers = CInt(objMapSettings.strReadString(“Layers”, “Count”, “”))
For i = 0 To intLayers – 1
If intLayers > 0 Then
strKey = “Layer” & i
strValue = objMapSettings.strReadString(“Layers”, strKey, “”)
arrString = Split(strValue, “,”, -1)
intGroup = CInt(arrString(0))
intChild = CInt(arrString(1))
ysnLayerOnOff = (arrString(2))
Call sLayerOn(intGroup, intChild, ysnLayerOnOff)
End If
Next i
conARMap.ARPageLayout.FocusARMap.Refresh()
objMapSettings = Nothing
End Sub

I will attempt to explain key points:

OpenFileDialog1.Title = “Select a Map Settings File”
OpenFileDialog1.Filter = “Curv Files (*.curv)|*.curv”
OpenFileDialog1.ShowDialog()

Open “Open File” dialog box

strMapName = objMapSettings.strReadString(“Layers”, “SettingsForMap”, “”)
If cmbMapSelection.Text <> strMapName Then
Exit Sub
End If

Check that the Map Settings file being opened matches the current, open PMF file, if it does not match, stop loading.

strCoords = objMapSettings.strReadString(“Layers”, “LayerExtents”, “”)
arrCoords = Split(strCoords, “,”, -1)
dXmin = CDbl(arrCoords(0))
dYmin = CDbl(arrCoords(1))
dXmax = CDbl(arrCoords(2))
dYmax = CDbl(arrCoords(3))
conARMap.ARPageLayout.FocusARMap.SetExtent(dXmin, dYmin, dXmax, dYmax)
intLayers = CInt(objMapSettings.strReadString(“Layers”, “Count”, “”))
For i = 0 To intLayers – 1
If intLayers > 0 Then
strKey = “Layer” & i
strValue = objMapSettings.strReadString(“Layers”, strKey, “”)
arrString = Split(strValue, “,”, -1)
intGroup = CInt(arrString(0))
intChild = CInt(arrString(1))
ysnLayerOnOff = (arrString(2))
Call sLayerOn(intGroup, intChild, ysnLayerOnOff)
End If
Next i
conARMap.ARPageLayout.FocusARMap.Refresh()
objMapSettings = Nothing
End Sub

Load the settings from the file use the Split function to break apart strings into an array (Split(strValue, “,”, -1))

Supporting Subs and Functions

Count Layers in the map.

Public Function fCountLayers() As Integer

Dim i As Integer
Dim j As Integer
Dim pLayer As ARLayer
Dim intLayerCount As Integer
intLayerCount = frmMain.conARMap.ARPageLayout.FocusARMap.ARLayerCount – 1
Dim intCounter As Integer
intCounter = 0
‘Loop through each layer in the focus map
For i = 0 To intLayerCount
pLayer = frmMain.conARMap.ARPageLayout.FocusARMap.ARLayer(i)
If pLayer.IsGroupLayer = False Then
‘If the layer is searchable add layer
‘to collection, and name to combo box
Else
For j = 0 To pLayer.ARLayerCount – 1
intCounter = intCounter + 1
Next j
End If
Next i

fCountLayers = intCounter
End Function

Create string with layer group index, layer index, and on/off state

Public Function fSetLayerIndexes(ByVal pintLayerCount As Integer) As String()

Dim i As Integer
Dim j As Integer
Dim pLayer As ARLayer
Dim intLayerCount As Integer
Dim strValue As String
intLayerCount = frmMain.conARMap.ARPageLayout.FocusARMap.ARLayerCount – 1
Dim arr() As String
Dim intCounter As Integer
intCounter = 0
ReDim arr(pintLayerCount)
‘Loop through each layer in the focus map
For i = 0 To intLayerCount
pLayer = frmMain.conARMap.ARPageLayout.FocusARMap.ARLayer(i)
If pLayer.IsGroupLayer = False Then
‘If the layer is searchable add layer
‘to collection, and name to combo box
Else
For j = 0 To pLayer.ARLayerCount – 1
strValue = i & “,” & j & “,” & pLayer.ChildARLayer(j).Visible
arr(intCounter) = strValue
intCounter = intCounter + 1
Next j
End If
Next i
fSetLayerIndexes = arr
End Function


Building a Custom Query

February 17, 2009

Years ago, I used to do a lot of programming with MS Access. Somewhere along the way I saw an interesting code sample of how to write a custom query. I have used the methodology described ever since. There may be better solutions available, and I am open to them, but I have used variations of the following code in all types of web pages and programs.

First Step:

  1. Create Search Form
    parcelsearch1
  2. Code The Search ButtonPrivate Sub cmdSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSearch.Click
    ‘On Error GoTo ActError

    ‘Query which searchs by user input
    Dim strwhere As String

    ‘Parcel Query Defaults
    strOwner = gtxtOwner
    strHouseNum = gtxtHouseNum
    strStreetName = gtxtStreetName
    strMap = gtxtMap
    strGroup = gtxtGroup
    strParcel = gttxtParcel
    strParcelFile = gtxtParcelFile
    strParcelID = gtxtParcelID
    With cmdSearch

    strwhere = “‘”

    If Len(txtOwnerSearch.Text) > 0 Then

    strwhere = ” and ” & strOwner & ” like ‘” & txtOwnerSearch.Text & “%’”
    End If

    If Len(txtCMAPSearch.Text) > 0 Then

    strwhere = strwhere & ” and ” & strMap & ” = ‘” & txtCMAPSearch.Text & “‘”

    End If

    If Len(txtGPSearch.Text) > 0 Then

    strwhere = strwhere & ” and ” & strGroup & ” = ‘” & txtGPSearch.Text & “‘”

    End If

    If Len(txtParcelSearch.Text) > 0 Then

    strwhere = strwhere & ” and ” & strParcel & ” = ” & txtParcelSearch.Text

    End If

    If Len(txtHouseNumSearch.Text) > 0 Then

    strwhere = strwhere & ” and ” & strHouseNum & ” = ” & txtHouseNumSearch.Text

    End If

    If Len(txtStreetNameSearch.Text) > 0 Then

    strwhere = strwhere & ” and ” & strStreetName & ” like ‘” & txtStreetNameSearch.Text & “%’”
    End If

    End With

    strwhere = UCase$(Mid$(strwhere, 6))

    txtSearch.Text = strwhere
    Call sSearch(strwhere)
    Me.ParcelsTableAdapter.Fill(Me.CurvDBDataSet.parcels)
    End Sub

    Explanation:
    I will attempt to explain the code.  It we look at:

    If Len(txtOwnerSearch.Text) > 0 Then
    strwhere = ” and ” & strOwner & ” like ‘” & txtOwnerSearch.Text & “%’”
    End If

    In the If…Then statement we test to see if txtOwnerSearch.text has a value.  I have been told that checking to see if the length of txtOwnerSearch.text is greater than 0 is slightly quicker than checking to see if txtOwnerSearch.text has a value.  If the length of txtOwnerSearch.text is greater than 0 and therefore has a value we begin to build the query statement.

    You will notice that all query statements begin with an AND regardless if it is the first statement.  This is by design and will be handled.

    strwhere = ” and ” & strOwner & ” like ‘” & txtOwnerSearch.Text & “%’”

    strwhere= Combined Query String
    strOwner=Column to be queried
    ” like ‘” & txtOwnerSearch.Text & “%’”=Search operator(Like), value(txtOwnerSearch.Text) and wildcard(%)

    Results:
    “and NAME_1=’Wilson M’”

    Handling the initial AND:

    strwhere = UCase$(Mid$(strwhere, 6))

    UCase$ = Capitalizes the entire string
    Mid$= Cuts off the first 6 characters, ” and “

    Results:
    strWhere=”NAME_1=’Wilson M’”

    Call sSearch(strwhere) – Call the search Subroutine

  3. Building the Search Sub:

    Sub sSearch(ByVal pstrWhere As String)
    ‘Set mouse cursor as this can take some time with large datasets
    On Error GoTo ErrorHandler
    ‘app.MousePointer = vbHourglass
    Dim intCount As Integer
    ‘Get layer to query
    Dim pARMap As ARMap
    pARMap = frmMain.conARMap.ARPageLayout.FocusARMap

    Call sSetIndexes(strParcelFile)
    pARLayer = pARMap.ARLayer(gintGroupIndex).ChildARLayer(gintLayerIndex)  ‘m_LayersIndex(cboLayers.ListIndex)

    ‘Build the ARSearchDef
    Dim pARSearchDef As ArcReaderSearchDef
    pARSearchDef = New ArcReaderSearchDef

    ‘Build WhereClause that meets search criteria
    Dim sWhereClause As String
    ‘Remove quotes from WhereClause if search is numeric
    sWhereClause = pstrWhere
    pARSearchDef.WhereClause = sWhereClause
    m_pFeatureCursor = pARLayer.SearchARFeatures(pARSearchDef)
    intCount = fCreateParcelDS(m_pFeatureCursor)

    If intCount > 0 Then
    lblMeets.Text = “Features MEETING the search criteria: ” & intCount
    Else
    lblMeets.Text = “Features MEETING the search criteria: 0″
    End If
    Exit Sub

    ErrorHandler:
    Debug.Print(Err.Number)
    Select Case Err.Number
    Case -2147219885
    MsgBox(“Check Field Names under Program Options”)
    ‘Me.MousePointer = vbDefault
    Exit Sub
    End Select

    End Sub

    Explanation:
    This subroutine is used to process the query string.  The code here is slanted to work with ArcReader Datasets and calls several custom functions which can be ignored.  The relevant section where the query is applied is:

    Call sSetIndexes(strParcelFile)Subroutine to set variables for search layer indexes
    pARLayer = pARMap.ARLayer(gintGroupIndex).ChildARLayer(gintLayerIndex)  ‘m_LayersIndex(cboLayers.ListIndex) – Set the layer to be searched

    ‘Build the ARSearchDef
    Dim pARSearchDef As ArcReaderSearchDef
    pARSearchDef = New ArcReaderSearchDef

    ‘Build WhereClause that meets search criteria
    Dim sWhereClause As String
    ‘Remove quotes from WhereClause if search is numeric
    sWhereClause = pstrWhere
    pARSearchDef.WhereClause = sWhereClause
    - Apply the search string
    m_pFeatureCursor = pARLayer.SearchARFeatures(pARSearchDef)
    - Build the Querried features
    intCount = fCreateParcelDS(m_pFeatureCursor)
    - Custom function to process the records and provide record count

Summary:

The methodology described above is extremely flexable.  I have used it in VB, VBA, .NET, PHP, and ASP projects.  I hope it helps you.


ArcReaderControl

February 15, 2009

Recently i have begun program a GIS viewer utilizing the arcreadercontrol. i wanted the viewer to have as much flexibility as possible. Some of the feature i am attempting to to include are:

  • Saved program settings
  • Saved map settings
    • zoom level
    • layer status(on/off)
  • Custom searches
  • Geocoding

currently, i have all functionality i desired working with the exception of text mark up. in the following posts i will attempt to detail how each item of functionality was accomplished.

Saved Program Settings

There are several reasons to save program settings.  In the case of the people I work with I find it easier to store the path to GIS data and projects within my programs.  I also, as stated earlier, want to be able to to build some custom searches.  The layer I want to be able to search is a parcel layer.  The parcel data I plan to search is from several different counties.  Unfortunately, due to naming conventions used in each county the field names are not always the same.  Therefore i need to save the field names as settings.

Saved Map Settings

On of the biggest frustrations, I have with ArcReader is the inability to save map settings.  For example, if I am working with a PMF files with many different layers, I would like the ability to save layers visibility based on the last setup I used.  With the standalone ArcReader application this is impossible.  I will work around this limitation in the custom viewer.

Custom Searches

The GIS users I work with tend to heavily utilize the available parcel layers.  To help facilitate their work I plan to create some customized searches to supplement the built in “Find” commands.  Alt hough the “Find” command is suitable for searching a single field, it does not handle searching multiple criteria.

Geocoding

The Geocoding functionailty availbe in ArcReader is limited to the ArcWeb Services Locators.  ArcReader and ArcReadercontrol can not utilize file based address locators.  I will attempt to see if there is a work around to allow file based geocoding.


Developing a Custom GIS Viewer

February 13, 2009

I have begun trying to build a custom GIS viewer for some of the GIS users I work with.  In my attempt to develop a viewer I have several goals in mind.  These goals include:

  • Viewer must be free
  • Viewer must read as many formats as possible
  • Developed in VB or VB.net
  • Flexible functionality

My goals for programming languages is strictly based on my own limitations.  I know how to program in VB, but preferably this project will focus on VB.net and help me to better learn its intricacies.

Currently, I have found 2 different paths to achieve my goals.  These paths include using MapWindow and the ArcReadercontrol.  The MapWindow website describes is as:

MapWindow GIS Open Source Software

The MapWindow application is a free, extensible, geographic information system GIS that can be used:

  • As an alternative desktop GIS
  • To distribute data to others
  • To develop and distribute custom spatial data analysis

via MapWindow GIS Open Source Project.

I like all of the functionality included with MapWindow, but the lack of GeoDatabase support in the long run is a potential problem.

My second option for building a viewer is using the ArcReadercontrol produced by ESRI.  According to the “ArcGIS Desktop Help” :

The ArcReaderControl and ArcReaderGlobeControl developer components are available as ActiveX Controls and .NET Windows controls on the Windows operating system. The ArcReaderControl and ArcReaderGlobeControl expose all the functionality available in the ArcReader application. Anyone with a Publisher license can develop custom ArcReader applications with the two controls. Developing with the ArcReaderControl and ArcReaderGlobeControl allows you to deliver specific ArcReader functionality to ArcReader users.

The ArcReadercontrol seems to have a lot of functionality but their are 2 areas of concern:

  1. Based on Proprietary software
  2. Control can only open PMF files (The PMF files can contan almost any format GIS data though)

Over the next serveral days and weeks, I will be posting my progress as well as code I used to develop my viewers.  Any suggestions or input is always welcome.


Water Quality Tools and Models – BASINS 4.0

December 13, 2008

Better Assessment Science Integrating point and Nonpoint Sources (BASINS)

BASINS is atool produced by the EPA.  As described on the BASINS website:

BASINS is a multipurpose environmental analysis system designed for use by regional, state, and local agencies in performing watershed and water quality-based studies. This system makes it possible to quickly assess large amounts of point source and non-point source data in a format that is easy to use and understand.

The original version of BASINS runs using ArcView 3.x.  The most recent version of BASINS is based on Open Source software.  From the BASINS 4.0 Description | Water Quality Tools and Models | US EPA:

The biggest change in BASINS 4.0 is the open source GIS software and the ability to transfer and share GIS standard data shapefile, dbf, and GeoTiff between other licensed GIS software. Also a Windows-based Climate Assessment Tool, for assessing potential impacts of changing climate on stream flows and pollutant loads has been added as a “plug-in” program which interfaces with WinHSPF.

I have used Basins 4.0 and find it pretty interesting.  It uses MapWindow.  I like the fact that Open Source software is being leveraged by the EPA.  For the most part BASINS worked well with 1 minor exception.  When I tried to projecting data it crashed.  To solve it I left everything in Geographiv coordibates.


Links to Crime mapping software

December 9, 2008

Here is a list of links I have started compiling for GIS and Crime mapping:

Crime Mapping & Analysis Program (CMAP)

RCAGIS

CASE (Crime Analysis Spatial Extension)

CrimeStat III


GIS and Health

December 9, 2008

ArcGIS, Python and File Exists

November 26, 2008

I use the script in models to test to see if output exists, if it exists, delete the files.  Otherwise do nothing.  Rather than include coding in my models for when the file does not exist, I have been create a “Step 2″ model.  I prefer creating multiple small models so that I can get each step working.  Someone asked, “Why not recombined once all the steps work?”  My answer is that I still find it easier to keep everything compartmentalized in case I want to tweak latter or try to streamline coding.

fileexists1

#**********************************************************************
# Description:
# Tests if a Dataset/Feature Layer and outputs two booleans:
#   Exists – true if the Dataset exists, false if it doesn’t exist
#   Not_Exists – true if the Dataset doesn’t exist, false if it does exist
#                (the logical NOT of the first output).
#
# Arguments:
#  0 – DataSet Name
#  1 – Exists (boolean – see above)
#  2 – Does Not Exists (boolean – see above)
#
# Created by: ESRI
# Modified By Mike Wilson (3/28/08)
#**********************************************************************

# Standard error handling – put everything in a try/except block
#
try:

# Import system modules
import sys, string, os, arcgisscripting

# Create the Geoprocessor object
gp = arcgisscripting.create()

# Get input arguments – DataSet Name
#
in_Dataset = gp.GetParameterAsText(0)

# First check that the DataSet exists
#
if gp.Exists(in_Dataset):
gp.SetParameterAsText(1, “True”)
gp.SetParameterAsText(2, “False”)
else:
gp.SetParameterAsText(1, “False”)
gp.SetParameterAsText(2, “True”)

# Handle script errors
#
except Exception, errMsg:

# If we have messages of severity error (2), we assume a GP tool raised it,
#  so we’ll output that.  Otherwise, we assume we raised the error and the
#  information is in errMsg.
#
if gp.GetMessages(2):
gp.AddError(GP.GetMessages(2))
else:
gp.AddError(str(errMsg))
#**********************************************************************

I modified this script quite a while ago and use it often.  I believe it is based on the “Field Check script” and the article “Branching: Implementing if-then-else logic“.  I apologize for note being more specific, but I misplaced my notes.  If I have improperly cited the origin, let me know.  I coded this prior to my start of using Evernote.


Free ArcGIS Tools – EasyCalculate

November 25, 2008

Someone sent me a link to these tools and expressions.  Although the company sells software and extensions for ArcGIS, they also some free tools.  Of particular interest is the EasyCalculate section (See Summary below).  I did not realize the true power of the field calculator until I had tested some of the provided expressions.  It is truly amazing what can be done just by running the field calculator.  If you have not had a chance I would recommend taking a look at the calculations and see what is available.

From the website:

EasyCalculate is a set of expressions currently 110 for the ArcGIS field calculator. The expressions can be loaded in the Field Calculator and when executed calculate some spatial characteristics of the features, edit the shapes, add records to a target layer, draw graphics etc.

via Free ArcGIS Tools