Wednesday, November 28, 2007

Unrecongnizable USB Drive

Ever plug in a USB Device, but you cannot access it using Windows Explorer? Yes, your USB may be a POS, or there may be another problem. It seems that Windows XP cannot map your USB drive to a drive letter if the first available drive letter after your system drives is mapped to a network drive. For example, if you have a C, D, and E local drive, and you have F mapped to a network drive, the USB device wont automatically map to G.

This can be fixed by performing the following steps, taken from this MS KB article:

KB

WORKAROUND
To prevent this issue from occurring, when you map a network drive, assign the highest available drive letter to the mapped network drive.

To work around this issue if the new volume appears in Disk Management, specify a different drive letter for the new device or volume. To do this, follow these steps:
1. Right-click My Computer, and then click Manage.
2. Under Computer Management (Local), click Disk Management.
3. In the list of drives in the right pane, right-click the new drive and then click Change Drive Letter and Path(s).
4. Click Change, and in the drop-down box, select a drive letter for the new drive that is not assigned to a mapped network drive.
5. Click OK, and then click OK again.
Both the mapped network drives and the recently installed drive appear in Windows Explorer.


Works like a charm, this is pretty obnoxious...

Sunday, November 4, 2007

Custom Advanced Search Task with Maptips Control





Custom AGS Search Tool



For the past couple months, weve been working on a project
to develop a custom search task for the web mapping application. For this
project, we were able to use some ESRI code as a starting point, but it really
wasnt refined enough for our requirements. Some key components that were
required include:



Dropdown searches with the ability
to add and remove search criteria



Custom task results



Incorporating keyword search



Interacting with maptips through
the task results



The ability to control what fields
are searchable with a table in sql



NOTE-REMOVED CODE DUE TO FORMATTING ISSUES, IF INTERESTED IN DETAILS EMAIL ME

The end of all of this work was a sweet search utility that
allows you to find exactly what you are looking for, generating customized
results, with the ability to interact with the maptips thru the search
results. The functionality is demonstrated in the following video:




advanced_search_with_maptips.wmv


This tool will be live at www.winemap.org in the near future at

WineMap Dot Org


 



 



Monday, July 9, 2007

Operation Aborted Hell

So I have my customized AGS EditorTask application that uses the google api for geocoding... When I moved my app from my development machine to the production server, some users were experiencing the well known "Operation Aborted" error. The most painful part of this error was that only some users were experiencing this error, and without any frequency.

After googling this error, several results came up. After reading through these errors, apparently this is caused by IE7 trying to modify DOM elements before the page had finished writing them, as described here


This could have been caused by several things my code was doing:

1) Executing javascript on body load that modifies the appearance of the EditorTask control

2) Initializing the Google Maps API

3) Some random ESRI javascript/other crap that is hidden away somewhere

4) On the server side page load event, I am completely clearing out the session variable when the page is completely reloaded. This is unlikely to cause the error, but a potential cause nonetheless. People coding with the editortask control should notice that the application will crash if the user refreshes the page, or returns to the page without closing the editortask control with the error `cannot change versions outside the edit session`.

At this point I began the painstaking process of isolating the error. I was unable to duplicate the error on my dev machine, but I was able to gain access to my friend's computer which threw the error consistently.

To start, I tried the following:

Move the GMAPs api tags after the body element
Insert defer="defer" into the script tags (putting this in the tag with the key breaks the page) per instructions on this site:
Internet Explorer cannot open the Internet site, Operation aborted "Google Map API error"

Then I read a great site that talks about executing javascript at the window.onload event instead of body.onload. So I use his wrapper code, thinking ok everything should be cool now, and surprise surprise the error still occurs.

window.onload (again)

The next thing I try is to take out all the javascript that is running on the body.load event, and run it during a client callback on the server side. As a note here, you cannot call an existing function during a callback- the application will freeze. So you have to re-write the contents of the function you want to call, and put it into a string, for example:

Dim jsfunctionq As String = "alert('BUFU');"
Dim crq As CallbackResult = New CallbackResult(Nothing, Nothing, "javascript", jsfunctionq)
Map1.CallbackResults.Add(crq)

Didnt work either.

Next I try removing the code that is clearing the Session variable (using Session.Clear()). Some interesting things to keep in mind if you do this are that the editortask will appear by itself automatically when the page loads. After looking through all the Session variables, I notice a few specific to the ESRI crap, including a variable that controls the Editortask's visibility. However, if I set

Session("/editormodule/editpage.aspxTaskManager1$EditorTask1_visible") = "false"

then the code crashes. So I am stuck with having the tool open automatically when the page loads, and then modifying it as soon as possible via javascript or on the first callback. One funny thing was throughout the whole project, I had been trying to modify the appearance of the editortask, and none of the settings were changing (ie colors etc). Finally figured out that in the web.config file there is a tag



that stored a attribute setting the style to match the predefined ESRI style I had unknowingly chosen. Clearing out the Session removed the style settings, used my settings within the aspx code, and enabled the cool effect of making the panels transparent when being dragged.

None of these changes have any affect on the Op Aborted Error...

