Getting Started with DotSpatial 1.0 Desktop Mapping

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. This article provides a quick overview and functional code that will help you get started with DotSpatial. Some of the basic operations that can be performed include: loading a shape file, panning and zooming.

Downloading DotSpatial

This article is based on the DotSpatial 1.0 Release — Minimal located on the downloads tab at http://dotspatial.codeplex.com

image

Note: Be aware that your browser may add an identifier to downloaded files which results in “blocked” dll files. You can click the following link to learn how to “Unblock” files. Right click on the zip file before unzipping, choose properties, go to the general tab and click the unblock button.

image

Once you have extracted the downloaded archive, you may run DemoMap.exe to get a sense of the capabilities in DotSpatial.

Creating a project

Start Visual Studio 2010 and create a new project. By using the Windows Forms Application template, a form is added to our project. Later, we will place visual elements on this form.

image

Adding Toolbox items

The toolbox provides a way to drag and drop controls onto the design surface of a form. Generally, when a control is dropped onto a form, Visual Studio will generate code necessary to instantiate the control, and add any required references to the project. You could instantiate the control without using the designer, by writing the appropriate code and making any necessary references.

Make sure the Solution Explorer is visible (View, Solution Explorer). Double-click Form1 to view it in Design view. Make the Toolbox visible (View, Toolbox). Optionally, create a new tab to contain the DotSpatial controls by right-clicking in the toolbox and clicking Add Tab in the context menu.

image

Right click in the tab you just created or in the General tab and click Choose Items…

image

Click Browse… and navigate to the location where you downloaded the DotSpatial files. Select DotSpatial.Controls and click Open, then OK.

image

You should see a number of DotSpatial control fill the Toolbox.

image

Laying out the user interface

Drop four Button controls onto the design surface of Form1. You can find the button in the Common Controls tab of the Toolbox. Also, drop a Map control onto the form. You will probably want to resize the form so that there is more space for placing the controls.

image

Adding DotSpatial references

You will notice that Visual Studio adds a reference to DotSpatial.Controls when you drop the Map control onto Form1. If we try to build the project at this point, however, we are notified that we need to add additional references to the project.

Add references to key DotSpatial libraries by clicking Project, Add Reference.…Browse to the location where you downloaded the files. Select DotSpatial.Data and DotSpatial.Symbology. You can select multiple files by holding the CTRL key while individually clicking on them.

clip_image001

Setting control properties

We return to the form designer to set properties of the various controls we have added. Again, this could be done in code, but properties may be easier to discover in the Properties Window. Select button1 and look at the Properties Window (View, Properties Window). Notice the Text property is “button1.” Change it to “Open File.” It is wise to change the name of the button as well to represent its function. Find (Name) and change it to “uxOpenFile.” Prefixing the button name with ux is simply a convention. You won’t be able to include spaces in a control name.

image

Similarly, update buttons 2-4 to represent Zoom In, Zoom Wide, and Pan. Remember to rename them. Rename the map from “map1” to “uxMap.”

image

If you were to run the project at this point, you would find you could drop a file onto the map control, but we haven’t yet wired up the buttons and they won’t do anything if you depress them. The designer in Visual Studio has a shortcut that will create a button event handler and take us to it so we can add our own code. Double click the Open File button. You are taken to the appropriate event handler. Type the following:

uxMap.AddLayer();

The AddLayer method will show the user a dialog so that they can select a relevant file to display on the map control.

Return to the form designer by double clicking on Form1 and create an event handler for Zoom In. Type the following code into the event handler.

uxMap.ZoomIn();

Now, when a user clicks the Zoom In button, the map view will lurch forward. You’ll similarly add the following code to deal with the situation when the user clicks the Zoom Wide button.

uxMap.ZoomToMaxExtent();

For the final button, instead of going back to the designer, just paste this code below the event handler for Zoom Wide. You need to make sure you paste it just after the event handler and above the two trailing braces }.

private void uxPan_Click(object sender, EventArgs e)
{
     uxMap.FunctionMode = DotSpatial.Controls.FunctionMode.Pan;
}

Now we need to attach this method to the uxPan Button. Double Click Form1 to return to the form designer and select the uxPan Button. In the Properties Window, click the lightning bolt icon to view Events. Type uxPan_Click into the Click Action.

When a user clicks the pan button, the cursor will change to a Pan (hand) symbol. In this mode, the map can be dragged from right to left, etc. While our previous event handlers execute methods, this event handler changes the FunctionMode of the map. The map will remain in pan mode until the user closes the application. Alternately, you could add buttons that would toggle the map into other modes.

