Skip to content

Commit

Permalink
Advanced Map - added pin or draw, migration added for adding geoJSON,…
Browse files Browse the repository at this point in the history
… model & types updated, externalAPIService updated
  • Loading branch information
sanjaytkbabu committed Dec 8, 2024
1 parent d4aa66c commit d3c56da
Show file tree
Hide file tree
Showing 24 changed files with 509 additions and 11 deletions.
1 change: 1 addition & 0 deletions .github/environments/values.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config:
FRONTEND_GEOCODER_APIPATH: https://geocoder.api.gov.bc.ca
FRONTEND_OIDC_AUTHORITY: https://dev.loginproxy.gov.bc.ca/auth/realms/standard
FRONTEND_OIDC_CLIENTID: nr-permit-connect-navigator-service-5188
FRONTEND_OPENMAPS_APIPATH: https://openmaps.gov.bc.ca
FRONTEND_OPENSTREETMAP_APIPATH: https://tile.openstreetmap.org
FRONTEND_ORGBOOK_APIPATH: https://orgbook.gov.bc.ca/api/v4
SERVER_APIPATH: /api/v1
Expand Down
1 change: 1 addition & 0 deletions .github/environments/values.prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config:
FRONTEND_GEOCODER_APIPATH: https://geocoder.api.gov.bc.ca
FRONTEND_OIDC_AUTHORITY: https://loginproxy.gov.bc.ca/auth/realms/standard
FRONTEND_OIDC_CLIENTID: nr-permit-connect-navigator-service-5188
FRONTEND_OPENMAPS_APIPATH: https://openmaps.gov.bc.ca
FRONTEND_OPENSTREETMAP_APIPATH: https://tile.openstreetmap.org
FRONTEND_ORGBOOK_APIPATH: https://orgbook.gov.bc.ca/api/v4
SERVER_APIPATH: /api/v1
Expand Down
1 change: 1 addition & 0 deletions .github/environments/values.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config:
FRONTEND_GEOCODER_APIPATH: https://geocoder.api.gov.bc.ca
FRONTEND_OIDC_AUTHORITY: https://test.loginproxy.gov.bc.ca/auth/realms/standard
FRONTEND_OIDC_CLIENTID: nr-permit-connect-navigator-service-5188
FRONTEND_OPENMAPS_APIPATH: https://openmaps.gov.bc.ca
FRONTEND_OPENSTREETMAP_APIPATH: https://tile.openstreetmap.org
FRONTEND_ORGBOOK_APIPATH: https://orgbook.gov.bc.ca/api/v4
SERVER_APIPATH: /api/v1
Expand Down
11 changes: 8 additions & 3 deletions app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,19 @@ app.use(
new URL(config.get('frontend.oidc.authority')).origin,
new URL(config.get('frontend.coms.apiPath')).origin,
new URL(config.get('frontend.geocoder.apiPath')).origin,
new URL(config.get('frontend.orgbook.apiPath')).origin
new URL(config.get('frontend.orgbook.apiPath')).origin,
new URL(config.get('frontend.openMaps.apiPath')).origin
],
'img-src': ["'self'", 'data:', new URL(config.get('frontend.openStreetMap.apiPath')).origin] // eslint-disable-line

'img-src': [
"'self'", // eslint-disable-line
'data:',
new URL(config.get('frontend.openStreetMap.apiPath')).origin
]
}
}
})
);

