Sunday, 31 March 2013

Announcing: MapGuide Open Source 2.5 RC2

I was wrong.

I thought we would only need one RC before pumping out the final release, but the amount of fixes, polish and shine that's been done to Fusion since RC1 is such that a second RC is warranted.

The changes from RC1 are mostly Fusion-centric, and it's a big list.

Templates

We've fixed up some annoyances that are present in the 5 templates that come with MapGuide

Toolbar text on the TurquoiseYellow is much more legible. Black text on a black gradient toolbar did not scream readability


The templates also had various behavioural fixes to improve the user experience:
  • The sidebar of the LimeGold template could not be expanded once it was collapsed
  • For templates with collapsible sidebars, they will re-expand the sidebar if the user invokes any of the (Show Legend/Overview/TaskPane/SelectionPanel) menu items, or a widget has loaded content into the Task Pane.
Greater Widget Autonomy

Some widgets were treated as mutually exclusive widgets. That meant, if you invoke this widget, it became the active widget. These widgets had no business hijacking the active widget state and brought unnecessary confusion to the user experience. The widgets in question are:
  • Redline
  • Buffer
  • Feature Information
  • Measure
  • Query
  • Theme
These widgets all load their UIs into either the Task Pane or a popup window. As long as you can see their UIs, they should be considered active. These widgets are pretty much like Invoke URL widgets anyway: Self-managed and independent of the active widget state. 

Having their UIs open should not interfere with panning/zooming/selecting/etc. The above widgets have been modified to no longer take over or care about active state. In addition certain widgets on that list have been modified to be more self-contained, which are detailed below.

Redline

The Redline widget hasn't changed much since the last time I wrote about it. However, we did discover afterwards that SHP-based import/export was broken on Linux due to missing ZipArchive support in its bundled PHP. That has been fixed.

Measure

This widget was a prime offender in bad user interactions, the offence being leaving dangling digitizers behind. You could be panning or zooming, and it would still be measuring because the digitizers weren't deactivated and/or properly cleaned up. Other widgets on that list above shared some of the same problems with this widget, but the Measure widget was the worst of them all.

We've changed this widget in the following ways to ensure such a thing doesn't happen again.

The widget still auto-initiates measurement, but we've added manual controls to the UI to stop/start this process.


In addition, we've added an abort link to the information bar in case the Measure UI is easily hidden or obscured (eg. In the Aqua template)


Feature Information

The layers dropdown now has a refresh link, so you don't have to re-invoke the widget to refresh this list.


Query

To be consistent with every other widget that uses a digitizer, the digitizing actions in this widget now use the Information Bar to provide digitization prompts.

The widget also cleans up any active digitizers when unloaded. Part of the greater widget autonomy and self-management that I mentioned above.

Legend

The legend widget now properly displays layer nodes above the group nodes at any level in the tree, thus syncing up with the AJAX viewer and presenting the exact visual representation of your layer/group structure as shown in Maestro's Map Definition editor


Scalebar

We have a scalebar widget? Yes we did, it just didn't work until now. What you saw here is the functional scalebar widget.


ScalebarDual

We have this widget too? Yes we did. This is basically a wrapper around the OpenLayers.Control.ScaleLine control. You couldn't access and include this widget with your Flexible Layouts because it didn't have a widgetinfo XML file.

CTRLClick

This widget doesn't actually exist (hasn't for a long time), but its widgetinfo XML file was still there, thus having Maestro give you the false impression that this widget actually exists and can be added to your Flexible Layouts. Well this is definitely not the case, and the widgetinfo XML file has been removed meaning Maestro will no longer show this widget.

Center Selection

Here's another broken widget that's been fixed for this release.

Selection Panel

Did you know this widget is actually configurable with extension properties? Yeah, we didn't document them in the widgetinfo XML, that's why Maestro shows nothing for this widget. That's fixed now.

Did you also know this widget has a horizontal representation as well? Yeah, that was broken too, but fixed for this release as well.


Non-Fusion Miscellany