Build and run your project and open a data file (see resource section for samples).

Points of Interest

You should be able to easily expand this project to include buttons which toggle between the Info, Measure, and Select tools.

This 1.0 release version supports the .Net 4 Client Profile.

Resources

dotspatial.codeplex.comAdditional information and documentation about DotSpatial

mapwindow6.codeplex.comMapWindow 6 – an extensible DotSpatial-based application

naturalearthdata.com Sample data files

www.diva-gis.org/gdata Sample data files

Advertisements

How to Create an Extension for DotSpatial Desktop Mapping GIS

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. This article explains how to create a DotSpatial extension by using the online template. Though this template is for C#, you can do something similar in other .Net languages.

Downloading Visual Studio

There are several free IDEs available, namely SharpDevelop, MonoDevelop, and Visual Studio Express. None of these presently support the template, however, so you’ll need Visual Studio Professional or better. Notably, Visual C# 2010 Express should support this template if NuGet becomes available.

Creating a New Project

Start Visual Studio 2010 and open the New Project dialog (File, New, Project…). Click the Online Template Tab and search for DotSpatial.

image

Select the DotSpatial Plugin Template from the list of results, name your project and click OK.

After accepting any applicable license agreement, the template will download and install and your project will be created.

image

Once you have initially downloaded and installed the template, you can create new projects using this template without going online and searching. It will be listed along with your other installed templates. Also, if we update the template, you may be prompted by Visual Studio to update your copy of it.

Customizing the extension

The advantage of creating an extension is that it can be published to the public extension feed or opened in any supported application, such as MapWindow 6.

Let’s modify our extension so that it shows the number of layers presently open.

The code corresponding to the extension is in MyPlugin1.cs. Open this file and change “My Button Caption” to “Show Layer Count”.

Replace the comment in the ButtonClick event handler method with code so that a progress message is displayed when the menu item is clicked:

public void ButtonClick(object sender, EventArgs e)
{
    string message = String.Format("Number of Layers: {0}",
        App.Map.Layers.Count);
    App.ProgressHandler.Progress(null, 0, message);
}

Building and running

The template contains a number of NuGet packages and a sample executable so that you can build and run your project without any further ado! (Debug, Start Debugging) The plugin will be copied to the appropriate directory and you will be presented with a sample legend, toolbox, and map configuration.

image

Feel free to drop a layer onto the map or click the menu item that was created.

 image

How to communicate between two extensions

I was asked by one developer how he might share data between two (DotSpatial) extensions and “light up” when the second extension was available.

This quick example shows exporting a method and importing it elsewhere by using a contract name. As long as the contract names and the signatures match, the export will be made available to the matching import by MEF.

public class MefImportPlugin : Extension
{
    public override void Activate()
    {
        App.HeaderControl.Add(new SimpleActionItem("Retrieve Message", ButtonClick));
        base.Activate();
    }

    public override void Deactivate()
    {
        App.HeaderControl.RemoveAll();
        base.Deactivate();
    }

    public void ButtonClick(object sender, EventArgs e)
    {
        var message = GetLayerCountMessage();
        System.Diagnostics.Trace.WriteLine(message);
    }

    [System.ComponentModel.Composition.Import("LayerCount.Message")]
    public Func<string> GetLayerCountMessage
    {
        get;
        set;
    }
}

 

public class MefExportPlugin : Extension
 {
     private string _Message;
     public override void Activate()
     {
         App.HeaderControl.Add(new SimpleActionItem("Show Layer Count", ButtonClick));
         base.Activate();
     }

     public override void Deactivate()
     {
         App.HeaderControl.RemoveAll();
         base.Deactivate();
     }

     public void ButtonClick(object sender, EventArgs e)
     {
         _Message = String.Format("Number of Layers: {0}", App.Map.Layers.Count);
         App.ProgressHandler.Progress(null, 0, _Message);
     }

     [System.ComponentModel.Composition.Export("LayerCount.Message")]
     public string Message()
     {
         return _Message;
     }
 }

These are standard Managed Extension Framework capabilities, so you can find more documentation by searching for MEF.

How to Add a Map to a Windows Forms Application

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. This article explains how get DotSpatial mapping inside of your existing application.

Using NuGet

DotSpatial can be installed as a standard NuGet package. This means you can easily get mapping functionality in your existing application. For this tutorial, we assume you have already installed NuGet (and are using a version of Visual Studio that supports NuGet).

