Discussion:
[mapguide-users] change layer definition runtime
Mark Chan
2016-09-07 04:08:33 UTC
Permalink
Thanks Jackie, 
I think i got the gist, but will this also work with fusion? I am currently using the fusion templates. I was wondering if i could also do this with .net to rebuild the mapdefinition or layer definition.
Thanks for the response, im a bit stuck on this.

Sent from Yahoo Mail on Android

On Wed, Sep 7, 2016 at 12:03 AM, Jackie Ng<***@gmail.com> wrote: You have to manipulate MgMap/MgLayer objects, so you have to use a
server-side script. It doesn't have to be .net. It could be in Java or PHP.
But it has to be one of the 3 languages which can work with the MapGuide Web
API.

Your script needs to take in mapname/sessionid and do the following:

- Opens the MgMap from the mapname
- Finds the matching MgLayer in the map's layer collection by its layer
name
- Make a new MgLayer that points to your new layer definition
- Replace the matching MgLayer with your new MgLayer
  - Insert the new MgLayer to the layer collection at the matching index of
the old MgLayer
  - Remove the old MgLayer from the layer collection
- Save the map state and trigger a map refresh back on the client-side

- Jackie



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284422.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2016-09-08 17:11:10 UTC
Permalink
Hi,

I have created layer definition from each maps on Maestro and just 1
MapDefinition, What i am trying to do is the just updated the
layerdefinition of the mapdefinition to the specific selected map. I wanted
to do it runtime. I cam currtently using fusion, is this possible to do on
JS or just .net? And how? i am quite stuck now.

Also another option for me to do is the create mapdefinition on runtime, but
still no success on doing this.

Any help will do.

Thanks in advance



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284782.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
Liglio
2016-09-08 19:18:25 UTC
Permalink
Hi,

I made an example of a class to manipulate the atribute Filter of a layer,
you can use as an example to manipulate any atribute of a layer. It´s made
in c#.

