Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
16 views96 pages

Report

Uploaded by

AMAN AGARWAL
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views96 pages

Report

Uploaded by

AMAN AGARWAL
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 96

INTERNSHIP PROJECT REPORT

on
“Optimisation Of Radar System”

SUBMITTED BY
- Aman Kumar Agarwal
(B. Tech - Computer Science and Engineering)
Indian Institute Of Information Technology , Sonepat

UNDER THE GUIDANCE OF


- Mr. Ichchha Shankar Sharma, Scientist ”F”,
Institute for Systems Studies & Analyses (ISSA)
Defence Research and Development Organisation (DRDO)
Ministry of Defence, Government of India.
CERTIFICATE
This is to certify that the Internship/Training Report titled “Optimisation
of Radar System”, conducted from June 6, 2025 to July 18, 2025. sub-
mitted by Aman Kumar Agarwal as part of the requirements for the
B.Tech degree in the Department of Computer Science Engineering at
Indian Institute of Information Technology Sonepat is an original record
of the candidate's work carried out under my supervision.
I hereby declare that, to the best of my knowledge and belief, this sub-
mission represents the candidate's own work. Furthermore, it does not
include any content that has been substantially accepted for any other
degree or diploma from a university or other institute of higher learn-
ing, except where appropriate acknowledgments are provided in the
text.

Mr. Ichchha Shankar Sharma, Scientist “F”,


ISSA, DRDO
DECLARATION
I hereby declare that this submission is my own work and to the best of
my knowledge and belief, it contains no material that has been previ-
ously published or authored by another individual. Furthermore, it does
not include any content that has been substantially accepted for the
award of any degree or diploma from any university or other institution
of higher learning, except where due acknowledgment has been appro-
priately made within the text.

Signature
Aman Kumar Agarwal
ACKNOWLEDGEMENT

I would like to extend my heartfelt gratitude to Ms. Deepakshi Shah, Di-


rector of the Institute for Systems Studies & Analyses (ISSA) Laboratory,
Defence Research and Development Organisation (DRDO), for granting
me the invaluable opportunity to undergo training at this esteemed or-
ganization. This experience allowed me to gain exposure to the Re-
search and Development environment and become familiar with Simu-
lation technologies.
I am deeply grateful to Mr. Ichchha Shankar Sharma, Scientist 'F, for his
insightful guidance and support throughout the training. My sincere
thanks also go to Ms. Suchitra Choudhary for giving me additional guid-
ance whenever possible.
Lastly, I wish to express my appreciation to all members of the ISSA
group for their constant encouragement, unwavering support, and ded-
ication, which made my training experience truly enriching.

Aman Kumar Agarwal Mr. Ichchha Shankar


Computer Science Engineering (Mentor)
4th Year
ABOUT THE ORGANIZATION
Defence Research & Development Organisation (DRDO)

The Defence Research & Development Organisation (DRDO) operates


under the Department of Defence Research and Development, part of
the Ministry of Defence. DRDO is committed to enhancing self-reliance
in defense systems by designing and developing world-class weapon
systems and equipment. These advancements align with the expressed
needs and qualitative requirements of the three services: The Army,
Navy, and Air Force.
DRDO was established in 1958 through the merger of:
The Technical Development Establishment (TDES) of the Indian Army,
The Directorate of Technical Development and Production (DTOP), and
The Defence Science Organisation (DSO).
The Defence Research and Development Organisation (DRDO) is a net-
work of more than 50 laboratories, dedicated to advancing defense
technologies across various domains. These include aeronautics, arma-
ments, electronics, combat vehicles, engineering systems, instrumenta-
tion, missiles, advanced computing and simulation, special materials,
naval systems, life sciences, training, information systems, and agricul-
ture. The organization is involved in several major projects, focusing on
the development of missiles, armaments, light combat aircraft, radars,
electronic warfare systems, and more. DRDO has already achieved sig-
nificant milestones in many of these technologies. As an agency of the
Republic of India, DRDO is responsible for the military's research and
development, with its headquarters located in New Delhi. In addition to
meeting the military's cutting-edge technology requirements, DRDO's
innovations provide considerable spin-off benefits to society at large,
contributing to national development and strengthening India's defense
capabilities.

Vision
To make India prosperous by establishing a world-class science and
technology base, and to provide our Defense Services with a decisive
edge by equipping them with internationally competitive systems and
solutions.

Mission
• To design, develop, and lead the production of state-of-the-art
sensors, weapon systems, platforms, and allied equipment for our
Defense Services.
• To provide technological solutions to the Services, optimizing
combat effectiveness and promoting the well-being of the troops.
• To develop infrastructure, nurture committed quality manpower,
and build a strong indigenous technology base.

Institute for Systems Studies & Analyses (ISSA)


ISSA is involved in System Analysis, Modeling & Simulation for various
defence applications pertaining to employment/deployment, tactics &
force potential evaluation, tactical/strategic & mission planning etc. We
develop war games for all the three Services.
Consequent to the reorganization of the system analysis activities
within DRDO, the functions of DSE were redefined and was given the
present name, i.e. Institute for Systems Studies & Analyses (ISSA) in the
year 1980. In the year 1972, a small group named as Aeronautical Sys-
tems Analysis Group (ASAG) was created with an objective to carry out
aeronautical systems studies and analyses.
This group was functioning from National Aeronautics Laboratory, Ban-
galore as a detachment of the Directorate of Aeronautics. In the year
1974, ASAG was converted into a self-accounting full-fledged unit
named as Centre for Aeronautical Systems Studies & Analyses (CASSA)
and was shifted to the premises of Aeronautical Development Establish-
ment, Bangalore.
From 1974 to 2003, CASSA contributed significantly to a series of sys-
tems analysis studies attributed to DRDO HQrs and the Indian Air Force.
It contributed into several design and development activities and policy
level issues with its objective analyses.
In the year 2003, CASSA was merged with ISSA with an objective to
synergies systems analysis activities and wargaming development pro-
cesses under integrated combat environment. With this, ISSA has
emerged as a nodal systems analyses lab and in 2013 ISSA is placed un-
der SAM Cluster with the mandate in the field of Training & Planning
Wargames, Integrated Air Defence & EW, Combat Modeling, Simulation
System Analysis and computerised Wargame.

Area Of Work
• Modeling, Simulation, Systems Analysis for Defence Application
• Systems Evaluation Studies
• Combat Model Development
• Computer Science and Applications for Defence Modelling & Sim-
ulation Domain
• Operations Research and Decision Support Techniques.
Vision
• Transform ISSA into centre of excellence in system analysis, mod-
elling & simulation of defence systems to meet the challenges of
the present and future requirements of the armed forces.
Mission
• Conduct system study and develop high quality integrated soft-
ware for system analysis & decision support in application areas
of Sensors & Weapons, Electronic Combat, Land & Naval Combat,
Air-to-Air Combat and Air Defence for effective use by DRDO and
Services for Design, Mission Planning, Tactics development and
Training.

CONTENTS
1. INTRODUCTION
1.1. PROBLEM STATEMENT 4
1.2. PROJECT GOALS AND OBJECTIVES 5
1.3. SCOPE DEFINITION 6
1.4. REPORT OVERVIEW 6

2. LITERATURE SURVEY 8
2.1. LITERARY SURVEY 8
2.2. <THEORETICAL UNDERSTANDING> 12

3. METHODOLOGY AND SOFTWARE REQUIREMENTS 20


3.1. METHODOLOGY 20
3.2. SOFTWARE REQUIREMENTS 21

4. IMPLEMENTATION 22
4.1. BACKEND 22
4.2. FRONTEND 23

5. RESULT AND ANALYSIS 31


6. CONCLUSION AND FUTURE PROSPECTS 32
REFERENCES

1. Introduction
1. 1 Problem Statement
Prior to this system, sensor deployment and coverage analysis often re-
lied on basic models that did not account for real-world terrain and en-
vironmental factors, leading to:
•Inaccurate radar coverage predictions
•Limited understanding of terrain and environmental impacts
•Inefficient radar placement decisions
•Lack of analysis on the effects of Earth’s curvature and elevation
changes
The Radar Placement System addresses these challenges by providing:
•Terrain-aware, latitude and longitude-based coverage calculation
•Consideration of altitude variations and Earth’s curvature in coverage
analysis
•Interactive tools for user-defined deployment parameters and sce-
nario analysis
•Efficient data processing and optimization using advanced algorithms
(such as genetic algorithms).
1.2 Project Goals and Objectives
The primary goal of this project is to optimize radar placement and pro-
vide accurate analysis of radar coverage patterns, taking into account
factors such as radar height, target height, range, terrain, and the cur-
vature of the Earth. Key functionalities include:

•Managing radar installations with configurable parameters for opti-


mal placement
•Calculating height- and terrain-aware radar coverage patterns
•Visualizing optimized coverage areas on interactive maps for ground
targets
•Visualizing coverage for aerial targets based on user-defined heights
•Efficient processing and analysis of geospatial and environmental data
to support optimization

1.3 Scope Overview


This system is designed for:
•Defense and security organizations
•Research and academic institutions
•Radar installation planning teams
•Coverage analysis specialists and system optimisation
The system can be extended with additional features such as:
•Advanced radar coverage analysis algorithms
•Multi-radar interference and overlap analysis
•Automated suggestions for optimal radar placement and configuration
•Historical analysis and visualization of coverage patterns

1.4 Report Overview


The Optimization of Radar System project is a modern, web-based ap-
plication designed to provide advanced visualization, analysis, and opti-
mization of radar coverage patterns with full awareness of terrain and
geospatial factors. The system enables users to manage and optimize
radar installations by incorporating real-world elevation data, support-
ing accurate coverage prediction and analysis for planning, research,
and operational purposes.
The system is divided into three major modules:
Radar Management Module
•Users can add, edit, and delete radar installations
•Configure radar parameters including position, range, altitude bands
and height.
•Accurate visualisation of Radar coverage.

Height and Terrain Analysis Module


•Performs radar coverage calculations sensitive to latitude, longitude,
and terrain elevation
•Conducts line-of-sight and coverage analysis considering both terrain
and Earth’s curvature

Coverage Visualization and Optimisation Module


•Generates ground and aerial target coverage maps
•Provides an interactive web interface for coverage analysis and opti-
mization
•Visualizes coverage areas and supports optimization of radar place-
ment using advanced algorithm.

The application implements a modern architecture using:


