[mapguide-users] FDO 3.4.0 Beta 1 - SQL 2008 - empty schema

miansi AndreiSinelnikov at SierraSystems.com
Mon Feb 16 13:23:08 EST 2009


Right...

The only reason I am messing up with FDO as I am trying to resolve one
problem.
I have database layout, which includes one "base" table and many concrete
tables, which have 1 to 1 relationships to the "base" table.

Observe:
http://n2.nabble.com/file/n2336381/DB.png 

On the map and inside my application I need to present information joined
from both tables. For that I created SQL view and used it.

Everything is OK, but I cannot select anything on this layer. I see features
on the map, I see mouse pointer changing its shape from ][ to arrow, but
neither clicking on feature nor selecting area, which includes multiple
features do select features.

I checked Map properties->Layer properties. Features are selectable
http://n2.nabble.com/file/n2336381/MapProperties.png 

OK. Further investigation showed that as soon as I point layer to the table
(NOT VIEW) - I am able to select features on the map. Sounds like FDO issue.

IMHO it is have something to do with clustered Primary Key (SQL requirement
for the table in order to create spatial index). And because I am unable to
create primary key on view - I would not be able to make features selectable
on the map. This is not an option.

Now. Maybe there is yet another setting I can try? For me this behaviour
looks like a bug. Is it? Or it is "feature"? If it is a bug - where I can
report it?

The only one option for me right now is to create Geo table, which will be
basically join between base and concrete tables and use triggers to keep
records in between the tables in sync. This is UGLY.

What you think? Did I miss something? My experience with MGOS 2.0.2 is about
month and a half, so it is quite possible that I missed something obvious.
Some setting (hopefully :-)) 

Here is code (just in case). I am creating layer and adding it to the map
using this approach (Creating .NET objects for Mapguide XML schema
Definitions (XSD) using LINQ -
http://www.webrade.com/blogs/darrin/2008/05/16/CreatingNETObjectsForMapguideXMLSchemaDefinitionsXSDUsingLINQ.aspx)

        private void AddLayerDef2Map(String layerName, String
layerLegendLabel, String groupName, String groupLegendLabel)
        {
            // get or set the resourceid of the map to load - in this case
i'm just going to hard code it
            MgResourceIdentifier resourceMap = new
MgResourceIdentifier(this.MyMgController.Attributes.MgMapName);
            // define a new layerResID to use in the loop
            MgResourceIdentifier resourseLayer = new
MgResourceIdentifier(this.MyMgController.Attributes.MgLayerName(layerName,
groupName));
            // create our connection to the resource service
            MgResourceService resourceService =
(MgResourceService)this.MyMgController.MgConn.CreateService(MgServiceType.ResourceService);
            // Get new Layer XML
            String xmlLayer = GetLayerXml();
            // Get updated map XML
            // TODO: Check if there is map available and if not:
            // 1. Create map
            // 2. Create layer
            String xmlMap = GetMapXml(resourceService, resourceMap,
resourseLayer, groupName, groupLegendLabel);

            resourceService.SetResource(resourseLayer, new
MgByteReader(xmlLayer, MgMimeType.Xml), null);
            resourceService.SetResource(resourceMap, new
MgByteReader(xmlMap, MgMimeType.Xml), null);

        }

        /// <summary>
        /// Create XML representation of updated map
        /// </summary>
        /// Map resource name, i.e. "Library://MUNICIPALITIES/MyTown/5
Map/Map.MapDefinition"
        /// Layer resource name, i.e. "Library://MUNICIPALITIES/MyTown/3
Layer/ENGINEEREDSTRUCTURE_ROAD_CULVERT_CULVERT.LayerDefinition"
        /// Name of the layer group, i.e. "WATER"
        /// Legend label for map group, i.e. "Water"
        /// <returns>Map XML as per MapDefinition-1.0.0.xsd (see C:\Program
Files\MapGuideOpenSource2.0\Server\Schema)</returns>
        public static String GetMapXml(MgResourceService resourceService,
MgResourceIdentifier resourceMap, MgResourceIdentifier resourseLayer, String
groupName, String groupLegendLabel)
        {
            // load the existing map from the libary into an XML document
            XmlDocument mapXml = GetResourceXml(resourceService,
resourceMap);

            // so at this point we have an XML document.  Let's try using
our new OSGeo.Mapguide.Object classes
            MapDefinition newMapDefinition = new MapDefinition();

            // to load the xml - call the shared/static method of
MapDefinition.Parse on the OuterXML of the XMLDocument
            newMapDefinition = MapDefinition.Parse(mapXml.OuterXml);

            // add any needed layer groups to the map.  In this example
we're only going to add one.
            newMapDefinition = AddMapLayerGroup(newMapDefinition, groupName,
groupLegendLabel);

            // Set layer properties for map definition
            //<MapLayer>
            //    <Name>ENGINEEREDSTRUCTURE_ROAD_CULVERT_CULVERT</Name>
            //    <ResourceId>Library://MUNICIPALITIES/MyTown/3
Layer/ENGINEEREDSTRUCTURE_ROAD_CULVERT_CULVERT.LayerDefinition</ResourceId>
            //    <Selectable>true</Selectable>
            //    <ShowInLegend>true</ShowInLegend>
            //    <LegendLabel>Culvert (DEV - MyTown)</LegendLabel>
            //    <ExpandInLegend>true</ExpandInLegend>
            //    <Visible>true</Visible>
            //    <Group>ROAD</Group>
            //</MapLayer>
            MapLayerType newLayerType = new MapLayerType();
            // for adding a layer to the map - we must use the MapLayerType
object 
            newLayerType.ResourceId = resourseLayer.ToString();
            newLayerType.Name = resourseLayer.GetName();
            newLayerType.Selectable = true;
            newLayerType.ShowInLegend = true;
            newLayerType.LegendLabel = resourseLayer.GetName();
            newLayerType.ExpandInLegend = true;
            newLayerType.Visible = true;
            newLayerType.Group = groupName;

            // Add layer to the map definition
            newMapDefinition.MapLayer.Insert(0, newLayerType);

            // At this point our map definition is loaded.
            // Lets convert it back to XML and save it to the Map Definition
            XmlDocument xmlMap = new XmlDocument();
            String szXML = newMapDefinition.Untyped.ToString();

            xmlMap.PreserveWhitespace = true;
            xmlMap.LoadXml(szXML);

            return xmlMap.OuterXml;
        }

        /// <summary>
        /// Create XML representation of the new layer
        /// </summary>
        /// <returns>Layer XML as per LayerDefinition-1.2.0.xsd (see
