public void CanConvertLatLngToPixelOffset() { List <WGSPoint> latLngs = new List <WGSPoint> { new WGSPoint(36.210.LatDegreesToRadians(), -115.025.LonDegreesToRadians()), new WGSPoint(36.205.LatDegreesToRadians(), -115.029.LonDegreesToRadians()), new WGSPoint(36.200.LatDegreesToRadians(), -115.018.LonDegreesToRadians()) }; var topLeft = new Point(100, 250); var pixelPoints = TileServiceUtils.LatLngToPixelOffset(latLngs, topLeft, 32768); var expectedPoints = new PointF[3] { new PointF { X = 1513777.25F, Y = 3287930F }, new PointF { X = 1513684F, Y = 3288074.5F }, new PointF { X = 1513940.38F, Y = 3288218.75F }, }; for (int i = 0; i < 3; i++) { Assert.Equal(expectedPoints[i], pixelPoints[i]); } }
/// <summary> /// Gets a map tile with the project boundary drawn on it. /// </summary> /// <param name="parameters">Map parameters such as bounding box, tile size, zoom level etc.</param> /// <param name="project">The project to draw the boundary for</param> /// <returns>A bitmap</returns> public byte[] GetProjectBitmap(MapParameters parameters, ProjectData project) { log.LogInformation($"GetProjectBitmap: project {project.ProjectUID}"); const int PROJECT_BOUNDARY_COLOR = 0x0080FF; //Note: packed is abgr order const int STROKE_TRANSPARENCY = 0x73; //0.45 of FF Rgba32 PROJECT_BOUNDARY_RGBA = new Rgba32((uint)((STROKE_TRANSPARENCY << 24) | PROJECT_BOUNDARY_COLOR)); const int PROJECT_OUTLINE_WIDTH = 4; byte[] projectImage = null; if (project != null) { using (Image <Rgba32> bitmap = new Image <Rgba32>(parameters.mapWidth, parameters.mapHeight)) { var projectPoints = project.ProjectGeofenceWKT.GeometryToPoints(); PointF[] pixelPoints = TileServiceUtils.LatLngToPixelOffset(projectPoints, parameters.pixelTopLeft, parameters.numTiles); bitmap.Mutate(ctx => ctx.DrawPolygon(PROJECT_BOUNDARY_RGBA, PROJECT_OUTLINE_WIDTH, pixelPoints)); projectImage = bitmap.BitmapToByteArray(); } } return(projectImage); }
/// <summary> /// Gets a map tile with load/dump locations drawn on it. /// </summary> /// <param name="parameters">Map parameters such as bounding box, tile size, zoom level etc.</param> /// <param name="loadDumpLocations">List of Load/Dump locations</param> /// <returns>A bitmap</returns> public byte[] GetLoadDumpBitmap(MapParameters parameters, List <LoadDumpLocation> loadDumpLocations) { log.LogInformation($"GetLoadDumpBitmap"); //Note: packed is abgr order const uint LOAD_COLOR = 0xFF008F01; //Green 0x018F00 const uint DUMP_COLOR = 0xFFFF3304; //Blue 0x0433FF Rgba32 LOAD_RGBA = new Rgba32(LOAD_COLOR); Rgba32 DUMP_RGBA = new Rgba32(DUMP_COLOR); var loadPen = new Pen <Rgba32>(LOAD_RGBA, 1); var dumpPen = new Pen <Rgba32>(DUMP_RGBA, 1); byte[] loadDumpImage = null; if (loadDumpLocations != null && loadDumpLocations.Any()) { using (Image <Rgba32> bitmap = new Image <Rgba32>(parameters.mapWidth, parameters.mapHeight)) { IEnumerable <WGSPoint> loads = loadDumpLocations .Select(x => new WGSPoint(x.loadLatitude.LatDegreesToRadians(), x.loadLongitude.LonDegreesToRadians())).ToList(); PointF[] pixelPoints = TileServiceUtils.LatLngToPixelOffset(loads, parameters.pixelTopLeft, parameters.numTiles); foreach (var p in pixelPoints) { //Coloring one pixel doesn't show up well therefore do rectangle of 4 pixels var x = (int)p.X; var y = (int)p.Y; var rect = new RectangleF(x, y, 2, 2); bitmap.Mutate(ctx => ctx.Draw(loadPen, rect)); //bitmap[(int) p.X, (int) p.Y] = LOAD_RGBA; } IEnumerable <WGSPoint> dumps = loadDumpLocations .Select(x => new WGSPoint(x.dumpLatitude.LatDegreesToRadians(), x.dumpLongitude.LonDegreesToRadians())).ToList(); pixelPoints = TileServiceUtils.LatLngToPixelOffset(dumps, parameters.pixelTopLeft, parameters.numTiles); foreach (var p in pixelPoints) { var x = (int)p.X; var y = (int)p.Y; var rect = new RectangleF(x, y, 2, 2); bitmap.Mutate(ctx => ctx.Draw(dumpPen, rect)); //bitmap[(int) p.X, (int) p.Y] = DUMP_RGBA; } loadDumpImage = bitmap.BitmapToByteArray(); } } return(loadDumpImage); }
private void DrawGeofence(MapParameters parameters, Image <Rgba32> bitmap, string uid, IEnumerable <WGSPoint> points, int color, bool isTransparent) { const byte FILL_TRANSPARENCY = 0x40; //0.25 of FF const byte STROKE_TRANSPARENCY = 0x73; //0.45 of FF const int SITE_OUTLINE_WIDTH = 2; log.LogDebug($"DrawGeofence drawing site or boundary {uid}"); var red = (byte)((color & 0xFF0000) >> 16); var green = (byte)((color & 0x00FF00) >> 8); var blue = (byte)(color & 0x0000FF); PointF[] pixelPoints = TileServiceUtils.LatLngToPixelOffset(points, parameters.pixelTopLeft, parameters.numTiles); if (!isTransparent) { var fillColor = new Rgba32(red, green, blue, FILL_TRANSPARENCY); bitmap.Mutate(ctx => ctx.FillPolygon(fillColor, pixelPoints)); } var lineColor = new Rgba32(red, green, blue, STROKE_TRANSPARENCY); bitmap.Mutate(ctx => ctx.DrawPolygon(lineColor, SITE_OUTLINE_WIDTH, pixelPoints)); }
/// <summary> /// Gets a map tile with alignment center lines drawn on it. /// </summary> /// <param name="parameters">Map parameters such as bounding box, tile size, zoom level etc.</param> /// <param name="projectId">Legacy project ID</param> /// <param name="alignmentPointsList">Points for the project's alignment files</param> /// <returns>A bitmap</returns> public byte[] GetAlignmentsBitmap(MapParameters parameters, long projectId, List <List <WGSPoint> > alignmentPointsList) { log.LogInformation($"GetAlignmentsBitmap: project {projectId}"); byte[] alignmentsImage = null; if (alignmentPointsList != null && alignmentPointsList.Any()) { using (Image <Rgba32> bitmap = new Image <Rgba32>(parameters.mapWidth, parameters.mapHeight)) { foreach (var alignmentPoints in alignmentPointsList) { if (alignmentPoints != null && alignmentPoints.Any()) { PointF[] pixelPoints = TileServiceUtils.LatLngToPixelOffset(alignmentPoints, parameters.pixelTopLeft, parameters.numTiles); bitmap.Mutate(ctx => ctx.DrawLines(Rgba32.Red, 1, pixelPoints)); } } alignmentsImage = bitmap.BitmapToByteArray(); } } return(alignmentsImage); }