•Frontend: Responsive user interface built with Angular, Bootstrap,
and Plotly.js for interactive visualization
•Backend: Robust REST API built with Java Spring Boot, using GeoTools
for geospatial data processing and PostgreSQL for data storage.
•Data Processing: Incorporates terrain data (e.g., DTED files), Haversine
formula, and Earth curvature analysis for accurate modeling
•Optimisation: Utilizes genetic algorithms and other advanced tech-
niques for optimal radar placement.
•Visualization: Interactive map and analytics dashboards for real-time
feedback and scenario analysis

2. Literature Review
2.1 Literature Review
Recent research on radar coverage applications spans diverse domains
—including terrain-aware network design, autonomous sensing, and
environmental monitoring. In terrain-challenged settings such as moun-
tainous regions or urban environments, studies frequently employ high-
resolution digital elevation models (DEMs) to model line-of-sight (LOS)
blockage and optimize radar placement. Techniques such as genetic al-
gorithms and particle swarm optimization have been used to refine
radar network coverage in complex terrains [1].
In urban and natural environments, multi-objective optimization meth-
ods—such as genetic algorithms—are applied to maximize effective
coverage and address challenges like multi-path propagation and inter-
ference. These approaches are particularly relevant for optimizing the
placement and configuration of multiple radar units to achieve robust
coverage [2].
For autonomous vehicles and robotics, modern radar systems (e.g.,
FMCW and SAR mmWave) are widely used for obstacle detection, map-
ping, and simultaneous localization and mapping (SLAM), demonstrat-
ing the importance of real-time, terrain-aware sensing in dynamic and
cluttered environments [3].
Remote sensing applications, such as agricultural and environmental
monitoring, leverage radar data and advanced processing techniques to
analyze variables like soil moisture and vegetation structure under vary-
ing coverage scenarios [4].
This body of literature highlights a clear trend: integrating terrain-
aware propagation models, digital elevation data, and optimization al-
gorithms—such as genetic algorithms—is essential for enhancing radar
coverage effectiveness. The present project builds on these advances
by combining high-resolution terrain data (e.g., DTED files), geospatial
analysis (using GeoTools), and genetic optimization techniques within a
modern web-based platform. This enables users to interactively ana-
lyze, visualize, and optimize radar coverage in real-world, terrain-influ-
enced scenarios.

2.2 Theoretical Understanding


The optimization of radar system coverage fundamentally relies on the
evaluation of high-resolution Digital Elevation Models (DEMs) and ad-
vanced computational techniques. By analyzing the line-of-sight (LOS)
between radar and target positions, the system determines whether
terrain features obstruct visibility, enabling precise assessment of cov-
erage areas.
Two primary factors are critical in this process:
1.Radar Height and Terrain Elevation: The height of the radar, com-
bined with the underlying terrain elevation at its location, significantly
influences coverage. Higher radar installations can overlook more ter-
rain features, while lower placements may be blocked by natural ob-
stacles. In our system, both radar height and terrain elevation are in-
corporated into the coverage calculation, allowing users to experi-
ment with different configurations and instantly visualize the impact
on coverage.
2.Earth’s Curvature: Over long distances, the curvature of the Earth re-
duces the effective height of targets relative to the radar. This effect is
accounted for by adjusting the target elevation using the following
formula:

Height reduction due to curvature = d 2 /2 R

Where:
• d represents the distance between the radar and the target
• R represents the radius of the Earth
By subtracting this value from the terrain elevation of the target posi-
tion, the system accurately models the impact of Earth’s curvature on
radar coverage.
Additionally, our project leverages optimization algorithms—such as ge-
netic algorithms—to determine the most effective radar placements
across complex ter- rains. The integra-
tion of DEM data, LOS analysis, and
optimization tech- niques enables the
system to generate and visualize opti-
mal coverage pat- terns interactively.
This theoretical fram ework en-
sures that the sys- tem provides ro-
bust, real-world cov- erage analysis
and supports in- formed decision-
making for radar de- ployment and net-
work optimization.

3. Methodol- ogy
3.1 Methodology

The backend of the Optimization of Radar System project was initially


developed and tested as a proof of concept to validate the feasibility of
radar coverage calculations and optimization algorithms. Early testing
focused on implementing and verifying core functionalities such as line-
of-sight (LOS) analysis, radar coverage generation, and the integration
of geospatial data processing libraries (GDAL, GeoTools, Apache SIS).
The backend was tested using DTED (.dt2) files, that are publicly avail-
able sources and organization-provided datasets, to ensure accurate
terrain modeling and coverage assessment.Optimization algorithms, in-
cluding genetic algorithms, were evaluated for their effectiveness in de-
termining optimal radar placements across complex terrains.
Once the backend achieved reliable results, a dummy fron-
tend was used to simulate user interactions and validate API endpoints.
After successful integration testing, a formal frontend was developed
using Angular, providing a modern, interactive web interface for config-
uring radar parameters, visualizing coverage, and analyzing optimiza-
tion results. The frontend communicates with the backend via RESTful
APIs, enabling real-time, user-driven analysis and visualization.
Subsequent development cycles focused on enhancing user experience,
adding advanced features (such as interactive map visualization, param-
eter tuning, and result export), and optimizing system performance for
large-scale geospatial datasets.

3.2 Software Requirements


Frontend
Angular
•Modern framework for building responsive, interactive web applica-
tions.
•Enables dynamic visualization of radar coverage and optimization re-
sults on interactive maps.
•Supports user input forms, real-time updates, and data-driven UI com-
ponents.
Mapping Libraries (e.g., Leaflet, OpenLayers)
•Provides map rendering and geospatial visualization capabilities.
•Allows overlay of radar coverage polygons and interactive user con-
trols.
Backend
Spring Boot
•Framework for building robust, scalable RESTful APIs.
•Manages business logic, user authentication, and orchestration of op-
timization and geospatial analysis tasks.
Optimization Algorithms (Genetic Algorithm, etc.)
•Implements advanced algorithms for optimal radar placement and
coverage maximization..
•Supports parameter tuning and scenario analysis.

