Drawing Military Symbols on Map

2020
1
10-02-2019 08:47 PM
JerryChen
New Contributor III

I'm using ArcGIS JSAPI 4.12 and wishing to use Spatial Illusions to draw military symbols on map.

When I add milsymbol.js to script, the console returns error Uncaught SyntaxError: Cannot use import statement outside a module, so I add type="module" to the script, the it returns Uncaught ReferenceError: ms is not defined.

Here's my code:

<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/css/main.css">
<script src="https://js.arcgis.com/4.12/">
</script><script type="module" src="milsymbol-2.0.0/src/milsymbol.js"></script>

<script>
        require([
          "esri/Map",
          "esri/views/MapView",
          "esri/layers/MapImageLayer",
          "esri/layers/FeatureLayer"
        ], function (Map, MapView, MapImageLayer, FeatureLayer) {
             var symbol = new ms.Symbol("SFG-UCI----D", { size: 30 }).asCanvas(3);
            var map = new Map({
                basemap: "topo-vector"
            });             
            var view = new MapView({
                container: "viewDiv",
                map: map,
                center: [121, 23],
                zoom: 7
            });
        });
    </script>

So, whether I add type="module" or not, there's always errors. However, in the official document of Spatial Illusions, there's no type="module" in the script. I'm now really confused, how do they manage to get it work without adding the type?

milsymbol.js

import { ms } from "./ms.js";import Symbol from "./ms/symbol.js";ms.Symbol = Symbol;export { ms };
1 Reply
ALOKRANJAN
New Contributor

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>2D Milsymbol Editor Final</title>

<link rel="stylesheet" href="https://js.arcgis.com/3.29/esri/css/esri.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.29/dijit/themes/claro/claro.css">

<script src="https://js.arcgis.com/3.29/"></script>
<script src="http://xxxxxxxx:8080/tacticalTactical/milsymbol2D.js"></script>
<link rel="stylesheet" href="http://xxxxxxxx:8080/tacticalTactical/milsymbol-unit-generator.css" type="text/css">
<script src="http://xxxxxxxx:8080/tacticalTactical/milsymbol-unit-generator.js"></script>
<script src="Scripts/LayoutManager.js"></script>
<link rel="stylesheet" type="text/css" href="CSS/Main.css"/>
<script>
var myMap;
var graphictactical;
var graphicLayertactical;
var graphicLayertacticalPicker;
var symbolFullList;
var svgGlobaleCodeImg;
var pElementId;
var editToolbar, ctxMenuForGraphics, ctxMenuForMap;
var tacticalFeatureLayer;
var queryParams;
var pictureMarkerSymbol;
var graphic;
var currentFeature = [];
var loadFeature = [];
var moveFeature = [];
var deleteFeature = [];
var globalSavePlanName;
var globalSaveAsPlanName;
var currentCount;
var myTacticalSymbol;
var moveGraphicFeature;
var currentGraphic;

