public CartoReaderContext(Env env, ICartoTranslator translator) { NodeValues = new Dictionary <int, string>(); Env = env; Translator = translator; _lockObj = new object(); }
public CartoReaderContext(Env env, ICartoTranslator translator) { NodeValues = new Dictionary<int, string>(); Env = env; Translator = translator; _lockObj = new object(); }
public static string ToFilter(CartoFilterSet filterSet, ICartoTranslator cartoTranslator) { string result = string.Empty; if (filterSet.Count > 0) { int i = 0; foreach (CartoFilterElement filter in filterSet.Filters) { if (i != 0) result += " and "; result += cartoTranslator.ToFilter(filter.Key.ToString(), ToExpressionOperator(filter.Op), ToExpressionValue(filter.Value)); i++; } } return result; }
/// <summary> /// Create styled layer /// </summary> /// <param name="cartoLayer"></param> /// <param name="cartoTranslator"></param> /// <returns></returns> private static StyledLayer CreateStyledLayer(CartoLayer cartoLayer, Map map, ICartoTranslator cartoTranslator) { ParameterCollection parameters = cartoTranslator.ToDatasourceParameters(cartoLayer); StyledLayer layer = new StyledLayer(cartoLayer.Name, parameters); layer.FeaturesCaching.Enabled = true; if (cartoLayer.Properties != null) { if (cartoLayer.Properties.ContainsKey("minzoom")) { layer.MinimumScale = ConvertUtility.ToScaleDenominator(Convert.ToInt32(cartoLayer.Properties["minzoom"])); } if (cartoLayer.Properties.ContainsKey("maxzoom")) { layer.MaximumScale = ConvertUtility.ToScaleDenominator(Convert.ToInt32(cartoLayer.Properties["maxzoom"])); } if (cartoLayer.Properties.ContainsKey("queryable")) { layer.Queryable = Convert.ToBoolean(cartoLayer.Properties["queryable"]); } if (cartoLayer.Properties.ContainsKey("cache-features")) // Extension { layer.FeaturesCaching.Enabled = Convert.ToBoolean(cartoLayer.Properties["cache-features"]); } } layer.Enabled = cartoLayer.Status != "off"; string providerName = parameters.GetValue("Type"); if (string.IsNullOrEmpty(providerName)) { LogFactory.WriteLogEntry(Logger.Default, new IOException(string.Format("Unable to detect the type of a data source provider for the layer '{0}'.", cartoLayer.Name))); } if (!string.IsNullOrEmpty(cartoLayer.Srs)) { layer.CRS = cartoTranslator.ToCoordinateSystem(string.IsNullOrEmpty(cartoLayer.Srs) ? cartoLayer.SrsName : cartoLayer.Srs, !string.IsNullOrEmpty(cartoLayer.SrsName)); } return(layer); }
public static string ToFilter(CartoFilterSet filterSet, ICartoTranslator cartoTranslator) { string result = string.Empty; if (filterSet.Count > 0) { int i = 0; foreach (CartoFilterElement filter in filterSet.Filters) { if (i != 0) { result += " and "; } result += cartoTranslator.ToFilter(filter.Key.ToString(), ToExpressionOperator(filter.Op), ToExpressionValue(filter.Value)); i++; } } return(result); }
public static Map ReadFromFile(string fileContent, string fileName) { string path = Path.GetDirectoryName(fileName); CartoProject cartoProject = null; switch (Path.GetExtension(fileName).ToLower()) { case ".mml": cartoProject = JsonConvert.DeserializeObject <CartoProject>(fileContent); if (cartoProject.Interactivity != null) { try { Dictionary <string, object> dict = JsonConvert.DeserializeObject <Dictionary <string, object> >(cartoProject.Interactivity.ToString()); cartoProject.Interactivity = dict; } catch { } try { bool enabled = JsonConvert.DeserializeObject <bool>(cartoProject.Interactivity.ToString()); cartoProject.Interactivity = enabled; } catch { } } break; case ".yaml": using (StringReader input = new StringReader(fileContent)) { Deserializer deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention(), ignoreUnmatched: true); var parser = new MergingParser(new YamlDotNet.Core.Parser(input)); cartoProject = deserializer.Deserialize <CartoProject>(new EventReader(parser)); } break; default: throw new Exception("Unknown extension of the CartoCSS project."); } Map map = null; if (cartoProject.Stylesheet != null && cartoProject.Stylesheet.Length > 0 && cartoProject.Layers.Length > 0) { ICartoTranslator cartoTranslator = CartoGeneratorConverterFactory.CreateTranslator(cartoProject.Generator); CartoParser parser = new CartoParser(); parser.NodeProvider = new CartoNodeProvider(); Env env = new Env(); List <Ruleset> ruleSets = new List <Ruleset>(); List <CartoDefinition> definitions = new List <CartoDefinition>(); foreach (string styleName in cartoProject.Stylesheet) { string styleFileName = Path.Combine(path, styleName); try { Ruleset ruleSet = parser.Parse(File.ReadAllText(styleFileName), styleFileName, env); ruleSets.Add(ruleSet); // Get an array of Ruleset objects, flattened // and sorted according to specificitySort var defs = new List <CartoDefinition>(); defs = ruleSet.Flatten(defs, null, env); defs.Sort(new SpecificitySorter()); definitions.AddRange(defs); env.Frames.Push(ruleSet); } catch (Exception ex) { Exception ex2 = new IOException(string.Format("An error occured during parsing of the style '{0}'.", styleFileName) + ex.Message); LogFactory.WriteLogEntry(Logger.Default, ex2); throw ex2; } } string interactivityLayer = null; if (cartoProject.GetInteractivity() != null && cartoProject.GetInteractivity().ContainsKey("layer")) { interactivityLayer = cartoProject.GetInteractivity()["layer"].ToString(); } map = CreateMap(cartoProject, definitions, env, cartoTranslator); foreach (CartoLayer cartoLayer in cartoProject.Layers) { CartoDatasource datasource = cartoLayer.Datasource; StyledLayer styledLayer = CreateStyledLayer(cartoLayer, map, cartoTranslator); try { string[] classes = (cartoLayer.Class.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); Dictionary <string, bool> classIndex = new Dictionary <string, bool>(classes.Length); for (int i = 0; i < classes.Length; i++) { classIndex[classes[i]] = true; } var matching = definitions.FindAll(delegate(CartoDefinition def) { return(def.AppliesTo(cartoLayer.Name, classIndex)); }); if (matching.Count > 0) { List <CartoStyle> rules = InheritDefinitions(matching, env); if (rules.Count > 0) { SortStyles(rules, env); for (int k = 0; k < rules.Count; k++) { CartoStyle cartoStyle = rules[k]; cartoStyle.Fold(env); string styleName = cartoLayer.Name + (cartoStyle.Attachment != "__default__" ? "-" + cartoStyle.Attachment : ""); FeatureTypeStyle style = CreateStyle(styleName, cartoStyle, env, cartoTranslator); if (style.Rules.Count > 0) { styledLayer.Styles.Add(style); } } cartoTranslator.ProcessStyles(styledLayer.Styles); } if (!string.IsNullOrEmpty(interactivityLayer) && interactivityLayer.Equals(styledLayer.Name)) { styledLayer.Enabled = false; } map.AddLayer(styledLayer); } } catch (Exception ex) { Exception ex2 = new IOException(string.Format("Unable to create data source provider with type '{0}' for the layer '{1}'.", datasource.Type, cartoLayer.Name) + ex.Message); LogFactory.WriteLogEntry(Logger.Default, ex2); } } } return(map); }
/// <summary> /// Detects font sets by analyzing all "text-face-name" properties. /// </summary> /// <param name="definitions"></param> /// <param name="env"></param> public static void SetFontSets(Map map, List <CartoDefinition> definitions, Env env, ICartoTranslator cartoTranslator) { List <FontSet> fontSets = new List <FontSet>(); Dictionary <string, FontSet> dictFontSets = new Dictionary <string, FontSet>(); using (FontFamilyCollection fontCollection = FontUtility.GetFontFamilyCollection()) { List <FontFamilyTypeface> typeFaces = new List <FontFamilyTypeface>(); List <string> notFoundFontNames = new List <string>(); int fontSetCounter = 0; foreach (CartoDefinition def in definitions) { foreach (CartoRule rule in def.Rules) { if (rule.Name == "text-face-name" || rule.Name == "shield-face-name") { try { Value value = rule.Value as Value; string strFontNames = value.Evaluate(env).ToString().Replace("\"", ""); FontSet fontSet = null; if (_dictFontSets.TryGetValue(strFontNames, out fontSet)) { if (!fontSets.Contains(fontSet)) { fontSets.Add((FontSet)fontSet.Clone()); dictFontSets.Add(strFontNames, fontSet); } continue; } string[] fontNames = strFontNames.Split(','); for (int i = 0; i < fontNames.Length; i++) { fontNames[i] = fontNames[i].Trim('\'').Trim(); } typeFaces.Clear(); foreach (string fontName in fontNames) { string fName = fontName.Replace(" ", ""); FontFamilyTypeface typeFace = null; foreach (MapSurfer.Drawing.FontFamily fontFamily in fontCollection.FontFamilies) { if (typeFace != null) { break; } foreach (FontFamilyTypeface fft in fontFamily.GetTypefaces()) { foreach (string faceName in fft.FaceNames) { string fullName = (fontFamily.Name + faceName).Replace(" ", ""); if (string.Equals(fName, fullName, StringComparison.OrdinalIgnoreCase)) { typeFace = fft; break; } } } } // We were not able to find appropriate type face if (typeFace == null) { if (!notFoundFontNames.Contains(fontName)) { notFoundFontNames.Add(fontName); LogFactory.WriteLogEntry(Logger.Default, string.Format("Unable to find font face(s) for '{0}'", fontName), LogEntryType.Warning); } } else { typeFaces.Add(typeFace); } } string fontSetName = "fontset-" + fontSetCounter.ToString(); if (typeFaces.Count > 0) { FontSet fs = new FontSet(fontSetName, typeFaces[0].Style, typeFaces[0].Weight); foreach (FontFamilyTypeface fft in typeFaces) { fs.FontNames.Add(fft.FontFamily.Name); } fontSets.Add((FontSet)fs.Clone()); _dictFontSets.TryAdd(strFontNames, fs); dictFontSets.Add(strFontNames, fs); fontSetCounter++; } } catch { } } } } } if (fontSets.Count > 0) { map.FontSets.AddRange(fontSets); } cartoTranslator.FontSets = dictFontSets; }
private static Dictionary <string, Dictionary <string, CartoRule> > CollectSymbolizers(CartoDefinition def, ZoomStruct zooms, int i, Env env, ICartoTranslator cartoTranslator) { Dictionary <string, Dictionary <string, CartoRule> > symbolizers = new Dictionary <string, Dictionary <string, CartoRule> >(); NodeList <CartoRule> rules = def.Rules; for (int j = i; j < rules.Count; j++) { CartoRule child = rules[j]; string symName = cartoTranslator.GetSymbolizerName(child.Name); string key = child.Instance + "/" + symName; if ((zooms.Current & child.Zoom) != 0 && (!(symbolizers.ContainsKey(key)) || (symbolizers[key] != null && !(symbolizers[key].ContainsKey(child.Name))))) { zooms.Current &= child.Zoom; if (!(symbolizers.ContainsKey(key))) { symbolizers[key] = new Dictionary <string, CartoRule>(); } symbolizers[key][child.Name] = child; } } if (symbolizers.Count > 0) { zooms.Rule &= (zooms.Available &= ~zooms.Current); return(symbolizers); } return(null); }
private static void CreateSymbolizers(Rule rule, Dictionary <string, Dictionary <string, CartoRule> > symbolizers, Env env, ICartoTranslator cartoTranslator) { // Sort symbolizers by the index of their first property definition List <KeyValuePair <string, int> > symOrder = new List <KeyValuePair <string, int> >(); List <int> indexes = new List <int>(); foreach (string key in symbolizers.Keys) { int minIdx = int.MaxValue; var props = symbolizers[key]; foreach (var prop in props) { int index = props[prop.Key].Index; if (index < minIdx) { minIdx = index; } } symOrder.Add(new KeyValuePair <string, int>(key, minIdx)); } // Get a simple list of the symbolizers, in order symOrder.Sort(delegate(KeyValuePair <string, int> a, KeyValuePair <string, int> b) { return(a.Value.CompareTo(b.Value)); }); foreach (KeyValuePair <string, int> kv in symOrder) { var attributes = symbolizers[kv.Key]; var symbolizer = kv.Key.Split('/')[1]; // Skip the magical * symbolizer which is used for universal properties // which are bubbled up to Style elements intead of Symbolizer elements. if (symbolizer == "*") { continue; } // Check if we have all required properties string[] properties = attributes.Keys.ToArray(); string[] values = new string[properties.Length]; string missingProperty = null; bool succ = cartoTranslator.HasRequiredProperties(symbolizer, properties, ref missingProperty); if (!succ) { NodeLocation loc = attributes[missingProperty].Location; throw new Exception(string.Format("A required property '{0}' is missing. Location: Index = {1} ; Source = {2}", missingProperty, loc.Index, loc.Source)); } int i = 0; foreach (string propName in attributes.Keys) { CartoRule cartoRule = attributes[propName]; values[i] = cartoRule.Value.GetValueAsString(env); i++; } Symbolizer sym = cartoTranslator.ToSymbolizer(symbolizer, properties, values); if (sym != null && sym.Enabled) { rule.Symbolizers.Add(sym); } } }
/// <summary> /// Creates rules /// </summary> /// <param name="style"></param> /// <param name="def"></param> /// <param name="env"></param> /// <param name="existingFilters"></param> /// <param name="cartoTranslator"></param> private static void CreateRules(FeatureTypeStyle style, CartoDefinition def, Env env, Dictionary <string, int> existingFilters, ICartoTranslator cartoTranslator) { string filter = def.Filters.ToString(); if (!(existingFilters.ContainsKey(filter))) { existingFilters[filter] = 0x7FFFFF; } int available = 0x7FFFFF; ZoomStruct zooms = new ZoomStruct(); zooms.Available = available; NodeList <CartoRule> rules = def.Rules; for (int i = 0; i < rules.Count; i++) { CartoRule cartoRule = rules[i]; zooms.Rule = cartoRule.Zoom; if ((existingFilters[filter] & zooms.Rule) == 0) { continue; } while (((zooms.Current = zooms.Rule) & available) != 0) { Dictionary <string, Dictionary <string, CartoRule> > symbolizers = CollectSymbolizers(def, zooms, i, env, cartoTranslator); if (symbolizers != null && symbolizers.Count > 0) { if ((existingFilters[filter] & zooms.Current) == 0) { continue; } int zoom = existingFilters[filter] & zooms.Current; int startZoom = -1, endZoom = 0; for (int zi = 0; zi <= 22; zi++) { if ((zoom & (1 << zi)) != 0) { if (startZoom == -1) { startZoom = zi; } endZoom = zi; } } Rule rule = new Rule(); rule.Filter = ConvertUtility.ToFilter(def.Filters, cartoTranslator); rule.Name = cartoRule.Instance; if (startZoom > 0) { rule.MaxScale = ConvertUtility.ToScaleDenominator(startZoom); } if (endZoom > 0) { rule.MinScale = ConvertUtility.ToScaleDenominator(endZoom + 1); } CreateSymbolizers(rule, symbolizers, env, cartoTranslator); existingFilters[filter] &= ~zooms.Current; // Check whether the rule has at least one visible symbolizer if (rule.Symbolizers.Count > 0 && rule.Symbolizers.Any(s => s.Enabled == true)) { style.Rules.Add(rule); } } } } //style.Rules.Sort(new RuleComparer()); }
/// <summary> /// Creates <see cref="FeatureTypeStyle"/> object /// </summary> /// <param name="styleName"></param> /// <param name="cartoStyle"></param> /// <param name="env"></param> /// <param name="cartoTranslator"></param> /// <returns></returns> private static FeatureTypeStyle CreateStyle(string styleName, CartoStyle cartoStyle, Env env, ICartoTranslator cartoTranslator) { FeatureTypeStyle style = new FeatureTypeStyle(styleName); style.ProcessFeatureOnce = true; List <CartoDefinition> definitions = cartoStyle.Definitions; Dictionary <string, int> existingFilters = null; List <string> imageFilters = new List <string>(); List <string> imageFiltersBuffer = new List <string>(); int k = 0; for (int i = 0; i < definitions.Count; i++) { CartoDefinition def = definitions[i]; NodeList <CartoRule> rules = def.Rules; for (int j = 0; j < rules.Count; j++) { CartoRule cartoRule = rules[j]; string ruleName = cartoRule.Name; if (ruleName == "image-filters") { string filter = cartoRule.Value.ToString(); if (!imageFilters.Contains(filter)) { style.ImageFiltersOptions.Filters.Add(cartoTranslator.ToImageFilter(filter)); style.ImageFiltersOptions.Enabled = true; imageFilters.Add(filter); } k++; } else if (ruleName == "image-filters-inflate") { bool inflate = Convert.ToBoolean(cartoRule.Value.ToString()); if (inflate) { style.ImageFiltersOptions.Enabled = true; } k++; } else if (ruleName == "direct-image-filters") { string filter = cartoRule.Value.ToString(); if (!imageFiltersBuffer.Contains(filter)) { style.ImageFiltersOptions.BufferFilters.Add(cartoTranslator.ToImageFilter(filter)); style.ImageFiltersOptions.Enabled = true; imageFiltersBuffer.Add(filter); } k++; } else if (ruleName == "comp-op") { style.BlendingOptions.CompositingMode = cartoTranslator.ToCompositingMode(cartoRule.Value.Evaluate(env).ToString()); k++; } else if (ruleName == "opacity") { style.BlendingOptions.Opacity = (float)(cartoRule.Value.Evaluate(env) as Number).Value; k++; } if (ruleName == "filter-mode") { string filterMode = cartoRule.Value.Evaluate(env).ToCSS(env); if (string.Equals(filterMode, "all")) { style.ProcessFeatureOnce = false; } else if (string.Equals(filterMode, "first")) { style.ProcessFeatureOnce = true; } k++; } } if (k < rules.Count) { if (existingFilters == null) { existingFilters = new Dictionary <string, int>(); } CreateRules(style, def, env, existingFilters, cartoTranslator); } } return(style); }
private static void CreateSymbolizers(Rule rule, Dictionary<string, Dictionary<string, CartoRule>> symbolizers, Env env, ICartoTranslator cartoTranslator) { // Sort symbolizers by the index of their first property definition List<KeyValuePair<string, int>> symOrder = new List<KeyValuePair<string, int>>(); List<int> indexes = new List<int>(); foreach (string key in symbolizers.Keys) { int minIdx = int.MaxValue; var props = symbolizers[key]; foreach (var prop in props) { int index = props[prop.Key].Index; if (index < minIdx) minIdx = index; } symOrder.Add(new KeyValuePair<string, int>(key, minIdx)); } // Get a simple list of the symbolizers, in order symOrder.Sort(delegate (KeyValuePair<string, int> a, KeyValuePair<string, int> b) { return a.Value.CompareTo(b.Value); }); foreach (KeyValuePair<string, int> kv in symOrder) { var attributes = symbolizers[kv.Key]; var symbolizer = kv.Key.Split('/')[1]; // Skip the magical * symbolizer which is used for universal properties // which are bubbled up to Style elements intead of Symbolizer elements. if (symbolizer == "*") continue; // Check if we have all required properties string[] properties = attributes.Keys.ToArray(); string[] values = new string[properties.Length]; string missingProperty = null; bool succ = cartoTranslator.HasRequiredProperties(symbolizer, properties, ref missingProperty); if (!succ) { NodeLocation loc = attributes[missingProperty].Location; throw new Exception(string.Format("A required property '{0}' is missing. Location: Index = {1} ; Source = {2}", missingProperty, loc.Index, loc.Source)); } int i = 0; foreach (string propName in attributes.Keys) { CartoRule cartoRule = attributes[propName]; values[i] = cartoRule.Value.GetValueAsString(env); i++; } Symbolizer sym = cartoTranslator.ToSymbolizer(symbolizer, properties, values); if (sym != null && sym.Enabled) rule.Symbolizers.Add(sym); } }
/// <summary> /// Creates map object from <see cref="CartoProject"/> /// </summary> /// <param name="project"></param> /// <param name="definitions"></param> /// <param name="env"></param> /// <param name="cartoTranslator"></param> /// <returns></returns> private static Map CreateMap(CartoProject project, List <CartoDefinition> definitions, Env env, ICartoTranslator cartoTranslator) { Map map = new Map(project.Name); map.Size = new SizeF(700, 500); map.MinimumScale = ConvertUtility.ToScaleDenominator(project.MinZoom); map.MaximumScale = ConvertUtility.ToScaleDenominator(project.MaxZoom); // if (project.Bounds != null) // map.WGS84Bounds = project.Bounds[0] + "," + project.Bounds[1] + "," + project.Bounds[2] + "," + project.Bounds[3]; map.CRS = cartoTranslator.ToCoordinateSystem(string.IsNullOrEmpty(project.Srs) ? project.SrsName : project.Srs, !string.IsNullOrEmpty(project.SrsName)); SetMapProperties(map, GetProperties(definitions, env, "Map"), cartoTranslator); SetFontSets(map, definitions, env, cartoTranslator); if (project.Center != null) { if (map.CoordinateSystem == null) { CoordinateSystemFactory csFactory = new CoordinateSystemFactory(); map.CoordinateSystem = (CoordinateSystem)csFactory.CreateSphericalMercatorCoordinateSystem(); } double cx = Convert.ToDouble(project.Center[0]); double cy = Convert.ToDouble(project.Center[1]); double cz = Convert.ToDouble(project.Center[2]); double scale = MapSurfer.Utilities.MapUtility.GetTileMapResolution(cz); GeoAPI.CoordinateSystems.Transformations.ICoordinateTransformation trans = CoordinateTransformationFactory.CreateCoordinateTransformation(GeographicCoordinateSystem.WGS84, map.CoordinateSystem); trans.MathTransform.Transform(ref cx, ref cy, ref cz); map.SetCenterAndZoom(cx, cy, scale); } return(map); }
/// <summary> /// Create styled layer /// </summary> /// <param name="cartoLayer"></param> /// <param name="cartoTranslator"></param> /// <returns></returns> private static StyledLayer CreateStyledLayer(CartoLayer cartoLayer, Map map, ICartoTranslator cartoTranslator) { ParameterCollection parameters = cartoTranslator.ToDatasourceParameters(cartoLayer); StyledLayer layer = new StyledLayer(cartoLayer.Name, parameters); layer.FeaturesCaching.Enabled = true; if (cartoLayer.Properties != null) { if (cartoLayer.Properties.ContainsKey("minzoom")) layer.MinimumScale = ConvertUtility.ToScaleDenominator(Convert.ToInt32(cartoLayer.Properties["minzoom"])); if (cartoLayer.Properties.ContainsKey("maxzoom")) layer.MaximumScale = ConvertUtility.ToScaleDenominator(Convert.ToInt32(cartoLayer.Properties["maxzoom"])); if (cartoLayer.Properties.ContainsKey("queryable")) layer.Queryable = Convert.ToBoolean(cartoLayer.Properties["queryable"]); if (cartoLayer.Properties.ContainsKey("cache-features")) // Extension layer.FeaturesCaching.Enabled = Convert.ToBoolean(cartoLayer.Properties["cache-features"]); } layer.Enabled = cartoLayer.Status != "off"; string providerName = parameters.GetValue("Type"); if (string.IsNullOrEmpty(providerName)) LogFactory.WriteLogEntry(Logger.Default, new IOException(string.Format("Unable to detect the type of a data source provider for the layer '{0}'.", cartoLayer.Name))); if (!string.IsNullOrEmpty(cartoLayer.Srs)) layer.CRS = cartoTranslator.ToCoordinateSystem(string.IsNullOrEmpty(cartoLayer.Srs) ? cartoLayer.SrsName : cartoLayer.Srs, !string.IsNullOrEmpty(cartoLayer.SrsName)); return layer; }
/// <summary> /// Creates <see cref="FeatureTypeStyle"/> object /// </summary> /// <param name="styleName"></param> /// <param name="cartoStyle"></param> /// <param name="env"></param> /// <param name="cartoTranslator"></param> /// <returns></returns> private static FeatureTypeStyle CreateStyle(string styleName, CartoStyle cartoStyle, Env env, ICartoTranslator cartoTranslator) { FeatureTypeStyle style = new FeatureTypeStyle(styleName); style.ProcessFeatureOnce = true; List<CartoDefinition> definitions = cartoStyle.Definitions; Dictionary<string, int> existingFilters = null; List<string> imageFilters = new List<string>(); List<string> imageFiltersBuffer = new List<string>(); int k = 0; for (int i = 0; i < definitions.Count; i++) { CartoDefinition def = definitions[i]; NodeList<CartoRule> rules = def.Rules; for (int j = 0; j < rules.Count; j++) { CartoRule cartoRule = rules[j]; string ruleName = cartoRule.Name; if (ruleName == "image-filters") { string filter = cartoRule.Value.ToString(); if (!imageFilters.Contains(filter)) { style.ImageFiltersOptions.Filters.Add(cartoTranslator.ToImageFilter(filter)); style.ImageFiltersOptions.Enabled = true; imageFilters.Add(filter); } k++; } else if (ruleName == "image-filters-inflate") { bool inflate = Convert.ToBoolean(cartoRule.Value.ToString()); if (inflate) style.ImageFiltersOptions.Enabled = true; k++; } else if (ruleName == "direct-image-filters") { string filter = cartoRule.Value.ToString(); if (!imageFiltersBuffer.Contains(filter)) { style.ImageFiltersOptions.BufferFilters.Add(cartoTranslator.ToImageFilter(filter)); style.ImageFiltersOptions.Enabled = true; imageFiltersBuffer.Add(filter); } k++; } else if (ruleName == "comp-op") { style.BlendingOptions.CompositingMode = cartoTranslator.ToCompositingMode(cartoRule.Value.Evaluate(env).ToString()); k++; } else if (ruleName == "opacity") { style.BlendingOptions.Opacity = (float)(cartoRule.Value.Evaluate(env) as Number).Value; k++; } if (ruleName == "filter-mode") { string filterMode = cartoRule.Value.Evaluate(env).ToCSS(env); if (string.Equals(filterMode, "all")) style.ProcessFeatureOnce = false; else if (string.Equals(filterMode, "first")) style.ProcessFeatureOnce = true; k++; } } if (k < rules.Count) { if (existingFilters == null) existingFilters = new Dictionary<string, int>(); CreateRules(style, def, env, existingFilters, cartoTranslator); } } return style; }
private static void SetMapProperties(Map map, Dictionary<string, string> properties, ICartoTranslator cartoTranslator) { if (properties.Count == 0) return; string paramValue; // ************************* Set background properties ************************* Background background = map.Background; if (properties.TryGetValue("background-color", out paramValue)) background.ColorHtml = paramValue; if (properties.TryGetValue("background-opacity", out paramValue)) background.Opacity = Convert.ToSingle(paramValue, CultureInfo.InvariantCulture); // TODO more image stuff if (properties.TryGetValue("background-image-file", out paramValue) || properties.TryGetValue("background-image", out paramValue)) { background.Image.FileName = cartoTranslator.ToPath(paramValue); } // ************************* Set render modes ************************* RenderModes renderModes = map.RenderModes; if (properties.TryGetValue("render-modes-bidi", out paramValue)) { renderModes.BidiMode = Convert.ToBoolean(paramValue); } if (properties.TryGetValue("render-modes-kerning", out paramValue)) { renderModes.Kerning = Convert.ToBoolean(paramValue); } if (properties.TryGetValue("render-modes-scale-factor", out paramValue)) { renderModes.ScaleFactor = Convert.ToSingle(paramValue); } if (properties.TryGetValue("render-modes-text-abbreviation", out paramValue)) { renderModes.TextAbbreviation = Convert.ToBoolean(paramValue); } if (properties.TryGetValue("render-modes-text-contrast", out paramValue)) { renderModes.TextContrast = Convert.ToInt32(paramValue); } if (properties.TryGetValue("render-modes-image-resampling", out paramValue)) { renderModes.ImageResamplingMode = EnumExtensions.GetValueByName<ImageResamplingMode>(typeof(ImageResamplingMode), paramValue, StringComparison.OrdinalIgnoreCase); } if (properties.TryGetValue("render-modes-smoothing", out paramValue)) { renderModes.SmoothingMode = EnumExtensions.GetValueByName<SmoothingMode>(typeof(SmoothingMode), paramValue, StringComparison.OrdinalIgnoreCase); } if (properties.TryGetValue("render-modes-text-rendering", out paramValue)) { renderModes.TextRenderingMode = EnumExtensions.GetValueByName<TextRenderMode>(typeof(TextRenderMode), paramValue, StringComparison.OrdinalIgnoreCase); } // ************************* Set label settings ************************* LabelPlacementProblemSettings labelSettings = map.LabelPlacementSettings; if (properties.TryGetValue("label-settings-solver", out paramValue)) { labelSettings.Solver = paramValue; labelSettings.SolverParameters = GetParameters(properties, "label-settings-solver-param"); } if (properties.TryGetValue("label-settings-accuracy", out paramValue)) { labelSettings.AccuracyMode = EnumExtensions.GetValueByName<MapSurfer.Labeling.CandidatePositionGenerators.LabelPlacementAccuracyMode>(typeof(MapSurfer.Labeling.CandidatePositionGenerators.LabelPlacementAccuracyMode), paramValue, StringComparison.OrdinalIgnoreCase); } if (properties.TryGetValue("label-settings-candidate-position-generator", out paramValue)) { labelSettings.CandidatePositionGenerator = paramValue; labelSettings.CandidatePositionGeneratorParameters = GetParameters(properties, "label-settings-candidate-position-generator-param"); } if (properties.TryGetValue("label-settings-collision-detector", out paramValue)) { labelSettings.CollisionDetector = paramValue; labelSettings.CollisionDetectorParameters = GetParameters(properties, "label-settings-collision-detector-param"); } string[] values = GetStringValues(properties, "label-settings-quality-evaluator-param"); if (values.Length > 0) { labelSettings.QualityEvaluators.Clear(); labelSettings.QualityEvaluators.AddRange(values); } // ************************* Font files ******************************* values = GetStringValues(properties, "font-files-file"); if (values.Length > 0) { map.FontFiles.AddRange(values); } if (properties.TryGetValue("font-directory", out paramValue)) { if (Directory.Exists(paramValue)) { foreach (string fileName in Directory.EnumerateFiles(paramValue)) { map.FontFiles.Add(fileName); } } } // ************************* Font sets ******************************* //TODO // ************************* Scales ************************* if (properties.TryGetValue("minimum-scale", out paramValue)) map.MinimumScale = Convert.ToDouble(paramValue, CultureInfo.InvariantCulture); if (properties.TryGetValue("maximum-scale", out paramValue)) map.MaximumScale = Convert.ToDouble(paramValue, CultureInfo.InvariantCulture); // ************************* Buffers ************************* int size = 256; if (properties.TryGetValue("buffer-size", out paramValue)) size = Convert.ToInt32(paramValue); map.Padding = new Size(size, size); if (properties.TryGetValue("buffer-image-size", out paramValue)) // Extension { size = Convert.ToInt32(paramValue); map.Buffer = new Size(size, size); } }
/// <summary> /// Detects font sets by analyzing all "text-face-name" properties. /// </summary> /// <param name="definitions"></param> /// <param name="env"></param> public static void SetFontSets(Map map, List<CartoDefinition> definitions, Env env, ICartoTranslator cartoTranslator) { List<FontSet> fontSets = new List<FontSet>(); Dictionary<string, FontSet> dictFontSets = new Dictionary<string, FontSet>(); using (FontFamilyCollection fontCollection = FontUtility.GetFontFamilyCollection()) { List<FontFamilyTypeface> typeFaces = new List<FontFamilyTypeface>(); List<string> notFoundFontNames = new List<string>(); int fontSetCounter = 0; foreach (CartoDefinition def in definitions) { foreach (CartoRule rule in def.Rules) { if (rule.Name == "text-face-name" || rule.Name == "shield-face-name") { try { Value value = rule.Value as Value; string strFontNames = value.Evaluate(env).ToString().Replace("\"", ""); FontSet fontSet = null; if (_dictFontSets.TryGetValue(strFontNames, out fontSet)) { if (!fontSets.Contains(fontSet)) { fontSets.Add((FontSet)fontSet.Clone()); dictFontSets.Add(strFontNames, fontSet); } continue; } string[] fontNames = strFontNames.Split(','); for (int i = 0; i < fontNames.Length; i++) { fontNames[i] = fontNames[i].Trim('\'').Trim(); } typeFaces.Clear(); foreach (string fontName in fontNames) { string fName = fontName.Replace(" ", ""); FontFamilyTypeface typeFace = null; foreach (MapSurfer.Drawing.FontFamily fontFamily in fontCollection.FontFamilies) { if (typeFace != null) break; foreach (FontFamilyTypeface fft in fontFamily.GetTypefaces()) { foreach (string faceName in fft.FaceNames) { string fullName = (fontFamily.Name + faceName).Replace(" ", ""); if (string.Equals(fName, fullName, StringComparison.OrdinalIgnoreCase)) { typeFace = fft; break; } } } } // We were not able to find appropriate type face if (typeFace == null) { if (!notFoundFontNames.Contains(fontName)) { notFoundFontNames.Add(fontName); LogFactory.WriteLogEntry(Logger.Default, string.Format("Unable to find font face(s) for '{0}'", fontName), LogEntryType.Warning); } } else { typeFaces.Add(typeFace); } } string fontSetName = "fontset-" + fontSetCounter.ToString(); if (typeFaces.Count > 0) { FontSet fs = new FontSet(fontSetName, typeFaces[0].Style, typeFaces[0].Weight); foreach (FontFamilyTypeface fft in typeFaces) { fs.FontNames.Add(fft.FontFamily.Name); } fontSets.Add((FontSet)fs.Clone()); _dictFontSets.TryAdd(strFontNames, fs); dictFontSets.Add(strFontNames, fs); fontSetCounter++; } } catch { } } } } } if (fontSets.Count > 0) map.FontSets.AddRange(fontSets); cartoTranslator.FontSets = dictFontSets; }
private static Dictionary<string, Dictionary<string, CartoRule>> CollectSymbolizers(CartoDefinition def, ZoomStruct zooms, int i, Env env, ICartoTranslator cartoTranslator) { Dictionary<string, Dictionary<string, CartoRule>> symbolizers = new Dictionary<string, Dictionary<string, CartoRule>>(); NodeList<CartoRule> rules = def.Rules; for (int j = i; j < rules.Count; j++) { CartoRule child = rules[j]; string symName = cartoTranslator.GetSymbolizerName(child.Name); string key = child.Instance + "/" + symName; if ((zooms.Current & child.Zoom) != 0 && (!(symbolizers.ContainsKey(key)) || (symbolizers[key] != null && !(symbolizers[key].ContainsKey(child.Name))))) { zooms.Current &= child.Zoom; if (!(symbolizers.ContainsKey(key))) symbolizers[key] = new Dictionary<string, CartoRule>(); symbolizers[key][child.Name] = child; } } if (symbolizers.Count > 0) { zooms.Rule &= (zooms.Available &= ~zooms.Current); return symbolizers; } return null; }
private static void SetMapProperties(Map map, Dictionary <string, string> properties, ICartoTranslator cartoTranslator) { if (properties.Count == 0) { return; } string paramValue; // ************************* Set background properties ************************* Background background = map.Background; if (properties.TryGetValue("background-color", out paramValue)) { background.ColorHtml = paramValue; } if (properties.TryGetValue("background-opacity", out paramValue)) { background.Opacity = Convert.ToSingle(paramValue, CultureInfo.InvariantCulture); } // TODO more image stuff if (properties.TryGetValue("background-image-file", out paramValue) || properties.TryGetValue("background-image", out paramValue)) { background.Image.FileName = cartoTranslator.ToPath(paramValue); } // ************************* Set render modes ************************* RenderModes renderModes = map.RenderModes; if (properties.TryGetValue("render-modes-bidi", out paramValue)) { renderModes.BidiMode = Convert.ToBoolean(paramValue); } if (properties.TryGetValue("render-modes-kerning", out paramValue)) { renderModes.Kerning = Convert.ToBoolean(paramValue); } if (properties.TryGetValue("render-modes-scale-factor", out paramValue)) { renderModes.ScaleFactor = Convert.ToSingle(paramValue); } if (properties.TryGetValue("render-modes-text-abbreviation", out paramValue)) { renderModes.TextAbbreviation = Convert.ToBoolean(paramValue); } if (properties.TryGetValue("render-modes-text-contrast", out paramValue)) { renderModes.TextContrast = Convert.ToInt32(paramValue); } if (properties.TryGetValue("render-modes-image-resampling", out paramValue)) { renderModes.ImageResamplingMode = EnumExtensions.GetValueByName <ImageResamplingMode>(typeof(ImageResamplingMode), paramValue, StringComparison.OrdinalIgnoreCase); } if (properties.TryGetValue("render-modes-smoothing", out paramValue)) { renderModes.SmoothingMode = EnumExtensions.GetValueByName <SmoothingMode>(typeof(SmoothingMode), paramValue, StringComparison.OrdinalIgnoreCase); } if (properties.TryGetValue("render-modes-text-rendering", out paramValue)) { renderModes.TextRenderingMode = EnumExtensions.GetValueByName <TextRenderMode>(typeof(TextRenderMode), paramValue, StringComparison.OrdinalIgnoreCase); } // ************************* Set label settings ************************* LabelPlacementProblemSettings labelSettings = map.LabelPlacementSettings; if (properties.TryGetValue("label-settings-solver", out paramValue)) { labelSettings.Solver = paramValue; labelSettings.SolverParameters = GetParameters(properties, "label-settings-solver-param"); } if (properties.TryGetValue("label-settings-accuracy", out paramValue)) { labelSettings.AccuracyMode = EnumExtensions.GetValueByName <MapSurfer.Labeling.CandidatePositionGenerators.LabelPlacementAccuracyMode>(typeof(MapSurfer.Labeling.CandidatePositionGenerators.LabelPlacementAccuracyMode), paramValue, StringComparison.OrdinalIgnoreCase); } if (properties.TryGetValue("label-settings-candidate-position-generator", out paramValue)) { labelSettings.CandidatePositionGenerator = paramValue; labelSettings.CandidatePositionGeneratorParameters = GetParameters(properties, "label-settings-candidate-position-generator-param"); } if (properties.TryGetValue("label-settings-collision-detector", out paramValue)) { labelSettings.CollisionDetector = paramValue; labelSettings.CollisionDetectorParameters = GetParameters(properties, "label-settings-collision-detector-param"); } string[] values = GetStringValues(properties, "label-settings-quality-evaluator-param"); if (values.Length > 0) { labelSettings.QualityEvaluators.Clear(); labelSettings.QualityEvaluators.AddRange(values); } // ************************* Font files ******************************* values = GetStringValues(properties, "font-files-file"); if (values.Length > 0) { map.FontFiles.AddRange(values); } if (properties.TryGetValue("font-directory", out paramValue)) { if (Directory.Exists(paramValue)) { foreach (string fileName in Directory.EnumerateFiles(paramValue)) { map.FontFiles.Add(fileName); } } } // ************************* Font sets ******************************* //TODO // ************************* Scales ************************* if (properties.TryGetValue("minimum-scale", out paramValue)) { map.MinimumScale = Convert.ToDouble(paramValue, CultureInfo.InvariantCulture); } if (properties.TryGetValue("maximum-scale", out paramValue)) { map.MaximumScale = Convert.ToDouble(paramValue, CultureInfo.InvariantCulture); } // ************************* Buffers ************************* int size = 256; if (properties.TryGetValue("buffer-size", out paramValue)) { size = Convert.ToInt32(paramValue); } map.Padding = new Size(size, size); if (properties.TryGetValue("buffer-image-size", out paramValue)) // Extension { size = Convert.ToInt32(paramValue); map.Buffer = new Size(size, size); } }
/// <summary> /// Creates map object from <see cref="CartoProject"/> /// </summary> /// <param name="project"></param> /// <param name="definitions"></param> /// <param name="env"></param> /// <param name="cartoTranslator"></param> /// <returns></returns> private static Map CreateMap(CartoProject project, List<CartoDefinition> definitions, Env env, ICartoTranslator cartoTranslator) { Map map = new Map(project.Name); map.Size = new SizeF(700, 500); map.MinimumScale = ConvertUtility.ToScaleDenominator(project.MinZoom); map.MaximumScale = ConvertUtility.ToScaleDenominator(project.MaxZoom); // if (project.Bounds != null) // map.WGS84Bounds = project.Bounds[0] + "," + project.Bounds[1] + "," + project.Bounds[2] + "," + project.Bounds[3]; map.CRS = cartoTranslator.ToCoordinateSystem(string.IsNullOrEmpty(project.Srs) ? project.SrsName : project.Srs, !string.IsNullOrEmpty(project.SrsName)); SetMapProperties(map, GetProperties(definitions, env, "Map"), cartoTranslator); SetFontSets(map, definitions, env, cartoTranslator); if (project.Center != null) { if (map.CoordinateSystem == null) { CoordinateSystemFactory csFactory = new CoordinateSystemFactory(); map.CoordinateSystem = (CoordinateSystem)csFactory.CreateSphericalMercatorCoordinateSystem(); } double cx = Convert.ToDouble(project.Center[0]); double cy = Convert.ToDouble(project.Center[1]); double cz = Convert.ToDouble(project.Center[2]); double scale = MapSurfer.Utilities.MapUtility.GetTileMapResolution(cz); GeoAPI.CoordinateSystems.Transformations.ICoordinateTransformation trans = CoordinateTransformationFactory.CreateCoordinateTransformation(GeographicCoordinateSystem.WGS84, map.CoordinateSystem); trans.MathTransform.Transform(ref cx, ref cy, ref cz); map.SetCenterAndZoom(cx, cy, scale); } return map; }
/// <summary> /// Creates rules /// </summary> /// <param name="style"></param> /// <param name="def"></param> /// <param name="env"></param> /// <param name="existingFilters"></param> /// <param name="cartoTranslator"></param> private static void CreateRules(FeatureTypeStyle style, CartoDefinition def, Env env, Dictionary<string, int> existingFilters, ICartoTranslator cartoTranslator) { string filter = def.Filters.ToString(); if (!(existingFilters.ContainsKey(filter))) existingFilters[filter] = 0x7FFFFF; int available = 0x7FFFFF; ZoomStruct zooms = new ZoomStruct(); zooms.Available = available; NodeList<CartoRule> rules = def.Rules; for (int i = 0; i < rules.Count; i++) { CartoRule cartoRule = rules[i]; zooms.Rule = cartoRule.Zoom; if ((existingFilters[filter] & zooms.Rule) == 0) continue; while (((zooms.Current = zooms.Rule) & available) != 0) { Dictionary<string, Dictionary<string, CartoRule>> symbolizers = CollectSymbolizers(def, zooms, i, env, cartoTranslator); if (symbolizers != null && symbolizers.Count > 0) { if ((existingFilters[filter] & zooms.Current) == 0) continue; int zoom = existingFilters[filter] & zooms.Current; int startZoom = -1, endZoom = 0; for (int zi = 0; zi <= 22; zi++) { if ((zoom & (1 << zi)) != 0) { if (startZoom == -1) startZoom = zi; endZoom = zi; } } Rule rule = new Rule(); rule.Filter = ConvertUtility.ToFilter(def.Filters, cartoTranslator); rule.Name = cartoRule.Instance; if (startZoom > 0) rule.MaxScale = ConvertUtility.ToScaleDenominator(startZoom); if (endZoom > 0) rule.MinScale = ConvertUtility.ToScaleDenominator(endZoom + 1); CreateSymbolizers(rule, symbolizers, env, cartoTranslator); existingFilters[filter] &= ~zooms.Current; // Check whether the rule has at least one visible symbolizer if (rule.Symbolizers.Count > 0 && rule.Symbolizers.Any(s => s.Enabled == true)) style.Rules.Add(rule); } } } //style.Rules.Sort(new RuleComparer()); }