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

Maksim Sestic max at geoinova.com
Thu Nov 15 10:14:57 EST 2007


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.



More information about the mapguide-users mailing list