require([
"esri/map",
"esri/geometry/Point",
"esri/geometry/Polygon",
"esri/graphic", "dojo/_base/array",
"esri/symbols/PictureMarkerSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/layers/GraphicsLayer",
"esri/layers/FeatureLayer", "esri/tasks/query",
"esri/toolbars/edit",
"dijit/Menu", "dijit/MenuItem",
"dojo/domReady!"
], function (
Map,
Point, Polygon, Graphic, arrayUtils,
PictureMarkerSymbol, SimpleMarkerSymbol, GraphicsLayer, FeatureLayer, Query ,Edit, Menu, MenuItem
) {

pictureMarkerSymbol = PictureMarkerSymbol;
graphic = Graphic;

myMap = new Map("viewDiv",
{
basemap: "streets",
center: [-80, 35],
zoom: 3,
sliderPosition: "top-right"
});

dojo.connect(myMap, "onClick", addGraphicsSVG);

myMap.on("load", createToolbarAndContextMenu);


graphicLayertactical = new esri.layers.GraphicsLayer();
myMap.addLayer(graphicLayertactical);

graphicLayertacticalPicker = new esri.layers.GraphicsLayer();
myMap.addLayer(graphicLayertacticalPicker);


tacticalFeatureLayer = new FeatureLayer("https://xxxxxxx/server/rest/services/xxxxxxl/FeatureServer/0", {
//mode: FeatureLayer.SELECTION_NEW,
outFields: ["*"],
visible: false
});

myMap.addLayer(tacticalFeatureLayer);

initSymbols(symbolFullList);

queryParams = new esri.tasks.Query();

currentCount = 0;


// Adding Plan into DropDown list - Tactical Plan Load
addTacticalPlan(queryParams, tacticalFeatureLayer);


cbTacticalPlanLoad.onchange = function ()
{
var planNameValue = document.getElementById("cbTacticalPlanLoad").value;

document.getElementById("txtSave").value = planNameValue;

globalSavePlanName = planNameValue;


};

// Save Tactical Plan
saveBtnTacticalPlan.onclick = function () {


if (globalSavePlanName != "") {

saveTacticalFeature(currentFeature, globalSavePlanName);
}
else {
alert("Please fill Plan Name in order to save");
}

};

// Save As Tactical Plan
saveAsBtnTacticalPlan.onclick = function () {

globalSaveAsPlanName = document.getElementById("txtSaveAs").value;

// alert(globalSaveAsPlanName);

if (globalSaveAsPlanName != "")
{

saveTacticalFeature(currentFeature, globalSaveAsPlanName);
}
else {
alert("Enter Tactical Plan");
}


};

// Calling Save plan from Save and SaveAs Button
function saveTacticalFeature(pCurrentFeatures, pPlanName)
{
//
var addedFeatures = pCurrentFeatures.map(function (item) {
var mappedItem = item;
mappedItem.attributes["MilitarySymbologyCode"] = item.attributes.svgCode;
mappedItem.attributes["PlanName"] = pPlanName;
return mappedItem;
});

var promise = tacticalFeatureLayer.applyEdits(addedFeatures, null, null);
}

function updateCurrentFeature(pSelected) {

// console.log("Current Graphic 1 " + pSelected.geometry.x);

// console.log("Selected Graphic 2" + moveGraphicFeature.geometry.x);

// Update Feature Move geomtery

for (var i in currentFeature)
{

var tempID = moveGraphicFeature.attributes["svgCode"];

if (currentFeature.SVGCodeID == tempID)
{

console.log(currentFeature.SVGx);
console.log(currentFeature.SVGy);


currentFeature.SVGx = 102.35;
currentFeature.SVGy = 102.35;

console.log(currentFeature.SVGx);
console.log(currentFeature.SVGy);

}


}

// currentFeature.push({ SVGCodeID: moveGraphicFeature.attributes["svgCode"], SVGID: moveGraphicFeature.attributes["countID"], SVGStatus: "CURRENT", SVGx: pSelected.geometry.x, SVGy: pSelected.geometry.y})

// console.log("currentFeature: " + currentFeature);

}


// Add Graphics on Map CLick
function addGraphicsSVG(evt)
{
var svgTacticalCode = null;

// svgTacticalCode = svgGlobaleCodeImg;

svgTacticalCode = document.getElementById("svgCode").innerHTML;

console.log(svgTacticalCode);

console.log("SymbolEditorMenu : " + document.getElementById("SymbolEditorMenu").style.display);

if (document.getElementById("SymbolEditorMenu").style.display == "") {

addGraphicsOnCondition(graphicLayertactical, svgTacticalCode, evt);

} else if (document.getElementById("SymbolEditorMenu").style.display == "block") {

addGraphicsOnCondition(graphicLayertactical, svgTacticalCode, evt);

} else if (document.getElementById("SymbolPickerMenu").style.display == "block") {

addGraphicsOnCondition(graphicLayertactical, svgGlobaleCodeImg, evt);

}


}

// This function Calling by Add Graphics - On Map Click
function addGraphicsOnCondition(pGraphicsLayer, pSVGCode, pEvt)
{

var currentStatus = "CURRENT";

var mysymbol = new MS.symbol(pSVGCode, { size: 30 }).getMarker();

myTacticalSymbol = mysymbol;


var symboltactical = new PictureMarkerSymbol({

"url": mysymbol.toDataURL(),
"width": Math.floor(mysymbol.width),
"height": Math.floor(mysymbol.height),
});

currentCount += 1;

var currentGraphic = new Graphic(pEvt.mapPoint, symboltactical, { "countID": currentCount - 1, "Status": currentStatus, "svgCode": pSVGCode });
pGraphicsLayer.add(currentGraphic);
myMap.addLayer(pGraphicsLayer);

var tacticalCode = pSVGCode;
var tacticalLocationX = pEvt.mapPoint.x.toString();
var tacticalLocationY = pEvt.mapPoint.y.toString();

// console.log(tacticalCode + " " + tacticalUser + " " + tacticalLocationX + " " + tacticalLocationY);

console.log("pGraphicsLayer" + pGraphicsLayer);

console.log("currentCount" + currentCount);

var feature = { SVGCodeID: tacticalCode, SVGID: currentCount - 1, SVGStatus: currentStatus, SVGx: tacticalLocationX, SVGy: tacticalLocationY, svgGemoetry: pEvt.mapPoint };
currentFeature.push(currentGraphic)

console.log("svgFeature: " + currentFeature);
}

function createToolbarAndContextMenu() {

editToolbar = new Edit(myMap);
dojo.connect(editToolbar, 'onGraphicMoveStop', handleGraphicEditStop);

myMap.on("click", function (evt) {
editToolbar.deactivate();
});


createGraphicsMenu();
}

function handleGraphicEditStop(graphic)
{

currentGraphic = new esri.Graphic(graphic.geometry, graphic.symbol);

console.log("currentGraphic Function Call " + currentGraphic.geometry.x);

updateCurrentFeature(currentGraphic);
}


function createGraphicsMenu() {


ctxMenuForGraphics = new Menu({});


ctxMenuForGraphics.addChild(new MenuItem({
label: "Move",
onClick: function ()
{
editToolbar.activate(Edit.MOVE, selected);
moveGraphicFeature = null;
moveGraphicFeature = selected;

console.log("moveGraphicFeature : " + moveGraphicFeature.geometry.x);

// updateCurrentFeature(selected);
}
}));


ctxMenuForGraphics.addChild(new MenuItem({
label: "Delete",
onClick: function () {
graphicLayertactical.remove(selected);
}
}));


ctxMenuForGraphics.startup();

graphicLayertactical.on("mouse-over", function (evt) {
// We'll use this "selected" graphic to enable editing tools
// on this graphic when the user click on one of the tools
// listed in the menu.
selected = evt.graphic;

// Let's bind to the graphic underneath the mouse cursor
ctxMenuForGraphics.bindDomNode(evt.graphic.getDojoShape().getNode());
});

graphicLayertactical.on("mouse-out", function (evt)
{
// console.log("mouse-out" + evt)
ctxMenuForGraphics.unBindDomNode(evt.graphic.getDojoShape().getNode());
});
}


});