At this point I am pretty pissed... 15 hours into the problem. The only thing to do is to rip all my javascript out, and add back in one piece at a time. I then went through and added one script tag/function at a time, testing the resulting page (open browser, run through wizard, refresh, run through wizard, close browser, repeat). This is extremely f*kd- I add one thing in, it works. Add another, it breaks... I rewrite and simplify my javascript (the project has evolved, so there was some extra logic in there but nothing that should break anything). I shuffle crap around and test test test.

FINALLY get it to a point where the error is not throwing on a clean browser instance. I can open the page, go through the editing wizard, repeat as many times as I want. I can repeat this time and again. At this point I call the error fixed, and get really drunk..

The next morning, I am f*king around on the site, playing with how my application interacts with a whole framework for users entering information about their winery, tasting room, vineyards at www.WineMap.org

I go to the main site, login to my profile, go through the wizard, click my link to return to the main site, and try to enter my page again, and happy day! the error reappears. I instantly realize the step I did not test during this hell was returning to the profile pages and then restarting the editor module. At this point I am 100% sure the application works on a clean browser instance, the problem is occurring after a user is returning to my page for the second time. This MUST be a configuration issue- makes no sense that it runs clean and then breaks when you go out and then return to the page.

Digging around IIS, and the virtual directory properties, I see that there is a setting in the ASP.NET configuration page in the "State Management" tab, called "Cookieless Mode". After checking around I determined that this setting determines how, when a browser tries to connect to a virtual directory, to assign a session to that user with cookies or without. Because my page works fine until you leave and come back, I deduced that this was the spot to change... So I changed the value from "UseCookies" to "UseURI", and started testing. The first thing I noticed was that the URL of the site changed- now, a long code(hexadecimal?) is added into the URL, for example going from:

http://gis.winemap.org/editormodule/editpage.aspx?h=800&w=1280&layers=wine,tasting,vine,&orgid=zzz&userid=&name=zzz&returnUrl=http%3a%2f%2fdirectory.winemap.org%2fDefault.aspx%3fTabId%zzz

to:
http://gis.winemap.org/editormodule/(S(iwzmayirkd4key45o0pps555))/editpage.aspx?h=800&w=1280&layers=wine,tasting,vine,&orgid=zzz&userid=&name=zzz&returnUrl=http%3a%2f%2fdirectory.winemap.org%2fDefault.aspx%3fTabId%zzz

Every time I go to the page, the code changes. The application thinks it is a new session, so it doesn't try to reload whatever is making it crash. And the error disappears! I haven't been able to reproduce after extensive testing. It is quite possible this was the problem this whole time (30+ hours)... Probably my fault I didn't check this setting... I didn't know it was there.

I guess the lesson to take from this is that if your sh!t is working on your dev machine, and you get some crazy error on another machine, start with configuration settings, not your code. Your code may well be good, or you would likely be crashing your browser on your dev machine also.

That and F*ck Microsoft and their sh!tty browser....

Hope this helps someone out there!

Saturday, June 16, 2007

Updated Editor Module

Made some more changes to the Editor Task module... We removed the main panel completely, as it wasn't really compatible with the wizard approach we were looking for. ESRI makes it a little difficult to accomplish this, because little of the HTML that is auto-written has an id tag, so you have to use something like

var tr = document.getElementsByTagName('td');

The annoying part is that the tag you want to change is not always at the same index location in the resulting array. So you have to do this to make sure you change the correct tag. For whatever reason the tags had different indexes depending which machine we used, development or production server.

if (tr[16].innerText == 'Edit: ') {
tr[16].innerText = '';
// alert(tr[16].innerText);
}

Also, depending on the browser you are using - we test for Mozilla, IE6 & 7, you have to use different techniques to alter the HTML. For mozilla, you can use the InnerHTML attribute. For both IEs you have to use the InnerText attribute. This may be limited to working with table/tr/td elements. There are also some types of elements that each browser wont change, so keep an eye out for that also.

Changing the button images was relatively easy. You can just change the hard-coded paths to the new .gif files. One problem though was that because we were basically ripping the select, save, and delete buttons from where they are originally and re-writing them in the new spot at the callback, there was some trickeyness with the new images getting replaced when the user did a mouseover/out on our button. To handle this, I just removed the appropriate javascript function that was screwing up a particular image from the corresponding td tag.

Here is a screenshot of the Editor. Looks pretty sweet IMO!

Wednesday, May 23, 2007

Updated Editor Attribute Panel Video

Checkit

Video Link

Tuesday, May 22, 2007

Brief Notes and code snippets for Attribute Panel

Ive had a few request for more info on how the attribute panel works. Only have time to give some quick pointers at the moment, but here they are.

1. In the EditorPanelsCreated sub, write code to add new panel

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Dim panel As New MyPanel("Editing Wizard Instructions", EditorTask1, "myPanelID")

e.EditorPanels.Insert(0, panel)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2. In your App_code folder, add an attribute panel class. In the writer sub, create an empty div that will hold your HTML for the panel

Imports Microsoft.VisualBasic

Public Class MyPanel

Inherits ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorPanel

Public Sub New(ByVal title As String, ByVal task As ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorTask, ByVal ID As String)
MyBase.New(title, task, ID)

End Sub

