npm package: @hyssostech/arcgis-plugin
Description: ArcGIS JS API 4.29-based map adapter that renders STP symbols using ArcGIS Military Symbol Dictionary Renderer (MIL-STD-2525D). This plugin provides seamless integration between STP (Sketch Through Plan) symbols and ArcGIS's powerful military symbology re
Latest version: 0.1.0

# ArcGIS Server Map Plugin

ArcGIS JS API 4.29-based map adapter that renders STP symbols using ArcGIS Military Symbol Dictionary Renderer (MIL-STD-2525D). This plugin provides seamless integration between STP (Sketch Through Plan) symbols and ArcGIS's powerful military symbology rendering capabilities.

## Features

- **Military Symbol Rendering**: Uses ArcGIS DictionaryRenderer with MIL-STD-2525D standard
- **Multiple Geometry Support**: Point, multipoint, line, and polygon symbols
- **Interactive Features**: Click selection, freehand drawing, and ink layer
- **Flexible Configuration**: Support for custom MIL-STD-2525 dictionaries via URL or Portal Item ID
- **Direct StpSymbol Integration**: Uses StpSymbol objects directly as graphic attributes for optimal performance

## Field Mapping Architecture

The plugin maps StpSymbol properties to ArcGIS DictionaryRenderer fields:

| Dictionary Field | StpSymbol Property | Description |
|------------------|-------------------|-------------|
| `sidc` | `deltaSIDC` | MIL-STD-2525D symbol identifier (computed from `sidc.partA/B/C`) |
| `uniquedesignation` | `designator1` | Primary unit designator |
| `higherformation` | `parent` | Parent unit designator |
| `datetimevalid` | `timeFrom` | Symbol validity start time |
| `datetimeexpired` | `timeTo` | Symbol validity end time |
| `z` | `minAltitude` | Minimum altitude |
| `z2` | `maxAltitude` | Maximum altitude |

## Quick Start

### 1. Include Dependencies

```html
<!DOCTYPE html>
<html>
<head>
  <!-- ArcGIS JS API CSS -->
  <link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/themes/light/main.css" />
</head>
<body>
  <!-- ArcGIS JS API (AMD loader) -->
  <script src="https://js.arcgis.com/4.29/"></script>
  
  <!-- ArcGIS adapter bundle -->
  <script src="path/to/arcgis-bundle-min.js"></script>
  
  <!-- STP SDK -->
  <script src="https://cdn.jsdelivr.net/npm/sketch-thru-plan-sdk@latest/dist/sketch-thru-plan-sdk-bundle-min.js"></script>
</body>
</html>
```

### 2. Create Map Instance

```html
<div id="map" style="height: 600px"></div>
<script>
  // Create map with optional configurations
  const map = new window.ArcGISMap(
    null,                              // API key (null for public services)
    'map',                            // Map div ID
    { lat: 34.05, lon: -118.24 },     // Center coordinates
    12,                               // Zoom level
    {
      // Optional: Override MIL-STD-2525 dictionary
      mil2525StyleUrl: 'https://your-style-url.com',
      // OR use Portal Item ID
      mil2525PortalItemId: 'your-portal-item-id'
    }
  );

  // Load the map
  map.load().then(() => {
    console.log('Map loaded successfully');
    
    // Add symbol features using StpSymbol.asGeoJSON()
    map.addFeature(symbolGeoJSON);
  });
</script>
```

### 3. Add Military Symbols

```javascript
// Assuming you have an StpSymbol instance from STP SDK
const stpSymbol = new StpSDK.StpSymbol();
stpSymbol.sidc = new StpSDK.Sidc();
stpSymbol.sidc.partA = '1003100000';
stpSymbol.sidc.partB = '1211000000';  
stpSymbol.designator1 = 'A';
stpSymbol.parent = '1/1';
stpSymbol.location = new StpSDK.Location();
// ... configure symbol properties

// Convert to GeoJSON and add to map
const symbolGeoJSON = stpSymbol.asGeoJSON();
map.addFeature(symbolGeoJSON);
```

## Creating Your Own Application

Follow these steps to create a new application based on the c2sim-arcgis sample:

### 1. Project Setup

```bash
# Create new project directory
mkdir my-arcgis-app
cd my-arcgis-app

# Initialize package.json
npm init -y

# Install dependencies
npm install sketch-thru-plan-sdk
npm install --save-dev typescript rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs terser cpx2 rimraf
```

### 2. Project Structure

```
my-arcgis-app/
├── package.json
├── tsconfig.json
├── src/
│   ├── index.html
│   ├── index.ts
│   └── styles.css
└── dist/           # Generated by build
```

### 3. Configure TypeScript (tsconfig.json)

```json
{
  "compilerOptions": {
    "target": "ES2018",
    "module": "ES2018",
    "lib": ["ES2018", "DOM"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
```

### 4. Build Configuration (package.json scripts)

```json
{
  "scripts": {
    "clean": "rimraf ./dist",
    "build": "npm run clean && tsc && npm run bundle && npm run bundle:min && npm run copyhtml",
    "bundle": "rollup ./dist/index.js --file ./dist/index.js --format iife --plugin @rollup/plugin-node-resolve={browser:true,preferBuiltins:false} --plugin @rollup/plugin-commonjs --external sketch-thru-plan-sdk --globals sketch-thru-plan-sdk=StpSDK",
    "bundle:min": "terser --ecma 6 --compress --mangle --module -o ./dist/index.min.js -- ./dist/index.js",
    "copyhtml": "cpx2 \"src/*.css\" \"dist\" && cpx2 \"src/*.html\" \"dist\""
  }
}
```

