Monthly Archives: September 2005

Google earth WMS view scales

I have had a few emails over the last week who are wanting to increase the usability of my WMS reflector script. One of the items that keeps popping up is the lack of integrating the standard GIS view scales. That is, only certain layers are available at certain scales.

At the application level it is very easy to specify the max/min scales in say Mapserver or Arcims, but this creates more problems inside GE if you are requesting a layer that may not exist.

The workaround isn’t as nice as i would like, but it does the job. We will use the ratio variable as the pseudo-scale factor. The way i calculated a rough “maxscale” was to,

1. Echo $ratio1

[code lang=”PHP”]$ratio1 = ($coords[2] - $coords[0]);
echo $ratio1;[/code]2. Jump to the required zoom level and submit the bbox coordinates inside a browser to grab the echo’d output
3. The first number echo’d (such as 0.00251) is the value we need to add some simple ratio checking (Dont forget to comment the echo in step 1 out else you will get errors inside GE)
4. First create a new array counter $n,

[code lang=”PHP”]$n = 0;[/code]5. When declaring the WMS server arrays add your favourite bit of logic to compare against the ratio and rinse and repeat against all WMS servers in the $WMS array.

[code lang=”PHP”]if ($ratio1 <= 0.0025) {
$name[$n] = "Layername";
$WMS[$n] = "http://.../servlet/com.esri.wms.Esrimap?ServiceName=earth&VERSION=1.1.0&REQUEST=GetMap&SRS=EPSG:4326&WIDTH=".$width."&HEIGHT=".$height."&LAYERS=layername...";
$n++;
} [/code] All this extra code will do will use the coordinate ratio to determine whether a server/layer should be accessible. If not, it will not be returned in the KML and so you will have a seamless, intuitive way that WMS layers can be added to GE.Some further avenues of hacking could include,

  • limiting WMS servers to a specific geographic area (ie. only requext layer A if between coords X1,Y1,X2,Y2 and at a ratio less than B)
  • adding an image layer using the WMS getLegendGraphic request to create a dynamic legend for your WMS layers

The original source for this entry can be found here

How to convert MXD to MAP using Amein!

Let us start with an existing Arcmap mxd project. Here i have added some local shapefiles (but can be sde) and have styled them to my liking.

I will assume you have have already added the amein! plugin into your toolbar. Lets run it,

This popup gives you general layer information which isnt all that interesting. Click ‘Exit’ to get back to the main setup screen. In the bottom left of the panel there is a UK Flag, click it to switch the language to english.

The ‘Paths’ tab is pretty self explanatory. I like to add these in myself later, but Amein! allows you to save/load settings to make things easier for future conversions, so add your own setup information and move onto the ‘Project’ tab,

Theres a couple of important things you should fill out in this tab. Firstly, give your project a name as this is what the output mapfile will be called. Secondly, be sure to add your relevant EPSG code. To not confuse most reading this i will stick to using the WGS84 code of 4326.

There is further options for WMS metadata if you wish to add more tags or setup options for your keymap. I’d highly recommend leaving ‘use reference map?’ checked as Amein! will generate the jpg and also spatially reference it inside the mapfile. Another shortcut.

Scalebar tab is self-explanatory. The Legend un Query (almost english :) ) tab has (for some reason) error checking to make sure you enter a font for ‘Font of Legend Caption’. Type in ‘Arial’ and move on to the Layer tab ..

As the instructions state, the order in which you ‘edit’ the layers affects the position inside the mapfile. At this stage i wouldnt worry too much, as its easy to manually cut/paste any offending layers later. Click ‘Edit Layers’ button and then select a layer (bottom-up)

There are a lot of symbology and labelling options here. No changes are required here, so in my case i will simply press ‘Ok’ and it will take me back to the previous dialog. Notice that the layer has been removed from the ‘Feature’ list.

Try and think of that feature list as a bucket waiting to be converted. As soon as you have ‘Edit Features’ on all the layers until none are left in the list, you can continue and create the map file. Once this is done, press ‘Ok’ to create the mapfile in the folder specified in the ‘Path’ tab.

Open the mapfile in your text editor and ensure the following paramters point to the correct paths,

SHAPEPATH, SYMBOLSET, FONTSET, TEMPLATE, IMAGEPATH, IMAGEURL

Now assuming you have a working mapserver install, simply execute a relevant WMS (getmap/getcapabilities) URL. If all went well you should have an output almost identical to the arcmap project. Look ma! No hands

Enjoy

Creating 3d views from contours

Amongst my trawling of the various GIS mailinglists, i stumbled upon an interesting post in Mapserver-Users from a guy showcasing his method of creating a X3d view generated from an area of interest inside Mapserver.

Screenshot

