private static void RenderMissingSegments(Graphics g, ILayer layer) { var coverage = ((NetworkCoverageFeatureCollection)layer.DataSource).RenderedCoverage; var locations = coverage.Locations.Values; for (int i = 0; i < locations.Count - 1; i++) { var loc1 = locations[i]; var loc2 = locations[i + 1]; var segments = NetworkHelper.GetShortestPathBetweenBranchFeaturesAsNetworkSegments(coverage.Network, loc1, loc2); if (segments.Count != 0) { continue; } var line = new LineString(new[] { loc1.Geometry.Coordinate, loc2.Geometry.Coordinate }); var linePen = new Pen(Color.Red, 5f) { DashStyle = DashStyle.Dot }; var missingSegmentStyle = new VectorStyle(Brushes.Black, linePen, false, linePen, 1.0f, typeof(ILineString), DelftTools.Utils.Drawing.ShapeType.Rectangle, 3); VectorRenderingHelper.RenderGeometry(g, layer.Map, line, missingSegmentStyle, null, true); linePen.Dispose(); } }
public override bool Render(IFeature feature, Graphics g, ILayer layer) { var segmentsLayer = (NetworkCoverageSegmentLayer)layer; var coverage = ((NetworkCoverageFeatureCollection)layer.DataSource).RenderedCoverage; IEnvelope mapExtents = layer.Map.Envelope; var sliceValues = coverage.GetValues(); // 1 find the segments withing the current extend var segments = coverage.Segments.Values;//.Where(seg => seg.Geometry.EnvelopeInternal.Intersects(mapExtents)).ToList(); for (int i = 0; i < segments.Count; i++) { INetworkSegment segment = segments[i]; if (segment.Geometry.EnvelopeInternal.Intersects(mapExtents) && sliceValues.Count > 0) { // 2 get the values for this segment // if SegmentGenerationMethod == SegmentGenerationMethod.RouteBetweenLocations the segments and // location do not have to match; return default value double value = coverage.SegmentGenerationMethod == SegmentGenerationMethod.RouteBetweenLocations ? 0 : (double)sliceValues[i]; // 3 use the Theme of the layer to draw var style = (VectorStyle)segmentsLayer.Theme.GetStyle(value); VectorRenderingHelper.RenderGeometry(g, layer.Map, segment.Geometry, style, null, true); } } return(true); }
private static void DrawSegment(VectorLayer segmentsLayer, INetworkCoverage coverage, ITheme theme, int segmentNumber, IList <double> allBranchLocationValues, bool firstSegment, bool lastSegment, Graphics graphics, INetworkSegment segment, VectorStyle defaultStyle, double offset) { var valueAtStart = allBranchLocationValues[segmentNumber * 2]; var value = allBranchLocationValues[segmentNumber * 2 + 1]; var valueAtEnd = allBranchLocationValues[segmentNumber * 2 + 2]; // extract based on valueAtStart and valueAtEnd the colors from the var styleStart = (theme != null) ? (VectorStyle)theme.GetStyle(valueAtStart) : segmentsLayer.Style; var themeStyle = (theme != null) ? (VectorStyle)theme.GetStyle(value) : segmentsLayer.Style; var styleEnd = (theme != null) ? (VectorStyle)theme.GetStyle(valueAtEnd) : segmentsLayer.Style; // check if within limits (preventing GDI+ overflow on 'ultrazoom') var strokes = Transform.TransformToImage((ILineString)segment.Geometry, segmentsLayer.Map); if (strokes.Any(s => !graphics.ClipBounds.Contains(s))) { return; } if (firstSegment && lastSegment) { // 1 segment; render segement based on coverage.Locations.InterpolationType if (coverage.Locations.ExtrapolationType == ExtrapolationType.None) { VectorRenderingHelper.RenderGeometry(graphics, segmentsLayer.Map, segment.Geometry, defaultStyle, null, true); return; } if (coverage.Locations.ExtrapolationType == ExtrapolationType.Linear) { VectorRenderingHelper.RenderGeometry(graphics, segmentsLayer.Map, segment.Geometry, themeStyle, null, true); return; } // todo use proper colors/styles from Theme; now 'via' styles are ignored. var kcolors = new[] { ((SolidBrush)styleStart.Fill).Color, ((SolidBrush)themeStyle.Fill).Color, ((SolidBrush)styleEnd.Fill).Color }; var kpositions = new[] { 0.0F, (float)((offset - segment.Chainage) / segment.Length), 1.0F }; DrawStrokesLinear(graphics, strokes, (int)themeStyle.Line.Width, kcolors, kpositions); return; } var positions = new[] { 0.0F, (float)((offset - segment.Chainage) / segment.Length), (float)((offset - segment.Chainage) / segment.Length), 1.0F }; var colors = CreateBeginEndColors(coverage, firstSegment, lastSegment, GetStyleColor(themeStyle), GetStyleColor(styleStart), GetStyleColor(styleEnd), GetStyleColor(defaultStyle)); // todo use proper colors/styles from Theme; now 'via' styles are ignored. if (!segment.Geometry.IsEmpty) { DrawStrokesLinear(graphics, strokes, (int)themeStyle.Line.Width, colors, positions); } }
private static void RenderConstantBetweenLocations(Graphics g, ILayer layer, bool fullyCovered) { var segmentsLayer = (NetworkCoverageSegmentLayer)layer; var coverage = ((NetworkCoverageFeatureCollection)layer.DataSource).RenderedCoverage; var mapExtents = layer.Map.Envelope; var theme = layer.Theme; int currentCount = 0; IBranch currentBranch = null; List <INetworkLocation> locations = null; var timeFilter = coverage.Filters.OfType <VariableValueFilter <DateTime> >().FirstOrDefault(); var hasTime = coverage.IsTimeDependent && timeFilter != null && timeFilter.Values.Count > 0; if (coverage.IsTimeDependent && !hasTime) { return; } foreach (INetworkSegment networkSegment in coverage.Segments.Values) { if (currentBranch != networkSegment.Branch) { currentCount = 0; currentBranch = networkSegment.Branch; locations = coverage.Locations.Values.Where(l => l.Branch == currentBranch).ToList(); if (fullyCovered) { var first = locations.FirstOrDefault(); if (first == null || first.Offset != 0) { locations.Insert(0, FindNodePoint(currentBranch.Source, coverage)); } } } if (!networkSegment.Geometry.EnvelopeInternal.Intersects(mapExtents)) { currentCount++; continue; } var value = !hasTime ? coverage[locations[currentCount]] : coverage[timeFilter.Values[0], locations[currentCount]]; var style = (theme != null) ? (VectorStyle)theme.GetStyle(value != null ? (double)value : 0) : segmentsLayer.Style; VectorRenderingHelper.RenderGeometry(g, layer.Map, networkSegment.Geometry, style, null, true); currentCount++; } }
/// <summary> /// Draw a branch with no segments; this will usually be drawn with the style for the default value. /// </summary> /// <param name="map"></param> /// <param name="coverage"></param> /// <param name="g"></param> /// <param name="style"></param> /// <param name="mapExtents"></param> /// <param name="drawnBranches"></param> /// <param name="theme"></param> private static void RenderSegmentFreeBranches(Map map, INetworkCoverage coverage, Graphics g, VectorStyle style, IEnvelope mapExtents, HashSet <IBranch> drawnBranches, ITheme theme) { var visibleBranches = coverage.Network.Branches.Where(b => b.Geometry.EnvelopeInternal.Intersects(mapExtents)).ToList(); visibleBranches.ForEach(vb => { if (!drawnBranches.Contains(vb)) { VectorRenderingHelper.RenderGeometry(g, map, vb.Geometry, style, null, true); } }); }
public override bool Render(IFeature feature, Graphics g, ILayer layer) { var locationLayer = (NetworkCoverageLocationLayer)layer; var coverage = ((NetworkCoverageFeatureCollection)layer.DataSource).RenderedCoverage; var mapExtents = layer.Map.Envelope; if (coverage.IsTimeDependent && coverage.Time.AllValues.Count == 0) { return(true); //skip } var sliceValues = coverage.GetValues(); var locations = coverage.Locations.Values.ToArray(); if (sliceValues.Count == 0) { return(true); } //1 find the locations withing the current extend /*var locations = coverage.Locations.Values * .Where(networkLocation => networkLocation.Geometry.EnvelopeInternal.Intersects(mapExtents)).ToList();*/ for (var i = 0; i < locations.Length; i++) { var location = locations[i]; if (!location.Geometry.EnvelopeInternal.Intersects(mapExtents)) { continue; } //2 get the values for this location var value = (double)sliceValues[i]; //3 use the Theme of the layer to draw a line. var vectorStyle = GetStyle(locationLayer, value); VectorRenderingHelper.RenderGeometry(g, layer.Map, location.Geometry, vectorStyle, null, true); } return(true); }
private static void RenderConstant(Graphics g, ILayer layer) { var segmentsLayer = (NetworkCoverageSegmentLayer)layer; var coverage = ((NetworkCoverageFeatureCollection)layer.DataSource).RenderedCoverage; var mapExtents = layer.Map.Envelope; var sliceValues = coverage.GetValues(); var theme = segmentsLayer.Theme; var drawnBranches = new HashSet <IBranch>(); // 1 find the segments withing the current extend var segments = coverage.Segments.Values; for (var i = 0; i < segments.Count; i++) { var segment = segments[i]; if (!segment.Geometry.EnvelopeInternal.Intersects(mapExtents) || sliceValues.Count <= 0) { continue; } drawnBranches.Add(segment.Branch); // 2 get the values for this segment // if SegmentGenerationMethod == SegmentGenerationMethod.RouteBetweenLocations the segments and // location do not have to match; return default value var value = coverage.SegmentGenerationMethod == SegmentGenerationMethod.RouteBetweenLocations ? 0 : (double)sliceValues[i]; // 3 use the Theme of the layer to draw var style = (theme != null) ? (VectorStyle)theme.GetStyle(value) : segmentsLayer.Style; VectorRenderingHelper.RenderGeometry(g, layer.Map, segment.Geometry, style, null, true); } //// draw branches that are visible but without segment and thus not yet drawn. //var defaultStyle = (theme != null) ? (VectorStyle)theme.GetStyle(coverage.DefaultValue) : segmentsLayer.Style; //RenderSegmentFreeBranches(layer.Map, coverage, g, defaultStyle, mapExtents, drawnBranches, theme); }
/// <summary> /// Renders all features on the currently visible part of the map, using the values from the feature coverage. /// </summary> /// <param name="feature">The coverage to render.</param> /// <param name="g">Graphics object to be used as a target for rendering.</param> /// <param name="layer">Layer where coverage belongs to.</param> /// <returns>When rendering succeds returns true, otherwise false.</returns> public bool Render(IFeature feature, Graphics g, ILayer layer) { // Use the FeatureCoverage function to get the coverage values var coverageLayer = (FeatureCoverageLayer)layer; IFeatureCoverage coverage = coverageLayer.FeatureCoverage; Map map = coverageLayer.Map; // No theme? No rendering! (This should be set in the FeatureCoverageLayer class' set_Features.) if (coverageLayer.Theme == null) { return(false); } // What features to render? IList featuresToRender; IFeature[] coverageFeatures; double[] values; lock (coverage.Store) // makes sure that features don't change before we get values { featuresToRender = coverageLayer.DataSource.GetFeatures(map.Envelope).Cast <IFeature>().ToArray(); if (featuresToRender.Count <= 0) { // No features in the envelope, so no rendering required. return(true); } coverageFeatures = coverage.FeatureVariable.Values.Cast <IFeature>().ToArray(); values = coverage.Components[0].Values.Cast <double>().ToArray(); } for (var i = 0; i < coverageFeatures.Length; i++) { var featureToRender = coverageFeatures[i]; if (!featuresToRender.Contains(featureToRender)) { continue; } // Use the GetStyle with the retrieved value var style = coverageLayer.Theme.GetStyle(values[i]) as VectorStyle; if (style != null) { // Draw background of all line-outlines first if (feature.Geometry is ILineString) { if (style.Enabled && style.EnableOutline) { VectorRenderingHelper.DrawLineString(g, featureToRender.Geometry as ILineString, style.Outline, map); } } else if (feature.Geometry is IMultiLineString) { if (style.Enabled && style.EnableOutline) { VectorRenderingHelper.DrawMultiLineString(g, featureToRender.Geometry as IMultiLineString, style.Outline, map); } } // Draw actual geometry VectorRenderingHelper.RenderGeometry(g, map, featureToRender.Geometry, style, VectorLayer.DefaultPointSymbol, coverageLayer.ClippingEnabled); } else { throw new ArgumentException("No style could be gotten from the theme; the feature cannot be rendered."); } } return(true); }