### 5. Basic HTML Template (src/index.html)

```html
<!DOCTYPE html>
<html>
<head>
  <title>My ArcGIS App</title>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
  <meta charset="utf-8">
  <link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/themes/light/main.css" />
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div id="map"></div>
  
  <!-- ArcGIS JS API -->
  <script src="https://js.arcgis.com/4.29/"></script>
  
  <!-- ArcGIS adapter bundle -->
  <script src="path/to/arcgis-bundle-min.js"></script>
  
  <!-- STP SDK -->
  <script src="https://cdn.jsdelivr.net/npm/sketch-thru-plan-sdk@latest/dist/sketch-thru-plan-sdk-bundle-min.js"></script>
  
  <!-- Your app -->
  <script src="index.min.js"></script>
</body>
</html>
```

### 6. Main Application (src/index.ts)

```typescript
// Global declarations
declare const StpSDK: any;
declare const ArcGISMap: any;

let map: any;

window.onload = () => start();

async function start() {
  // Parse URL parameters for configuration
  const urlParams = new URLSearchParams(window.location.search);
  const lat = parseFloat(urlParams.get('lat') || '34.05');
  const lon = parseFloat(urlParams.get('lon') || '-118.24');
  const zoom = parseInt(urlParams.get('zoom') || '12');
  
  // MIL-STD-2525 dictionary configuration
  const milStyleUrl = urlParams.get('mil2525StyleUrl');
  const milStylePortalId = urlParams.get('mil2525PortalItemId');
  
  // Create map
  map = new ArcGISMap(
    null,                    // API key
    'map',                   // div ID
    { lat, lon },           // center
    zoom,                   // zoom level
    {
      mil2525StyleUrl: milStyleUrl,
      mil2525PortalItemId: milStylePortalId
    }
  );

  // Event handlers
  map.onStrokeCompleted = handleStrokeCompleted;
  map.onSelection = handleSymbolSelection;
  
  // Load map
  await map.load();
  console.log('Map loaded successfully');
}

function handleStrokeCompleted(
  bounds: any,
  topLeft: any,
  bottomRight: any,
  strokePoints: any[],
  timeStart: string,
  timeEnd: string,
  intersectedPoids: string[]
) {
  console.log('Stroke completed:', strokePoints);
  // Process stroke for symbol recognition
}

function handleSymbolSelection(symbol: any) {
  console.log('Symbol selected:', symbol);
  // Handle symbol selection
}
```

### 7. Build and Run

```bash
# Build the application
npm run build

# Serve from dist directory
npx serve dist -p 8080

# Open in browser
open http://localhost:8080?lat=34.05&lon=-118.24&zoom=12
```

## Configuration Options

### Constructor Options

```javascript
const map = new ArcGISMap(apiKey, divId, center, zoom, options);
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `apiKey` | `string \| null` | ArcGIS API key (null for public services) |
| `divId` | `string` | HTML div ID for map container |
| `center` | `{lat: number, lon: number}` | Map center coordinates |
| `zoom` | `number` | Initial zoom level |
| `options` | `object` | Optional configuration |
| `options.mil2525StyleUrl` | `string` | MIL-STD-2525 dictionary style URL |
| `options.mil2525PortalItemId` | `string` | ArcGIS Portal Item ID for dictionary |

### URL Parameters

The sample supports these query parameters:

- `lat`, `lon`, `zoom`: Map positioning
- `mil2525StyleUrl` or `milstyleurl`: Dictionary style URL
- `mil2525PortalItemId` or `milstyle`: Portal Item ID

Example:
```
http://localhost:8080?lat=34.05&lon=-118.24&zoom=12&mil2525PortalItemId=d815f3bdf6e6452bb8fd153b654c94ca
```

## API Reference

### Methods

- `load(): Promise<void>` - Initialize and load the map
- `addFeature(symbolGeoJSON: any): void` - Add military symbol from StpSymbol.asGeoJSON()
- `removeFeature(poid: string): Promise<void>` - Remove symbol by POID
- `addPoly(coords: Array<{lat: number, lon: number}>, color?: string, weight?: number): void` - Add polyline
- `clearInk(): void` - Clear freehand drawing layer
- `getBounds(): any` - Get current map extent
- `displayInfo(content: string, location: {lat: number, lon: number}): void` - Show popup

### Events

- `onStrokeStart?: (location, timestamp) => void` - Freehand drawing started
- `onStrokeCompleted?: (bounds, topLeft, bottomRight, points, timeStart, timeEnd, intersectedPoids) => void` - Freehand drawing completed
- `onSelection?: (symbol) => void` - Symbol clicked/selected

## Building the Plugin

To build the ArcGIS plugin itself:

```bash
cd plugins/maps/arcgis
npm install
npm run build
```

Bundles will be generated in `dist/`:
- `arcgis-bundle.js` - UMD bundle
- `arcgis-bundle-min.js` - Minified UMD bundle
- `index.d.ts` - TypeScript definitions

## Notes

- **ArcGIS JS API Requirement**: Page must load ArcGIS JS API 4.29+ before using this plugin
- **AMD Loader**: Plugin relies on ArcGIS AMD loader (`require` function)
- **StpSymbol Integration**: Plugin uses StpSymbol objects directly as graphic attributes for maximum efficiency
- **MIL-STD-2525D**: Defaults to ArcGIS Online MIL-STD-2525D dictionary if no custom style provided
- **Field Mapping**: Uses `deltaSIDC` field computed from `sidc.partA/B/C` properties