Building simple clients for MapFish — Underlying Infrastructure

In order to build simple clients for the MapFish print service, we have to understand what the protocols are that are invoked and how they function.  To do this we can read the MapFish Print Module Doc, and then modify and vamp from there.  While I was going to joke that this would be an excellent cure for insomnia, the joke fell apart when I actually read the Print Module Doc, and it was clear, concise, readable, and frankly at least as interesting as most of my blog entries (no comments here please).

But, I did that after the fact.  In other words, I did it the hard way– just like you do when you bring home that really cool electronic toy, and play with it for a couple hours before (maybe, if ever) picking up the manual.  So for me, instead of reading the excellent documentation, I sniffed the protocol using a GeoExt interface to a GeoServer/MapFish combo with Firebug.  (quick aside– if you write web stuff and are new to it, then you should know you should use Firebug to write it better and test it on the fly– or if you’re a cool kid with horn-rimmed glasses and an ironic t-shirt, do it in Google Chrome’s Javascript Console, it makes no real difference as far as outcomes, just a difference in style).

In sniffing the protocol, I saw that my request for a PDF was a POST request to the server, with a JSON object as the request.  In short, the interface converts my form information into a bunch of text (a javascript object) which it pushes to the server.  The server location in this case is: http://localhost:8080/geoserver/pdf/create.json.  The text it’s pushing is a file which reads something like this:

{
	"units" : "ft",
	"srs" : "EPSG:3734",
	"layout" : "1) LETTER 8.5x11 Portrait",
	"dpi" : 300,
	"serviceParams" : {
		"locale" : "en_US"
	},
	"resourcesUrl" : "http://maps/geoserver/www/printing",
	"layersMerging" : true,
	"preferredIntervalFractions" : [0.1, 0.2, 0.4],
	"metaTitle" : "Title Here Please! GIS Print",
	"metaAuthor" : "Title Here Please!",
	"metaSubject" : "Title Here Please! GIS Print",
	"metaKeywords" : "",
	"outputFilename" : "cm_gis",
	"legends" : [],
	"layers" : [{
			"baseURL" : "http://maps/geoserver/wms?",
			"opacity" : 1,
			"singleTile" : false,
			"type" : "WMS",
			"layers" : ["cuy_bridge_decks", "planet_osm_line_outside_cuy_map", "cuy_roads_poly", "cuyahoga_street_centerlines", "reservation_bounds_solid"],
			"format" : "image/png",
			"styles" : [""],
			"customParams" : {
				"TILED" : "false",
				"TRANSPARENT" : true
			}
		}
	],
	"pages" : [{
			"center" : [2160649.7795275, 597547.8687664],
			"scale" : 6000,
			"rotation" : 0,
			"mapTitle" : "Title Here Please!"
		}
	]
}

I’ll call your attention to the last little bit of code in the object:


"pages" : [{
		"center" : [2160649.7795275, 597547.8687664],
		"scale" : 6000,
		"rotation" : 0,
		"mapTitle" : "Title Here Please!"
	}

]

I was proud of myself for recognizing (through the haze of a guy who’s modified a lot of javascript, but never learned it proper-like) that this is a javascript array with just one object.  Which means, we can make it an array with more than one object.  Eureka!  multi-page pdfs with just 5-6 more lines of code:


"pages" : [{
		"center" : [2160649.7795275, 597547.8687664],
		"scale" : 6000,
		"rotation" : 0,
		"mapTitle" : "Title Here Please!"
	}, {
		"center" : [2216902.0734907, 596701.84251968],
		"scale" : 1800,
		"rotation" : 0,
		"mapTitle" : "Title Here Please!"
	}
]

Now, just to figure out how to test this out without building a web page to do it.  curl is our friend here, just a few extra flags for telling the server what we are doing with the json file (thanks to this post):

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d @test.json http://localhost:8080/geoserver/pdf/create.json

And now for all the json fit to print:

{
	"units" : "ft",
	"srs" : "EPSG:3734",
	"layout" : "1) LETTER 8.5x11 Portrait",
	"dpi" : 300,
	"serviceParams" : {
		"locale" : "en_US"
	},
	"resourcesUrl" : "http://maps/geoserver/www/printing",
	"layersMerging" : true,
	"preferredIntervalFractions" : [0.1, 0.2, 0.4],
	"metaTitle" : "Title Here Please! GIS Print",
	"metaAuthor" : "Title Here Please!",
	"metaSubject" : "Title Here Please! GIS Print",
	"metaKeywords" : "",
	"outputFilename" : "cm_gis",
	"legends" : [],
	"layers" : [{
			"baseURL" : "http://maps/geoserver/wms?",
			"opacity" : 1,
			"singleTile" : false,
			"type" : "WMS",
			"layers" : ["cuy_bridge_decks", "planet_osm_line_outside_cuy_map", "cuy_roads_poly", "cuyahoga_street_centerlines", "reservation_bounds_solid"],
			"format" : "image/png",
			"styles" : [""],
			"customParams" : {
				"TILED" : "false",
				"TRANSPARENT" : true
			}
		}
	],
	"pages" : [{
			"center" : [2160649.7795275, 597547.8687664],
			"scale" : 6000,
			"rotation" : 0,
			"mapTitle" : "Title Here Please!"
		}, {
			"center" : [2216902.0734907, 596701.84251968],
			"scale" : 1800,
			"rotation" : 0,
			"mapTitle" : "Title Here Please!"
		}
	]
}

*Updated with better formatted sourcecode, thanks to notepad++’s JSMin plugin

One thought on “Building simple clients for MapFish — Underlying Infrastructure

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.