public class UtilMap
{
private string strSessionMap;
private string strMapDefinition;
private MgSiteConnection siteConnection;
private MgUserInformation userInfo;
private MgFeatureService featureService;
private MgResourceService resourceService;
private MgMap map;
private string mapName;
private string strTempLayerSufix;

/// <summary>
/// Constructor of class to manipulate the RunTime Mapguide Map
/// </summary>
/// Map Session ID
/// Map Library Definition
public UtilMap(string pstrSessionMap, string pstrMapDefinition)
{
try
{
strSessionMap = pstrSessionMap;
strMapDefinition = pstrMapDefinition;
strTempLayerSufix = "-" + strSessionMap;

siteConnection = new MgSiteConnection();
userInfo = new MgUserInformation(strSessionMap);

siteConnection.Open(userInfo);
featureService =
(MgFeatureService)siteConnection.CreateService(MgServiceType.FeatureService);
resourceService =
(MgResourceService)siteConnection.CreateService(MgServiceType.ResourceService);

mapName = strMapDefinition;

//if mapName is empty, I just want to work with session
repository, no map operations
if (mapName != "")
{
map = new MgMap(siteConnection);
map.Open(resourceService, mapName);
}

}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

/// <summary>
/// Set a filter to a Layer in session repository
/// </summary>
/// Layer Name
/// Filter condition
/// <returns>Operation success</returns>
public bool SetLayerFilter(string strLayerName, string strFilter)
{
try
{
//
// Set/Add a filter to a temporary layer created based on an
original one.
//
MgResourceIdentifier resId, resIdTemp;
MgLayerBase layer, layerTemp;
string tempResource;
string strLayerNameForSession;
string strXml;

//Verify if Layer Name is the temporary layer. If It is,
correct to original Layer Name.
if (strLayerName.IndexOf(strTempLayerSufix) > 0)
{
strLayerName = strLayerName.Replace(strTempLayerSufix,
"");
}

//Use random name to avoid overwrites
strLayerNameForSession = strLayerName +
this.strTempLayerSufix;

//Test if the original or temporary layers existis
if (GetLayerByName(map, strLayerName) == null &&
GetLayerByName(map, strLayerNameForSession) == null)
return false;

//Test if the filter is not null
if (strFilter == null)
strFilter = "";

//Get the temporary layer
layer = GetLayerByName(map, strLayerNameForSession);

//Get the original layer, if temporary later not exist
if (layer == null)
layer = GetLayerByName(map, strLayerName);

//If the temp resource was not created, read the original
xml
tempResource = "Session:" + strSessionMap + "//" +
strLayerNameForSession + "." + MgResourceType.LayerDefinition;
resIdTemp = new MgResourceIdentifier(tempResource);

//Read the resource original layer
resId = layer.GetLayerDefinition();
strXml =
(resourceService.GetResourceContent(resId)).ToString();

//Manipulate xml, set the Tags Filter

strXml = Util.SetTagTextContent(strXml,
"/LayerDefinition/VectorLayerDefinition/Filter", strFilter, true,
"/LayerDefinition/VectorLayerDefinition/FeatureNameType");

//Write the resource
System.Text.ASCIIEncoding encoding = new
System.Text.ASCIIEncoding();
MgByteSource ByteSource = new
MgByteSource(encoding.GetBytes(strXml), strXml.Length);
resourceService.SetResource(resIdTemp,
ByteSource.GetReader(), null);

//Get the temp layer
layerTemp = GetLayerByName(map, strLayerNameForSession);
if (layerTemp == null)
{
layerTemp = new MgLayer(resIdTemp, resourceService);
layerTemp.SetGroup(layer.GetGroup());
layerTemp.SetName(strLayerNameForSession);
layerTemp.SetLegendLabel(strLayerName);
layerTemp.SetSelectable(true);
layerTemp.SetVisible(true);

MgLayerCollection layers = map.GetLayers();
//Insert at the same position of the original layer
layers.Insert(layers.IndexOf(strLayerName), layerTemp);
}

layerTemp.ForceRefresh();
map.Save(resourceService);

return true;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}

}

}

********************************************************

objUtilMap = new UtilMap(SessionMapLightining, MapNameLightining);
string strFiltroLayer = "time_lightining >= ToDate('2016-09-08 10:00:00')
AND time_lightining < ToDate('2016-09-08 10:05:00')";
objUtilMap.SetLayerFilter("Lightining", strFiltroLayer);



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284814.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2016-09-08 19:42:16 UTC
Permalink
Thanks Liglio

I will definitely give this shot. Ill let you know if it works. Thanks
thanks a bunch.



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284819.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2016-09-08 19:50:21 UTC
Permalink
Hi Liglio,

Sorry to have disturbed you but, what namespace did you use for
Util.SetTagTextContent and where is the method GetLayerByName?

Thanks



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284823.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
Liglio
2016-09-08 20:03:43 UTC
Permalink
Put in UtilMap class

/// <summary>
/// Get layer object by his name in the Runtime Map
/// </summary>
/// Mapguide MapObject
/// Layer Name
/// <returns></returns>
private MgLayerBase GetLayerByName(MgMap map, string layerName)
{
try
{
MgLayerBase layer = null;
for (int i = 0; i < map.GetLayers().GetCount(); i++)
{
MgLayerBase nextLayer = map.GetLayers().GetItem(i);
if (nextLayer.GetName().ToUpper() ==
layerName.ToUpper())
{
layer = nextLayer;
break;
}
}
return layer;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

*********************************************************
using System;
using System.IO;
using System.Xml;
using System.Data;

static public class Util
{
static public string SetTagTextContent(string strXml, string strNode,
string strContent, bool bolCreateIfInexist = true, string strNodeCreateAfter
= null)
{
XmlDocument xmlDoc = new XmlDocument();
XmlNode xmlNode = null;
XmlNode xmlNewNode;
XmlNode xmlAfterNode;
string strRet;
string strTag;

xmlDoc.PreserveWhitespace = true;
xmlDoc.LoadXml(strXml);
try
{
xmlNode = xmlDoc.SelectSingleNode(strNode);
if (xmlNode == null && bolCreateIfInexist)
{
strTag = strNode.Substring(strNode.LastIndexOf("/") +
1);
xmlNewNode = xmlDoc.CreateNode(XmlNodeType.Element,
strTag, null);
xmlNewNode.InnerText += " " + strContent;
xmlNode = xmlDoc.SelectSingleNode(strNode.Replace("/" +
strTag, ""));
xmlAfterNode =
xmlDoc.SelectSingleNode(strNodeCreateAfter);
xmlNode.InsertAfter(xmlNewNode, xmlAfterNode);
}
else
{
xmlNode.InnerText = strContent;
}
}
catch (System.Xml.XPath.XPathException)
{
}

strRet = xmlDoc.InnerXml;

return strRet;
}

}



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284826.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2016-09-08 20:28:09 UTC
Permalink
Hi Liglio,

Thanks for the quick update, i am getting this error when it reaches
map.open

if i keyed in: resourceService and resourceidentifier
"Resource data was not found: RuntimeData"

if i keyed in: resourceService and mapName or mapdefinition

Invalid resource path: Library://Langan Floor Plans

My scenario is i have fusion, the i am calling the function
mapwidget.getSessionId(), as soon i get the session id, i have a ajax to
call server side method and call

UtilMap up = new UtilMap(sessionid, "Library://Langan Floor Plans/Floor Plan
Map.MapDefinition")

but if i call map.create(resourceIdentifier,"anyName") i works. i can even
access all layers, but is there any difference between the open and create?




--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284835.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2016-09-08 21:44:48 UTC
Permalink
Solved the error. I should be getting the mapname from the mapdwiget.

Now there is no error. But it looks like i need to refresh fusion mapwidget
for the layers to effect.

Only thing now i think is to refresh the mapwidget for the layers to take
effect. But it seems that layerTemp.ForceRefresh(); wont refresh the
widget.



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284847.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
Liglio
2016-09-08 22:54:28 UTC
Permalink
You have to refresh the map using javascript.

Put in UtilMap class:
/// <summary>
/// Refresh the Map in the Client using JavaScrit
/// </summary>
/// Page Object calling this method
public void RefreshMapClient(Page objPage)
{
try
{
string strScript = "";

strScript += "" + "\r\n";

// Detect if the page has ScriptManager
if (System.Web.UI.ScriptManager.GetCurrent(objPage) == null)

objPage.ClientScript.RegisterStartupScript(objPage.GetType(),
"RefreshMapClient", strScript, false);
else

System.Web.UI.ScriptManager.RegisterStartupScript(objPage,
objPage.GetType(), "RefreshMapClient", strScript, false);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}


Put in the your page server-side, after setting the filter layer:
objUtilMap.RefreshMapClient(this);





--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284858.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2016-09-09 16:25:07 UTC
Permalink
Thank Liglio,

It worked well! :)

last question, is there a way to also change featuresourceid ,
featureclassname? the properties are "read only"

Thanks



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5284992.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
Liglio
2016-09-10 14:15:08 UTC
Permalink
The layer definition is a xml where you can modify all atributes, including
featuresourceid , featureclassname, etc. Debug the code and examine the
string xml layer read in the set filter method.



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5285095.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2016-09-21 19:57:39 UTC
Permalink
Thanks, found it and made it work.

Also, sorry for asking this here cause i know ive already posted this on a
new thread.

Do you happen to know how to refresh the jxpanel? because it seems that when
i replaces all the layers via the .net api's, the jxpanels doesnt work
anymore with the changed map, the legends and the selections doesnt work
anymore.

Thhanks



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5287171.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2016-09-30 17:13:03 UTC
Permalink
After refreshing, the select button at the toolbar doesnt work anymore, each
time i select an objct on the map. It does nothing, any idea? need help been
stuck here for almost a week..





--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5288779.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
Liglio
2016-10-05 14:26:02 UTC
Permalink
I don´t know what is happening in your application. What version of mapguide
are you using? You are using Fusion framework ?



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5289434.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2017-04-12 17:30:53 UTC
Permalink
Hi,

Back again, was able to make it work before with MapGuide 2.6.1 32bit now
upgraded to 3.1.0 64bit.. Same code with changing layer at runtime.. funny
thing now, nothing happens, but if select something on the map, it throws an
error inside fusion-compressed.js, 'layerName' does not exists.

From the c# code layers.remove(layer) it did work it seems that the layer
was really removed on the map.. but the mapwidget itself didnt refresh to
the new layer, it still looks the same. did call the command.
mapWidget.redraw, mapWidget.reloadMap(). but nothing happens.

Tried almost everything but its not working at all..

Is there something that i missed on the code?



--
View this message in context: http://osgeo-org.1560.x6.nabble.com/change-layer-definition-runtime-tp5284382p5317071.html
Sent from the MapGuide Users mailing list archive at Nabble.com.
makoychan
2017-12-15 19:43:03 UTC
Permalink
Anyone tried this with MGOS 3.1 and Fusion 3? apparantly after i updated
everything to this version, none of the code works.



--
Sent from: http://osgeo-org.1560.x6.nabble.com/MapGuide-Users-f4182607.html
Liglio
2017-12-27 14:20:53 UTC
Permalink
Maybe this will help.

http://osgeo-org.1560.x6.nabble.com/Mapguide-3-1-Add-layer-on-runtime-c-td5346722.html




--
Sent from: http://osgeo-org.1560.x6.nabble.com/MapGuide-Users-f4182607.html
Continue reading on narkive:
Loading...