</script>

<script type="text/javascript">

function show(elementId) {

document.getElementById("SymbolEditorMenu").style.display = "none";
document.getElementById("SymbolProcessMenu").style.display = "none";
document.getElementById("SymbolPickerMenu").style.display = "none";
document.getElementById(elementId).style.display = "block";
pElementId = null;
pElementId = elementId;
}


function showSelection(checkedID) {

if (document.getElementById('rdLoad').checked)
{

document.getElementById("myFormLoad").style.display = "none";
document.getElementById("myFormSave").style.display = "none";
document.getElementById("myFormSaveAs").style.display = "none";
document.getElementById(checkedID).style.display = "block";
} else if (document.getElementById('rdSave').checked) {

document.getElementById("myFormLoad").style.display = "none";
document.getElementById("myFormSave").style.display = "none";
document.getElementById("myFormSaveAs").style.display = "none";
document.getElementById(checkedID).style.display = "block";
} else if (document.getElementById('rdSaveAs').checked) {

document.getElementById("myFormLoad").style.display = "none";
document.getElementById("myFormSave").style.display = "none";
document.getElementById("myFormSaveAs").style.display = "none";
document.getElementById(checkedID).style.display = "block";
}

}

</script>

<script>

function codeToSymbol(code) {
return mysymbol = new MS.symbol(code, { size: 30 }).getMarker();
}


