Monday, August 17, 2009

MapGuide and SQL Server 2008

MapGuide and SQL Server 2008

Recently Ive been struggling to get MapGuide and Sql server to work together. After posting to the forums I got a reply: http://www.mail-archive.com/mapguide-users@lists.osgeo.org/msg11760.html. Very nice and to further explain here is a quick overview of what I did:

Step 1

Import your shape files into Sql Server I’ve used Shape2Sql available from www.sharpgis.net

Step 2

Run this query in sql to remove SRID from your features

update dbo.NAN_PARCELS set GEOM.STSrid = 0; Like described here.

Step 3

In my site I’ve used the Maestro API to load and filter my layers dynamically. This is my code behind in my default.aspx page.

        //First we connect to the MapGuide server

        string username = "Anonymous";

        string password = "";

        string layout = "Library://MyFeat/Layout/Layout.WebLayout";

        String configPath = @"C:\Program Files\OSGeo\MapGuide\Web\www\webconfig.ini";

 

        MapGuideApi.MgInitializeWebTier(configPath);

 

        Uri host = new Uri("http://localhost/mapguide/mapagent/mapagent.fcgi");

        conn = new HttpServerConnection(host, username, password, "en", true);

       

        MgUserInformation userInfo = new MgUserInformation(conn.SessionID);

        MgSiteConnection siteConnection = new MgSiteConnection();

        siteConnection.Open(userInfo);

 

        //Now I get the origanal layout that I created in the Maestro Application

        //Get the original layout

        WebLayout weblayout = conn.GetWebLayout(layout);

 

        //Get the mapDefinition

        MapDefinition mapDef = conn.GetMapDefinition(weblayout.Map.ResourceId);

 

        //get the feature source

        FeatureSource feaSource = conn.GetFeatureSource("Library://MyFeat/Data/SQL.FeatureSource");

 

        //Generate a temporary feature source

        string tempFeaDef = new ResourceIdentifier("SQL1", ResourceTypes.FeatureSource, conn.SessionID);

 

        //Save the modified FeatureSource at its new temporary location

        conn.SaveResourceAs(feaSource, tempFeaDef);

       

       

        LayerDefinition layerFeatDefinition = conn.GetLayerDefinition("Library://MyFeat/Layer/Feat.LayerDefinition");

        VectorLayerDefinitionType vectorLayerFeatDefinition = layerFeatDefinition.Item as VectorLayerDefinitionType;

        vectorLayerFeatDefinition.ResourceId = tempFeaDef;

  //Now we filter on the user name

        vectorLayerFeatDefinition.Filter = "User_ID = '" + User.Identity.Name + "'";

        //Save a copy of the layer, temporary

        string tempLayerFeatDef = new ResourceIdentifier("MyFeatLayer", ResourceTypes.LayerDefiniton, conn.SessionID);

        conn.SaveResourceAs(layerFeatDefinition, tempLayerFeatDef);

       

       

        //Create a new MapLayer object

        MapLayerType Featlayer = new MapLayerType();

 

        //Absolute minimum properties

        Featlayer.Visible = true;

        Featlayer.ResourceId = tempLayerFeatDef;

 

        //Extra properties

        Featlayer.Selectable = true;

        Featlayer.ExpandInLegend = true;

        Featlayer.ShowInLegend = true;

        Featlayer.LegendLabel = "Feats";

        Featlayer.Name = "Feat";

        //Now we add these layers to the Map

        List<MapLayerType> maplayers = new List<MapLayerType>();

 

        maplayers.Insert(0, layerLande);

        maplayers.Insert(1, Featlayer);

 

        mapDef.Layers = new MapLayerTypeCollection();

        foreach (MapLayerType mlt in maplayers)

        {

            mapDef.Layers.Add(mlt);

        }

 

        MgFeatureService featureService = (MgFeatureService)siteConnection.CreateService(MgServiceType.FeatureService);

        MgResourceIdentifier resId = new MgResourceIdentifier("Library://MyFeat/Data/SQL.FeatureSource");

        String schema = featureService.DescribeSchemaAsXml(resId, "");

 

        OSGeo.MapGuide.MaestroAPI.LayerDefinition ldef = conn.GetLayerDefinition(tempLayerFeatDef);

        Topology.Geometries.IEnvelope env = null;

        //To show the correct extend filter again (Very Important)

        env = ldef.GetSpatialExtent("User_ID = '" + User.Identity.Name + "'");

        mapDef.Extents.MinX = env.MinX;

        mapDef.Extents.MinY = env.MinY;

        mapDef.Extents.MaxX = env.MaxX;
        mapDef.Extents.MaxY = env.MaxY;

       

        //create a temp map

  string tempMapDef = new ResourceIdentifier("MyMap", ResourceTypes.MapDefinition, conn.SessionID);

 

        //Save the modified map at its new temporary location

        conn.SaveResourceAs(mapDef, tempMapDef);

 

        //Generate a temporary WebLayout id

        tempWebLayout = new ResourceIdentifier("MyMap", ResourceTypes.WebLayout, conn.SessionID);

 

        //Update the WebLayout to point at the modified MapDefinition

        weblayout.Map.ResourceId = tempMapDef;

 

        //Save the modified layout at its new temporary location

        conn.SaveResourceAs(weblayout, tempWebLayout);

Step 4

My main problem was finding the correct extends of the selected geometry using the layers filters, and to load it after the filter was processed otherwise all the data in my database would be loaded, and will filter after the load which will really impact the performance. Please write a comment if you know of a better way of doing this.

 

No comments:

Post a Comment