utils/geometryUtil.js

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchConvertAndBufferGeometry = void 0;
const axios_1 = __importDefault(require("axios"));
const proj4_1 = __importDefault(require("proj4"));
const datumConversions_1 = require("./datumConversions");
/**
 * @namespace geometryUtils
 * @description Utility functions for fetching, converting, and buffering geometry data.
 */
/**
 * Projection system for converting coordinates from WKID 3361 to WGS84.
 *
 * @memberof geometryUtils
 * @type {string}
 */
const fromProjection = datumConversions_1.WKID_3361;
/**
 * WGS84 projection used as the target projection.
 *
 * @memberof geometryUtils
 * @type {string}
 */
const toProjection = proj4_1.default.WGS84;
/**
 * Converts a distance from feet to degrees.
 *
 * @memberof geometryUtils
 * @function feetToDegrees
 * @param {number} feet - The distance in feet to be converted.
 * @returns {number} The equivalent distance in degrees.
 * @example
 * const degrees = feetToDegrees(5280); // Convert 1 mile to degrees
 * console.log(degrees); // Approx. 0.014472
 */
const feetToDegrees = (feet) => feet / 364000;
/**
 * Fetches geometry data for a given region and PIN, converts coordinates from WKID 3361 to WGS84,
 * calculates the centroid, and generates a buffered polygon around the centroid.
 *
 * @memberof geometryUtils
 * @function fetchConvertAndBufferGeometry
 * @async
 * @param {string} region - The region identifier for the API request.
 * @param {string} pin - The PIN identifier for the API request.
 * @param {number} bufferFeet - The buffer distance in feet.
 * @returns {Promise<Buffer>} A promise resolving to a polygon array representing the buffered region.
 * @throws {Error} Throws an error if data fetching or processing fails.
 * @example
 * const region = "horry";
 * const pin = "12345";
 * const bufferFeet = 100;
 * const bufferedPolygon = await fetchConvertAndBufferGeometry(region, pin, bufferFeet);
 * console.log(bufferedPolygon);
 * // Output: [
 * //   [-79.2, 34.0],
 * //   [-79.2, 34.1],
 * //   [-79.1, 34.1],
 * //   [-79.1, 34.0],
 * //   [-79.2, 34.0]
 * // ]
 */
const fetchConvertAndBufferGeometry = (region, pin, bufferFeet) => __awaiter(void 0, void 0, void 0, function* () {
    const url = `https://polyline-47877aa70139.herokuapp.com/api/${region}/${pin}`;
    try {
        const response = yield axios_1.default.get(url);
        const geometry = response.data[0].geometry;
        // Convert coordinates from LCC to WGS84
        const convertedCoordinates = geometry.map((coordinate) => {
            return (0, proj4_1.default)(fromProjection, toProjection, coordinate);
        });
        // Calculate the centroid of the polygon
        const centroid = convertedCoordinates.reduce((acc, coordinate) => {
            acc[0] += coordinate[1]; // Latitude
            acc[1] += coordinate[0]; // Longitude
            return acc;
        }, [0, 0]).map((coord) => coord / convertedCoordinates.length);
        // Calculate the bounding box with the given buffer from the centroid
        const buffer = feetToDegrees(bufferFeet);
        const bufferedPolygon = [
            [centroid[1] - buffer, centroid[0] - buffer],
            [centroid[1] - buffer, centroid[0] + buffer],
            [centroid[1] + buffer, centroid[0] + buffer],
            [centroid[1] + buffer, centroid[0] - buffer],
            [centroid[1] - buffer, centroid[0] - buffer],
        ];
        return bufferedPolygon;
    }
    catch (error) {
        console.error('Error fetching data:', error);
        throw new Error('Failed to fetch data');
    }
});
exports.fetchConvertAndBufferGeometry = fetchConvertAndBufferGeometry;