Add bbox coordinates to object_pictures for chip highlight feature
- Add bbox_x/y/w/h FLOAT columns to object_pictures (0–1 percentage range)
- Include type ('word'|'object') and bbox in feed placeholder response
- Fix picture query to use DISTINCT ON instead of LIMIT 1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -310,6 +310,12 @@ async function migrate() {
|
|||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
// Bounding-box columns for object highlights (percentage 0–1 of image size)
|
||||||
|
await query(`ALTER TABLE object_pictures ADD COLUMN IF NOT EXISTS bbox_x FLOAT`);
|
||||||
|
await query(`ALTER TABLE object_pictures ADD COLUMN IF NOT EXISTS bbox_y FLOAT`);
|
||||||
|
await query(`ALTER TABLE object_pictures ADD COLUMN IF NOT EXISTS bbox_w FLOAT`);
|
||||||
|
await query(`ALTER TABLE object_pictures ADD COLUMN IF NOT EXISTS bbox_h FLOAT`);
|
||||||
|
|
||||||
// M2M: objects <-> pairs (Platzhalter)
|
// M2M: objects <-> pairs (Platzhalter)
|
||||||
await query(`
|
await query(`
|
||||||
CREATE TABLE IF NOT EXISTS object_pairs (
|
CREATE TABLE IF NOT EXISTS object_pairs (
|
||||||
|
|||||||
@@ -94,7 +94,9 @@ router.get('/', requireJwt, async (req, res, next) => {
|
|||||||
`SELECT id, titel_de AS de, titel_en AS en, titel_sv AS sv FROM words WHERE id = ANY($1)`,
|
`SELECT id, titel_de AS de, titel_en AS en, titel_sv AS sv FROM words WHERE id = ANY($1)`,
|
||||||
[uuidArr]
|
[uuidArr]
|
||||||
);
|
);
|
||||||
wordRes.rows.forEach(w => { placeholderMap[w.id] = { de: w.de, en: w.en, sv: w.sv }; });
|
wordRes.rows.forEach(w => {
|
||||||
|
placeholderMap[w.id] = { de: w.de, en: w.en, sv: w.sv, type: 'word', bbox: null };
|
||||||
|
});
|
||||||
|
|
||||||
// Object lookup → get first linked word as label
|
// Object lookup → get first linked word as label
|
||||||
const objUuids = uuidArr.filter(u => !placeholderMap[u]);
|
const objUuids = uuidArr.filter(u => !placeholderMap[u]);
|
||||||
@@ -109,7 +111,10 @@ router.get('/', requireJwt, async (req, res, next) => {
|
|||||||
// First word per object
|
// First word per object
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
objRes.rows.forEach(r => {
|
objRes.rows.forEach(r => {
|
||||||
if (!seen.has(r.id)) { placeholderMap[r.id] = { de: r.de, en: r.en, sv: r.sv }; seen.add(r.id); }
|
if (!seen.has(r.id)) {
|
||||||
|
placeholderMap[r.id] = { de: r.de, en: r.en, sv: r.sv, type: 'object', bbox: null };
|
||||||
|
seen.add(r.id);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,14 +161,24 @@ router.get('/', requireJwt, async (req, res, next) => {
|
|||||||
const pictureMap = {}; // objectId → { url, blurhash }
|
const pictureMap = {}; // objectId → { url, blurhash }
|
||||||
if (resolvedObjectIds.size) {
|
if (resolvedObjectIds.size) {
|
||||||
const picRes = await query(
|
const picRes = await query(
|
||||||
`SELECT op.object_id, p.picture_link AS url, p.blurhash
|
`SELECT DISTINCT ON (op.object_id)
|
||||||
|
op.object_id, p.picture_link AS url, p.blurhash,
|
||||||
|
op.bbox_x, op.bbox_y, op.bbox_w, op.bbox_h
|
||||||
FROM object_pictures op
|
FROM object_pictures op
|
||||||
JOIN pictures p ON p.id = op.picture_id
|
JOIN pictures p ON p.id = op.picture_id
|
||||||
WHERE op.object_id = ANY($1)
|
WHERE op.object_id = ANY($1)
|
||||||
LIMIT 1`,
|
ORDER BY op.object_id, p.created_at`,
|
||||||
[[...resolvedObjectIds]]
|
[[...resolvedObjectIds]]
|
||||||
);
|
);
|
||||||
picRes.rows.forEach(r => { pictureMap[r.object_id] = { url: r.url, blurhash: r.blurhash }; });
|
picRes.rows.forEach(r => {
|
||||||
|
pictureMap[r.object_id] = { url: r.url, blurhash: r.blurhash };
|
||||||
|
// Attach bbox to placeholder if all four values are present
|
||||||
|
if (placeholderMap[r.object_id] && r.bbox_x != null) {
|
||||||
|
placeholderMap[r.object_id].bbox = {
|
||||||
|
x: r.bbox_x, y: r.bbox_y, w: r.bbox_w, h: r.bbox_h,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pick first available picture across all placeholders in the pair
|
// Pick first available picture across all placeholders in the pair
|
||||||
|
|||||||
Reference in New Issue
Block a user