19 December, 2007

Getting the map to zoom to a feature in ESRI webADF is a chore

ESRI can be as frustrating as it can get. My lack of experience with ASP.NET 2.0/3.0 combined with the vast differences betwen the desktop functionality of ArcGIS and the web functionality of ArcIMS / WebADF is giving me gray hair faster then my kids every could dream of doing.

I have a .NET pretty much out of the box site - that is, I went into "ArcIMS Web Manager for the Microsoft .NET Framework" and setup a new site. I have some queries that had to be customized, and I ran out of time trying to get the TaskResults panel to display the query results (I'll post about that experience when I have a little more time), so I put them in an HTML table in their own panel. I have a hyperlink in the table which, when clicked, should zoom to that feature on the map. I have looked and, and am using some code from this thread how can i zoom to my selected features - only it isn't working fully.

// This is the method to zoom to the feature, param 'key' is the objectid of the feature, and the param 'layer' is the name of the feature layer
protected void ZoomToFeature(string key, string layer)
{
ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality mf;
ESRI.ArcGIS.ADF.IMS.Carto.MapView mv;
mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality)Map1.GetFunctionality(0);
mv = mf.MapView;
ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer queryLayer;
queryLayer = (FeatureLayer)mv.Layers.FindByName(layer);
Filter queryFilter = new Filter();
QueryParameters queryParams = new QueryParameters(queryFilter);
queryFilter.WhereExpression = "ObjectID = '" + key + "'";
queryFilter.Tolerance = 20;
queryFilter.ToleranceUnits = BufferUnits.Meters;
queryParams.ReturnGeometries = true;
queryParams.ReturnGlobalEnvelope = true;
ESRI.ArcGIS.ADF.IMS.Display.Symbol.FeatureSymbol fs = new ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleFillSymbol(System.Drawing.Color.White, System.Drawing.Color.Red, ESRI.ArcGIS.ADF.IMS.Display.Symbol.PolygonFillType.Solid);
ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer sr = new ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer(fs);
queryLayer.Visible = true;
FeatureTable ft = queryLayer.Query(queryParams);
if (ft.Rows.Count > 0)
{
ESRI.ArcGIS.ADF.IMS.Geometry.Geometry featureGeom = (ESRI.ArcGIS.ADF.IMS.Geometry.Geometry)ft.Rows[0]["#SHAPE#"];
ESRI.ArcGIS.ADF.Web.Geometry.Geometry adfGEom = ESRI.ArcGIS.ADF.Web.DataSources.IMS.Converter.ToADFGeometry(featureGeom);
ESRI.ArcGIS.ADF.Web.Geometry.Envelope adfEnv = ESRI.ArcGIS.ADF.Web.Geometry.Envelope.GetMinimumEnclosingEnvelope(adfGEom);
Map1.Extent = adfEnv;
}
Map1.Refresh();
}

// This is the code in RaiseCallbackEvent(string responseString) method which calls the ZoomToFeature method
this.ZoomToFeature(eventArg, layerArg);
response = Map1.CallbackResults.ToString();

I am getting new envelope for the feature, and I am setting the map extents to that envelope. I know this works because I put some dummy code in a Map1_ExtentsChanged event handler and checked to ensure the map extents were changed. Then I hit Map1.Refresh(); but the map does not change. I'm returning the Map1.CallBackResults.ToString();, but I'm ignorant of what to do with the results on the client side. The RaiseCallbackEvent method returns the 'response' string.


After playing around and doing some more searching with different keywords, I found this thread; The ESRI Map control does not refresh ..... which talks about client side map.redraw(); giving the following example:

var map = Maps['<%=Map1.ClientID %>'];
map.redraw();

I thought this would solve my problem and it almost-but-not-quite does. It does redraw the map (at least it looks like it does). But what I get is a completely blank map until I either zoom in or out. Then the map appears zoomed to roughly the correct location (depending on if I zoomed in or out to make it show up). Also works using the mouse wheel.




Technorati Tags: , , , ,

13 December, 2007

I might be going crazy

This is getting more annoying by the fracking minute!!!!!!!!

I need a search with cascading combo boxes. That is, when the search panel is displayed, combobox1 is populated, and combobox2 is empty. When the user selects a value from combobox1, it then populates combobox2 with values based on combobox1. Simple enough right? I get that population of the boxes down pat, no problems there. Doing through Callback and everything so the page doesn't have to refresh or anything like that.

Here is my problem. I need the results to display in the ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults results panel - we'll call it TaskResults1 (because that is what it is called when the site is created through the ESRI ArcIMS manager). I have tried just putting the code in there, but to no avail. I have tried creating a QueryAttributesTask and defaulting the values to what I need, and executing the task. Still no dice.

