Showing posts with label AutoCAD Map. Show all posts
Showing posts with label AutoCAD Map. Show all posts

Thursday, 9 January 2014

GS1452: Using the Power of AIMS and AutoCAD Map 3D to Manage Assets and Facilities

It turns out the presentation that one of our major clients presented at Autodesk University 2013 was also recorded as well.

If you have a registered AU account, you can watch the presentation online here.

Friday, 25 October 2013

Going to Autodesk University?

Well I'm not going unfortunately. But one of our major clients is.

Recep Alakus from Hume City Council will be at Autodesk University 2013 to present about using AIMS and AutoCAD Map3D to manage assets and facilities.

Most of our MapGuide-related handiwork is in use at Hume City Council. So this presentation may be of interest to any of you that are going to AU.

Saturday, 11 May 2013

MapGuide tidbits: Maximizing .net code reuse

Code reuse is always a good thing. If you use the .net MapGuide API, you may want to consider some options that can enhance re-usability of your code.

For those who don't know, the MapGuide API is an extension of a common subset known as the Geospatial Platform API. AutoCAD Map3D extends this subset to integrate with AutoCAD Map3D, MapGuide extends this common subset to support web applications and mg-desktop extends this subset to give you a portable MapGuide environment for your desktop applications.



As you can see from the diagram there are key abstract classes in the Geospatial Platform API that are derived by the various implementations (bolded for emphasis). It just so happens that these classes are the key classes for working with maps and layers and the rest of the API through service classes.

By writing your .net code to work against the abstract classes in the Geospatial Platform API, you get to maximize its reuse against the various extensions of this common subset. For example, have your code:
  • Work against MgMapBase instead of MgMap, MgdMap or AcMapMap
  • Work against MgLayerBase instead of MgLayer, MgdLayer or AcMapLayer
  • Work against MgResourceService instead of AcMapResourceService or MgdResourceService
You hopefully get the idea. Where possible, work against the abstract class instead of the concrete implementation.

Writing code this way makes the code more amenable to easy manual dependency injection, with your MapGuide, mg-desktop or AutoCAD Map3D specific code doing the actual injecting, but the dependency injectee not having to care because it works against the abstract class and not the concrete implementations, thus allowing this injectee code to be re-used anywhere that can provide a concrete implementation of the class.

Of course, each extension of the common subset has their own implementation quirks. AutoCAD Map3D has some, mg-desktop has some too. But if such quirks do not affect you, then this coding strategy is something to consider if you want to re-use such code beyond MapGuide web applications.

Wednesday, 29 August 2012

A 200 post retrospective

When I first opened shop, I knew this blog was going to be about MapGuide and FDO in some form or another.

I just didn't imagine that 4 years and 200 posts later to the present day, that this blog would become the defacto knowledgebase of all things MapGuide and FDO, and that I would still have plenty of MapGuide-related things to talk about.

So to celebrate the 200th posting on this blog, here's some highlights of my double-century blogging run (in chronological order).