DotSpatial is broken out into a number of NuGet packages. The one with a map control for Windows Forms in DotSpatial.Controls. We’ll actually use the DotSpatial.Controls.Sample package, which has a dependency on DotSpatial.Controls and brings a sample form into our project. Because NuGet packages modify projects, and not Visual Studio, a package isn’t able to add controls to the Toolbox, but we can copy the map from the sample form into the correct place in our project or just use the form directly.

DotSpatial.Controls.Sample package is designed to work with C# Windows Forms applications.

Adding a reference to DotSpatial

Open your existing project in Visual Studio. Use the package manager (Project, Manage NuGet Packages…) to search for DotSpatial.Controls.  Select DotSpatial.Controls.Sample and install it.

This will install all of the needed dependencies and add MapForm.cs to our project. When we close the package manager we may be prompted to reload our project. As of NuGet 1.8 adding forms to a project is not directly supported, and the project is programmatically edited to add the form properly. Reload the project (as prompted).

image

Instantiating MapForm

You can examine MapForm in the designer, and will note that it displays a DotSpatial map control that is docked to fill the form. You can copy this control to an appropriate place in your application or display the form as demonstrated below. I show the form on a button click. This is rather trivial because the MapForm is added to your application’s root namespace.

private void showMapButton_Click(object sender, EventArgs e)
{
    var form = new MapForm();
    form.Show();
}

Build and run your application!

After running the application I loaded an image onto the map by dragging it onto the map control. Then, I zoomed in by using the spacebar and scroll wheel.

image

Points of Interest

Visit http://dotspatial.codeplex.com to learn how to get more out of your DotSpatial map control.

Using MEF Contracts to Coordinate Communication Between Extensions

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. This article explains how to allow extensions to communicate with one another. You will want to follow the introductory article, as we add additional functionality to the extension created in that article.

In many cases one class library will reference another in order to access functionality provided by the latter. Sometimes, however, these relationships are established at runtime to provide the user with more flexibility to mix and match components. In other cases, an extension is written so that it is itself extensible and will provide some service to other extensions which follow a proscribed convention, or it will “light-up” when other extensions expose the appropriate data or methods.

There are several approaches in DotSpatial for communicating between extensions. Named contracts require more documentation or inside knowledge and provide fewer guarantees about compatibility. Interface contracts are self-documenting but introduce more complexity, as the interface needs to be referenced. This article describes how to use Managed Extensibility Framework (MEF) named contracts. This article will not give you a complete understanding of MEF, but provides a simple example.

Getting Started with Exports

Open the project you created in the previous exercise. To keep things simple, we will expose the message that is being displayed in the status bar when the user clicks the Show Layer Count button. Widen the scope of the message variable, making it a field.

private string _Message;
public void ButtonClick(object sender, EventArgs e)
{
    _Message = String.Format("Number of Layers: {0}", App.Map.Layers.Count);
    App.ProgressHandler.Progress(null, 0, _Message);
}

Then, wrap the field in a method. The name of the method is not important, because we are using a named contract. If we were using an interface we would be able to use a property, instead, and expose it as part of the interface.

public string Message()
{
    return _Message;
}

The approach we will take for the string Message will work for any built-in .NET type. A similar approach will also work for collections. If you want to pass custom types between extensions, you will need to declare those in a separate assembly  and reference it in each extension project.

MEF uses the concept of Exports and Imports, where data, classes, or methods are exported by one class and imported by one or more classes. We mark our Message method for export by adding the Export attribute and specifying a contract name that will be used by all importers (“LayerCount.Message”).

[System.ComponentModel.Composition.Export("LayerCount.Message")]
public string Message()
{
    return _Message;
}

Getting Started with Imports

We will create another extension in this same project. Add a new class (Project, Add class…) named MefImport that derives from Extension. On Activate() a new SimpleActionItem should be added with the caption “Retrieve Message”. In the corresponding event handler, we retrieve the message and write it to the trace listeners. You’ll need to add the same using statements the plugin template includes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DotSpatial.Controls;
using DotSpatial.Controls.Header;

public class MefImport : Extension
{
    public override void Activate()
    {
        App.HeaderControl.Add(new SimpleActionItem("Retrieve Message", ButtonClick));
        base.Activate();
    }

    public override void Deactivate()
    {
        App.HeaderControl.RemoveAll();
        base.Deactivate();
    }

    public void ButtonClick(object sender, EventArgs e)
    {
        var message = GetLayerCountMessage();
        System.Diagnostics.Trace.WriteLine(message);
    }
}

