Wednesday, December 5, 2012

ARCGIS JavaScript API – ADVANCED EDITING TOOLS PART VI – Part 1

1.     Introduction

In this document I will treat the creation of more advanced editing tools. In the ArcGis JavaScript API it is difficult to perform geometric operations on geometry in code.  However to perform advanced geometry operations we can use the geometry services available at an ArcGis server. Using this technique you are able to perform actions as split and merge of geometries.  By combining geometry service methods you can even more complex operations. Some tools will using the basic edit commands as building blocks for creation of advanced tools is.  In another example  I will show how you can use the JavaScript API to build tools in native JavaScript code without geometry services.
Another solution for extending editing by using Service Object Extensions (SOE). They can play the same role as does the geometry services of the ArcGis Server.

2.     Primary geometry tools

Two important tools in web editing are the split and merge tool. Like other commands explained in previous documents, the tools are triggered through the use of the MVVM (Model View ViewModel+)  library and buttons on the web page.
2.1 Split tool

The split tool for a polygon was implemented by doing the following steps:
·         Select a feature (polygon)
·         Draw a polygon that is used for the split action
·         Perform the method cut of the geometry service
·         Update the feature with one part of the split
·         Add the remaining parts as new features to the layer, attribute information is copied from the 
        selected feature.

 


The first two actions are already part of the framework. I only has to implement the use of the geometry service ‘cut’ with a callback method. The update and add of features are implemented in the callback method.

The split command in the ViewModel  looks contains the following code:
splitCommand: function () {
   try {
   // Verify a polygon is selected on the layer specified
     var featureLayer = null;    
     if (commonData.ViewModel.selectedLayer() != null)     
          featureLayer = gisOperation.getMap().getLayer(
     commonData.ViewModel.selectdLayer().layerName);
    if (featureLayer == null 

       || featureLayer.geometryType != "esriGeometryPolygon"
       || featureLayer.getSelectedFeatures().length < 1) {
     // Invalid choice                                                    
       commonData.ViewModel.setEditActive(false);
       return;
     }
     // Draw line
     gisCommon.drawGeometry(esri.toolbars.Draw.POLYLINE, splitLineComplete);
   } catch (err) {      
     logging.logMessage("E", "error in splitCommand ->" + err.name + " - "
          + err.message, "editToolbarAdvancedVM");
   }
 }


After the line has been drawn, in the callback the cut operation is executed through a call to the gisEditing class. A callback method is added  in case some past processing is needed at the business level. All tools contains also an error processing method, very important there are errors during the geometry service method calls.

function splitLineComplete(polyline) {
// Do now second part , doing the split
   if (polyline) {
     var featureLayer =
     gisOperation.getMap().getLayer(commonData.ViewModel.selectedLayer().layerName);
     var selectGraphics = featureLayer.getSelectedFeatures();
     gisEditing.splitOperation(featureLayer, selectGraphics, polyline,
     splitComplete, geometryServiceFailed);
   } else {
     return;
   }
}
The real job is done in the editing framework I implemented through the use of the cut method of the rest service.

splitOperation: function (featureLayer, selectGraphics, polyline,
   geometryServiceComplete, geometryServiceFailed) {
   try {
     if (geometryServiceFailed == null)
       geometryServiceFailed = defaultErrorHdl;
       var selectGeometries = new Array();
       for (var i = 0; i < selectGraphics.length; i++) {
         selectGeometries.push(selectGraphics[i].geometry);
       }
       currentCallBack = geometryServiceComplete;
       currentFeatureLayer = featureLayer;
       gisOperation.getGeometryService().cut(selectGeometries, polyline,
       splitCompleted, geometryServiceFailed);
   } catch (err) {
       logging.logMessage("E", "split failed ->" + err.message,
       "gisEditing/splitOperation");
   }
}
In the edit framework I do also care about the replication of the attribute information and update and add the features. Therefor the callback of the cut is treated within the edit class, and after the replication and feature update  is done, the callback is executed of the calling command.

