Vishful thinking…

Options for implementing Spatial Validation rules

Posted in ArcGIS, ESRI by viswaug on February 10, 2009

I had a pretty engaging dialog with one of my colleagues today about how and where to implement spatial validation rules for one of the enterprise GIS web application that we are working on. I thought I would discuss some of those options here to possibly invite more suggestions or criticisms of some of the approaches

Implement and resolve the spatial validations on the client-side web interface only. Since this application is the only one updating the SDE, lets not spend a lot of effort performing spatial validations on the server-side also. Well, to put it in simpler terms, if the user is sketching a “Land Owner Boundary” that crosses state boundaries, then use the AGS REST API to make sure that the sketched shape does not cross state boundaries and if it does use a custom REST service to clip to the required boundaries. So, the spatial validation and the resolution is performed by the client before the shape is sent back to the server to be added as a new feature. But not performing all the validations on the server also just doesn’t feel right.

Perform all the spatial validation involved on the ArcGIS Server machine in Feature Class Extensions by implementing the various interfaces exposed in the ArcObjects SDK. This way all the data getting into the SDE has been passed through the same pipeline of validation methods before being inserted/updated into the SDE. If you are interested in going this route, check out the following interfaces that are available and will help get the job done. IClassExtension, IObjectClassExtension, IObjectClassEvents, IObjectClassValidation, IFeatureClassExtension. This method seems like a very good way too do things but there are some drawbacks to it. The first of which is implementing validations can get a little hairy fast and all the validation logic needs to be written in ArcObjects which is not a fast way of doing things. It would be easier, fast and more robust to construct Geo-processing models to perform these spatial validations. The bigger one I think is that when handling the OnCreate event or implementing the ValidateRow method, there is no way for us to pass in more context information into these methods which are necessary to perform the spatial validations required.

I personally think that the decision to put the validations in these feature class extensions as mentioned above is more similar to the argument of putting domain logic in Stored Procedures and Triggers in relational databases. It is very powerful, but also very constraining and rigid. Also, not all validations can be implemented this way.

Perform the spatial validation in the Domain Object model sitting on the web server( or ArcGIS server) machine. In our web application, we have a data access layer that performs the CRUD operations on an Oracle DB and the SDE. We also have the domain objects that models the entities in our domain/project and in turn use the data access layer to perform the operations required. This is a very flexible place to position the spatial validation logic since in this layer of the application, we have access to not only the entire domain object of the feature(all feature attributes) and other involved domain objects (related features etc) instead of just the data access objects which by themselves(individually) don’t tell us everything about that feature. This methods also lends itself better to unit testing than the previous two methods.

I am personally leaning towards the third option of having the spatial validations performed in the domain objects. Well, that is not to say that the spatial validation/resolutions need not be done on the client-side. I don’t think there is no escaping that nor should we attempt to. In the past, for Windows Forms based database applications, we could have represented all the validation logic in one place (on our POCO’s for example) using some library like the Validation Application Block in the Enterprise Library. This validation logic can be used on the UI (windows forms using IDataErrorInfo) and also on the server-side validations. But since we are swimming in the world wide web, the same validation logic needs to be represented in JavaScript using something like the jQuery Validation plug-in rules for example. Now, stack on top of that spatial validation, and it gets even better…<grin>

Advertisements

Automating Start/Stop AGS and AGS services

Posted in Agile, ArcGIS, ESRI by viswaug on February 10, 2009

I was working on setting up our automated build process for one of the projects I am working on and needed a way to start/stop the ArcGIS server running on a remote machine and also start/stop specific ArcGIS services running on remote machines. I was looking to see if ArcGIS Server provided any command line tools to perform these tasks so that I can just call these commands from my build file. But there is no out-of-the-box command line tools that come with ArcGIS Server which I could use for that purpose. So, I had to improvise and use some utilities and cook up a little bit of code.

To start/stop ArcGIS Services running on a remote machine, I was able to use the “PsService” from the Sysnternals Process utilities. Here is the crux of what PsService does.

PsService displays the status, configuration, and dependencies of a service, and allows you to start, stop, pause, resume and restart them. Unlike the SC utility, PsService enables you to logon to a remote system using a different account, for cases when the account from which you run it doesn’t have required permissions on the remote system

Usage: psservice [\\computer [-u username] [-p password]] <command> <options>

So, we can use the “stop” command and provide the service name for ArcGIS Server process “ArcServerObjectManager” as the option. Here is an example showing how it can be used.

psservice \\MachineName -u username -p password stop ArcServerObjectManager

Since, I had to call it from my NAnt build file, here is a sample of how it can be done

Setting up NAnt build file properties

<property name =“AGSMachineName” value=“myMachine”/>

<property name =“AGSAdminUser” value=“myUserName”/>

<property name =“AGSAdminPassword” value=“myPassword”/>

<!–comma seperated list of MapServices that needs to started/stopped–>

<property name =“AGSMapServices” value=“BaseMap, Boundaries, DynamicMap”/>

Targets to Start and Stop ArcGIS Server

<target name =“StopAGS”>

<exec program=“psservice” basedir=“.\tools\pstools\” append=“true”>

<arg line=“\\${AGSMachineName} -u ${AGSAdminUser} -p ${AGSAdminPassword} stop ArcServerObjectManager”/>

</exec>

</target>

<target name =“StartAGS”>

<exec program=“psservice” basedir=“.\tools\pstools\” append=“true”>

<arg line=“\\${AGSMachineName} -u ${AGSAdminUser} -p ${AGSAdminPassword} start ArcServerObjectManager”/>

</exec>

</target>

Now that’s good. The first hurdle has been crossed. But I still needed to start and stop specific MapServices that I desired. I couldn’t shortcut my way through this one and had to write some code to do this. The code to do it was pretty simple and didn’t turn out to be a pain.

The tool to start/stop ArcGIS services can be downloaded here

The source code for this tool can be downloaded here

The syntax to use the tool from the command line is

Usage: arcgisservice [serverName] [serviceName] [serviceType] [start | stop | restart] <username> <password>

The “username” & “password” for a user belonging to the “agsadmin” group can be specified here. If they are not specified, your current windows credentials will be used. And here is how it can be used in the NAnt build file.

Targets to Start and Stop ArcGIS MapServices specified as a comma seperated list

<target name=“StopMaps”>

<foreach item=“String” in=“${AGSMapServices}” delim=“,” property=“mapService”>

<exec program=“agsUtil” basedir=“.\tools\AGSTools\” append=“true”>

<arg line=” ${AGSMachineName} ${mapService} MapServer stop ${AGSAdminUser} ${AGSAdminPassword}”/>

</exec>

</foreach>

</target>

<target name=“StartMaps”>

<foreach item=“String” in=“${AGSMapServices}” delim=“,” property=“mapService”>

<exec program=“agsUtil” basedir=“.\tools\AGSTools\” append=“true”>

<arg line=“${AGSMachineName} ${mapService} MapServer start ${AGSAdminUser} ${AGSAdminPassword}”/>

</exec>

</foreach>

</target>

The target above will loop through and stop/start all the MapServices specified as a comma separated list in the “AGSMapServices” NAnt property.

And if you want to do the above and much more through another GUI didn’t want ArcCatalog installed all over the place, then the SOEXplorer would be the way to go.