Select to view content in your preferred language

Creating custom graphics/markers with custom symbology

4832
11
12-04-2012 06:49 PM
UAENavy
New Contributor
we have a requirement for creating custom graphics with custom symbols where the drawing routine is dynamic.

for example, a pie graphic that draws a pie based on dynamic start & end angles!

The SDK documentation and API reference is really poor, and so the graphics rendering process is not clear.
did anybody try rendering custom graphics without having to use a drawing overlay?


Thank you
0 Kudos
11 Replies
EricBader
Honored Contributor
Sounds interesting!

As you may know by now, the API for graphic rendering is not extensible, but maybe you can present more details into exactly what you would like to see in the product, from a developer standpoint?
Also, I appreciate your comments about the documentation, and we would really value your ideas on what needs to be embellished here. Please feel free to share.

Thank you!
0 Kudos
UAENavy
New Contributor
Appreciate the clarifications

It's truly disappointing that the runtime SDK is not mature yet!!! certainly not the satisfaction we were expecting from a solutions provider as big as Esri niether from an SDK or a Runtime. I can't imagine an SDK without thinking customization!

We are evaluating the Runtime SDK before final purchase, we have already implemented the solution (and a lot more) with the Flex API by extending the MarkerSymbol class which was nice!

We expected the Runtime SDK to provide the bare minimum extensibility to draw our own custom shapes or at least meet the features of the Flex SDK, we were planning to port our client to a Java Desktop Think client so we can utilize the GPU & achieve higher performance

Regarding the shape required, kindly see attached, a 2D Sector (Pie) shape with a start angle and a sweep input value, this can take 0 - 360 degrees depending on the starting angle, with a dynamic heading (direction) ... all dynamic!, and it should redraw and re-scale properly with different scale levels, a 100 km diameter for example should look smaller on lower zoom levels.

The documentation was so poor that it had misspellings, and sometimes no comments at all, parameters not described, processes unexplained, in fact, the documentation was unprofessional to be honest, there was no use of it, the only helpful resource were the samples that ship with the SDK! ... and the community ...

Thank you
0 Kudos
EricBader
Honored Contributor
I see. Thank you for the attachment.
It is possible that you could do the angle calculations you need to do, then create the graphic lines based on those angles and the coordinates, i beleive. So, in your example, you would not need custom symbol objects, but you would just use basic line symbols and draw them use the correct coords, yes? ....or maybe i misinterpreted .

Thanks also for your candid feedback regarding the documentation. Yes, we need to keep working on this as a priority. These forums are a great way to comkunicate thibgs like this, and community is certainly KEY...so thanks.
0 Kudos
EricBader
Honored Contributor
To follow up on the recommendation I gave, it may prove to be quite difficult to do this. Thank you for pointing this out. The team is looking into your scenario.
0 Kudos
MarkBaird
Esri Regular Contributor
Hi

There is quite a lot you can do with a simple graphics layer which you can add to the map.  They are pretty efficient and work well with realtime updated displays.

I've started by looking at how you can draw a line from an origin pointing in a given direction.  Don't be put off by the amound of code, I've just added loads of debug graphics which are added to the screen so you can see how I'm building up the picture.  Let me know if this helps you get started.

