Skip to content
Draft
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
73 changes: 73 additions & 0 deletions lib/providers/__fixtures__/parcelles-invalides.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[
{
"id": "11",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[1.084555, 44.496374],
[1.08459, 44.496382],
[1.084529, 44.496535],
[1.084626, 44.496605],
[1.084563, 44.496746],
[1.085022, 44.496457],
[1.085022, 44.496457],
[1.085022, 44.496457],
[1.085022, 44.496458],
[1.08502, 44.496457],
[1.085021, 44.496457],
[1.085021, 44.496457],
[1.085021, 44.496457],
[1.085021, 44.496457],
[1.085021, 44.496457],
[1.085022, 44.496458],
[1.085022, 44.496458],
[1.084559, 44.496756],
[1.084149, 44.496643],
[1.084304, 44.49655],
[1.084555, 44.496374],
[1.084566, 44.49675],
[1.084702, 44.496786],
[1.084795, 44.496812],
[1.08496, 44.496479],
[1.08494, 44.496475],
[1.084917, 44.496466],
[1.084585, 44.496382],
[1.084531, 44.496534],
[1.08463, 44.496602],
[1.084609, 44.496644],
[1.084588, 44.49667],
[1.084573, 44.496702],
[1.084566, 44.49675]
]
]
},
"conversion_niveau": "AB",
"nom": "Parcelle self intersection"
},
{
"id": "12",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[1.129222719666474, 43.34712010991465],
[1.129222731940167, 43.34712011114064],
[1.129613335697593, 43.34565983706976],
[1.129863977944959, 43.34563818715289],
[1.129699819339938, 43.34403735803216],
[1.129193596649804, 43.34417432499001],
[1.129314543272036, 43.3456754444915],
[1.129314556083055, 43.345675434929426],
[1.129608101470201, 43.34567831682737],
[1.129608113250817, 43.345678327942345],
[1.129390535099628, 43.346492787026946],
[1.129223374770301, 43.34711770668325],
[1.129222733620067, 43.3471201021833],
[1.129222719666474, 43.34712010991465]
]
]
},
"nom": "Parcelle invalide"
}
]
41 changes: 40 additions & 1 deletion lib/providers/cartobio.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const records = require('./__fixtures__/records.json')
const recordToUpdate = require('./__fixtures__/records-to-update.json')
const parcelles = require('./__fixtures__/parcelles.json')
const otherParcelles = require('./__fixtures__/parcelles-aquacole-frontaliere.json')
const invalidParcelles = require('./__fixtures__/parcelles-invalides.json')
const user = require('./__fixtures__/decoded-token-oc.json')
const agencebioOperator = require('./__fixtures__/agence-bio-operateur.json')
const agencebioOperatorsApiResults = require('./__fixtures__/agence-bio-operateur-for-search.json')
Expand Down Expand Up @@ -609,8 +610,46 @@ describe('createOrUpdateOperatorRecord', () => {
expect(result.parcelles[5].commune).toBeNull()
expect(result.parcelles[5].etranger).toEqual(true)
})
})