C:\Program Files\MapGuideOpenSource2.0\Server\Schema)</returns>
        public String GetLayerXml()
        {
            XmlDocument xmlLayer = new XmlDocument();
            LayerDefinitionType newLayer = new LayerDefinitionType();

            VectorLayerDefinitionType vectorLayerDefinitionType = new
VectorLayerDefinitionType();

            vectorLayerDefinitionType.ResourceId =
"Library://MUNICIPALITIES/MyTown/2 Data/Data.FeatureSource";
            vectorLayerDefinitionType.FeatureName = "dbo:vw_Pipe_Channel";
            vectorLayerDefinitionType.FeatureNametype = "FeatureClass";
            vectorLayerDefinitionType.Filter = String.Empty;

            // TODO: iterate through all available properties
            NameStringPairType propertyMapping = new NameStringPairType();
            propertyMapping.Name = "Id";
            propertyMapping.Value = "Id";
            vectorLayerDefinitionType.PropertyMapping.Add(propertyMapping);

            vectorLayerDefinitionType.Geometry = "Geo";
            vectorLayerDefinitionType.Url = String.Empty;
            vectorLayerDefinitionType.ToolTip = String.Empty;

            // TODO: Build style... Point, line or polygon
            VectorScaleRangeType rangeType = new VectorScaleRangeType();
            PointTypeStyleType pointStyleType = new PointTypeStyleType();

            pointStyleType.DisplayAsText = false;
            pointStyleType.AllowOverpost = false;

            PointRuleType ruleType = new PointRuleType();
            ruleType.LegendLabel = String.Empty;

            PointSymbolization2DType pointSymbolization2D = new
PointSymbolization2DType();

            MarkSymbolType markSymbolType = new MarkSymbolType();
            markSymbolType.Unit = "Points";
            markSymbolType.SizeContext = "DeviceUnits";
            markSymbolType.SizeX = "10";
            markSymbolType.SizeY = "10";
            markSymbolType.Rotation = "0";
            markSymbolType.MaintainAspect = true;
            markSymbolType.InsertionPointX = "0";
            markSymbolType.InsertionPointY = Convert.ToDouble("0");
            markSymbolType.Shape = "Star";

            FillType fillType = new FillType();
            fillType.FillPattern = "Solid";
            fillType.ForegroundColor = "ff000000";
            fillType.BackgroundColor = "ffffffff";

            StrokeType edge = new StrokeType();
            edge.LineStyle = "Solid";
            edge.Thickness = "1";
            edge.Color = "ffff00";
            edge.Unit = "Points";
            edge.SizeContext = "DeviceUnits";

            markSymbolType.Fill = fillType;
            markSymbolType.Edge = edge;
            pointSymbolization2D.Mark = markSymbolType;
            ruleType.PointSymbolization2D = pointSymbolization2D;
            pointStyleType.PointRule.Add(ruleType);
            rangeType.PointTypeStyle.Add(pointStyleType);
            vectorLayerDefinitionType.VectorScaleRange.Add(rangeType);
            newLayer.VectorLayerDefinition = vectorLayerDefinitionType;

            xmlLayer.PreserveWhitespace = true;
            // Load template
           
xmlLayer.Load(Server.MapPath(@"~/Templates/layerdefinition.templ"));
            // Replace VectorLayerDefinition with layer definition from
newLayer
            //<?xml version="1.0" encoding="UTF-8"?>
            //<LayerDefinition
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="LayerDefinition-1.2.0.xsd" version="1.2.0">
            //    <VectorLayerDefinition>
            //    </VectorLayerDefinition>
            //</LayerDefinition>
            xmlLayer.DocumentElement.InnerXml =
newLayer.VectorLayerDefinition.Untyped.ToString();

            return xmlLayer.OuterXml;

        }

        /// <summary> 
        /// Returns a loaded XML document of the specified resourceId 
        /// </summary> 
        /// An open connection to the Mapguide Resource Service 
        /// The MgResourceID of the entity in question 
        /// <returns>A loaded XMLDocument of the specified
