[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