The values get put into the TaskResults1 results, but they just don't display. I can't figure why they don't display. I know they are there because after I perform the query, if I do a canned search, or use the MapIdentify feature (both of which add data to the TaskResults1 container), the results display with the new data.

I have tried finding help on the ESRI forums, but that is slow and I'm on a deadline.

I'll keep trying different wild and crazy stuff to see if I can figure it out.

Hmmmm....I wonder if I can refresh the TaskResults1 container from client side java?

29 October, 2007

ESRI 9.2 lacks info regarding VS 2005

ESRI seems to like to play things very close to the vest - so to speak. It is difficult to find information on just about anything dealing with creating class libraries in .NET to work with ArcGIS 9.2, even though they tout that 9.2 is built on the .NET Framework 2.0. So far, 99% of the articles, tutorials or help I have found have been for pre-9.2 and VS 2003 (Framework 1.1).

To be fair, I have found a few PDF files discussing 9.2 and .NET 2.0, but that is about it. They are actually PDFs made from PowerPoint slides that I'm certain were from some conference or demonstration given probably a year or so ago. But the walkthroughs they have on their site for VS 2003 - which seem exceptional in detail - are conspicuously missing for VS 2005. Everything I have found that deals with VS 2005 centers around the ArcGIS SDK which , of course, didn't get installed on my system along with ArcGIS 9.2, and is not downloadable from ESRI - which I find strange. It seems to me that other companies make their SDK readily available to developers, but ESRI doesn't seem to want to play that game for some reason.

So here I am, about a week into the project. I've got most of the VBA code translated, but I can't test any of it because I can't get the crap to work properly in ArcMap, and I can't find any decent assistance on the 'net. I guess I'm going to have to go be the quintessential n00b at the ESRI forums and beg for some sort of help. I hate doing that, but, like Duke Wayne said "A man's gotta do what a man's gotta do" ( or someone said that anyway ).

Here are the walkthrough/tutorials that I found pertaining to ESRI and .NET if anyone is interested/needs them:

The way I'm looking at this right now, It seems like it would be infinitely easier to create a desktop app and add the ArcMap to the app, instead of trying to create modules to run in ArcMap. But that isn't the way things are right now, so I've gotta do what they want done.




Technorati Tags: , , ,

17 October, 2007

Converting VBA code to .Net

My latest torture assignment is to convert legacy VBA code in ArcView applications to the .NET Framework. I haven't decided yet if I will convert them to VB .NET or C#, but since I like the C# language better, I will probably attempt to convert them to C#. But then, that somewhat depends on ArcView and how it handles these things. I haven't much (any) experience with ArcView so this is all new territory to me.

I did find a couple of somewhat useful links regarding converting VBA to .NET:

Converting Code from VBA to Visual Basic .NET

Convert VBA to VB .Net and C#

I found this VBA script which purports to export VBA modules, class modules and forms associated with an ArcView document to a separate folder. I haven't tried it yet as I won't get ArcView loaded until tomorrow. But I'm certainly going to give it a go. Anything to make things easier!

Export VBA Code

Okay, I don't know if the module will work at any rate because we can't compile the ArcView project here. I tapped another developer who actually has ArcView on her machine and we were going to run this module, but the guy who created this project has referenced some Autodesk stuff, which we don't have. So we have to export the modules,classes and forms one at a time. There are quite a few of them there.

I'll keep you posted on what entails with converting the VBA to C# code as this endeavor progresses.

13 September, 2007

Altering QueryString with Javascript

I'm making a grid in a legacy ASP application. That's right kids, ASP as in Active Server Pages. Old School stuff. None of the ultra-kewl .NET does it all for you stuff. Which, BTW, I really love because I can do so much more so much faster and better. But, alas, the client says "ASP only!" so, I go with ASP.