function loadJSON(path, success, error) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
if (success)
success(JSON.parse(xhr.responseText));
// alert("Hello STart");
} else {
if (error)
error(xhr);
}
}


};
xhr.open("GET", path, true);
xhr.send();
}

//

function initSymbols(militarySymbolArray) {


var selectTacticalA = document.getElementById("tacticalIdA");
var selectTacticalB = document.getElementById("tacticalIdB");

var optionAir = document.createElement('option');
var optionGround = document.createElement('option');
var optionSEA = document.createElement('option');
var optionSUBSURFACE = document.createElement('option');


var optionFriend = document.createElement('option');
var optionHOSTILE = document.createElement('option');
var optionUNKNOWN = document.createElement('option');
var optionNEUTRAL = document.createElement('option');

optionFriend.text = "FRIEND";
optionFriend.value = 1;
selectTacticalA.add(optionFriend, 1);

optionHOSTILE.text = "HOSTILE";
optionHOSTILE.value = 2;
selectTacticalA.add(optionHOSTILE, 2);

optionUNKNOWN.text = "UNKNOWN";
optionUNKNOWN.value = 3;
selectTacticalA.add(optionUNKNOWN, 3);

optionNEUTRAL.text = "NEUTRAL";
optionNEUTRAL.value = 4;
selectTacticalA.add(optionNEUTRAL, 4);


optionAir.text = "AIR";
optionAir.value = 1;
selectTacticalB.add(optionAir, 1);

optionGround.text = "GROUND";
optionGround.value = 2;
selectTacticalB.add(optionGround, 2);

optionSEA.text = "SEA";
optionSEA.value = 3;
selectTacticalB.add(optionSEA, 3);

optionSUBSURFACE.text = "SUBSURFACE";
optionSUBSURFACE.value = 4;
selectTacticalB.add(optionSUBSURFACE, 4);

// console.log("militarySymbolArray" + militarySymbolArray);

loadJSON('https://localhost/tacticalTactical/jsonSVGTactical.json',
function (data) {

militarySymbolArray = data;
// console.log("militarySymbolArray Total Lenght : " + militarySymbolArray.length);

var tacticalIMG, container = document.getElementById("tacticalTblStyleContainer");

console.log("Before Loop : " + militarySymbolArray.length);

tacticalIdB.onchange = function () {

clearTacticalcontainer(container);

var tacticalIDA = document.getElementById("tacticalIdA").value;
var tacticalIDB = document.getElementById("tacticalIdB").value;

var tacticalIDValueA = document.getElementById("tacticalIdA").options[tacticalIDA].text;

var tacticalIDValueB = document.getElementById("tacticalIdB").options[tacticalIDB].text;

console.log("tacticalIDValue After : " + tacticalIDValueA + " : " + tacticalIDValueB);

for (let i = 0; i < militarySymbolArray.length; i++)
{
// militarySymbolArray.length

var svgCateGoryA = militarySymbolArray.CategoryA;
var svgCateGoryB = militarySymbolArray.CategoryB;

if (svgCateGoryA.toUpperCase() == tacticalIDValueA && svgCateGoryB.toUpperCase() == tacticalIDValueB) {


var svgCodeImg = militarySymbolArray.SVGCodeID;
var svgImage = codeToSymbol(svgCodeImg);

tacticalIMG = document.createElement("img");
tacticalIMG.className = "pickerItemIcon";
tacticalIMG.id = svgCodeImg;
tacticalIMG.src = svgImage.toDataURL();

tacticalIMG.height = "50";
tacticalIMG.width = "50";

tacticalIMG.onclick = function () {

svgCodeCapture(this.id);

};

container.appendChild(tacticalIMG);
}
else
{
console.log("AIR Else : " + svgCateGoryA);
console.log("FRIEND Else : " + svgCateGoryB);
}


};

}


// console.log("After Added Arry : " + militarySymbolArray);
},
function (xhr) {
console.error(xhr);
}

);


}