Open3dgis.org is an opensource project that utilises PostGIS, Python, Mapserver and a variety of 3d packages to generate a 3d view from an otherwise “flat” 2d contour view. With a few small pre-requisites, if you have access to contour linestring data with an obvious height attribute, you can also create your own 3d views in about 5 seconds. The X3d format (while obviously reliant on a plugin and 3d hardware) is a good way to visualise in three dimensions.

The O3dGIS guys have a public demonstration up at http://www.opengeo.com.br/ms/o3dg/ if anyone is interested. You will need to install a X3d viewer in order to view the output.

The install instructions on their site detail a Fedora linux install, but given that the guts of the program is python i’d be interested to hear if anyone has had success on windows.

I’m impressed, simply because i never knew a Delauney algorithm existed, nor that you could generate a 3d view so easily from something as common as countour linestrings. There is obvious applications in the emergency management space as this method allows near-real time 3d views without the need for large, time consuming DEM models to be created.

SVG GIS usage to increase?

With many applications already supporting SVG output such as Geoserver, Mapserver and Arcims(?), historically the low uptake of SVG in a GIS sense has been a result of users being required to download the plugin (current SVG use at 12%, in comparison to 97% for flash, or 94% for java [source]) .

With native SVG support coming for IE v7 and Firefox 1.5, you would expect SVG GIS usage to exponentially increase and maybe even become a defacto standard, at least for viewing simple vector data.

I must admit i have had limited use with SVG, but I can definately see this little niche becoming more mainstream. I will leave you with some interesting SVG links for anyone keen to have a look at its capabilities. I’d love to hear anyone’s thoughts for the future with SVG.

Interesting times ahead ..

Carto.net repository. Great info, recommended.
Directionsmag article on SVG GIS. Good introduction and background
Arcview / ArcMap -> SVG converter
AMRI GIS Some very good SVG utils and examples
Mapinfo TAB -> SVG Converter

Time to tweak your javascript bloat

Lets take a look at a couple of js based clients out there and see some of the easy ways I use to trim the suckers down.

Ka-Map ~10 scripts total: 130kb
Arcims4 html viewer ~17 scripts, total: 291kb

1. Trimming

The Kamap devs have already included by default, a way to “compress” the javascript on the fly by removing newlines, comments by calling getcjs.php. Its a good start and easy to implement on any js app, not just ka-map and can be done similarly in another language. See brainjar.com for a static javascript implementation

//Snip $aSearch = array('///.*/', // c++ style comments - //something  '//*.**//sU', // c style comments - /* something */ '/s{2,}/s', //2 or more spaces down to one space '/n/', //newlines removed '/s=/', //space = '/=s/', // = space );  $aReplace = array( '', '', ' ', '', '=', '=',);  //remove c++ comments $szContents = preg_replace( $aSearch, $aReplace, $szContents ); ?>

Most trimming systems such as cjs.php create a new compressed file, not touching the original. This allows all the legible formatting and comments to remain in the source, but then be stripped out for use in production. This can cause some management issues, as once you trim the js, theres no way to rebuild the original source should it be lost.

2. Use JS declarations wisely

Contrary to what alot of people think, use of JS includes in the head of a webpage will affect the load time of the body. The body will simply not be rendered until the JS has been downloaded. See the problem now?

Furthermore, each individual JS document adds an increased overhead on the webserver as each definition is an additional HTTP request to the server.

Thats not to say the best thing is to dump all the code into one file though. Ideally, the best way to optimise the load is to only include the code that will be needed at a particular section and try to ensure the client caches the javascript where applicable. Its a big balancing act indeed

Recommended reading: peachpit.com article

3. GZIP encoding

If there is one thing people should enable, its gzip. All major webservers have some support for GZIP or a variation of it (eg. mod_gzip for Apache 1.x or mod_deflate for Apache 2.x). I wont bore you with details because thats all readily available at sites like webperformance.org or websiteoptimization.com. Think of it like stuffing all your js, html and CSS into a zip file … sending it to the client, and the client decompressing and viewing the contents all on the fly. Its common to save upward of 60% in filesize vs. the uncompressed source. Very big savings when you look at it in terms of download time (and bandwidth),

App Original Time (56k) CJS Time (56k) GZIP Time (56k)
Kamap 130kb 18secs 81.3kb 11secs 23.05kb 3secs
Arcims 291kb 42secs 205kb 29secs 56.55kb 8secs

Huge savings across the board.

GZIP is by far the easiest, cleanest way to noticably improve the end user’s load time, particularly on a low bandwidth connection. Unfortunately it doesnt seem to be used much on heavy javascript-centric web GIS systems. Whether or not that is due to insufficient access to the webserver or simply not knowing, there is no excuse for expecting clients to download ~300kb of javascript just so you can show that super-cool rubberbanding, aspect snapping zoom tool.

Thoughts / comments ?