function splitCompleted(results) {
   try {
     if (results.geometries != null && results.geometries.length > 1) {
     // Update first geometry
       var updateGraphic =
       currentFeatureLayer.getSelectedFeatures()[0].setGeometry(results.geometries[0]);
       // Create for the next
       currentSymbol = currentFeatureLayer.getSelectedFeatures()[0].symbol;
       var newGraphics = new Array();
       for (var i = 1; i < results.geometries.length; i++) {
         newGraphics.push(new esri.Graphic(results.geometries[i],

         currentSymbol,currentAttributes));
       }
       currentFeatureLayer.applyEdits(newGraphics, [updateGraphic], null, 

         function (addResults, updateResults, deleteResults) {
           var updateCount = updateResults.length + addResults.length;
           if (currentCallBack != null)
             currentCallBack(results.geometries);
         }, function (err) {
           logging.logMessage("E", "applyEdits failed for first feature -->"
            + err.message, "gisEditing/splitCompleted");
           if (currentCallBack != null)
             currentCallBack(null);
       });
     }
   } catch (err) {
      logging.logMessage("E", "splitcomplete failed failed -->"
        + err.message, "gisEditing/splitCompleted");
   }
}
 

The procedure outlined in this split tool is used for all the advanced tools I implemented. In general what I do is
1.       Do the necessary selection of features.
2.       Activate the tool , in general done through a button click.
3.       If needed, start  a drawing action through the general draw tool.
4.       Use a callback to step to a next action.
5.       Repeat step 4 if different actions are required.

This is in general the steps  you will do if you would add a tool to ArcMap as an extension. In development of extension you will use events instead of callback methods.
It is also very important to encapsulate all code into a try catch structure. During writing tools often the asynchronous working of geometry operations can results in unexpected behaviors.

2.2 Merge tool

The merge tool can be considered as a command in terms of ArcMap. This tool is much simpler than the split tool. For the merge I only require the selection of a number of features of a feature layer. As is the case with the split tool, the geometry service of an ArcGis server will do the hard work of doing a union of the geometries.
The only asynchronous process required after the merge is the post processing of the features on the feature layer, consisting of an update of a feature (geometry) and a delete of a feature.
The startup of the merge tool is similar as that with the split tool:

unionGeometries: function (featureLayer, selectGraphics, geometryServiceComplete,      geometryServiceFailed) {
   try {
     if (geometryServiceFailed == null)
       geometryServiceFailed = defaultErrorHdl;
     currentCallBack = geometryServiceComplete;
     currentFeatureLayer = featureLayer;
     var selectGeometries = new Array();
     for (var i = 0; i < selectGraphics.length; i++) {
       selectGeometries.push(selectGraphics[i].geometry);
     }
     gisOperation.getGeometryService().union(selectGeometries,
     unionGeometriesCompleted, geometryServiceFailed);
   } catch (err) {
      logging.logMessage("E", "merge polygons failed -->"
       + err.message, "gisEditing/unionGeometries");
   }
}
As you can see, a lot of code is similar to the code used for the split tool. The most important line is the call to the geometry service ‘union’. The callback function will gives us the merged geometry. The only thing that remains is the update and delete of features so that only one feature remains as the result of the merge.

3.     Native JavaScript tools
It is not always an easy job to create geometry tools entirely in JavaScript. However the ArcGis JavaScript API offers some possibilities through the composition of the polygon and polyline classes. One example of a tool from ArcMap that can be reproduced in JavaScript is the explode tool.  The principle is very simple :

·         For polygons, isolate each ring into a separate geometry (polygon)
·         For polylines, Isolate each path into a separate geometry (polyline)

You only need to delete the original feature and replace it by a number of new features corresponding to the number of rings or paths. No round trip is required to the ArcGis server for creating the different geometries, only an asynchronous operation is required to update the feature class with the new features.