See you later at 300 posts (assuming I haven't ran out of interesting things to blog about)

Monday, 5 September 2011

Taking MapGuide beyond the Server and Web right into your desktop




Previously, I briefly mentioned how the new Local Connection mode in the next release of Maestro was backed by a new desktop implementation of the MapGuide API. This (lengthy) post covers this

Preface

Let's start with a little personal backstory of mine.

Remember this software?

The MapGuide ActiveX viewer (source: Directions Magazine)

Now truth be told. I was not a major fan of Autodesk MapGuide 6.5. I guess that could be attributed to the following:
  • I was just getting started not only with Autodesk products and technologies, but also on the basic concepts, practices and workflows of GIS systems. So for all intents and purposes, I was a total noob at the time.
  • Windows only. Ewwwwww!
  • The viewer is an ActiveX control that can only be embedded in Internet Explorer. Ewwwwwww!
Now the first time I got acquainted with MapGuide was in 2005 with the 6.5 version. It was also the time at my first ADN event when I heard about Autodesk's next version of MapGuide. Seeing the demos of this next version in action was quite a mind-blowing experience, given my not-so-positive experience with MapGuide 6.x. 

The AJAX-based viewer, multi-platform support, purty looking maps, flexible data access through this mysterious (at the time, to me) FDO technology and the list goes on. It just ticked all the boxes of what a modern, open-ended web mapping system should be. But then came the biggest bomb-shell of them all: It will all be open source!* So then several months later, the very first version of MapGuide Open Source was released and the rest (as they say) was history.^


Now despite my less-than-flattering opinion about MapGuide 6.x. It did have some very unique qualities to it that has yet to be replicated in MGOS/AIMS. Its map viewer, due to being based on ActiveX meant it could be embedded into .net applications. The second quality was that MWF files can contain static layers. This combination meant that it was possible to build mobile and disconnected MapGuide applications in .net or any other windows technology that supports COM (Component Object Model)


And it is in this respect that MGOS/AIMS has nothing comparable in its technological offerings.
  • Disconnected? Not a chance! Client applications must be connected at all times. No server connectivity = no maps for you! Even the latest mobile extension for AIMS still requires constant connectivity.
  • Mobility? You could have a full blown MGOS/AIMS installation on localhost, which your windows application can communicate via an embedded Internet Explorer. A functional, but very inelegant configuration. Nothing approaches the simplicity of a windows application + static MWF + 3mb ActiveX control configuration that was possible with MapGuide 6.x
So while MGOS/AIMS does most things leaps and bounds better than MapGuide 6.x, there are some other things where it pales in comparison.


Enter the MapGuide Desktop API (hereby known as mg-desktop for the rest of this post). mg-desktop is a desktop implementation of the MapGuide Platform API allowing for the same feature data access, map rendering/stylization functionality as the MapGuide Server, but without needing a MapGuide Server installed on your machine!


Genesis


The seeds of the MapGuide Desktop API were planted with this groundbreaking AU 2009 presentation. This presentation, for those unable to access that link showed how MapGuide Open Source actually has lots of shared components that can actually be re-used outside of the MapGuide Server and Web tiers. 

The main example from that presentation was a simple snapshot application that can produce a rendered map image or DWF file from a list of named Layer Definition documents without ever needing to contact a MapGuide Server ever! The first thought I had after seeing that presentation, was simply: Can't we just use a Map Definition to drive all this?


The second thought was, that AutoCAD Map already proved that the MapGuide API can be taken in a different direction, away from the MapGuide Server/Web Tier to become a API inside AutoCAD Map





So couldn't we have another implementation that makes it a fully self-contained framework that is usable by any desktop application, taking the concepts proven feasible by that AU presentation to its logical conclusion? mg-desktop is my answer to that question.

mg-desktop is a desktop implementation of the Geospatial Platform API, with its own implementation of the core platform classes, as shown below:



Where the MapGuide API operates in the context of the MapGuide Server/Web Tier and the AutoCAD Map Platform API operates in the context of inside AutoCAD Map, mg-desktop operates in a standalone context, with no dependencies on any particular application. It provides a suitable foundation for creating your own desktop-based MapGuide application.

In addition to implementing the core classes and services of the Geospatial Platform API, it also includes some of the additional service APIs provided by the MapGuide API, such as:
  • MgRenderingService
  • MgDrawingService
  • MgTileService
mg-desktop also supports loading of MapGuide Packages (*.mgp). So you can transfer data and resources from a MapGuide Server to an mg-desktop installation.

Key Differences from the MapGuide API

Because mg-desktop is a desktop implementation of the Geospatial Platform API, some concepts which were applicable in MapGuide and/or AutoCAD Map no longer apply in mg-desktop:
  • There is no session expiry :D Session resources still exist as a way to have temporary resources
  • There is no resource security model
  • On the same subject, there is no authentication required for access to services.
  • There is no need to open/save runtime map state. Everything operates off of the current state of the runtime map in memory.
The mg-desktop implementation of MgResourceService wraps a pre-defined directory on the file system. Folders and resources in the mg-desktop repository conceptually map to files and folders in the file system.


The mg-desktop implementation of MgFeatureService is a thin wrapper around FDO. Each service API maps to a corresponding FDO command. All FDO types that would be returned are wrapped up and/or converted to their corresponding Mg* counterparts.


Aside from these differences, it's the same MapGuide API that you've come to know all along.

Unique APIs


mg-desktop not only just implements the abstract classes in the Geospatial Platform API, but extends them with our own additional APIs to correct my perceived shortcomings of the current MapGuide APIs. Here's an overview of the unique APIs of mg-desktop.


MgdFeatureService


MgdFeatureService is the desktop implementation of MgFeatureService and includes the following extra methods:
  • RegisterProvider - Registers a new FDO provider into the provider registry by its library path
  • UnregisterProvider - Removes a registered FDO provider from the provider registry by its provider name
  • InsertFeatures - Allows for individual insertion of features into a feature class, instead of having to use the monolithic UpdateFeatures
  • DeleteFeatures - Allows for individual deletion of features in a feature class, instead of having to use the monolithic UpdateFeatures
  • UpdateFeatures - Although it unfortunately shares the same name as the monolithic method it's trying to replace, this allows for individual updates of features in a feature class.
  • SelectFeaturesExtended - Almost identical to SelectFeatures, except this returns a scrollable feature reader that behaves similarly to the FDO scrollable feature reader
MgdLayer


MgdLayer is the desktop implementation of MgLayerBase which adds extra convenience methods, allowing you to operate on the layer itself instead of needing to obtain an MgFeatureService reference and the layer's feature source id and class name:
  • BeginTransaction - Convenience form of MgFeatureService.BeginTransaction
  • SelectFeaturesExtended - Convenience form of MgdFeatureService.SelectFeaturesExtended
  • InsertFeatures - Convenience form of MgdFeatureService.InsertFeatures
  • DeleteFeatures - Convenience form of MgdFeatureService.DeleteFeatures
  • UpdateFeatures - Convenience form of MgdFeatureService.UpdateFeatures


The Map Viewer Component


So having a reusable library to build your own geospatial applications is good and all, but is there something out-of-the-box like a map viewer that we can embed in a .net application? The answer is an emphatic yes. mg-desktop includes an embeddable map viewer component!




This is not some trick of embedding a web browser to use the AJAX viewer to talk to a local or remote MapGuide Server, this is all native .net WinForms controls and using the same self-contained MapGuide rendering and stylization services provided by the mg-desktop library and it does pretty much everything you can do in the AJAX/Fusion viewer.

What about more complex stuff like digitizing and redlining? No problem. It can do that too!








And all of this is functionality is contained in one single sub-100kb dll! (OSGeo.MapGuide.Viewer.dll). The next release of Maestro will be using this viewer component for previewing Feature Sources, Layer Defintions, Watermarks and Map Definitions in the new Local Connection mode

In Closing...


I have submitted a pending RFC to have this included in the official MapGuide source tree, which would greatly improve integration, code re-use and ability to receive fixes and enhancements to upstream components.


The source and binaries# for the mg-desktop library (and map viewer) are available from the Google Code project home page. Note that FDO that is included with the binaries is a partial distribution (because I lack the ability to build certain FDO providers). You will need a Mercurial client to checkout the source code.

If you want to build the source, you will need to do a full svn checkout of MapGuide Open Source and FDO trunk. Then you will need to build FDO and the MapGuide Oem components first before you can finally build mg-desktop. The hg clone needs to reside in a Desktop subdirectory under MgDev in your MapGuide svn working copy. There is currently no 64-bit or Linux targets yet, so feel free to submit any patches.


* Let's give credit where it's due here. mg-desktop, Maestro and FDO Toolbox would not exist if it weren't for Autodesk open sourcing the MapGuide product and FDO technology. Similarly, my knowledge of MapGuide and FDO wouldn't have reached encyclopedic levels that they are today if these technologies were not open sourced.

^ As most of us found out, v1.0.0 of MapGuide Open Source turned out to be pretty rough round the edges and performance of Feature Joins (which 6.x handled brilliantly) was absolutely woeful and buggy, which sadly is still applicable to this very day. But this is a known problem with a known workaround, which is to have all the data in a centralised, spatially-enabled RDBMS, which you should be already doing in the first place.


# To reduce download size, mg-desktop contains a reduced distribution of CS-Map. If there are problems due to missing coordinate systems, download the country-specific grid files here and drop them into the Dictionaries directory.




Thursday, 25 November 2010

A PostGIS Public Service Announcement

If you use PostGIS, avoid using the OSGeo.PostGIS provider. It hasn't been maintained for quite some time now and there are many un-fixed stability and performance problems that have made this provider unsuitable for production use.

Instead, use the OSGeo.PostgreSQL provider which is included in the 2.2 release of MapGuide Open Source (currently in RC), Autodesk MapGuide Enterprise 2011, AutoCAD Map3D 2011 and recent releases of FDO Toolbox.

The OSGeo.PostgresSQL provider is built on the same robust core as the MySQL, SQL Server and other RDBMS providers, and provides better stability and reliability than the old provider.

The OSGeo.PostGIS provider is not included in the next version of FDO. The next beta of FDO Toolbox will not include this provider, as it is using the next version of FDO.

So for those still using the old provider, take this as a warning to start migrating your PostGIS connections and layers in MapGuide over to the new provider before it's too late!

Tuesday, 6 July 2010

Connecting to MS Access databases with the 64-bit FDO ODBC provider

One of the (many) joys of going 64-bit is the astronomically huge amount of memory (2^64 bytes) you can throw at any application.

However, one of the pains thus far (on Windows at least) is the lack of connectivity to MS Access databases due to a lack of a fully native 64-bit ODBC driver.

Well it seems Microsoft have finally listened to its 64-bit userbase and finally released 64-bit drivers for Microsoft Access Databases last month.

Now how can we use these drivers in the just released 64-bit FDO Toolbox? If you thought the Connect to ODBC command choosing MsAccess as the data source type (like I first did), then you thought wrong.

It turns out the Office 2010 ODBC drivers have slightly tweaked the required connection string.

Here's what a current MS Access ODBC connection string would look like:

Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\parcels.mdb

If you used that same connection string in a 64-bit FDO Toolbox, that will not work (you'll get an error message similar to: RDBMS: No open database). You have to tweak that string so it looks like this:

Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=C:\parcels.mdb

That will load the correct 64-bit driver.

Now I had just made this discovery after releasing the first ever 64-bit FDO Toolbox, so in the meantime to connect to MS Access databases using the 64-bit FDO Provider, choose Connect to ODBC command using the Generic data source type.

This will present a simple UI which will allow you to enter the raw ODBC connection string.

And remember that FDO Toolbox is just another FDO client application, so this method should work for any other application that uses 64-bit FDO, like: AutoCAD Map 2011 and MapGuide Enterprise 2011

Wednesday, 3 February 2010

WPF + Geospatial Platform API = A recipe for failure

If you use WPF in your AutoCAD Map applications and you are using the Geospatial Platform API you may encounter something like this when designing any WPF content:



The type initializer for '<Module>' threw an exception.
at System.Reflection.CustomAttribute._CreateCaObject(Void* pModule, Void* pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
at System.Reflection.CustomAttribute.CreateCaObject(Module module, RuntimeMethodHandle ctor, IntPtr& blob, IntPtr blobEnd, Int32& namedArgs)
at System.Reflection.CustomAttribute.GetCustomAttributes(Module decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes)
at System.Reflection.CustomAttribute.GetCustomAttributes(Assembly assembly, RuntimeType caType)
at System.Reflection.Assembly.GetCustomAttributes(Boolean inherit)
at MS.Internal.ReferenceAssemblyUtils.SafeGetCustomAttributes(Assembly assembly, Type filter, Boolean inherit)
at MS.Internal.Xaml.ReflectionProjectNode.BuildNamespaces()
at MS.Internal.Xaml.ReflectionProjectNode.Find(Identifier namespaceUri)
at MS.Internal.Xaml.PrefixScope.FindType(XamlName name)
at MS.Internal.Xaml.XmlElement.FindElementType(PrefixScope parentScope, IParseContext context)
at MS.Internal.DocumentTrees.Markup.XamlSourceDocument.get_RootType()
at Microsoft.Windows.Design.Documents.Trees.MarkupDocumentTreeManager.get_RootType()
at Microsoft.Windows.Design.Documents.MarkupDocumentManager.CalculateLoadErrorState()
at Microsoft.Windows.Design.Documents.MarkupDocumentManager.get_LoadState()
at MS.Internal.Host.PersistenceSubsystem.Load()
at MS.Internal.Host.Designer.Load()
at MS.Internal.Designer.VSDesigner.Load()
at MS.Internal.Designer.VSIsolatedDesigner.VSIsolatedView.Load()
at MS.Internal.Designer.VSIsolatedDesigner.VSIsolatedDesignerFactory.Load(IsolatedView view)
at MS.Internal.Host.Isolation.IsolatedDesigner.BootstrapProxy.LoadDesigner(IsolatedDesignerFactory factory, IsolatedView view)
at MS.Internal.Host.Isolation.IsolatedDesigner.BootstrapProxy.LoadDesigner(IsolatedDesignerFactory factory, IsolatedView view)
at MS.Internal.Host.Isolation.IsolatedDesigner.Load()
at MS.Internal.Designer.DesignerPane.LoadDesignerView()


A nested exception occurred after the primary exception that caused the C++ module to fail to load.

at <CrtImplementationDetails>.ThrowNestedModuleLoadException(Exception innerException, Exception nestedException)
at <CrtImplementationDetails>.ThrowNestedModuleLoadException(Exception , Exception )
at <CrtImplementationDetails>.LanguageSupport.Cleanup(LanguageSupport* , Exception innerException)
at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* )
at .cctor()


Type constructor threw an exception.
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
at <CrtImplementationDetails>.DoCallBackInDefaultDomain(IntPtr function, Void* cookie)
at <CrtImplementationDetails>.DoCallBackInDefaultDomain(IntPtr , Void* )
at <CrtImplementationDetails>.LanguageSupport.InitializeDefaultAppDomain(LanguageSupport* )
at <CrtImplementationDetails>.LanguageSupport._Initialize(LanguageSupport* )
at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* )

Though you can still build and run the project, the WPF designer is completely hosed, all intellisense is lost and as a result, the WPF designer becomes a bloated version of notepad.

The reason that happens is because the Autodesk.Map.Platform.dll is actually just a thin managed wrapper to the unmanaged AcMap* dlls in your AutoCAD Map installation, so the WPF designer is actually trying to locate these dlls from either:
  • The project's output directory
  • Or, some special working directory that's defined by Visual Studio (where this is, I have no idea)
After 5 hours of sleuthing around, I have found an acceptable workaround.

Simply put the AutoCAD Map installation directory into your PATH environment variable and restart Visual Studio. The WPF designer will correctly locate the AcMap* dlls and you'll regain full designer functionality.

This little tip will no doubt be useful to someone out there. I lost 5 work hours so you don't have to :-)