diff options
Diffstat (limited to 'src/scripts/pages/sheet-map/index.ts')
| -rw-r--r-- | src/scripts/pages/sheet-map/index.ts | 185 |
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]); + }; +})(); |