What they wanted to do was display their data in a grid. Yeah, right, ASP and datagrids, that is a rich one. So what I did was something almost, but not quite, completely different from a grid. I put their data in an HTML table with alternating row colors (hey, at least they think it's in a grid).

But of course, in any good datagrid, one must be able to click on the grid headers and VOILA! the grid sorts by the header clicked. This, I figured out, to do with JavaScript via the QueryString. The table is in an IFRAME, so the URL is never displayed to the end user. Doing this keeps the displayed URL fairly nice and neat. My original though, which seemed to work fairly well was just to cut the QueryString off at the desired parameter, and replace that parameter with the new one as such:

function reSortGrid(str)
{
var idx = location.href.indexOf('&sortby');
var loc = location.href.substring(0, idx);
loc = loc + '&sortby=' + str;
location.href = loc;
}
But then it occurred to me that if any parameters existed beyond the parameter I was replacing, they would be lost. No, what I really needed was to replace the existing sortby parameter within the actual string, while maintaining the rest of the string. This took a little thinking on my part, and what I came up with is:
function resortGrid(str)
{
var newQueryString = '';
if (location.href.indexOf('&sortby') > -1)
{
var locArray = new Array();
locArray = location.href.split('&');
for (i=0; iif (locArray[i].indexOf('sortby') > -1)
{
locArray[i] = "sortby=" + str;
// check to see if this is the start of the QueryString
if (locArray[i].indexOf('?') == -1)
newQueryString = newQueryString + '&' + locArray[i];
else
newQueryString = locArray[i];
}
}else{
newQueryString = location.href + '&sortby=' + str;
}
location.href = newQueryString;
}
So what I ended up with is a QueryString with the correct parameter changed, and the rest of the parameters intact.

14 August, 2007

Old School

This is becoming less of a blog about C# lately, and more of a blog about web programming in general. Hopefully I'll get back to C# sooner, rather than later.

Currently, my project is to enhance and expand an application written in ASP and...get this...Delphi!!!! And I have to tell you, after using C# and ASP.NET for the past 5 years, ASP SUCKS!! And not just a little, ASP sucks splendidly!

The current problem I fighting with is accessing an MS Access database via ASP. Getting there the first time isn't too bad, but when I try to get to it a second time, it blows up with that oh so informative error of:
Provider error '80004005'

Unspecified error

/Bridge/facilities/facmain.inc, line 13

Now, if Microsoft could any more ambiguous, I don't know how. It looks like I'm going to have make a separate DB connection for each RecordSet. This seems stupid and entirely inefficient, but as Duke Wayne said "A man's gotta do what a man's gotta do."

I am seriously not wanting to delve into that Delphi portion of the project, but that is coming soon enough.




Technorati Tags: , ,

01 August, 2007

Basic blog DB diagram

As promised, here is a basic diagram for my blog database. I still need to look at creating user role permissions (like can they post? can the delete comments? etc.). If you have any ideas, please through them my way!



Anyway, it is a start. I almost forgot to include a configuration table for the blog! This would have been a dire thing indeed without that!

Anyway, there you have it. If anyone is actually reading this stuff, please let me know what you think (I am no database guy), and offer suggestions!

Thanks.

Loading themes programmatically

I've made a little progress on the database diagram, but admittedly, that is not the most fun aspect of life. So I have been concentrating a little more the past couple of days on the front-end. I have been playing with themes, skins and styles.

One thing I wanted to be able to do was change the theme programmatically. I know this should be possible, but dog-gone if it wasn't a pain in the arse to figure out! After oodles of Google searches, I finally found this article at ASP Alliance. Good detail and explains a lot.

In a nutshell, the best way to programmatically change themes is to create a base class. I named mine BasePage.cs. This class inherits System.Web.UI.Page. Other pages (not the .master pages though) inherit this BasePage instead of System.Web.UI.Page. Wait, I think I'm getting a little ahead of myself. Let me back up a little.

One can programmatically set the page theme (this.Page.Theme), but only in the Page_PreInit(object sender,System.EventArgs e) method. However, this method is not valid in any .master file. Therefore, this method must be set in the actual .aspx files. There are two ways to do this, put the Page_PreInit method in each and every page file. This can cause issues if one wants to change the way they programmatically load themes (i.e., via cookies, session, use-select etc). The better way is to create a separate class which inherits from System.Web.UI.Page, and which all other .aspx classes inherit (instead of the System.Web.UI.Page class).

Okay, now that I have that out of the way, back to the meat. In the BasePage class I added a Page_PreInit method. In this method is where I set the theme.

void Page_PreInit(object sender, System.EventArgs e)
{
if (Session["Theme"] != null && Session["Theme"].ToString().Length > 0)
this.Page.Theme = Session["Theme"].ToString();
else
this.Page.Theme = "Default";
}

For testing, I created three themes, Default, LeftSidebar and RightSidebar. In the .master file I created a table with a 'header' row which contains only 1 column, a 'body' row which contains three columns and a 'footer' row which contains only 1 column. I assigned classes to each of the columns. In the stylesheet in the theme folders I defined how the table should appear. For instance, for easy identification in the Default theme's stylesheet, I put the header column background to aqua, the footer to lime the left side bar to read the main body to white and the right side bar to blue. This way, it is very easy to see what is displaying proper and what isn't.

For the LeftSidebar and RightSidebar themes' stylesheet, I simply made the column width 0px and the background color transparent (for which ever column was going to not be seen).

.leftSideBar
{
width:15%;
background-color:Red;
vertical-align:top;

}
.rightSideBar
{
width:0px;
background-color:Transparent;
vertical-align:top;
}

Am I making any sense here? Sometimes I think I start rambling, and then I don't very well explain myself. Anyway...

To select which theme to load, I placed a DropDownList in the header section of the table. The list contains four items "Select Theme","Default","Left Side Bar Theme" and "Right Side Bar Theme". Then I added an SelectedIndexChanged event handler and set a Session variable to the selected value of the DropDownList control.

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.DropDownList1.SelectedIndex > 0)
{
Session["Theme"] = this.DropDownList1.SelectedItem.Value;
Response.Redirect(Request.Url.AbsoluteUri);
}
}