explode: function (featureLayer, feature, callback) {
   try {
     var updateFeatures = new Array();
     var addFeatures = new Array();
     var deleteFeatures = new Array();
     var actionRequired = false;
     var newGeometry;
     var newGraphic;
     currentAttributes = clone(feature.attributes);
     currentAttributes[featureLayer.objectIdField] = null;
     currentSymbol = feature.symbol;
     currentFeatureLayer.clearSelection();
     switch (feature.geometry.type) {
     case "polygon":
     // Create number of features of rings in the geometry
       if (feature.geometry.rings.length > 1) {
         actionRequired = true;
         var ringCount = feature.geometry.rings.length;
         for (var i = 0; i < ringCount; i++) {
         newGeometry =
           new esri.geometry.Polygon(feature.geometry.spatialReference);
         newGeometry.addRing(feature.geometry.rings[i]);
         newGraphic =
           new esri.Graphic(newGeometry, currentSymbol, currentAttributes);
         addFeatures.push(newGraphic);
         }
         deleteFeatures.push(feature);
      }
      break;
    case "polyline":
    // Create number of features of paths in the geometry
      if (feature.geometry.paths.length > 1) {
        for (var i = 0; i < feature.geometry.paths.length; i++) {
          newGeometry =
            new esri.geometry.Polyline(feature.geometry.spatialReference);
          newGeometry.addPath(feature.geometry.paths[i]);
          newGraphic =
            new esri.Graphic(newGeometry, currentSymbol, currentAttributes);
          addFeatures.push(newGraphic);
        }
        deleteFeatures.push(feature);
        actionRequired = true;
      }
      break;
    default:
      break;
    }
    if (actionRequired) {
      featureLayer.applyEdits(addFeatures, updateFeatures, deleteFeatures,
      function (addResults, updateResults, deleteResults) {
        var updateCount = updateResults.length + addResults.length;
        callbackExplode(updateCount, callback);
        }, function (err) {
          logging.logMessage("E", "explode failed -->" +
            err.message, "gisEditing/explode");
       });
    }
    else {
      callbackExplode(0, callback);
    }
  } catch (err) {
      logging.logMessage("E", "explode failed -->" +
       err.message, "gisEditing/explode");
  }
}



As you can see not very complex to realize. This tool will work in polygons and polylines that consist of simple multipart geometries. If the geometry consist of a complex structure, this tool could fail, in the current implementation failures are logged.
Another example of a tool that can be realized in JavaScript is the lengthening or shortening of a polyline over a given distance ,at the start or at the end of the polyline. This is a tool that I previous developed as an ArcMap tool. Here you can use methods exposed in the esri.geometry namespace.
4.     Complex geometry tools

A first tool is the creation of a polygon based on points added on the map. This tools involves two buttons, one to start creation of points on the map. A second button will create the polygon using the method convexHul l of the geometry service of an ArcGis server.  Even as the tool looks complex, the implementation is very simple, thanks to the geometry service of an ArcGis server.

 
createConvexHull: function (featureLayer, pointList, geometryServiceComplete,
   geometryServiceFailed) {
   try {
     gisOperation.disableDrawMode();
     if (geometryServiceFailed == null)
       geometryServiceFailed = defaultErrorHdl;
     currentCallBack = geometryServiceComplete;
     currentFeatureLayer = featureLayer;
     var points = new Array();
     for (var i = 0; i < pointList.length; i++) {
       points.push(pointList[i].geometry);
     }
     gisOperation.getGeometryService().convexHull(points, convexHullCompleted,

        geometryServiceFailed);
   } catch (err) {
      logging.logMessage("E", "ConvexHull failed -->"
        + err.message, "gisEditing/createConvexHull");
   }
}


In the callback we can now add the resulting geometry as new feature to the feature class selected using default values for the attributes.
5.     Conclusion

In this first part I illustrated how easy you can add custom tools to an editing ArcGis application. Doing some advanced editing requires the use of a geometry service at an ArcGis Server. When you required some functionality not found in the geometry service, you can move towards the creation of Server Object Extensions(SOE)  and use them in the same way as using geometry services. Knowledge of ArcObjects is a must when starting with writing Server Object Extensions.  Use always rest services when using SOE’s, you don’t want  XML from a SOAP web service, but Json. Adding SOE’s is best done in a separate Dojo class, so it can only be loaded when needed through AMD.

Saturday, November 10, 2012

Using AMD pattern to create modular ArcGis JavaScript Applications

1.     Introduction

As from Dojo 1.7, the pattern of using modular JavaScript classes was introduced to load JavaScript files asynchronous, no longer requiring loading the files at the retrieve of a html files or at least create a much simpler approach of this pattern. With the version 3.2 of the ArcGis JavaScript library ESRI introduced AMD for its portal API. ESRI will extend the use of AMD in other modules with later releases.

In this document I will illustrate how we can use this pattern to refactor the GIS framework described in earlier documents.  You will also see how popular other libraries can fit into this pattern.
2.     The modular approach

