using System.Data; using GeoAPI.Geometries; using NetTopologySuite.Geometries; using SharpMap.Data; using SharpMap.Data.Providers; using SharpMap.Layers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; namespace HeuristicLab.BioBoost.Views.MapViews { public class LazyVectorLayerGenerator : ILazyLayerGenerator { private GeometryFeatureProvider geom; private IEnumerable locationNames; private IEnumerable transportTargets; private IEnumerable transportAmounts; private ILayer layer; public String LayerName { get; set; } public Color VectorColor { get; set; } public int LineOffset { get; set; } public LazyVectorLayerGenerator(GeometryFeatureProvider geom, IEnumerable locationNames, IEnumerable transportTargets, IEnumerable transportAmounts, Color vectorColor, String layerName) { this.geom = geom; if (locationNames == null) throw new ArgumentNullException("locationNames"); if (transportTargets == null) throw new ArgumentNullException("transportTargets"); this.locationNames = locationNames; this.transportTargets = transportTargets; this.transportAmounts = transportAmounts; this.VectorColor = vectorColor; this.LayerName = layerName; } public ILayer Layer { get { if (layer == null) BuildLayer(); return layer; } } private void BuildLayer() { string[] locationNames = this.locationNames.ToArray(); int[] transportTargets = this.transportTargets.ToArray(); double[] transportAmounts = this.transportAmounts == null ? null : this.transportAmounts.ToArray(); this.locationNames = null; this.transportTargets = null; var nameIndex = locationNames.Select((loc, idx) => new { loc, idx }).ToDictionary(p => p.loc, p => p.idx); var centroids = new Coordinate[locationNames.Length]; foreach (FeatureDataRow row in geom.Features) { int idx; if (nameIndex.TryGetValue((string)row["NUTS_ID"], out idx)) { var centroid = row.Geometry.Centroid; try { if (!centroid.Within(row.Geometry)) centroid = row.Geometry.InteriorPoint; } catch (Exception x) { } centroids[idx] = centroid.Coordinate; } } var dataTable = new FeatureDataTable(); dataTable.Columns.Add("NUTS_ID_SRC"); dataTable.Columns.Add("NUTS_ID_DEST"); // var transports = new Collection(); // GeoAPI.GeometryServiceProvider.Instance = new NetTopologySuite.NtsGeometryServices(); // var f = GeoAPI.GeometryServiceProvider.Instance.CreateGeometryFactory(4326); for (int i = 0; i < locationNames.Length; i++) { if (transportAmounts != null && transportAmounts[i] <= 0) continue; IGeometry g = null; var j = transportTargets[i]; var source = centroids[i]; if (source == null) continue; if (i == j) g = new NetTopologySuite.Geometries.Point(source); if (j == -1) continue; var target = j < centroids.Length && j >= 0 ? centroids[j] : null; if (target != null) g = new LineString(new[] { source, target }); var row = dataTable.NewRow(); row.Geometry = g; row["NUTS_ID_SRC"] = locationNames[i]; row["NUTS_ID_DEST"] = locationNames[j]; dataTable.AddRow(row); } var geometryProv = new GeometryFeatureProvider(dataTable); var vectorLayer = new VectorLayer(LayerName, geometryProv); vectorLayer.SmoothingMode = SmoothingMode.HighQuality; vectorLayer.Style.Line.SetLineCap(LineCap.NoAnchor, LineCap.ArrowAnchor, DashCap.Flat); vectorLayer.Style.Line.CustomEndCap = new AdjustableArrowCap(3, 5); vectorLayer.Style.Line.Color = VectorColor; vectorLayer.Style.Line.Width = 1; vectorLayer.Style.LineOffset = LineOffset; vectorLayer.Style.PointColor = new SolidBrush(VectorColor); vectorLayer.Style.PointSize = 2; this.layer = vectorLayer; } } }