Thursday, 2 May 2013

MapGuide tidbits: MgByteReader and friends

This one's a bit of a post for newbies, so you can skip it if you already know this stuff :)

If you look at the various bits of the MapGuide API, you'll probably see lots of references to MgByteReader lying around. An API will either return one or require one as part of its method parameters.

What is a MgByteReader? A MgByteReader is basically a MapGuide analogue to your Stream class in .net/Java and serves the same purpose: an unified I/O abstraction for things that can be fed into the MapGuide API and things that are returned from the MapGuide API. Things like.

  • Images (of rendered maps/selections)
  • Resource Data files (to download/upload)
  • XML files (to/from the repository)
  • DWF files (for DWF ePlots)
So if you're given an MgByteReader from a particular API, what can I do with it? Similarly, if an API requires passing in a MgByteReader, how can I make one?

Here's a diagram I made up that should explain everything to you.

Since MgByteReader is basically a stream, you might be wondering if the .net/Java/PHP wrappers to the MapGuide API provides any adapters to allow MgByteReader objects to be consumed as Stream objects, so you don't have to do any manual conversion. For PHP and Java, you're out of luck. You'll have to dump the MgByteReader into a supported form as per the above diagram, and then work from there.

For .net however, I've already solved this problem for you :) If you're using the Maestro API (that wraps both the official MapGuide API and the mapagent interface), for APIs that return MgByteReader objects Maestro provides wrapper APIs that return System.IO.Stream objects instead. Similarly for APIs that take MgByteReader parameters, Maestro's wrapper API takes System.IO.Stream objects.

If you're not using Maestro, there's a MgReadOnlyStream class I wrote for mg-desktop that can easily be reused for your own .net applications if you require a System.IO.Stream adapter. MgReadOnlyStream provides mg-desktop an easy way to convert the output of a rendering service API into something that requires a System.IO.Stream (eg. a System.Drawing.Image). That's pretty much the gist of how our mg-desktop viewer works, taking MgByteReader objects from the rendering service, wrapping it into a MgReadOnlyStream and feeding that to a System.Drawing.Image, to then be painted onto a WinForms control surface.

Hope this helps.

No comments: