Wednesday, June 16, 2010

Interactive SMS with DOTGO, Part 1

For those of you who don't know what DOTGO is, go check it out.

For those of you who don't want to follow a link, DOTGO is a FREE way to SMS-enable your website. It funnels SMS messages to your public domain name (No IP Addresses), where an XML file listens to keywords in the message to decide how to respond to the sender.

The XML listener file (.cmrl) is simple, but can do many complicated things, including:
  • Forwarding on requests to web services, to do some data crunching, perhaps
  • store session variables
  • respond with RSS feeds
  • auto-correct fat-fingered input
I recently worked on a project in which we wanted people to query a Spatial Database (PostGreSQL with PostGIS) to return the nearest locations that sold a particular product.

Interacting using Keywords

Based on the DOTGO examples, the SMS messages sent to a server usually follow a formula:
<your domain name> <command> <keywords>

For example, I might send the text to 368266 (DOTCOM): "ryanmwhitley getupdates ESRI", which might return the latest articles I wrote with the tag ESRI.

What happens here is that this message gets sent to 368266, which looks at the 1st word (ryanmwhitley), and routes the remainder of the message to ryanmwhitley.com/index.cmrl. It knows to go to .com because of the specific number. DOTGO has other numbers for .org etc.

Anyway, the remainder of the message (getupdates ESRI) is parsed by the .cmrl file sitting in the root of my website. It sees the 'getupdates' command, so forwards the rest on to a web service, which is passed the string 'ESRI'. It looks up posts with the tag ESRI (just regular web service stuff in C#), and returns the list to the Phone of the original user.

This is great when you only have a few commands and keywords. But the problem is how to get your users to remember all of the different keywords and combinations (you have to get it in the right order).

Is there an easier way?

I wanted something easier for my users (of course, harder for us to implement), so came up with a scheme to have a little back and forth.
First, I wanted the user to be able to select from a menu of options, and not have to remember all of my different keywords.

So I set up my .cmrl file to just listen for anyone who sends a text to 368266 with just ryanmwhitley as the message.

My XML snippet is: <match pattern="">>, meaning no matter what people send, I'm just going to spit back some results. Inside of that tag, I have:


<message>
<content>
Welcome to ryanmwhitley SMS.
Please enter your location (town name, district name or X,Y)

</content>

So, sending a txt to 368266 with the domain name would return the welcome message above to the phone, with a prompt for the user to respond with their location.

I have to go change diapers, so more on DOTGO later.

Wednesday, July 15, 2009

3D Model positioning in Google Earth API

I've been creating a demo using the Google Earth API.

I was trying to position a 3D model 'myModel.dae' (a Collada file exported from Google Skechup or downloaded from 3D Warehouse) at a fixed height above the ground, say 300 meters.

Following the code in the Google Earth API Sample Gallery, I attempted to use the kmlModel object's setAltitude method (and also setLatLngAlt).


function PlaceModel() {
var placemark = ge.createPlacemark('');
placemark.setName('model');
myModel = ge.createModel('');
ge.getFeatures().appendChild(placemark);
var loc = ge.createLocation('');

var link = ge.createLink('');

// A textured model created in Sketchup and exported as Collada.
link.setHref('myModel.dae');
myModel.setLink(link);

loc.setLatLngAlt(initLat, initLon, initAlt);

placemark.setGeometry(myModel);
}


This never worked. I tried numerous permutations of setting the altitude to no avail.

I eventually tried adding the following:
...
myModel = ge.createModel('');
myModel.setAltitudeMode(ge.ALTITUDE_ABSOLUTE); //<-- Without this, model is 'clamped to ground'
ge.getFeatures().appendChild(placemark);
...

You need to add the ge.ALTITUDE_ABSOLUTE to the .setAltitudeMode() to get it to be not clamped to ground.

Cheers!

Do-It-Yourself Editing w/ESRI JavaScript API & ArcSDE

Do you feel trapped into using the ESRI Web ADF for your application because of its out of the box Editing functionality?

Don't!

I recently fell into the same trap - the client's timeline was agressive, and I figured that the less custom features we had to write the better. The requirement was for users to be able to draw points and lines on the map and type in a comment, then save to the database. So we chose the Editor Task to edit a 'comment point' or 'comment line' layer. (Using ArcGIS Server 9.3.1 with SQL Server 2005 & SDE)

The user has to open the editor task window, choose which layer they want to comment on, then choose the editor drawing tool. After drawing on the map and typing a comment, the user has to jump back up to the top of the form and choose to save their edits. Not at all intuitive.

Turns out, the only people who know how to use/can figure out how to use the out of the box Editor Task in the Web ADF are GIS analysts. So, if your users are regular people, they probably won't want to take the time to 'figure it out', which means they won't use the feature, which means you're creating an app that people won't use.

Well, my colleague and I revisited this problem soon after finishing the Web ADF version of the application.

For grins, he migrated the app (with the exception of the editing task) to the ESRI JavaScript API and immediately notice a SIGNIFICANT improvement in performance for all operations, including page loading, layer visibility toggling, and querying.

So, the only question remaining for us was how to edit (or at least insert) new features through the JavaScript API. We came up with several hypotheses:


  • Use WFS-T to insert features

  • Write custom ArcObjects code



Great. So I started down the dreaded ArcObjects route. Within a few hours, I had cobbled together a solution:

User clicks on map and types a comment. In JavaScript we capture these values and append to an AJAX request (in DOJO or jQuery) to a .NET web handler. The handler picks up the querystring parameters, parses them and passes them off to a C# Class which contains the ArcObjects code which inserts the geometry into SDE. Phew!

Thought we had it down, then realized that this solution requires that the host server have ArcGIS Desktop or ArcEngine installed to take advantage of the licensing. Drat!

So I slightly modified some code I found on the ESRI Resource pages.

Instead of connecting to SDE using Direct Connect, you connect to the Server Object Manager and go from there.

So the result is that the Client Side JavaScript calls the .NET handler, which calls the C# class to insert the geometry ArcGIS Server Style.

Woo Hoo!

Friday, July 3, 2009

ESRI Misleads the Public, Pt. 2

Once more, our friends in Redlands are trying to increase your already elevated blood pressure by posting erroneous code snippets.

In the 'Working with AJAX capabilities of the Web ADF' article' , they incorrectly state that the correct way of registering Map Callback results with the .NET Script Manager is to use the following snippet:

. . .
string jsProcessCallbackResult = string.Format("ESRI.ADF.System.processCallbackResult('{0}');", Map1.CallbackResults.ToString().Replace("\\", \\\\));

ScriptManager.RegisterClientScriptBlock(Page, sender.GetType(), "changeextent", string.Format(jsProcessCallbackResult, Map1.CallbackResults), true);

Well, someone probably just copied and pasted the wrong info. Here's how you do it:

string jsProcessCallbackResult = string.Format("ESRI.ADF.System.processCallbackResult('{0}');", Map1.CallbackResults.ToString().Replace("\\", \\\\));

ScriptManager.RegisterClientScriptBlock(Page, Map1.GetType(), "changeextent", jsProcessCallbackResult, true);

Overall, this whole way of working with the ADF is clunky, clumsy, and downright frustrating. I hope they're working on something a little slicker down there in Redlands.

Thursday, June 11, 2009

ESRI Misleads The Public, pt. 1

The ArcGIS Server 9.3.1 .NET Web ADF doesn't work very well behind a proxy when trying to access WMS resources, or other internet ArcGIS Server resources.

...which is why ESRI created a obscure file located on your ADF-installed machine (C:\Program Files\ArcGIS\DotNet\ProxyServer.config). This config file will help you help the ADF with proxy server settings and such.

The 'Knowledge Base' Technical Articles section of the ESRI support website has a 'How To' article that explains how to configure this file to get out from under the oppressive foot of an coorprate Proxy server.

However, this article leads to nothing but misery.

Here, they foolishly instruct you to do the following.


----------------
To configure ArcGIS Server to work with a proxy server, change the following settings:

Enabled: Determines whether Web requests by .NET ADF components pass through the proxy server or not.

Valid values:

TRUE



or

FALSE


-------------------------

Try as you might, these changes simply don't work.

However, if you try LOWER CASE values, everything will work just fine.

Valid values:

true


or

false

Thursday, March 5, 2009

IE6 Cached Tile Transparency Problems

For those 18% of you using IE6 (or for those of you developing sites for the public to consume), you may come across a problem in which map tiles with transparency show up partly dark or partly black.

Our ArcGIS Server is handing out a .JPG base layer, and a PNG8 layer showing parcels to overlay on top. The top layer needs to have a transparent background so we can see the basemap, right? Great. Everything is peachy in FF3, FF2, and IE7. In IE6, *parts* of some of the transparent tiles are showing up black! We noticed that it seems to be worse in areas where the parcel boundaries are relatively close together.

In the ESRI JavaScript Extensions for Virtual Earth, we were also setting the parcel layer's opacity to .9 (layer.setOpacity = 0.9;).
I've also seen these transparency problems using MS MapCruncher to create a tilecache for consumption in Virtual Earth.

After searching blogs and forums, and after our team was about out of options, I stumbled across this page. The key line that helped me out was "With MSIE 6 you can only have transparency or opacity control, not both."
So ArcGIS Server is giving us PNG8s with transparent background, AND we were setting the opacity using JavaScript. No good.

I commented out the layer.setOpacity = 0.9; and, voila! Everything works in IE6+....

Hope this helps someone!




Wednesday, March 4, 2009

Welcome to GeoSpat!

This is my first attempt at blogging. I hope this won't be my only entry! This blog will discuss my work with Geospatial Technologies/Internet Mapping and everything that goes along for the ride.


I'm currently working on several Geospatial Web Applications:
  • A Google Maps/.NET site to gather public feedback regarding public transportation options
  • An ArcGIS Server/ESRI JavaScript API & Virtual Earth County Assessor's Parcel Viewer
  • A PostGreSQL/GeoServer/OpenLayers Portfolio Tracking application
In the last year, I've had the opportunity to work on some cool projects, including the GeoEye GeoFUSE Search and Discovery Tool. This stack included SQL Server '05/ArcSDE/ArcGIS Server 9.3, the ESRI Google Maps Extensions and the Google Maps API.

One of my job responsibilities is to 'poke around' with new technologies and keep track of what is 'out there'. I've spent time poking around with:
  • Deep Earth Silverlight Control
  • SQL Server 2008 connection to GeoServer
  • Using the native SQL Server 2008 Geometry Type with ArcSDE
  • SMS Text (DOTGO) -> .JPG -> Virtual Earth 3D Billboard
  • Creating .NET Web Handlers as REST endpoints for custom spatial data entry
  • Using SQL Server 2008's XML capabilities to transform queried GML with XSLT