# Friday, September 26, 2008

I have enough junk running on my development machine.  In an effort to try and keep my workstation speedy - I don't install any unnecessary services (Oracle server, Mapguide Server etc) on this machine.  In a larger development environment, running multiple servers on local development machines has a few other less than desirable results.  For example licensing issues and costs could increase, data management can become more complex, and just managing the extra services on N machines could cause a lot more work for your already overworked IT guy.

So instead I have centralized my server resources into a nice VM setup running on my beefy Dell server.  Now, regardless of which machine I use to develop I can still access the same data sets.  This is especially nice when traveling.  Specifically Mapguide Server and web tier are installed on my development web server.  When coding, I will either use my local IIS or the built in Visual Studio web server.  This poses one problem when working with Mapguide.  Referencing the web tier on the shared server from another web server will result in (XSS) errors.  Basically, javascript on one web server cannot access javascript code on another web server, which under most circumstances is a good thing.  When trying to develop using the Mapguide Web API on a central Mapguide server this poses a problem as the web tier API is wholly contained within the virtual directory on another server.  Gotta love when 'security' jumps up bites us in the behind.

The simple solution to this problem is to install the Mapguide web tier on every development machine.  This will require that each development machine have a web server installed, but chances are that is already the case.  When installing the web tier be sure to have the IP address of the Mapguide server handy as it will needed during the install.  Once the web tier is running locally, reference the local web tier in your URLs and the cross site scripting vulnerabilities go away!  If you're running the 64 Bit version of Vista on your development machine, check out my post installing the

Technorati Tags: ,
Friday, September 26, 2008 12:41:01 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Thursday, September 25, 2008

Over the years, this problem has sporadically appeared (probably once or twice a year).  In the Mapguide 6.5 server admin when creating a new data source the Autodesk Spatial Data Provider for Oracle Spatial doesn't appear as an option.  Every time this comes up I end up wracking my brain to remember what the solution is.  I know I've dealt with this many times - but I cannot remember the details.  Usually it's occurring on a customer's production server which is not a place I like to mess around.  This time, it was my development server - let the messing around begin!

In a nutshell this is a result of installing Mapguide server before the Oracle client is installed on the server.  The solution is to do a repair install of Mapguide Server (or a re-install if you prefer) once the Oracle client is installed.  Hopefully next year when this comes up again - writing this down will help me remember.  Worst case Google might pick this up and I'll find my own post when I search for it...

Technorati Tags: ,
Wednesday, September 24, 2008 11:41:38 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Wednesday, June 25, 2008

Typically developers are color stupid (myself included).  I've seen some really really ugly maps.  I've created some really really ugly maps.  With Mapguide 6.5 in particular - I gave up on trying to create visually appealing maps.  The 255 colors, in the ranges defined I just could not do it.

With Mapguide Enterprise - I may have found a solution.  Recently I created a themed layer for municipalities.  There were twenty five municipalities in a single spatial table.  Each municipality had a unique code.   In an effort to bang these off quickly I added the twenty five municipalities and the filter condition.   Next I entered the twenty five legend labels.

Here is the developer friendly method I came up with creating a somewhat visually appealing color range.  In the first condition I set first set the transparency to 50%.  The transparency affects the resulting color.  Select the color combo and choose "More Colors".  This should bring up the custom color dialog.  First, select one of the "Custom Color" boxes and set the Hue to 0. Next I created a color I wanted to use as my starting shade.

At this point, I saved the color using the "Add to Custom Colors" button.  Your form should look something like this:

Mapguide Color Dialog

Click OK a couple of times and your first condition should be set.  Next I selected my next condition, and clicked the color combo again choosing "More Colors" once again.  This time, select the saved custom color and it should reset the form with the previously saved shade.  At this point I incremented the Hue by 20 to 20.  Click ok a couple of times and repeat.  I was not re-saving my shade, though I suppose that might have made sense.  Each time you repeat this process increase the hue by 20 until you hit the max of 239.

If needed, and you do hit the max hue start the process over starting with another complimentary base shade with a hue of 0. Using a hue increment of 40 might have resulted in more distinct colorations and may be a good idea.

