コード例 #1
0
        /// <summary>
        /// Draw square boxes around each area to approximate how they would behave in an offline app
        /// </summary>
        /// <param name="info">the image information for drawing</param>
        /// <param name="items">the elements to draw.</param>
        /// <returns>byte array of the generated .png tile image</returns>
        public byte[] DrawOfflineEstimatedAreas(ImageStats info, List <DbTables.Place> items)
        {
            SKBitmap bitmap  = new SKBitmap(info.imageSizeX, info.imageSizeY, SKColorType.Rgba8888, SKAlphaType.Premul);
            SKCanvas canvas  = new SKCanvas(bitmap);
            var      bgColor = SKColors.Transparent;

            canvas.Clear(bgColor);
            canvas.Scale(1, -1, info.imageSizeX / 2, info.imageSizeY / 2);
            SKPaint fillpaint = new SKPaint();

            fillpaint.IsAntialias = true;
            fillpaint.Style       = SKPaintStyle.Fill;
            var strokePaint = new SKPaint();

            strokePaint.Color       = SKColors.Black;
            strokePaint.TextSize    = 32;
            strokePaint.StrokeWidth = 3;
            strokePaint.Style       = SKPaintStyle.Stroke;
            strokePaint.TextAlign   = SKTextAlign.Center;
            //TagParser.ApplyTags(items);

            var placeInfo = PraxisCore.Standalone.Standalone.GetPlaceInfo(items.Where(i =>
                                                                                      i.IsGameElement
                                                                                      ).ToList());

            //this is for rectangles.
            foreach (var pi in placeInfo)
            {
                var rect = PlaceInfoToRect(pi, info);
                fillpaint.Color = SKColor.Parse(TagParser.PickStaticColorForArea(pi.Name));
                canvas.DrawRect(rect, fillpaint);
                canvas.DrawRect(rect, strokePaint);
            }

            canvas.Scale(1, -1, info.imageSizeX / 2, info.imageSizeY / 2); //inverts the inverted image again!
            foreach (var pi in placeInfo)
            {
                var rect = PlaceInfoToRect(pi, info);
                canvas.DrawText(pi.Name, rect.MidX, info.imageSizeY - rect.MidY, strokePaint);
            }

            var ms   = new MemoryStream();
            var skms = new SKManagedWStream(ms);

            bitmap.Encode(skms, SKEncodedImageFormat.Png, 100);
            var results = ms.ToArray();

            skms.Dispose(); ms.Close(); ms.Dispose();
            return(results);
        }
コード例 #2
0
        /// <summary>
        /// Take a path provided by a user, draw it as a maptile. Potentially useful for exercise trackers. Resulting file must not be saved to the server as that would be user tracking.
        /// </summary>
        /// <param name="pointListAsString">a string of points separate by , and | </param>
        /// <returns>the png file with the path drawn over the mapdata in the area.</returns>
        public byte[] DrawUserPath(string pointListAsString)
        {
            //String is formatted as Lat,Lon~Lat,Lon~ repeating. Characters chosen to not be percent-encoded if submitted as part of the URL.
            //first, convert this to a list of latlon points
            string[]          pointToConvert = pointListAsString.Split("|");
            List <Coordinate> coords         = pointToConvert.Select(p => new Coordinate(double.Parse(p.Split(',')[0]), double.Parse(p.Split(',')[1]))).ToList();

            var     mapBuffer = resolutionCell8 / 2; //Leave some area around the edges of where they went.
            GeoArea mapToDraw = new GeoArea(coords.Min(c => c.Y) - mapBuffer, coords.Min(c => c.X) - mapBuffer, coords.Max(c => c.Y) + mapBuffer, coords.Max(c => c.X) + mapBuffer);

            ImageStats info = new ImageStats(mapToDraw, 1024, 1024);

            LineString line         = new LineString(coords.ToArray());
            var        drawableLine = PolygonToSKPoints(line, mapToDraw, info.degreesPerPixelX, info.degreesPerPixelY);

            //Now, draw that path on the map.
            var places    = GetPlaces(mapToDraw); //, null, false, false, degreesPerPixelX * 4 ///TODO: restore item filtering
            var baseImage = DrawAreaAtSize(info, places);

            SKBitmap sKBitmap = SKBitmap.Decode(baseImage);
            SKCanvas canvas   = new SKCanvas(sKBitmap);
            SKPaint  paint    = new SKPaint();

            paint.Style       = SKPaintStyle.Stroke;
            paint.StrokeWidth = 4;                    //Larger than normal lines at any zoom level.
            paint.Color       = new SKColor(0, 0, 0); //Pure black, for maximum visibility.
            for (var x = 0; x < drawableLine.Length - 1; x++)
            {
                canvas.DrawLine(drawableLine[x], drawableLine[x + 1], paint);
            }

            var ms   = new MemoryStream();
            var skms = new SKManagedWStream(ms);

            sKBitmap.Encode(skms, SKEncodedImageFormat.Png, 100);
            var results = ms.ToArray();

            skms.Dispose(); ms.Close(); ms.Dispose();
            return(results);
        }
