[mapguide-users] Changing existing dynamic layer's Filter onthefly

Maksim Sestic max at geoinova.com
Sat Nov 17 09:10:55 EST 2007


Dennis, 

Your code works fine, I've tested it. So, this is how it's finally
implemented:

1) there's a MgLayer definition stored in a Library repository, but not in
the Library-based MgMap...
or...
there's a file-based XML definition of a MgLayer

2) function receives that Library-only/file-based MgLayer definition and
does the work over MgMap object found in a Session repository

This gymnastics with creating temporary group, populating it with changed
layers... then erasing them during next query... :-) is obviously the only
possible approach. Still, I'm wondering why isn't it possible to use
SetLayerDefinition() if there's only one resulting layer (my case).

Regards,
Maksim Sestic




djonio wrote:
> 
> Maksim,
> 
> Maybe you are just making to many assumptions about what is under the
> covers? ;-) 
> 
> It takes a few more lines of code but I try to make it a practice to
> modify/delete at the object level and only ever use iterator/index for
> reading. 
> 
> ...burned a couple times with .NET hashtables.
>   
> 
> -----Original Message-----
> From: mapguide-users-bounces at lists.osgeo.org
> [mailto:mapguide-users-bounces at lists.osgeo.org] On Behalf Of Maksim
> Sestic
> Sent: Thursday, November 15, 2007 10:15 AM
> To: mapguide-users at lists.osgeo.org
> Subject: RE: [mapguide-users] Changing existing dynamic layer's Filter
> onthefly
> 
> 
> Djonio, thanks for sharing the code. I'll try it and come out with
> results.
> 
> BTW, did anyone notice that managed version of MgLayerCollection has
> some
> nasty problem when it comes to removing items?
> 
> Try removing MgLayer items by:
> 
> Dim layerIndex As Integer = map.GetLayers.IndexOf(layerName)
> map.GetLayers.RemoveAt(layerIndex)
> 
> and it turns out that either IndexOf or RemoveAt doesn't perform well.
> Or
> maybe it's me doing it the wrong way?
> 
> Regards,
> Maksim Sestic
> 
> 
> 
> djonio wrote:
>> 
>> Maksim, 
>> 
>>  
>> 
>> This is what I am doing in codebehind and it works ... I have to
> clobber
>> the existing layers in this particular group and rebuild them. I have
>> this  "third" dimension thingee to deal with. For you I am sure it all
>> is very obvious.
>> 
>>  
>> 
>> Kenneth,
>> 
>> I am working in MGOS 1.1 ....
>> 
>> Where is this:
>> 
>> MgMap map = new MgMap();
>> 
>> map.Open("map", srv);
>> 
>>  
>> 
>> map.Layers("layername").Filter = "Column = 5";
>> 
>> map.Save();
>> 
>>  
>> 
>> ???????????????????
>> 
>>  
>> 
>>  
>> 
>>  
>> 
>>    public void GenerateSpatialQueryFilteredLayer(MgMap map,
>> MgResourceService resourceService, string keys, Hashtable htFloors,
>> MgLayer fromLayer)
>> 
>>     {
>> 
>>         // Set the group
>> 
>>         MgLayerGroup mglg_root = this.CreateLayerGroup(map,
>> "_SpatialQueryResults", null);
>> 
>>         // Remove all the layers from the last query
>> 
>>         MgLayer layer = null;
>> 
>>         ArrayList layers_to_be_removed = new ArrayList();
>> 
>>         for (int i = 0; i < map.GetLayers().GetCount(); i++)
>> 
>>         {
>> 
>>             MgLayer nextLayer = (MgLayer)map.GetLayers().GetItem(i);
>> 
>>             MgLayerGroup actual_group = nextLayer.GetGroup();
>> 
>>             if (actual_group != null)
>> 
>>             {
>> 
>>                 if (actual_group.Name == mglg_root.Name)
>> 
>>                     layers_to_be_removed.Add(nextLayer);
>> 
>>             }
>> 
>>         }
>> 
>>         for (int i = 0; i < layers_to_be_removed.Count; i++)
>> 
>>         {
>> 
>>             if (layers_to_be_removed[i] != null)
>> 
>>             {
>> 
>>                 bool IsRemoved =
>> map.GetLayers().Remove((MgLayerBase)layers_to_be_removed[i]);
>> 
>>                 // Lets try one more time if we failed .... no good
>> reason ... just try
>> 
>>                 if (IsRemoved == false)
>> 
>>                 {
>> 
>>                     IsRemoved =
>> map.GetLayers().Remove((MgLayerBase)layers_to_be_removed[i]);
>> 
>>                 }
>> 
>>             }
>> 
>>         }        
>> 
>>         map.Save(resourceService);
>> 
>>         
>> 
>>         // Get the floors from the passed in hashtable so we can make
> up
>> a layer for each
>> 
>>         ArrayList al = new ArrayList();
>> 
>>         IDictionaryEnumerator ide = htFloors.GetEnumerator();
>> 
>>         while (ide.MoveNext())
>> 
>>         {
>> 
>>             DictionaryEntry de = (DictionaryEntry)ide.Current;
>> 
>>             al.Add((string)de.Key);
>> 
>>         }
>> 
>>         al.Sort(null);
>> 
>>         string[] Floors = (string[])al.ToArray(typeof(string));
>> 
>>  
>> 
>>         // Get the definition identifier from the passed in layer ...
>> just one time       
>> 
>>         MgResourceIdentifier toResId = new
>> MgResourceIdentifier(fromLayer.GetLayerDefinition().ToString());
>> 
>>         // Go get the layer definition
>> 
>>         string LibLayDef =
>> resourceService.GetResourceContent(toResId).ToString();
>> 
>>         XmlDocument doc = new XmlDocument();
>> 
>>         doc.PreserveWhitespace = true;
>> 
>>         doc.LoadXml(LibLayDef);
>> 
>>         XPathNavigator nav = doc.CreateNavigator();
>> 
>>         
>> 
>>         // for each floor name create a layer and set the filter for
>> each
>> 
>>         for (int _f = 0; _f < Floors.Length; _f++)
>> 
>>         {
>> 
>>             string LayerNameForSession = Floors[_f];
>> 
>>             nav.MoveToRoot();
>> 
>>             XPathNodeIterator nodeIter =
>> nav.Select("//VectorLayerDefinition/Filter");
>> 
>>             // There should be only one ....
>> 
>>             while (nodeIter.MoveNext())
>> 
>>             {
>> 
>>                 nodeIter.Current.InnerXml = "(" + keys + ") AND (Floor
>> ='" + Floors[_f] + "')";
>> 
>>             }
>> 
>>             // Setup to load the definition into the active map object
>> 
>>             MemoryStream xmlStream = new MemoryStream();
>> 
>>             doc.Save(xmlStream);
>> 
>>             byte[] layerDefinition = xmlStream.ToArray();
>> 
>>             //Encoding utf8 = Encoding.UTF8;
>> 
>>             String layerDefStr = new
>> String(Encoding.UTF8.GetChars(layerDefinition));
>> 
>>             layerDefinition = new byte[layerDefStr.Length - 1];
>> 
>>             int byteCount = Encoding.UTF8.GetBytes(layerDefStr, 1,
>> layerDefStr.Length - 1, layerDefinition, 0);
>> 
>>  
>> 
>>             MgByteSource byteSource = new
> MgByteSource(layerDefinition,
>> layerDefinition.Length);
>> 
>>             byteSource.SetMimeType(MgMimeType.Xml);
>> 
>>             MgByteReader mgByteReaderOut = byteSource.GetReader();
>> 
>>             MgResourceIdentifier mgResIdAcvLaySess = new
>> MgResourceIdentifier(
>> 
>>  
>> "Session:" +
>> 
>>  
>> map.SessionId +
>> 
>>                                                                 "//" +
>> 
>>  
>> LayerNameForSession +
>> 
>>                                                                 "." +
>> 
>>  
>> MgResourceType.LayerDefinition);
>> 
>>  
>> 
>>             // Set the map with the new resource
>> 
>>             resourceService.SetResource(mgResIdAcvLaySess,
>> mgByteReaderOut, null);
>> 
>>             // make sure that we do not duplicate 
>> 
>>             MgLayer layer_check = null;
>> 
>>             try
>> 
>>             {
>> 
>>                 layer_check =
>> (MgLayer)map.GetLayers().GetItem(LayerNameForSession) as MgLayer;
>> 
>>                 layer_check.ForceRefresh();
>> 
>>             }
>> 
>>             catch (Exception) { };
>> 
>>             if (layer_check == null)
>> 
>>             {
>> 
>>                 layer = new MgLayer(mgResIdAcvLaySess,
> resourceService);
>> 
>>  
>> 
>>                 layer.SetGroup(mglg_root);
>> 
>>                 layer.SetName(LayerNameForSession);
>> 
>>                 layer.SetLegendLabel(LayerNameForSession);
>> 
>>                 layer.SetDisplayInLegend(true);
>> 
>>                 layer.SetSelectable(true);
>> 
>>                 layer.ForceRefresh();
>> 
>>                 // Add it to the collection
>> 
>>                 MgLayerCollection layers = map.GetLayers();
>> 
>>                 layers.Insert(0, layer);
>> 
>>             }
>> 
>>         }
>> 
>>         map.Save(resourceService);
>> 
>>     }
>> 
>>  
>> 
>>  
>> 
>> -----Original Message-----
>> From: mapguide-users-bounces at lists.osgeo.org
>> [mailto:mapguide-users-bounces at lists.osgeo.org] On Behalf Of Kenneth,
>> GEOGRAF A/S
>> Sent: Thursday, November 15, 2007 8:28 AM
>> To: MapGuide Users Mail List
>> Subject: Re: [mapguide-users] Changing existing dynamic layer's Filter
>> onthe fly
>> 
>>  
>> 
>> When the MapDefinition is turned into a runtime Map, it copies 
>> 
>> properties from the layerdefinition.
>> 
>> This means that you will see no changes, even if you choose to modify 
>> 
>> the LayerDefinition.
>> 
>>  
>> 
>> You must modify the layer copy in the runtime map.
>> 
>> Fortunately, that is actually easier than what you are doing now:
>> 
>>  
>> 
>> MgMap map = new MgMap();
>> 
>> map.Open("map", srv);
>> 
>>  
>> 
>> map.Layers("layername").Filter = "Column = 5";
>> 
>> map.Save();
>> 
>>  
>> 
>> Regards, Kenneth, GEOGRAF A/S
>> 
>>  
>> 
>>  
>> 
>>  
>> 
>> Maksim Sestic skrev:
>> 
>>> I think I'm having problems with changing existing dynamic layer's
>> Filter
>> 
>>> property (the one that filters data from FeatureSource) using .NET.
>> Here's
>> 
>>> the approach that doesn't report any error, but when I refresh the
> map
>> there
>> 
>>> are no changes to the layer - new filter doesn't get applied.
>> 
>>>
>> 
>>> Dim layer As MgLayer = ...getting a MgLayer object...
>> 
>>> Dim document As New XmlDocument
>> 
>>> document.PreserveWhitespace = True
>> 
>>> Dim byteReader As MgByteReader =
>> 
>>> resources.Service.GetResourceContent(layer.LayerDefinition)
>> 
>>> document.LoadXml(byteReader.ToString)
>> 
>>>
>> 
>>> Allright, it's all in XmlDocument now and then I do some parsing to
>> change
>> 
>>> the Filter element. When I save the definition to XML file (just for
>> 
>>> testing) everything's OK, structure and data is preserved and Filter
>> element
>> 
>>> is set to some new value.
>> 
>>>
>> 
>>> ' Saving XmlDocument to memory stream
>> 
>>> Dim stream As MemoryStream = New System.IO.MemoryStream()
>> 
>>> document.Save(stream)
>> 
>>>
>> 
>>> ' Converting stream to byte array 
>> 
>>> Dim byteArray() As Byte = stream.ToArray
>> 
>>>
>> 
>>> ' Converting byte array to String (BOM included, otherwise
> SetResource
>> 
>>> raises an error while parsing XML)
>> 
>>> Dim outerXml As String =
>> System.Text.Encoding.UTF8.GetString(byteArray, 0,
>> 
>>> byteArray.Length - 1)
>> 
>>>
>> 
>>> ' Converting String to byte array with UTF-8 encoding 
>> 
>>> byteArray = System.Text.Encoding.UTF8.GetBytes(outerXml)
>> 
>>>
>> 
>>> ' Creating MgByteSource out of byte array, setting appropriate
>> MimeType
>> 
>>> Dim byteSource As MgByteSource = New MgByteSource(byteArray,
>> 
>>> byteArray.Length)
>> 
>>> byteSource.SetMimeType(MgMimeType.Xml)
>> 
>>>
>> 
>>> ' Getting MgResourceIdentifier corresponding to current SessionId and
>> 
>>> existing Layer name
>> 
>>> Dim resourceId As New
>> 
>>>
> MgResourceIdentifier(String.Format("Session:{0}//{1}.LayerDefinition",
>> 
>>> sessionId, layerName))
>> 
>>>
>> 
>>> ' Setting a resource (without Header) using MgResourceIdentifier and
>> byte
>> 
>>> source
>> 
>>> resources.Service.SetResource(resourceId, byteSource.GetReader,
>> Nothing)
>> 
>>>
>> 
>>> ' I don't know if this is necessary, but still...
>> 
>>> layer.ForceRefresh()
>> 
>>>
>> 
>>>
>> 
>>> Now, when I call parent.parent.Refresh() on the client side nothing
>> happens.
>> 
>>> What am I doing wrong here?
>> 
>>>
>> 
>>> Regards,
>> 
>>> Maksim Sestic
>> 
>>>
>> 
>>>
>> 
>>>
>> 
>>>
>> 
>>>  
>> 
>>>   
>> 
>> _______________________________________________
>> 
>> mapguide-users mailing list
>> 
>> mapguide-users at lists.osgeo.org
>> 
>> http://lists.osgeo.org/mailman/listinfo/mapguide-users
>> 
>>  
>> 
>>  
>> 
>> E-mails are automatically scanned for viruses using McAfee.
>> 
>> 
>> _______________________________________________
>> mapguide-users mailing list
>> mapguide-users at lists.osgeo.org
>> http://lists.osgeo.org/mailman/listinfo/mapguide-users
>> 
>> 
> 
> -- 
> View this message in context:
> http://www.nabble.com/Changing-existing-dynamic-layer%27s-Filter-on-the-
> fly-tf4811727s16610.html#a13770485
> Sent from the MapGuide Users mailing list archive at Nabble.com.
> 
> _______________________________________________
> mapguide-users mailing list
> mapguide-users at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/mapguide-users
> 
> 
> E-mails are automatically scanned for viruses using McAfee.
> _______________________________________________
> mapguide-users mailing list
> mapguide-users at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/mapguide-users
> 
> 

-- 
View this message in context: http://www.nabble.com/Changing-existing-dynamic-layer%27s-Filter-on-the-fly-tf4811727s16610.html#a13809458
Sent from the MapGuide Users mailing list archive at Nabble.com.



More information about the mapguide-users mailing list