We declare a property that is essentially a pointer to a function that returns a string. In C# the Func<> class represents a “pointer to a function” so our property looks like this:

public Func<string> GetLayerCountMessage
{
    get;
    set;
}

 

Lastly, we need MEF to import a contract by the name of “LayerCount.Message” so we add the import attribute.

[System.ComponentModel.Composition.Import("LayerCount.Message")]
public Func<string> GetLayerCountMessage
{
    get;
    set;
}

 

You can build and run the application. Click Show Layer Count, then Retrieve Message. Drag and drop a layer on the map, and then click Show Layer Count and Retrieve Message, again.

image

Check the output window (Debug, Windows, Output) to see that the message was properly retrieved when GetLayerCountMessage() was called.

What if the exporting extension wasn’t available?

If we expected the exporting extension to only occasionally be available, we can use a named parameter of the Import attribute to indicate that instead of throwing an exception, we would like MEF to leave our GetLayerCountMessage property with its default value (null). Of course, we have to check for null before using the property, in that case.

public void ButtonClick(object sender, EventArgs e)
{
    if (GetLayerCountMessage != null)
    {
        var message = GetLayerCountMessage();
        System.Diagnostics.Trace.WriteLine(message);
    }
}

[System.ComponentModel.Composition.Import("LayerCount.Message", AllowDefault = true)]
public Func<string> GetLayerCountMessage
{
    get;
    set;
}

 

Now we can prevent the Layer Count extension from loading by commenting it out. When running the application, we will still find the Retrieve Message menu item, and clicking it won’t cause any problem.

Points of Interest

if multiple extensions will be exporting a given contract, the importer should use the ImportMany attribute and import an IEnumerable<> of the original, expected type.

Trying to expose Message as a property under a named contract won’t work because MEF will perform the import (and export) only once, by default. We would see the original null message, and nothing else.

Fields can also be exported and imported, so as a matter of style, I used properties.

How to Sort Layers Alphabetically

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. This article explains how to create a DotSpatial extension by using the online template. The extension we are creating will allow the user to sort the layers so that they appear in the Legend alphabetically.

Getting Started

If you are not familiar with creating a simple DotSpatial-based extension, please consider the introductory article. For practical purposes, we assume you are coming to this article after having completed the previous one. This article is based on DotSpatial 1.2.

Creating a New Project

Create a new project using the DotSpatial Plugin Template. You may delete the Readme.txt and modify the name of the MyPlugin1 class (to reflect the functionality provided by the extension). I named mine SortLayersPlugin. Change the caption of the SimpleActionItem from “My Button Caption” to “Sort Layers”.

Replace the ButtonClick event handler with the following code, which is explained inline.

public void ButtonClick(object sender, EventArgs e)
{
    // Get a list of layers sorted alphabetically by LegendText.
    var newLayers = App.Map.Layers.OrderByDescending(l => l.LegendText).ToList();

    // Suspending events speeds our changes up and prevents redrawing multiple times.
    // The events will be called only once, when we call ResumeEvents().
    App.Map.Layers.SuspendEvents();

    // By default, it appears some part of the layer is disposed when it is removed from the collection.
    // If we were to use App.Map.Layers.Clear(), we would stlil need to LockDispose on each layer.
    while (App.Map.Layers.Any())
    {
        var layer = App.Map.Layers[0];
        layer.LockDispose();
        App.Map.Layers.RemoveAt(0);
    }

    // As we add each layer back in, in the correct order, we UnlockDispose so that the layer can be disposed
    // at the appropriate time.
    foreach (IMapLayer newLayer in newLayers)
    {
        App.Map.Layers.Add(newLayer);
        newLayer.UnlockDispose();
    }
    App.Map.Layers.ResumeEvents();
}

Conclusion.

Build and run the application. You can add a few layers and then use the menu item to sort them.

image

Points of Interest

You can add another button to sort the layers in reverse alphabetical order by replacing App.Map.Layers.OrderByDescending(…)… with App.Map.Layers.OrderBy(…)….

How to Customize Branding of MapWindow 6

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. The end-user release version of DotSpatial is named MapWindow 6. We’ve made it really easy for you to customize MapWindow 6 without even downloading the source code by adding your own extensions and re-branding the application.

Downloading MapWindow 6

This article is based on the MapWindow 6.1.1 Release located on the downloads tab at http://mapwindow6.codeplex.com. You will want to download the zip package.