resource</returns> 
        /// <remarks></remarks> 
        public static XmlDocument GetResourceXml(MgResourceService
resourceService, MgResourceIdentifier resourceId)
        {
            XmlDocument resourceDocument = new XmlDocument();
            resourceDocument.PreserveWhitespace = true;

            string resourceXml =
resourceService.GetResourceContent(resourceId).ToString();
            int byteCount = 0;
            byte[] bytes = new byte[resourceXml.Length + 1];
            byteCount = Encoding.UTF8.GetBytes(resourceXml, 0,
resourceXml.Length, bytes, 0);

            MemoryStream memStream = new MemoryStream(bytes);
            resourceDocument.Load(memStream);

            return resourceDocument;
        }

        /// <summary> 
        /// Adds a layer group to the passed MapDefinition, and returns the
updated MapDefinition Object. 
        /// If desired, additional parameters could be added to this to
customize the various other properties 
        /// like ShowInLegend etc 
        /// </summary> 
        /// The loaded MapDefinition obect 
        /// The Layer Name of the new layer group 
        /// The Layer Alias of the new layer group 
        /// <returns>the passed MapDefinition, with the new layer group
added</returns> 
        /// <remarks></remarks> 
        public static MapDefinition AddMapLayerGroup(MapDefinition
mapDefinition, String groupName, String groupLegendLabel)
        {
            MapLayerGroupType newLayerGoup = new MapLayerGroupType();
            newLayerGoup.Name = groupName;
            newLayerGoup.LegendLabel = groupLegendLabel;
            newLayerGoup.ShowInLegend = true;
            newLayerGoup.ExpandInLegend = true;
            newLayerGoup.Visible = true;
            newLayerGoup.Group = String.Empty;
            mapDefinition.MapLayerGroup.Add(newLayerGoup);

            return mapDefinition;
        }




Thank you


Jason Birch wrote:
> 
> Heh; I'm surprised you made it that far.  I'm pretty sure that FDO 3.4.x
> will not work with MapGuide 2.0.2; the latest version that is binary
> compatible (and which also includes the SQL2008 Provider) is available
> here:
>  
> http://download.osgeo.org/fdo/3.3.2/
>  
> The only client-side app I know of that currently works with FDO 3.4 beta
> is FDO Toolbox.
>  
> Jason
> 
> ________________________________
> 
> From: miansi
> Sent: Sun 2009-02-15 9:09 AM
> To: mapguide-users at lists.osgeo.org
> Subject: Re: [mapguide-users] FDO 3.4.0 Beta 1 - SQL 2008 - empty schema
> 
> Do I treat it as no schemas? Any idea where to poke next? ;-)
> 
> 
>  
> _______________________________________________
> mapguide-users mailing list
> mapguide-users at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/mapguide-users
> 
> 

-- 
View this message in context: http://n2.nabble.com/FDO-3.4.0-Beta-1---SQL-2008---empty-schema-tp2322472p2336381.html
Sent from the MapGuide Users mailing list archive at Nabble.com.



More information about the mapguide-users mailing list