I think it turned out OK, but then again as I stated earlier - I'm color stupid. 

Resulting Color Range

Wednesday, June 25, 2008 10:30:30 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Tuesday, June 24, 2008

I've been authoring some test data for my ongoing Mapguide Enterprise \ MGOS work.  For consistency with my existing tabular test data, I need to migrate some Mapguide 6.5 maps over to Enterprise.  This is quite the chore.  I really wish Autodesk would have kept updating the Mapguide 6.5 and bring that up to support a current release of Mapguide.  Even with the tools flaws, it was still a good start on migration - but oh well, that's another rant completely..and maybe another side project that I just don't have time for =)

Anyhow, I wanted to share the .  I can't believe I hadn't found this page sooner.  A fantastic, and crucial reference.   Tons of useful settings for the chart generator.  Show the hex codes for using the colors in HTML, Decimal RGB values for Mapguide Enterprise \ Autocad.  The colors under the Decimal heading are the RGB values - ordered in Red, Green, Blue.  I've been using the chart in .

Thanks Pima County.  Hopefully, you guys were able to come up with a programmatic method of creating this chart.  I'd hate to be the guy tasked with 'eyedropping' all these colors using Photoshop or something.

The decimal values by the way should work with AutoCAD too.

 

Technorati Tags:
Tuesday, June 24, 2008 3:59:23 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Wednesday, May 21, 2008

As a follow up to my previous post on , I wanted to share some examples of using these new objects, so I created this example of doing some dynamic authoring before the map viewer has loaded.  Currently, all of my work is done using Mapguide Enterprise 2009, however this code should work using Mapguide Open 2.0 as well.  I believe I had this code working using Mapguide 2008 initially, and then migrated it over to the 2009 platform.  Feel free to give that shot if you are still using Mapguide 2008.  Some changes would be needed in the .Net objects project - to remove 2009 specific XSD files and possibly reference some of the older XSDs for things like layers.

One of my first tasks with Mapguide Enterprise was to build a map on the fly.  There were examples for adding layers to the map programmatically after the viewer had loaded, but this didn't match the desired flow of my application.  Also, having come from years of Mapguide 6.5 and lower -  I was trying to avoid as much client side automation as possible.  The new was one of the things that excited me the most about Mapguide Enterprise / Mapguide Open Source

I've pasted the full, commented code here, as well as attached a solution containing the two projects needed.  Note these projects are Visual Studio 2008 projects.  Please feel free to use this code for learning purposes.  If it helps you out, link back to this article =)

If you choose instead to create a new project, be sure to add a project or DLL reference to the OSGeo.Mapguide.Objects.dll file we created previously .  The project I've included here contains both the sample Web Application project, as well as a copy of the .NET objects for Mapguide project.  It should be almost ready for the running.  Also ensure there is a reference to the Microsoft.XML.Schema.Linq namespace added to the project.  Also copy the required .DLL files from the Autodesk provided .NET viewer\bin folder to the web projects bin folder.  I did not include these here as I was not sure of the legality of doing so.

First load up the into your Mapguide repository.  For the purposes of this example, open the Map definition in Mapguide Studio (or equivalent) and remove all the layers and layer groups from the map.  If you forget to do this you will get a Duplicate Object error when you load up the map.  Once that is done, you are ready to try out the code.

You should be able top unzip the zip and open the MGEDynamicAuthoringSample.sln file with Visual Studio.  Pretty much the only thing you may need to change are the constants to match your machine specific items:

 

   1: 'set some contants up - webconfig.ini, map viewer url, Map, Layout and Layer locatinos
   2: Private Const gszWebConfig As String = "C:\inetpub\MapGuideEnterprise2009\WebServerExtensions\www\webconfig.ini"
   3: Private Const gszViewerUrl As String = "http://localhost/mapguide2009/mapviewerdwf"
   4: Private Const gszMapResID As String = "Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition"
   5: Private Const gszLayerFolderResID As String = "Library://Samples/Sheboygan/Layers.Folder"
   6: Private Const gszLayoutResID As String = "Library://Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout"
   7: 'lets run with Administrator for noew to eliminate permission problems.  Update your password as needed, or specify your
   8: 'own credentials if you are comfortable with setting up repository permissions.
   9: Private Const gszMGUser As String = "Administrator"
  10: Private Const gszMGPass As String = "admin"