Basically, this will cause two postbacks. The first when the DropDownList control selection is changed, and the second after the Session["Theme"] value is set. It is neccessary to do another post back at this time because, in the hierarchy of how things happen in ASP.NET, the Page_PreInit method happens before the Page_PostBack and anything that follows that. Since the Session variable is not set until after the Page_PreInit is executed, it is necessary to post back again after setting the Session["Theme"] variable.

This will programmatically change the themes based on what the user selects. Other ways of loading themes I will be investigating are via cookies, and database entries.

Thanks for stopping by, you can wake up now!

31 July, 2007

Templates and themes and skins...OH MY

Templates, templates, templates!

One of the great new features of ASP.NET in the 2.x/3.x framework are templates. Short story, templates are just what they imply, the create a basic framework for you ASP.NET application, into which you stick your content.

We all like sites that are intuitive and easy to navigate. Before now, the way we achieved this was either through frames, user controls and/or simply copying code to all the pages. This would get the breadcrumb trail and the left margin links and the header an all that great stuff. The most efficient, IMO were user controls. You create a control, and stick it on each page, then if you needed a change, you just change the control, not having to bother with the other pages.

Templates work in much the same way, but they go beyond that. With ASP.NET 2.x you can apply themes and skins to your site by simply identifying which one to use. You can have blue skins, and red skins and purple skins. And you can allow the visitor to select which skin they like best, and load that one for them.

Themes are a little more in depth. Anyone familiar with blogger or wordpress or other blogging formats will understand the themes idea. A theme defines the layout and module content of the page. What I am referring to as module content in this case are the little applet type things one finds on pages. Like the aforementioned breadcrumb trail, the header, the footer the sidebars, the ad space, the blog rolls or other links. Basically, everything that is not your main content, that you want viewable on every page.

There are a plethora (gosh I love that word - plethora - it just kind of rolls of the tongue, doesn't it?) of pages out there with information on how to use templates, and with some digging, one can find instructions on how to make templates. Please note, templates,skins and themes make extensive use of CSS. If you don't understand CSS, it would be a really good idea to learn more about that first, because it will only frustrate you in the end!

One of the best sources I have found for theme information and instruction is Microsoft's ASP.NET Quickstart Tutorials. This is setup so, if you know the basics, and are familiar with ASP.NET 1.1, you can jump right into what you are looking for.

If creating your own template seems to daunting a task, you can download several templates from the MSDN site, then customize as you see fit! The templates are available in both VB and C# source, so which ever you use, you can use these templates.

Over the next few weeks (hopefully not that long, but you never know). I'm going to create a template from scratch (hopefully it will be visually appealing, but again, you never know), and use this site to document my efforts. The template I am going to create will be for a blog. I have been (as stated in other posts I think) lamentful that there is really good, easily usable and easily findable blog software written in ASP.NET (especially C#). So I am going to create blog software to do that. First, I must create the database though, and for that I am going to borrow heavily from the mySQL database used for WordPress blogs. That database has pretty much everything I can think to need, but there are something I think I would do differently, so I'm going to use the schema as base point to start from. The database will be created using Microsoft SQL Server 2005.

Hopefully, but the end of the week, I'll have a database diagram that I can post here and (if anyone is actually reading this) can get some feedback on.

Until then, take care, and thanks for visiting! (seriously, you can leave comments and everything!)

11 July, 2007

Spex

Something that we didn't really do at my previous job was functional
specifications for projects or applications. Well, that is not entirely
accurate. What I should say is that we didn't do these before we started coding the application, but once it was all done and complete, then we would write out the specs. Amazing how all of our code matched perfectly to the specs and design docs.



This puts me at somewhat of a disadvantage as now I am supposed to
write up a functional spec for a project. Up pops the trusty ol' Google
search engine. This is what I have found regarding functional
specifications for software. There is a whole lot of stuff out there,
but it is very difficult to find the one that really describes things
in a way that 1) is understandable by me and b) somewhat almost fits
the type of project I'm working on.

