Tuesday, March 25, 2008
Posted on Tuesday, March 25, 2008 11:15:25 AM (Mountain Daylight Time, UTC-06:00)  Comments [0] | 
Categories: ArcDeveloper | Virtual Earth

Just a quick note about some updates to the Virtual Earth Tile Server code base. You can grab the latest code from the Subversion repository (http://svn2.assembla.com/svn/arcdeveloper/tileserver).

Note: This update will require some configuration changes, but I think they are well worth it.

 

WMS Support

The Tile Server now as a WMS Tile Provider. This allows you to very easily add WMS Services into your Virtual Earth applications. This is a pretty base implementation, but it works smoothly. You just need to specify the base Url (which should include the LAYERS you want in the map images) and the version of WMS to use. The WMSTileProvider takes care of the rest. I've only tested with WMS 1.1.1 at this point, but I'll be working with all flavors shortly so should there be any issues, I'll be fixing the code.

<!-- WMS Service -->

<component id="WMSBathymetry" service="..." type="...">

  <parameters>       

    <wmsBaseUrl>http://www.mapsherpa.com/cgi-bin/wms_iodra?LAYERS=Bathymetry</wmsBaseUrl>

     <wmsVersion>1.1.1</wmsVersion>

  </parameters>

</component>

This is the configuration file in source control, and it is pulling a global bathymetry layer from mapsherpa.com. It can be a little slow at the top levels, but once it's cached, it rips.

Improved Caching Options

Caching is great, and can improve performance, but it can also eat up a lot of disk space. For example, at level 15, there are more than 1 billion tiles, so you could really fill up some disk space. Unless your data only covers a small area, the likelihood of a cache hit at the higher levels is pretty low. Thus you are storing lots of tiles which are not really helping performance. To help manage this, I've added a MaxCacheLevel property to the Tile Service. By default it will cache everything, but you can change that by just adding maxCacheLevel into the parameter list in the service configuration...

<!--Bathymetry Service-->

<component id="WMSBathymetryService" service="..." type="...">

   <parameters>

     <servicename>wmsbathymetry</servicename>

     <tileProvider>${WMSBathymetry}</tileProvider>

     <storageProvider>${FileStorageProvider}</storageProvider>

     <maxCacheLevel>10</maxCacheLevel>

   </parameters>

</component>

 

FileStorageProvider Changes

The tiles are now stored in sub-folders with the name of the service. So - instead of seeing something like:

c:\tiles\l1\

you will see

c:\tiles\someservice\l1

This allows you to  use the same FileStorageProvider across multiple services in your configuration. Not a big deal, but saves some configuration.

Monday, March 24, 2008
Posted on Monday, March 24, 2008 7:35:15 PM (Mountain Daylight Time, UTC-06:00)  Comments [1] | 
Categories: ArcDeveloper | ArcGIS Server

Could anyone who is using the ArcGIS Server Virtual Earth Tile Server code please shoot me an email or drop a note in the comments. ESRI is preparing a press release about the Code Challenge winners, and they asked for a list of people/agencies etc using it. Some free publicity if you answer quickly!

Thanks!

Monday, March 10, 2008
Posted on Monday, March 10, 2008 10:57:24 AM (Mountain Daylight Time, UTC-06:00)  Comments [1] | 
Categories: ArcDeveloper | ArcGIS Server

I've mentioned the ArcDeveloper project in the past, and called out the community to "just do it" if we really wanted an ArcGIS Server REST API.

Well, the good news is that it's now alive and kicking. At this point it's lean and mean - you can:

  • Get a single feature by id (must be OBJECTID, ugh)
  • Query multiple features with a where clause and/or a bounding box

The requests look like this:

http://65.101.234.201/rest/rest.svc/TestService/Flyways/10?g=true

(go ahead and try it - it's live and will return GeoJSON)

Currently there is only one format - GeoJSON, and it's not a 100% implementation yet, but it's enough to get the geometries and attributes.

The project is designed around a plug-in model - so as the need arises, we can write different formatters (think ESRI 9.3 REST compatibility), and different data services (think SQL Server 2008).

Huge props go out to Glenn Goodrich, who wrote the vast majority of the existing code. He has posted an Intro to the project that talks about how to get the code and the requirements, as well as a second article about how the end point works. I don't want to speak for him, but it looks like he will be posting more about the code, so go ahead and subscribe now.

For those with a short attention span who want to see the code, here's the subversion repository:

http://svn2.assembla.com/svn/arcdeveloper/ArcDeveloper.REST/trunk/

Demo Site

I am using this code on an active project, and I'm hosting a test service @ work. The project comes with a demo page, that uses prototype with OpenLayers. You can see a live version here: http://65.101.234.201/rest/ 

rest-demo

The demo is super simple at this point, but we'll be adding more functionality as we have time.

Comments / Bugs / Issues / Ideas?

We have setup a Google Group for the project - pop on over and let us know what you think. http://groups.google.com/group/arcdeveloper-dev

Sunday, February 03, 2008
Posted on Sunday, February 03, 2008 3:32:04 PM (Mountain Standard Time, UTC-07:00)  Comments [6] | 
Categories: ArcDeveloper | ArcGIS Devt | ArcGIS Server | Community

Starting from the little bit of hacked up code that I cooked up a while back, I've created an extensible, interface based, adaptive caching Virtual Earth Tile Server that can be extended to use any map rendering engine. The initial release has one Tile Provider which uses the ArcGIS Server SOAP API. In the coming weeks I will be adding providers for both WMS and ArcIMS services.

Project Features:

  • HttpHandler (.ashx)that responds to Tile requests from Virtual Earth
  • Supports multiple layers/map services through the same handler
  • ArcGIS Server Tile Provider uses the AGS SOAP API (fast!)
  • Projects the data - can be used with any ArcGIS Server map service
  • Extensible design allows for additional Tile Providers - i.e. ArcIMS, Image Server
  • Extensible design allows for additional storage providers - i.e. Amazon S3, DBMS
  • Easy to use - just edit the web.config file.
  • Includes a demo web page to get you up and running quickly.
  • API Documentation compiled using DocProject is at http://doc.arcdeveloper.net/tileserver (coming soon!)
  • Leverages the Castle Windsor Inversion of Control Container.
  • Exceptions are written into a tile image so it's easy to debug your configuration.

Design

The Virtual Earth Tile Handler uses a Virtual Earth Tile Service Manager to actually do all the work. The Tile Service Manager contains a collection of Tile Services, keyed by a name. This allows a single instance of the Tile Handler to host multiple tile services. The handler determines which Tile Service to use by extracting the service name from the url of the request. Assuming your tile handler lives in a subdirectory called "tileHandler", a request to http://myserver/tileHandler/tahoe/<vetileindex>.ashx will look for the tahoe tile service, and use it's settings to create the map.

Tile Service is simply a named container for a Tile Provider (a class which creates map image tiles) and a Storage Provider (a class which can cache the images on disk)

The logic in the system is quite simple as shown below:

 TileServer-logic

How to Configure Tile Server:

There are 2 main things you need to do to configure this for your site - add the layer to your Virtual Earth map control, setup a TileService in the web.config.

Adding a Tile Layer to the Virtual Earth Map Control:

Using version 6 of the Map control this is very easy (the Default.aspx file in the attached zip file has this code in it)

First Create a bounding box that will limit the area that Virtual Earth will make tile requests. This box is for Colorado.

var bounds = [new VELatLongRectangle(new VELatLong(40,-109),new VELatLong(37,-102))];

Next, create a Tile Source Specification. You will need to specify the full Url to the handler if your Virtual Earth page is not located in the same web application. What's important to note is that the name of the TileService must be in the url - in this case it's "colorado". You will need to change this to the name of the TileService you want this layer to pull from.
var tileSourceSpec = new VETileSourceSpecification("agssoap", "./colorado/%4.ashx");

From here, it's just setting some simple tile source properties...
tileSourceSpec.NumServers = 1;
tileSourceSpec.Bounds = bounds;
tileSourceSpec.MinZoomLevel = 10;
tileSourceSpec.MaxZoomLevel = 18;
tileSourceSpec.Opacity = 0.5;
tileSourceSpec.ZIndex = 100;

Finally you want to add the layer to your map
map.AddTileLayer(tileSourceSpec, true);

 

Setting up a Tile Service in Web.config

A Tile Service is a container for a Tile Provider and a Storage Provider, so we are going to set up these three things, and link them together. The web.config file in the download already has these sections in it - you will just need to change a few things.

Step 1: Configure the Tile Service

Change the service name to match what you put into the VETileSourceSpecification path, as this is the linkage between the Tile Service and the Url that the request is coming from. For now, leave the other elements alone.

<!-- Colorado Tile Service-->

      <component id="ColoradoVETileService"

                service="ArcDeveloper.TileServer.Interfaces.IVirtualEarthTileService, ArcDeveloper.TileServer.Interfaces"

                type="ArcDeveloper.TileServer.Core.VirtualEarthTileService, ArcDeveloper.TileServer.Core" >

        <parameters>

          <!-- Service Name - must be specified in the url parsed by the handler -->

          <servicename>colorado</servicename>

          <!-- The tile provider for this service is AGSColorado, with it's settings defined lower down -->

          <tileProvider>${AGSColorado}</tileProvider>

          <!-- The storage provide for the cache is the default FileStorage Provider, but this could be changed as needed -->

          <storageProvider>${FileStorageProvider}</storageProvider>

        </parameters>

      </component>

The other sections specify the TileProvider and StorageProvider that this Tile Service will use. If you want to use different or differently configurated providers, just copy/paste the sections and rename them. The configuration syntax here is based on the Castle Windsor project, and you can get more information about how this works by reading Simone Busoli's articles here: Part 1, Part 2, Part 3, and Part 4.

Step 2: Specify the Map Service URL

Locate the following section in the web.config

<component id="AGSColorado"

                service="ArcDeveloper.TileServer.Interfaces.ITileProvider, ArcDeveloper.TileServer.Interfaces"

                type="ArcDeveloper.TileServer.ArcGIS.ArcSoapTileProvider, ArcDeveloper.TileServer.ArcGIS">

        <parameters>

          <!-- Make sure this Url is accessible from this web server or you'll get an exception -->

          <webServiceUrl>http://YOURSERVER/arcgis/services/YOURSERVICENAME/MapServer</webServiceUrl>

        </parameters>

      </component

 

Step 3: Change the StorageProvider location

The Storage Provider is used to cache the tiles as they are created. Thus the location you specify must have write privileges granted to the identity that the ASP.NET application runs as (ASPNET on Windows XP and NETWORK SERVICE on Windows Server 2003)

<component id="FileStorageProvider"

                service="ArcDeveloper.TileServer.Interfaces.IStorageProvider, ArcDeveloper.TileServer.Interfaces"

                type="ArcDeveloper.TileServer.Core.FileStorageProvider, ArcDeveloper.TileServer.Core">

        <parameters>

          <!-- Make sure this path exists, or you'll get an Exception instantiating the FileStorageProvider -->

          <cacheFilePath>c:\tiles\</cacheFilePath>

        </parameters>

      </component>

That's it.

Known Issues:

Occasionally empty tiles are returned from ArcGIS Server. I am still looking into why this occurs, but since the SOAP API actually returns an image, there is no way for the code to know that it's a blank image, and thus it is still added to the cache.

Do not use labeling in the map service. This is because the images are requested at their native tile size of 256 x 256. Thus the labels will be cramped into the tile, and you will have a lot of repeated labels across your map. In the future we may build out a tool that will pre-cook a tile cache, and when doing that you can request larger images which will not have this issue. For now, just turn your labels off.

Feedback / Bugs / Issues

Please use the ArcDeveloper.net forums to ask questions or raise issues. This way everyone will benefit, and it's less one on one emailing.

Source Code:

All the source code for this project is available at the ArcDeveloper project hosted at Assembla.com. You can get the source code from http://svn2.assembla.com/svn/arcdeveloper/tileserver/trunk

If you would like to contribute to the project, use the contact link at the top of this page and I will send you an invitation to join the project team.

Download

Download ArcDeveloper.net Tile Server v0.1 (from ArcScripts). This zip file contains the source code current as of February 3,2008.

Vote!

I also entered this code in the ESRI Code Challenge . If you are an EDN subscriber or are going to the 2008 Developer Summit, and find this code useful, I'd appreciate your vote!

Wednesday, November 28, 2007
Posted on Wednesday, November 28, 2007 6:01:20 AM (Mountain Standard Time, UTC-07:00)  Comments [0] | 
Categories: .NET | ArcDeveloper | Unit Testing

Tonight added a few more projects to the ArcDeveloper Subversion repository up at Assembla (http://svn2.assembla.com/svn/arcdeveloper).

Since the goal of the ArcDeveloper.net open-source projects is to streamline unit testing for the ArcGIS developer, the logical place to start is with a methodology for passing geometries into tests.

The code that's up there handles geometry serialization / deserialization. In addition to a set of classes which handle the "work", it also includes 3 ArcMap tools:

  1. Serializing selected geometries to a file,
  2. Serializing a sketch to a file, and
  3. Drawing serialized geometries on screen so you can be sure you captured the right thing.

It also has a simple example showing how to write tests using this methodology.

I'm not going to go into a full-blown "how to" at this point, but the general flow goes like this:

  1. Use the tools in ArcMap to create serialized geometry files
  2. Add these files into your Test assembly as Embedded Resources
  3. Pull the geometries out of the test assembly when the tests are run.

This allows you to store all sorts of complex geometry scenarios without being reliant on particular spatial data sets residing at fixed locations - the data is embedded into the test assembly.

I will be posting a much more detailed "how to", as well as adding content into the ArcDeveloper.net wiki.

Backlog Items

These will be added into TRAC when I get time, but here's the quick list

  • Enable serialization of entire features
  • Add tests for the actual utility classes themselves
  • Improve the messaging
  • Make the Extension be a "JIT" extension so it's easily enabled/disabled
  • Better exception handling (currently just MessageBoxes)

Project Status

If you are interested in following along with what's happening on the project, I'll be posting finer grained information on the "project flow" page, which like all good things has an RSS feed.

Monday, November 19, 2007
Posted on Monday, November 19, 2007 8:03:02 PM (Mountain Standard Time, UTC-07:00)  Comments [1] | 
Categories: .NET | ArcDeveloper | Visual Studio 2005

In the last post, I said I'd post shortly so - here's the skinny on the code that's currently in the ArcDeveloper Assembla repository.

The VSTemplates Project

Back in September I posted about using MSBuild to package up Visual Studio Item templates. I've uploaded this code into the repository, and it's ready to roll. The templates are setup for ArcDeveloper projects (i.e. an MIT license, "ArcDeveloper" etc.), but you can easily modify this and re-run the MSBuild script to create a set customized for your company / team.

At this time, there are just 3 templates - class, interface and non-COM class - with both C# and VB.NET flavors. I've got ideas for others, and will be adding more as they come up in my development.

Running MSBuild

If you have edited the templates, you'll want to run the ArcDeveloper.Templates.Build file. Here's how you do that:

  1. Edit the .build file so the SolutionDir and BuildFolder are correct for your machine.
  2. Open a Visual Studio Command Prompt
  3. cd to the folder with the .build file
  4. run msbuild arcdeveloper.templates.build

The build script will zip up the templates (as required by Visual Studio) and drop them into the BuildFolder. In order to have Visual Studio pick these up, you need to tell it where your Item Templates are. Go to Tools --> Options and select the Projects and Solutions item. Set the User Item Template location.

vs-settings

Now when you add an item to Visual Studio, you'll have some additional options

vs-items

Get It!

If you just want the templates, you can download them from here: http://www.assembla.com/spaces/files/arcdeveloper

If you want to be able to build the templates, grab the code from Subversion: http://svn2.assembla.com/svn/arcdeveloper

Sunday, November 18, 2007
Posted on Sunday, November 18, 2007 8:03:02 PM (Mountain Standard Time, UTC-07:00)  Comments [0] | 
Categories: .NET | Agile | ArcDeveloper | ArcGIS Devt

I had originally setup a SourceForge project for ArcDeveloper.net, but the whole SourceForge experience is clunky and web 1.0. So when I found out about Assembla, I immediately setup a project.

ad-assembla

Assembla is a really cool, free Subversion + TRAC + wiki + Scrum development tool / service. It's really amazing. It's totally free for projects up to 200Mb in size (which is a MOUNTAIN of source code).

ArcDeveloper Projects

A repository and some tools is nice, but a bigger question is what projects will be there. Well, my goal for ArcDeveloper is to provide a set of code resources that will make unit testing on ArcGIS projects easier. Since software quality is something that all developers must address, and since it's the same regardless of your vertical market, I think that few organizations would object to using and contributing to this effort.

Getting Access

The repository is open for all users, just point your Subversion client to http://svn2.assembla.com/svn/arcdeveloper and you can get latest on everything. If you are not familiar with Subversion, Assembla has some handy starter info here, and you can Google for mountains of information.

Project Status (TRAC)

The project is managed in TRAC - since it's a web based tool, you can access it here: http://trac2.assembla.com/arcdeveloper/wiki. There's not a whole lot in there yet, but I'll be posting about the inital project shortly.

Bug Reporting / Feature Requests / Contributing

You'll need to be a member on the project to add a TRAC ticket. The easiest way to do this is to contact me, and I'll send you an invite directly from Assembla. If you are already an Assembla member (sigh-up here - takes 30 seconds and it's free), you should be able to contact me through the project's team page. Either case, as far as I can tell, I have to invite you into a project - I don't think you can "apply" to join.

Once you are a member of the project, you will also be able to contribute code.

So that's it for now - as I said, I'll be posting about the initial code base shortly...

Thursday, September 20, 2007
Posted on Thursday, September 20, 2007 2:26:59 AM (Mountain Daylight Time, UTC-06:00)  Comments [0] | 
Categories: .NET | ArcDeveloper | Devt Tools

I'm in the process of creating a set of Visual Studio templates to share with the community - pretty simple stuff, but can be quite a time saver. In the past I've posted about how to streamline coding using templates, and while the process for packaging templates outlined in that post works, it's pretty manual, and that's not going to work if I'm going to maintain and grow these things. Enter MSBuild. But before I go into that, lets review how I've organized the solution.

The solution is called "ArcDevelper.Templates" - and it simply contains a bunch of other projects that contain the template files, as shown in the following graphic.

Template Solution Contents

Each project simply has the template file (class.cs for example), an associated icon, and the vstemplate file that tells Visual Studio how to transform the file. It's important to note that I'm are just using Visual Studio as an editing environment, and the solution as an organizational scheme - we do not actually "build" anything in the traditional sense.

First off the projects would not compile because the still have string parameters in them that get replaced when the templates are run (see my previous post on templates for more). What we want to do is package the files so they can be used as "templates" - this is where MSBuild comes in.

The MSBuild Script

The other thing I have in the solution is a build.xml file that actually extracts out the files, puts them into zip files and moves them to my "ItemTemplates" folder. With this in place, I can easily make changes to my templates, re-run the build script, and have the updated templates immediately available.

In order to make this work, I had to use MSBuild "batching", which is not exactly intuitive. Without getting into too much about MSBuild (Google it - there's ton's of info around), when creating the itemgroup that will be fed into the target (the actual zip & copy), you need to create some metadata for the items, and then use the Outputs attribute of the Target to subset the items by some of the metadata. As an old client of mine used to say - clear as mud. Maybe this will help...

  <ItemGroup>

    <Projects Include="$(SolutionDir)\csclass">

      <path>$(SolutionDir)\csclass</path>

      <zipname>CSClass</zipname>

      <itemname>Class</itemname>

    </Projects>

    <Projects Include="$(SolutionDir)\vbclass">

      <path>$(SolutionDir)\vbclass</path>

      <zipname>VBClass</zipname>

      <itemname>Class</itemname>

    </Projects>

  </ItemGroup>

This is the Item Group that lists the templates (projects) that we will be working with. The path, zipname and itemname sub-elements are the metadata I was talking about. This is then used by the target...

  <Target Name="Build" Inputs="@(Projects)" Outputs="%(Projects.ZipName)">

    <!-- Create a list of the files in the output folder-->

    <CreateItem Include="%(Projects.path)\%(Projects.itemname).*">

      <Output TaskParameter="Include" ItemName="FilesToZip" />

    </CreateItem>

    <!-- Zip the files-->

    <Zip Files="@(FilesToZip)" ZipFileName="$(BuildFolder)\%(Projects.zipname).zip"  Flatten="true"/>

  </Target>

The target specifically notes the inputs and the outputs. Apparently by specifying a metadata item in the outputs forces MSBuild to group / subset the items (depending on how you want to think about it) by that item. In my case, the item is unique - so I get the effect of simply looping over the list.

Anyhow - now I've got this all working smoothly, so I'll add some more stuff into the templates, and then load it up into the ArcDeveloper.net Subversion repository over at SourceForge. I'll post about the actual templates when they are up there.

Monday, September 17, 2007
Posted on Monday, September 17, 2007 10:15:52 AM (Mountain Daylight Time, UTC-06:00)  Comments [1] | 
Categories: ArcDeveloper | Community

I spent some time this weekend re-tooling the ArcDeveloper.net web site. Here's a quick look...

arcdev-peek

I'm building it on top of the open-source, ASP.NET based, ScrewTurn wiki engine, with a few custom pages and a forum package thrown in. I'm still tweaking some of the CSS, some graphics and a few pages, but I hope to have it up for some beta testers later this week. If you are interested in kicking the tires, use the Contact link at the top of this page to let me know.

I'm also looking for people who may want to post some articles on the site (kinda like a stripped down, GIS-centric CodeProject). These will be kept in a separate secure sub-wiki, so you don't need to be concerned about someone else messing with your stuff.