In modular languages  the last years new design patterns has been introduced to create modular and maintainable applications. Two patterns that emerged are separation of concerns and loose coupling.  In the picture below I outlined the flow of the different modules with the dependencies between them.  The way Dojo  AMD works can at a certain stage be compared to the use of PRISM for  Silverlight/WPF applications which is a library that implements  the two patterns separation of concerns and loose coupling .

Dojo AMD is responsible to create classes and inject there dependencies into the modules which helps us to create the modular concept. One of the goals of AMD is to restrict the use of global variables and encapsulate as much as possible into the created classes this covers the separation of concerns.

 In the previous version of my framework I heavenly relied on global variables that were created at the startup. With AMD this will no longer be the case, as they will be maintained by Dojo and can be compared to the pattern of loose coupling.


In PRISM on Silverlight/WPF there is component container that contains all objects which can be defined  with a single or multiple occurrence.

Most of the modules we will need does not  require multiple instances,  but rather requires to be a singleton.  Dojo AMD does not have a definition singletons. The map module, legend module and others requires only a single instance. Below you will find the blue print of a module definition that we can use to implement  a singleton class in Dojo AMD . You can find more information on this pattern at

http://unscriptable.com/2011/09/22/amd-module-patterns-singleton/

A typical singleton module has the structure outlook below.

define ([…],function () {
                var instance;
                // Add here the local variables and the local functions
                function Singleton() {

                }
                Singleton.prototype = {   
                // Add here your  public methods   
                 }
                return (instance || (instance || new Singleton()));
});

When the require function create the class it always returns the same object. In our application all component  modules as map, legend, toolbars are created as a singleton. This is also the case for the viewmodels in the MVVM pattern, except the main viewmodel , that I will explain later.

In a future document I will illustrate a regular AMD class that will create a new type of layer derived from the graphic layer that I called ‘sqlLayer’ and can have multiple instances. This class will make it possible to add SQL tables that have a geometry element and that are not managed by an ArcSde server. A REST service is responsible for doing the CRUDQ  actions.  A typical example is the use of a Microsoft SqlGeometry attribute in a table.

3.     Before and after AMD illustrated


In the diagram illustration of the different modules,  you can see the different components of a typical GIS application. With the help of KnockoutJS the demo application gives us the possibility to make a separation between the GUI and the business logic. I wanted also separate the GIS modules from the Business modules. The best solutions is when you can also separate the business components from the ArcGis JavaScript API.
First look at the situation before using AMD.
<script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.2" ></script>
<script type="text/javascript">
/*------------------------------------*/
// REQUIRE
/*------------------------------------*/
         dojo.require("dijit.dijit");
         dojo.require("dijit.form.CheckBox");
         dojo.require("dijit.layout.BorderContainer");
         dojo.require("dijit.layout.ContentPane");
         dojo.require("dijit.layout.StackContainer");
         dojo.require("dijit.layout.StackController");
         dojo.require("dijit.layout.TabContainer");
         dojo.require("dijit.layout.AccordionContainer");
         dojo.require("dijit.popup");
         dojo.require("dijit._base.popup");
         dojo.require("dijit.DropDownMenu");
         dojo.require("dijit.MenuItem");
         dojo.require("dijit.MenuBar");
         dojo.require("dijit.PopupMenuBarItem");
         dojo.require("dijit.Toolbar");
         dojo.require("dijit.registry");
         // Esri dijits
         dojo.require("esri.arcgis.utils");
         dojo.require("esri.dijit.InfoWindow");
         dojo.require("esri.dijit.Legend");
         dojo.require("esri.dijit.Measurement");
         dojo.require("esri.dijit.Scalebar");
         dojo.require("esri.geometry");
         dojo.require("esri.map");
         dojo.require("esri.dijit.editing.Editor-all");
         dojo.require("esri.dijit.editing.TemplatePicker-all");
         dojo.require("esri.dijit.AttributeInspector-all");
         dojo.require("esri.layers.wms");
         dojo.require("esri.layers.wmts");
         dojo.require("esri.SnappingManager");
         dojo.require("esri.symbol");
         dojo.require("esri.renderer");
         dojo.require("esri.utils"); 
         dojo.require("esri.tasks.query");
         dojo.require("esri.toolbars.navigation");
