-
Notifications
You must be signed in to change notification settings - Fork 25
Developer's Guide
MIL SYMBOLOGY JAVASCRIPT RENDERER
DEVELOPER’S GUIDE
Revision History
Initial Document 12/18/2012
Updated 02/24/2014
Updated 03/17/2014 - New ImageInfo function documented.
Updated 03/25/2014 - System Requirements section updated.
Updated 04/25/2014 - Added info on new ICON attribute.
Updated 08/03/2014 - Added info on new LookAtTag attribute.
Updated 10/31/2014 - Added GeoJSON format and noted new toSVG function off of the ImageInfo object
Updated 08/26/2016 - Added new feature SVG format information for singlepoints
Updated 10/21/2016 - Updated information on rendering multipoints with web workers
Updated 12/21/2018 - Fixed TOC links
1 Overview
1.1 Features
1.2 System Requirements
2 Setting up the JavaScript Renderer for Use
2.1 Compile the mil-sym-js project
2.2 Loading the JavaScript Renderer in your page
3 Rendering
3.1 Configuring the Renderer for your Needs
3.2 Singlepoint Icon Symbology
3.2.1 Setting Modifiers
3.2.2 Setting Attributes
3.2.3 Getting your Image (ImageInfo)
3.2.4 Rendering Your Image via HTML5 Canvas
3.2.5 Rendering Your Image via Data URL
3.2.6 Rendering Your Image via jQuery plugin
3.2.7 Make Sure The Fonts Are Loaded Before Trying To Render
3.2.8 Rendering Singlepoints as SVG
3.3 Multipoint Symbology
3.3.1 Required Parameters for Multipoint Symbology
3.3.2 Rendering Multipoint Symbology in a Web Worker
4 SymbolUtilties
4.1 getBasicSymbolID()
4.2 hasModifier()
4.3 isMultiPoint()
5 The Symbol Definition Table
5.1 hasSymbolDef()
5.2 getSymbolDef()
The JavaScript versions of the Mil-Std Symbology Renderer supports rendering of single & multi point symbology. Single points as an html5 canvas object or a data url. Multi points as kml.
Only IE & Firefox are tested on a regular basis but the other browsers listed seem to work well.
Windows 7: IE 9+ or Firefox 16+ or Chrome 32+ or Opera 21+
OS X: Chrome 14+, Opera 11.6+, Safari 7
Debian 6: Opera 12+, Firefox 12+, Chrome 30+
IOS 7.1: Safari
Android 4.3: Chrome 33+
Windows Phone 8: IE
See compatibility chart for more detail: Single Point Rendering Web Browser Compatibility Chart
Should work on any current browser
This project builds with Ant resulting in two JavaScript files. One has all of the JS code combined into one file. The other is a minified version of the first file. (i.e. sm-bc.js & sm-bc.min.js)
Open a command prompt to the root folder of the repository on your local machine and enter:
ant clean
ant concat sm-bc minify samples
"sm-bc" represents what you rendering capabilities you want.
• s: singlepoint (Canvas)(jquery plugin for singlepoint rendering only available in singlepoint only builds)
• m: multipoints (KML, GeoJSON, GeoCanvas, SVG)
• sm: both
• sv: singlepoints(SVG)
• svm: singlepoints(SVG) and multipoints
• b: 2525B support
• c: 2525C support
• bc: both
• allFlavors: every variation will be generated
Running "ant concat sm-bc minify samples" would result in the following files being placed in the "dist" folder:
• fonts (contains fonts needed for singlepoint rendering)
• renderer.css (to load the font files for singlepoint canvas rendering)
• jquery-[version].min.js
• multiPointTester1.html (renders kml for a couple multipoint symbols)
• multiPointTester2.html (renders kml for a couple multipoint symbols in a loop to test performance)
• singlePointTester.html (renders a couple of singlepoint symbols to the page)
• single-point-plugin.html (show sample usage with jQuery)
• sm-bc.js (concatenated renderer code)
• sm-bc.min.js (concatenated & minified renderer code)
The top of your html page should look similar to the snippet below:
<!DOCTYPE html>
<html>
<head>
<!-- Meta line required for IE-->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>single point tester</title>
<link rel="stylesheet" href="renderer.css" type="text/css" charset="utf-8" />
<script src="sm-bc.min.js" type="text/javascript" ></script>
This loads the required font files via the css file and pulls in the concatenated JavaScript renderer file.
The fonts are necessary for html5 canvas rendering. Make sure fonts are loaded before rendering.
The “RendererSettings” object will let you set some default rendering values. It is accessible at "armyc2.c2sd.renderer.utilities.RendererSettings”.
RendererSettings.setSymbologyStandard(RendererSettings.Symbology_2525C);
RendererSettings.setTextOutlineWidth(1);
Singlepoint rendering is provided by the MilStdIconRenderer object
You would typically render a single point via the code snippet below:
var ii = armyc2.c2sd.renderer.MilStdIconRenderer.Render("SUGDUSAT----***",modifiers);
You also have the option to render single point as SVGs.
“modifiers” is an object which can contain Mil-Std modifiers and rendering attributes. The modifiers can be set like this:
var mu = armyc2.c2sd.renderer.utilities.ModifiersUnits
var modifiers = {};
modifiers[mu.C_QUANTITY]=10;
modifiers[mu.H_ADDITIONAL_INFO_1] = "H";
modifiers[mu.H1_ADDITIONAL_INFO_2] = "H1";
//or like this for Single Point Tactical Graphics:
modifiers[armyc2.c2sd.renderer.utilities.ModifiersTG.H2_ADDITIONAL_INFO_3] = "H2";
ModifiersUnits.js and ModifiersTG.js contain all the modifier key constants for units and tactical graphics.
Attributes will override any defaults set in RendererSettings.
var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes;
modifiers[msa.PixelSize]=60;
modifiers[msa.KeepUnitRatio]=true;
modifiers[msa.SymbologyStandard] = RendererSettings.Symbology_2525Bch2_USAS_13_14;
MilStdAttributes.js contains all the modifier key constants for the attributes that can be applied to rendering.
PixelSize = Default size 35. This is the size of the core symbol (not including modifiers) which will fit within a 35x35 pixel space.
LineColor, FillColor and IconColor, if you want to override the default affiliation colors, do something like:
modifiers[msa.LineColor]="#FF0000”
no alpha value supported at the moment.
KeepUnitRatio If true (defaults true), the symbols will have proper proportions in relation to each other (see table VIII in the MilStd 2525C). Hostile airspace, with a size of 35, will end up being 25.667 wide by 30.333 high, hostile unit will be 33.6x33.6 ((35/1.5)*1.44). If false, image will fill the pixel space as much as it can without distorting the shape.
SymbologyStandard Takes RendererSettings.Symbology_2525Bch2_USAS_13_14 or RendererSettings.Symbology_2525C for a value. This parameter determines which rendering standard to use. “2525B” represents 2525Bch2 with USAS 13-14. “2525C” represents 2525C with USAS 13-14.
ICON=true, will result in a symbol that is stripped of display & text modifiers so that you get just the core symbol. This is useful for use as tree-node icons. If you had all the detail, the symbols would be so small it would be hard for the user to determine what symbol they're looking at.
LookAtTag=true, will generate and add a "" tag to multipoint kml.
Looking back at the call to render, you’ll see you get an object back. This object contains the image along with some information about the image.
var ii = armyc2.c2sd.renderer.MilStdIconRenderer.Render("SUGDUSAT----***",modifiers);
What is returned is the “ImageInfo” object (armyc2.c2sd.renderer.utilities.ImageInfo). It has the following functions available.
“getImage()” returns an HTML5 canvas object which you can use to draw to another canvas.
“toDataUrl()” returns a base64 string that represents the image.
“getCenterPoint()” returns a point object that represents where the image should be centered if rendered on a coordinate based map. {x:Number,y:Number}
“getSymbolBounds()” returns a rectangle object that represents to area in the image that the core symbol (not including any modifiers) exists. {x:Number,y:Number,width:Number,height:Number}
“getImageBounds()” returns a rectangle object that represents the size of the entire image. {x:Number,y:Number,width:Number,height:Number}
“getSquareIcon()” returns an HTML5 canvas object where space is added as necessary to make the image a square so that it will fit nicely in a tree node or for any other situation where consistent image size is important. So if you draw a friendly ground unit and the resultant image is 16x10, this function will return a version that is 16x16.
“getCenteredImage()” will return an image such that the anchor point or center point of the symbol is placed in the center of the overall image. So as long as the image is centered on the desired location, the symbol will be placed properly. Not recommended. It would be better to use “getImage()” with “getCenterPoint()” so that you can properly place the symbol using offsets.
"toSVG()" will return a string containing an SVG tag. The image is embedded as a dataurl within the SVG. No actual vector data is present.
In your html you’ll need a canvas object.
<canvas id="preview" width="650" height="200"></canvas>
In your JavaScript, you can use the following code to render.
var preview = document.getElementById("preview");
var ctx = preview.getContext('2d');
ctx.drawImage(ii.getImage(), 0, 0);
Have an image tag somewhere in your html:
<img id="urlexample" src="" alt="test" height="35" width="35">;
Modify the image tag with this JavaScript code:
//render via Data Url
modifiers = new Object();
modifiers[msa.PixelSize]=60;
ii = armyc2.c2sd.renderer.MilStdIconRenderer.Render("SHAPWMSA-------",modifiers);
var width = ii.getImageBounds().getWidth();
var height = ii.getImageBounds().getHeight();
var img = document.getElementById("urlexample");
img.src = ii.toDataUrl();
img.width = width;
img.height = height;
Note that this only works with the single point only compilations of the JavaScript renderer.
<html>
<head>
<title>Renderer jQuery Plugin Example</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="renderer.css" type="text/css" charset="utf-8" >
<script src="jquery-1.10.2.min.js" type="text/javascript"></script>
<script src="s-b.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).bind("load", function() {
// Invoke render2525() on jQuery objects that match canvas tags
// when symbols on a canvas need to be drawn or re-drawn
$("canvas").render2525();
});
</script>
</head>
<body>
<!--
To display a symbol, canvas elements must contain a valid
15-character symbol code in the data-symbol-code attribute.
The optional data-pixel-size attribute controls the size of
the symbol.
-->
<canvas data-symbol-code="SHAPCF---------" data-pixel-size="64"></canvas>
</body>
</html>
Depending how things are loaded, the fonts may not be ready in time for your first render attempt. The following sample code will check to make sure the milstd fonts are loaded. You may need to modify this code to meet your needs. This code was taken from singlePointTester2.html
var fontCheckTimer = null;
var retries = 15;
var attempts = 0;
var fontsLoaded = false;
function checkFonts()
{
if(armyc2.c2sd.renderer.utilities.RendererUtilities.fontsLoaded())
{
console.log("fonts loaded");
fontsLoaded = true;
}
else if(attempts < retries)
{
attempts++;
fontCheckTimer = setTimeout(checkFonts, 1000);
console.log("fonts loading...");
//sometimes font won't register until after a render attempt
armyc2.c2sd.renderer.MilStdIconRenderer.Render("SHAPWMSA-------",{});
}
else
{
console.log("fonts didn't load or status couldn't be determined for " + retries + " seconds.");
//Do actions to handle font failure to load scenario
}
}
if(armyc2.c2sd.renderer.utilities.RendererUtilities.fontsLoaded()){
console.log("fonts loaded fast");
fontsLoaded = true;
}
else
{
fontCheckTimer = setTimeout(checkFonts, 1000);
}
Looking back at the call to render, you’ll see you get an object back. This object contains the image along with some information about the image. You'll need to use one of the files starting with "sv" like sv-bc.js or svm-bc.js. sv-bc, sv-b and sv-c are safe for use in a web worker. There's an example of how that can work in the release zip file
var si = armyc2.c2sd.renderer.MilStdSVGRenderer.Render("SUGDUSAT----***",modifiers);
What is returned is the “SVGInfo” object (armyc2.c2sd.renderer.utilities.SVGInfo). It has the following functions available.
“getSVG()” returns a string representation of the SVG element.
getSVGDataURI()” Returns a string like: "data:image/svg+xml;base64,[SVG string after run through btoa()]" which can be assigned like can assign like "image.src = SVGInfo.getSVGDataURI()".
getAnchorPoint()” returns a point object that represents where the image should be centered if rendered on a coordinate based map. {x:Number,y:Number}
“getSymbolBounds()” returns a rectangle object that represents to area in the image that the core symbol (not including any modifiers) exists. {x:Number,y:Number,width:Number,height:Number}
####3.2.8.5 getSVGBounds()
“getSVGBounds()” returns a rectangle object that represents the size of the entire svg. {x:Number,y:Number,width:Number,height:Number}
Multipoint rendering is provided by the SECWebRenderer object
KML rendering example:
var formatGeoJSON = 2;
var formatKML = 0;
var rendererMP = sec.web.renderer.SECWebRenderer;
var pixelWidth = 800;
var pixelHeight = 600;
//SECTOR RANGE FAN EXAMPLE/////////////////////////////////
var symbolCode3 = "GFFPAXS---****X"; //sector range fan
var kml3=null;
var json3=null;
var controlPoints3 = "66.26700036208742,30.62755038706961";// point format “x,y x,y x,y…”
/*bbox The viewable area of the map. Passed in the format of a string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." Not required but can speed up rendering in some cases.//*/
var bbox3 = "66.25,30.627,66.27,30.63";//whole symbol will be calculated
var scale3 = 50000.0;
//distance (AM), azimuth (AN), and altitudeDepth (X) can all have multiple values so they are enclosed in brackets.
//you can set with the string constants from “ModifiersTG”.
var mtg = armyc2.c2sd.renderer.utilities.ModifiersTG;
modifiers = {};
modifiers[mtg.AM_DISTANCE] = [300,1000];//AM, AN, & X are the only modifiers that are passed as arrays
modifiers[mtg.AN_AZIMUTH] = [315,45]; //The rest of the modifiers are String or Number values.
modifiers[mtg.X_ALTITUDE_DEPTH] = [0];
var msa = armyc2.c2sd.renderer.utilities.MilStdAttributes;
modifiers[msa.LineWidth]=8;
format = formatKML;
//RenderSymbol for Google Earth. KML format recommended.
kml3 = rendererMP.RenderSymbol("ID","Name","Description", symbolCode3, controlPoints3, "clampToGround",scale3, bbox3, modifiers,format);
format = formatGeoJSON;
//RenderSymbol2D for 2D maps, JSON Recommended for simpler output.
json3 = rendererMP.RenderSymbol2D("ID","Name","Description", symbolCode3, controlPoints3, pixelWidth, pixelHeight, bbox3, modifiers,format);
id = a unique identifier used to identify the symbol by Google map. The id will be the folder name that contains the graphic.
name = a string used to display to the user as the name of the graphic being created.
description = a brief description about the graphic being made and what it represents.
controlPoints = the vertices of the graphics that make up the graphic. They are passed in the format of a string, using decimal degrees separating lat and lon by a comma, separating coordinates by a space. The following format shall be used "x1,y1[,z1] [xn,yn[,zn]]...".
altitudeMode = indicates whether the symbol should interpret altitudes as above sea level or above ground level. Options are "clampToGround", "relativeToGround" (from surface of earth), "absolute" (sea level), "relativeToSeaFloor" (from the bottom of major bodies of water).
scale = a number corresponding to how many meters one meter of our map represents. A value "50000" would mean 1:50K which means for every meter of our map it represents 50000 meters of real world distance.
pixelWidth & pixelHeight = represents the width & height in pixels of the visible map area of a 2D map.
bbox = the viewable area of the map. Passed in the format of a string "lowerLeftX,lowerLeftY,upperRightX,upperRightY." example: "-50.4,23.6,-42.2,24.2"
modifiers = a JSON string representing all the possible symbol modifiers represented in the MIL-STD-2525C. Format of the string will be {"modifiers": {"attributeName":"value"[,"attributeNameN":"valueN"]...}}. The quotes are literal in the above notation. Example: {"modifiers": {"C":"4","Z":"300","AN":[100,200]}}
ModifiersTG.js contains all the modifier key constants for tactical graphics.
format = an enumeration: 0 for KML, 1 for JSON (deprecated), 2 for GeoJSON, 3 for GeoCanvas, 4 for DataURL, 6 for GeoSVG.
KML and GeoJSON are specifications for drawing shapes and text on a globe.
The GeoCanvas is just an object with a canvas and two geo coordinates (top left and bottom right) used to place the image on the map. DataURL returns those same two points but with a DataURL representation of the image instead of a canvas. Generating a DataURL is expensive so it is recommended to use the "GeoCanvas" output over the DataURL when possible.
//GeoCanvas
{image, geoTL, geoBR, width, height}//canvas, geocoord, geocoord, pixel width, pixel height
//DataURL
{dataURL, geoTL, geoBR, width, height}//canvas, geocoord, geocoord, pixel width, pixel height
GeoSVG is very similar and looks like:
//GeoSVG
{svg, geoTL, geoBR, bounds}//SVG string, geocoord, geocoord, bounds.width & bounds.height for pixel dimensions of the SVG.
symStd = a Mil-Std symbology enumeration: 0 for 2525Bch2, 1 for 2525C.
Recommended for Canvas output on a 3D map such. See "Canvas Converter ReadMe.txt" for a sample converter we created for Cesium. This helps the renderer to convert the geo coordinates into pixel coordinates and back so we can get the best output for your map window.
Only renderer versions starting with "m-", "svm-" and "savm-" support working in a web worker. Only KML, GeoJSON and GeoSVG output is supported for web workers. Canvas output in a web worker is not possible. In the .92 release zip file and later, there is a "MultiPointTesterWebWorker.html" and "MPWorker.js" file. Please use these as an example of how one might do multipoint rendering with a web worker. MPWorker supports single and batch render calls. You are not required to use MPWorker.js. It is there to use or to be a starting point to make your own web worker.
/* expected input format
var e.data = {};
e.data.id = "ID";
e.data.name = "Name";
e.data.description = "description";
e.data.symbolID = "SFGPU----------";//A 15 character symbolID corresponding to one of the graphics in the MIL-STD-2525C
e.data.points = controlPoints4;//like "66.26700036208742,30.62755038706961 66.27555681517738,30.64727776502703 66.25654247497746,30.64632704801704","x1,y1[,z1] [xn,yn[,zn]]...".
e.data.altMode = "absolute";//for 3D
e.data.scale = scale4;//for 3D like 50000.0; a number corresponding to how many meters one meter of our map represents. A value "50000" would mean 1:50K which means for every meter of our map it represents 50000 meters of real world distance.
e.data.bbox = bbox4;//like "66.25,30.60,66.28,30.65";"lowerLeftX,lowerLeftY,upperRightX,upperRightY."
e.data.modifiers = modifiers;
e.data.format = format;//0 for KML, 2 for GeoJSON, 6 for GeoSVG
e.data.pHeight = pixelHeight;//for 2D
e.data.pWidth = pixelWidth;//for 2D
e.data.converter = {} optional converter object for custom geoToPixel Conversion
e.data.fontInfo = {} required for SVG format only. Get from RendererSettings.getMPFontInfo();
*/
/* return object for KML or GeoJSON
{
id:e.data.id,//same as what was passed in
result:strOutput,//resultant kml,json or error message
format:e.data.format//format number or "ERROR" if there was a problem like missing required parameters
}
*/
/* return object for SVG
{
id:e.data.id,//same as what was passed in
result:{svg:dataURI,geoTL:{x,y}, geoBR:{x,y}, wasClipped:true/false, bounds:{x,y,width,height}}
format:e.data.format//format number or "ERROR" if there was a problem like missing required parameters
}
*/
/* expected input format for batch
var e.data = {};
e.data.altMode = "absolute";//for 3D
e.data.scale = scale4;//for 3D like 50000.0; a number corresponding to how many meters one meter of our map represents. A value "50000" would mean 1:50K which means for every meter of our map it represents 50000 meters of real world distance.
e.data.bbox = bbox4;//like "66.25,30.60,66.28,30.65";"lowerLeftX,lowerLeftY,upperRightX,upperRightY."
e.data.format = format;//0 for KML, 2 for GeoJSON, 6 for GeoSVG
e.data.pHeight = pixelHeight;//for 2D
e.data.pWidth = pixelWidth;//for 2D
e.data.converter = {} optional converter object for custom geoToPixel Conversion
e.data.fontInfo = {} required for SVG format only. Get from RendererSettings.getMPFontInfo();
e.data.batch = [{id:"ID",name:"name",description:"description",symbolID:"GFTPL-----****X",points:controlPoints,symStd:symStd,modifiers:{ModifiersTG.T_UNIQUE_DESIGNATION_1:"T",MilStdAttributes.LineColor:"#00FF00"}}];
*/
/* return objects for batch
{
//KML
[{id:batch.id,symbolID:symbolID,kml:"kml string"}]
//GeoJSON
[{id:batch.id,symbolID:symbolID,geojson:"geojson string"]
//SVG
[{id:batch.id,symbolID:symbolID,svg:dataURI,geoTL:geoCoordTL, geoBR:geoCoordBR, wasClipped:wasClipped}]
}
*/
armyc2.c2sd.renderer.utilities.SymbolUtilities is an object with various utility functions used to process symbolIDs. The two a user is most likely to use are below. Please look at the class for other functions that may be of use.
“getBasicSymbolID(symbolID)” will be used often with the other objects in the renderer. It will take a symbolID like “SFGPUCI----K***” and turn it into “SGUCI---*****”. Object like SymbolDefTable & UnitDefTable use the basic symbol ID for lookups.
“hasModifier(symbolID, modifier)” will tell you if the modifier is valid for a specific symbolID.
symbolID – a 15 character symbol code.
modifier – Can be one of the constants from the ModifiersUnits or ModifiersTG object.
Returns true or false.
Use like:
Var SymbolUtilities = armyc2.c2sd.renderer.utilities.SymbolUtilities;
var result = SymbolUtilities.hasModifier(symbolID, ModifiersUnits.B_ECHELON);
“isMultiPoint(symbolID, symStd)” will tell you if the modifier is valid for a specific symbolID.
symbolID – a 15 character symbol code.
symStd – a Mil-Std symbology enumeration: 0 for 2525Bch2, 1 for 2525C. Will use renderer default if not provided.
Returns true or false.
The SymbolDefTable object will provide information about the tactical graphics that can be drawn. (Appendix B in the MilStd 2525)
armyc2.c2sd.renderer.utilities.SymbolDefTable.getSymbolDef(symbolID, symStd)
This function takes the following parameters:
symbolID – a basic 15 character symbol ID code stripped of affiliation, status & modifiers.
symStd – 0 or 1 depending if you want a definition based on 2525B or 2525C.
Returns true if a symbol definition exists for the passed basic symbolID and symbology standard.
armyc2.c2sd.renderer.utilities.SymbolDefTable.getSymbolDef(symbolID, symStd)
This function takes the following parameters: symbolID – a basic 15 character symbol ID code stripped of affiliation, status & modifiers. symStd – 0 or 1 depending if you want a definition based on 2525B or 2525C.
This function will return an object with the following properties:
symbolID – a basic 15 character symbol ID code stripped of affiliation, status & modifiers.
minPoints – the minimum # of points the symbol can have.
maxPoints – the max # of points the symbol can have. Assume any value over 100 means infinite.
modifiers – a string like “T.T1.W.” which shows which modifiers the symbol can have.
drawCategory – an integer representing the type of symbol that is being drawn. These constants can be found in the SymbolDefTable.js. Based on these constants, you’ll know what symbols have required modifiers. For instance, DRAW_CATEGORY_TWO_POINT_RECT_PARAMETERED_AUTOSHAPE: 20, is a symbol that requires one AM value. These requirements are described in SymbolDefTable.js as well.