// Skip if running tests
if (process.env.NODE_ENV !== 'test') {
app.use(httpLogger);
Expand Down
3 changes: 3 additions & 0 deletions app/config/custom-environment-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"authority": "FRONTEND_OIDC_AUTHORITY",
"clientId": "FRONTEND_OIDC_CLIENTID"
},
"openMaps": {
"apiPath": "FRONTEND_OPENMAPS_APIPATH"
},
"openStreetMap": {
"apiPath": "FRONTEND_OPENSTREETMAP_APIPATH"
},
Expand Down
26 changes: 26 additions & 0 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
},
"dependencies": {
"@prisma/client": "^5.17.0",
"@types/proj4": "^2.5.5",
"api-problem": "^9.0.2",
"axios": "^1.7.7",
"compression": "^1.7.4",
Expand All @@ -67,6 +68,7 @@
"jsonwebtoken": "^9.0.2",
"knex": "^3.1.0",
"pg": "^8.12.0",
"proj4": "^2.15.0",
"ts-node": "^10.9.2",
"uuid": "^10.0.0",
"winston": "^3.13.1",
Expand Down
1 change: 1 addition & 0 deletions app/src/controllers/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ const controller = {
naturalDisaster: data.location.naturalDisaster,
projectLocation: data.location.projectLocation,
projectLocationDescription: data.location.projectLocationDescription,
geoJSON: data.location.geoJSON,
locationPIDs: data.location.ltsaPIDLookup,
latitude: data.location.latitude,
longitude: data.location.longitude,
Expand Down
30 changes: 30 additions & 0 deletions app/src/db/migrations/20241127000000_016-advanced-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-disable max-len */
import type { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {
return Promise.resolve()
.then(() =>
knex.schema.alterTable('submission', function (table) {
table.json('geo_json');
})
)
.then(() =>
knex.schema.alterTable('submission', function (table) {
table.text('location_pids_auto');
})
);
}

export async function down(knex: Knex): Promise<void> {
return Promise.resolve() // Drop public schema tables
.then(() =>
knex.schema.alterTable('submission', function (table) {
table.dropColumn('geo_json');
})
)
.then(() =>
knex.schema.alterTable('submission', function (table) {
table.dropColumn('location_pids_auto');
})
);
}
5 changes: 5 additions & 0 deletions app/src/db/models/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ export default {
submitted_by: input.submittedBy,
consent_to_feedback: input.consentToFeedback,
location_pids: input.locationPIDs,
location_pids_auto: input.locationPIDsAuto,
company_name_registered: input.companyNameRegistered,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
geo_json: input.geoJSON as any,
single_family_units: input.singleFamilyUnits,
has_rental_units: input.hasRentalUnits,
street_address: input.streetAddress,
Expand Down Expand Up @@ -106,10 +109,12 @@ export default {
submittedAt: input.submitted_at?.toISOString() as string,
submittedBy: input.submitted_by,
locationPIDs: input.location_pids,
locationPIDsAuto: input.location_pids_auto,
consentToFeedback: input.consent_to_feedback,
projectName: input.project_name,
projectDescription: input.project_description,
companyNameRegistered: input.company_name_registered,
geoJSON: input.geo_json,
singleFamilyUnits: input.single_family_units,
hasRentalUnits: input.has_rental_units,
streetAddress: input.street_address,
Expand Down
2 changes: 2 additions & 0 deletions app/src/db/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ model submission {
housing_coop_description String?
submission_type String?
consent_to_feedback Boolean @default(false)
geo_json Json? @db.Json
location_pids_auto String?
activity activity @relation(fields: [activity_id], references: [activity_id], onDelete: Cascade, map: "submission_activity_id_foreign")
user user? @relation(fields: [assigned_user_id], references: [user_id], onDelete: Cascade, map: "submission_assigned_user_id_foreign")
Expand Down
8 changes: 8 additions & 0 deletions app/src/routes/v1/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ router.use(
})
);

// router.get('/test', (_req: Request, res: Response) => {
// const url =
// 'https://openmaps.gov.bc.ca/geo/pub/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&outputFormat=json&typeName=WHSE_CADASTRE.PMBC_PARCEL_FABRIC_POLY_SVW&CQL_FILTER=INTERSECTS(SHAPE,%20POLYGON%20((1193370.672730913%20383239.8324306654,%201193348.609585723%20383168.66953196935,%201193474.1532485012%20383132.9849056583,%201193529.7406295289%20383223.5657357173,%201193370.672730913%20383239.8324306654)))';
// axios.get(url).then(function (response) {
// res.status(200).send(response.data);
// });
// });

/** OpenAPI Docs */
router.get('/', (_req: Request, res: Response) => {
res.send(docs.getDocHTML('v1'));
Expand Down
88 changes: 86 additions & 2 deletions app/src/services/submission.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable no-useless-catch */
import axios from 'axios';
import config from 'config';
import proj4 from 'proj4';

import prisma from '../db/dataConnection';
import { submission } from '../db/models';
Expand All @@ -27,14 +28,96 @@ function chefsAxios(formId: string, options: AxiosRequestConfig = {}): AxiosInst
});
}

/**
* @function openMapsAxios
* Returns an Axios instance for the CHEFS API
* @param {AxiosRequestConfig} options Axios request config options
* @returns {AxiosInstance} An axios instance
*/
function openMapsAxios(options: AxiosRequestConfig = {}): AxiosInstance {
return axios.create({
baseURL: config.get('server.openMaps.apiPath'),
timeout: 10000,
...options
});
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function getPolygonArray(geoJSON: any) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const polygonArray = geoJSON.geometry.coordinates[0].map((c: any) => {
return { lat: c[1], lng: c[0] };
});
return polygonArray;
}

/**
* @function getParcelDataFromPMBC
* DataBC’s Open Web Services
* Accessing geographic data via WMS/WFS
* Services Provided by OCIO - Digital Platforms & Data - Data Systems & Services
* ref: https://docs.geoserver.org/main/en/user/services/wfs/reference.html#getfeature
* ref: https://catalogue.data.gov.bc.ca/dataset/parcelmap-bc-parcel-fabric
* @returns parcel data in JSON
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function getPIDs(polygon: Array<any>) {
// const { getConfig } = storeToRefs(useConfigStore());
// close polygon by re-adding first point to end of array
// const points = polygon.concat(polygon[0]);

// define the source and destination layer types
// leaflet map layer
const source = proj4.Proj('EPSG:4326'); // gps format of leaflet map
// projection (BC Parcel data layer)
proj4.defs(
'EPSG:3005',
'PROJCS["NAD83 / BC Albers", GEOGCS["NAD83", DATUM["North_American_Datum_1983", SPHEROID["GRS 1980",6378137,298.257222101, AUTHORITY["EPSG","7019"]], TOWGS84[0,0,0,0,0,0,0], AUTHORITY["EPSG","6269"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.0174532925199433, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4269"]], PROJECTION["Albers_Conic_Equal_Area"], PARAMETER["standard_parallel_1",50], PARAMETER["standard_parallel_2",58.5], PARAMETER["latitude_of_center",45], PARAMETER["longitude_of_center",-126], PARAMETER["false_easting",1000000], PARAMETER["false_northing",0], UNIT["metre",1, AUTHORITY["EPSG","9001"]], AXIS["Easting",EAST], AXIS["Northing",NORTH], AUTHORITY["EPSG","3005"]]'

Check warning on line 75 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (20.x)

This line has a length of 714. Maximum allowed is 120

Check warning on line 75 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (18.x)

This line has a length of 714. Maximum allowed is 120

Check warning on line 75 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (20.x)

This line has a length of 714. Maximum allowed is 120

Check warning on line 75 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (18.x)

This line has a length of 714. Maximum allowed is 120

Check warning on line 75 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (16.x)

This line has a length of 714. Maximum allowed is 120

Check warning on line 75 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (16.x)

This line has a length of 714. Maximum allowed is 120
);
const dest = proj4.Proj('EPSG:3005');

// convert lat/long for WFS query
const result = polygon.map((point) => {
//@ts-expect-error please help
return proj4(source, dest, { x: point.lng, y: point.lat });
});

// built query string for WFS request
let query = '';
result.forEach((point, index, array) => {
query = query.concat(point.x, ' ', point.y);
if (index < array.length - 1) query = query.concat(', ');
});

let params =
'/geo/pub/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&outputFormat=json&typeName=WHSE_CADASTRE.PMBC_PARCEL_FABRIC_POLY_SVW&CQL_FILTER=INTERSECTS(SHAPE, POLYGON ((query)))';

Check warning on line 93 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (20.x)

This line has a length of 181. Maximum allowed is 120

Check warning on line 93 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (18.x)

This line has a length of 181. Maximum allowed is 120

Check warning on line 93 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (20.x)

This line has a length of 181. Maximum allowed is 120

Check warning on line 93 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (18.x)

This line has a length of 181. Maximum allowed is 120

Check warning on line 93 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (16.x)

This line has a length of 181. Maximum allowed is 120

Check warning on line 93 in app/src/services/submission.ts

View workflow job for this annotation

GitHub Actions / Unit Tests (App) (16.x)

This line has a length of 181. Maximum allowed is 120

params = params.replace('query', query);

// return params;

const response = await openMapsAxios().get(params);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const parcelData = response.data.features?.map((f: any) => f.properties);
// get comma separated PIDs
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const PIDs = parcelData.map((p: any) => p.PID_FORMATTED).join(',');

return PIDs;
}

const service = {
/**
* @function createSubmission
* Creates a new submission
* @returns {Promise<Partial<Submission>>} The result of running the transaction
*/
createSubmission: async (data: Partial<Submission>) => {
const polygonArray = getPolygonArray(data.geoJSON);
const PIDs = await getPIDs(polygonArray);
data.locationPIDsAuto = PIDs;
const response = await prisma.submission.create({
//@ts-expect-error please help
data: { ...submission.toPrismaModel(data as Submission), created_at: data.createdAt, created_by: data.createdBy },
include: {
activity: {
Expand All @@ -48,7 +131,7 @@ const service = {
}
}
});

//@ts-expect-error please help
return submission.fromPrismaModelWithContact(response);
},

Expand Down Expand Up @@ -352,6 +435,7 @@ const service = {
updateSubmission: async (data: Submission) => {
try {
const result = await prisma.submission.update({
//@ts-expect-error please help
data: { ...submission.toPrismaModel(data), updated_at: data.updatedAt, updated_by: data.updatedBy },
where: {
submission_id: data.submissionId
Expand All @@ -368,7 +452,7 @@ const service = {
}
}
});

//@ts-expect-error please help
return submission.fromPrismaModelWithContact(result);
} catch (e: unknown) {
throw e;
Expand Down
3 changes: 3 additions & 0 deletions app/src/types/Submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ export type Submission = {
submittedAt: string;
submittedBy: string;
locationPIDs: string | null;
locationPIDsAuto: string | null;
companyNameRegistered: string | null;
consentToFeedback: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
geoJSON: any;
projectName: string | null;
projectDescription: string | null;
singleFamilyUnits: string | null;
Expand Down
1 change: 1 addition & 0 deletions app/src/types/SubmissionIntake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type SubmissionIntake = {
naturalDisaster?: string;
projectLocation?: string;
projectLocationDescription?: string;
geoJSON?: JSON;
ltsaPIDLookup?: string;
latitude?: number | null;
longitude?: number | null;
Expand Down
1 change: 1 addition & 0 deletions charts/pcns/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ config:
FRONTEND_GEOCODER_APIPATH: ~
FRONTEND_OIDC_AUTHORITY: ~
FRONTEND_OIDC_CLIENTID: ~
FRONTEND_OPENMAPS_APIPATH: ~
FRONTEND_OPENSTREETMAP_APIPATH: ~
FRONTEND_ORGBOOK_APIPATH: ~

Expand Down
Loading

0 comments on commit d3c56da

Please sign in to comment.