1 | #region License Information
|
---|
2 | /* HeuristicLab
|
---|
3 | * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
|
---|
4 | *
|
---|
5 | * This file is part of HeuristicLab.
|
---|
6 | *
|
---|
7 | * HeuristicLab is free software: you can redistribute it and/or modify
|
---|
8 | * it under the terms of the GNU General Public License as published by
|
---|
9 | * the Free Software Foundation, either version 3 of the License, or
|
---|
10 | * (at your option) any later version.
|
---|
11 | *
|
---|
12 | * HeuristicLab is distributed in the hope that it will be useful,
|
---|
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
15 | * GNU General Public License for more details.
|
---|
16 | *
|
---|
17 | * You should have received a copy of the GNU General Public License
|
---|
18 | * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
|
---|
19 | */
|
---|
20 | #endregion
|
---|
21 |
|
---|
22 |
|
---|
23 | using GeoAPI.CoordinateSystems;
|
---|
24 | using GeoAPI.Geometries;
|
---|
25 | using NetTopologySuite.CoordinateSystems.Transformations;
|
---|
26 | using NetTopologySuite.Geometries;
|
---|
27 | using ProjNet.CoordinateSystems;
|
---|
28 | using ProjNet.CoordinateSystems.Transformations;
|
---|
29 | using SharpMap.Data;
|
---|
30 | using SharpMap.Data.Providers;
|
---|
31 | using SharpMap.Layers;
|
---|
32 | using SharpMap.Rendering.Thematics;
|
---|
33 | using SharpMap.Styles;
|
---|
34 | using System;
|
---|
35 | using System.Collections.Generic;
|
---|
36 | using System.Drawing;
|
---|
37 | using System.Drawing.Drawing2D;
|
---|
38 | using System.Linq;
|
---|
39 | using ColorBlend = SharpMap.Rendering.Thematics.ColorBlend;
|
---|
40 |
|
---|
41 | namespace HeuristicLab.BioBoost.Views.MapViews {
|
---|
42 | public class LazyValueLayerGenerator : ILazyLayerGenerator {
|
---|
43 | public static ColorBlend DefaultColorBlend = new ColorBlend(new[] {
|
---|
44 | Color.FromArgb(0, 128, 255),
|
---|
45 | Color.FromArgb(0, 255, 255),
|
---|
46 | Color.FromArgb(0, 255, 0),
|
---|
47 | Color.FromArgb(128, 255, 0),
|
---|
48 | Color.FromArgb(255, 255, 0),
|
---|
49 | Color.FromArgb(255, 128, 0),
|
---|
50 | }, new[] { 0f, 1f / 5, 2f / 5, 3f / 5, 4f / 5, 1f });
|
---|
51 |
|
---|
52 |
|
---|
53 | private GeometryFeatureProvider geom;
|
---|
54 | private IEnumerable<string> locationNames;
|
---|
55 | private IEnumerable<double> values;
|
---|
56 | private ILayer layer;
|
---|
57 | public ColorBlend ColorBlend { get; set; }
|
---|
58 | public double? MinValue { get; set; }
|
---|
59 | public double? MaxValue { get; set; }
|
---|
60 | public double ActualMinValue { get; private set; }
|
---|
61 | public double ActualMaxValue { get; private set; }
|
---|
62 | public String LayerName { get; set; }
|
---|
63 | public bool RealtiveToSize { get; set; }
|
---|
64 | public string Unit { get; set; }
|
---|
65 | public Dictionary<string, double> Mapping;
|
---|
66 |
|
---|
67 | public LazyValueLayerGenerator(GeometryFeatureProvider geom, IEnumerable<string> locationNames, IEnumerable<double> values, String layerName) {
|
---|
68 | this.geom = geom;
|
---|
69 | this.locationNames = locationNames;
|
---|
70 | this.values = values;
|
---|
71 | this.LayerName = layerName;
|
---|
72 | this.RealtiveToSize = false;
|
---|
73 | this.ColorBlend = DefaultColorBlend;
|
---|
74 | }
|
---|
75 |
|
---|
76 | public ILayer Layer {
|
---|
77 | get {
|
---|
78 | if (layer == null) BuildLayer();
|
---|
79 | return layer;
|
---|
80 | }
|
---|
81 | }
|
---|
82 |
|
---|
83 | private void BuildLayer() {
|
---|
84 | string[] locationNames = this.locationNames.ToArray();
|
---|
85 | double[] values = this.values.ToArray();
|
---|
86 | this.locationNames = null;
|
---|
87 | this.values = null;
|
---|
88 | Mapping = locationNames
|
---|
89 | .Zip(values, (location, value) => new { location, value })
|
---|
90 | .ToDictionary(p => p.location, p => p.value);
|
---|
91 | if (RealtiveToSize) {
|
---|
92 | foreach (FeatureDataRow row in geom.Features.Rows) {
|
---|
93 | var nutsId = (string)row["NUTS_ID"];
|
---|
94 | double value;
|
---|
95 | if (Mapping.TryGetValue(nutsId, out value)) {
|
---|
96 | Mapping[nutsId] = value / GetAreaInHa(row.Geometry);
|
---|
97 | }
|
---|
98 | }
|
---|
99 | }
|
---|
100 | MinValue = MinValue ?? Mapping.Values.Min();
|
---|
101 | MaxValue = MaxValue ?? Mapping.Values.Max();
|
---|
102 | ActualMinValue = Math.Min(MinValue.Value, MaxValue.Value);
|
---|
103 | ActualMaxValue = Math.Max(MinValue.Value, MaxValue.Value);
|
---|
104 | var range = ActualMaxValue - ActualMinValue;
|
---|
105 | if (range == 0) range = 1;
|
---|
106 | layer = new VectorLayer(LayerName, geom) {
|
---|
107 | SmoothingMode = SmoothingMode.HighQuality,
|
---|
108 | Theme = new CustomTheme(row => {
|
---|
109 | var col = Color.LightGray;
|
---|
110 | double value;
|
---|
111 | if (row != null && Mapping.TryGetValue((string)row["NUTS_ID"], out value)) {
|
---|
112 | if (value != 0)
|
---|
113 | col = ColorBlend.GetColor((float)((value - ActualMinValue) / range));
|
---|
114 | }
|
---|
115 | return new VectorStyle {
|
---|
116 | Fill = new SolidBrush(col),
|
---|
117 | EnableOutline = true,
|
---|
118 | Outline = new Pen(Color.Black, 1f),
|
---|
119 | };
|
---|
120 | })
|
---|
121 | };
|
---|
122 |
|
---|
123 | }
|
---|
124 |
|
---|
125 | private static readonly CoordinateTransformationFactory transformFactory = new CoordinateTransformationFactory();
|
---|
126 | private static readonly CoordinateSystemFactory factory = new CoordinateSystemFactory();
|
---|
127 | private static double GetAreaInHa(IGeometry geom) {
|
---|
128 | geom = (IGeometry)geom.Clone();
|
---|
129 | var centroid = geom.Centroid;
|
---|
130 | var parameters = new List<ProjectionParameter> {
|
---|
131 | new ProjectionParameter("latitude_of_origin", centroid.Y),
|
---|
132 | new ProjectionParameter("central_meridian", centroid.X),
|
---|
133 | new ProjectionParameter("standard_parallel_1", 30),
|
---|
134 | new ProjectionParameter("standard_parallel_2", 75),
|
---|
135 | new ProjectionParameter("false_easting", 0),
|
---|
136 | new ProjectionParameter("false_northing", 0)
|
---|
137 | };
|
---|
138 | var projection = factory.CreateProjection("Albers", "albers_conic_equal_area", parameters);
|
---|
139 | var cartesian = factory.CreateProjectedCoordinateSystem(
|
---|
140 | "local albers",
|
---|
141 | GeographicCoordinateSystem.WGS84,
|
---|
142 | projection,
|
---|
143 | LinearUnit.Metre,
|
---|
144 | new AxisInfo("East", AxisOrientationEnum.East),
|
---|
145 | new AxisInfo("North", AxisOrientationEnum.North));
|
---|
146 | var transform = transformFactory.CreateFromCoordinateSystems(GeographicCoordinateSystem.WGS84, cartesian);
|
---|
147 | var transformed = GeometryTransform.TransformGeometry(GeometryFactory.Default, geom, transform.MathTransform);
|
---|
148 | return transformed.Area / 10000;
|
---|
149 | }
|
---|
150 | }
|
---|
151 | }
|
---|