public override void PutOnMap(IDrawingSurface tileSet, ITile iTile, IObjectsLayoutManager olm) { base.PutOnMap(tileSet, iTile, olm); m_pixelLocationBottomLeft = tileSet.toPixelLocation(new GeoCoord(m_geoTiff.BottomLeftLng, m_geoTiff.BottomLeftLat), iTile); m_pixelLocationTopRight = tileSet.toPixelLocation(new GeoCoord(m_geoTiff.TopRightLng, m_geoTiff.TopRightLat), iTile); m_pixelLocationBottomRight = tileSet.toPixelLocation(new GeoCoord(m_geoTiff.BottomRightLng, m_geoTiff.BottomRightLat), iTile); boundingRect(); // make sure we have current values there }
public virtual void PutOnMap(IDrawingSurface map, ITile iTile, IObjectsLayoutManager iOlm) { m_map = map; m_itile = iTile; m_olm = iOlm; // can be null m_pixelLocation = map.toPixelLocation(m_location, iTile); }
public override void Paint(Graphics graphics, IDrawingSurface tileSet, ITile iTile) { if (!m_enabled) { return; } Point pLoc = tileSet.toPixelLocation(Location, iTile); //LibSys.StatusBar.Trace("VehicleGps::Paint() - " + Location + " - " + m_doName + m_labelBoundingRect); Font font = Project.getLabelFont(m_fontSize); int xx = m_labelBoundingRect.X - 3; int yy = m_labelBoundingRect.Y - 1; //string label = "" + m_labelPosition + " " + Name; string label = Name; if (Project.vehicleUseShadow) { graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx, yy); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx + 2, yy); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx, yy - 2); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx + 2, yy - 2); } graphics.DrawString(label, font, Project.vehicleFontBrush, xx + 1, yy - 1); if (Image == null) { graphics.DrawEllipse(Project.vehiclePen, m_pixelLocation.X - MIN_VEH_PIXEL_RADIUS + 2, m_pixelLocation.Y - MIN_VEH_PIXEL_RADIUS + 2, MIN_VEH_PIXEL_RADIUS * 2 - 4, MIN_VEH_PIXEL_RADIUS * 2 - 4); graphics.FillEllipse(Project.vehicleBrush, m_pixelLocation.X - 2, m_pixelLocation.Y - 2, 4, 4); } else { // assume the center of the image is hotpoint: graphics.DrawImage(Image, m_pixelLocation.X - Image.Width / 2, m_pixelLocation.Y - Image.Height / 2); graphics.DrawEllipse(Project.vehiclePen, m_pixelLocation.X - 2, m_pixelLocation.Y - 2, 4, 4); } if (arrowPoints != null) { graphics.FillPolygon(brushVelocity, arrowPoints); graphics.DrawLine(penVelocity, new Point(m_pixelLocation.X, m_pixelLocation.Y), arrowPoints[0]); } // debug only: // graphics.DrawRectangle(Project.debugPen, m_boundingRect); // graphics.DrawRectangle(Project.debug2Pen, m_imageBoundingRect); // graphics.DrawRectangle(Project.debug3Pen, m_labelBoundingRect); }
public override void Paint(Graphics graphics, IDrawingSurface tileSet, ITile iTile, int offsetX, int offsetY) { if (!m_enabled) { return; } //LibSys.StatusBar.Trace("Paint(): Place: - " + Location + " - " + Name); Point pLoc = tileSet.toPixelLocation(Location, iTile); int toffsetX = iTile.getOffset().X; Rectangle r = m_imageBoundingRect; r.Offset(toffsetX, 0); Font font = Project.getLabelFont(m_fontSize); if (m_doName) { int xx = m_labelBoundingRect.X - 3 + toffsetX + offsetX; int yy = m_labelBoundingRect.Y - 1 + offsetY; //string label = "" + m_labelPosition + Name; string label = Name; if (m_doDrawShadow) { graphics.DrawString(label, font, m_labelShadowBrush, xx, yy); graphics.DrawString(label, font, m_labelShadowBrush, xx + 2, yy); graphics.DrawString(label, font, m_labelShadowBrush, xx, yy - 2); graphics.DrawString(label, font, m_labelShadowBrush, xx + 2, yy - 2); } graphics.DrawString(label, font, m_labelBrush, xx + 1, yy - 1); } if (m_doDrawPoint) { if (m_doDrawShadow) { graphics.DrawEllipse(m_shadowPen, r.X + 3 + offsetX, r.Y + 3 + offsetY, r.Width - 5, r.Height - 5); graphics.DrawEllipse(m_shadowPen, r.X + 1 + offsetX, r.Y + 1 + offsetY, r.Width - 2, r.Height - 2); } graphics.DrawEllipse(m_pen, r.X + 2 + offsetX, r.Y + 2 + offsetY, r.Width - 4, r.Height - 4); } // debug only: // graphics.DrawRectangle(Project.debugPen, m_boundingRect); // graphics.DrawRectangle(Project.debug2Pen, m_imageBoundingRect); // graphics.DrawRectangle(Project.debug3Pen, m_labelBoundingRect); }
public override void Paint(Graphics graphics, IDrawingSurface tileSet, ITile iTile, int offsetX, int offsetY) { if (!m_enabled) { return; } Point pLoc = tileSet.toPixelLocation(Location, iTile); //LibSys.StatusBar.Trace("Vehicle::Paint() - " + Location + " - " + m_doName + m_labelBoundingRect); Rectangle r = m_imageBoundingRect; Font font = Project.getLabelFont(m_fontSize); int xx = m_labelBoundingRect.X - 3; int yy = m_labelBoundingRect.Y - 1; //string label = "" + m_labelPosition + Name; string label = Name; if (Project.vehicleUseShadow) { graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx, yy); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx + 2, yy); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx, yy - 2); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx + 2, yy - 2); } graphics.DrawString(label, font, Project.vehicleFontBrush, xx + 1, yy - 1); if (m_image == null) { graphics.DrawEllipse(Project.vehiclePen, r.X + 2, r.Y + 2, r.Width - 4, r.Height - 4); } else { graphics.DrawImage(m_image, r.X, r.Y); } // debug only: // graphics.DrawRectangle(Project.debugPen, m_boundingRect); // graphics.DrawRectangle(Project.debug2Pen, m_imageBoundingRect); // graphics.DrawRectangle(Project.debug3Pen, m_labelBoundingRect); }
// for the LiveMap:isRelevant() method // we need to know how important/big the waypoint representation is on the map without // instantiating the visial object. So, we use static method here. public static Rectangle boundingRectEstimate(IDrawingSurface map, LabeledPoint wp) { Point pPoint; try { pPoint = map.toPixelLocation(wp.Location, null); } catch (Exception e) { return(Rectangle.Empty); } int w = wp.imageSizeByType(wp.LiveObjectType); int h = w; Rectangle re = new Rectangle(pPoint.X - w, pPoint.Y - h, w * 2, h * 2); return(re); }
// for the LiveMap:isRelevant() method // we need to know how big the earthquake is on the map without // instantiating the visial object. So, we use static method here. public static Rectangle boundingRectEstimate(IDrawingSurface map, Earthquake eq, double magnFactor) { Point pPoint; try { pPoint = map.toPixelLocation(eq.Location, null); } catch (Exception e) { return Rectangle.Empty; } int w, h; int minSize = 15; int maxSize = 300; int xFactor = 2; int yFactor = 2; int yExtra = 0; double xMetersPerPixel = map.xMetersPerPixel(); w = (int)(eq.Magn * magnFactor / map.xMetersPerPixel()); if(w < minSize) // we don't want the quake to show up too small or too big { w = minSize; } if(w > maxSize) { w = maxSize; } h = (int)(eq.Magn * magnFactor / map.yMetersPerPixel()); if(h < minSize) { h = minSize; } if(h > maxSize) { h = maxSize; } double cameraElevationKm = map.getCameraElevation() / 1000.0d; switch (Project.earthquakeStyle) { default: case STYLE_CONCENTRICCIRCLES: // concentric circles case STYLE_SQUARES: case STYLE_FILLSQUARES: case STYLE_CIRCLES: case STYLE_FILLCIRCLES: // filled circles Alan Jones "Seismic Eruptions" style { double magMin; double magOff; double magFact; if(cameraElevationKm > 4000.0d) // world map { magMin = 5.0d; magOff = 4.5d; magFact = 7.0d; } else if(cameraElevationKm > 900.0d) { // small scale magMin = 4.0d; magOff = 2.5d; magFact = 6.0d; } else if(cameraElevationKm > 370.0d) { // medium scale magMin = 2.0d; magOff = 0.5d; magFact = 5.0d; } else { // very large scale magMin = 1.0d; magOff = 0.5d; magFact = 4.0d; } if(eq.Magn <= magMin) { w = 3; h = 3; } else { w = h = (int)((eq.Magn - magOff) * magFact); } } break; case STYLE_TRIANGLE: // triangle pointing down to epicenter; the deeper the quake, // the more narrow the triangle is: h = (int)(((double)h) * (1.0d + cameraElevationKm / 10000.0d)); // make them more visible on small scale maps: w = eq.calcTriWidth(h) * 2; // triWidth is actually half of the upper side of the triangle. if(w < 50 && Project.displayEqDepth) { w = 50; } yFactor = 1; xFactor = 1; yExtra = 3; // 3 pixels for the epicenter oval break; case STYLE_DOT: // dot w = 3; h = 3; break; } Rectangle re = new Rectangle(pPoint.X-(w*xFactor/2), pPoint.Y-h, w*xFactor, h*yFactor + yExtra); return re; }
public override void Paint(Graphics graphics, IDrawingSurface tileSet, ITile iTile, int offsetX, int offsetY) { if(!m_enabled) { return; } Point pLoc = tileSet.toPixelLocation(Location, iTile); //LibSys.StatusBar.Trace("Vehicle::Paint() - " + Location + " - " + m_doName + m_labelBoundingRect); Rectangle r = m_imageBoundingRect; Font font = Project.getLabelFont(m_fontSize); int xx = m_labelBoundingRect.X - 3; int yy = m_labelBoundingRect.Y - 1; //string label = "" + m_labelPosition + Name; string label = Name; if(Project.vehicleUseShadow) { graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx, yy); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx+2, yy); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx, yy-2); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx+2, yy-2); } graphics.DrawString(label, font, Project.vehicleFontBrush, xx+1, yy-1); if(m_image == null) { graphics.DrawEllipse(Project.vehiclePen, r.X+2, r.Y+2, r.Width-4, r.Height-4); } else { graphics.DrawImage(m_image, r.X, r.Y); } // debug only: // graphics.DrawRectangle(Project.debugPen, m_boundingRect); // graphics.DrawRectangle(Project.debug2Pen, m_imageBoundingRect); // graphics.DrawRectangle(Project.debug3Pen, m_labelBoundingRect); }
public Rectangle thumbBoundingRect(IDrawingSurface map) { if(this.ThumbImage == null) { return Rectangle.Empty; } try { Point pPoint = map.toPixelLocation(this.Location, null); int width = this.ThumbImage.Width; int height = this.ThumbImage.Height; Rectangle re; switch(this.ThumbPosition) { case 0: // top right re = new Rectangle(pPoint.X, pPoint.Y-height, width, height); break; case 1: // center default: re = new Rectangle(pPoint.X-width/2, pPoint.Y-height/2, width, height); break; } return re; } catch { return Rectangle.Empty; } }
// for the LiveMap:isRelevant() method // we need to know how big the earthquake is on the map without // instantiating the visial object. So, we use static method here. public static Rectangle boundingRectEstimate(IDrawingSurface map, Earthquake eq, double magnFactor) { Point pPoint; try { pPoint = map.toPixelLocation(eq.Location, null); } catch (Exception e) { return(Rectangle.Empty); } int w, h; int minSize = 15; int maxSize = 300; int xFactor = 2; int yFactor = 2; int yExtra = 0; double xMetersPerPixel = map.xMetersPerPixel(); w = (int)(eq.Magn * magnFactor / map.xMetersPerPixel()); if (w < minSize) // we don't want the quake to show up too small or too big { w = minSize; } if (w > maxSize) { w = maxSize; } h = (int)(eq.Magn * magnFactor / map.yMetersPerPixel()); if (h < minSize) { h = minSize; } if (h > maxSize) { h = maxSize; } double cameraElevationKm = map.getCameraElevation() / 1000.0d; switch (Project.earthquakeStyle) { default: case STYLE_CONCENTRICCIRCLES: // concentric circles case STYLE_SQUARES: case STYLE_FILLSQUARES: case STYLE_CIRCLES: case STYLE_FILLCIRCLES: // filled circles Alan Jones "Seismic Eruptions" style { double magMin; double magOff; double magFact; if (cameraElevationKm > 4000.0d) // world map { magMin = 5.0d; magOff = 4.5d; magFact = 7.0d; } else if (cameraElevationKm > 900.0d) { // small scale magMin = 4.0d; magOff = 2.5d; magFact = 6.0d; } else if (cameraElevationKm > 370.0d) { // medium scale magMin = 2.0d; magOff = 0.5d; magFact = 5.0d; } else { // very large scale magMin = 1.0d; magOff = 0.5d; magFact = 4.0d; } if (eq.Magn <= magMin) { w = 3; h = 3; } else { w = h = (int)((eq.Magn - magOff) * magFact); } } break; case STYLE_TRIANGLE: // triangle pointing down to epicenter; the deeper the quake, // the more narrow the triangle is: h = (int)(((double)h) * (1.0d + cameraElevationKm / 10000.0d)); // make them more visible on small scale maps: w = eq.calcTriWidth(h) * 2; // triWidth is actually half of the upper side of the triangle. if (w < 50 && Project.displayEqDepth) { w = 50; } yFactor = 1; xFactor = 1; yExtra = 3; // 3 pixels for the epicenter oval break; case STYLE_DOT: // dot w = 3; h = 3; break; } Rectangle re = new Rectangle(pPoint.X - (w * xFactor / 2), pPoint.Y - h, w * xFactor, h * yFactor + yExtra); return(re); }
public void Paint(Graphics graphics, IDrawingSurface layer, ITile iTile, bool isPrint) { if (!m_enabled) { return; } //LibSys.StatusBar.Trace("Track::Paint() - " + m_trackpoints.Count + " : " + Name); int prevX = 0; int prevY = 0; int arrowWingsTrk = Math.Max(15, (int)(7.0f * TrackPalette.penTrackThickness)); int arrowWingsRte = Math.Max(18, (int)(9.0f * TrackPalette.penRouteThickness)); float trackThicknessFactor = TrackPalette.penTrackThickness / 2.0f; Pen penHighlight = new Pen(Color.Red, 3.0f * trackThicknessFactor); Pen penHighlight2 = new Pen(Color.Yellow, 3.0f * trackThicknessFactor); int diam = (int)Math.Ceiling(4.0f * trackThicknessFactor); int rad = diam / 2; Waypoint _lastHighlightedWaypoint = null; int step = getStep(this, layer.getCameraElevation()); bool doDrawPoints = Project.drawTrackpoints && (layer.getCameraElevation() < DRAW_POINT_TRESHOLD); int pointCount = 0; int lastArrowCount = 0; // Point tailPoint = Point.Empty; Point lastArrowPoint = Point.Empty; // prepare default brushes/pens, with either random or preset color: Brush trkBrush = getBrush(); // filled circles, arrow heads Pen trkPen = getTrackPen(); // lines Pen rtePen = getRoutePen(); // lines Pen rteTrkPen; // square (flat) Cap is a pain in neck; this kind of works: GraphicsPath objPath = new GraphicsPath(); // objPath.AddRectangle(new Rectangle(0, -1, 0, 0)); CustomLineCap squareCap = new System.Drawing.Drawing2D.CustomLineCap(objPath, null, LineCap.Flat); squareCap.WidthScale = 0.0f; bool skipOne; for (int i = 0; i < m_trackpoints.Count; i += step) { skipOne = false; try { Waypoint wp1 = (Waypoint)m_trackpoints.GetByIndex(i); bool doDrawThisPoint = doDrawPoints; if (wp1.ThumbImage != null) { skipOne = true; // draw and move to next trackpoint; keep in sync with the stepping logic } pointCount++; Waypoint wp2 = null; if (i != m_trackpoints.Count - 1 && (i + step) < m_trackpoints.Count) // last point { wp2 = (Waypoint)m_trackpoints.GetByIndex(i + step); } if (!layer.insideScreenRectangle(wp1.Location) && wp2 != null && !layer.insideScreenRectangle(wp2.Location)) { goto nextLoop; } Point p1 = isPrint ? layer.toPixelLocationPrint(wp1.Location, iTile) : layer.toPixelLocation(wp1.Location, iTile); // if(tailPoint.IsEmpty) // { // tailPoint = p1; // } int dd = diam; bool staying = false; bool doHighlight = false; bool hasContent = wp1.hasContent; bool hasUrl = wp1.Url != null && wp1.Url.Length > 0; string stayLbl = ""; if (TimeFilter.Enabled) { doHighlight = TimeFilter.passes(wp1.DateTime); if (!doHighlight && TimeFilter.beforeFrom(wp1.DateTime)) { // in case it doesn't pass directly, but we are in the middle of the track // and the time filter boundaries are between this point and next point, // we highlight both points because we are sitting there at this time. if (i > 0 && wp2 != null) // mid-track { if (TimeFilter.afterTo(wp2.DateTime)) { doHighlight = true; dd *= 3; staying = true; DateTime wp2LocalTime = Project.zuluToLocal(wp2.DateTime); stayLbl = "staying till " + wp2LocalTime.TimeOfDay; } } } } if (SelectFilter.Enabled) { doHighlight = SelectFilter.passes(wp1); dd = 2; } if (doHighlight) { if (_lastHighlightedWaypoint == null) { _lastHighlightedWaypoint = wp1; } graphics.DrawEllipse(penHighlight, p1.X - dd, p1.Y - dd, dd * 2, dd * 2); if (staying) { int x = p1.X + 10; int y = p1.Y - dd * 2; Font font = Project.getLabelFont(Project.FONT_SIZE_REGULAR + 2); if (Project.waypointUseShadow) { graphics.DrawString(stayLbl, font, Project.blackBrush, x, y); graphics.DrawString(stayLbl, font, Project.blackBrush, x + 2, y); graphics.DrawString(stayLbl, font, Project.blackBrush, x, y - 2); graphics.DrawString(stayLbl, font, Project.blackBrush, x + 2, y - 2); } graphics.DrawString(stayLbl, font, Project.whiteBrush, x + 1, y - 1); } } if (hasUrl) { graphics.DrawEllipse(penHighlight2, p1.X - 4, p1.Y - 4, 8, 8); } if (hasContent) { if (!hasUrl) { graphics.DrawEllipse(Pens.Cyan, p1.X - 4, p1.Y - 4, 8, 8); } graphics.DrawEllipse(penHighlight, p1.X - 2, p1.Y - 2, 4, 4); } if (hasUrl || hasContent || (wp2 == null && (i == 0 || !Project.makeRouteMode))) // last point { int offsetX = 0; int offsetY = 0; if (isPrint) { Point pixelPosPrint = layer.toPixelLocationPrint(wp1.Location, null); Point pixelPosDispl = wp1.PixelLocation; offsetX = pixelPosPrint.X - pixelPosDispl.X; offsetY = pixelPosPrint.Y - pixelPosDispl.Y; } wp1.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY); } if (wp2 != null) // not the last point { Point p2 = isPrint ? layer.toPixelLocationPrint(wp2.Location, iTile) : layer.toPixelLocation(wp2.Location, iTile); bool thickPen = false; if (m_isRoute) { rteTrkPen = rtePen; } else { if (Project.trackElevColor) { double elevRange = ElevMax - ElevMin; if (elevRange > 1.0d && elevRange < 20000.0d) { double elevFactor = elevRange / 256.0d; double elev = wp2.Location.Elev; int r = (int)((elev - ElevMin) / elevFactor); if (r > 255) { r = 255; } int b = 255 - r; int g = (255 - (r > b ? r : b)) * 2; // will be high where R and B are close to equal, amounts to cyan Color legColor = Color.FromArgb(r, g, b); trkBrush = new SolidBrush(legColor); trkPen = new Pen(trkBrush, (r > 250 ? 5.0f : 3.0f) * trackThicknessFactor); thickPen = true; } } else if (Project.trackSpeedColor) { double speedRange = SpeedMax - SpeedMin; if (speedRange > 1000.0d && speedRange < 1000000000.0d) { double speedFactor = speedRange / 256.0d; double speed = wp2.Speed; int r = (int)((speed - SpeedMin) / speedFactor); if (r > 255) { r = 255; } int b = 255 - r; int g = (255 - (r > b ? r : b)) * 2; // will be high where R and B are close to equal, amounts to cyan Color legColor = Color.FromArgb(r, g, b); trkBrush = new SolidBrush(legColor); trkPen = new Pen(trkBrush, (r > 250 ? 5.0f : 3.0f) * trackThicknessFactor); thickPen = true; } } rteTrkPen = doHighlight ? penHighlight : trkPen; } int dltaX = p2.X - p1.X; int dltaY = p2.Y - p1.Y; double lenSq = dltaX * dltaX + dltaY * dltaY; int dlta2X = p2.X - lastArrowPoint.X; int dlta2Y = p2.Y - lastArrowPoint.Y; double lenSq2 = dlta2X * dlta2X + dlta2Y * dlta2Y; if (lenSq2 > 10000.0d || lenSq > 900.0d) // big enough to hold arrow? { float arrowWidth = thickPen ? 4 : 3; float arrowHeight = 6; bool arrowFill = true; rteTrkPen.CustomEndCap = new AdjustableArrowCap(arrowWidth, arrowHeight, arrowFill); lastArrowCount = pointCount; lastArrowPoint = p2; // tailPoint = p2; //doDrawThisPoint = false; } else { // no cap - null doesn't work here rteTrkPen.CustomEndCap = squareCap; } graphics.DrawLine(rteTrkPen, p1, p2); if (doDrawThisPoint && diam > 2) { graphics.FillEllipse(trkBrush, p2.X - rad, p2.Y - rad, diam, diam); } if (i == 0) { int offsetX = 0; int offsetY = 0; if (isPrint) { Point pixelPosPrint = layer.toPixelLocationPrint(wp1.Location, null); Point pixelPosDispl = wp1.PixelLocation; offsetX = pixelPosPrint.X - pixelPosDispl.X; offsetY = pixelPosPrint.Y - pixelPosDispl.Y; } wp1.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY); prevX = p1.X; prevY = p1.Y; } else if ((p1.X - prevX) * (p1.X - prevX) + (p1.Y - prevY) * (p1.Y - prevY) > 900) { if (Project.showTrackpointNumbers) { // call simplified PaintLabel, not regular one: PaintLabel(graphics, wp1.Name, p1.X, p1.Y, isPrint); } prevX = p1.X; prevY = p1.Y; } } else if (doDrawThisPoint) { graphics.FillEllipse(trkBrush, p1.X - rad, p1.Y - rad, diam, diam); } } catch (Exception e) { LibSys.StatusBar.Error("Track::Paint() - " + e.Message); } nextLoop: if (skipOne) { i -= (step - 1); // move to the next trackpoint continue; } int pointsLeft = m_trackpoints.Count - i; if (pointsLeft > 1 && pointsLeft < step) { step = pointsLeft - 2; if (step < 1) { step = 1; } } } if (Project.thumbDoDisplay) { SortedList ppts = Project.mainCommand.getWaypointsWithThumbs(m_id); for (int i = 0; i < ppts.Count; i++) { Waypoint wpt = (Waypoint)ppts.GetByIndex(i); Pen thumbBorderPen = Pens.Blue; Pen thumbCornerPen = new Pen(Color.Blue, 3.0f); int width = wpt.ThumbImage.Width; int height = wpt.ThumbImage.Height; Point p1 = isPrint ? layer.toPixelLocationPrint(wpt.Location, iTile) : layer.toPixelLocation(wpt.Location, iTile); switch (wpt.ThumbPosition) { case 0: // top right graphics.DrawImage(wpt.ThumbImage, p1.X, p1.Y - height, width, height); graphics.DrawRectangle(thumbBorderPen, p1.X, p1.Y - height, width - 1, height - 1); graphics.DrawLine(thumbCornerPen, p1.X + 2, p1.Y, p1.X + 2, p1.Y - 10); graphics.DrawLine(thumbCornerPen, p1.X, p1.Y - 2, p1.X + 10, p1.Y - 2); break; case 1: // center default: graphics.DrawImage(wpt.ThumbImage, p1.X - width / 2, p1.Y - height / 2, width, height); graphics.DrawRectangle(thumbBorderPen, p1.X - width / 2, p1.Y - height / 2, width - 1, height - 1); break; } int offsetX = 0; int offsetY = 0; if (isPrint) { Point pixelPosPrint = layer.toPixelLocationPrint(wpt.Location, null); Point pixelPosDispl = wpt.PixelLocation; offsetX = pixelPosPrint.X - pixelPosDispl.X; offsetY = pixelPosPrint.Y - pixelPosDispl.Y; } wpt.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY); } } if (_lastHighlightedWaypoint != null) { lastHighlightedWaypoint = _lastHighlightedWaypoint; } }
public override void Paint(Graphics graphics, IDrawingSurface tileSet, ITile iTile) { if(!m_enabled) { return; } Point pLoc = tileSet.toPixelLocation(Location, iTile); //LibSys.StatusBar.Trace("VehicleGps::Paint() - " + Location + " - " + m_doName + m_labelBoundingRect); Font font = Project.getLabelFont(m_fontSize); int xx = m_labelBoundingRect.X - 3; int yy = m_labelBoundingRect.Y - 1; //string label = "" + m_labelPosition + " " + Name; string label = Name; if(Project.vehicleUseShadow) { graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx, yy); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx+2, yy); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx, yy-2); graphics.DrawString(label, font, Project.vehicleBackgroundBrush, xx+2, yy-2); } graphics.DrawString(label, font, Project.vehicleFontBrush, xx+1, yy-1); if(Image == null) { graphics.DrawEllipse(Project.vehiclePen, m_pixelLocation.X-MIN_VEH_PIXEL_RADIUS+2, m_pixelLocation.Y-MIN_VEH_PIXEL_RADIUS+2, MIN_VEH_PIXEL_RADIUS*2-4, MIN_VEH_PIXEL_RADIUS*2-4); graphics.FillEllipse(Project.vehicleBrush, m_pixelLocation.X-2, m_pixelLocation.Y-2, 4, 4); } else { // assume the center of the image is hotpoint: graphics.DrawImage(Image, m_pixelLocation.X-Image.Width/2, m_pixelLocation.Y-Image.Height/2); graphics.DrawEllipse(Project.vehiclePen, m_pixelLocation.X-2, m_pixelLocation.Y-2, 4, 4); } if(arrowPoints != null) { graphics.FillPolygon(brushVelocity, arrowPoints); graphics.DrawLine(penVelocity, new Point(m_pixelLocation.X, m_pixelLocation.Y), arrowPoints[0]); } // debug only: // graphics.DrawRectangle(Project.debugPen, m_boundingRect); // graphics.DrawRectangle(Project.debug2Pen, m_imageBoundingRect); // graphics.DrawRectangle(Project.debug3Pen, m_labelBoundingRect); }
public void Paint(Graphics graphics, IDrawingSurface layer, ITile iTile, bool isPrint) { if(!m_enabled) { return; } //LibSys.StatusBar.Trace("Track::Paint() - " + m_trackpoints.Count + " : " + Name); int prevX = 0; int prevY = 0; int arrowWingsTrk = Math.Max(15, (int)(7.0f * TrackPalette.penTrackThickness)); int arrowWingsRte = Math.Max(18, (int)(9.0f * TrackPalette.penRouteThickness)); float trackThicknessFactor = TrackPalette.penTrackThickness / 2.0f; Pen penHighlight = new Pen(Color.Red, 3.0f * trackThicknessFactor); Pen penHighlight2 = new Pen(Color.Yellow, 3.0f * trackThicknessFactor); int diam = (int)Math.Ceiling(4.0f * trackThicknessFactor); int rad = diam/2; Waypoint _lastHighlightedWaypoint = null; int step = getStep(this, layer.getCameraElevation()); bool doDrawPoints = Project.drawTrackpoints && (layer.getCameraElevation() < DRAW_POINT_TRESHOLD); int pointCount = 0; int lastArrowCount = 0; // Point tailPoint = Point.Empty; Point lastArrowPoint = Point.Empty; // prepare default brushes/pens, with either random or preset color: Brush trkBrush = getBrush(); // filled circles, arrow heads Pen trkPen = getTrackPen(); // lines Pen rtePen = getRoutePen(); // lines Pen rteTrkPen; // square (flat) Cap is a pain in neck; this kind of works: GraphicsPath objPath = new GraphicsPath(); // objPath.AddRectangle(new Rectangle(0, -1, 0, 0)); CustomLineCap squareCap = new System.Drawing.Drawing2D.CustomLineCap(objPath, null, LineCap.Flat); squareCap.WidthScale = 0.0f; bool skipOne; for(int i=0; i < m_trackpoints.Count ;i+=step) { skipOne = false; try { Waypoint wp1 = (Waypoint)m_trackpoints.GetByIndex(i); bool doDrawThisPoint = doDrawPoints; if(wp1.ThumbImage != null) { skipOne = true; // draw and move to next trackpoint; keep in sync with the stepping logic } pointCount++; Waypoint wp2 = null; if(i != m_trackpoints.Count-1 && (i + step) < m_trackpoints.Count) // last point { wp2 = (Waypoint)m_trackpoints.GetByIndex(i+step); } if(!layer.insideScreenRectangle(wp1.Location) && wp2 != null && !layer.insideScreenRectangle(wp2.Location)) { goto nextLoop; } Point p1 = isPrint ? layer.toPixelLocationPrint(wp1.Location, iTile) : layer.toPixelLocation(wp1.Location, iTile); // if(tailPoint.IsEmpty) // { // tailPoint = p1; // } int dd = diam; bool staying = false; bool doHighlight = false; bool hasContent = wp1.hasContent; bool hasUrl = wp1.Url != null && wp1.Url.Length > 0; string stayLbl = ""; if(TimeFilter.Enabled) { doHighlight = TimeFilter.passes(wp1.DateTime); if(!doHighlight && TimeFilter.beforeFrom(wp1.DateTime)) { // in case it doesn't pass directly, but we are in the middle of the track // and the time filter boundaries are between this point and next point, // we highlight both points because we are sitting there at this time. if(i > 0 && wp2 != null) // mid-track { if(TimeFilter.afterTo(wp2.DateTime)) { doHighlight = true; dd *= 3; staying = true; DateTime wp2LocalTime = Project.zuluToLocal(wp2.DateTime); stayLbl = "staying till " + wp2LocalTime.TimeOfDay; } } } } if(SelectFilter.Enabled) { doHighlight = SelectFilter.passes(wp1); dd = 2; } if(doHighlight) { if(_lastHighlightedWaypoint == null) { _lastHighlightedWaypoint = wp1; } graphics.DrawEllipse(penHighlight, p1.X-dd, p1.Y-dd, dd*2, dd*2); if(staying) { int x = p1.X + 10; int y = p1.Y - dd*2; Font font = Project.getLabelFont(Project.FONT_SIZE_REGULAR + 2); if(Project.waypointUseShadow) { graphics.DrawString(stayLbl, font, Project.blackBrush, x, y); graphics.DrawString(stayLbl, font, Project.blackBrush, x+2, y); graphics.DrawString(stayLbl, font, Project.blackBrush, x, y-2); graphics.DrawString(stayLbl, font, Project.blackBrush, x+2, y-2); } graphics.DrawString(stayLbl, font, Project.whiteBrush, x+1, y-1); } } if(hasUrl) { graphics.DrawEllipse(penHighlight2, p1.X-4, p1.Y-4, 8, 8); } if(hasContent) { if(!hasUrl) { graphics.DrawEllipse(Pens.Cyan, p1.X-4, p1.Y-4, 8, 8); } graphics.DrawEllipse(penHighlight, p1.X-2, p1.Y-2, 4, 4); } if(hasUrl || hasContent || (wp2 == null && (i==0 || !Project.makeRouteMode))) // last point { int offsetX = 0; int offsetY = 0; if(isPrint) { Point pixelPosPrint = layer.toPixelLocationPrint(wp1.Location, null); Point pixelPosDispl = wp1.PixelLocation; offsetX = pixelPosPrint.X - pixelPosDispl.X; offsetY = pixelPosPrint.Y - pixelPosDispl.Y; } wp1.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY); } if(wp2 != null) // not the last point { Point p2 = isPrint ? layer.toPixelLocationPrint(wp2.Location, iTile) : layer.toPixelLocation(wp2.Location, iTile); bool thickPen = false; if(m_isRoute) { rteTrkPen = rtePen; } else { if(Project.trackElevColor) { double elevRange = ElevMax - ElevMin; if(elevRange > 1.0d && elevRange < 20000.0d) { double elevFactor = elevRange / 256.0d; double elev = wp2.Location.Elev; int r = (int)((elev - ElevMin) / elevFactor); if(r > 255) { r = 255; } int b = 255 - r; int g = (255 - (r > b ? r : b)) * 2; // will be high where R and B are close to equal, amounts to cyan Color legColor = Color.FromArgb(r, g, b); trkBrush = new SolidBrush(legColor); trkPen = new Pen(trkBrush, (r > 250 ? 5.0f : 3.0f) * trackThicknessFactor); thickPen = true; } } else if(Project.trackSpeedColor) { double speedRange = SpeedMax - SpeedMin; if(speedRange > 1000.0d && speedRange < 1000000000.0d) { double speedFactor = speedRange / 256.0d; double speed = wp2.Speed; int r = (int)((speed - SpeedMin) / speedFactor); if(r > 255) { r = 255; } int b = 255 - r; int g = (255 - (r > b ? r : b)) * 2; // will be high where R and B are close to equal, amounts to cyan Color legColor = Color.FromArgb(r, g, b); trkBrush = new SolidBrush(legColor); trkPen = new Pen(trkBrush, (r > 250 ? 5.0f : 3.0f) * trackThicknessFactor); thickPen = true; } } rteTrkPen = doHighlight ? penHighlight : trkPen; } int dltaX = p2.X - p1.X; int dltaY = p2.Y - p1.Y; double lenSq = dltaX * dltaX + dltaY * dltaY; int dlta2X = p2.X - lastArrowPoint.X; int dlta2Y = p2.Y - lastArrowPoint.Y; double lenSq2 = dlta2X * dlta2X + dlta2Y * dlta2Y; if(lenSq2 > 10000.0d || lenSq > 900.0d) // big enough to hold arrow? { float arrowWidth = thickPen ? 4 : 3; float arrowHeight = 6; bool arrowFill = true; rteTrkPen.CustomEndCap = new AdjustableArrowCap(arrowWidth, arrowHeight, arrowFill); lastArrowCount = pointCount; lastArrowPoint = p2; // tailPoint = p2; //doDrawThisPoint = false; } else { // no cap - null doesn't work here rteTrkPen.CustomEndCap = squareCap; } graphics.DrawLine(rteTrkPen, p1, p2); if(doDrawThisPoint && diam > 2) { graphics.FillEllipse(trkBrush, p2.X-rad, p2.Y-rad, diam, diam); } if(i == 0) { int offsetX = 0; int offsetY = 0; if(isPrint) { Point pixelPosPrint = layer.toPixelLocationPrint(wp1.Location, null); Point pixelPosDispl = wp1.PixelLocation; offsetX = pixelPosPrint.X - pixelPosDispl.X; offsetY = pixelPosPrint.Y - pixelPosDispl.Y; } wp1.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY); prevX = p1.X; prevY = p1.Y; } else if((p1.X - prevX)*(p1.X - prevX) + (p1.Y - prevY)*(p1.Y - prevY) > 900) { if(Project.showTrackpointNumbers) { // call simplified PaintLabel, not regular one: PaintLabel(graphics, wp1.Name, p1.X, p1.Y, isPrint); } prevX = p1.X; prevY = p1.Y; } } else if(doDrawThisPoint) { graphics.FillEllipse(trkBrush, p1.X-rad, p1.Y-rad, diam, diam); } } catch (Exception e) { LibSys.StatusBar.Error("Track::Paint() - " + e.Message); } nextLoop: if(skipOne) { i -= (step - 1); // move to the next trackpoint continue; } int pointsLeft = m_trackpoints.Count - i; if(pointsLeft > 1 && pointsLeft < step) { step = pointsLeft - 2; if(step < 1) { step = 1; } } } if(Project.thumbDoDisplay) { SortedList ppts = Project.mainCommand.getWaypointsWithThumbs(m_id); for (int i=0; i < ppts.Count ;i++) { Waypoint wpt = (Waypoint)ppts.GetByIndex(i); Pen thumbBorderPen = Pens.Blue; Pen thumbCornerPen = new Pen(Color.Blue, 3.0f); int width = wpt.ThumbImage.Width; int height = wpt.ThumbImage.Height; Point p1 = isPrint ? layer.toPixelLocationPrint(wpt.Location, iTile) : layer.toPixelLocation(wpt.Location, iTile); switch(wpt.ThumbPosition) { case 0: // top right graphics.DrawImage(wpt.ThumbImage, p1.X, p1.Y-height, width, height); graphics.DrawRectangle(thumbBorderPen, p1.X, p1.Y-height, width-1, height-1); graphics.DrawLine(thumbCornerPen, p1.X+2, p1.Y, p1.X+2, p1.Y-10); graphics.DrawLine(thumbCornerPen, p1.X, p1.Y-2, p1.X+10, p1.Y-2); break; case 1: // center default: graphics.DrawImage(wpt.ThumbImage, p1.X-width/2, p1.Y-height/2, width, height); graphics.DrawRectangle(thumbBorderPen, p1.X-width/2, p1.Y-height/2, width-1, height-1); break; } int offsetX = 0; int offsetY = 0; if(isPrint) { Point pixelPosPrint = layer.toPixelLocationPrint(wpt.Location, null); Point pixelPosDispl = wpt.PixelLocation; offsetX = pixelPosPrint.X - pixelPosDispl.X; offsetY = pixelPosPrint.Y - pixelPosDispl.Y; } wpt.PaintLabel(graphics, layer, iTile, isPrint, offsetX, offsetY); } } if(_lastHighlightedWaypoint != null) { lastHighlightedWaypoint = _lastHighlightedWaypoint; } }
// for the LiveMap:isRelevant() method // we need to know how important/big the waypoint representation is on the map without // instantiating the visial object. So, we use static method here. public static Rectangle boundingRectEstimate(IDrawingSurface map, LabeledPoint wp) { Point pPoint; try { pPoint = map.toPixelLocation(wp.Location, null); } catch (Exception e) { return Rectangle.Empty; } int w = wp.imageSizeByType(wp.LiveObjectType); int h = w; Rectangle re = new Rectangle(pPoint.X-w, pPoint.Y-h, w*2, h*2); return re; }
public override void Paint(Graphics graphics, IDrawingSurface layer, ITile iTile, int offsetX, int offsetY) { // waypoints belonging to tracks are painted in Track:Paint() if(!m_enabled || m_trackId != -1L) { return; } //LibSys.StatusBar.Trace("Waypoint::Paint() - " + Location + " : " + m_doName + m_labelBoundingRect); int x, y, w, h; x = m_imageBoundingRect.X + 1 + offsetX; y = m_imageBoundingRect.Y + 1 + offsetY; w = m_imageBoundingRect.Width - 2; h = m_imageBoundingRect.Height - 2; Image symImage = null; if(Project.useWaypointIcons) { symImage = Project.waypointImageGetter.getImageBySymbol(m_sym); } if(Project.thumbDoDisplay && this.ThumbImage != null) { Pen thumbBorderPen = Pens.Blue; Pen thumbCornerPen = new Pen(Color.Blue, 3.0f); int width = this.ThumbImage.Width; int height = this.ThumbImage.Height; Point p1 = layer.toPixelLocation(this.Location, iTile); int tx = p1.X + offsetX; int ty = p1.Y + offsetY; switch(this.ThumbPosition) { case 0: // top right graphics.DrawImage(this.ThumbImage, tx, ty-height, width, height); graphics.DrawRectangle(thumbBorderPen, tx, ty-height, width-1, height-1); graphics.DrawLine(thumbCornerPen, tx+2, ty, tx+2, ty-10); graphics.DrawLine(thumbCornerPen, tx, ty-2, tx+10, ty-2); break; case 1: // center default: graphics.DrawImage(this.ThumbImage, tx-width/2, ty-height/2, width, height); graphics.DrawRectangle(thumbBorderPen, tx-width/2, ty-height/2, width-1, height-1); break; } } else if(symImage != null) { graphics.DrawImage(symImage, x, y); } else { switch(LiveObjectType) { case LiveObjectTypes.LiveObjectTypeGeocache: if(m_found) { graphics.DrawEllipse(Project.waypointPen1bold, x, y, w, h); graphics.DrawEllipse(Project.waypointPen2bold, x+4, y+4, w-8, h-8); //graphics.DrawEllipse(Project.waypointPen3, x+8, y+8, w-16, h-16); } else { graphics.DrawEllipse(Project.waypointPen1, x, y, w, h); graphics.DrawEllipse(Project.waypointPen2, x+4, y+4, w-8, h-8); //graphics.DrawEllipse(Project.waypointPen3, x+8, y+8, w-16, h-16); } break; default: graphics.DrawEllipse(Project.waypointPen, x, y, w, h); break; } } // debug only - show bounding rectangles: //graphics.DrawRectangle(Project.debugPen, m_boundingRect); // red //graphics.DrawRectangle(Project.debug2Pen, m_imageBoundingRect); // green //graphics.DrawRectangle(Project.debug3Pen, m_labelBoundingRect); // yellow }