fetch/fetch-parcel-by-pin.js

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
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.fetchDataForPin = void 0;
exports.formatBookPage = formatBookPage;
exports.formatTimestampToDate = formatTimestampToDate;
const axios_1 = __importDefault(require("axios"));
const turf = __importStar(require("@turf/turf"));
// Shared imports
const calculate_centroid_1 = require("../utils/polyline/calculate-centroid");
const generate_attributes_1 = require("../utils/attributes/generate-attributes");
const turf_buffer_1 = require("../utils/polyline/turf-buffer");
const constants_1 = require("../utils/constants/constants");
/**
 * @namespace fetch
 * @description Utility functions and modules for processing geometry, formatting, and fetching data.
 */
/**
 * Parses a string to extract the book and page components.
 * The input format should be either `part1-part2` or `part1 part2`.
 *
 * @memberof utils
 * @export
 * @function formatBookPage
 * @param {string} input - The string input containing book and page information.
 * @returns {{ book: string, page: string }} An object containing the parsed book and page values.
 * @example
 * const { book, page } = formatBookPage("123-456");
 * console.log(book, page); // "123", "456"
 */
function formatBookPage(input) {
    if (!input) {
        console.error("Invalid Input");
        return { book: "N/A", page: "N/A" };
    }
    input = input.trim();
    const parts = input.split(/[-\s]/);
    if (parts.length !== 2) {
        console.error("Invalid format. Expected format is 'part1-part2' or 'part1 part2'.");
        return { book: "N/A", page: "N/A" };
    }
    const [book, page] = parts;
    return { book, page };
}
/**
 * Converts a timestamp into a human-readable date string in the format MM/DD/YYYY.
 *
 * @memberof utils
 * @export
 * @function formatTimestampToDate
 * @param {number} timestamp - The Unix timestamp in milliseconds.
 * @returns {string} The formatted date string.
 * @example
 * const date = formatTimestampToDate(1672531200000);
 * console.log(date); // "01/01/2023"
 */
function formatTimestampToDate(timestamp) {
    const date = new Date(timestamp);
    const month = (date.getMonth() + 1).toString().padStart(2, '0'); // Months are 0-indexed
    const day = date.getDate().toString().padStart(2, '0');
    const year = date.getFullYear();
    return `${month}/${day}/${year}`;
}
/**
 * Fetches data for a given PIN (Parcel Identification Number) using a specified schema and geometry.
 * Processes the fetched geometry to calculate centroid, generate attributes, and apply offsets.
 *
 * @memberof fetch
 * @export
 * @async
 * @function fetchDataForPin
 * @param {string} county - The name of the county for the data request.
 * @param {string} pin - The Parcel Identification Number (PIN) to fetch data for.
 * @param {string} baseUrl - The base URL for the API endpoint.
 * @param {string} spatialReference - The spatial reference (e.g., EPSG code) for geometry transformation.
 * @param {SchemaKeys} schema - The schema defining the keys for the data attributes.
 * @param {string} layer - The layer name for categorization.
 * @returns {Promise<object>} A promise resolving to the fetched and processed data, or an error object.
 * @throws {Error} Throws an error if the data fetching or processing fails.
 * @example
 * const result = await fetchDataForPin(
 *   "Horry",
 *   "123456",
 *   "https://example.com/api",
 *   "4326",
 *   schemaKeys,
 *   "parcels"
 * );
 * console.log(result.features);
 */
const fetchDataForPin = (county, pin, baseUrl, spatialReference, schema, layer) => __awaiter(void 0, void 0, void 0, function* () {
    const urls = [
        `${baseUrl}?where=${schema.pinKey}=${pin}&inSR=${spatialReference}&outSR=${spatialReference}&outFields=*&f=json`,
    ];
    try {
        const responses = yield Promise.all(urls.map(url => axios_1.default.get(url, { httpsAgent: constants_1.agent })));
        const data = responses.map(response => response.data);
        if (!data[0] || !data[0].features || !data[0].features[0] || !data[0].features[0].geometry) {
            throw new Error(`Invalid data structure for geometry for PIN ${pin}`);
        }
        const dataAttr = Object.assign({}, data[0].features[0].attributes);
        const rings = data[0].features[0].geometry.rings;
        const polyline = (0, calculate_centroid_1.convertRingsToPolyline)(rings);
        const centroid = (0, calculate_centroid_1.calculateCentroid)(polyline);
        const poly1 = turf.polygon(rings);
        const offsetter = [(0, turf_buffer_1.offsetPolygon)(poly1.geometry.coordinates, 100, spatialReference).geometry.coordinates[0]];
        const { attributes } = (0, generate_attributes_1.generateAttributes)(dataAttr, schema, spatialReference, county);
        return {
            features: [
                {
                    type: 'parcel',
                    layer,
                    attributes,
                    centroid,
                    geometry: { rings },
                },
            ],
        };
    }
    catch (error) {
        console.error(`Error fetching data for PIN ${pin}:`, error);
        return { error: `An error occurred while fetching data for PIN ${pin}` };
    }
});
exports.fetchDataForPin = fetchDataForPin;