We’ll consider HydroDesktop, which builds upon and customizes MapWindow 6, as a case study.

Replacing or Adding Extensions

The extensibility feature in DotSpatial is heavily used in MapWindow 6. You can learn more about where to find extensions and how to write your own extensions. By default, the ClickOnce version of MapWindow includes several extensions, such as, an updater, an extension manager, an error reporter, a tree of map layers (legend), and a splash screen. All of these extensions will be composed seamlessly when the application starts. In addition, a few other UI extensions are downloaded when the application starts for the first time.

When you have located or built the extensions you want to include, you will install them into the Plugins or Application Extensions folder. You may likewise replace or remove extensions that you don’t want or need. Some extensions depend on others, so you will have to add or remove them in sets.

Also, your application must contain an implementation of IProgressHandler, IHeaderControl, and IDockManager, if it includes any extension that implements IExtension. It may contain Tools or DataProviders without this restriction. This is because Extensions are designed to work with a user interface and this base set of functionality is expected (e.g., the ability to add a menu item). Extension Manager will download a default set of UI controls if an implementation is not already provided.

HydroDesktop adds a plethora of custom built extensions, and uses its own DockManager.

Changing the Form Name

The main form title is “MapWindow 6” by default. You can replace this by modifying MapWindow.exe.config.

Notice the setting named CustomMainFormTitle in the userSettings section. Provide the value CUAHSI HydroDesktop.

<setting name="CustomMainFormTitle" serializeAs="String">
    <value>CUAHSI HydroDesktop</value>
</setting>

  image

Changing the Application Icon

The application icon appears in the About extension and in the upper left hand corner of the form. It can also be customized by modifying MapWindow.exe.config. It may be easiest to drop the icon in the same folder as the executable, as I did.

<setting name="CustomAppIconPath" serializeAs="String">
    <value>HydroDesktop.ico</value>
</setting>

image

Customizing the SplashScreen Logo

If you are using the DotSpatial.Plugins.SplashScreenManager, you may customize it by providing a logo that is displayed in the splash screen. Place a PNG image in the same folder as the executable. Its dimensions shouldn’t be much larger than 426 x 120 px. Modify MapWindow.exe.config to reference the new logo and delete the old MapWindowSplashLogo.png file from the directory.

<setting name="CustomSplashImagePath" serializeAs="String">
  <value>HydroDesktopSplashLogo.PNG</value>
</setting>

image

Customizing the Executable Icon

The MapWindow.exe executable has an icon resource embedded in it. Windows displays this icon in explorer and as the default icon for any shortcuts to the executable. You can use a tool such as XN Resource Editor to replace the icon. You would generally need to check the MapWindow 6 license before doing this, but this type of modification is permitted in this open-source project (though, I’m not a lawyer).

I used the Import image Resource menu item on the context menu of XN Resource Editor and removed the old icon (Delete Resource).

image

Renaming the Executable

Renaming the executable is a simple two-step process: rename both the executable and the config file.

image

Note: After the extension is renamed, you will notice the extension manager reports that packages are placed in a different directory based on the new executable name. The path would look something like %appdata%\HydroDesktop.exe\Extensions. Packages in the %appdata%\MapWindow6.exe\Extensions folder will be ignored by this executable.

How to Add Support for Loading DotSpatial.Plugins.Ribbon

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. DotSpatial can be extended with a number of extensions. Some of these extensions require the application developer provide additional support before they will load. We look at adding support for those that require a Shell export, which includes the extensions providing ribbon and docking features.

Getting Started

You will need to implement basic extensions loading support as described: How to Support Loading Extensions in DotSpatial. For practical purposes, we assume you are coming to this article after having completed the previous one.

Extensions may depend on other extensions being available. They may also “light up” synergistically when other extensions are available. This behavior is made possible through the Managed Extension Framework (MEF) via a set of Import and Export attributes. Since MEF is available on MSDN, instead of explaining how it works, I’ll cover how the DockManager, Ribbon, and ToolManager plugins use it.

Windows Forms

In order for an extension like the Ribbon to register itself properly with the main form of your application, it must be told what form that is. Your application could include a number of forms, so one of them must be specified as the Shell.

This functionality relies on MEF, and not on DotSpatial, because it is not directly related to mapping. So, instead of creating an interface in DotSpatial, we provide a convention to be followed.

Specifying a Shell

The application should Export a field or property with the contact name of “Shell” and type of ContainerControl. In MapWindow 6, this is added as a field to the MainForm class (as shown).