For this release, we've also officially deprecated Mapping Service APIs related to eMap DWF functionality. The front-end DWF map viewer was deprecated a long time ago, but nothing was official in terms of API documentation about the Web APIs that supported this viewer. Thanks to our SWIG enhancement work, you'll get nice C#/Java compiler warnings when using these APIs. 

We're doing this because eMap functionality support has been long since removed from the DWF Toolkit and MapGuide is still currently hamstrung on a super-ancient version of the DWF Toolkit due to the need to support eMap, which could also present interoperability problems with newer versions of AutoCAD and its verticals (that would be using newer versions of the DWF Toolkit). I've seen several DWF files plotted from MapGuide crash recent versions of Autodesk Design Review probably due to this reason.

Being stuck on an old DWF Toolkit was also one of the roadblocks in my failed 64-bit Linux experiment. And you know why MapGuide still doesn't support DWFX files? Same reason.

Not saying that this is what we're definitely going to be doing with a new DWF Toolkit, but it clearly shows what's stopping us from doing so (eMap support). So if we ever do upgrade our DWF Toolkit, we should at least give a one release-cycle warning. If you happen to still be using the DWF-based map viewer and/or the supporting Web APIs, this is your final boarding call to either migrate or seek alternative solutions.

I'm pencilling in a final release of 2.5 one week from now. What you see in this release will be pretty much be what's in the final release. Any issues filed against this release will be shelved to 2.5.1 or 2.6 unless those issues are of the really show-stopping nature.

Download

Wednesday, 27 March 2013

MapGuide tidbits: Fusion/AJAX Viewer similarities and differences

Disclaimer: Some of the Fusion examples here use a testing build of Fusion made after the release of MapGuide Open Source 2.5 RC1 and as such may not be reproducible on that and earlier releases of Fusion.

For this post, we're going to focus on the differences between the AJAX and Fusion viewers and their similarities.

Similarities

On a conceptual level, there are actually many similarities between the AJAX Viewer and Fusion.
  • Both have a way of defining a discrete piece of application functionality. Fusion has Widgets. AJAX Viewer has Commands
  • Both have to be defined within a master collection of functionality (WidgetSet in a Fusion Flexible Layout, CommandSet in a AJAX Viewer Web Layout)
  • UI References to these widgets are defined in the viewer's menus and toolbars (Abstracted in Fusion Flexible Layouts as "containers". Menus and Toolbars are fixed in the AJAX Viewer Web Layout)
  • Both Flexible and Web Layouts need a Map Definition specified, which all the Widgets/Commands will be interacting with.
These conceptual similarities are reflected in the similar editor workflows in Maestro.

Specifying a Map (AJAX Viewer)


Specifying a Map (Fusion)



Defining the master set of functionality (AJAX Viewer)


Defining the master set of functionality (Fusion)


Laying out menu/toolbar access to this functionality (AJAX Viewer)


Laying out menu/toolbar access to this functionality (Fusion)


This is where the similarities end

Differences (especially on widgets)

Each AJAX Viewer command type is unique with their own specialized set of configuration parameters (ie. Each command type is its own specialized XML data type in the Web Layout XML schema)

Each Fusion widget is unique, but is driven through arbitrary XML elements under the widget's "Extension" XML element. The valid XML content that can reside under the widget extension is defined by the widget's respective widgetinfo XML. Here's an example widgetinfo for the Task Pane widget. This widgetinfo XML is how Maestro is able to not only build the default XML for that widget, but also provide additional information/description about each Extension Property for that widget.



It is this arbitrary XML configuration nature of Fusion widgets that allows the ApplicationDefinition XML schema to stay the same (since the introduction of Fusion in MapGuide Open Source 2.0) and allows for individual widgets to be improved upon with additional features and properties without needing to do endless XML schema revisions (as is the case with the AJAX Viewer Web Layout)

Widget Types

In Fusion there is are two separate types of widgets
  1. Dockable widgets
  2. Non-dockable widgets