コード例 #3
0
        public byte[] DrawAreaAtSize(ImageStats stats, List <CompletePaintOp> paintOps)
        {
            //This is the new core drawing function. Once the paint operations have been created, I just draw them here.
            //baseline image data stuff
            SKBitmap bitmap = new SKBitmap(stats.imageSizeX, stats.imageSizeY, SKColorType.Rgba8888, SKAlphaType.Premul);
            SKCanvas canvas = new SKCanvas(bitmap);

            canvas.Clear(eraser.Color);
            canvas.Scale(1, -1, stats.imageSizeX / 2, stats.imageSizeY / 2);
            SKPaint paint = new SKPaint();

            foreach (var w in paintOps.OrderByDescending(p => p.paintOp.LayerId).ThenByDescending(p => p.areaSize))
            {
                paint = cachedPaints[w.paintOp.Id]; //SetPaintForTPP(w.paintOp); // w.paintOp.paint;

                if (w.paintOp.FromTag)              //FromTag is for when you are saving color data directly to each element, instead of tying it to a styleset.
                {
                    paint.Color = SKColor.Parse(w.tagValue);
                }

                if (w.paintOp.Randomize) //To randomize the color on every Draw call.
                {
                    paint.Color = new SKColor((byte)r.Next(0, 255), (byte)r.Next(0, 255), (byte)r.Next(0, 255), 99);
                }

                paint.StrokeWidth = (float)w.lineWidthPixels;
                var path = new SKPath();
                switch (w.elementGeometry.GeometryType)
                {
                case "Polygon":
                    var p = w.elementGeometry as Polygon;
                    //if (p.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw
                    //continue;
                    path.AddPoly(PolygonToSKPoints(p.ExteriorRing, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY));
                    foreach (var ir in p.Holes)
                    {
                        //if (ir.Envelope.Length < (w.lineWidth * 4)) //This poly's perimeter is less than 2x2 pixels in size.
                        //continue;
                        path.AddPoly(PolygonToSKPoints(ir, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY));
                    }
                    canvas.DrawPath(path, paint);
                    break;

                case "MultiPolygon":
                    foreach (var p2 in ((MultiPolygon)w.elementGeometry).Geometries)
                    {
                        //if (p2.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw
                        //continue;
                        var p2p = p2 as Polygon;
                        path.AddPoly(PolygonToSKPoints(p2p.ExteriorRing, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY));
                        foreach (var ir in p2p.Holes)
                        {
                            //if (ir.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw
                            // continue;
                            path.AddPoly(PolygonToSKPoints(ir, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY));
                        }
                        canvas.DrawPath(path, paint);
                    }
                    break;

                case "LineString":
                    var firstPoint = w.elementGeometry.Coordinates.First();
                    var lastPoint  = w.elementGeometry.Coordinates.Last();
                    var points     = PolygonToSKPoints(w.elementGeometry, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY);
                    if (firstPoint.Equals(lastPoint))
                    {
                        //This is a closed shape. Check to see if it's supposed to be filled in.
                        if (paint.Style == SKPaintStyle.Fill)
                        {
                            path.AddPoly(points);
                            canvas.DrawPath(path, paint);
                            continue;
                        }
                    }
                    //if (w.lineWidth < 1) //Don't draw lines we can't see.
                    //continue;
                    for (var line = 0; line < points.Length - 1; line++)
                    {
                        canvas.DrawLine(points[line], points[line + 1], paint);
                    }
                    break;

                case "MultiLineString":
                    //if (w.lineWidth < 1) //Don't draw lines we can't see.
                    //continue;
                    foreach (var p3 in ((MultiLineString)w.elementGeometry).Geometries)
                    {
                        var points2 = PolygonToSKPoints(p3, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY);
                        for (var line = 0; line < points2.Length - 1; line++)
                        {
                            canvas.DrawLine(points2[line], points2[line + 1], paint);
                        }
                    }
                    break;

                case "Point":
                    var convertedPoint = PolygonToSKPoints(w.elementGeometry, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY);
                    //If this type has an icon, use it. Otherwise draw a circle in that type's color.
                    if (!string.IsNullOrEmpty(w.paintOp.FileName))
                    {
                        SKBitmap icon = SKBitmap.Decode(TagParser.cachedBitmaps[w.paintOp.FileName]);     //TODO optimize by making icons in Initialize.
                        canvas.DrawBitmap(icon, convertedPoint[0]);
                    }
                    else
                    {
                        var circleRadius = (float)(ConstantValues.resolutionCell10 / stats.degreesPerPixelX / 2);     //I want points to be drawn as 1 Cell10 in diameter.
                        canvas.DrawCircle(convertedPoint[0], circleRadius, paint);
                        //TODO re-add outline paint to this DLL not TagParser.
                        //canvas.DrawCircle(convertedPoint[0], circleRadius, TagParser.outlinePaint);
                    }
                    break;

                default:
                    Log.WriteLog("Unknown geometry type found, not drawn.");
                    break;
                }
            }
            //}

            var ms   = new MemoryStream();
            var skms = new SKManagedWStream(ms);

            bitmap.Encode(skms, SKEncodedImageFormat.Png, 100);
            var results = ms.ToArray();

            skms.Dispose(); ms.Close(); ms.Dispose();
            return(results);
        }