[Export("Shell", typeof(ContainerControl))]
private static ContainerControl Shell;

At any point before LoadExtensions() is called, this field should be set to the form that is considered the Shell. We do this in the MainForm constructor in MapWindow 6.

Shell = this;
appManager.LoadExtensions();

The Ribbon extension imports Shell when it is being loaded and adds a ribbon control to the associated form’s control collection. You can similarly export other types from one extension to another, and create a more loosely coupled set of classes.

Points of Interest

You will want to obtain a copy of the Ribbon or DockManager so that you can test your implementation. These can be pulled as packages from the DotSpatial feed (gallery).

Composing an Application by Combining Extensions

Introduction

DotSpatial is an open-source project that contains controls which can be used to manipulate and display geographic information. MapWindow 6 is a thin wrapper around DotSpatial. This article explains how to create an application like MapWindow 6 or HydroDesktop, by combining extensions to get the desired set of functionality. Some extensions are included by default with DotSpatial builds while others can be found in the Extension Manager.

Obtaining Extensions

Presently, we don’t make any distinction between the terms add-on, plugin, or extension. In general, these refer to a class that provides some functionality designed to complement DotSpatial and inherits from IExtension (or implements Extension).

There are other types of extensions that provide a more specific type of functionality such as DataProviders, HeaderControls, and ProgressHandlers. These inherit from specific interfaces such as IDataProvider, IHeaderControl, IProgressHandler and so on. They are less general purpose in nature.

Extensions can be obtain in a number of ways:

Codeplex Downloads – the Extended release package includes additional extensions.

DotSpatial Package Feed – updated extensions are built and pushed to the feed automatically. The feed may also include user-contributed (closed source) packages and is used by the Extension Manager.

The Extension Manager – the extension manager itself is an extension. It allows the user to download additional extensions.

You – you can create your own DotSpatial extensions as well. Then you can compose various applications by including the appropriate extensions that result in the desired set of features.

Installing Extensions

There are three different places an extension may be placed. Each yields slightly different functionality. A programmer may also add additional directories to the appManager.Directories property so that additional directories are searched. When installing an extension, you’ll need the extension assembly (dll) as well as any of its dependencies. The built in assembly resolver allows you to create an extension that depends on another.

Plugins folder – when a developer builds the DotSpatial project, extensions are placed in the Plugins folder inside of the application folder. These extensions (assuming they inherit from IExtension) may be activated or deactivated by the end-user. If you are deploying your application with a specific set of extensions that you wish to behave in this way, this is the right place for them.

Application Extensions folder – extensions placed here will be activated when the application launches; the user will not be able to deactivate them. This allows the developer to create a set of extensions that make up the branding of the application. From the user perspective, these are part of “the application”, and the developer can use this flexibility to divide up application logic into multiple extensions. An end user wouldn’t be able to tell whether the feature was built into DotSpatial, or was an extension.

Extensions folder – this folder is placed in the user profile folder inside of a folder based on the application assembly name. You can open this folder by clicking Show Extensions Folder in the Extension Manager.

image

The path would look something like %appdata%\DemoMap.exe\Extensions.

When users install or update packages from the online section of the Extension Manager, they are placed here.

Note: If an extension was originally in the Plugins folder, and the user chooses to update it, the new version will be placed in the Extensions folder and the existing version will be removed (after a restart).

Loading Extensions

When an extension is loaded, we guarantee that it will be able to access an AppManager, IProgressHandler, and IHeaderControl. This allows the developer to avoid checking whether these properties are null before each use. This means, however, that extensions fulfilling these requirements must be available. In DemoMap.exe implementations are included in the project itself as classes. In MapWindow 6, example implementations are included as extensions. You can use whichever suits you.

You may want to review a few related articles:

How to Support Loading Extensions (Loading GDAL)

How to Load DotSpatial Extensions Into My Toolbar

Case Study

The MapWindow 6 application is strictly a set of extensions, the DotSpatial library, a small amount of code to allow you to brand it with your own splash screen image and name, and a little code to deal with command line parameters.

The HydroDesktop application is a copy of MapWindow 6 with a different set of extensions and custom branding. Eventually, HydroDesktop can become more of an “extension pack” so that it can be downloaded into any DotSpatial compatible application.

Points of Interest

See Also: Using the Extension Manager

Extensions can communicate with one another using the Managed Extensibility Framework (MEF).

Setting AppManager.UseBaseDirectoryForExtensionsDirectory can alter the location where extensions are installed by the Extension Manager.