(NOTE: I'm not sure about the official terminology here, but this is the lingo I'm using for the Fusion Editor UI changes you'll see in the next release of Maestro 5.0, some of which I'm also previewing in this post)

Dockable widgets are widgets that can be housed within a Fusion "container" (ie. A menu or toolbar)

Non-dockable widgets cannot be docked within a Fusion "container". The Legend and TaskPane widgets are examples of such widgets.

The layout of such non-dockable widgets is generally handled by Fusion and its template. If such a widget is included in the Flexible Layout, Fusion will render the widget UI into the DOM element of the template with the same id. For the 5 templates that come with MapGuide, all the necessary DOM elements are set up for such widgets to be rendered into, so you generally do not have to concern yourself with such plumbing details.

The only time you need to be concerned with such details is:
  1. You are creating your own Fusion template
  2. You are using a non-standard non-dockable widget.
If you are creating your own Fusion template, you need to make sure that either declaratively or programmatically that your template provides a DOM element whose id matches the type of non-dockable widget that Fusion could render into. I won't go too much into this detailed topic, because this would most likely have to be a subject of a separate post.

If you are using a non-standard non-dockable widget (eg. Scalebar), it won't show if the template does not provide a DOM element with a matching ID, which is probably the case with the 5 standard templates. I'll show to get such widgets working later in this post.

Now the reason I want to emphasize this distinction between dockable and non-dockable widgets is because as of the latest beta of MapGuide Maestro 5.0, the Fusion editor failed to make this distinction, meaning it was possible to do illegal things like this:


And then have your Fusion template break down for the most cryptic of reasons. So we've fixed this up 2 ways.

Firstly, when you add a widget to a container, non-dockable widgets are filtered out, making it impossible to cause scenarios like the one above.

Secondly, we've tweaked the Widget Management dialog to show you which widgets are dockable and which ones are not.


Non-dockable widgets will auto-render into the template's DOM by Fusion just by existing in the Widget Set. There is no layout/placement work required on your part. That is all handled by Fusion and the template you're using. This gives a nice segway back into our Scalebar example.

The Scalebar is a non-dockable widget, and probably exists in any new Application Definition document you create in Maestro. So where is this scalebar when we load the template up with our Application Definition?


If you look at the HTML of the template (Slate). You'll come to find that there is no div in the markup or created programmatically in the template's JavaScript that has an id of "Scalebar". This is why our scalebar does not show, because Fusion could not find the matching DOM element in the template for the Scalebar widget to render into.

So to fix that, we need to put in a div with that id into the template's index.html.



