Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add filter by geom for trees route #388

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions __tests__/e2e/trees.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,16 @@ describe('trees', () => {
},
1000 * 30,
);

it(
'trees?lat=39.0619&lon=-122.6064&lat=38.1519&lon=-123.3139&lat=37.8879&lon=-121.1001',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dagmawig we need you the standard data format for this, which is the geojson, so you need to give a parameter like geojson following the protocol: https://geojson.org/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also, postgresql recogonize geojson for example this: https://postgis.net/docs/ST_GeomFromGeoJSON.html

async () => {
const response = await supertest(app).get(
'/trees?lat=39.0619&lon=-122.6064&lat=38.1519&lon=-123.3139&lat=37.8879&lon=-121.1001',
);
expect(response.status).toBe(200);
expect(response.body.trees.length).toBe(145);
},
1000 * 30,
);
});
37 changes: 37 additions & 0 deletions server/infra/database/TreeRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,4 +304,41 @@ export default class TreeRepository extends BaseRepository<Tree> {
const object = await this.session.getDB().raw(sql);
return object.rows;
}

async getByGeometry(
geometry: { lat: Array<number>; lon: Array<number> },
totalCount = false,
) {
const pointArray = geometry.lon.map((item, i) => `ST_MakePoint(${item}, ${geometry.lat[i]})`);
pointArray.push(`ST_MakePoint(${geometry.lon[0]}, ${geometry.lat[0]})`);

if (totalCount) {
const totalSql = `
SELECT
COUNT(*)
FROM trees t
WHERE
ST_CONTAINS(
ST_SETSRID(ST_CONVEXHULL(ST_MAKELINE(ARRAY[${pointArray.toString()}])), 4326),
ST_SETSRID(ST_POINT(t.lon, t.lat), 4326)
)
`;
const total = await this.session.getDB().raw(totalSql);
return parseInt(total.rows[0].count.toString());
}

const sql = `
SELECT
*
FROM trees t
WHERE
ST_CONTAINS(
ST_SETSRID(ST_CONVEXHULL(ST_MAKELINE(ARRAY[${pointArray.toString()}])), 4326),
ST_SETSRID(ST_POINT(t.lon, t.lat), 4326)
)
`;

const object = await this.session.getDB().raw(sql);
return object.rows;
}
}
11 changes: 11 additions & 0 deletions server/models/Tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Filter = Partial<{
date_range: { startDate: string; endDate: string };
tag: string;
wallet_id: string;
geometry: { lat: Array<number>; lon: Array<number> };
}>;

function getByFilter(
Expand Down Expand Up @@ -41,6 +42,11 @@ function getByFilter(
const trees = await treeRepository.getByWallet(filter.wallet_id, options);
return trees;
}
if (filter.geometry) {
log.warn('using geometry filter...');
const trees = await treeRepository.getByGeometry(filter.geometry);
return trees;
}

const trees = await treeRepository.getByFilter(filter, options);
return trees;
Expand Down Expand Up @@ -84,6 +90,11 @@ function countByFilter(
return total;
}

if (filter.geometry) {
log.warn('using geometry filter...');
const total = await treeRepository.getByGeometry(filter.geometry, true);
return total;
}
const total = await treeRepository.countByFilter(filter);
return total;
};
Expand Down
7 changes: 7 additions & 0 deletions server/routers/treesRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Filter = Partial<{
tag: string;
wallet_id: string;
active: true;
geometry: { lat: Array<number>; lon: Array<number> };
}>;

router.get(
Expand Down Expand Up @@ -70,6 +71,8 @@ router.get(
offset: Joi.number().integer().min(0),
startDate: Joi.string().regex(/^\d{4}-\d{2}-\d{2}$/),
endDate: Joi.string().regex(/^\d{4}-\d{2}-\d{2}$/),
lat: Joi.array().items(Joi.number()),
lon: Joi.array().items(Joi.number()),
}),
);
const {
Expand All @@ -83,6 +86,8 @@ router.get(
endDate,
tag,
wallet_id,
lat,
lon,
} = req.query;
const repo = new TreeRepository(new Session());
const filter: Filter = { active: true };
Expand All @@ -105,6 +110,8 @@ router.get(
filter.tag = tag;
} else if (wallet_id) {
filter.wallet_id = wallet_id;
} else if (lat && lon) {
filter.geometry = { lat, lon };
}

const result = await TreeModel.getByFilter(repo)(filter, options);
Expand Down
Loading