Once you've changed all the needed settings, you should be good to go.  Run the code in Visual Studio and you should now see a map similar to the default Sheboygan map.  The key difference is that all of the layers will exist within the layer group we created programmatically.

Commented Codebehind:

   1: Imports OSGeo.MapGuide
   2: 'we still need to import and use system.xml, but don't really need to use many parts of the XML
   3: 'functionality =)
   4: Imports System.Xml
   5: Partial Public Class _Default
   6:     '' 'So for this example, we're going to use the sheboygan sample package available from 
   7:     '' ' http://mapguide.osgeo.org/download/releases/2.0.x-samples.  Be sure to grab both the 
   8:     '' ' dotnetviewstample.zip as well as the sheboygan.mgp.  Import the package using
   9:     '' ' the mapguide site administrator.  I've tried to use the default resource paths
  10:     '' ' but some tweaking of map will be needed
  11:     '' ' 
  12:     '' ' Open the map definition in Studio, and remove all the layers from Samples/Sheboygan/Maps/Sheboygan.MapDefinition 
  13:     '' ' we're going to add them dynamically    
  14:  
  15:     Inherits System.Web.UI.Page
  16:  
  17:     'set some contants up - webconfig.ini, map viewer url, Map, Layout and Layer locatinos
  18:     Private Const gszWebConfig As String = "C:\inetpub\MapGuideEnterprise2009\WebServerExtensions\www\webconfig.ini"
  19:     Private Const gszViewerUrl As String = "http://localhost/mapguide2009/mapviewerdwf"
  20:     Private Const gszMapResID As String = "Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition"
  21:     Private Const gszLayerFolderResID As String = "Library://Samples/Sheboygan/Layers.Folder"
  22:     Private Const gszLayoutResID As String = "Library://Samples/Sheboygan/Layouts/SheboyganAsp.WebLayout"
  23:     Private Const gszMGUser As String = "Administrator"
  24:     Private Const gszMGPass As String = "admin"
  25:  
  26:     ''' <summary>
  27:     ''' Page_Load does everything =)  Be sure to copy the dll files from your mapviewernet\bin folder to this projects bin folder.
  28:     ''' I did not include them as that might have violated some autodesk license.    
  29:     ''' </summary>
  30:     ''' <param name="sender"></param>
  31:     ''' <param name="e"></param>
  32:     ''' <remarks></remarks>
  33:     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  34:  
  35:         'setup our siteconnection
  36:         Dim siteConnection As New MgSiteConnection
  37:         siteConnection = CreateMGSession(gszMGUser, gszMGPass, gszWebConfig)
  38:         Dim szSessionId As String = siteConnection.GetSite.CreateSession()
  39:  
  40:         'create our connection to the resource service
  41:         Dim resSvc As MgResourceService
  42:         resSvc = siteConnection.CreateService(MgServiceType.ResourceService)
  43:  
  44:         'get or set the resourceid of the map to load - in this case i'm just going to hard code it
  45:         Dim mapResourceID As New MgResourceIdentifier(gszMapResID)
  46:  
  47:         'load the existing map from the libary into an XML document
  48:         Dim mapXML As XmlDocument = GetResourceXML(resSvc, mapResourceID)
  49:  
  50:         'so at this point we have an XML document.  Let's try using our new OSGeo.Mapguide.Object classes
  51:         Dim newMapDefinition As New OSGeo.MapGuide.Objects.MapDefinition
  52:  
  53:         'to load the xml - call the shared/static method of MapDefinition.Parse on the OuterXML of the XMLDocument
  54:         newMapDefinition = OSGeo.MapGuide.Objects.MapDefinition.Parse(mapXML.OuterXml)
  55:  
  56:         'at this point we have a loaded .NET Object containing the map.  Try using Intellisense to see the different methods
  57:         'Lets add a layer group now
  58:  
  59:         'add any needed layer groups to the map.  In this example we're only going to add one.
  60:         Dim szLayerGroupName As String = "NewLayerGroup"
  61:         Dim szLayerGroupAlias As String = "My Layer Group Alias"
  62:         newMapDefinition = AddMapLayerGroup(newMapDefinition, szLayerGroupName, szLayerGroupAlias)
  63:  
  64:         'get or set the resourceid of the folder that contains our layers to add
  65:         Dim layerPath As New MgResourceIdentifier(gszLayerFolderResID)
  66:  
  67:         'so we now have a layer group in our map.  Lets add the layers
  68:         AddFolderOfLayers(resSvc, newMapDefinition, layerPath, szLayerGroupName)
  69:  
  70:         'at this point our map definition is loaded.  Lets convert it back to XML and save it to the session
  71:         Dim newMapDoc As New XmlDocument
  72:         newMapDoc.PreserveWhitespace = True
  73:  
  74:         Dim szXML As String = newMapDefinition.Untyped.ToString
  75:         newMapDoc.LoadXml(szXML)
  76:  
  77:         'create our 'new' resourceID in the session repository
  78:         Dim newMapResourceID As New MgResourceIdentifier("Session:" & szSessionId & "//" & mapResourceID.GetName() & "." & MgResourceType.MapDefinition)
  79:  
  80:         'save the newly created map in the session repository
  81:         CreateSessionResource(resSvc, newMapDoc, szSessionId, newMapResourceID.GetName, MgResourceType.MapDefinition)
  82:  
  83:         'now lets deal with the layout - we need to load up the library layout, update the map definition, and save it to the repository
  84:         Dim layoutResourceID As New MgResourceIdentifier(gszLayoutResID)
  85:         Dim newLayoutResourceID As New MgResourceIdentifier("Session:" & szSessionId & "//" & layoutResourceID.GetName() & "." & MgResourceType.WebLayout)
  86:  
  87:         'same process here, load the XML, parse the XML into the new .net Object
  88:         Dim layoutXML As XmlDocument = GetResourceXML(resSvc, layoutResourceID)
  89:  
  90:         Dim newLayout As New OSGeo.MapGuide.Objects.WebLayout
  91:         newLayout = OSGeo.MapGuide.Objects.WebLayout.Parse(layoutXML.OuterXml)
  92:  
  93:         'update the map resource ID in the layout to point to our newly created map in the session
  94:         newLayout.Map.ResourceId = newMapResourceID.ToString
  95:  
  96:         'finally go through the motinos to save the layout to the session
  97:         Dim newLayoutXML As New XmlDocument
  98:         newLayoutXML.PreserveWhitespace = True
  99:         newLayoutXML.LoadXml(newLayout.Untyped.ToString())
 100:  
 101:         CreateSessionResource(resSvc, newLayoutXML, szSessionId, newLayoutResourceID.GetName, MgResourceType.WebLayout)
 102:  
 103:         'our last step is to update the src attribute of the iframe with the information needed to load the newly created layout
 104:         SetupIFrame(newLayoutResourceID, szSessionId)
 105:     End Sub
 106:     Private Sub SetupIFrame(ByVal layoutResId As MgResourceIdentifier, ByVal szSessionID As String)
 107:         'build the URL based on our constants, and the layout + session info
 108:         Dim szUrl As String = gszViewerUrl & "?WEBLAYOUT=" & layoutResId.ToString & "&SESSION=" & szSessionID
 109:  
 110:         'update the iframe
 111:         ifrmViewer.Attributes.Add("src", szUrl)
 112:     End Sub
 113:     ''' <summary>
 114:     ''' Adds a layer group to the passed MapDefinition, and returns the updated MapDefinition Object.
 115:     ''' If desired, additional parameters could be added to this to customize the various other properties
 116:     ''' like ShowInLegend etc        
 117:     ''' </summary>
 118:     ''' <param name="mapDef">The loaded MapDefinition obect</param>
 119:     ''' <param name="szLayerGroupName">The Layer Name of the new layer group</param>
 120:     ''' <param name="szLayerGroupAlias">The Layer Alias of the new layer group</param>
 121:     ''' <returns>the passed MapDefinition, with the new layer group added</returns>
 122:     ''' <remarks></remarks>
 123:     Public Shared Function AddMapLayerGroup(ByVal mapDef As OSGeo.MapGuide.Objects.MapDefinition, ByVal szLayerGroupName As String, ByVal szLayerGroupAlias As String) As OSGeo.MapGuide.Objects.MapDefinition
 124:         Dim newLayGRoup As New OSGeo.MapGuide.Objects.MapLayerGroupType
 125:         newLayGRoup.Name = szLayerGroupName
 126:         newLayGRoup.LegendLabel = szLayerGroupAlias
 127:         newLayGRoup.ShowInLegend = "True"
 128:         newLayGRoup.ExpandInLegend = "True"
 129:         newLayGRoup.Visible = "True"
 130:         newLayGRoup.Group = ""
 131:         mapDef.MapLayerGroup.Add(newLayGRoup)
 132:         Return mapDef
 133:     End Function
 134:  
 135:     ''' <summary>
 136:     ''' Adds all layer definitions within the specified repository folder to the specified map
 137:     ''' </summary>
 138:     ''' <param name="resSvc">An open resource service connection</param>
 139:     ''' <param name="newMap">the MapDefinition object to modify</param>
 140:     ''' <param name="resLocation">The folder in the repository to search for layer objects</param>
 141:     ''' <returns>Update MapDefinition object</returns>
 142:     ''' <remarks></remarks>
 143:     Public Shared Function AddFolderOfLayers(ByRef resSvc As MgResourceService, ByVal newMap As OSGeo.MapGuide.Objects.MapDefinition, ByVal resLocation As MgResourceIdentifier, ByVal szLayerGroupName As String) As OSGeo.MapGuide.Objects.MapDefinition
 144:         'get the list of layers in the folder
 145:         Dim resList As OSGeo.MapGuide.Objects.ResourceList
 146:         'use GetAllResources to get a new resList
 147:         resList = GetAllResources(resSvc, resLocation, 1, MgResourceType.LayerDefinition)
 148:  
 149:         'resList items are pretty much a collection of resrouceDocumentLocalTypes so define one of these to use in the for loop
 150:         Dim resItem As OSGeo.MapGuide.Objects.ResourceList.ResourceDocumentLocalType
 151:  
 152:         'define a new layerResID to use in the loop
 153:         Dim layerResID As MgResourceIdentifier
 154:  
 155:         'for each layer - process it and add it to the map
 156:         Dim newLayerType As New OSGeo.MapGuide.Objects.MapLayerType
 157:         For Each resItem In resList.ResourceDocument
 158:             layerResID = New MgResourceIdentifier(resItem.ResourceId)
 159:             'for adding a layer to the map - we must use the MapLayerType object 
 160:             newLayerType = New OSGeo.MapGuide.Objects.MapLayerType
 161:             newLayerType.ResourceId = layerResID.ToString
 162:             'Be sure to specify the name of the 
 163:             newLayerType.Group = szLayerGroupName
 164:             newLayerType.Name = layerResID.GetName
 165:             newLayerType.Selectable = "false"
 166:             newLayerType.ShowInLegend = "true"
 167:             newLayerType.LegendLabel = layerResID.GetName
 168:             newLayerType.ExpandInLegend = "true"
 169:             newLayerType.Visible = "true"
 170:  
 171:             newMap.MapLayer.Insert(0, newLayerType)
 172:         Next
 173:         'return the updated MapDefinition
 174:         Return newMap
 175:     End Function
 176:  
 177:     'Some handy functions
 178:  
 179:     ''' <summary>
 180:     ''' Saves the specified XMLDocument to the session respository
 181:     ''' </summary>
 182:     ''' <param name="resSvc">The open resource service connection</param>
 183:     ''' <param name="xmlDoc">the XMLDocument to save to the session repository</param>
 184:     ''' <param name="szSessionId">String containing the session ID</param>
 185:     ''' <param name="szName">The name of the newly created object in the repository</param>
 186:     ''' <param name="szResourceType">the object type</param>