aboutsummaryrefslogtreecommitdiffstats
path: root/src/scripts/pages/sheet-map/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripts/pages/sheet-map/index.ts')
-rw-r--r--src/scripts/pages/sheet-map/index.ts185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/scripts/pages/sheet-map/index.ts b/src/scripts/pages/sheet-map/index.ts
new file mode 100644
index 0000000..a4e45b0
--- /dev/null
+++ b/src/scripts/pages/sheet-map/index.ts
@@ -0,0 +1,185 @@
+import { generateWebPage } from "@/shared/generate-web-page";
+import getDownloadMapPDFPageContent from "@/scripts/pages/sheet-map/download-map-pdf-page-content.html";
+import getMapPlotPolygonPathElement from "@/scripts/pages/sheet-map/map-plot-polygon-path-element.html";
+import getMapPlotNumberLabelTextElement from "@/scripts/pages/sheet-map/map-plot-number-label-text-element.html";
+import getPlotInformationElement from "@/scripts/pages/sheet-map/plot-information-element.html";
+
+interface PlotPolygon {
+ plotArea: number;
+ plotno: string;
+ polygon: string;
+};
+
+interface PlotNumberLabel {
+ plotno: string;
+ point: string;
+}
+
+const headerElement = document.querySelector("#headerTable > tbody > tr")!;
+const plotNumberInput = document.querySelector<HTMLInputElement>("#txtPlotNo")!;
+const plotInformation = document.createElement("div") as HTMLDivElement;
+let plotPolygonPathElements = "";
+let plotNumberLabelTextElements = "";
+
+document.body.appendChild(plotInformation);
+
+/**
+ * Creates a header toolbar button and appends it to the page header.
+ * The button starts hidden and is shown when data is ready.
+ *
+ * @param text - The button label text.
+ * @returns The created button element.
+ */
+const createHeaderButton = (text: string) => {
+ const buttonContainer = document.createElement("td");
+ const button = document.createElement("button");
+ button.innerHTML = text;
+ button.style.display = "none";
+ buttonContainer.appendChild(button);
+ headerElement.appendChild(buttonContainer);
+ return button;
+};
+
+/**
+ * Displays the area and plot number for the given polygon in a floating
+ * info panel, or shows "0.000" / empty if no polygon is selected.
+ *
+ * @param plotPolygon - The selected plot's data, or `null`/`undefined` to clear.
+ */
+const setPlotInformation = (plotPolygon: PlotPolygon | null | undefined = null) => {
+ plotInformation.innerHTML = plotPolygon ? getPlotInformationElement({
+ area: (plotPolygon.plotArea/1000).toFixed(3),
+ plotNumber: plotPolygon.plotno
+ }) : getPlotInformationElement({
+ area: "0.000",
+ plotNumber: ""
+ });
+};
+
+/**
+ * Opens a new window with a printable PDF view of the map, optionally
+ * including plot-number labels.
+ *
+ * @param labelPoints - Whether to include plot number text labels.
+ */
+const downloadPDF = (labelPoints: boolean = true) => {
+ /** Extracts a detail value (district/block/mouza) from the header table by column index. */
+ const _getMapDetail = (i: number) => {
+ const detail = document.querySelector(`#headerTable > tbody > tr > td:nth-child(${i})`)!
+ .innerHTML
+ .split("[")[1]
+ .trim();
+ return detail.substring(0, detail.length - 1);
+ };
+ generateWebPage(
+ getDownloadMapPDFPageContent({
+ district: _getMapDetail(1),
+ block: _getMapDetail(2),
+ mouza: _getMapDetail(3),
+ mapContent: plotPolygonPathElements + (labelPoints ? plotNumberLabelTextElements : "")
+ }),
+ "map"
+ );
+};
+
+const downloadPDFButton = createHeaderButton("SAVE PDF");
+const downloadPDFNoLabelButton = createHeaderButton("SAVE PDF (NO LABEL)");
+
+downloadPDFButton.addEventListener("click", e => {
+ e.preventDefault();
+ downloadPDF();
+});
+
+downloadPDFNoLabelButton.addEventListener("click", e => {
+ e.preventDefault();
+ downloadPDF(false);
+});
+
+setPlotInformation();
+
+(async () => {
+ const searchParams = new URLSearchParams(window.location.search);
+ const response1 = await fetch(
+ "/BanglarBhumi/sheetMap_populateLayerData?lstSheetNo=" + searchParams.get("lstSheetNo"),
+ {
+ method: "POST"
+ });
+ const plotPolygonList: PlotPolygon[] = (await response1.json()).features;
+ const response2 = await fetch(
+ "/BanglarBhumi/sheetMap_populateCentroidData?lstSheetNo=" + searchParams.get("lstSheetNo"),
+ {
+ method: "POST"
+ });
+ const plotNumberLabelList: PlotNumberLabel[] = (await response2.json()).features;
+ let plotPolygons: { [key: string]: PlotPolygon } = {};
+
+ for (const plotPolygon of plotPolygonList) {
+ const plotPolygonPoints = plotPolygon.polygon.split("(((")[1].split(")))")[0];
+ plotPolygonPathElements += getMapPlotPolygonPathElement({
+ polygonVertices: plotPolygonPoints
+ });
+ }
+
+ for (const plotNumberLabel of plotNumberLabelList) {
+ const plotNumberLabelPoint = plotNumberLabel.point.split("(")[1].split(")")[0].split(" ");
+ plotNumberLabelTextElements += getMapPlotNumberLabelTextElement({
+ x: plotNumberLabelPoint[0],
+ y: plotNumberLabelPoint[1],
+ plotNumber: plotNumberLabel.plotno
+ });
+ }
+
+ downloadPDFButton.style.display = "inherit";
+ downloadPDFNoLabelButton.style.display = "inherit";
+
+ document.querySelector("#btnSearch")!.addEventListener("click", () => {
+ let plotPolygon;
+ for (const p of plotPolygonList) {
+ if (p.plotno === plotNumberInput.value) {
+ plotPolygon = p;
+ break;
+ }
+ }
+ setPlotInformation(plotPolygon);
+ });
+
+ await new Promise<void>((resolve, _reject) => {
+ const plotElementIdsControl = setInterval(() => {
+ let plotElements = document.querySelector("#OpenLayers_Layer_Vector_25_vroot")?.children || [];
+ if (plotElements.length) {
+ clearInterval(plotElementIdsControl);
+ for (let i = 0; i < plotElements.length; i++) {
+ plotPolygons[plotElements[i].id] = plotPolygonList[i];
+ }
+ resolve();
+ }
+ }, 50);
+ });
+
+ setInterval(() => {
+ for (const plotElementId in plotPolygons) {
+ const e = document.getElementById(plotElementId);
+ if (e) {
+ e.removeEventListener("click", handlePlotClick);
+ e.addEventListener("click", handlePlotClick);
+ }
+ }
+ }, 300);
+
+ /**
+ * Highlights the clicked plot on the SVG map and shows its
+ * information in the info panel.
+ *
+ * @param e - The mouse click event.
+ */
+ const handlePlotClick = (e: MouseEvent) => {
+ document.querySelectorAll("path").forEach(e => {
+ e.setAttribute("fill", "#ffcc66");
+ });
+
+ const target = e.target as SVGPathElement;
+
+ target.setAttribute("fill", "#8aeeef");
+ setPlotInformation(plotPolygons[target.id]);
+ };
+})();