I've added a tiled layer to the map and wired up a map click event:

        map = new JMap();
        map.addMouseListener(new MouseAdapter() {
         @Override
         public void mouseClicked(MouseEvent arg0) {
           drawSweep(arg0);
         }
        });
        window.getContentPane().add(map);

        ArcGISTiledMapServiceLayer tiledLayer = new ArcGISTiledMapServiceLayer(
            "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
        map.getLayers().add(tiledLayer);

When the user clicks on the map, a line will draw from the click point at an angle of 20 degrees east of north.  A bearing of -20 or 340 degrees.

    private void drawSweep(MouseEvent mouseArgs)
    {
     //new graphics layer added to the map
     GraphicsLayer graphicsLayer = new GraphicsLayer();
     map.getLayers().add(graphicsLayer);
    
     //get the position clicked on the map
     Point clickedPoint = map.toMapPoint(mouseArgs.getX(), mouseArgs.getY());
    
    
     //construct an origin of 0,0
     Point origin = new Point(0,0);
    
     //pop the origin on the map
     SimpleMarkerSymbol smsOrigin = new SimpleMarkerSymbol(Color.RED, 5, Style.CIRCLE);
     Graphic originGraphic = new Graphic(origin, smsOrigin);
     graphicsLayer.addGraphic(originGraphic);
    
     //make another point due north of the origin
     Point rotateMe = new Point(0,100000);
    
     //draw point due north on the map
     SimpleMarkerSymbol smsrotateMe = new SimpleMarkerSymbol(Color.BLUE, 5, Style.DIAMOND);
     Graphic rotateMeGraphic = new Graphic(rotateMe, smsrotateMe);
     graphicsLayer.addGraphic(rotateMeGraphic);
    
    
     //angle of rotation for heading from north position (converting to radians)
     double heading = 20 *( Math.PI / 180);
    
     //rotate 20 degrees
     Transformation2D td = new Transformation2D();
     td.rotate(heading);
     rotateMe.applyTransformation(td);
    
     //draw rotated point
     SimpleMarkerSymbol smsRotated = new SimpleMarkerSymbol(Color.ORANGE, 5, Style.TRIANGLE);
     Graphic rotatedGraphic = new Graphic(rotateMe, smsRotated);
     graphicsLayer.addGraphic(rotatedGraphic);
    
     //now use the origin and the rotated point to make a line
     Polyline bearing = new Polyline();
     bearing.startPath(origin);
     bearing.lineTo(rotateMe);
     bearing.closeAllPaths();
    
     //make a symbol and graphic
     SimpleLineSymbol slsBearing = new SimpleLineSymbol(Color.CYAN, 2);
     Graphic bearingGraphic = new Graphic(bearing, slsBearing);
     graphicsLayer.addGraphic(bearingGraphic);
    
    
     //now the line can me moved to be somewhere else (like where we clicked on the map)
     Transformation2D transShift = new Transformation2D();
     transShift.setShift(clickedPoint.getX(), clickedPoint.getY());
    
     bearing.applyTransformation(transShift);
    
     //then drawing bearing (this is probably the only line you want to draw)
     SimpleLineSymbol slsShiftedBearing = new SimpleLineSymbol(Color.GREEN, 2);
     Graphic shiftedGraphic = new Graphic(bearing, slsShiftedBearing);
     graphicsLayer.addGraphic(shiftedGraphic);
    
    
    }
0 Kudos
AliJoudeh
Emerging Contributor
hello

thank you for the insight

I have noticed a bug in the API with the JMap toScreenPoint method actually returns a geometry.Point! not a java.awt.Point as documented.

There is actually no way of getting around with a solution without this method.

did I get myself an unstable release?!
0 Kudos
EricBader
Honored Contributor
hello

thank you for the insight

I have noticed a bug in the API with the JMap toScreenPoint method actually returns a geometry.Point! not a java.awt.Point as documented.

There is actually no way of getting around with a solution without this method.

did I get myself an unstable release?!



It looks like the Javadoc has been corrected for this in the 10.1.1 update, soon to be released.
0 Kudos
AliJoudeh
Emerging Contributor
excellent! any expectations when 10.1.1 is to be release date?

I have figured a solution out using the Polygon class to dynamically draw sectors, also managed to draw a geodetic representation of the geometry that conforms to the projection!! ill be testing the performance for that ...

my other question is, what strategy was considered in the API design to solve Graphics/Geometry composition?
in other words, how can I combine multiple geometries in a single Graphic without relying on any service or JSON nodes? only using the client!

so that ..
1. selecting the graphic selects all contained geometry objects
2. animating the graphic should animate contained geometry objects

I can't find any practical usage for the MultiLayerSymbol!!
the base Symbol class is final & cannot be extended!!!
If I will use multiple graphics then I must manage them individually, is there any way to avoid this overhead?

Thank you for sharing and for the quick responses
0 Kudos
MarkBaird
Esri Regular Contributor
If the QA process goes to plan you should see 10.1.1 in January.  We are currently testing prior to release.

The MultiLayerSymbol won't work for what you are trying to achieve at the moment.  The purpose of the class is to identity the type of a graphic which is used to display MIL-STD-2525C or App6B symbols.

If you want to move or highlight your graphics then they must be processed individually.  This isn't going to be a big overhead on your application though, as this is exactly what the graphics layer is designed for.  We have proven the graphics layer animating thousands of graphics so your sweep shouldn't present too much of a problem.  You just need to write efficient code which doesn't use "new Class" repeatedly in loops for example.

In terms of highlight, 10.1.1 has a much improved mechanism for performing this over the existing SelectionSymbol.  You can now simply select a graphic and is shows a glow (configurable colour) around the graphic.  The SelectionSymbol is of course still supported.
0 Kudos