#region Disclaimer / License // Copyright (C) 2013, Jackie Ng // http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using OSGeo.MapGuide.MaestroAPI; using OSGeo.MapGuide.MaestroAPI.Resource; using OSGeo.MapGuide.ObjectModels; using OSGeo.MapGuide.ObjectModels.ApplicationDefinition; using OSGeo.MapGuide.ObjectModels.LayerDefinition; using OSGeo.MapGuide.ObjectModels.MapDefinition; using OSGeo.MapGuide.ObjectModels.WatermarkDefinition; using OSGeo.MapGuide.ObjectModels.WebLayout; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Maestro.Editors.Preview { public class ResourcePreviewEngine { private string _rootUrl; private IEditorService _edSvc; public ResourcePreviewEngine(string rootUrl, IEditorService edSvc) { _rootUrl = rootUrl; _edSvc = edSvc; } static string GetLocale(string locale) { return string.IsNullOrEmpty(locale) ? "en" : locale; //NOXLATE } private string GenerateFeatureSourcePreviewUrl(IResource res, string locale) { string url = _rootUrl; if (!url.EndsWith("/")) //NOXLATE url += "/"; //NOXLATE var resId = res.ResourceID; var sessionId = _edSvc.SessionID; url += "schemareport/describeschema.php?viewer=basic&schemaName=&className=&resId=" + resId + "&sessionId=" + sessionId + "&locale=" + GetLocale(locale); //NOXLATE return url; } private string GenerateLayerPreviewUrl(IResource res, string locale) { string url = _rootUrl; if (!url.EndsWith("/")) //NOXLATE url += "/"; //NOXLATE var ldf = (ILayerDefinition)res; var sessionId = _edSvc.SessionID; var conn = res.CurrentConnection; string layerName = string.Empty; //Use feature source as name/label if new and unsaved if (_edSvc.IsNew) layerName = ResourceIdentifier.GetName(ldf.SubLayer.ResourceId); else layerName = ResourceIdentifier.GetName(_edSvc.ResourceID); var mdf = CreateLayerPreviewMapDefinition(ldf, sessionId, layerName, conn); //if (PropertyService.Get(ConfigProperties.PreviewViewerType, "AJAX").Equals("AJAX")) //NOXLATE if (PreviewSettings.UseAjaxViewer) { //Create temp web layout to house this map var wl = ObjectFactory.CreateWebLayout(_edSvc.GetEditedResource().CurrentConnection, new Version(1, 0, 0), mdf.ResourceID); //Add a custom zoom command (to assist previews of layers that aren't [0, infinity] scale) AttachPreviewCommands(wl); var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".WebLayout"; //NOXLATE conn.ResourceService.SaveResourceAs(wl, resId); url += "mapviewerajax/?WEBLAYOUT=" + resId + "&SESSION=" + sessionId + "&LOCALE=" + GetLocale(locale); //NOXLATE } else { throw new NotImplementedException(); ////Create temp flex layout //var appDef = ObjectFactory.CreatePreviewFlexLayout(conn); //var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".ApplicationDefinition"; //NOXLATE //appDef.AddMapGroup("previewmap", true, mdfId); //NOXLATE //conn.ResourceService.SaveResourceAs(appDef, resId); //url += "fusion/templates/mapguide/preview/index.html?Session=" + sessionId + "&ApplicationDefinition=" + resId; //NOXLATE } return url; } internal static IMapDefinition CreateLayerPreviewMapDefinition(ILayerDefinition ldf, string sessionId, string layerName, IServerConnection conn) { //Create temp map definition to house our current layer var mdfId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".MapDefinition"; //NOXLATE string csWkt; var extent = ldf.GetSpatialExtent(true, out csWkt); if (extent == null) throw new ApplicationException(Strings.FailedToCalculateFeatureSourceExtents); //TODO: Based on the visible scales in this layer, size this extents accordingly var mdf = ObjectFactory.CreateMapDefinition(conn, Strings.PreviewMap, csWkt, extent); var layer = mdf.AddLayer(null, layerName, ldf.ResourceID); conn.ResourceService.SaveResourceAs(mdf, mdfId); mdf.ResourceID = mdfId; return mdf; } private static void AttachPreviewCommands(IWebLayout wl) { var cmd = wl.CreateInvokeScriptCommand(); cmd.Name = "ZoomScale"; //NOXLATE cmd.Label = Strings.Label_ZoomToScale; cmd.Tooltip = Strings.Desc_ZoomToScale; cmd.Script = @" var map = parent.parent.GetMapFrame(); var center = map.GetCenter(); var scale = parseFloat(prompt('Enter the scale:')); map.ZoomToView(center.X, center.Y, scale, true); "; //NOXLATE cmd.TargetViewer = TargetViewerType.Ajax; cmd.ImageURL = "../stdicons/icon_zoom.gif"; //NOXLATE wl.CommandSet.AddCommand(cmd); var cmd2 = wl.CreateInvokeScriptCommand(); cmd2.Name = "GetMapKml"; //NOXLATE cmd2.Label = Strings.Label_GetMapKml; cmd2.Description = Strings.Desc_GetMapKml; cmd2.Tooltip = Strings.Desc_GetMapKml; cmd2.Script = @" var map = parent.parent.GetMapFrame(); var url = ""../mapagent/mapagent.fcgi?OPERATION=GETMAPKML&VERSION=1.0.0&FORMAT=KML&DISPLAYDPI=96&MAPDEFINITION=" + wl.Map.ResourceId + @"""; url += ""&SESSION="" + map.GetSessionId(); window.open(url);"; //NOXLATE cmd2.TargetViewer = TargetViewerType.Ajax; cmd2.ImageURL = "../stdicons/icon_invokescript.gif"; //NOXLATE wl.CommandSet.AddCommand(cmd2); var cmd3 = wl.CreateInvokeScriptCommand(); cmd3.Name = "GetExtents"; //NOXLATE cmd3.Label = Strings.Label_GetExtents; cmd3.Description = Strings.Desc_GetExtents; cmd3.Tooltip = Strings.Desc_GetExtents; cmd3.Script = @" var map = parent.parent.GetMapFrame(); alert('Map Extents\n\nLower Left: ' + map.extX1 + ', ' + map.extY2 + '\nUpper Right: ' + map.extX2 + ', ' + map.extY1); "; //NOXLATE cmd3.TargetViewer = TargetViewerType.Ajax; cmd3.ImageURL = "../stdicons/icon_invokescript.gif"; //NOXLATE wl.CommandSet.AddCommand(cmd3); var zoomScale = wl.CreateCommandItem(cmd.Name); var menu = wl.CreateFlyout(Strings.Label_Tools, Strings.Label_Tools, Strings.Label_ExtraTools, string.Empty, string.Empty, wl.CreateCommandItem("ZoomScale"), //NOXLATE wl.CreateCommandItem("GetMapKml"), //NOXLATE wl.CreateCommandItem("GetExtents") //NOXLATE ); wl.ToolBar.AddItem(menu); } private string GenerateWatermarkPreviewUrl(IWatermarkDefinition wmd, string locale) { //We demand a 2.3.0 Map Definition or higher if (wmd.CurrentConnection.SiteVersion < new Version(2, 3)) throw new InvalidOperationException(Strings.SiteVersionDoesntSupportWatermarks); IMapDefinition2 map = CreateWatermarkPreviewMapDefinition(wmd); return GenerateMapPreviewUrl(map, locale); } internal static IMapDefinition2 CreateWatermarkPreviewMapDefinition(IWatermarkDefinition wmd) { IMapDefinition2 map = (IMapDefinition2)ObjectFactory.CreateMapDefinition(wmd.CurrentConnection, wmd.SupportedMapDefinitionVersion, "Watermark Definition Preview"); //NOXLATE map.CoordinateSystem = @"LOCAL_CS[""*XY-M*"", LOCAL_DATUM[""*X-Y*"", 10000], UNIT[""Meter"", 1], AXIS[""X"", EAST], AXIS[""Y"", NORTH]]"; //NOXLATE map.Extents = ObjectFactory.CreateEnvelope(-1000000, -1000000, 1000000, 1000000); map.AddWatermark(wmd); return map; } private string GenerateMapPreviewUrl(IResource res, string locale) { string url = _rootUrl; if (!url.EndsWith("/")) //NOXLATE url += "/"; //NOXLATE var sessionId = _edSvc.SessionID; var mdfId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".MapDefinition"; //NOXLATE var mdf = (IMapDefinition)res; var conn = mdf.CurrentConnection; conn.ResourceService.SaveResourceAs(mdf, mdfId); //if (PropertyService.Get(ConfigProperties.PreviewViewerType, "AJAX").Equals("AJAX")) //NOXLATE if (PreviewSettings.UseAjaxViewer) { //Create temp web layout to house this map var wl = ObjectFactory.CreateWebLayout(_edSvc.GetEditedResource().CurrentConnection, new Version(1, 0, 0), mdfId); //Add a custom zoom command (to assist previews of layers that aren't [0, infinity] scale) AttachPreviewCommands(wl); var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".WebLayout"; //NOXLATE conn.ResourceService.SaveResourceAs(wl, resId); url += "mapviewerajax/?WEBLAYOUT=" + resId + "&SESSION=" + sessionId + "&LOCALE=" + GetLocale(locale); //NOXLATE } else { throw new NotImplementedException(); ////Create temp flex layout //var appDef = ObjectFactory.CreateFlexibleLayout(conn); //var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".ApplicationDefinition"; //NOXLATE //appDef.AddMapGroup("previewmap", true, mdfId); //NOXLATE //conn.ResourceService.SaveResourceAs(appDef, resId); //url += "fusion/templates/mapguide/preview/index.html?Session=" + sessionId + "&ApplicationDefinition=" + resId; //NOXLATE } return url; } private string GenerateWebLayoutPreviewUrl(IResource res, string locale) { string url = _rootUrl; if (!url.EndsWith("/")) //NOXLATE url += "/"; //NOXLATE var sessionId = _edSvc.SessionID; var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".WebLayout"; //NOXLATE var conn = res.CurrentConnection; conn.ResourceService.SaveResourceAs(res, resId); url += "mapviewerajax/?WEBLAYOUT=" + resId + "&SESSION=" + sessionId + "&LOCALE=" + GetLocale(locale); //NOXLATE return url; } private string GenerateFlexLayoutPreviewUrl(IResource res, string locale) { string url = _rootUrl; if (!url.EndsWith("/")) //NOXLATE url += "/"; //NOXLATE //Create temp flex layout var sessionId = _edSvc.SessionID; var appDef = (IApplicationDefinition)res; var conn = appDef.CurrentConnection; var resId = "Session:" + sessionId + "//" + Guid.NewGuid() + ".ApplicationDefinition"; //NOXLATE conn.ResourceService.SaveResourceAs(appDef, resId); url += appDef.TemplateUrl + "?Session=" + sessionId + "&ApplicationDefinition=" + resId + "&locale=" + GetLocale(locale); //NOXLATE return url; } public string GeneratePreviewUrl(IResource res, string locale) { switch (res.ResourceType) { case ResourceTypes.FeatureSource: return GenerateFeatureSourcePreviewUrl(res, locale); case ResourceTypes.ApplicationDefinition: return GenerateFlexLayoutPreviewUrl(res, locale); case ResourceTypes.LayerDefinition: return GenerateLayerPreviewUrl(res, locale); case ResourceTypes.MapDefinition: return GenerateMapPreviewUrl(res, locale); case ResourceTypes.WebLayout: return GenerateWebLayoutPreviewUrl(res, locale); case ResourceTypes.WatermarkDefinition: return GenerateWatermarkPreviewUrl((IWatermarkDefinition)res, locale); default: throw new InvalidOperationException(Strings.UnpreviewableResourceType); } } private static ResourceTypes[] PREVIEWABLE_RESOURCE_TYPES = new ResourceTypes[] { ResourceTypes.FeatureSource, ResourceTypes.ApplicationDefinition, ResourceTypes.LayerDefinition, ResourceTypes.MapDefinition, ResourceTypes.WebLayout, ResourceTypes.WatermarkDefinition }; internal static bool IsPreviewableType(OSGeo.MapGuide.MaestroAPI.ResourceTypes rt) { return Array.IndexOf(PREVIEWABLE_RESOURCE_TYPES, rt) >= 0; } } }