</script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.14/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="scripts/jquery.tmpl.js"></script>
<script type="text/javascript" src="scripts/jquery.livequery.js"></script>
<script type="text/javascript" src="scripts/jquery.xml2json.js"></script>
<script type="text/javascript" src="scripts/Modules/jqueryAgsLegendPlugIn.js"></script>
<script type="text/javascript" src="scripts/Modules/jqueryAgsSelectPlugIn.js"></script>
<script type="text/javascript" src="scripts/knockout-2.0.0.js"></script>
<script type="text/javascript" src="scripts/globalVars.js"></script>
<!-- Supporting JavaScript objects -->
<script type="text/javascript" src="scripts/Helper/eventAggregator.js"></script>
<script type="text/javascript" src="scripts/Helper/dataMapping.js"></script>
<script type="text/javascript" src="scripts/Helper/logUtil.js"></script>
<script type="text/javascript" src="scripts/Helper/genUtil.js"></script>
<!-- Gis JavaScript framework -->
<script type="text/javascript" src="scripts/Gis/gisOperation.js"></script>
<script type="text/javascript" src="scripts/Gis/gisCommonTasks.js"></script>
<script type="text/javascript" src="scripts/Gis/gisEditing.js"></script>
<script type="text/javascript" src="scripts/Gis/gisGeoProcessing.js"></script>
<script type="text/javascript" src="scripts/Gis/gisExtra.js"></script>
<!-- JavaScript GIS Modules -->
<script type="text/javascript" src="scripts/Modules/legendModule.js"></script>
<script type="text/javascript" src="scripts/Modules/layerSelectionModule.js"></script>
<script type="text/javascript" src="Scripts/Modules/commonToolbarModule.js"></script> 
<script type="text/javascript" src="scripts/Modules/editToolbarGeneralModule.js"></script>
<script type="text/javascript" src="scripts/Modules/mapModule.js"></script>
<!-- JavaScript View models -->
<script type="text/javascript" src="scripts/ViewModels/mainViewModel.js"></script>
<script type="text/javascript" src="scripts/ViewModels/commonToolbarVM.js"></script>
<script type="text/javascript" src="scripts/ViewModels/editToolbarGeneralVM.js"></script>
<script type="text/javascript" src="scripts/ViewModels/layerSelectionVM.js"></script>
<!-- JavaScript bootstrapper -->
<script type="text/javascript" src="scripts/startup.js"></script>
<!-- END JAVASCRIPT -->

As  you can see, this looks horrible if you not try to group the JavaScript files into more global files, but then you lose the modularity when you try to replace one module by another version. The AMD is clearly a solution to this issue.  After transferring to AMD, the same code now looks like this:
<script type="text/javascript">
  var dojoConfig = {
    async: true,
    tlmSiblingOfDojo: false,
    parseOnLoad: true,
    packages: [
         "name"'jtSoftware'"location""/Scripts/Gis" },
         "name"'helper'"location""/Scripts/Helper" },
         "name"'viewModels'"location""/Scripts/ViewModels" },
         "name"'modules'"location""/Scripts/Modules" },
         "name"'common'"location""/Scripts", main: "globalDefs" },
   "name"'google'"location"'https://maps.googleapis.com/maps/api/js?
sensor=false'},
        "name"'jquery'"location"'http://ajax.googleapis.com/ajax/libs/jquery/1.8.2', main: 'jquery.min' },
        "name"'jqueryui'"location"'http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.0', main: 'jquery-ui.min' },
        "name"'jquerytmpl'"location""/Scripts", main: 'jquery.tmpl'},
        { "name"'jqueryxml'"location""/Scripts", main: 'jquery.xml2json'},
        "name"'ko'"location"'http://ajax.aspnetcdn.com/ajax/knockout', main: 'knockout-2.1.0' }]
  };
</script>
<script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.2"></script>
<!-- JavaScript bootstrapper -->
<script type="text/javascript" src="scripts/bootstrap.js"></script>
<!-- END JAVASCRIPT -->

As you can see, all dependencies defined by require before AMD are gone and are now defined in the different modules as happens in high level programming languages.
With the use of packages, you now can group different JavaScript files together like you use libraries into high level programming languages.