function svgCodeCapture(pSvgGlobaleCodeImg) {
svgGlobaleCodeImg = null;
svgGlobaleCodeImg = pSvgGlobaleCodeImg;
}

function clearTacticalcontainer(pContainer) {

try {
while (pContainer.firstChild)
pContainer.removeChild(pContainer.firstChild);

}
catch (ex) {
pContainer.innerHTML = ex;
}
}

</script>

<script>

// Adding Tactical Plan name - Call by Map Onload
function addTacticalPlan(queryParams, featureLayer)
{

queryParams.outFields = ["PlanName"];
queryParams.where = "1=1";
queryParams.returnGeometry = false;
queryParams.returnDistinctValues = true;

featureLayer.queryFeatures(queryParams, function (response) {

addPlanInSelection(response);

});


}

function addPlanInSelection(response)
{


var features = response.features;
// console.log(features.length);

for (var i = 0; i < features.length; i++)
{
var _feature = features;

var option = document.createElement("option");
option.text = _feature.attributes["PlanName"];
option.value = _feature.attributes["PlanName"];
var select = document.getElementById("cbTacticalPlanLoad");
select.appendChild(option);


}

}

// Load all Tacical Plan - Plan Name condition
function loadPlanOnMap() {

var pQueryParams = new esri.tasks.Query();
var pFeatureLayer = tacticalFeatureLayer;

var planNameStr = document.getElementById("cbTacticalPlanLoad").value;

pQueryParams.returnGeometry = true;
pQueryParams.outFields = ["*"];

pQueryParams.where = "PlanName='" + planNameStr + "'";


pFeatureLayer.queryFeatures(pQueryParams, function (response) {

addPlanOnMap(response);

});
}

function addPlanOnMap(pResponse)
{

alert("Hello");

graphicLayertactical.clear();

var features = pResponse.features;

for (var i = 0; i < features.length; i++)
{
var _feature = features;

if (_feature.geometry.x != "NaN")
{

var mysymbol = new MS.symbol(_feature.attributes["MilitarySymbologyCode"], { size: 30 }).getMarker();

console.log(_feature.geometry);

var symboltactical = new pictureMarkerSymbol({

"url": mysymbol.toDataURL(),
"width": Math.floor(mysymbol.width),
"height": Math.floor(mysymbol.height),
});

var symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 10,
new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID,
new esri.Color([255, 0, 0]), 1),
new esri.Color([0, 255, 0, 0.25]));

myMap.graphics.add(new graphic(_feature.geometry, symboltactical));
}


}

}

</script>

</head>

<body class="mdc-typography" onload="milsymbolUnitGenerator()" >

<div id="viewDiv">
<div style='float: right;'>Share</div>
<div id='SymbolPicker' class="symbolPanel">


<table id="tacticalTblStyle">

<tr>
<th onclick="show('SymbolEditorMenu');">Editor</th>
<th onclick="show('SymbolProcessMenu');">Plan Manager</th>
<th onclick="show('SymbolPickerMenu');">Picker</th>
</tr>


</table>

<div id='SymbolEditorMenu' style="display:block;">