Protected Overloads Function Init(ByVal cur As String) As Boolean

End Function 'Init

Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
writer.Write("
")
writer.Write("
")

end sub

end class

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

3. You can dynamically change the content of this div using the client callback functionality. I change the content when a callback has triggered, for example when I hit the next button, or save attributes, or whatever. I also change the content when the _PostToolExecute event is triggered, like when a user selects a feature. This way I can populate the attributes for a feature that has already been entered.

First write the output HTML into a string
dim txt as string = "BLAHBLAHBLAHBLAH" 'put formatted html here.
A note here~ it is a pain to get the HTML formatted into a string. The easy way is to have a seperate page for your attribute panel in your visual studio project, set it up using asp, run the page, and copy the rendered html. You then paste the rendered html, replace " with """ & ", move everything to one line, and add quotation marks around it.

You then trigger the update to your div with this code:

Dim o() As Object = New Object(0) {} = txt
Dim crn2 As CallbackResult = New CallbackResult("div", "innercontent2", "innercontent", o)
Map1.CallbackResults.Add(crn2)

This will change the contents of your innercontent2 div to be whatever you put in the o(0) object.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

That is basically it. The hard part is tracking which layer you are working on, and changing the content based on that. Also populating the attributes for an existing feature is a pain too.

I would recommend keeping it as simple as possible.

One thing to keep in mind is I have to trigger the attribute save with a button click. You dont have to do a button click with the out of the box attribute panel... but then again that attribute panel sucks, or you would'nt be reading this. Still need to figure out how to make the updates automatic. Attribute updates done using a feature cursor:
Dim featLayer As ESRI.ArcGIS.Carto.IFeatureLayer = serverContext.CreateObject("esriCarto.FeatureLayer")
featLayer = mapServerObj.Layer(mapServer.DefaultMapName, 2)
Dim cursor As IFeatureCursor = featLayer.FeatureClass.GetFeatures(fidset, False)
dim feature as ifeature
feature = cursor.NextFeature()
While Not (feature Is Nothing)
Dim pFields As IFields = feature.Fields
etc etc standard update query

The button is part of the html I write. Does a standard call to a javascript function:

function callback1() {
var message = 'Here are my event args for the server code, ie updateattributes:value1;value2...';
var context = 'Map1';
<%=sCallBackFunctionInvocation%>

}

This gets handled in the RaiseCallback event...

Hope this helps, it should get you going, but you still have lots of work to do. Keep your head up!

Saturday, May 12, 2007

Updated Video- Custom Editor Attribute Panels

Here's an updated video of an custom attribute panel- this has many textboxes, dropdowns, checkboxes, radio buttons, and a cool hours of operation tool:

http://www.fileden.com/files/2007/2/27/829259/editor_new_attribute_panels.wmv

Enjoy!

Thursday, May 10, 2007

AGS KML Network Links

I was testing the KML capabilities of ArcGIS Server, and found a bug. Here is my tech support request:

I am having issues with publishing kml network links using arcgis
server workgroup standard. There is either a bug or a limitation
that I ran into and isolated (after several hours of work).

The issue is that I can only sucessfully publish mxds with kml
capabilities, and read the network links in google earth, if all
layers within the mxd have fields that are 255 characters or less.

If I have a personal geodatabase feature class, or an sde feature
class, with a empty string field that is longer than 255
characters, the layer will show up in the layer list in google
earth but the layer will not display any features. If I populate
this field with data, I get the attached "buffer overrun" error
messages from ArcSOC.exe.




My need is to be able to have a long string field, that I can use
for the KML Snippet attribute (that gets displayed in the attribute
balloon). This string attribute needs to hold more data than 255
characters, which is extremely limiting. I would like to store
approx 2-3 thousand characters in this field... html formatting can
get long... Personal geodatabase and sde feature classes should
support this capability. I cannot find any such limitation in the
KML documentation from Google.

Please let me know if this is a bug, or a software limitation, how
to fix ASAP... Seems like it must be a bug, because 255 characters
wont cut it for most people.

The response from ESRI (after 10 days) was as follows:

I will be the analyst working with you on this incident. This issue you
are facing is related to a bug and the tracking number for reference is
#NIM008717. Unfortunately, at this point of time there is no workaround
for this. I have added this incident number (#xxxxx) to an existing
bug. You can check the status of the bug at any time either by calling
Support or contacting your Account Representative.

I am marking the incident as resolved.

Thanks for using ESRI Support!

So, the moral of the story is that if you want to use AGS to publish your GIS data to a network link to display in Google Earth, you cannot have any fields over 255 characters. If your KML Snippet field needs to have HTML inside, the HTML formatting sucks up most of your space. I was able to fit a short text feature description, and a hyperlink to a web page that contained more descriptive attributes. If you want decent popup balloon content, I would generate your KML with your own code (there are samples at arcscripts), or look into a product such as Arc2Earth.

Then again, maybe ESRI will get their act together on this at some point soon and save the trouble. For tens of thousands of dollars, this seems like a pretty big shortcoming.

Monday, April 23, 2007

EditorTask ToolsCreated, EditorPanelsCreated Events

Playing around with the EditorTask, and just wanted to note that it is only possible to access the Main panel (with the layer dropdown, select button, save etc) and the ExistingFeatureEditor panel (with the geometry tools) using the ToolsCreated Event. So you can add, remove, and reorder tools within those panels- But you cannot change the contents of the Create feature panel, or the attribute editor panel. It appears your only option for these is to use the EditorPanelsCreated event to completely remove these, and add additional panels as required.

For example:

Protected Sub EditorTask1_EditorPanelsCreated(ByVal sender As Object, ByVal e As ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorPanelsCreatedEventArgs) Handles EditorTask1.EditorPanelsCreated
'Occurs when the editor panels (create feature, edit feature, edit attribute) are created. Can be used to add a custom panel to the main EditorTask panel.

'Remove Existing Feature Edit Panel
If e.EditorPanels.Item(1).Title.Contains("Exist") Then
e.EditorPanels.Remove(e.EditorPanels.Item(1))
End If

'Add New Custom Panel Class with Appropriate Controls
Dim panel As New MyPanel("Wizard Commands", EditorTask1, "myPanelID", buttonvis)
e.EditorPanels.Insert(0, panel)
End Sub

Protected Sub EditorTask1_ToolsCreated(ByVal sender As Object, ByVal e As ToolsCreatedEventArgs) Handles EditorTask1.ToolsCreated
'Occurs when the tools in an existing toolbar, in an Editor panel, are created.
'Can be used to add a custom tool to an existing toolbar.

'find show vertices tool, xy tool by name and remove
Dim xxx As Integer = 0
'must use while instead of for because the count decreases when you remove a tool, causing index outside of array error
While xxx < count
If e.Toolbars.Item(0).ToolbarItems.Item(xxx).Name = "ShowVertex" Then
e.Toolbars.Item(0).ToolbarItems.Remove(e.Toolbars.Item(0).ToolbarItems.Find("ShowVertex"))
count -= 1
End If

If e.Toolbars.Item(0).ToolbarItems.Item(xxx).Name = "EnterXY" Then
e.Toolbars.Item(0).ToolbarItems.Remove(e.Toolbars.Item(0).ToolbarItems.Find("EnterXY"))
count -= 1
End If
xxx += 1
End While

End Sub

These subs, as well as a painful amount of javascript and work with Client Callbacks and some other stuff, results in the following Editor appearance:



Enjoy!

Thursday, April 19, 2007

ArcGIS Server EditorTask, and C# code converter

I was looking at the new EditorTask functionality included with ArcGIS Server Service Pack 2, and ran into a problem- I dont code C#, I can only read it. I taught myself vb 6 and then migrated to vb.net... All of the documentation samples for the EditorTask are in C#, so I started looking for a utility to convert the C# to VB, and found two sites:

http://authors.aspalliance.com/aldotnet/examples/translate.aspx

http://www.kamalpatel.net/ConvertCSharp2VB.aspx

Both sites allow the user to input C# code onto a form, hit a button, and the VB code is generated. The first site did give more accurate results- Here is some code (this sample inserts a new panel into the editor task control) and a description from the EditorTask control documentation from the EDN site: (http://edndoc.esri.com/arcobjects/9.2/NET_Server_Doc/developer/ADF/control_editortask.htm)

"
Adding Custom Editor Panels

The EditorPanelsCreated and SettingsPanelsCreated events can be handled to modify the panels shown in the main Editor panel and also in the associated Settings panel. Panels may be added, removed and reordered. To add a panel, create a subclass of EditorPanel or TooledEditorPanel and add it to the collection exposed in the event argument. TooledEditorPanel has a collection of toolbar items which can be populated by overriding the CreateToolbars() method. This class will fire the ToolsCreated on the EditorTask after this method returns. Here is a very simple example of a custom EditorPanel.

[C#]

public class MyPanel : EditorPanel
{
public MyPanel(string title, EditorTask task, string ID) : base(title, task, ID) { }

protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write("This is my custom panel");
}
}

By adding this class to the App_Code folder of the EditorTask web application, the custom panel can be added to the EditorTask with the following EditorPanelsCreated event handler code:

[C#]

protected void EditorTask1_EditorPanelsCreated(object sender, EditorPanelsCreatedEventArgs e)
{
MyPanel panel = new MyPanel("My Custom Panel", EditorTask1, "myPanelID");
e.EditorPanels.Insert(0, panel);
}
"

Using the first site, the code gets converted into VB, and then I added in the fully qualified name of the controls:

Public Class MyPanel
Inherits ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorPanel
Public Sub New(ByVal title As String, ByVal task As ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorTask, ByVal ID As String)
MyBase.New(title, task, ID)
End Sub

Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
writer.Write("This is my custom panel")
End Sub
End Class

I added this code to a new class in the App_data folder. Then I added a sub in the editor application to trigger the new panel to be added:

Protected Sub EditorTask1_SettingsPanelsCreated(ByVal sender As Object, ByVal e As ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorPanelsCreatedEventArgs) Handles EditorTask1.SettingsPanelsCreated
'Occurs when the settings panel is created (when the Settings link in the main EditorTask panel is clicked). Can be used to add a custom panel to the Settings panel.
Dim panel As New MyPanel("My Custom Settings Panel", EditorTask1, "myPanelID")
e.EditorPanels.Insert(0, panel)
End Sub

The screenshot below is an output of the resulting editor panel:



Enjoy :)

Thursday, April 5, 2007

MS Ajax and the 9.2 ADF

Bryan Baker wrote a great post on using the MS Ajax library to update ADF controls using client callbacks:

http://serverx.esri.com/ESRIBlogs/blogs/arcgisserver/archive/2007/04/02/Using-ASP.NET-AJAX-with-the-Web-ADF.aspx

Here is his sample in action:
http://serverz.esri.com/ajaxadfdemo/AjaxADFDemoCS.aspx

Definitely required reading, this will allow a developer to utilize the MS Ajax library to create custom MS AJAX controls, such as custom TOC menus etc, that affect the map and other ADF controls.

One issue that was raised is that if you use an Overview Map control with the MS Ajax library, the partial postback takes very(to the point that it is unacceptable for a user) long to occur. Im going to investigate this, and ask Bryan if there is a workaround.

Bryan Baker for President!

Thursday, March 8, 2007

Find Polygon Attributes by Intersecting features



Hey yall-

Made a new ArcView tool you might want to have a look at... Included all source files in the link below.

The purpose was to be able to go through each polygon feature in a layer, get all the polygons in the same layer that intersect that feature (optionally using a buffer of the input feature), then write a specific attribute for each of the intersecting polygons to a field in the source record in a comma delimited list.

Works for shapefiles only as of now.

Lemme know if anyone has questions or comments.

Here is the core code:

Private Sub btnOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOk.Click
Dim bufferd As Double
If txtDistance.Text <> "" Then
If IsNumeric(txtDistance.Text) Then
bufferd = CDbl(txtDistance.Text)
Else
MsgBox("Search Distance Must Be Numeric!")
Exit Sub
End If
End If

If cboAttribute.Text = "" Or cboOutput.Text = "" Then
MsgBox("ID, Attribute and Output Fields Are Required")
Exit Sub
End If


'perform spatial query using the geometry buffered to the number in the textbox
'read the returned attribute for each match
'add attribute value to string
'once looped, put the string in the original shapes output attribute field
'get next feature in the table

Dim pMxDoc As IMxDocument
pMxDoc = m_pApp.Document

Dim pMap As IMap
pMap = pMxDoc.FocusMap

Dim pSelLayer As ILayer
pSelLayer = pMap.Layer(0)

Dim pSelFeatureLayer As IFeatureLayer
pSelFeatureLayer = pSelLayer


Dim pFeatSel As IFeatureSelection
pFeatSel = pSelLayer
Dim y As Integer = 0

Dim ptable As ITable = pSelFeatureLayer.FeatureClass
Dim pfeatclass As IFeatureClass
pfeatclass = pSelFeatureLayer.FeatureClass

txttotal.Text = pSelFeatureLayer.FeatureClass.FeatureCount(Nothing).ToString

Dim pDsFc As IDataset
Dim pWs As IWorkspace
pDsFc = pfeatclass
pWs = pDsFc.Workspace
'Dim searchfield As String

If (pWs.Type.ToString = "esriLocalDatabaseWorkspace") Then
'searchfield = "Personnel Geodatabase"
' searchfield = "OBJECTID"
MsgBox("Shapefiles Only")
Exit Sub
ElseIf (pWs.Type.ToString = "esriRemoteDatabaseWorkspace") Then
'searchfield = "ArcSDE Geodatabase"
' searchfield = "OBJECTID"
MsgBox("Shapefiles Only")
Exit Sub
'MsgBox("Must be in edit mode for SDE geodatabase!")
ElseIf (pWs.Type.ToString = "esriFileSystemWorkspace") Then
' searchfield = "FID"
Else

End If

Dim i As Integer = 0

Dim pFlds As IFields
pFlds = pfeatclass.Fields
Dim valuesstring As String = ""
Dim currentvalue As String = ""
Dim aFld As Long
aFld = pFlds.FindField(cboAttribute.Text.ToString)
Dim oFld As Long
oFld = pFlds.FindField(cboOutput.Text.ToString)
'Dim iFld As Long
'iFld = pFlds.FindField(cboID.Text.ToString)

If pFlds.Field(oFld).Type <> esriFieldType.esriFieldTypeString Then
MsgBox("Output Field Must Be a String")
Exit Sub
End If

Dim pfeatcursor As IFeatureCursor
' pfeatcursor = pfeatclass.Update(pquery, False)
pfeatcursor = pfeatclass.Update(Nothing, False)

' Do
Dim pfeat As IFeature
pfeat = pfeatcursor.NextFeature
Dim currentattvalue As String = ""

While Not pfeat Is Nothing
currentattvalue = pfeat.Value(aFld).ToString()
Dim squery As ISpatialFilter
squery = New SpatialFilter
Dim pselGeometry As IGeometry
pselGeometry = pfeat.Shape

If txtDistance.Text <> "" Then
Dim ptopo As ITopologicalOperator
Dim pgeom As IGeometry
Dim pgeomcoll As IGeometryCollection
pgeomcoll = New GeometryBag
pgeomcoll.AddGeometry(pfeat.Shape)
ptopo = pgeomcoll
pgeom = ptopo.Buffer(bufferd)
With squery
.Geometry = pgeom
.GeometryField = "SHAPE"
.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects
End With

Else
With squery
.Geometry = pselGeometry
.GeometryField = "SHAPE"
.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects
End With
End If

Dim pAdjFeatureCursor As IFeatureCursor
pAdjFeatureCursor = pfeatclass.Search(squery, True)

Dim rfeat As IFeature
rfeat = pAdjFeatureCursor.NextFeature
'Dim currentattvalue As String = rfeat.Value(aFld).ToString()
While Not rfeat Is Nothing

currentvalue = rfeat.Value(aFld).ToString()

If currentvalue.ToString <> currentattvalue.ToString Then

If valuesstring = "" Then
valuesstring = currentvalue
Else
valuesstring = currentvalue & "," & valuesstring
End If
End If
rfeat = pAdjFeatureCursor.NextFeature
'Loop While Not pAdjFeatureCursor.NextFeature Is Nothing
End While
pfeat.Value(oFld) = valuesstring
pfeatcursor.UpdateFeature(pfeat)
i += 1
txtcurrent.Text = i.ToString
'Loop Until i = pSelFeatureLayer.FeatureClass.FeatureCount(Nothing)
'Loop Until pfeatcursor.NextFeature Is Nothing
pfeat = pfeatcursor.NextFeature
'pfeatcursor.Flush()
valuesstring = ""
currentvalue = ""
End While
end sub



download link:
http://arcscripts.esri.com/details.asp?dbid=14973

Enjoy!

Update-

After doing some testing, it seems to be running about 1 record per second. So, if you have 50,000 polygons in your layer, like I do, dont sit at your machine waiting for it to finish. This is probably because I am looping thru each feature using a queryfilter, and I should be using a feature cursor. Ill probably change this at some point...

Update2- Fixed a couple small issues and the setup program, now runs a little faster. Need to do more research on improving performance.

Download at:
http://arcscripts.esri.com/details.asp?dbid=14973

Tuesday, February 27, 2007

Export Gridview contents to text file

So I have a asp gridview with a bunch of records that I want to export to a text file so I can bring it into Excel, Access, or any other app... You could use this method to write your own KML export tool as well, as long as you have x,y data in your gridview.

To accomplish this,

1. Write records to temp text file using StreamWriter
2. Force the file download dialog box.

Here is the code:

Protected Sub btnexporttext_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnexporttext.Click
'write selected records to text file in temp folder
Dim datecode As String = Replace(Replace(Replace(Trim(Date.Now), ":", ""), "/", ""), " ", "")
Dim FILENAME As String = "c:/temp/export/" & datecode & ".txt"
'makes a textfilename with the current datetime without spaces or slashes or :s
Dim sw As StreamWriter
sw = File.CreateText(FILENAME)
sw.WriteLine("Header Line for text file")
Dim stradd As String
For index As Integer = 0 To ResultsGridView.Rows.Count - 1
Dim allstring As String = ""
Dim gvr2 As GridViewRow = ResultsGridView.Rows.Item(index)
Dim j As Integer = 0
'write the row data for each record in gridview
For j = 0 To gvr2.Cells.Count - 1
stradd = gvr2.Cells.Item(j).Text
If allstring <> "" Then
allstring = allstring & "," & stradd
Else
allstring = stradd
End If

Next
'End If
sw.WriteLine(allstring)
Next
sw.Close()

'prompt the user to download the text file
updatelink(FILENAME)


End Sub

Public Function updatelink(ByVal FILENAME As String)
Dim path As Path
Dim fullpath = path.GetFullPath(FILENAME)
Dim name = path.GetFileName(FILENAME)
Dim ext = path.GetExtension(FILENAME)
Dim type As String = ""

Select Case ext
Case ".htm", ".html"
Type = "text/HTML"
Case ".txt"
type = "text/plain"
Case ".kml"
type = "text/plain"
Case ".doc", ".rtf"
type = "Application/msword"
Case ".csv", ".xls"
Type = "Application/x-msexcel"
Case Else
Type = "text/plain"

End Select
Response.ContentType = Type
Response.WriteFile(FILENAME)
Response.AppendHeader("content-disposition", "attachment; filename=" & name)
Response.End()
End Function


Pretty simple method for creating a text file from a gridview. I plan on using this to do KML export functions for various mashup projects Im working on.

ArcGIS Server 9.2 Maptips

Playing around with maptips with Js help... Pretty cool feature, though limited to one point layer per Web App. Made a quick video showing some capabilities:


http://www.fileden.com/files/2007/2/27/829259/maptips.wmv

The yahoo search was pretty simple, just did search.yahoo.com/bin/search?p= and added whatever the search string was at the end. Heres the maptips code link:


http://www.fileden.com/files/2007/2/27/829259/code.txt

Had a weird error popping up when trying to label the maptip body with the shape_area field, said input string was not in correct format, and the map wouldnt draw. Removing this field from the map tip fixed it. Not sure if maptips only support string fields

9.2 and Concurrent Use license with non-usb dongle


We have had 3 licenses of ArcInfo, with the non-usb dongles. After upgrading to 9.2, whenever I do a Remote Desktop onto one of the workstations with the dongle, I get the following popup:




No matter what I try, I cannot use ArcGIS over a remote desktop because of this problem.


Called ESRI and they told me it was a defective dongle, which makes absolutely no sense because it was working perfectly before, and breaks immediately after doing a remote desktop, so I think it is probably a software issue. In any case they told me to send the offending dongle in, and it was replaced by a usb dongle, and now everything works great! In the mean time, you cant use remote desktop, and when you go back to the workstation that had the error you must restart the server and reread the license file using the license manager tools to run ArcGIS.


So, if you are having these problems, just tell ESRI the dongle is defective and theyll send you a new one- not really worth arguing with tech support about how illogical their reasoning is.

Friday, February 23, 2007

Good ASP & SQL & Mozilla Migration Sites..

Reference site for SQL Syntax in 20 formats for all major dbs

http://www.connectionstrings.com/

Configuring an ASP.NET 2.0 Application to Work with Microsoft SQL Server 2000 or SQL Server 2005

http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=395

ASP.NET and Mozilla

http://www.agileprogrammer.com/dotnetguy/archive/2003/02/03/4512.aspx

Client-Side Validation in Downlevel Browsers

http://aspnet.4guysfromrolla.com/articles/051204-1.aspx

ASP.NET Image Manipulation Examples: Adding, Zooming, Enlarging

http://www.codeproject.com/aspnet/ASPImaging1.asp

State Management in ASP.NET...

http://www.dotnetjohn.com/articles.aspx?articleid=32

Making an UpdatePanel update from Javascript (trigger a postback)

http://forums.asp.net/1397409/ShowThread.aspx

Migrate apps from Internet Explorer to Mozilla

http://www-128.ibm.com/developerworks/web/library/wa-ie2mozgd/

The top 10 mistakes when using AJAX

http://dotnetslackers.com/Ajax/re-42427_The_top_10_mistakes_when_using_AJAX.aspx

ASP.NET Client Callback feature

2 Good articles about Client Callback(running server side code thru javascript using XmlHTTP), the ajax method you will use for the Web Application for ArcGIS Server/ArcIMS

http://dotnetjunkies.com/Tutorial/E80EC96F-1C32-4855-85AE-9E30EECF13D7.dcik

http://www.codeproject.com/useritems/ClientCallback.asp

ArcGIS Server Development Blog- Using the Callback control framework
http://serverx.esri.com/ESRIBlogs/blogs/arcgisserver/archive/2006/12/18/Using-the-Callback-control-framework.aspx


KEY ESRI site on creating custom tools and commands, and discusses the client callback clearly.. Identifies exactly what you can modify using the client callback, and how- serversiiide and clientsiiide. Also explains what the behind the scenes javascript is doing:
http://edndoc.esri.com/arcobjects/9.2/NET_Server_Doc/developer/ADF/custom_tools_commands.htm

Select Distinct in ArcGIS




Select Distinct Tool for ArcGIS. This tool selects records from a feature class based on distinct field values. There is an order by option as well. Wrote this tool because ArcGIS doesnt support the select distinct statement using the Jet SQL provider, and it is super annoying to have to export a table to Access, do your select disinct statement, and then bring the table back into ArcMap to do your analysis.

I will add a link to download the source at some point , ask me if you need it and I can hook you up


Doesnt completely remove the need for a SQL tool, but its a start. Enjoy!
Updated- Here is the link to download this tool. Add as you would a normal ArcGIS .dll, through the customize tab, add from file:

If anyone is interested in the source code leave a comment below and Ill throw it up.
http://www.fileden.com/files/2007/2/27/829259/prjSelectDistinct.zip

Select Query MySQL from ASP.net w/ vb

1. go to MySQL.com and get the connectors
2. add reference to asp project
3. add Imports MySql.Data.MySqlClient to top of vb code

4. Write SQL query- can be a select, update, or anything

Dim strquery As String = "select fieldname from `tablename` where fieldname=""" & txtusername.text &amp; """;"

Note- beware the """s. Will explain these when I have time...

5. Write execute query function:

Private Function GetQueryresult(ByVal strQuery As String) As String
Try
'intialize variable
Getvalue = ""
Dim connectionString As String = "server=servername;database=dbname;port=3306;uid=ODBC;" 'password=password"
Dim connection As New MySqlConnection(connectionString)
Dim command As New MySqlCommand(strQuery, connection)
connection.Open()
Dim reader As MySqlDataReader = command.ExecuteReader()
'make sure rows were returned
If reader.HasRows Then
' Call Read before accessing data.
While reader.Read()
'Depending on how many fields your SQL query returns, adjust what reader(x) values you want to pull out.
If reader(0) IsNot DBNull.Value Then
Getvalue = reader(0).ToString
End If
End While
End If
' Call Close when done reading.
reader.Close()
'close the connection
connection.Close()
connection.Dispose()
'clean up
reader = Nothing
connection = Nothing
'Return GetCBSA
Catch ex As MySql.Data.MySqlClient.MySqlException
Response.Write(ex.Message)
End Try
End Function




if you arent doing a select, and doing an update, you can use:

If reader2.RecordsAffected <> 0 Then
End If
do make sure your query changed some rows.

Microsoft Ajax library and 9.2 ESRI Web Application

What ESRI had to say about the AJAX problem....

The Map and other Web ADF 9.2 controls are not supported with the UpdatePanel and other container-type controls in the ASP.NET AJAX library. Since ASP.NET AJAX went final after our 9.2, there was no way we could ensure compatibility with our version. We've been investigating and see that the page handling mechanism is different in the AJAX library (which uses "partial postbacks") from the one in our controls (which uses the ASP.NET 2.0 client callback mechanism). We've had lots of questions on this, but there's not much we could have done due to the timing of releases.

Our controls should work OK when on the same page as the MS AJAX controls, as long as they're not being contained by them. That's not official support, but we've found that it works.

We plan on supporting the MS AJAX controls fully by our next major release (currently numbered 9.3).

The moral of the story is if you have an 9.1 IMS Ajax app that uses update panels, you are SOL. You will be able to use the MS Ajax library at 9.3, but who wants to wait that long...

ArcGIS Server Development Blog

http://blogs.esri.com/Dev/blogs/arcgisserver/

Arcview 3x field calculation fun

[shape].getx get x coordinate of point feature
[shape].returncenter.getx get x coordinate of centroid of poly feature/midpoint of line feature

when you do the centroid, some points will be generated outside the poly boundary. So, once you create an event theme select by location the points not intersecting the polys, and manually move them in.

blah.asstring convert number to string
blah.asnumber convert string to number
blah.astokens("split expression").get(0)
the split expression is what you break the string by. for get, you choose the value in the split string array, which starts at 0. You will get a syntax error when you try to get a value from the array that doesnt exist, usually due to null values.

So,
blah = "I love GWB"
blah.astokens(" ").get(1) = "love"

blah.count returns the number of characters in a string

enjoy!

MapWindow GIS

http://www.mapwindow.org/

Open-Source GIS viewer, developer API

Mapperz - The Map and GIS News Source Blog

http://mapperz.blogspot.com/

great site with lots of cool GIS apps

Land Measurement Conversion Guide

http://www.ghostseekers.com/Conversions.htm

Very usefull site for area conversion factors. How many square feet in a square mile again?

Implementing a Slider control with the Atlas framework

http://aspadvice.com/blogs/garbin/archive/2006/06/30/18988.aspx

SQL Server licensing

http://www.developer.com/db/article.php/3502746

State Plane and UTM Projection list

http://home.comcast.net/~rickking04/gis/spc.htm

System Design Strategies- Enterprise GIS

http://www.esri.com/library/whitepapers/pdfs/sysdesig.pdf

Guide to setting up your enterprise GIS, lists different configurations, key considerations you need to make to setup a successfull enterprise GIS

SIC/NAICS translation

http://www.census.gov/epcd/www/naicstab.htm#download

HowTo: Cannot connect to ArcSDE via ArcIMS Author

http://support.esri.com/index.cfm?fa=knowledgebase.techarticles.articleShow&d=26238


also, you must add the sde_home environment variable:

1. You must add SDEHOME to your list of environment variables. The value should refer to the ArcIMS server directory: /server. In the PATH enfironment variable, add %SDEHOME%/bin. 2. Then, you must restart ArcIMS Monitor and ArcIMS Application Server.

asp.net treeview

http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.treeview.aspx

Install: Install IIS with Tomcat 5.5.17 using J2SE JDK 5.0 Update 6 for ArcIMS 9.2 on Windows

Install: Install IIS with Tomcat 5.5.17 using J2SE JDK 5.0 Update 6 for ArcIMS 9.2 on Windows

http://support.esri.com/index.cfm?fa=knowledgebase.techArticles.articleShow&d=31252

embedded media html generator

http://cit.ucsf.edu/embedmedia/step1.php

ASP.net fire onclick event in javascript

http://forums.asp.net/1461136/ShowThread.aspx

Census Metro Area Links

Current Lists of Metropolitan and Micropolitan Statistical Areas and Definitions
http://www.census.gov/population/www/estimates/metrodef.html

Ranking Tables
http://www.census.gov/population/www/cen2000/phc-t29.html

Census 2000 Summary File 1 ASCII text data files
http://www.census.gov/support/SF1ASCII.html#Microsoft%20Access%20procedures

Census FTP site
http://www2.census.gov/census_2000/datasets/Summary_File_3/0_National/

Data Set list from American Fact Finder
http://factfinder.census.gov/servlet/DatasetMainPageServlet?_lang=en&_ts=178029527163&_ds_name=DEC_2000_SF3_U&_program=

asp.net force file download

http://aspalliance.com/259

Use this information to force the file download box from your asp page. Usefull for sending text files or anything

asp.net gridview checkboxes

http://aspnet.4guysfromrolla.com/articles/052406-1.aspx

vb.net create text file

http://www.extaspx.com/files/create.aspx

vb.net convert text file to XML

http://www.devx.com/getHelpOn/10MinuteSolution/20356

VB.Net Functions

Good link about formatting strings, numbers, dates

http://www.seattlecentral.org/faculty/ymoh/mic110vb/function_list.htm