public System.Collections.Generic.List<Cumberland.Feature> GetFeatures(Cumberland.Rectangle rectangle) { List<Feature> result = new List<Feature>(); foreach (Feature f in features) { if (f.CalculateBounds().Overlaps(rectangle)) result.Add(f); } return result; }
public Bitmap Draw(Map map, Cumberland.Rectangle extents, string projection, int width, int height) { ProjFourWrapper dst = null; Graphics g = null; List<string> label_names = new List<string>(); List<LabelRequest> labels = new List<LabelRequest>(); try { #region setup drawing Bitmap b = new Bitmap(width, height); g = Graphics.FromImage(b); if (map.BackgroundColor.A > 0) { g.Clear(map.BackgroundColor); } // set antialiasing mode g.SmoothingMode = Smoothing; g.TextRenderingHint = textRenderingHint; // we need to convert map points to pixel points // so let's do as much of this at once: // calculate map rectangle based on image width/height Rectangle envelope = extents.Clone(); // set aspect ratio to image envelope.AspectRatioOfWidth = Convert.ToDouble(width) / Convert.ToDouble(height); // get the scale double scale = Convert.ToDouble(envelope.Width) / Convert.ToDouble(width); double displayScale = scale; // instantiate output projection if (!string.IsNullOrEmpty(projection)) { dst = new ProjFourWrapper(projection); if (!string.IsNullOrEmpty(map.Projection) && projection != map.Projection) { // we want to use the map projection for min/max scale on layers/styles/etc. using (ProjFourWrapper orig = new ProjFourWrapper(map.Projection)) { Point p1 = dst.Transform(orig, extents.Min); Point p2 = dst.Transform(orig, extents.Max); displayScale = Math.Abs(p1.X-p2.X) / width; } } } else if (!string.IsNullOrEmpty(map.Projection)) { dst = new ProjFourWrapper(map.Projection); } #endregion foreach (Layer layer in map.Layers) { if (!layer.Visible || layer.Data == null || displayScale > layer.MaxScale || displayScale < layer.MinScale) { continue; } ProjFourWrapper src = null; try { #region set up layer drawing Rectangle layerEnvelope = envelope.Clone(); // instantiate layer projection bool reproject = false; if (dst != null && !string.IsNullOrEmpty(layer.Projection)) { src = new ProjFourWrapper(layer.Projection); reproject = true; // reproject extents to our source for querying layerEnvelope = new Rectangle(dst.Transform(src, layerEnvelope.Min), dst.Transform(src, layerEnvelope.Max)); } string themeField = null; // query our data List<Feature> features = null; if (layer.Theme == ThemeType.None) { features = layer.Data.GetFeatures(layerEnvelope, null, layer.LabelField); } else { // check for valid field themeField = layer.ThemeField; if (string.IsNullOrEmpty(themeField)) { throw new MapConfigurationException("Layer has been set for theming, but no ThemeField was provided"); } features = layer.Data.GetFeatures(layerEnvelope, themeField, layer.LabelField); } if (features.Count == 0) { continue; } if (layer.Styles.Count == 0) { throw new MapConfigurationException("Layer lacks a Style"); } List<string> names = new List<string>(); // set up a delegate for getting style based on theme type StyleForFeatureFinder getStyle = GetBasicStyleForFeature; if (layer.Theme == ThemeType.Unique) { getStyle = GetUniqueStyleForFeature; } else if (layer.Theme == ThemeType.NumericRange) { getStyle = GetRangeStyleForFeature; } #endregion if (layer.Data.SourceFeatureType == FeatureType.Point) { #region handle point rendering for (int ii=0; ii < features.Count; ii++) { Point p = features[ii] as Point; Style style = getStyle(layer, p.ThemeFieldValue, displayScale); if (style == null) { continue; } PointDrawer drawPoint = GetPointDrawer(style); if (reproject) { // convert our data point to the map projection p = src.Transform(dst, p); } // convert our map projected point to a pixel point System.Drawing.Point pp = ConvertMapToPixel(envelope, scale, p); drawPoint(style, g, pp); if (style.ShowLabels && displayScale <= style.LabelMaxScale && displayScale >= style.LabelMinScale) { labels.Add(new LabelRequest(style, p.LabelFieldValue, pp, layer.AllowDuplicateLabels, names)); } } #endregion } else if (layer.Data.SourceFeatureType == FeatureType.Polyline) { #region Handle line rendering for (int ii=0; ii < features.Count; ii++) { PolyLine pol = (PolyLine) features[ii]; Style style = getStyle(layer, pol.ThemeFieldValue, displayScale); if (style == null || style.LineStyle == LineStyle.None) { continue; } for (int jj=0; jj < pol.Lines.Count; jj++) { Line r = pol.Lines[jj]; if (style.Simplify) { r = r.Simplify(style.SimplifyTolerance); } System.Drawing.Point[] ppts = new System.Drawing.Point[r.Points.Count]; int segmentIdx = 1; double maxSegment = 0; for (int kk = 0; kk < r.Points.Count; kk++) { Point p = r.Points[kk]; if (reproject) { p = src.Transform(dst, p); } ppts[kk] = ConvertMapToPixel(envelope, scale, p); if ((style.DrawPointSymbolOnPolyLine || (style.ShowLabels && scale <= style.LabelMaxScale && scale >= style.LabelMinScale)) && kk > 0) { // find the segment with the longest length to pin a label to double seg = r.Points[kk-1].Distance(r.Points[kk]); if (seg > maxSegment) { maxSegment = seg; segmentIdx = kk; } } } g.DrawLines(ConvertLayerToPen(style), ppts); if (style.DrawPointSymbolOnPolyLine || (style.ShowLabels && pol.LabelFieldValue != null && displayScale <= style.LabelMaxScale && displayScale >= style.LabelMinScale)) { Point start = r.Points[segmentIdx-1]; Point end = r.Points[segmentIdx]; // pin our label to the center point of the line Point polyCenter = new Point((start.X+end.X)/2, (start.Y+end.Y)/2); //Point polyCenter = r.CalculateBounds().Center; // transform (if neccessary) the convert to pixel point System.Drawing.Point plpt = ConvertMapToPixel(envelope, scale, (reproject ? src.Transform(dst, polyCenter) : polyCenter)); if (style.ShowLabels) { float angle = style.LabelAngle; if (style.CalculateLabelAngleForPolyLine) { // calculate the slope of this line and use as our label angle angle = CalculateSegmentAngle(start, end); } labels.Add(new LabelRequest(style, pol.LabelFieldValue, plpt, layer.AllowDuplicateLabels, names, angle)); } } } } #endregion } else if (layer.Data.SourceFeatureType == FeatureType.Polygon) { #region polygon rendering for (int ii=0; ii < features.Count; ii++) { Polygon po = features[ii] as Polygon; Style style = getStyle(layer, po.ThemeFieldValue, displayScale); if (style == null) { continue; } GraphicsPath gp = new GraphicsPath(FillMode.Alternate); for (int jj = 0; jj < po.Rings.Count; jj++) { Ring r = po.Rings[jj]; if (style.Simplify) { r = r.Simplify(style.SimplifyTolerance); } System.Drawing.Point[] ppts = new System.Drawing.Point[r.Points.Count]; for (int kk = 0; kk < r.Points.Count; kk++) { Point p = r.Points[kk]; if (reproject) { p = src.Transform(dst, p); } ppts[kk] = ConvertMapToPixel(envelope, scale, p); } gp.AddPolygon(ppts); } if (style.FillStyle != FillStyle.None) { Brush fillBrush; if (style.FillStyle == FillStyle.Texture) { if (string.IsNullOrEmpty(style.FillTexturePath)) { throw new MapConfigurationException("A style with FillStyle.Texture must have a FillTexturePath"); } fillBrush = new TextureBrush(new Bitmap(style.FillTexturePath)); } else { fillBrush = new SolidBrush(style.FillColor); } g.FillPath(fillBrush, gp); } if (style.LineStyle != LineStyle.None) { g.DrawPath(ConvertLayerToPen(style), gp); } if (style.ShowLabels && po.LabelFieldValue != null && displayScale <= style.LabelMaxScale && displayScale >= style.LabelMinScale) { Point polyCenter = po.CalculateBounds().Center; labels.Add(new LabelRequest(style, po.LabelFieldValue, ConvertMapToPixel(envelope, scale, (reproject ? src.Transform(dst, polyCenter): polyCenter)), layer.AllowDuplicateLabels, names)); } } #endregion } } finally { // dispose of proj4 if (src != null) { src.Dispose(); } } } foreach (LabelRequest lr in labels) { if (!lr.AllowDuplicates) { if (label_names.Contains(lr.Label)) continue; label_names.Add(lr.Label); } if (lr.Style.DrawPointSymbolOnPolyLine) { GetPointDrawer(lr.Style)(lr.Style, g, lr.Coord); } DrawLabel(g, lr.Style, lr.Coord, lr.Label, lr.ForcedLabelAngle); } return b; } finally { // dispose of proj4 if (dst != null) { dst.Dispose(); } if (g != null) { g.Dispose(); } } }
public List<Feature> GetFeatures(Cumberland.Rectangle rectangle, string themeField) { return GetFeatures(); }
public List<Cumberland.Feature> GetFeatures(Cumberland.Rectangle rectangle) { return GetFeatures(rectangle, null); }