Search code examples
javafxdrawingdesktop-applicationarcgis-runtime

Circle/Rectangle Shapes Drawing using ArcGIS Java SDK


so i've been working on a map related desktop application (in JavaFX) using ArcGIS Java SDK 100.6.0. I want to draw certain shapes on the map and save them. I've seen the documentation and as far as i know they provide a SketchEditor class for drawing on map. The class object allows me to draw freehand, polylines and polygons on the map. My application requires a complete drawing feature to draw various shapes. This class does not allow me to draw squares, rectanlges, circles. My question is that how can i draw these shapes on my mapview. Has anyone ever come up with any idea to draw shapes apart from the SketchEditor's available ones.

Edit: I think my question is not clear enough. I'll just share what my application requires and what i can actually implement:

These are are the shapes that i want my application to support

These are the shapes that ArcGIS Java SDK currently supports

Now I've found a workaround for circle from this link:

https://gis.stackexchange.com/questions/26636/draw-a-circle-in-arcgis-map

Now the shapes that remain are rectangle/square. I hope someone can share how they solved this problem in Java.


Solution

  • I tried to find workarounds for the drawing of those unsupported shapes. It was found that by using the polygon geometry, and by giving the right points, i can create those shapes (Circle, Square, Rectangle). Here is the code snippet that shows how i managed to draw those shapes (The methods that return graphic object for the shapes):

    Circle

    public static Graphic drawFullCircle(Point centerPoint, double radius, int borderColor) {
        int ptCount = 240;
        double slice = 2 * Math.PI / ptCount;
        PointCollection pc = new PointCollection(SpatialReferences.getWgs84());
        for (int i = 0; i <= ptCount; i++) {
            double rad = slice * i;
            double px = centerPoint.getX() + radius * Math.cos(rad);
            double py = centerPoint.getY() + radius * Math.sin(rad);
            pc.add(new Point(px, py));
        }
        Polygon poly = new Polygon(new PartCollection(pc));
        SimpleFillSymbol sfs = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, 0x00FFFFFF, new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, borderColor, 1.5f));
        Graphic g = new Graphic(poly, sfs);
        return g;
    }
    

    I was able to draw rectangular shapes using the Envelop geometry.

    Rectangle

    public static Graphic drawRectangle(Point p1, Point p2, int borderColor) {
        Envelope envelope = new Envelope(p1, p2); // start (p1) and end (p2) points of a diagonal
        PointCollection pc = new PointCollection(SpatialReferences.getWgs84());
        pc.add(new Point(envelope.getXMin(), envelope.getYMin()));
        pc.add(new Point(envelope.getXMax(), envelope.getYMin()));
        pc.add(new Point(envelope.getXMax(), envelope.getYMax()));
        pc.add(new Point(envelope.getXMin(), envelope.getYMax()));
    
        Polygon poly = new Polygon(new PartCollection(pc));
        SimpleFillSymbol sfs = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, 0x00FFFFFF, new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, borderColor, 1.5f));
        return new Graphic(poly, sfs);
    }
    

    Square

    public static Graphic drawSquare(Point p1, Point p2, int borderColor) {
        Envelope rectEnvelope = new Envelope(p1, p2); start (p1) and end (p2) points of a diagonal
    
        PointCollection pc = new PointCollection(SpatialReferences.getWgs84());
        // these conditions make sure that the square is created from the start point and not from any other point.
        if(rectEnvelope.getWidth() > rectEnvelope.getHeight())
        {
            if(p2.getX() > p1.getX())
            {
                pc.add(new Point(rectEnvelope.getXMin(), rectEnvelope.getYMin()));
                pc.add(new Point(rectEnvelope.getXMin()+rectEnvelope.getHeight(), rectEnvelope.getYMin()));
                pc.add(new Point(rectEnvelope.getXMin()+rectEnvelope.getHeight(), rectEnvelope.getYMax()));
                pc.add(new Point(rectEnvelope.getXMin(), rectEnvelope.getYMax()));
            }
            else
            {
                pc.add(new Point(rectEnvelope.getXMax()-rectEnvelope.getHeight(), rectEnvelope.getYMax()-rectEnvelope.getHeight()));
                pc.add(new Point(rectEnvelope.getXMax(), rectEnvelope.getYMin()));
                pc.add(new Point(rectEnvelope.getXMax(), rectEnvelope.getYMax()));
                pc.add(new Point(rectEnvelope.getXMax()-rectEnvelope.getHeight(), rectEnvelope.getYMax()));
            }
        }
        else
        {
            if(p2.getY() > p1.getY())
            {
                pc.add(new Point(rectEnvelope.getXMin(), rectEnvelope.getYMin()));
                pc.add(new Point(rectEnvelope.getXMax(), rectEnvelope.getYMin()));
                pc.add(new Point(rectEnvelope.getXMax(), rectEnvelope.getYMin()+rectEnvelope.getWidth()));
                pc.add(new Point(rectEnvelope.getXMin(), rectEnvelope.getYMin()+rectEnvelope.getWidth()));
            }
            else
            {
                pc.add(new Point(rectEnvelope.getXMin(), rectEnvelope.getYMax()-rectEnvelope.getWidth()));
                pc.add(new Point(rectEnvelope.getXMax(), rectEnvelope.getYMax()-rectEnvelope.getWidth()));
                pc.add(new Point(rectEnvelope.getXMax(), rectEnvelope.getYMax()));
                pc.add(new Point(rectEnvelope.getXMin(), rectEnvelope.getYMax()));
            }
        }
    
        Polygon poly = new Polygon(new PartCollection(pc));
        SimpleFillSymbol sfs = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, 0x00FFFFFF, new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, borderColor, 1.5f));
        return new Graphic(poly, sfs);
    }
    

    This might contain unoptimized code logic however this is all what we have for now with ArcGIS Java SDK 100.6.0. Any edits and suggestions would be appreciated.