#region License Information /* HeuristicLab * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using GeoAPI.CoordinateSystems; using GeoAPI.Geometries; using NetTopologySuite.CoordinateSystems.Transformations; using NetTopologySuite.Geometries; using ProjNet.CoordinateSystems; using ProjNet.CoordinateSystems.Transformations; using SharpMap.Data; using SharpMap.Data.Providers; using SharpMap.Layers; using SharpMap.Rendering.Thematics; using SharpMap.Styles; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using ColorBlend = SharpMap.Rendering.Thematics.ColorBlend; namespace HeuristicLab.BioBoost.Views.MapViews { public class LazyValueLayerGenerator : ILazyLayerGenerator { public static ColorBlend DefaultColorBlend = new ColorBlend(new[] { Color.FromArgb(0, 128, 255), Color.FromArgb(0, 255, 255), Color.FromArgb(0, 255, 0), Color.FromArgb(128, 255, 0), Color.FromArgb(255, 255, 0), Color.FromArgb(255, 128, 0), }, new[] { 0f, 1f / 5, 2f / 5, 3f / 5, 4f / 5, 1f }); private GeometryFeatureProvider geom; private IEnumerable locationNames; private IEnumerable values; private ILayer layer; public ColorBlend ColorBlend { get; set; } public double? MinValue { get; set; } public double? MaxValue { get; set; } public double ActualMinValue { get; private set; } public double ActualMaxValue { get; private set; } public String LayerName { get; set; } public bool RealtiveToSize { get; set; } public string Unit { get; set; } public Dictionary Mapping; public LazyValueLayerGenerator(GeometryFeatureProvider geom, IEnumerable locationNames, IEnumerable values, String layerName) { this.geom = geom; this.locationNames = locationNames; this.values = values; this.LayerName = layerName; this.RealtiveToSize = false; this.ColorBlend = DefaultColorBlend; } public ILayer Layer { get { if (layer == null) BuildLayer(); return layer; } } private void BuildLayer() { string[] locationNames = this.locationNames.ToArray(); double[] values = this.values.ToArray(); this.locationNames = null; this.values = null; Mapping = locationNames .Zip(values, (location, value) => new { location, value }) .ToDictionary(p => p.location, p => p.value); if (RealtiveToSize) { foreach (FeatureDataRow row in geom.Features.Rows) { var nutsId = (string)row["NUTS_ID"]; double value; if (Mapping.TryGetValue(nutsId, out value)) { Mapping[nutsId] = value / GetAreaInHa(row.Geometry); } } } MinValue = MinValue ?? Mapping.Values.Min(); MaxValue = MaxValue ?? Mapping.Values.Max(); ActualMinValue = Math.Min(MinValue.Value, MaxValue.Value); ActualMaxValue = Math.Max(MinValue.Value, MaxValue.Value); var range = ActualMaxValue - ActualMinValue; if (range == 0) range = 1; layer = new VectorLayer(LayerName, geom) { SmoothingMode = SmoothingMode.HighQuality, Theme = new CustomTheme(row => { var col = Color.LightGray; double value; if (row != null && Mapping.TryGetValue((string)row["NUTS_ID"], out value)) { if (value != 0) col = ColorBlend.GetColor((float)((value - ActualMinValue) / range)); } return new VectorStyle { Fill = new SolidBrush(col), EnableOutline = true, Outline = new Pen(Color.Black, 1f), }; }) }; } private static readonly CoordinateTransformationFactory transformFactory = new CoordinateTransformationFactory(); private static readonly CoordinateSystemFactory factory = new CoordinateSystemFactory(); private static double GetAreaInHa(IGeometry geom) { geom = (IGeometry)geom.Clone(); var centroid = geom.Centroid; var parameters = new List { new ProjectionParameter("latitude_of_origin", centroid.Y), new ProjectionParameter("central_meridian", centroid.X), new ProjectionParameter("standard_parallel_1", 30), new ProjectionParameter("standard_parallel_2", 75), new ProjectionParameter("false_easting", 0), new ProjectionParameter("false_northing", 0) }; var projection = factory.CreateProjection("Albers", "albers_conic_equal_area", parameters); var cartesian = factory.CreateProjectedCoordinateSystem( "local albers", GeographicCoordinateSystem.WGS84, projection, LinearUnit.Metre, new AxisInfo("East", AxisOrientationEnum.East), new AxisInfo("North", AxisOrientationEnum.North)); var transform = transformFactory.CreateFromCoordinateSystems(GeographicCoordinateSystem.WGS84, cartesian); var transformed = GeometryTransform.TransformGeometry(GeometryFactory.Default, geom, transform.MathTransform); return transformed.Area / 10000; } } }