Geospatial Components
GeoTools 33.0
•Open source java library for geospatial data analysis and processing .
•Supports creation and manipulation of radar coverage layers, raster
analysis, and feature creation.
•Provides tools for coordinate transformations, spatial queries, and in-
tegration with various geospatial data formats (e.g., DTED, GeoTIFF).
GDAL 2.4 ((Geospatial Data Abstraction Library)
•Industry-standard library for reading, writing, and transforming raster
and vector geospatial data.
•Enables coordinate system transformations, reprojection, and geospa-
tial metadata management.
•Essential for processing digital elevation models (DEMs) and terrain
data used in radar coverage analysis.
Apache SIS(Spatial Information System)
•Provides robust support for coordinate reference systems and geospa-
tial operations.
•Offers tools for raster and vector data analysis, including transforma-
tions and projections.
•Fully compliant with OGC and ISO geospatial standards, ensuring inter-
operability.

Development Tools
IDEs
•Visual Studio Code: VSCode along with extensions(Java , HTML , Type-
Script,CSS)
Version Control & CI/CD
•Git: Distributed version control system for source code management.-
GitHub for repository hosting
•GitHub Actions or Jenkins: For continuous integration and automated
deployment pipelines.
Dependency Management
•Maven or Gradle: For managing Java backend dependencies and build
lifecycle.
•npm: For managing Angular frontend dependencies.
Monitoring & Debugging
•Spring Boot Actuator: For backend health checks and monitoring.
•Browser Developer Tools: For frontend debugging and performance
profiling.
•Logging Frameworks (e.g., Logback, SLF4J): For backend diagnostics
and error tracking.
•Java VisualVM: For JVM memory and performance monitoring.
•ExecutorService: For efficient multithreading and parallel processing in
backend computations.

4. Implementation
Overview
The Optimization of Radar System application follows a modern, web-
based three-tier architecture, designed for efficient radar data process-
ing, terrain-aware analysis, and interactive visualization:
1. Presentation Layer(Frontend)
•Built with Angular for a responsive, interactive web interface.
•Provides real-time map visualization with radar coverage overlays us-
ing mapping libraries (e.g., Leaflet or OpenLayers).
•Handles user interactions for radar configuration, parameter tuning,
and scenario analysis.
•Allows users to define radar parameters (location, height, range etc.)
and visualize optimization results.
2. Application Layer(Backend)
•Developed with Spring Boot to provide robust RESTful APIs and busi-
ness logic.
•Integrates geospatial libraries (GeoTools, GDAL, Apache SIS) for terrain
and elevation data analysis.
•Implements advanced algorithms for line-of-sight (LOS) analysis, radar
coverage calculation, and optimization (e.g., genetic algorithms for op-
timal placement)
•Processes user requests, orchestrates geospatial computations, and
returns results to the frontend.

3. Data Layer
•Utilizes GDAL, GeoTools, and Apache SIS for accessing and processing
digital elevation data (DTED and DEM files)
•Utilizes GDAL, GeoTools, and Apache SIS for accessing and processing
digital elevation data (DTED, GeoTIFF, DEM files)
•Optimized for efficient handling of large geospatial datasets and multi-
threaded processing.

Key Components
Frontend Components (Angular):
•Map Visualization Component: Displays interactive maps with radar
coverage overlays and allows users to place and configure radars.
•Radar Configuration Forms: Collects user input for radar parameters
( height, range, etc.).
•Coverage Results Display: Visualizes optimized coverage areas, LOS
analysis, and allows export of results (e.g., as images or shapefiles).
•User Experience Enhancements: Responsive layouts, real-time up-
dates, and intuitive controls for scenario analysis.
All Frontend Components are utilised together in the MainFile.

Backend Structure (Spring Boot):


Backend Components:
•Sensor Entity & Repository:The Sensor entity represents each radar or
sensor in the system, encapsulating properties such as its coordinates
(x, y), elevation, and radar height. This entity is mapped to a relational
database table using JPA annotations, enabling persistent storage and
retrieval. The SensorRepository interface extends Spring Data JPA’s
JpaRepository, providing CRUD operations and efficient batch process-
ing for sensor data.

• SensorArrangementController: This is the main REST controller re-


sponsible for handling API requests related to sensor arrangement
and analytics. It provides endpoints for uploading terrain files (DTED,
GeoTIFF, DEM), specifying sensor count and range, and retrieving an-
alytics such as coverage percentage and blind spots. The controller
validates all user inputs, manages file uploads (with size and format
checks), and orchestrates the sensor placement workflow.

• Terrain Data Processing Utilities: Classes like SimpleDtedReader and


GeoTiffLoader are dedicated to reading and parsing digital elevation
data from various formats. These utilities convert raw elevation files
into structured arrays or grids, which are then used for line-of-sight
and coverage calculations. The backend supports downsampling of
large terrain datasets to optimize performance and memory usage,
ensuring that even high-resolution files can be processed efficiently.

• Genetic Algorithm Optimization: At the core of the optimization


process is the GeneticSensorPlacer class, which implements a genetic
algorithm to determine the optimal placement of sensors for maxi-
mum coverage. The algorithm initializes a population of possible sen-
sor arrangements, evaluates their fitness based on coverage and
overlap, and iteratively evolves the population through selection,
crossover, and mutation. The best arrangement is selected after a set
number of generations, ensuring a balance between computational
efficiency and solution quality. If the genetic algorithm fails to find a
suitable arrangement, a fallback method provides a basic sensor dis-
tribution.

• Service Layer: The SensorService interface and its implementation


(SensorServiceImpl) encapsulate the business logic for sensor place-
ment, retrieval, and analytics. These services interact with the reposi-
tory for data persistence and with the optimization logic for sensor
arrangement. The service layer also supports batch placement of sen-
sors and provides methods for retrieving all sensors, updating, or
deleting them as needed.

• API & Integration: All backend functionalities are exposed via RESTful
APIs, allowing the Angular frontend to interact seamlessly with the
backend. The APIs support uploading terrain files, configuring sensor
parameters, retrieving sensor arrangements, and accessing analytics.
CORS configuration is managed via a dedicated CorsConfig class, en-
suring secure and flexible cross-origin requests during development
and deployment.

• Data Management & Performance: The backend uses PostgreSQL for


persistent storage of sensor data, with H2 as an alternative for offline
or testing scenarios. Application properties allow fine-tuning of file
size limits, supported formats, and performance parameters such as
thread pool sizes and batch processing. Multi-threading (using Java’s
ExecutorService) is employed for efficient processing of large terrain
datasets and parallel execution of optimization routines, ensuring re-
sponsive performance even with complex scenarios.
• Geospatial Libraries: The backend integrates several industry-stan-
dard geospatial libraries:
• GeoTools: For advanced geospatial data analysis, raster/vector
operations, and coordinate transformations.
• GDAL: For reading, writing, and transforming raster and vector
geospatial data, including DTED and GeoTIFF files.
• Apache SIS: For coordinate reference system management,
geospatial operations, and compliance with OGC/ISO standards.
• Logging, Monitoring, and Error Handling: Comprehensive logging is
implemented using SLF4J and Logback, capturing key events, errors,
and performance metrics. Application properties are configured for
robust error handling, including file upload limits, validation errors,
and fallback mechanisms. Health checks and monitoring endpoints
are enabled for backend diagnostics and maintenance.

Security and Integration


•Offline Handling of Elevation Data:
•No Mandatory Online Dependency
•Data Integrity Validation:
•Separation of Concerns
•Secure API Design

Advantages
1. Specialized for Radar/Sensor Optimization:
•Implements advanced algorithms (e.g., genetic algorithms) for optimal
sensor placement and coverage maximization.
•Provides accurate, terrain-aware coverage visualization for both
ground and aerial scenarios.
•Supports scalable deployment for multiple sensors/radars across large
geographic areas.
2. Enhanced Data Processing
•Integrates industry-standard geospatial libraries (GeoTools, GDAL,
Apache SIS) for efficient terrain data analysis and coordinate transfor-
mations.
•Dedicated backend modules for sensor arrangement, line-of-sight
analysis, and coverage calculation.
•Utilizes multi-threading and optimized data structures for fast pro-
cessing of large elevation datasets.
3. Maintainable and Extensible Architecture
•Modular design with clear separation between frontend (Angular) and
backend (Spring Boot) components.
•Backend services are independently scalable and can be extended
with new optimization algorithms or geospatial features.
•RESTful API structure allows easy integration with other systems or fu-
ture enhancements (e.g., analytics, reporting, or mobile clients).

4.1 Frontend Implementation


Angular Project Structure
The frontend of the Optimization of Radar System project is developed
using Angular, a modern web application framework. The project is or-
ganized into modular components and services to ensure maintainabil-
ity, scalability, and a responsive user experience.
frontend/

• angular.json
• package.json
• tsconfig.json

• src/
◦ index.html

◦ environments/
▪ environment.ts
▪ environment.prod.ts
◦ assets/
▪ icons/
▪ map-tiles/
◦ app/
▪ app.module.ts
▪ app.component.ts

▪ models/
▪ sensor.model.ts
▪ coverage.model.ts
▪ services/
▪ sensor.service.ts
▪ terrain-data.service.ts
▪ optimization.service.ts
▪ components/
▪ header.component.ts
▪ map-visualization.component.ts
▪ sensor-config.component.ts
▪ coverage-results.component.ts

▪ ... (other UI components)


Major Components
1. Map Visualization & Sensor Arrangement (ShapeLayer Equivalent)
Component:
• SensorArrangementComponent (frontend/src/app/
components/sensor-arrangement/sensor-arrangement.compo-
nent.ts)
Responsibilities:
•Renders a visual panel for terrain and sensor placement (using custom
HTML/CSS and Plotly for 3D terrain).
•Handles user input for sensor count, range, radar height, and optional
terrain file upload.
•Submits configuration to backend via SensorService.
•Displays deployed sensors and their coverage visually (with overlays
and markers).
•Shows a 3D terrain plot with sensor positions if terrain data is pro-
vided.
2. Radar Coverage Calculation (getCoverageForMap Equivalent)
Component/Service:
•SensorArrangementComponent (form and submit logic)
•SensorService (frontend/src/app/services/sensor.service.ts)
Responsibilities:
•Collects user parameters via a reactive form.
•Calls backend endpoints:
• /api/arrange-sensors (with terrain file)
• /api/sensors/arrange (simple mode)
•Receives and displays sensor arrangement and coverage data.
3. Sensor List & Management
Component:
• SensorListComponent (frontend/src/app/components/sensor-list/
sensor-list.component.ts)
Responsibilities:
• Lists all deployed sensors with coordinates and elevation.
• Allows refreshing, deleting, and (future) editing/viewing of sensors.
• Shows statistics (total, average, min, max elevation).
4. Analytics & Coverage Analysis
Component:
• AnalyticsComponent (frontend/src/app/analytics.component.ts)
Responsibilities:
• Fetches and displays analytics (coverage %, blind spots, overlap)
from backend.
• Shows summary and statistics for current deployment.
5. UI & Navigation
Components:
• HeaderComponent (header with time and secure mode)
• AppComponent (main layout, navigation bar, footer)
• HelpComponent (user guide and FAQ)

ShapeLayer Equivalent
import { Component, OnInit, ViewChild, ElementRef, DoCheck } from '@angular/core';

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { SensorService } from '../../services/sensor.service';


import { SensorArrangementResponse, Sensor } from '../../models/sensor.model';

import * as Plotly from 'plotly.js-dist';

@Component({

selector: 'app-sensor-arrangement',

template: `

<div class="container-fluid py-4">

<div class="row">

<!-- Configuration Panel -->

<div class="col-lg-4">

<div class="drdo-card">

<h3 class="mb-3">

<i class="fas fa-cogs me-2"></i>

Sensor Configuration

</h3>

<form [formGroup]="arrangementForm" (ngSubmit)="onCombinedSubmit()">

<div class="mb-3">

<label for="terrainFile" class="form-label">

<i class="fas fa-map me-1"></i>

Terrain Data (DTED File) <span class="text-muted">(optional)</span>

</label>

<input

type="file"

class="form-control"

id="terrainFile"

(change)="onFileSelected($event)"

accept=".dt0,.dt1,.dt2">

<div class="form-text">Upload DTED terrain elevation data (optional)</div>

</div>

<div class="mb-3">
<label for="sensorCount" class="form-label">

<i class="fas fa-satellite me-1"></i>

Number of Sensors

</label>

<input

type="number"

class="form-control"

id="sensorCount"

formControlName="sensorCount"

min="1"

max="100">

</div>

<div class="mb-3">

<label for="sensorRange" class="form-label">

<i class="fas fa-broadcast-tower me-1"></i>

Sensor Range (meters)

</label>

<input

type="number"

class="form-control"

id="sensorRange"

formControlName="sensorRange"

min="100"

max="10000">

</div>

<div class="mb-3">

<label for="radarHeight" class="form-label">

<i class="fas fa-broadcast-tower me-1"></i>


Radar Height (meters)

</label>

<input

type="number"

class="form-control"

id="radarHeight"

formControlName="radarHeight"

min="0"

step="0.01">

</div>

<button

type="submit"

class="drdo-btn-primary w-100"

[disabled]="!arrangementForm.valid || isLoading">

<i class="fas fa-play me-2"></i>

{{ isLoading ? 'Processing...' : 'Deploy Sensors' }}

</button>

</form>

</div>

<!-- Results Summary -->

<div class="drdo-card" *ngIf="combinedResults.length > 0">

<h4 class="mb-3">

<i class="fas fa-chart-bar me-2"></i>

Deployment Summary

</h4>

<div class="row">

<div class="col-6">

<div class="text-center">

<div class="h4 text-primary">{{ combinedResults.length }}</div>


<small class="text-muted">Sensors Deployed</small>

</div>

</div>

</div>

</div>

</div>

<!-- Visualization Panel -->

<div class="col-lg-8">

<div class="drdo-card">

<h3 class="mb-3">

<i class="fas fa-map-marked-alt me-2"></i>

Terrain & Sensor Visualization

</h3>

<div class="coverage-map" #coverageMap>

<div

*ngFor="let sensor of combinedResults; let i = index"

class="sensor-marker"

[style.left.%]="(sensor.x / 50) * 100"

[style.top.%]="(sensor.y / 50) * 100"

[title]="'Sensor ' + (i + 1) + ': (' + sensor.x + ', ' + sensor.y + ')'">

</div>

<div

*ngFor="let sensor of combinedResults; let i = index"

class="coverage-area"

[style.left.%]="(sensor.x / 50) * 100"

[style.top.%]="(sensor.y / 50) * 100"

[style.width.px]="(sensorRange / 50) * 400"

[style.height.px]="(sensorRange / 50) * 400"

[style.margin-left.px]="-((sensorRange / 50) * 400) / 2"


[style.margin-top.px]="-((sensorRange / 50) * 400) / 2">

</div>

</div>

<!-- Sensor List -->

<div class="mt-3" *ngIf="combinedResults.length > 0">

<h5>Deployed Sensors</h5>

<div class="table-responsive">

<table class="table table-sm">

<thead>

<tr>

<th>#</th>

<th>X Coordinate</th>

<th>Y Coordinate</th>

<th>Elevation</th>

<th>Radar Height</th>

<th>Actions</th>

</tr>

</thead>

<tbody>

<tr *ngFor="let sensor of combinedResults; let i = index">

<td>{{ i + 1 }}</td>

<td>{{ sensor.x }}</td>

<td>{{ sensor.y }}</td>

<td>{{ sensor.height | number:'1.2-2' }}m</td>

<td>{{ sensor.radarHeight | number:'1.2-2' }}m</td>

<td>

<button class="btn btn-sm btn-outline-primary" (click)="saveSensor(sensor)">

<i class="fas fa-save"></i>

</button>
</td>

</tr>

</tbody>

</table>

</div>

</div>

<div class="visualization-container">

<div

*ngFor="let sensor of combinedResults"

class="sensor-dot"

[style.left.%]="maxX ? (sensor.x / maxX) * 100 : 0"

[style.top.%]="maxY ? (sensor.y / maxY) * 100 : 0"

[title]="'Sensor: (' + sensor.x + ', ' + sensor.y + ')'"

></div>

</div>

<div id="terrainPlot" style="width:900px; height:700px; margin:auto;"></div>

</div>

</div>

</div>

</div>

styles: [`

.coverage-map {

border: 2px solid #e5e7eb;

background: linear-gradient(45deg, #f8fafc 25%, transparent 25%),

linear-gradient(-45deg, #f8fafc 25%, transparent 25%),

linear-gradient(45deg, transparent 75%, #f8fafc 75%),

linear-gradient(-45deg, transparent 75%, #f8fafc 75%);

background-size: 20px 20px;

background-position: 0 0, 0 10px, 10px -10px, -10px 0px;


}

.table th {

background: var(--drdo-primary);

color: white;

font-weight: 600;

.visualization-container {

position: relative;

width: 100%;

height: 400px;

background: #f8fafc;

border: 1px solid #e5e7eb;

border-radius: 10px;

margin-bottom: 1rem;

overflow: hidden;

.sensor-dot {

position: absolute;

width: 16px;

height: 16px;

background: #1976d2;

border-radius: 50%;

border: 2px solid #fff;

transform: translate(-50%, -50%);

box-shadow: 0 0 4px #1976d2;

`]

})
export class SensorArrangementComponent implements OnInit, DoCheck {

@ViewChild('coverageMap') coverageMap!: ElementRef;

arrangementForm: FormGroup;

isLoading = false;

combinedResults: any[] = [];

sensorRange = 0;

file: File | null = null;

maxX = 1;

maxY = 1;

constructor(

private fb: FormBuilder,

private sensorService: SensorService

){

this.arrangementForm = this.fb.group({

sensorCount: [5, [Validators.required, Validators.min(1), Validators.max(100)]],

sensorRange: [1000, [Validators.required, Validators.min(100), Validators.max(10000)]],

radarHeight: [5.0, [Validators.required, Validators.min(0)]]

});

ngOnInit(): void {

this.arrangementForm.get('sensorRange')?.valueChanges.subscribe(range => {

this.sensorRange = range;

});

ngDoCheck(): void {

if (this.combinedResults.length > 0) {

this.maxX = Math.max(...this.combinedResults.map(s => s.x));

this.maxY = Math.max(...this.combinedResults.map(s => s.y));


}

onFileSelected(event: any): void {

this.file = event.target.files[0] || null;

onCombinedSubmit(): void {

if (this.arrangementForm.valid) {

this.isLoading = true;

const { sensorCount, sensorRange, radarHeight } = this.arrangementForm.value;

if (this.file) {

// Advanced mode with terrain file

console.log('Uploading terrain file:', this.file.name, 'Size:', this.file.size);

this.sensorService.arrangeSensors(this.file, sensorCount, sensorRange).subscribe({

next: (result) => {

console.log('Terrain processing successful:', result);

this.combinedResults = result.sensors.map(s => ({ ...s, radarHeight: radarHeight }));

this.isLoading = false;

if (result.terrain) {

this.render3DTerrainPlot(result.terrain, result.sensors);

// Show success message

if (result.message) {

alert(result.message);

},

error: (error) => {

console.error('Terrain processing error:', error);

this.isLoading = false;
let errorMessage = 'Error processing terrain data. Please try again.';

// Extract specific error message from response

if (error.error && error.error.error) {

errorMessage = error.error.error;

} else if (error.message) {

errorMessage = error.message;

} else if (error.status === 413) {

errorMessage = 'File size too large. Please use a smaller terrain file (under 200MB).';

} else if (error.status === 400) {

errorMessage = 'Invalid file format or parameters. Please check your input.';

} else if (error.status === 0) {

errorMessage = 'Cannot connect to server. Please ensure the backend is running on


http://localhost:8080';

} else if (error.status >= 500) {

errorMessage = 'Server error. Please try again later or contact support.';

// Add debugging information for Windows offline mode

if (error.status === 0 || error.status >= 500) {

errorMessage += '\n\nDebugging steps for Windows offline mode:';

errorMessage += '\n1. Check if backend is running (should show on http://localhost:8080)';

errorMessage += '\n2. Check backend.log for detailed error messages';

errorMessage += '\n3. Ensure Java has enough memory (try restarting with more memory)';

errorMessage += '\n4. Verify the .dt2 file is not corrupted';

errorMessage += '\n5. Try with a smaller terrain file';

alert(errorMessage);

});
} else {

// Simple mode without terrain file

console.log('Using simple sensor arrangement mode');

this.sensorService.arrangeSensorsSimple(sensorCount, radarHeight).subscribe({

next: (sensors) => {

console.log('Simple arrangement successful:', sensors);

this.combinedResults = sensors;

this.isLoading = false;

},

error: (error) => {

console.error('Simple arrangement error:', error);

this.isLoading = false;

let errorMessage = 'Error arranging sensors: ‘;

if (error.error && error.error.message) {

errorMessage += error.error.message;

} else if (error.message) {

errorMessage += error.message;

} else {

errorMessage += 'Unknown error occurred.';

alert(errorMessage);

});

} else {

console.warn('Form validation failed:', this.arrangementForm.errors);

alert('Please fill in all required fields correctly.');

}
saveSensor(sensor: Sensor): void {

this.sensorService.placeSensor(sensor).subscribe({

next: (savedSensor) => {

console.log('Sensor saved:', savedSensor);

alert('Sensor saved successfully!');

},

error: (error) => {

console.error('Error saving sensor:', error);

alert('Error saving sensor. Please try again.');

});

render3DTerrainPlot(terrain: number[][], sensors: any[]) {

const gridSize = terrain.length;

const z = terrain;

const x = Array.from({length: gridSize}, (_, i) => i);

const y = Array.from({length: gridSize}, (_, i) => i);

// Surface plot for terrain

const surface = {

z: z,

x: x,

y: y,

type: 'surface',

colorscale: 'Viridis',

opacity: 0.95,

showscale: true,

colorbar: { title: 'Elevation', thickness: 20 }

};

// Scatter plot for sensors


const sensorScatter = {

x: sensors.map(s => s.x),

y: sensors.map(s => s.y),

z: sensors.map(s => s.height),

mode: 'markers+text',

type: 'scatter3d',

marker: {

color: 'red',

size: 16,

symbol: 'circle',

line: { color: 'black', width: 2 }

},

text: sensors.map((s, i) => `S${i+1}`),

textposition: 'top center',

name: 'Sensors',

hovertemplate: 'Sensor %{text}<br>X: %{x}<br>Y: %{y}<br>Z: %{z}<extra></extra>'

};

const layout = {

title: '3D Terrain with Sensor Placement',

autosize: false,

width: 900,

height: 700,

margin: { l: 0, r: 0, b: 0, t: 40 },

scene: {

xaxis: {title: 'X', showgrid: true, zeroline: false},

yaxis: {title: 'Y', showgrid: true, zeroline: false},

zaxis: {title: 'Elevation', showgrid: true, zeroline: false},

camera: {

eye: {x: 1.5, y: 1.5, z: 1.2}


}

};

Plotly.newPlot('terrainPlot', [surface, sensorScatter], layout, {responsive: true});

getCoverageForMap Equivalent
import { Injectable } from '@angular/core';

import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable } from 'rxjs';

import { Sensor, SensorDTO, SensorArrangementResponse } from '../models/sensor.model';

@Injectable({

providedIn: 'root'

})

export class SensorService {

private apiUrl = '/api';

constructor(private http: HttpClient) { }

// Get all sensors

getAllSensors(): Observable<Sensor[]> {

return this.http.get<Sensor[]>(`${this.apiUrl}/sensors`);

// Place a new sensor

placeSensor(sensor: SensorDTO): Observable<Sensor> {

return this.http.post<Sensor>(`${this.apiUrl}/sensors`, sensor);

// Arrange sensors using terrain data

arrangeSensors(file: File, sensorCount: number, sensorRange: number): Observable<SensorArrange-


mentResponse> {
const formData = new FormData();

formData.append('file', file);

formData.append('sensorCount', sensorCount.toString());

formData.append('sensorRange', sensorRange.toString());

return this.http.post<SensorArrangementResponse>(`${this.apiUrl}/arrange-sensors`, formData);

// Get sensor by ID

getSensorById(id: number): Observable<Sensor> {

return this.http.get<Sensor>(`${this.apiUrl}/sensors/${id}`);

// Update sensor

updateSensor(id: number, sensor: SensorDTO): Observable<Sensor> {

return this.http.put<Sensor>(`${this.apiUrl}/sensors/${id}`, sensor);

// Delete sensor

deleteSensor(id: number): Observable<void> {

return this.http.delete<void>(`${this.apiUrl}/sensors/${id}`);

arrangeSensorsSimple(numSensors: number, radarHeight: number) {

return this.http.post<Sensor[]>(`${this.apiUrl}/sensors/arrange`, {

numSensors,

radarHeight

});

getAnalytics() {

return this.http.get<any>('/api/sensors/analytics');

}
Sensor List & Management
import { Component, OnInit } from '@angular/core';

import { SensorService } from '../../services/sensor.service';

import { Sensor } from '../../models/sensor.model';

@Component({

selector: 'app-sensor-list',

template: `

<div class="container-fluid py-4">

<div class="drdo-card">

<div class="d-flex justify-content-between align-items-center mb-3">

<h3>

<i class="fas fa-list me-2"></i>

Deployed Sensors

</h3>

<button class="drdo-btn-primary" (click)="refreshSensors()">

<i class="fas fa-sync-alt me-2"></i>

Refresh

</button>

</div>

<div class="loading-spinner" *ngIf="isLoading">

<div class="spinner-border text-primary" role="status">

<span class="visually-hidden">Loading...</span>

</div>

</div>
<div *ngIf="!isLoading && sensors.length === 0" class="text-center py-5">

<i class="fas fa-satellite fa-3x text-muted mb-3"></i>

<h4 class="text-muted">No sensors deployed yet</h4>

<p class="text-muted">Deploy sensors using the arrangement tool to see them here.</p>

</div>

<div *ngIf="!isLoading && sensors.length > 0">

<table class="table table-striped table-hover">

<thead>

<tr>

<th>#</th>

<th>X Coordinate</th>

<th>Y Coordinate</th>

<th>Elevation (Z)</th>

</tr>

</thead>

<tbody>

<tr *ngFor="let sensor of sensors; let i = index">

<td>{{ sensor.id || (i + 1) }}</td>

<td>{{ sensor.x }}</td>

<td>{{ sensor.y }}</td>

<td>{{ sensor.height | number:'1.2-2' }} m</td>

</tr>

</tbody>

</table>

</div>

<!-- Statistics -->

<div class="row mt-4" *ngIf="!isLoading && sensors.length > 0">


<div class="col-md-3">

<div class="drdo-card text-center">

<div class="h3 text-primary">{{ sensors.length }}</div>

<small class="text-muted">Total Sensors</small>

</div>

</div>

<div class="col-md-3">

<div class="drdo-card text-center">

<div class="h3 text-success">{{ averageElevation | number:'1.1-1' }}m</div>

<small class="text-muted">Avg Elevation</small>

</div>

</div>

<div class="col-md-3">

<div class="drdo-card text-center">

<div class="h3 text-warning">{{ minElevation | number:'1.1-1' }}m</div>

<small class="text-muted">Min Elevation</small>

</div>

</div>

<div class="col-md-3">

<div class="drdo-card text-center">

<div class="h3 text-info">{{ maxElevation | number:'1.1-1' }}m</div>

<small class="text-muted">Max Elevation</small>

</div>

</div>

</div>

</div>

</div>

`,

styles: [`
table {

width: 100%;

margin-bottom: 1rem;

background-color: #fff;

th, td {

text-align: center;

vertical-align: middle;

.table-hover tbody tr:hover {

background-color: #f5f5f5;

`]

})

export class SensorListComponent implements OnInit {

sensors: Sensor[] = [];

isLoading = false;

averageElevation = 0;

minElevation = 0;

maxElevation = 0;

constructor(private sensorService: SensorService) {}

ngOnInit(): void {

this.loadSensors();

loadSensors(): void {

this.isLoading = true;
this.sensorService.getAllSensors().subscribe({

next: (sensors) => {

this.sensors = sensors;

this.calculateStatistics();

this.isLoading = false;

},

error: (error) => {

console.error('Error loading sensors:', error);

this.isLoading = false;

});

refreshSensors(): void {

this.loadSensors();

calculateStatistics(): void {

if (this.sensors.length === 0) return;

const elevations = this.sensors.map(s => s.height);

this.averageElevation = elevations.reduce((a, b) => a + b, 0) / elevations.length;

this.minElevation = Math.min(...elevations);

this.maxElevation = Math.max(...elevations);

viewSensorDetails(sensor: Sensor): void {

console.log('Viewing sensor details:', sensor);

// Implement detailed view modal


}

editSensor(sensor: Sensor): void {

console.log('Editing sensor:', sensor);

// Implement edit functionality

deleteSensor(sensor: Sensor): void {

if (confirm('Are you sure you want to delete this sensor?')) {

if (sensor.id) {

this.sensorService.deleteSensor(sensor.id).subscribe({

next: () => {

this.loadSensors();

alert('Sensor deleted successfully!');

},

error: (error) => {

console.error('Error deleting sensor:', error);

alert('Error deleting sensor. Please try again.');

});

Analytics & Coverage Analysis


import { Component, OnInit } from '@angular/core';

import { SensorService } from './services/sensor.service';


@Component({

selector: 'app-analytics',

template: `

<div class="container py-4">

<div class="drdo-card mb-4">

<h3><i class="fas fa-chart-bar me-2"></i>Sensor Deployment Analytics</h3>

<div *ngIf="isLoading" class="text-center py-5">

<div class="spinner-border text-primary" role="status">

<span class="visually-hidden">Loading...</span>

</div>

</div>

<div *ngIf="!isLoading">

<div class="row mb-3">

<div class="col-md-4">

<div class="drdo-card text-center">

<div class="h3 text-success">{{ coveragePercent | number:'1.1-2' }}%</div>

<small class="text-muted">Coverage</small>

</div>

</div>

<div class="col-md-4">

<div class="drdo-card text-center">

<div class="h3 text-danger">{{ blindSpots }}</div>

<small class="text-muted">Blind Spots</small>

</div>

</div>

<div class="col-md-4">

<div class="drdo-card text-center">

<div class="h3 text-warning">{{ overlapPercent | number:'1.1-2' }}%</div>

<small class="text-muted">Sensor Overlap</small>


</div>

</div>

</div>

<div class="mb-3">

<h5>Summary</h5>

<p>{{ summary }}</p>

</div>

</div>

</div>

</div>

`,

styles: [`

.drdo-card { margin-bottom: 1rem; }

.text-center { text-align: center; }

`]

})

export class AnalyticsComponent implements OnInit {

isLoading = true;

coveragePercent = 0;

blindSpots = 0;

overlapPercent = 0;

summary = '';

constructor(private sensorService: SensorService) {}

ngOnInit(): void {

this.sensorService.getAnalytics().subscribe({

next: (data: { coveragePercent: number; blindSpots: number; overlapPercent: number; summary:


string }) => {
this.coveragePercent = data.coveragePercent;

this.blindSpots = data.blindSpots;

this.overlapPercent = data.overlapPercent;

this.summary = data.summary;

this.isLoading = false;

},

error: (err: any) => {

this.summary = 'Failed to load analytics.';

this.isLoading = false;

});

UI & Navigation
iimport { Component } from '@angular/core';

@Component({

selector: 'app-header',

template: `

<header class="drdo-header">

<div class="container">

<div class="row align-items-center">

<div class="col-md-6">

<h1 class="mb-0">
<i class="fas fa-satellite-dish me-2"></i>

DRDO Sensor Placement System

</h1>

<p class="mb-0 mt-1">Advanced Terrain-Aware Sensor Deployment</p>

</div>

<div class="col-md-6 text-end">

<div class="d-flex justify-content-end align-items-center">

<span class="me-3">

<i class="fas fa-shield-alt me-1"></i>

Secure Mode

</span>

<span>

<i class="fas fa-clock me-1"></i>

{{ currentTime | date:'HH:mm:ss' }}

</span>

</div>

</div>

</div>

</div>

</header>

styles: [`

.drdo-header h1 {

font-size: 1.8rem;

font-weight: 700;

.drdo-header p {

font-size: 0.9rem;

opacity: 0.9;

}
@media (max-width: 768px) {

.drdo-header h1 {

font-size: 1.4rem;

.drdo-header .text-end {

text-align: left !important;

margin-top: 1rem;

`]

})

export class HeaderComponent {

currentTime = new Date();

constructor() {

// Update time every second

setInterval(() => {

this.currentTime = new Date();

}, 1000);

UI & Navigation
iimport { Component } from '@angular/core';

@Component({

selector: 'app-header',

template: `

<header class="drdo-header">

<div class="container">

<div class="row align-items-center">


<div class="col-md-6">

<h1 class="mb-0">

<i class="fas fa-satellite-dish me-2"></i>

DRDO Sensor Placement System

</h1>

<p class="mb-0 mt-1">Advanced Terrain-Aware Sensor Deployment</p>

</div>

<div class="col-md-6 text-end">

<div class="d-flex justify-content-end align-items-center">

<span class="me-3">

<i class="fas fa-shield-alt me-1"></i>

Secure Mode

</span>

<span>

<i class="fas fa-clock me-1"></i>

{{ currentTime | date:'HH:mm:ss' }}

</span>

</div>

</div>

</div>

</div>

</header>

styles: [`

.drdo-header h1 {

font-size: 1.8rem;

font-weight: 700;

.drdo-header p {

font-size: 0.9rem;
opacity: 0.9;

@media (max-width: 768px) {

.drdo-header h1 {

font-size: 1.4rem;

.drdo-header .text-end {

text-align: left !important;

margin-top: 1rem;

`]

})

export class HeaderComponent {

currentTime = new Date();

constructor() {

// Update time every second

setInterval(() => {

this.currentTime = new Date();

}, 1000);

Features in the UI
Accurate Visualisation
- Interactive sensor visualization panel with real-time updates
- Displays deployed sensors as markers and overlays coverage areas
-3D terrain plot (using Plotly.js) for advanced terrain-aware sensor placement
Radar Management
- Radar configuration form with built-in validation (sensor count, range, radar
height, optional terrain file)
- Submits user-defined parameters to backend for coverage calculation
- Visualizes calculated sensor positions and coverage immediately upon deploy-
ment
Data Validation
- Input validation for all radar parameters using Angular reactive forms
- Backend-integrated data integrity checks (e.g., file format, parameter sanity)
- Real-time validation feedback and error messages in the UI
4.2 Backend Implementation
The backend system is built using Java (Spring Boot) and leverages
geospatial processing via custom logic and utility classes. It is responsi-
ble for radar coverage calculation, line-of-sight (LOS) analysis, and sen-
sor arrangement optimization.

Core Components
1. Terrain Data Handling
• SimpleDtedReader (util/SimpleDtedReader.java):
Reads and parses DTED terrain files, converting them into a 2D grid of
elevation values for further processing.
2. Sensor Arrangement & Coverage Calculation
• GeneticSensorPlacer (logic/GeneticSensorPlacer.java):
• Implements a genetic algorithm to find optimal sensor place-
ments on the terrain grid.
• Evaluates arrangements based on coverage, using LOS checks
and sensor range.
• Contains a hasLineOfSight method to determine if a sensor can
"see" a given point, considering terrain elevation.
• SensorArrangementController (controller/SensorArrangementCon-
troller.java)
• Handles API requests for sensor arrangement.
• Validates input, processes terrain files, invokes the genetic algo-
rithm, and returns sensor positions and terrain data to the fron-
tend.
• Provides fallback sensor arrangement if the genetic algorithm
fails.

3. Sensor Management
• SensorService & SensorServiceImpl (service/, serviceImpl/):
• Manages CRUD operations for sensors.
• Provides methods to place sensors, retrieve all sensors, and ar-
range sensors in a grid (simple mode).
4. Coverage & Analytics
• Coverage Calculation:
• Performed within GeneticSensorPlacer by simulating sensor cov-
erage and LOS for each grid cell.
• Analytics Endpoint:
• SensorController provides /api/sensors/analytics for fron-
tend analytics (coverage %, blind spots, overlap).

Backend Code Snippet


(SimpleDtedReader.java)

package com.example.sensor.util;

import java.io.*;

import java.nio.ByteOrder;
import java.nio.ByteBuffer;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class SimpleDtedReader {

private static final Logger logger = LoggerFactory.getLogger(SimpleDtedReader.class);

public static short[][] readDtedGrid(File file, int gridSize) throws IOException {

if (!file.exists()) {

throw new IOException("File does not exist: " + file.getAbsolutePath());

if (file.length() == 0) {

throw new IOException("File is empty: " + file.getAbsolutePath());

logger.info("Reading DTED file: {}, size: {} bytes, readable: {}",

file.getAbsolutePath(), file.length(), file.canRead());

java.util.List<String> suspiciousElevations = new java.util.ArrayList<>();

int suspiciousElevationLogLimit = 10;

try (DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)))) {

// Read and validate DTED header

byte[] header = new byte[3428];

int bytesRead = dis.read(header);

if (bytesRead != 3428) {

logger.warn("Incomplete DTED header: expected 3428 bytes, got {}", bytesRead);

// Try with smaller header for some DTED variants

if (bytesRead < 100) {

throw new IOException("Invalid DTED header: file too small for DTED format. Got " + bytesRead + "
bytes, need at least 100");

}
}

// Validate DTED format with more flexible checking

String headerStr = new String(header, 0, Math.min(10, bytesRead));

boolean isValidHeader = headerStr.contains("UHL") || headerStr.contains("DSI") ||

headerStr.contains("DTED") || headerStr.startsWith("DTED");

if (!isValidHeader) {

logger.warn("Unexpected DTED header: {}", headerStr);

// Continue anyway - some DTED files might have different headers

// Auto-detect grid size if gridSize == 0

int fileLength = (int) file.length();

int headerSize = Math.min(3428, bytesRead);

int remainingBytes = fileLength - headerSize;

logger.info("File analysis: total={}, header={}, remaining={}",

fileLength, headerSize, remainingBytes);

// Calculate expected dimensions with fallback

int columnSize = 8 + 2 * 1201 + 4; // 8 bytes header, 1201 rows, 2 bytes each, 4 bytes checksum (for typi-
cal DTED1)

int numColumns = remainingBytes / columnSize;

int numRows = 1201; // Default for DTED1

// Validate calculations with reasonable bounds

if (numColumns <= 0) {

// Try alternative calculation

numColumns = 1;

numRows = (remainingBytes - 8) / 2; // Assume simple format


logger.warn("Using fallback calculation: {} columns x {} rows", numColumns, numRows);

} else if (numColumns > 10000) {

numColumns = 10000;

logger.warn("Limiting columns to 10000 for performance");

if (gridSize > 0) {

numRows = gridSize;

numColumns = gridSize;

logger.info("DTED dimensions: {} columns x {} rows", numColumns, numRows);

short[][] grid = new short[numColumns][numRows];

for (int col = 0; col < numColumns; col++) {

try {

// Read column header (8 bytes) - skip if not available

if (dis.available() >= 8) {

dis.skipBytes(8);

// Read elevation data

for (int row = 0; row < numRows; row++) {

if (dis.available() < 2) {

logger.warn("Unexpected end of file at column {}, row {}", col, row);

break;

short elevation = dis.readShort();


// Handle byte order (DTED files are typically big-endian)

if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {

elevation = Short.reverseBytes(elevation);

// Enhanced elevation range and collect suspicious values

if (elevation < -20000 || elevation > 20000) {

if (suspiciousElevations.size() < suspiciousElevationLogLimit) {

suspiciousElevations.add("[" + col + "," + row + "]: " + elevation);

// Clamp to wider range

elevation = (short) Math.max(-20000, Math.min(20000, elevation));

grid[col][row] = elevation;

// Skip checksum (4 bytes) if available

if (dis.available() >= 4) {

dis.skipBytes(4);

} catch (EOFException e) {

logger.warn("Unexpected end of file at column {}", col);

// Fill remaining columns with default values

for (int remainingCol = col; remainingCol < numColumns; remainingCol++) {

for (int row = 0; row < numRows; row++) {

grid[remainingCol][row] = 0;

break;
} catch (IOException e) {

logger.error("Error reading column {}: {}", col, e.getMessage());

// Continue with next column

for (int row = 0; row < numRows; row++) {

grid[col][row] = 0;

// After reading, print summary of suspicious elevations if any

if (!suspiciousElevations.isEmpty()) {

System.out.println("Suspicious elevation values (first " + suspiciousElevationLogLimit + "): " + suspi-


ciousElevations);

logger.info("Successfully read DTED grid: {}x{}", numColumns, numRows);

return grid;

} catch (IOException e) {

logger.error("Error reading DTED file: {}", e.getMessage(), e);

throw e;

/**

* Validate DTED file format with more flexible checking

*/

public static boolean isValidDtedFile(File file) {

try (DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)))) {

byte[] header = new byte[Math.min(3428, (int) file.length())];

int bytesRead = dis.read(header);


if (bytesRead < 10) {

logger.warn("File too small for DTED validation: {} bytes", bytesRead);

return false;

// Check for DTED header indicators with more flexible matching

String headerStr = new String(header, 0, Math.min(50, bytesRead));

boolean isValid = headerStr.contains("UHL") || headerStr.contains("DSI") ||

headerStr.contains("DTED") || headerStr.startsWith("DTED") ||

file.getName().toLowerCase().matches(".*\\.dt[0-3]$");

logger.info("DTED validation result: {} (header: '{}')", isValid, headerStr.substring(0, Math.min(20, header-


Str.length())));

return isValid;

} catch (IOException e) {

logger.error("Error validating DTED file: {}", e.getMessage());

return false;

/**

* Get file information for debugging

*/

public static String getFileInfo(File file) {

try {

return String.format("File: %s, Size: %d bytes, Exists: %s, Readable: %s",

file.getName(), file.length(), file.exists(), file.canRead());

} catch (Exception e) {

return "Error getting file info: " + e.getMessage();


}

(GeneticSensorPlacer.java)

package com.example.sensor.logic;

import java.util.*;

public class GeneticSensorPlacer {

private final int gridSize;

private final int sensorCount;

private final int sensorRange;

private final short[][] terrain;

private final int populationSize = 20;

private final int generations = 30;

private final double mutationRate = 0.2;


private final Random rand = new Random();

public GeneticSensorPlacer(short[][] terrain, int sensorCount, int sensorRange) {

this.terrain = terrain;

this.gridSize = terrain.length;

this.sensorCount = sensorCount;

this.sensorRange = sensorRange;

public List<int[]> findBestArrangement() {

List<List<int[]>> population = new ArrayList<>();

for (int i = 0; i < populationSize; i++) {

population.add(randomIndividual());

List<int[]> best = null;

double bestFitness = -1;

for (int gen = 0; gen < generations; gen++) {

population.sort(Comparator.comparingDouble(this::fitness).reversed());

if (fitness(population.get(0)) > bestFitness) {

bestFitness = fitness(population.get(0));

best = population.get(0);

List<List<int[]>> newPop = new ArrayList<>();

// Elitism: keep top 2

newPop.add(population.get(0));

newPop.add(population.get(1));

while (newPop.size() < populationSize) {

List<int[]> parent1 = tournament(population);

List<int[]> parent2 = tournament(population);


List<int[]> child = crossover(parent1, parent2);

if (rand.nextDouble() < mutationRate) mutate(child);

newPop.add(child);

population = newPop;

return best;

private List<int[]> randomIndividual() {

Set<String> used = new HashSet<>();

List<int[]> ind = new ArrayList<>();

while (ind.size() < sensorCount) {

int x = rand.nextInt(gridSize);

int y = rand.nextInt(gridSize);

String key = x + "," + y;

if (!used.contains(key)) {

ind.add(new int[]{x, y});

used.add(key);

return ind;

private double fitness(List<int[]> individual) {

boolean[][] covered = new boolean[gridSize][gridSize];

for (int[] pos : individual) {

int sx = pos[0], sy = pos[1];

float sensorElev = terrain[sx][sy];


for (int i = 0; i < gridSize; i++) {

for (int j = 0; j < gridSize; j++) {

double dist = Math.sqrt(Math.pow(sx - i, 2) + Math.pow(sy - j, 2));

if (dist <= sensorRange && hasLineOfSight(sx, sy, i, j, sensorElev, terrain[i][j])) {

covered[i][j] = true;

int coveredCount = 0;

for (int i = 0; i < gridSize; i++)

for (int j = 0; j < gridSize; j++)

if (covered[i][j]) coveredCount++;

// Optionally, add penalty for overlapping sensors or reward for spread

return coveredCount;

// Line of Sight: returns true if there is LOS from (x1, y1) to (x2, y2)

private boolean hasLineOfSight(int x1, int y1, int x2, int y2, float hSensor, float hTarget) {

int steps = (int)(Math.hypot(x2 - x1, y2 - y1) * 2);

if (steps == 0) return true;

for (int step = 1; step < steps; step++) {

double t = step / (double)steps;

int xi = (int)Math.round(x1 + t * (x2 - x1));

int yi = (int)Math.round(y1 + t * (y2 - y1));

float expectedHeight = (float)(hSensor + t * (hTarget - hSensor));

int xIdx = Math.max(0, Math.min(xi, gridSize - 1));

int yIdx = Math.max(0, Math.min(yi, gridSize - 1));

float terrainHeight = terrain[xIdx][yIdx];


if (terrainHeight > expectedHeight) return false;

return true;

private List<int[]> tournament(List<List<int[]>> population) {

int k = 5;

List<List<int[]>> sample = new ArrayList<>();

for (int i = 0; i < k; i++) sample.add(population.get(rand.nextInt(population.size())));

return sample.stream().max(Comparator.comparingDouble(this::fitness)).get();

private List<int[]> crossover(List<int[]> p1, List<int[]> p2) {

Set<String> used = new HashSet<>();

List<int[]> child = new ArrayList<>();

for (int i = 0; i < sensorCount; i++) {

int[] gene = rand.nextBoolean() ? p1.get(i) : p2.get(i);

String key = gene[0] + "," + gene[1];

if (!used.contains(key)) {

child.add(new int[]{gene[0], gene[1]});

used.add(key);

} else {

// If duplicate, pick random unused

int tries = 0;

while (tries < 10) {

int x = rand.nextInt(gridSize);

int y = rand.nextInt(gridSize);

key = x + "," + y;

if (!used.contains(key)) {
child.add(new int[]{x, y});

used.add(key);

break;

tries++;

return child;

private void mutate(List<int[]> ind) {

int idx = rand.nextInt(sensorCount);

int x = rand.nextInt(gridSize);

int y = rand.nextInt(gridSize);

ind.set(idx, new int[]{x, y});

(SensorArrangementController.java)

package com.example.sensor.controller;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import java.util.*;

import java.io.IOException;

import com.example.sensor.util.SimpleDtedReader;
import java.util.Arrays;

import com.example.sensor.logic.GeneticSensorPlacer;

import com.example.sensor.repository.SensorRepository;

import com.example.sensor.entity.Sensor;

import org.springframework.beans.factory.annotation.Autowired;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

@RestController

@RequestMapping("/api")

public class SensorArrangementController {

private static final Logger logger = LoggerFactory.getLogger(SensorArrangementController.class);

@Autowired

private SensorRepository sensorRepository;

@PostMapping("/arrange-sensors")

public ResponseEntity<Map<String, Object>> arrangeSensors(

@RequestParam("file") MultipartFile file,

@RequestParam("sensorCount") int sensorCount,

@RequestParam("sensorRange") int sensorRange) {

Map<String, Object> result = new HashMap<>();

try {

logger.info("Starting terrain processing - File: {}, Size: {} bytes, Sensors: {}, Range: {}",
file.getOriginalFilename(), file.getSize(), sensorCount, sensorRange);

// Validate input parameters

if (file == null || file.isEmpty()) {

logger.error("No file uploaded or file is empty");

result.put("error", "No file uploaded or file is empty.");

return ResponseEntity.badRequest().body(result);

if (sensorCount <= 0 || sensorCount > 100) {

logger.error("Invalid sensor count: {}", sensorCount);

result.put("error", "Invalid sensor count. Must be between 1 and 100.");

return ResponseEntity.badRequest().body(result);

if (sensorRange <= 0 || sensorRange > 10000) {

logger.error("Invalid sensor range: {}", sensorRange);

result.put("error", "Invalid sensor range. Must be between 1 and 10000 meters.");

return ResponseEntity.badRequest().body(result);

// Validate file size with generous limit

if (file.getSize() > 200 * 1024 * 1024) { // 200MB limit

logger.error("File size too large: {} bytes", file.getSize());

result.put("error", "File size exceeds 200MB limit. Please use a smaller file.");

return ResponseEntity.badRequest().body(result);

// Validate file extension (accept multiple DTED formats)


String originalFilename = file.getOriginalFilename();

if (originalFilename == null) {

logger.error("Invalid file name: null");

result.put("error", "Invalid file name.");

return ResponseEntity.badRequest().body(result);

String lowerFilename = originalFilename.toLowerCase();

if (!lowerFilename.endsWith(".dt0") && !lowerFilename.endsWith(".dt1") &&

!lowerFilename.endsWith(".dt2") && !lowerFilename.endsWith(".dt3")) {

logger.error("Invalid file format: {}", originalFilename);

result.put("error", "Invalid file format. Please upload a DTED file (.dt0, .dt1, .dt2, .dt3).");

return ResponseEntity.badRequest().body(result);

java.io.File tempFile = null;

try {

// Create temp file with robust Windows path handling

String tempDir = System.getProperty("java.io.tmpdir");

if (tempDir == null || tempDir.trim().isEmpty()) {

tempDir = "temp";

new java.io.File(tempDir).mkdirs();

// Ensure temp directory exists and is writable

java.io.File tempDirFile = new java.io.File(tempDir);

if (!tempDirFile.exists()) {

boolean created = tempDirFile.mkdirs();

if (!created) {
logger.error("Failed to create temp directory: {}", tempDir);

result.put("error", "Failed to create temporary directory. Please check permissions.");

return ResponseEntity.badRequest().body(result);

if (!tempDirFile.canWrite()) {

logger.error("Temp directory not writable: {}", tempDir);

result.put("error", "Temporary directory is not writable. Please check permissions.");

return ResponseEntity.badRequest().body(result);

String tempFileName = "uploaded_" + System.currentTimeMillis() + "_" +

Thread.currentThread().getId() + ".dt2";

tempFile = new java.io.File(tempDirFile, tempFileName);

logger.info("Creating temp file: {} (exists: {}, writable: {})",

tempFile.getAbsolutePath(), tempFile.exists(), tempFile.canWrite());

// Transfer file to temp location with retry mechanism

boolean transferSuccess = false;

int maxRetries = 3;

for (int attempt = 1; attempt <= maxRetries && !transferSuccess; attempt++) {

try {

logger.info("Attempting file transfer (attempt {}/{}): {} -> {}",

attempt, maxRetries, originalFilename, tempFile.getAbsolutePath());

file.transferTo(tempFile);

transferSuccess = true;
logger.info("File transfer successful on attempt {}", attempt);

} catch (IOException e) {

logger.warn("File transfer attempt {} failed: {}", attempt, e.getMessage());

if (attempt == maxRetries) {

throw e;

Thread.sleep(1000); // Wait 1 second before retry

if (!tempFile.exists() || tempFile.length() == 0) {

logger.error("Failed to save uploaded file. Exists: {}, Size: {}",

tempFile.exists(), tempFile.length());

result.put("error", "Failed to save uploaded file to temporary location.");

return ResponseEntity.badRequest().body(result);

logger.info("Uploaded file saved successfully: {}, size: {} bytes",

tempFile.getAbsolutePath(), tempFile.length());

// Validate DTED file format

logger.info("Validating DTED file format...");

if (!SimpleDtedReader.isValidDtedFile(tempFile)) {

logger.error("Invalid DTED file format: {}", tempFile.getAbsolutePath());

result.put("error", "Invalid DTED file format. Please ensure the file is a valid DTED file.");

return ResponseEntity.badRequest().body(result);

logger.info("DTED file format validation passed");


// Read DTED file with comprehensive error handling

short[][] terrain;

try {

logger.info("Reading DTED file: {}", tempFile.getAbsolutePath());

terrain = SimpleDtedReader.readDtedGrid(tempFile, 0); // auto-detect size

logger.info("DTED file read successfully. Terrain dimensions: {}x{}",

terrain.length, terrain[0].length);

} catch (Exception e) {

logger.error("Error reading DTED file: {}", e.getMessage(), e);

result.put("error", "Error reading DTED file: " + e.getMessage() + ". Please ensure the file is
a valid DTED format.");

return ResponseEntity.badRequest().body(result);

// Validate terrain data

if (terrain == null || terrain.length == 0 || terrain[0].length == 0) {

logger.error("Invalid terrain data: null or empty");

result.put("error", "Invalid terrain data: empty or corrupted file.");

return ResponseEntity.badRequest().body(result);

// Ensure reasonable terrain dimensions

if (terrain.length > 10000 || terrain[0].length > 10000) {

logger.error("Terrain file too large: {}x{}", terrain.length, terrain[0].length);

result.put("error", "Terrain file too large. Please use a smaller terrain file.");

return ResponseEntity.badRequest().body(result);

int origX = terrain.length;


int origY = terrain[0].length;

int targetSize = Math.min(50, Math.min(origX, origY)); // Adaptive sizing

logger.info("Downsampling terrain from {}x{} to {}x{}", origX, origY, targetSize, targetSize);

// Downsample terrain data with bounds checking

short[][] downsampled = new short[targetSize][targetSize];

int stepX = Math.max(1, origX / targetSize);

int stepY = Math.max(1, origY / targetSize);

for (int i = 0; i < targetSize; i++) {

for (int j = 0; j < targetSize; j++) {

int srcX = Math.min(i * stepX, origX - 1);

int srcY = Math.min(j * stepY, origY - 1);

downsampled[i][j] = terrain[srcX][srcY];

logger.info("Terrain downsampled successfully to {}x{}", targetSize, targetSize);

// Use Genetic Algorithm for sensor placement with error handling

logger.info("Starting genetic algorithm for sensor placement...");

GeneticSensorPlacer ga = new GeneticSensorPlacer(downsampled, sensorCount,


sensorRange);

List<int[]> bestSensors = ga.findBestArrangement();

if (bestSensors == null || bestSensors.isEmpty()) {

// Fallback: create simple sensor arrangement

logger.warn("Genetic algorithm failed, using fallback sensor placement");


bestSensors = createFallbackSensorArrangement(targetSize, sensorCount);

logger.info("Sensor placement completed. Placed {} sensors", bestSensors.size());

List<Map<String, Object>> sensors = new ArrayList<>();

Set<String> used = new HashSet<>();

List<Sensor> sensorEntities = new ArrayList<>();

for (int[] pos : bestSensors) {

int x = pos[0];

int y = pos[1];

// Ensure coordinates are within bounds

x = Math.max(0, Math.min(x, targetSize - 1));

y = Math.max(0, Math.min(y, targetSize - 1));

String key = x + "," + y;

if (used.contains(key)) continue;

Map<String, Object> sensor = new HashMap<>();

sensor.put("x", x);

sensor.put("y", y);

sensor.put("height", downsampled[x][y]);

sensor.put("radarHeight", sensorRange);

sensors.add(sensor);

used.add(key);

// Prepare entity for DB


Sensor s = new Sensor();

s.setX(x);

s.setY(y);

s.setHeight(downsampled[x][y]);

s.setRadarHeight(sensorRange);

sensorEntities.add(s);

// Save to database with comprehensive error handling

try {

logger.info("Saving {} sensors to database...", sensorEntities.size());

sensorRepository.deleteAll();

if (!sensorEntities.isEmpty()) {

sensorRepository.saveAll(sensorEntities);

logger.info("Successfully saved {} sensors to database", sensorEntities.size());

} catch (Exception e) {

logger.error("Error saving sensors to database: {}", e.getMessage(), e);

// Continue without database save - sensors are still returned

logger.warn("Continuing without database save due to error");

result.put("terrain", downsampled);

result.put("sensors", sensors);

result.put("message", "Terrain processed successfully. " + sensors.size() + " sensors de-


ployed.");

result.put("terrainDimensions", Arrays.asList(targetSize, targetSize));

result.put("originalDimensions", Arrays.asList(origX, origY));


logger.info("Terrain processing completed successfully. Deployed {} sensors", sensors.size());

return ResponseEntity.ok(result);

} finally {

// Clean up temp file with error handling

if (tempFile != null && tempFile.exists()) {

try {

boolean deleted = tempFile.delete();

if (deleted) {

logger.info("Cleaned up temp file: {}", tempFile.getAbsolutePath());

} else {

logger.warn("Failed to delete temp file: {}", tempFile.getAbsolutePath());

// Schedule for deletion on JVM exit

tempFile.deleteOnExit();

} catch (Exception e) {

logger.warn("Error deleting temp file: {}", e.getMessage());

tempFile.deleteOnExit();

} catch (Exception e) {

logger.error("Unexpected error during terrain processing: {}", e.getMessage(), e);

result.put("error", "An unexpected error occurred: " + e.getMessage());

return ResponseEntity.badRequest().body(result);

}
/**

* Fallback sensor arrangement when genetic algorithm fails

*/

private List<int[]> createFallbackSensorArrangement(int gridSize, int sensorCount) {

List<int[]> sensors = new ArrayList<>();

Random random = new Random();

Set<String> usedPositions = new HashSet<>();

for (int i = 0; i < sensorCount && i < gridSize * gridSize; i++) {

int x, y;

String key;

int attempts = 0;

do {

x = random.nextInt(gridSize);

y = random.nextInt(gridSize);

key = x + "," + y;

attempts++;

} while (usedPositions.contains(key) && attempts < 100);

usedPositions.add(key);

sensors.add(new int[]{x, y});

logger.info("Created fallback sensor arrangement with {} sensors", sensors.size());

return sensors;

}
(SensorServiceImpl.java)
package com.example.sensor.serviceImpl;

import com.example.sensor.dto.SensorDTO;

import com.example.sensor.entity.Sensor;

import com.example.sensor.repository.SensorRepository;

import com.example.sensor.service.SensorService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

import java.util.stream.Collectors;

@Service

public class SensorServiceImpl implements SensorService {

@Autowired

private SensorRepository repository;

@Override

public SensorDTO placeSensor(SensorDTO dto) {

Sensor sensor = new Sensor();

sensor.setX(dto.getX());

sensor.setY(dto.getY());

sensor.setHeight(dto.getHeight());

Sensor saved = repository.save(sensor);

SensorDTO result = new SensorDTO();

result.setX(saved.getX());

result.setY(saved.getY());
result.setHeight(saved.getHeight());

return result;

@Override

public List<SensorDTO> getAllSensors() {

return repository.findAll().stream().map(sensor -> {

SensorDTO dto = new SensorDTO();

dto.setX(sensor.getX());

dto.setY(sensor.getY());

dto.setHeight(sensor.getHeight());

return dto;

}).collect(Collectors.toList());

@Override

public List<SensorDTO> placeSensors(int numSensors, double radarHeight) {

int gridSize = (int) Math.ceil(Math.sqrt(numSensors));

List<SensorDTO> sensors = new java.util.ArrayList<>();

for (int i = 0; i < numSensors; i++) {

int x = i % gridSize;

int y = i / gridSize;

double elevation = 0.0 + radarHeight; // Replace 0.0 with terrain elevation if available

SensorDTO dto = new SensorDTO();

dto.setX(x);

dto.setY(y);

dto.setHeight(elevation);

dto.setRadarHeight(radarHeight);

sensors.add(dto);
}

return sensors;

5. Result and Analysis


This application provides a comprehensive solution for radar coverage
analysis, utilizing real-world terrain data and modern web technologies.
The system is built with a Java Spring Boot backend and
an Angular frontend, ensuring both computational efficiency and a
user-friendly interface.
Key Aspects of the Approach:
• Sensor Placement Logic:
The backend implements custom logic for sensor (radar) placement,
as seen in SensorServiceImpl.java. Sensors are arranged in a grid,
and their positions and heights are dynamically set based on user input
and terrain data. This allows for flexible deployment strategies and ac-
curate modeling of radar coverage.
• Terrain Data Integration:
The application processes DTED and GeoTIFF files using utility classes
(GeoTiffLoader, SimpleDtedReader) to extract elevation data. This data
is crucial for determining line-of-sight and coverage, especially in
complex terrains.
• Multithreaded Processing:
To handle large terrain datasets efficiently, the backend leverages
Java’s multithreading capabilities. This ensures that coverage calcula-
tions are performed quickly, even for high-resolution or large-
area analyses.
• Dynamic Coverage Calculation:
The coverage area is computed based on the radar’s height, which
is provided by the user. The backend accounts for both the Earth’s
curvature and terrain elevation, resulting in realistic coverage polygons:
• In flat regions, the coverage is nearly circular.
• In mountainous regions, the coverage becomes irregular, accu-
rately reflecting terrain obstructions.
• User-Driven Analysis:
The system allows users to specify radar parameters (such as
height and number of sensors) via the Angular frontend. The back-
end then computes and returns detailed coverage data, which is visual-
ized interactively.
• High-Resolution Output:
The coverage polygon is generated with approximately 360 points (one
per degree), providing a detailed and accurate representation of the
radar’s effective area.
Tech Stack:
• Backend: Java, Spring Boot, custom sensor placement and cover-
age logic, multithreading, DTED/GeoTIFF integration.
• Frontend: Angular, TypeScript, interactive visualization of sen-
sor coverage.
• Data Handling: Efficient processing and streaming of large ter-
rain files.
Summary of Your Approach:
This approach combines:
• Custom sensor arrangement algorithms (grid-based, parameter-
ized by user input)
• Real terrain data integration for accurate modeling
• Efficient, multithreaded computation for fast results
• Modern web technologies for an interactive user experience
This enables users to analyze and optimize radar deployment for both
flat and mountainous regions, with results that adapt to both user input
and real-world terrain.

6. Conclusion
Conclusion
The Radar Coverage Analysis Application marks a significant step for-
ward in the field of radar deployment planning and coverage assess-
ment. By leveraging modern web technologies, efficient backend pro-
cessing, and real-world terrain data, the system provides a robust and
flexible platform for analyzing radar visibility in diverse environments.
Key Achievements
• Seamless Integration of Modern Technologies:
Developed a scalable backend using Java Spring Boot, with a responsive
Angular frontend for interactive user experiences.
• Terrain-Aware, Multi-Threaded Processing:
Integrated DTED and GeoTIFF terrain data, processed efficiently using
custom Java logic and multithreading for rapid, accurate coverage cal-
culations.
• Custom Sensor Placement Algorithms:
Implemented flexible sensor arrangement strategies, allowing users to
dynamically configure radar parameters and instantly visualize the im-
pact on coverage.
• High-Resolution, Realistic Coverage Visualization:
Generated detailed coverage polygons that accurately reflect both flat
and mountainous terrains, providing actionable insights for deployment
planning.
Impact and Applications
The application’s versatility and accuracy make it valuable for a range of
users and scenarios:

• Defense and Security:


Enables defense organizations and security agencies to optimize radar
placement and maximize surveillance effectiveness.
• Research and Analysis:
Assists research institutions in studying coverage patterns and evaluat-
ing new deployment strategies.
• Emergency Response and Communications:
Supports emergency teams in assessing communication and sensor cov-
erage in challenging terrains.

Future Outlook
The project’s modular architecture and robust foundation open the
door to future enhancements, including:
• Integration with Additional Data Sources:
Support for more terrain formats and real-time data feeds.
• Advanced Analytics and Machine Learning:
Incorporation of predictive analytics and AI-driven optimization for sen-
sor placement.
• Enhanced Visualization:
More sophisticated, interactive visualizations and reporting tools.
• Adaptation to New Technologies:
Flexibility to accommodate emerging radar and sensor technologies.

7. References
Literature Review
[1]. Kurdzo, J. M., & Palmer, R. D. (2012). Objective optimization of
weather radar networks for low-level coverage using a genetic algo-
rithm. Journal of Atmospheric and Oceanic Technology, 29(6), 807–
821.https://doi.org/10.1175/JTECH-D-11-00076.1
Relevant for genetic algorithm-based sensor placement, similar to the
logic in GeneticSensorPlacer.java.
[2]. Wang, Z., Wang, M., Wu, X., & Yang, S. (2025). Multi-node small
radar network deployment optimization in 3D terrain. Sensors, 25(7),
1964.https://doi.org/10.3390/s25071964
Pertinent to your use of DTED/GeoTIFF terrain data and multi-sensor
deployment strategies.
[3]. Ersü, C., Petlenkov, E., & Janson, K. (2024). A systematic review of
cutting-edge radar technologies: Applications for unmanned ground ve-
hicles (UGVs). Sensors, 24(23),
7807.https://doi.org/10.3390/s24237807
Provides context for modern radar applications, relevant to your sys-
tem’s adaptability.
[4]. Zhang, W., Chen, E., Li, Z., et al. (2020). Review of applications of
radar remote sensing in agriculture. Journal of Radars, 9(3), 444–
461.https://doi.org/10.12000/JR20051
Highlights the versatility of radar coverage analysis, supporting your ap-
plication’s potential for cross-domain use.
Development Technologies
Frontend Development
• Angular (TypeScript):
Used for building a modern, interactive web interface for sensor config-
uration and coverage visualization
• Angular Documentation
• Plotly.js:
For high-resolution, interactive coverage polygon visualization.
Backend Development
• Java (Spring Boot):
Provides a robust, scalable REST API for sensor management, coverage
calculation, and terrain data processing.
• Multithreading (Java Concurrency):
Ensures efficient, parallel processing of large terrain datasets for fast
coverage computation.
• DTED/GeoTIFF Integration:
Custom utility classes (GeoTiffLoader, SimpleDtedReader) for reading
and processing elevation data.
• Custom Logic:
Sensor placement and coverage algorithms implemented in SensorSer-
viceImpl.java and GeneticSensorPlacer.java.
Development Resources
Tutorials and Guides
• Spring Boot:
Spring Boot Reference Guide
• Angular:
Angular Getting Started
• Java Concurrency:
Baeldung Java Concurrency
• GeoTIFF/DTED Handling:
• GeoTools Tutorials
• GDAL Java Bindings
Community Resources
• Stack Overflow – For troubleshooting and code Q&A
• GitHub Discussions – For open source collaboration
• Dev.to – For developer articles and best practices
Additional Resources
• Oracle Java Documentation
• FreeCodeCamp – For general programming tutorials
Research Papers and Technical Reports
1. Radar Coverage Analysis
• IEEE Transactions on Aerospace and Electronic Systems
• International Journal of Remote Sensing
• Journal of Defense Science and Technology
2. Geospatial Visualization and Terrain Analysis
• Computer Graphics Forum
• IEEE Transactions on Visualization and Computer Graphics
• International Journal of Geographical Information Science

You might also like