Natural Geography

Posted on Sunday 28 February 2010

Mikel is a geographer (of the natural worthwhile variety). His work and blog are simply terrific. Bravo.

mapbutcher @ 10:42 pm
Filed under: porterhouse
ST_MULTILINESTRING….ESRI Bug?

Posted on Sunday 28 February 2010

As a bit of background I’ve been working on a project which delivers a set location translation web services – basically the organisation collect data using a number of methods some of which have a linear aspect. They want to be able to translate between these methods as well as validate that the locations to ensure consistent quality assurance and finally enrich each location through spatial analysis. In effect the we’ve been developing an advanced linear referencing locator.
The web services are served out from an application server which communicates with our spatial server hosted within ArcGIS Server. The spatial server component provides dynamic segmentation and some other spatial functions. For linear locations the dynamic segmentation operations return ArcObjects geometry which is parsed and returned to the application server as WKT – why? Because we’ve made use of as much functionality at the Database level as possible and that means we use ST_Geometry where we can.
Recently our client found a bug :( They were testing the services and tried to create a long linear location – suddenly the server returned a nasty oracle error. Everything had worked fine up until the application server tried to write the geometry as WKT into the database at which point things went astray. To resolve this issue we built a small test which uses ODP.Net:

BugsLifeWallpaper800[1]

As a bit of background I’ve been working on a project which delivers a set location translation web services – basically the organisation collect data using a number of methods some of which have a linear aspect. They want to be able to translate between these methods as well as validate the locations to ensure a consistent data quality and finally enrich each location through spatial analysis. In effect we’ve been developing an advanced linear referencing locator.

We made a decision with the solution that we would utilise as much functionality at the database level as possible and that means we use ST_Geometry where we can. Unlike some implementations the ESRI ST implementation does not provide linear referencing functions therefore the web services which are served out from an application server communicates with our spatial server hosted within ArcGIS Server. The spatial server component provides dynamic segmentation and some other spatial functions. For linear locations the dynamic segmentation operations return ArcObjects geometry which is parsed and returned to the application server as WKT.

All has been fine until last week when our client found a bug :( They were testing the services and tried to create a long linear location – suddenly the server returned a nasty oracle error. Everything had worked fine up until the application server tried to write the geometry as WKT into the database at which point things went astray. To resolve this issue we built a small test which uses ODP.Net:

//wkt
string WKT = "some well known text"
 
//create parameters
OracleParameter p_wkt  = new OracleParameter();
p_wkt.OracleDbType = OracleDbType.Clob;
p_wkt.Value = WKT;
 
OracleParameter p_srid  = new OracleParameter();
p_srid.OracleDbType = OracleDbType.Int32;
p_srid.Value = 0;
 
//create command
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.Parameters.Add(p_wkt);
cmd.Parameters.Add(p_srid);
 
//sql
string sql = "INSERT INTO GEOMETRY_TESTBED VALUES(1, SDE.MULTILINESTRING(:p_wkt, :p_srid))";
 
//execute
cmd.CommandText = sql;
cmd.ExecuteNonQuery();

So basically Oracle was spitting a dummy when I was inserting a lengthy piece of text as the WKT parameter, returning an ORA-01461: can bind a LONG value only for insert into a LONG column. Basically when the WKT was truncated to less than 4000 characters long the insert was working. I wanted to try and insert a very long geometry so I selected (ST_ASTEXT & ST_LENGTH) the geometry from the database with the highest number of points (ST_NUMPOINTS) which returned a 400,000+ character string using the ST_LINESTRING M constructor, I updated the code to:

string sql = "INSERT INTO GEOMETRY_TESTBED VALUES(1, SDE.LINESTRING M(:p_wkt, :p_srid))";

Insert worked fine. So lets try another geometry – this time using ST_NUMGEOMETRIES > 1 I selected the longest multi part with the highest number of verticies. This time the database returned a geometry with the ST_MULTILINESTRING M constructor, I updated the code to:

string sql = "INSERT INTO GEOMETRY_TESTBED VALUES(1, SDE.MULTILINESTRING M(:p_wkt, :p_srid))";

Insert worked fine! Ok then, now I tried my geometry as returned from my ArcObjects parser – this time amended to have a dummy M value appended to each coordinate, and using the ST_MULTILINESTRING M constructor. Worked!

Is this a bug with the ST_MULTILINESTRING constructor within the ESRI ST implementation on Oracle? Somewhere under the hood is the UDT using a varchar when it shouldn’t be?

Has anyone else seen this issue?

mapbutcher @ 9:45 pm
Filed under: rib
Gold Coast to Palm Springs

Posted on Monday 22 February 2010

Ding dong, I haven’t had time to think since Christmas.

It’s been really busy at work, with the big project I’ve worked on for the past year coming to a close and I’ve started to work on some new projects. I’m looking forward to a change.  Amongst all the mayhem of tenders, my daily batch of Jira and the occasional bit of consultancy March and April are shaping up quite nicely thank you.

To begin with myself and my good friend Peter are heading to the Gold Coast to present at this years OZRI. We’re going to share our experiences of using SCRUM on a large GIS project. It’s been a great journey with plenty of ups and downs but I think that it’s been a success.  More than anything else I feel we’ve worked together as a team  to deliver on what the organisation wanted. I think SCRUM engenders a culture of working together which removes the old school vendor/client bullshit which often gets in the way of just getting on and getting the job done.  To top it all off I’ve managed to squeeze a pork pie into my slide deck – that alone is an achievement I am proud of.

Following OZRI I’m heading across to the ESRI Developer Summit – It’s my first ever ESRI event and I will be putting on my little c# badge, packing in the kool aid and soaking it up – I’m hoping to catch up with some of the people whose blogs I’ve read for years but never had the chance to meet  - i could go some Belgium BBQ action

Aside from all this I have an old friend visiting from the UK, tickets for Calexico and the legendary Buddy Guy and I’m heading to NZ to see my Brother – it really couldn’t get any better than this……..or could it

mapbutcher @ 9:23 pm
Filed under: porterhouse
Anybody interested in working in New Zealand?

Posted on Tuesday 12 January 2010

From Nelson

My good friends Tony and Harley are looking to add a their growing team.  Having worked at GBS I can recommend the team there – a great bunch and a really good attitude to work and life. Hey you might even get to fly on some very small planes over the best landscapes in the world, work on some really interesting projects, meet some great people and have the occasional social beer :)

Find out more here

mapbutcher @ 8:46 pm
Filed under: porterhouse
Make your Server Object Extensions exception friendly

Posted on Thursday 10 December 2009

tumblr_ks6ye726wN1qznuot[1]

I’m working on a project where I’ve applied the following simple design principle:

“Don’t use ArcObjects unless you have to”

Most of the spatial functionality is delivered via a set of web services and is implemented directly between a custom WCF application server and Oracle (ESRI’s flavour of ST_Geometry). I took this decision for the following reasons:

1. I didn’t want to overly complicate what are essentially simple spatial processing steps

2. I wanted to reduce the number of layers within the application as much as possible

3. I wanted to make the services as fast as possible

However there are cases when I have no option and I have to use ArcObjects – I have implemented the functionality within a Server Object Extension (SOE) hosted within an ArcGIS Server Map Server context which  I make remote calls to from the application server. Works Sweet.

For a long time our test manager has been busting my nuts about the crap error messages which are received back from the SOE when an exception occurs, this is basically because I’ve never implemented a useful exception class for my SOE – so this afternoon I did just that.  Basically what I wanted was the ability for the application server to make calls onto the SOE and catch the custom exception. The communication between the application server and ArcGIS Server is via DCOM so I have a local instance of the SOE assembly referenced by the application server which means that I can do this:

catch (LRSSpatialServerException sEx)
{
throw new LRSException(ProcessStepType.error, “validateDerivedDistance”, sEx.Message + ” : ” + sEx.RunTimeMessage, id);
}
catch (MyCustomSOEException SoeEx)
 
{
 
...do something
 
}

However the important thing is to ensure that your custom exception is serializable  so that when it is thrown by the SOE it can be serialized/deserialized on the application server. Here’s how you do that:

1.  Mark the class as serializable:

[Serializable]
 
public class MyCustomSOEException : Exception
 
{
   string foo;
}

2.  Override the base Exceptions Serializable constructor to implement deserialization

protected MyCustomSOEException (SerializationInfo info, StreamingContext context)
 
: base(info, context)
 
{
 
this.foo= info.GetString("foo");
 
}

3.  Override the GetObjectData method to implement serialization

public override void GetObjectData(SerializationInfo info, StreamingContext context)
 
{
 
info.AddValue("foo", this.foo);
 
base.GetObjectData(info, context);
 
}

The Exception class is now ready to be passed back and forth between the application server and the SOE. For example in the catch block on the application server side we can access any custom exception properties if the SOE throws:

catch (MyCustomSOEException SoeEx)
 
{
 
string exceptionProperty = SoeEx.foo;
 
}

The same methodology can be applied to any objects you wish to return from a method call onto your SOE. As long as they’re safely serializable then you’re good to go – Making custom exceptions serializable is particularly important if your developing a server object extension for use by others.

mapbutcher @ 9:38 pm
Filed under: shank