commit bad79af3f3f239832d673b248c43343b78e19e34
parent 5e34e8c3d8421b571943aec66200880a96ce8d4c
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Mon, 28 Oct 2024 13:37:13 +0000
geocoder: edit geocoder add class interface and methods
Diffstat:
4 files changed, 146 insertions(+), 41 deletions(-)
diff --git a/geocoder/src/geocoder.ts b/geocoder/src/geocoder.ts
@@ -1,11 +1,11 @@
-import { err_msg, type ErrorMessage, type GeolocationCoordinatesPoint, type ResultsList } from "@radroots/utils";
+import { err_msg, ResultObj, type ErrorMessage, type GeolocationCoordinatesPoint, type ResultsList } from "@radroots/utils";
import type { Database } from "sql.js";
-import type { GeocoderDegreeOffset, GeocoderErrorMessage, GeocoderReverseResult } from "./types";
-import { parse_geocode_reverse_result } from "./utils";
+import type { GeocoderErrorMessage, GeocoderReverseResult, IGeocoder, IGeocoderCountryCenter, IGeocoderCountryListResult, IGeocoderReverse } from "./types";
+import { parse_geocode_country_center_result, parse_geocode_country_list_result, parse_geocode_reverse_result } from "./utils";
const KM_PER_DEGREE_LATITUDE = 111;
-export class Geocoder {
+export class Geocoder implements IGeocoder {
private _db: Database | null = null;
private _database_name: string;
@@ -28,13 +28,7 @@ export class Geocoder {
};
}
-
-
- public async reverse(opts: {
- point: GeolocationCoordinatesPoint;
- degree_offset?: GeocoderDegreeOffset;
- limit?: number | false;
- }): Promise<ResultsList<GeocoderReverseResult> | ErrorMessage<GeocoderErrorMessage>> {
+ public async reverse(opts: IGeocoderReverse): Promise<ResultsList<GeocoderReverseResult> | ErrorMessage<GeocoderErrorMessage>> {
try {
if (!this._db) return err_msg(`*-db`);
const limit = typeof opts.limit === `boolean` ? `` : opts.limit ? Math.round(opts.limit) : `1`;
@@ -58,4 +52,63 @@ export class Geocoder {
return err_msg(`*`);
};
}
-}
-\ No newline at end of file
+
+ public async country(opts: IGeocoderCountryCenter): Promise<ResultsList<GeocoderReverseResult> | ErrorMessage<GeocoderErrorMessage>> {
+ try {
+ if (!this._db) return err_msg(`*-db`);
+ const query = `SELECT * FROM geonames WHERE country_id = $id;`
+ const stmt = this._db.prepare(query);
+ if (!stmt) return err_msg(`*-statement`);
+ const $id = opts.country_id
+ stmt.bind({ $id });
+ const results: GeocoderReverseResult[] = [];
+ while (stmt.step()) {
+ const result = parse_geocode_reverse_result(stmt.getAsObject());
+ if (result) results.push(result);
+ };
+ return { results };
+ } catch (e) {
+ console.log(`Error: Geocoder reverse `, e);
+ return err_msg(`*`);
+ };
+ }
+
+ public async country_list(): Promise<ResultsList<IGeocoderCountryListResult> | ErrorMessage<GeocoderErrorMessage>> {
+ try {
+ if (!this._db) return err_msg(`*-db`);
+ const query = `SELECT country_id, country_name, AVG(latitude) AS latitude_c, AVG(longitude) AS longitude_c FROM geonames GROUP BY country_id;`
+ const stmt = this._db.prepare(query);
+ if (!stmt) return err_msg(`*-statement`);
+ const results: IGeocoderCountryListResult[] = [];
+ while (stmt.step()) {
+ const result = parse_geocode_country_list_result(stmt.getAsObject());
+ if (result) results.push(result);
+ };
+ return { results };
+ } catch (e) {
+ console.log(`Error: Geocoder reverse `, e);
+ return err_msg(`*`);
+ };
+ }
+
+
+ public async country_center(opts: IGeocoderCountryCenter): Promise<ResultObj<GeolocationCoordinatesPoint> | ErrorMessage<GeocoderErrorMessage>> {
+ try {
+ if (!this._db) return err_msg(`*-db`);
+ const query = `SELECT AVG(latitude) AS latitude_c, AVG(longitude) AS longitude_c FROM geonames WHERE country_id = $id;`;
+ const stmt = this._db.prepare(query);
+ if (!stmt) return err_msg(`*-statement`);
+ const $id = opts.country_id
+ stmt.bind({ $id });
+ while (stmt.step()) {
+ const result = parse_geocode_country_center_result(stmt.getAsObject());
+ if (result) return { result };
+ };
+ return err_msg(`*-result`);
+ } catch (e) {
+ console.log(`Error: Geocoder reverse `, e);
+ return err_msg(`*`);
+ };
+ }
+}
+
diff --git a/geocoder/src/global.d.ts b/geocoder/src/global.d.ts
@@ -1,6 +0,0 @@
-declare module 'jshashes' {
- export class SHA256 {
- b64(input: string): string;
- b64_hmac(key: string, input: string): string;
- }
-}
diff --git a/geocoder/src/types.ts b/geocoder/src/types.ts
@@ -1,4 +1,7 @@
+import type { ErrorMessage, GeolocationCoordinatesPoint, ResultObj, ResultsList } from "@radroots/utils";
+
export type GeocoderErrorMessage =
+ | `*-result`
| `*-statement`
| `*-db`
| `*`
@@ -15,3 +18,23 @@ export type GeocoderReverseResult = {
};
export type GeocoderDegreeOffset = 0.5 | 1.0 | 1.5 | 2.0 | 2.5 | 3
+
+export type IGeocoderReverse = {
+ point: GeolocationCoordinatesPoint;
+ degree_offset?: GeocoderDegreeOffset;
+ limit?: number | false;
+};
+
+export type IGeocoderCountryCenter = {
+ country_id: string;
+};
+
+export type IGeocoderCountryListResult = GeolocationCoordinatesPoint & { country_id: string; country: string };
+
+export type IGeocoder = {
+ connect(): Promise<true | ErrorMessage<GeocoderErrorMessage>>;
+ reverse(opts: IGeocoderReverse): Promise<ResultsList<GeocoderReverseResult> | ErrorMessage<GeocoderErrorMessage>>;
+ country(opts: IGeocoderCountryCenter): Promise<ResultsList<GeocoderReverseResult> | ErrorMessage<GeocoderErrorMessage>>;
+ country_list(): Promise<ResultsList<IGeocoderCountryListResult> | ErrorMessage<GeocoderErrorMessage>>;
+ country_center(opts: IGeocoderCountryCenter): Promise<ResultObj<GeolocationCoordinatesPoint> | ErrorMessage<GeocoderErrorMessage>>
+}
+\ No newline at end of file
diff --git a/geocoder/src/utils.ts b/geocoder/src/utils.ts
@@ -1,29 +1,63 @@
-import type { GeocoderReverseResult } from "./types";
+import type { GeolocationCoordinatesPoint } from "@radroots/utils";
+import type { GeocoderReverseResult, IGeocoderCountryListResult } from "./types";
export const parse_geocode_reverse_result = (obj: any): GeocoderReverseResult | undefined => {
- if (typeof obj !== 'object' || !obj) return undefined;
+ if (typeof obj !== `object` || !obj) return undefined;
const { id, name, admin1_id, admin1_name, country_id, country_name, latitude, longitude } = obj;
if (
- typeof id !== `number` ||
- typeof name !== `string` ||
- typeof admin1_id !== `string` ||
- typeof admin1_name !== `string` ||
- typeof country_id !== `string` ||
- typeof country_name !== `string` ||
- typeof latitude !== `number` ||
- typeof longitude !== `number`
+ typeof id === `number` &&
+ typeof name === `string` &&
+ (typeof admin1_id === `string` || typeof admin1_id === `number`) &&
+ typeof admin1_name === `string` &&
+ typeof country_id === `string` &&
+ typeof country_name === `string` &&
+ typeof latitude === `number` &&
+ typeof longitude === `number`
) {
- return undefined;
+ return {
+ id,
+ name,
+ admin1_id,
+ admin1_name,
+ country_id,
+ country_name,
+ latitude,
+ longitude
+ };
}
- const result: GeocoderReverseResult = {
- id,
- name,
- admin1_id,
- admin1_name,
- country_id,
- country_name,
- latitude,
- longitude
- };
- return result;
+ return undefined;
};
+
+export const parse_geocode_country_list_result = (obj: any): IGeocoderCountryListResult | undefined => {
+ if (typeof obj !== `object` || !obj) return undefined;
+ const { country_id, country_name: country, latitude_c: lat, longitude_c: lng } = obj;
+ if (
+ typeof country_id === `string` &&
+ typeof country === `string` &&
+ typeof lat === `number` &&
+ typeof lng === `number`
+ ) {
+ return {
+ country_id,
+ country,
+ lat,
+ lng
+ };
+ }
+ return undefined;
+};
+
+export const parse_geocode_country_center_result = (obj: any): GeolocationCoordinatesPoint | undefined => {
+ if (typeof obj !== `object` || !obj) return undefined;
+ const { latitude_c: lat, longitude_c: lng } = obj;
+ if (
+ typeof lat === `number` &&
+ typeof lng === `number`
+ ) {
+ return {
+ lat,
+ lng
+ };
+ }
+ return undefined;
+};
+\ No newline at end of file