(NOTE: I myself am not sure if there are any DOM placement rules we have to follow, I'm just going by a suggestion from the mapguide-users mailing list. This is a trial and error process at the moment)

If we reload the template now, you should finally see our mystery scale bar widget!


So for such non-dockable widgets (which the next release of Maestro 5.0 will help you distinguish), it's best to double-check your Fusion template's HTML/JS to make sure such widgets can be displayed.

Hopefully, this post sheds more light on how Fusion and AJAX viewers are similar, but also how they're different. But more importantly the ins and outs of widgets, the fundamental building blocks of a MapGuide Fusion application.

Saturday, 23 March 2013

MapGuide tidbits: Localization

MapGuide Maestro makes translating your MapGuide applications much simpler, but this is only half the equation. MapGuide Maestro only assists in translating your Menus and Toolbars of your viewer application. The viewer itself may require translation.

I've authored up a section of the MapGuide wiki several months ago, that covers all the localization tasks you need to do to fully translate MapGuide to your desired language.

Hope this helps.

Friday, 22 March 2013

MapGuide tidbits: The MgMap constructor

Question. How do you create your MgMap objects. Like this?

MgMap map = new MgMap();

If you do, please stop. Not only is this way of creating a MgMap object long been deprecated (thanks to RFC129, you'll now get nice C#/java compiler warnings about it), but you lose access to a whole bunch of convenience APIs that have been introduced with RFC9 (ie. MapGuide Open Source 1.2)
  • MgLayerBase.GetClassDefinition()
  • MgLayerBase.SelectFeatures()
  • MgLayerBase.SelectAggregate()
  • MgLayerBase.UpdateFeatures()
  • MgSelectionBase.GetSelectedFeatures()
These APIs are only available if your MgMap was created like so:

MgSiteConnection siteConn = new MgSiteConnection();
...
MgMap map = new MgMap(siteConn);

This constructor is deprecated along with a whole bunch of other related MgMap methods. See the RFC for more information. You should be using the alternatives as described in that RFC.

Wednesday, 20 March 2013

250 not out

Hmmm, didn't I just celebrate my 200 post milestone not too long ago?

Time either flies or MapGuide/FDO/Fusion/Maestro is still a deep pool with plenty of material to still salvage from.



Given my current draft queue, I think it's the latter :)

MapGuide tidbits: Fusion with .net/Java

Let me clear up a possible misconception with Fusion.

Just because Fusion is built with HTML, JavaScript and PHP does not mean PHP is your only choice of language for building extending application functionality through the MapGuide API.

Fusion, like the AJAX viewer both provide the same common extension points for your viewer:

  • Invoke Script commands
  • Invoke URL commands
Invoke Script commands are javascript-based, so for the AJAX viewer, you're coding commands against it's viewer API, for Fusion you're coding commands against the Fusion API

Invoke URL commands simply launch the specified URL into the Task Pane or a specified target. The AJAX/Fusion viewer does not care about whether the page serving that URL is written in PHP, .net or Java. All your viewer cares about is that your page exists and accepts a SESSION, LOCALE and a MAPNAME parameter, that contain the MapGuide session id, the desired locale code, and the map name (to be able to Open() a MgMap) respectively. You can write this page in any of the languages supported by the MapGuide Web API. The viewer doesn't care.

Besides, even if you did not install the PHP viewer as part of the MapGuide installation, PHP the runtime is still installed regardless as that's required by the MapGuide Site Administrator and the feature source previewer applications and Fusion. So PHP will never be missing in a MapGuide installation.

Sunday, 17 March 2013

Announcing: MapGuide Open Source 2.5 RC1

Here's the first (and probably only) Release Candidiate for MapGuide Open Source 2.5

The release comes in the following flavours:
  • 32/64-bit Windows Installer
  • 32/64-bit Windows InstantSetup bundles
  • 32-bit Ubuntu 12.04 deb installer
  • 32-bit CentOS 6.x tarball
This release was built with the FDO 3.8.0 RC1 binary SDKs for windows and linux and still includes the ArcSDE provider.

The key changes/fixes from beta 1 include:
All currently open tickets targeted for 2.5 will either be moved to 2.6 or closed due to ticket inactivity and/or lack of information (what did I say about this?). Only report issues targeting 2.5 if it is:
  • Related to Fusion
  • A true show-stopping defect in the server or web tier that prevents us from shipping the final release.
Otherwise, it's not considered high-priority enough for us to address for 2.5

Saturday, 16 March 2013

MapGuide tidbits: scale range gotcha

Here's a little gotcha to be aware of.

Consider this Layer Definition



Do you think this layer covers all scales from 0 to 15000?

For those who thought not, you can stop reading this post now :)

Otherwise read on.

The layer above does not actually cover all scales from 0 to 15000 because the stylizer only considers a view to be in a given scale range if the scale is greater than or equal to the minimum scale and less than the maximum scale of that scale range

ie. Your view scale is applicable for this range if: min scale <= view scale < max scale

This means for a view scale of 5000 or 10000, you actually have no matches according to the stylizer and nothing from that layer will be rendered out.

This isn't much of a big deal for a Map Definition full of dynamic layers, but for Map Definitions with tiled layers, this can be a problem. One or more of your finite scales may be off by 1 and nothing is actually rendered in your map tiles as a result.

So remembering the range check as stated above helps.

Wednesday, 13 March 2013

MapGuide tidbits: The golden rule of selection

I probably have mentioned about this in passing in a previous post, but it's probably worth repeating in a separate dedicated post because it's very important. The golden rule of selection:

For a layer to be selectable, it's feature class must have identity properties

If you can't select objects on from a layer on a map, always refer to the above rule. It will be true 99% of the time.

Now where this would commonly be the case (no identity properties) is if you are creating a layer off of a database view, where FDO is generally not clever enough to infer the identity properties from that view. In such cases, schema overrides come to the rescue allowing to you override how the FDO provider is supposed to interpret your physical data store.

Now surprisingly, this rule does not just apply to you users and developers building MapGuide applications. It equally applies to us developers hacking on the MapGuide core.

Case in point, a show-stopping bug relating to the RFC123 optimizations. After scratching my head for days wondering why a SQL Server RFC123-optimized layer was not selectable, I remembered about this rule and it lit a light bulb, giving me greater clues about the source of the problems. Turns out the MgFeatureReader wrapping our FDO join query result used for rendering/stylization presented a class definition that (you guessed it) did not have any identity properties. So when MapGuide needed to extract the class definition from the MgFeatureReader to build a selection set, there was nothing there to build a selection out of!

After some hacking around of the class definition that's returned by the reader in such cases, we now have selections working again!

So it helps to memorize this rule. It won't let you down because it sure didn't let me down.

Saturday, 9 March 2013

MapGuide tidbits: UpdateFeatures

Here's a long overdue post about a part of the MapGuide API that will no doubt confuse beginners (and some experienced ones too). The UpdateFeatures method of MgFeatureService

What does this method do?

UpdateFeatures is your one stop shop for all you spatial data CRUD needs. Don't let the name fool you, this method does the full (C)reate, (U)pdate and (D)elete portions of the CRUD quartet, the (R)ead portion handled by the SelectFeatures method. If you are going to be manipulating data in your MapGuide Feature Sources, you will need to know how to use this method.

The method signature looks like this:

MgPropertyCollection UpdateFeatures(MgResourceIdentifier resource, MgFeatureCommandCollection commands, bool useTransaction); 

and a new variant that takes MgTransaction objects was introduced in MapGuide Open Source 2.2

MgPropertyCollection UpdateFeatures(MgResourceIdentifier resource, MgFeatureCommandCollection commands, MgTransaction transaction); 

The general process of using this method is:

  1. Identify the Feature Source you are going to be manipulating
  2. Load up one or more manipulation commands 
  3. Execute the UpdateFeatures method
  4. Inspect and/or process the return value
Manipulation commands

You can load up to 3 different types of commands into the MgFeatureCommandCollection
  • MgInsertFeatures: A command that inserts one or more features/records into a specific feature class. Analogous to a SQL INSERT or BULK INSERT.
  • MgUpdateFeatures: A command that updates features in a specific feature class with the given set of property values based on a filter criteria. Analogous to a SQL UPDATE.
  • MgDeleteFeatures: A command that deletes features in a specific feature class based on a filter criteria. Analogous to a SQL DELETE.
The commands are executed sequentially in the order that they were added into the collection

Transactions

If you call UpdateFeatures with useTransaction = true or call the other variant passing in a valid MgTransaction object. The method will execute atomically inside a transaction (created internally or the one you passed in). If any failures occur, the method as a whole will fail and a MgFdoException is thrown on the first failure. 

If you passed in a MgTransaction object, you will have to remember to rollback this transaction after catching the exception. If you call UpdateFeatures with useTransaction = true, a transaction is created internally, and is rollbacked internally in the event of a failure. An MgFdoException is still thrown in this case.

If you call UpdateFeatures with useTransaction = false or call the other variant with a null MgTransaction, the method will not throw any MgFdoException, which will undoubtedly be a great source of confusion.

Exceptions that occur with a non-transactional UpdateFeatures are actually serialized out as part of the return value. Read on to the next section for the nitty gritty.

The key thing to note here is that transactions are not universally supported across the different FDO providers, so it is illegal to call UpdateFeatures with useTransaction = true if the underlying FDO provider does not support transactions. To determine whether transactions can be used, you would have to inspect the FDO provider's capabilities XML (with the GetCapabilities method).

However, if you know what Feature Sources you'll be working with up-front, then you'll most likely know what its capabilities are and you can bypass this programmatic checking of capabilities and just call UpdateFeatures transactionally or non-transactionally.

The return value

The UpdateFeatures method returns a MgPropertyCollection that contains a command result corresponding with each command in the input MgFeatureCommandCollection. The first item in the MgPropertyCollection carries the result of the first command in the MgFeatureCommandCollection, and so on.

This is the mechanism by which individual command results can be inspected in a non-transactional call to UpdateFeatures, as some commands in a MgFeatureCommandCollection may succeed and some may fail.

As a general rule, never call UpdateFeatures and disregard the return value. It is important to inspect the values in this collection to determine whether your call as a whole is a success or failure.

The type of results in this collection depends on the type of command executed:
  • A MgInsertFeatures returns a MgFeatureProperty containing a MgFeatureReader of the inserted features. You should remember to always close these readers as dangling feature readers are a notorious cause of busy resource errors.
  • A MgUpdateFeatures returns a MgInt32Property containing the number of features updated.
  • A MgDeleteFeatures returns a MgInt32Property containing the number of features deleted.
  • An MgStringProperty indicates a failure with the corresponding command and contains the serialized FDO exception message.
Now until MapGuide Open Source 2.4, we actually forgot to include that final point in the API documentation which just happens to be the most important point of them all as it is the way you check if an UpdateFeatures has partially failed in a non-transactional call. Transaction calls throw exceptions, non-transactional calls serialize internally caught exceptions into MgStringProperty objects.

Does it have to be *this* complicated?

That was my initial thought when I looked at this method the first time round. Having to create all these commands, all these collections, all these objects just to insert one feature! The API just feels so clunky with all this complex setup of the UpdateFeatures method parameters.

It is this thought that drove me to provide a simplified set of APIs in mg-desktop to simplify the insert/update/delete of spatial data, by actually providing indiviudal InsertFeatures/UpdateFeatures/DeleteFeatures methods so you don't have to go through this complex monolithic method call. Bringing such convenience APIs over to MapGuide proper is under my consideration   for something after MGOS 2.5.

My thoughts on this API changed however when I looked at the WFS-T specification. I couldn't help but notice that the WFS-T inputs and outputs described in the specification conceptually map quite easily into the inputs and outputs of this "clunky" UpdateFeatures API. So I guess this API was designed this way for a reason: To lay the groundwork for adding WFS-T support in MapGuide for anyone who accepts the challenge ;-)

In closing

So what's the minimum you should get out of this?
  • Call UpdateFeatures transactionally if you can. It simplifies error handling. All you have to do is be on the lookout for MgFdoExceptions
  • Not all FDO providers support transactions. You can programmatically check its capabilities to determine if transactions are supported. But if you know what feature sources you're working with, you would generally know up front whether transactions are available to you or not.
  • Always inspect the return value. If you don't really care, then at the minimum always close any feature readers and log/aggregate any MgStringProperty values in the MgPropertyCollections as these represent the command failures in a non-transactional UpdateFeatures call
  • Yeah the API is somewhat clunky, but IMO it's clunky for a reason. We can definitely make things simpler, but it will have to be a post-2.5 release exercise

Fusion redlining revisited.

For the next MapGuide Open Source 2.5 release (not sure if it will be another beta or straight to RC atm), we're giving the Fusion (in particular the Redline widget) a bit more spit and polish.

History

As explained previously, in this author's opinion, the original Redline widget for Fusion was completely useless functionality wise:

  • Can't plot a view of your map with your redlines
  • Can't control the styling of your redlines
  • GML is your only import/export format. Who on earth consumes GML? Certainly not Autodesk's geospatial products!
So we threw it out and rebuilt it based on the original Generic Tasks sample for the AJAX viewer.

Now admittedly, the v1 re-implementation (which was in AIMS 2013) was nothing more than a carbon copy of the Generic Tasks sample, meaning not much real thought was put into usability and user efficiency. The redlining process was a cumbersome multi-step process that didn't really scream productivity.

So for the MGOS 2.4 iteration of this widget, we patched up the usability problems, shortcutting most of the previously mandatory setup steps (with options to revisit these steps if required). We also took advantage of some previously-unknown fusion components (to me anyway) to improve the digitizing process with informative prompts.

This iteration while usable and powerful, had one remaining limitation. SDF was the only import/export format. While round-tripping between Autodesk's geospatial products is not a problem, round-tripping to other geospatial software is a problem because SDF is not exactly a well supported format outside of Autodesk's range of geospatial products.

The widget improvements

So for the MGOS 2.5 iteration of this widget, the Redline widget now supports the following formats:
  • Import: SDF, SQLite and SHP (as a zip file)
  • Export: SDF, SQLite, SHP (as a zip file), KML and KMZ
That's 2 extra import formats and 4 extra export formats!

Here's how the revised management UI looks


Most of the UI functions as it did before, so we'll just cover the bits that have changed.

What was previously the "New" button has now been separated into its own section 


This may look a bit complex, but it's not really. You pick the types of geometries you want to be able to digitize and hit the button to create the redline data store of the desired format. 

Why did we have to do this? Simple. If we want to support the ever-ubiquitous ESRI SHP file as a redline import/export format, we have to cater to its extremely cumbersome file storage limitations. While SDF/SQLite files can happily store all 3 geometry types for redline data, SHP can only support one geometry type per SHP file

So if we want the user to be able to record redlines in SHP files, we have to know what type of SHP file the user wants to create. As you can see from the screenshot, as all 3 geometry types are selected so SHP is not available as an option. But if you only checked one of those types, the ability to create a SHP file for redlines is then made available.

The second difference, is in the actual redline digitizing UI. Geometry types that cannot be digitized will be disabled. So the digitizing UI for a point-only SHP file looks like this (notice how only "Point" is enabled):



The final difference, is the expanded list of download options.


"Download Data" will serve out the redline data store as before. KML and KMZ download options take advantage of MapGuide's built-in KML service APIs to export the selected redline layer out as KML/KMZ files. Unlike the normal usage scenario, this a full KML/KMZ dump of the layer (ie. a GetFeaturesKml call) and not the map (ie. GetMapKml), which is actually a KML skeleton of NetworkLinks back into the mapagent to get the actual layer KML data.

So how does this KML look? Here's some redlines I've prepared earlier


Clicking "Download KML" or "Download KMZ" gives you the download prompt.


Which looks like this when we look at it from Google Earth


As you can see, we lose a bit of visual fidelity because MapGuide styles don't cleanly translate 1:1 to KML styles, but the core geometric shapes and text information are there.

A general note about Importing/Exporting

I guess we failed to document this when re-implementing this widget so it's better now than never.

There are some caveats to take note of when importing/exporting redlines.
  • Your export format is the format that you specified when you created/imported the redline data store. If you created a SQLite redline data store, that is what you will get prompted to download (a SQLite file) when exporting. Previously the only supported data store format was SDF, so this wasn't much of an issue.
  • If exporting redlines as SHP, you will be prompted to download a zip file. Once again, the shapefile format is not one file, but a set of inter-related files. Since we can't prompt you to download multiple files at once, the widget zips up the files in question and serves that file out for download.
  • Similarly for importing redline files. If you want to import a SHP redline, it has to be a zip file of the SHP file and its related DBF, IDX, SHX, etc files.
  • On the general subject of importing, the file you choose to upload must meet certain structural requirements in order to be accepted as a redline feature source. Generally speaking, we assume you are uploading redline files created orignally by this widget.
  • Exporting only exports the data and not its visual representation (ie. the Layer Definition)
  • Similarly, importing will set up a default Layer Definition for your uploaded data.