So far, one of the ones I like the best is the PDF doc "Template for Functional Specifications".

A rather humorous template can be found a Joel on Software.

A rather nice essay titled "Writing Software Requirements Specifications" by Donn LeVie, Jr is informative, but not really much of a sample. I'm much better with looking at how something is put together, then altering it to fit my needs, than I am at reading on how to do it from scratch.

Another template in PDF format is the "Software Functional Specification Template". It is sometimes interesting to see the different methods and styles used to write basically the same information.

Well, I hope these resources help you out some if you need to look at doing a functional spec. If not, well at least it was a short post, and you didn't waste too much time on it!

Have Fun!


Technorati Tags: , , , ,

21 June, 2007

New Directions

Okay, so I have changed jobs. Where I was working I was doing C# desktop development. Now, I am doing C# ASP.NET development. This is quite a change. I have not done any web development for about four years. I have quite a bit of catching up to do.

I am working with a mental picture of web development that is four years old. In internet years, that is something like 75.6 years old to you and me. So I will probably be posting here a lot more as I run across what I think are new and exciting things in the world of C# ASP.NET development.

Stay tuned, and hang on. It looks like it is going to be a bumpy ride!

22 February, 2007

Resolving strange label behavior

I ran into a problem recently where I have something very much like map in my Windows Desktop application. The map-type thingy is bound to a dataset. The app draws items in a picture box based on the data in the dataset. What I needed was a label that would display information when the user moved the mouse over one of the items drawn on the form (like a tool tip).

Naturally, I used a dynamically created System.Windows.Forms.Label object. The user has the ability to determine what is displayed in the mouse over label. They could go to a settings form and set to display static text, values from data columns, or a combination of static text and column values (i.e. ID=234 - ID being static, 243 being the value from the dataset).

The problem I ran into was that the label generated and displayed properly when a data value was declared, but would only display the label border when only static text was to be displayed. The label has a border of BorderStyle.FixedSingle and the BackColor of Color.FromARGB(255,255,225) - this is the color of the standard ToolTip in Windows. but what was being displayed was just the outline of the label. No BackColor, no text. The label color would be whatever color was under where the label was supposed to be.

On a last ditch effort, I set the Label.Font property to this.Font. That fixed the problem. I don't know why it fixed the problem. I don't know what happened to the default font for the label, nor why the label BackColor was displaying as either Color.Transparent, or Color.Empty or whatever it was doing. But I do know that this fixed the problem.

I hope this helps someone out there.

Thanks for visiting!

06 January, 2007

A new direction

Ok, while at work I'm still kinda-sorta working with the Enterprise Library, that has - for a while anyway - been put on hold while I tossed onto a product to be delivered in January 07. This is something I haven't worked on, and must now get caught up in what it is and what it does, so the EntLib has to be put on hold.

On another note. I have a couple of other blogs, most hosted by places like this (blogger.com). One is hosted on my own. I mean, I host it on space I rent - it's not like I actually have access to the server guts or anything. For that blog (http://www.bigsibling.com), I have been using DotNetNuke. DNN is a great portal application. I use it several other places as well. And for what it is designed for, it does an exceptional job, and I wouldn't really want to use anything else for a portal application.

But (there is always a but - isn't there), for the blog I am using a blog module for DNN. While this works for the most part. Posting to it is a bit slow, and something just don't work as smoothly as I would imagine they should. I want to emphatically state that the product is a great and feature rich product. I have no real complaints about DNN or the blog plugin for DNN. The only thing is, the whole thing is a little bloated because it was not designed to be a blog application, but a porta application. So DNN has oodles of ultra-kewl features that I don't use on the blog itself.

With that in mind, I'm toying with the idear of creating a blog web appliction in .NET. I know, I know, there is dasBlog and probably some others. But hey, how can I learn new and exciting stuff if all I do is use other peoples stuff? Also, how can you laugh at all of my stupid mistakes if I don't jump into adventures like this? I mean, seriously, how can I provide your needed comic releif in any other way?

In preliminary research I did find this fairly (I think) comprehensive list of what a good blog application should have.

Anyway, this is what I'm thinking of. If you care, let me know if you think it is a worthy endeavour, or if you think I'm nutz.

Thanks for visiting!