示例#1
0
        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;
        }
示例#2
0
        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();
                }
            }
        }
示例#3
0
 public List<Feature> GetFeatures(Cumberland.Rectangle rectangle, string themeField)
 {
     return GetFeatures();
 }
示例#4
0
 public List<Cumberland.Feature> GetFeatures(Cumberland.Rectangle rectangle)
 {
     return GetFeatures(rectangle, null);
 }