test('invalid parcelle corrected or not with update_communes trigger', async () => {
const record = recordToUpdate

const featureCollection = {
type: 'FeatureCollection',
features: []
}

for (const parcelle of invalidParcelles) {
featureCollection.features.push(/** @type {Feature} */{
type: 'Feature',
id: parcelle.id,
geometry: parcelle.geometry,
properties: {
id: parcelle.id,
COMMUNE: null
}
})
}

const result = await createOrUpdateOperatorRecord(
{ ...record, parcelles: featureCollection },
{ user, copyParcellesData: false },
db
)

expect(result.parcelles).toHaveLength(2)
expect(result.parcelles[0].commune).toEqual('46089')
expect(result.parcelles[0].etranger).toEqual(false)
expect(result.parcelles[1].commune).toEqual('31250')
expect(result.parcelles[1].etranger).toEqual(false)

const { rows } = await db.query("SELECT id, ST_IsValid(geometry) as valid, ST_Geometrytype(geometry) as type FROM cartobio_parcelles WHERE id = '11' OR id = '12' ORDER BY id ASC")
expect(rows[0].valid).toEqual(false)
expect(rows[0].type).toEqual('ST_Polygon')
expect(rows[1].valid).toEqual(true)
expect(rows[1].type).toEqual('ST_Polygon')
})
})
describe('updateAuditRecordState', () => {
afterEach(async () => {
await db.query('DELETE FROM cartobio_operators where numerobio = \'' + recordToUpdate.numerobio + '\'')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
'use strict';

var dbm;
var type;
var seed;

/**
* We receive the dbmigrate dependency from dbmigrate initially.
* This enables us to not have to rely on NODE_PATH.
*/
exports.setup = function(options, seedLink) {
dbm = options.dbmigrate;
type = dbm.dataType;
seed = seedLink;
};

exports.up = async function(db) {
await db.runSql(
/* sql */`
CREATE OR REPLACE FUNCTION update_communes() RETURNS trigger AS $$
DECLARE
validGeometry public.geometry(geometry, 4326);
tmpValidGeometry public.geometry(geometry, 4326);
initialArea float;
makeValidArea float;
difference float;
i integer;
BEGIN
IF NEW.commune IS NOT NULL AND NEW.commune != '' THEN
RETURN NEW;
END IF;

IF ST_IsValid(NEW.geometry) = false THEN
validGeometry := ST_MakeValid(NEW.geometry, 'method=structure');
IF ST_Geometrytype(validGeometry) = 'ST_MultiPolygon' THEN
tmpValidGeometry := ST_GeometryN(validGeometry, 1);
FOR i IN
SELECT generate_series(1, ST_NumGeometries(validGeometry)) AS i
LOOP
IF ST_Area(ST_GeometryN(validGeometry, i), true) > ST_Area(tmpValidGeometry, true) THEN
tmpValidGeometry := ST_GeometryN(validGeometry, i);
END IF;
END LOOP;
validGeometry := tmpValidGeometry;
END IF;
initialArea := ST_Area(NEW.geometry, true);
makeValidArea := ST_Area(validGeometry, true);
difference := ABS(initialArea - makeValidArea);
IF (difference / 1000) < 1 AND ABS(difference / (initialArea / 100)) < 1 THEN
NEW.geometry = validGeometry;
END IF;
ELSE
validGeometry := NEW.geometry;
END IF;

NEW.etranger =
EXISTS(
SELECT fid
FROM territoires
WHERE ST_Intersects(
validGeometry,
territoires.geom
)
) = false;

IF NEW.etranger = true THEN
RETURN NEW;
END IF;

NEW.commune = (
SELECT code
FROM communes
ORDER BY ST_Area(
ST_Intersection(
validGeometry,
communes.geometry
), true
) DESC,
ST_Distance(
validGeometry,
communes.geometry
) ASC
LIMIT 1
)::text;

RETURN NEW;
END;
$$ LANGUAGE plpgsql;
`)
};

exports.down = async function(db) {
await db.runSql(
/* sql */`
CREATE OR REPLACE FUNCTION update_communes() RETURNS trigger AS $$
DECLARE
validGeometry public.geometry(geometry, 4326);
BEGIN
IF NEW.commune IS NOT NULL AND NEW.commune != '' THEN
RETURN NEW;
END IF;

IF ST_IsValid(NEW.geometry) = false THEN
validGeometry := ST_MakeValid(NEW.geometry, 'method=structure');
ELSE
validGeometry := NEW.geometry;
END IF;

NEW.etranger =
EXISTS(
SELECT fid
FROM territoires
WHERE ST_Intersects(
validGeometry,
territoires.geom
)
) = false;

IF NEW.etranger = true THEN
RETURN NEW;
END IF;

NEW.commune = (
SELECT code
FROM communes
ORDER BY ST_Area(
ST_Intersection(
validGeometry,
communes.geometry
)
) DESC,
ST_Distance(
validGeometry,
communes.geometry
) ASC
LIMIT 1
)::text;

RETURN NEW;
END;
$$ LANGUAGE plpgsql;
`)
};

exports._meta = {
"version": 1
};