/// <summary> /// 将世界范围转为像素范围 /// </summary> /// <param name="self"></param> /// <param name="extent"></param> /// <returns></returns> public static RectangleF ExtentToRectangleF(this IProj self, IExtent extent) { PointF topLeft = CoordinateToPointF(self, extent.MinX, extent.MaxY); PointF bottomRight = CoordinateToPointF(self, extent.MaxX, extent.MinY); return(new RectangleF(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y)); }
/// <summary> /// Converts a rectangle in pixel coordinates relative to the map control into /// a geographic envelope. /// </summary> /// <param name="self">This IProj</param> /// <param name="rect">The rectangle to convert</param> /// <returns>An IEnvelope interface</returns> public static Extent PixelToProj(this IProj self, Rectangle rect) { Point tl = new Point(rect.X, rect.Y); Point br = new Point(rect.Right, rect.Bottom); Coordinate topLeft = PixelToProj(self, tl); Coordinate bottomRight = PixelToProj(self, br); return new Extent(topLeft.X, bottomRight.Y, bottomRight.X, topLeft.Y); }
/// <summary> /// Converts a single geographic envelope into an equivalent Rectangle /// as it would be drawn on the screen. /// </summary> /// <param name="self">This IProj</param> /// <param name="env">The geographic IEnvelope</param> /// <returns>A Rectangle</returns> public static Rectangle ProjToPixel(this IProj self, Extent env) { Coordinate tl = new Coordinate(env.MinX, env.MaxY); Coordinate br = new Coordinate(env.MaxX, env.MinY); Point topLeft = ProjToPixel(self, tl); Point bottomRight = ProjToPixel(self, br); return new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y); }
/// <summary> /// Projects all of the rectangles int the specified list of rectangles into geographic regions. /// </summary> /// <param name="self">This IProj</param> /// <param name="clipRects">The clip rectangles</param> /// <returns>A List of IEnvelope geographic bounds that correspond to the specified clip rectangles.</returns> public static List<Extent> PixelToProj(this IProj self, List<Rectangle> clipRects) { List<Extent> result = new List<Extent>(); foreach (Rectangle r in clipRects) { result.Add(PixelToProj(self, r)); } return result; }
/// <summary> /// Converts a single geographic envelope into an equivalent Rectangle as it would be drawn on the screen. /// </summary> /// <param name="self">This IProj</param> /// <param name="env">The geographic IEnvelope</param> /// <returns>A Rectangle</returns> public static Rectangle ProjToPixel(this IProj self, Envelope env) { var tl = new double[] { env.MinX, env.MaxY }; var br = new double[] { env.MaxX, env.MinY }; Point topLeft = ProjToPixelPoint(self, tl); Point bottomRight = ProjToPixelPoint(self, br); return(new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y)); }
/// <summary> /// 世界坐标转像素坐标 /// </summary> /// <param name="self"></param> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public static PointF CoordinateToPointF(this IProj self, double x, double y) { PointF point = PointF.Empty; if (self != null) { point = CoordinateToPointF(self.Extent, self.Bound, x, y); } return(point); }
/// <summary> /// Translates all of the geographic regions, forming an equivalent list of rectangles. /// </summary> /// <param name="self">This IProj</param> /// <param name="regions">The list of geographic regions to project</param> /// <returns>A list of pixel rectangles that describe the specified region</returns> public static List<Rectangle> ProjToPixel(this IProj self, List<Extent> regions) { List<Rectangle> result = new List<Rectangle>(); foreach (Extent region in regions) { if (region == null) continue; result.Add(ProjToPixel(self, region)); } return result; }
/// <summary> /// Projects all of the rectangles int the specified list of rectangles into geographic regions. /// </summary> /// <param name="self">This IProj</param> /// <param name="clipRects">The clip rectangles</param> /// <returns>A List of IEnvelope geographic bounds that correspond to the specified clip rectangles.</returns> public static List <Envelope> PixelToProj(this IProj self, List <Rectangle> clipRects) { List <Envelope> result = new List <Envelope>(); foreach (Rectangle r in clipRects) { result.Add(PixelToProj(self, r)); } return(result); }
/// <summary> /// 世界坐标转像素坐标 /// </summary> /// <param name="self"></param> /// <param name="coordinate"></param> /// <returns></returns> public static PointF CoordinateToPointF(this IProj self, ICoordinate coordinate) { PointF point = PointF.Empty; if (self != null && coordinate != null) { point = self.CoordinateToPointF(coordinate.X, coordinate.Y); } return(point); }
/// <summary> /// 将世界范围转为像素范围 /// </summary> /// <param name="self"></param> /// <param name="extent"></param> /// <returns></returns> public static Rectangle ExtentToRectangle(this IProj self, IExtent extent) { PointF topLeft = CoordinateToPointF(self, extent.MinX, extent.MaxY); PointF bottomRight = CoordinateToPointF(self, extent.MaxX, extent.MinY); int left = (int)topLeft.X; int top = (int)topLeft.Y; int right = (int)bottomRight.X; int bottom = (int)bottomRight.Y; return(new Rectangle(left, top, right - left, bottom - top)); }
/// <summary> /// Converts a single point location into an equivalent geographic coordinate /// </summary> /// <param name="self">This IProj</param> /// <param name="position">The client coordinate relative to the map control</param> /// <returns>The geographic ICoordinate interface</returns> public static Coordinate PixelToProj(this IProj self, Point position) { double x = Convert.ToDouble(position.X); double y = Convert.ToDouble(position.Y); if (self != null && self.GeographicExtents != null) { x = (x - self.ImageRectangle.X) * self.GeographicExtents.Width / self.ImageRectangle.Width + self.GeographicExtents.MinX; y = self.GeographicExtents.MaxY - (y - self.ImageRectangle.Y) * self.GeographicExtents.Height / self.ImageRectangle.Height; } return new Coordinate(x, y, 0.0); }
/// <summary> /// 像素坐标转世界坐标 /// </summary> /// <param name="self"></param> /// <param name="point"></param> /// <returns></returns> public static Coordinate PointFToCoordinate(this IProj self, PointF point) { Coordinate coordinate = null; if (self != null) { var ret = PointFToXY(self.Extent, self.Bound, point); coordinate = new Coordinate(ret.X, ret.Y); } return(coordinate); }
/// <summary> /// Converts a single geographic location into the equivalent point on the screen relative to the top left corner of the map. /// </summary> /// <param name="self">This IProj</param> /// <param name="location">The geographic position to transform</param> /// <returns>A Point with the new location.</returns> public static Point ProjToPixel(this IProj self, Coordinate location) { if (self.GeographicExtents.Width == 0 || self.GeographicExtents.Height == 0 || location == null) { return(Point.Empty); } double X = self.ImageRectangle.X + (location.X - self.GeographicExtents.MinX) * (self.ImageRectangle.Width / self.GeographicExtents.Width); double Y = self.ImageRectangle.Y + (self.GeographicExtents.MaxY - location.Y) * (self.ImageRectangle.Height / self.GeographicExtents.Height); // Custom handling of overflows : try to preserve ratio from screen coords (0;0), // so that a line starting from within screen and ending on that point would be displayed very close to // a line projected to "infinity", keeping correct orientation (since maxint is still above 2 billions, and result is in "pixels") if (X < -k_dMaxInt || X > k_dMaxInt || Y < -k_dMaxInt || Y > k_dMaxInt) { if (Math.Abs(X) > Math.Abs(Y)) { double dRatio = Y / X; if (X > 0) { X = k_dMaxInt; } else { X = -k_dMaxInt; } Y = Math.Round(X * dRatio); } else { double dRatio = X / Y; if (Y > 0) { Y = k_dMaxInt; } else { Y = -k_dMaxInt; } X = Math.Round(Y * dRatio); } } else { X = Math.Round(X); Y = Math.Round(Y); } return(new Point((int)X, (int)Y)); }
/// <summary> /// Converts a single point location into an equivalent geographic coordinate /// </summary> /// <param name="self">This IProj</param> /// <param name="position">The client coordinate relative to the map control</param> /// <returns>The geographic ICoordinate interface</returns> public static double[] PixelToProj(this IProj self, Point position) { double x = Convert.ToDouble(position.X); double y = Convert.ToDouble(position.Y); if (self != null && self.Envelope != null) { x = (x - self.Rectangle.X) * self.Envelope.Width() / self.Rectangle.Width + self.Envelope.MinX; y = self.Envelope.MaxY - (y - self.Rectangle.Y) * self.Envelope.Height() / self.Rectangle.Height; } return(new double[] { x, y }); }
/// <summary> /// 像素坐标转世界坐标 /// </summary> /// <param name="self"></param> /// <param name="point"></param> /// <returns></returns> public static (double X, double Y) PointFToXY(this IProj self, PointF point) { (double X, double Y)ret; if (self == null) { ret = (point.X, point.Y); } else { ret = PointFToXY(self.Extent, self.Bound, point); } return(ret); }
/// <summary> /// 像素范围转为世界范围 /// </summary> /// <param name="self"></param> /// <param name="rect"></param> /// <returns></returns> public static IExtent RectangleFToExtent(this IProj self, RectangleF rect) { var topLeft = self.PointFToXY(rect.X, rect.Y); var bottomRight = self.PointFToXY(rect.Right, rect.Bottom); return(new Extent() { MinX = topLeft.X, MinY = bottomRight.Y, MaxX = bottomRight.X, MaxY = topLeft.Y }); }
/// <summary> /// 像素坐标转世界坐标 /// </summary> /// <param name="self"></param> /// <param name="point"></param> /// <returns></returns> public static (double X, double Y) PointFToXY(this IProj self, float x, float y) { (double X, double Y)ret; if (self == null) { ret = (x, y); } else { ret = PointFToXY(self.Extent, self.Bound, x, y); } return(ret); }
/// <summary> /// Translates all of the geographic regions, forming an equivalent list of rectangles. /// </summary> /// <param name="self">This IProj</param> /// <param name="regions">The list of geographic regions to project</param> /// <returns>A list of pixel rectangles that describe the specified region</returns> public static List <Rectangle> ProjToPixel(this IProj self, List <Envelope> regions) { List <Rectangle> result = new List <Rectangle>(); foreach (Envelope region in regions) { if (region == null) { continue; } result.Add(ProjToPixel(self, region)); } return(result); }
/// <summary> /// Translates all of the geographic regions, forming an equivalent list of rectangles. /// </summary> /// <param name="self">This IProj</param> /// <param name="regions">The list of geographic regions to project</param> /// <returns>A list of pixel rectangles that describe the specified region</returns> public static List <Rectangle> ProjToPixel(this IProj self, List <IExtent> regions) { List <Rectangle> result = new List <Rectangle>(); foreach (var region in regions) { if (region == null) { continue; } result.Add(ExtentToRectangle(self, region)); } return(result); }
/// <summary> /// Converts a rectangle in pixel coordinates relative to the map control into /// a geographic envelope. /// </summary> /// <param name="self">This IProj</param> /// <param name="rect">The rectangle to convert</param> /// <returns>An IEnvelope interface</returns> public static Envelope PixelToProj(this IProj self, Rectangle rect) { Point tl = new Point(rect.X, rect.Y); Point br = new Point(rect.Right, rect.Bottom); var topLeft = PixelToProj(self, tl); var bottomRight = PixelToProj(self, br); return(new Envelope() { MinX = topLeft[0], MinY = bottomRight[1], MaxX = bottomRight[0], MaxY = topLeft[1] }); }
/// <summary> /// Converts a single geographic location into the equivalent point on the /// screen relative to the top left corner of the map. /// </summary> /// <param name="self">This IProj</param> /// <param name="location">The geographic position to transform</param> /// <returns>A Point with the new location.</returns> public static Point ProjToPixel(this IProj self, Coordinate location) { if (self.GeographicExtents.Width == 0 || self.GeographicExtents.Height == 0) return Point.Empty; try { int x = Convert.ToInt32(self.ImageRectangle.X + (location.X - self.GeographicExtents.MinX) * (self.ImageRectangle.Width / self.GeographicExtents.Width)); int y = Convert.ToInt32(self.ImageRectangle.Y + (self.GeographicExtents.MaxY - location.Y) * (self.ImageRectangle.Height / self.GeographicExtents.Height)); return new Point(x, y); } catch (OverflowException) { return Point.Empty; } }
/// <summary> /// Converts a single geographic location into the equivalent point on the screen relative to the top left corner of the map. /// </summary> /// <param name="self">This IProj</param> /// <param name="location">The geographic position to transform</param> /// <returns>A Point with the new location.</returns> public static Point ProjToPixelPoint(this IProj self, double[] location) { if (self.Envelope.Width() == 0 || self.Envelope.Height() == 0) { return(Point.Empty); } try { int x = Convert.ToInt32(self.Rectangle.X + (location[0] - self.Envelope.MinX) * (self.Rectangle.Width / self.Envelope.Width())); int y = Convert.ToInt32(self.Rectangle.Y + (self.Envelope.MaxY - location[1]) * (self.Rectangle.Height / self.Envelope.Height())); return(new Point(x, y)); } catch (OverflowException) { return(Point.Empty); } }
/// <summary> /// Draws a LineString. /// </summary> /// <param name="g"></param> /// <param name="p"></param> /// <param name="pens"></param> /// <param name="bls"></param> internal static void DrawLineString(Graphics g, IProj p, List <Pen> pens, IBasicLineString bls) { // Even if an entire multi-linestring is in view, entire parts may be outside the view if (bls.Envelope.Intersects(p.GeographicExtents.ToEnvelope()) == false) { return; } // get the coordinates once and cache them, because some data types have to create the array. IList <Coordinate> clist = bls.Coordinates; int count = clist.Count; Point[] points = new Point[count]; for (int i = 0; i < count; i++) { points[i] = p.ProjToPixel(clist[i]); } foreach (Pen currentPen in pens) { g.DrawLines(currentPen, points); } }
/// <summary> /// Calculates an integer length distance in pixels that corresponds to the double length specified in the image. /// </summary> /// <param name="self">The IProj that this describes</param> /// <param name="distance">The double distance to obtain in pixels</param> /// <returns>The integer distance in pixels</returns> public static double ProjToPixel(this IProj self, double distance) { return(distance * self.Rectangle.Width / self.Envelope.Width()); }
private static Rectangle ComputeClippingRectangle(IProj args) { const int maxSymbologyFuzz = 50; var clipRect = new Rectangle(args.ImageRectangle.Location.X, args.ImageRectangle.Location.Y, args.ImageRectangle.Width, args.ImageRectangle.Height); clipRect.Inflate(maxSymbologyFuzz, maxSymbologyFuzz); return clipRect; }
/// <summary> /// Draws some section of the extent to the specified graphics object. /// </summary> /// <param name="g">The graphics object to draw to.</param> /// <param name="p">The projection interface that specifies how to transform geographic coordinates to an image.</param> public override void DrawSnapShot(Graphics g, IProj p) { // First pass is the "border" which actually fills things in, but then will be painted over with the fill. throw new NotImplementedException(); //bool TO_DO_Draw_LINE_SNAPSHOT = true; }
/// <summary> /// Draws a LineString. /// </summary> /// <param name="g"></param> /// <param name="p"></param> /// <param name="pens"></param> /// <param name="bls"></param> internal static void DrawLineString(Graphics g, IProj p, List<Pen> pens, IBasicLineString bls) { // Even if an entire multi-linestring is in view, entire parts may be outside the view if (bls.Envelope.Intersects(p.GeographicExtents.ToEnvelope()) == false) return; // get the coordinates once and cache them, because some data types have to create the array. IList<Coordinate> clist = bls.Coordinates; int count = clist.Count; Point[] points = new Point[count]; for (int i = 0; i < count; i++) { points[i] = p.ProjToPixel(clist[i]); } foreach (Pen currentPen in pens) { g.DrawLines(currentPen, points); } }
/// <summary> /// Calculates an integer length distance in pixels that corresponds to the double length specified in the image. /// </summary> /// <param name="self">The IProj that this describes</param> /// <param name="distance">The double distance to obtain in pixels</param> /// <returns>The integer distance in pixels</returns> public static double ProjToPixel(this IProj self, double distance) { return(distance * self.Bound.Width / self.Extent.Width); }
private static Bitmap GetSymbolizerBitmap(IPointSymbolizer symbolizer, IProj e) { if (symbolizer == null) return null; var scaleSize = symbolizer.GetScale(e); var size = symbolizer.GetSize(); if (size.Width * scaleSize < 1 || size.Height * scaleSize < 1) return null; var bitmap = new Bitmap((int)(size.Width * scaleSize) + 1, (int)(size.Height * scaleSize) + 1); var bg = Graphics.FromImage(bitmap); bg.SmoothingMode = symbolizer.Smoothing ? SmoothingMode.AntiAlias : SmoothingMode.None; var trans = bg.Transform; // keenedge: // added ' * scaleSize ' to fix a problme when ploted using ScaleMode=Geographic. however, it still // appeared to be shifted up and left by 1 pixel so I also added the one pixel shift to the NW. trans.Translate(((float)(size.Width * scaleSize) / 2 - 1), (float)(size.Height * scaleSize) / 2 - 1); bg.Transform = trans; symbolizer.Draw(bg, 1); return bitmap; }
/// <summary> /// Draws some section of the extent to the specified graphics object. /// </summary> /// <param name="g">The graphics object to draw to.</param> /// <param name="p">The projection interface that specifies how to transform geographic coordinates to an image.</param> public override void DrawSnapShot(Graphics g, IProj p) { //bool To_DO_DRaw_Polygon_Snapshot = true; throw new NotImplementedException(); }
/// <summary> /// This method actaully draws the image to the snapshot using the graphics object. This should be overridden in /// sub-classes because the drawing methods are very different. /// </summary> /// <param name="g">A graphics object to draw to</param> /// <param name="p">A projection handling interface designed to translate geographic coordinates to screen coordinates</param> public virtual void DrawSnapShot(Graphics g, IProj p) { throw new NotImplementedException("This should be overridden in sub-classes"); }
/// <summary> /// Draws some section of the extent to the specified graphics object. /// </summary> /// <param name="g">The graphics object to draw to.</param> /// <param name="p">The projection interface that specifies how to transform geographic coordinates to an image.</param> public override void DrawSnapShot(Graphics g, IProj p) { // bool To_DO_DRaw_Polygon_Snapshot = true; throw new NotImplementedException(); }
/// <summary> /// Handles drawing point images to the graphics object. The extent handling should be already figured out /// by using the projection interface. /// </summary> /// <param name="g">The Graphics object to draw to.</param> /// <param name="p">The projection tool that specifies how geographic coordinates should transform to visual coordinates.</param> public override void DrawSnapShot(Graphics g, IProj p) { //IFeatureList fList = this.DataSet.Features; //double dX = Symbolizer.GeographicSize.XSize / 2; //double dY = Symbolizer.GeographicSize.YSize / 2; //Rectangle r = p.ImageRectangle; //if (Symbolizer.ScaleMode != ScaleModes.Geographic) //{ // System.Drawing.Point center = new System.Drawing.Point(r.Left + r.Width / 2, r.Top + r.Height / 2); // int offsetX = Convert.ToInt32(center.X + Symbolizer.SymbolSize.Width); // int offsetY = Convert.ToInt32(center.Y + Symbolizer.SymbolSize.Height); // System.Drawing.Point offset = new System.Drawing.Point(offsetX, offsetY); // ICoordinate c = p.PixelToProj(center); // ICoordinate cOffset = p.PixelToProj(offset); // dX = (cOffset.X - c.X) / 2; // dY = (cOffset.Y - c.Y) / 2; //} //Bitmap symbol = new Bitmap(Symbolizer.PixelSize.Width, Symbolizer.PixelSize.Height); //Rectangle symbolRect = new Rectangle(0, 0, Symbolizer.PixelSize.Width, Symbolizer.PixelSize.Height); //Graphics symbolG = Graphics.FromImage(symbol); //Symbolizer.Draw(symbolG, symbolRect); //symbolG.Dispose(); //IEnvelope env = p.GeographicExtents.Copy(); //env.ExpandBy(dX, dY); // expand the envelope so we don't accidentally crop off points just outside the envelope. //foreach (IFeature feature in fList) //{ // ICoordinate[] coords = feature.BasicGeometry.Coordinates; // foreach (ICoordinate center in coords) // { // if (env.Contains(center) == false) continue; // don't try to draw points where no part falls in the image // Envelope imageBounds = new Envelope(center.X - dX, center.X + dX, center.Y - dY, center.Y + dY); // Rectangle imageRect = p.ProjToPixel(imageBounds); // g.DrawImage(symbol, imageRect); // } //} }
/// <summary> /// Calculates an integer length distance in pixels that corresponds to the double /// length specified in the image. /// </summary> /// <param name="self">The IProj that this describes</param> /// <param name="distance">The double distance to obtain in pixels</param> /// <returns>The integer distance in pixels</returns> public static double ProjToPixel(this IProj self, double distance) { return(distance * self.ImageRectangle.Width / self.GeographicExtents.Width); }
private static Rectangle ComputeClippingRectangle(IProj args, ILineSymbolizer ls) { // Compute a clipping rectangle that accounts for symbology int maxLineWidth = 2 * (int)Math.Ceiling(ls.GetWidth()); var clipRect = new Rectangle(args.ImageRectangle.Location.X, args.ImageRectangle.Location.Y, args.ImageRectangle.Width, args.ImageRectangle.Height); clipRect.Inflate(maxLineWidth, maxLineWidth); return clipRect; }
/// <summary> /// This method actually draws the image to the snapshot using the graphics object. This should be /// overridden in sub-classes because the drawing methods are very different. /// </summary> /// <param name="g"> /// A graphics object to draw to /// </param> /// <param name="p"> /// A projection handling interface designed to translate /// geographic coordinates to screen coordinates /// </param> public virtual void DrawSnapShot(Graphics g, IProj p) { // Overridden in subclasses }
/// <summary> /// Draws some section of the extent to the specified graphics object. /// </summary> /// <param name="g">The graphics object to draw to.</param> /// <param name="p">The projection interface that specifies how to transform geographic coordinates to an image.</param> public override void DrawSnapShot(Graphics g, IProj p) { bool To_DO_DRaw_Polygon_Snapshot = true; }