<section>
<div class="demo-tabs__scroller">
<div id="tab-bar-scroller" class="mdc-tab-bar-scroller">
<div class="mdc-tab-bar-scroller__indicator mdc-tab-bar-scroller__indicator--back">
<a class="mdc-tab-bar-scroller__indicator__inner material-icons" href="#" aria-label="scroll back button">
<svg fill="rgba(0, 0, 0, .54)" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z" />
<path d="M0-.5h24v24H0z" fill="none" />
</svg>
</a>
</div>
<div class="mdc-tab-bar-scroller__scroll-frame">
<nav id="scrollable-tab-bar" class="mdc-tab-bar mdc-tab-bar-scroller__scroll-frame__tabs custom-indicator-tab-bar">
<a role="tab" aria-controls="panel-1" class="mdc-tab" href="#panel-1">MIL-STD-2525C</a>
<a role="tab" aria-controls="panel-2" class="mdc-tab" href="#panel-2">APP-6 B</a>
<a role="tab" aria-controls="panel-3" class="mdc-tab" href="#panel-3">MIL-STD-2525D</a>
<a role="tab" aria-controls="panel-4" class="mdc-tab" href="#panel-4">APP-6 D</a>
<span class="mdc-tab-bar__indicator"></span>
</nav>
</div>
<div class="mdc-tab-bar-scroller__indicator mdc-tab-bar-scroller__indicator--forward">
<a class="mdc-tab-bar-scroller__indicator__inner material-icons" href="#" aria-label="scroll forward button">
<svg fill="rgba(0, 0, 0, .54)" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z" />
<path d="M0-.25h24v24H0z" fill="none" />
</svg>
</a>
</div>
</div>
</div>
</section>

<section class="content">
<div class="panels">
<div class="panel panel-2525c" id="panel-1" role="tabpanel" aria-hidden="true">

</div>
<div class="panel panel-app6b" id="panel-2" role="tabpanel" aria-hidden="true">

</div>
<div class="panel panel-2525d" id="panel-3" role="tabpanel" aria-hidden="true">

</div>
<div class="panel panel-app6d" id="panel-4" role="tabpanel" aria-hidden="true">

</div>
</div>
</section>

</div>

<div id='SymbolProcessMenu' style="display:none;">

<div class="form-container" id="myFormRadio">


<h1>Tactical Plan - Select Process </h1>


<div id="selection" class="form-container">
<label>

<input type="radio" id="rdLoad" name='tactical' onclick="showSelection('myFormLoad');" value="Load" checked /> <strong> Load </strong>

</label>
<label>

<input type="radio" id="rdSave" name='tactical' value="Save" onclick="showSelection('myFormSave');" /> <strong> Save </strong>
</label>
<label>

<input type="radio" id="rdSaveAs" name='tactical' value="SaveAs" onclick="showSelection('myFormSaveAs');" /> <strong> Save As </strong>
</label>
</div>

</div>

<div class="form-container" id="myFormLoad" style="display:block;">


<select id="cbTacticalPlanLoad" name="cbTacticalPlanLoad" class="btn Load">
<option>SELECT</option>
</select>


<h1> </h1>

<button type="button" class="btn Load" onclick="loadPlanOnMap()">Load</button>

</div>

<div class="form-container" id="myFormSave" style="display:none;">


<input type="text" id="txtSave" style="background-color :antiquewhite;" disabled />

<h1> </h1>


<button type="button" id="saveBtnTacticalPlan" class="btn Load">Save</button>

</div>

<div class="form-container" id="myFormSaveAs" style="display:none;">

<input type="text" id="txtSaveAs" style="background-color :antiquewhite;" />


<h1> </h1>
<button type="button" id="saveAsBtnTacticalPlan" class="btn Load">Save As</button>

</div>

</div>

<div id='SymbolPickerMenu' style="display:none;" class="form-container">

<div>
<table style="width:100%">
<tr>
<td class="pickerSelectorLabal">
<label> <strong> Afliation : </strong></label>
</td>
<td class="pickerSelectorSelect">
<select id="tacticalIdA" name="TaticalA" class="btn Load">
<option>SELECT</option>
</select>
</td>
</tr>
</table>

</div>
<div>
<table style="width:100%">
<tr>
<td class="pickerSelectorLabal">
<label><strong> Dimension : </strong> </label>
</td>
<td class="pickerSelectorSelect">
<select id="tacticalIdB" name="TaticalB" class="btn Load ">
<option>SELECT</option>
</select>
</td>
</tr>
</table>
</div>

<div class="verticalSplit"></div>

<div id="tacticalTblStyleContainer" style="height:100%;overflow:auto"></div>

</div>

</div>

</div>


</body>


</html>

0 Kudos