The result is now a HTML page with little JavaScript code embedded. This makes a more clear separation between code behind (JavaScript embedded) and the business logic. Adapting the GUI for different environments (Mobile, Pad, Desktop) is no longer requiring adapting the different JavaScript definitions but can be done at module loading.
The loading of external libraries is defined also with the packages option. Popular libraries as ‘jquery’ and ‘knockoutJS’  can make use of AMD and are ether AMD compliant or are either support AMD loading as is the case of ‘jquery’. For jquery you must explicit define a property.

                define.amd.jQuery = true;

 4.     The flow of processing
In the HTML besides the loading of the ArcGis JavaScript API library, only one other JavaScript file is included in the HTML page, the ‘bootstrapper.js’. All will start with this module which after loading the configuration file kicks of the whole loading process of the different components of the HTML page. In the picture shows earlier, I illustrate how all different modules interact with each other. The following order is executing :

·         Document ready
·         Get configurations
·         Create viewmodel(s
·         Map module  initialization
·         Legend Module
·         Layer Selection module
·         Toolbar modules

During the loading of the modules, the needed GIS modules are loaded through the AMD pattern. Another important aspect is the  asynchronous starting of the initialization of the modules. To manage this asynchronous behavior the observer pattern is needed in pour application. For this I use a custom class ‘EventAggregator’ explained in an earlier document
http://jpenet.blogspot.be/2012/03/arcgis-javascript-api-creation-of.html

The use of publish and subscribe can also be used with the Dojo library, but for now I stick to this simpler solution.  It is very important, at least in the development stage, to add a lot of logging information for tracking the asynchronous process. With AMD, you now have two dimensions into the asynchronous process :

·         Asynchronous processing of GIS operations

·         Asynchronous loading of the AMD classes

In the first version of the  JavaScript implementation  I  mostly used the closure pattern .The refactoring of the modules for AMD (Singleton pattern) is not a hard job,  there is already a separation of local variables, only some renaming is required.
5.     Separation of concern

In the  flowchart of the modules, you see there are three main parts

·         GUI interface
·         Business logic
·         GIS  modules
o   GIS Framework
o   ESRI ArcGis JavaScript API         
With the use of MVVM through the library ‘knockoutJS’ I already separated the GUI interface from the business logic implemented with the map module, legend module, select layer module and the different viewmodel modules.
It is also useful to separate the Business logic from the ESRI ArcGis JavaScript API.  In the current implementation this Is not the case, but it is not a hard work to encapsulate all the direct use of ESRI components into the GIS framework. Although it was not the purpose in this study to replace the ESRI GIS solution by another GIS solution, by doing a clear separation of the business logic from the ArcGIS JavaScript library you could create an application based on another GIS implementation (OpenLayers , GeoServer) by replacing the GIS framework modules.
For the moment  there are a limited number of modules in the GIS framework. A split into core functionality and separate functional modules is a next step in implementing AMD. You can by example put all Google functionality into one separate module. Editing could also be split into base editing and more advance edit functionality.
6.     A first look at the AMD modules

To illustrate what the look is from the singleton modules created for the AMD version, I will show what I did with the map module. The creation of the map module is at the heart of the bootstrap process. All modules depends on the creation of a map module.
Before we had this as

var mapModule = (function () {
Now the header this looks as:

define(["helper/logging""helper/eventAggregator",
        "jtSoftware/configuration""jtSoftware/gisOperation""jtSoftware/gisEditing""modules/legendModule"],
    function (logging, eventAggregator, configuration, gisOperation, gisEditing, legendModule) {

The header shows now the dependency of the different classes. Through the parameters the Dojo library performs the dependency injection.
The method functions defined in the map module in the closure pattern is coded as

 return {
    init: function (divElement, mapLayersInitialized) {
       try {
          esri.config.defaults.map.slider = { left: "30px", top: "30px", width: null,
                          height: "200px" };
          var mapControl = new esri.Map(divElement, {});

 In AMD with the singleton pattern looks now like

MapModule.prototype = {
   init: function () {
      try {
            gisOperation.setSlider("30px""30px"null"200px");
            gisOperation.setMap(commonData.MapRegion);
            mapControl = gisOperation.getMap();

In the code above you can see how de dependency of the ArcGis library in the earlier version was removed by encapsulating the creation of the map object within the GIS framework.  This is the job to be done for making the business layer independed of the GIS architecture choosen. 
The loading of the ESRI components will be kicked off by the GisOperation  module of the GIS framework through AMD pattern.

In a next document I will illustrate more of the practical aspects in detail to move towards AMD implementation.